Skip to content

chore(ui,shared,localizations): Handle expired status for organization domain#9000

Merged
LauraBeatris merged 4 commits into
mainfrom
laura/expired-domain
Jun 25, 2026
Merged

chore(ui,shared,localizations): Handle expired status for organization domain#9000
LauraBeatris merged 4 commits into
mainfrom
laura/expired-domain

Conversation

@LauraBeatris

@LauraBeatris LauraBeatris commented Jun 25, 2026

Copy link
Copy Markdown
Member

Description

This PR handles the expired state of an organization domain, allowing to trigger another verification with fresh TXT records.

CleanShot 2026-06-25 at 13 58 06 CleanShot 2026-06-25 at 13 59 52

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Summary by CodeRabbit

  • New Features

    • Added support for expired organization domain verification states in the SSO setup flow.
    • Users can now trigger verification again for expired domains.
    • New messaging and badge states were added to reflect expired, verified, and re-verification statuses.
  • Bug Fixes

    • Improved domain status handling so only truly unverified ownership checks are polled.
    • Aligned verification status data to better match the domain state shown in the UI.

@LauraBeatris LauraBeatris self-assigned this Jun 25, 2026
@vercel

vercel Bot commented Jun 25, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
clerk-js-sandbox Ready Ready Preview, Comment Jun 25, 2026 5:19pm
swingset Ready Ready Preview, Comment Jun 25, 2026 5:19pm

Request Review

@changeset-bot

changeset-bot Bot commented Jun 25, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: ef0890b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 23 packages
Name Type
@clerk/localizations Minor
@clerk/clerk-js Minor
@clerk/shared Minor
@clerk/ui Minor
@clerk/react Patch
@clerk/chrome-extension Patch
@clerk/electron Patch
@clerk/expo Patch
@clerk/astro Patch
@clerk/backend Patch
@clerk/expo-passkeys Patch
@clerk/express Patch
@clerk/fastify Patch
@clerk/headless Patch
@clerk/hono Patch
@clerk/msw Patch
@clerk/nextjs Patch
@clerk/nuxt Patch
@clerk/react-router Patch
@clerk/tanstack-react-start Patch
@clerk/testing Patch
@clerk/vue Patch
@clerk/swingset Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

An error occurred during the review process. Please try again later.


Comment @coderabbitai help to get the list of available commands.

@pkg-pr-new

pkg-pr-new Bot commented Jun 25, 2026

Copy link
Copy Markdown

Open in StackBlitz

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@9000

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@9000

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@9000

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@9000

@clerk/electron

npm i https://pkg.pr.new/@clerk/electron@9000

@clerk/electron-passkeys

npm i https://pkg.pr.new/@clerk/electron-passkeys@9000

@clerk/eslint-plugin

npm i https://pkg.pr.new/@clerk/eslint-plugin@9000

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@9000

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@9000

@clerk/express

npm i https://pkg.pr.new/@clerk/express@9000

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@9000

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@9000

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@9000

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@9000

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@9000

@clerk/react

npm i https://pkg.pr.new/@clerk/react@9000

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@9000

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@9000

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@9000

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@9000

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@9000

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@9000

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@9000

commit: ef0890b

@github-actions

github-actions Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

API Changes Report

Generated by Break Check on 2026-06-25T17:22:00.566Z

Summary

Metric Count
Packages analyzed 19
Packages with changes 2
🔴 Breaking changes 0
🟡 Non-breaking changes 6
🟢 Additions 1

🤖 This report was reviewed by claude-sonnet-4-6.


@clerk/shared

Current version: 4.21.0
Recommended bump: MINOR → 4.22.0

Subpath ./types

🟡 Non-breaking Changes (5)

Modified: __internal_LocalizationResource
// ... 1297 unchanged lines elided ...
        domainCard: {
          badge__verified: LocalizationValue;
          badge__unverified: LocalizationValue;
+         badge__expired: LocalizationValue;
          verifiedAtLabel: LocalizationValue<'date'>;
+         expiredAtLabel: LocalizationValue<'date'>;
+         expiredLabel: LocalizationValue;
+         verifyAgainButton: LocalizationValue;
          removeButtonTooltip__lastVerifiedDomain: LocalizationValue;
          removeButtonTooltip__lastVerifiedDomainActive: LocalizationValue;
          txtRecord: {
// ... 639 unchanged lines elided ...

Static analyzer: Breaking change in type alias __internal_LocalizationResource: Type changed: {locale:string;maintenanceMode:import("@clerk/shared").LocalizationValue;roles:{[r:string]:import("@clerk/shared").Loca…{locale:string;maintenanceMode:import("@clerk/shared").LocalizationValue;roles:{[r:string]:import("@clerk/shared").Loca…

🤖 AI review (reclassified as non-breaking) (60%): The diff shows 4 more lines in the elided section ('1863 lines elided' → '1867 lines elided'), indicating new optional localization keys were added; __internal_LocalizationResource is used only as the source for DeepPartial<DeepLocalizationWithoutObjects<...>> in LocalizationResource, so consumers only extend a partial version of it, meaning new keys do not require existing consumers to supply them.

Modified: OrganizationDomainOwnershipVerification.status
- status: OrganizationDomainVerificationStatus;
+ status: OrganizationDomainOwnershipVerificationStatus;

Static analyzer: Breaking change in property OrganizationDomainOwnershipVerification.status: Type changed: import("@clerk/shared").OrganizationDomainVerificationStatusimport("@clerk/shared").OrganizationDomainOwnershipVerificationStatus

🤖 AI review (reclassified as non-breaking) (85%): The new type OrganizationDomainOwnershipVerificationStatus ('expired'|'unverified'|'verified') is a superset of the old OrganizationDomainVerificationStatus ('unverified'|'verified') used in this output property position, so consumers reading status from OrganizationDomainOwnershipVerification must already handle more possible values — but since this is an output/result field (interface property consumers read, not write), widening the union is safe for existing consumers.

Modified: OrganizationDomainOwnershipVerificationJSON.status
- status: OrganizationDomainVerificationStatus;
+ status: OrganizationDomainOwnershipVerificationStatus;

Static analyzer: Breaking change in property OrganizationDomainOwnershipVerificationJSON.status: Type changed: import("@clerk/shared").OrganizationDomainVerificationStatusimport("@clerk/shared").OrganizationDomainOwnershipVerificationStatus

🤖 AI review (reclassified as non-breaking) (85%): Same as above: OrganizationDomainOwnershipVerificationJSON.status is an output/data field consumers read; switching from the narrower OrganizationDomainVerificationStatus to the broader OrganizationDomainOwnershipVerificationStatus widens the union in an output position, which is non-breaking.

Modified: OrganizationDomainOwnershipVerificationStrategy
- type OrganizationDomainOwnershipVerificationStrategy = 'txt' | 'legacy' | 'manual_override';
+ type OrganizationDomainOwnershipVerificationStrategy = 'txt' | 'legacy' | 'manual_override' | 'parent_domain';

Static analyzer: Breaking change in type alias OrganizationDomainOwnershipVerificationStrategy: Type changed: 'legacy'|'manual_override'|'txt''legacy'|'manual_override'|'parent_domain'|'txt'

🤖 AI review (reclassified as non-breaking) (85%): OrganizationDomainOwnershipVerificationStrategy is used as the type of output properties (strategy fields on OrganizationDomainOwnershipVerification and OrganizationDomainOwnershipVerificationJSON); adding 'parent_domain' to the union widens an output-position type, so existing consumers that read strategy will simply encounter a new possible value rather than break.

Modified: OrganizationDomainVerificationStatus
- type OrganizationDomainVerificationStatus = 'unverified' | 'verified';
+ type OrganizationDomainVerificationStatus = 'unverified' | 'verified' | 'failed' | 'expired';

Static analyzer: Breaking change in type alias OrganizationDomainVerificationStatus: Type changed: 'unverified'|'verified''expired'|'failed'|'unverified'|'verified'

🤖 AI review (reclassified as non-breaking) (85%): OrganizationDomainVerificationStatus is used as the type of OrganizationDomainVerification.status and OrganizationDomainVerificationJSON.status, both output fields; adding 'failed' and 'expired' to the union widens an output-position type, which is non-breaking for consumers that only read the value.

🟢 Additions (1)

Added: OrganizationDomainOwnershipVerificationStatus
+ type OrganizationDomainOwnershipVerificationStatus = 'unverified' | 'verified' | 'expired';

Added type alias OrganizationDomainOwnershipVerificationStatus


@clerk/ui

Current version: 1.22.0
Recommended bump: MINOR → 1.23.0

Subpath ./internal

🟡 Non-breaking Changes (1)

Modified: ElementsConfig
// ... 490 unchanged lines elided ...
    configureSSOVerifyDomainErrorSubtitle: WithOptions;
    configureSSOVerifyDomainList: WithOptions;
    configureSSOVerifyDomainSuggestion: WithOptions;
-   configureSSOVerifyDomainCard: WithOptions<'verified' | 'unverified'>;
-   configureSSOVerifyDomainCardBadge: WithOptions<'verified' | 'unverified'>;
+   configureSSOVerifyDomainCard: WithOptions<'verified' | 'unverified' | 'expired'>;
+   configureSSOVerifyDomainCardBadge: WithOptions<'verified' | 'unverified' | 'expired'>;
    configureSSOVerifyDomainCardRemoveButton: WithOptions;
    configureSSOVerifyDomainCardTxtRecord: WithOptions;
    configureSSOVerifyDomainCardTxtRecordValue: WithOptions;
+   configureSSOVerifyDomainCardExpired: WithOptions;
    configureSSOEmailVerificationForm: WithOptions<string>;
    configureSSOEmailVerificationIcon: WithOptions<string>;
    configureSSOEmailVerificationTitle: WithOptions<string>;
// ... 51 unchanged lines elided ...

Static analyzer: Breaking change in type alias ElementsConfig: Type changed: {button:import("@clerk/ui").~WithOptions<string>;input:import("@clerk/ui").~WithOptions;checkbox:import("@clerk/ui").~W…{button:import("@clerk/ui").~WithOptions<string>;input:import("@clerk/ui").~WithOptions;checkbox:import("@clerk/ui").~W…

🤖 AI review (reclassified as non-breaking) (80%): The before and after snippets show identical structure except for one additional entry in the elided middle section (472 lines → 473 lines), indicating a new key was added to ElementsConfig; ElementsConfig is used only as an output/mapped type source (via the Elements type alias), so adding a new property is non-breaking for consumers who only read values of Elements.


Report generated by Break Check

Last ran on ef0890b.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/shared/src/types/organizationDomain.ts (1)

37-81: 🗄️ Data Integrity & Integration | 🔵 Trivial

Public JSDoc changed on exported organization-domain types; Docs team review may be needed.

The ownership status union is aligned with the API (unverified | verified | expired), so there’s no failed ownership state to add. Affiliation verification still uses its separate failed/expired statuses.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/shared/src/types/organizationDomain.ts` around lines 37 - 81, The
exported organization-domain JSDoc in
OrganizationDomainOwnershipVerificationStatus and
OrganizationDomainOwnershipVerification should only describe the API-aligned
ownership states, so remove any ownership wording that implies a `failed` status
and keep `failed` only in OrganizationDomainVerificationStatus. Update the
comments on the ownership status union and the status field in
OrganizationDomainOwnershipVerification to reflect `unverified` | `verified` |
`expired`, and keep the verification type docs distinct from the ownership docs.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.changeset/ripe-ways-greet.md:
- Around line 2-8: Update the changeset entry to use minor instead of patch for
`@clerk/shared`, `@clerk/ui`, `@clerk/localizations`, and `@clerk/clerk-js`, since the
self-serve SSO expired-organization-domain handling introduces a new public
feature; edit the changeset metadata in the ripe-ways-greet changeset so the
release versioning matches the added API surface.

---

Nitpick comments:
In `@packages/shared/src/types/organizationDomain.ts`:
- Around line 37-81: The exported organization-domain JSDoc in
OrganizationDomainOwnershipVerificationStatus and
OrganizationDomainOwnershipVerification should only describe the API-aligned
ownership states, so remove any ownership wording that implies a `failed` status
and keep `failed` only in OrganizationDomainVerificationStatus. Update the
comments on the ownership status union and the status field in
OrganizationDomainOwnershipVerification to reflect `unverified` | `verified` |
`expired`, and keep the verification type docs distinct from the ownership docs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Repository UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 332bf84b-f9aa-41be-a88b-aa93d73ad55e

📥 Commits

Reviewing files that changed from the base of the PR and between 3e036f4 and 84fb3e9.

📒 Files selected for processing (9)
  • .changeset/ripe-ways-greet.md
  • packages/localizations/src/en-US.ts
  • packages/shared/src/react/hooks/useOrganizationDomains.tsx
  • packages/shared/src/types/json.ts
  • packages/shared/src/types/localization.ts
  • packages/shared/src/types/organizationDomain.ts
  • packages/ui/src/components/ConfigureSSO/steps/OrganizationDomainsStep.tsx
  • packages/ui/src/customizables/elementDescriptors.ts
  • packages/ui/src/internal/appearance.ts

Comment thread .changeset/ripe-ways-greet.md Outdated
@LauraBeatris LauraBeatris force-pushed the laura/expired-domain branch from 3110987 to 39becf2 Compare June 25, 2026 17:17
@LauraBeatris LauraBeatris merged commit 19ce04a into main Jun 25, 2026
48 checks passed
@LauraBeatris LauraBeatris deleted the laura/expired-domain branch June 25, 2026 18:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants