Skip to content

feat(js,ui): mount and render the directory sync setup flow - #9592

Open
kalafut wants to merge 4 commits into
jim/dir-sync-2-hooksfrom
jim/dir-sync-3-ui
Open

feat(js,ui): mount and render the directory sync setup flow#9592
kalafut wants to merge 4 commits into
jim/dir-sync-2-hooksfrom
jim/dir-sync-3-ui

Conversation

@kalafut

@kalafut kalafut commented Aug 27, 2026

Copy link
Copy Markdown

Description

Part 3 of 4 of the self-serve Directory Sync stack. Stacked on jim/dir-sync-2-hooks; the changeset rides the first PR and the stack will be squashed on merge.

  • @clerk/clerk-js: __internal_mountConfigureDirectorySync with guards mirroring ConfigureSSO's (orgs enabled, active org, self-serve directory sync feature).
  • @clerk/ui: ConfigureDirectorySync wizard over the organization's enterprise connection and directory (show-once token held in wizard session state, read-only attribute mapping from the directory, test step polls provisioned users), plus a Directory Sync section on the Security page. Google-provider connections are directed to the Dashboard.

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:

🤖 Generated with Claude Code

https://claude.ai/code/session_01U54pszNFtqsBNpQhXaGvaa

@vercel

vercel Bot commented Aug 27, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated
clerk-js-sandbox Ready Ready Preview Sep 1, 2026 11:35pm UTC
swingset Ready Ready Preview Sep 1, 2026 11:35pm UTC

Request Review

@kalafut kalafut changed the title feat(self-serve-ds): mount and render ConfigureDirectorySync feat(js,ui): mount and render the directory sync setup flow Aug 27, 2026
@changeset-bot

changeset-bot Bot commented Aug 28, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: d73777b

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes changesets to release 23 packages
Name Type
@clerk/clerk-js Minor
@clerk/localizations Minor
@clerk/react Minor
@clerk/shared Minor
@clerk/ui Minor
@clerk/chrome-extension Patch
@clerk/electron Patch
@clerk/expo Patch
@clerk/nextjs Patch
@clerk/react-router Patch
@clerk/tanstack-react-start 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/nuxt Patch
@clerk/testing Patch
@clerk/vue Patch
@clerk/swingset Patch

Click here to learn what changesets are, and how to add one.

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

@pkg-pr-new

pkg-pr-new Bot commented Aug 28, 2026

Copy link
Copy Markdown

Open in StackBlitz

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/electron

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

@clerk/electron-passkeys

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

@clerk/eslint-plugin

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

@clerk/expo

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

@clerk/expo-google-signin

npm i https://pkg.pr.new/@clerk/expo-google-signin@9592

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/hono

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

@clerk/localizations

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

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/react

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

@clerk/react-router

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

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/ui

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

@clerk/upgrade

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

@clerk/vue

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

commit: 0d268a1

@github-actions

github-actions Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

API Changes Report

Generated by Break Check on 2026-09-01T20:29:53.191Z

Summary

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

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


@clerk/clerk-js

Current version: 6.30.3
Recommended bump: MINOR → 6.31.0

Subpath .

🟢 Additions (2)

Added: Clerk.__internal_mountConfigureDirectorySync
+ __internal_mountConfigureDirectorySync: (node: HTMLDivElement, props?: ConfigureSSOProps) => void;

Added property Clerk.__internal_mountConfigureDirectorySync

Added: Clerk.__internal_unmountConfigureDirectorySync
+ __internal_unmountConfigureDirectorySync: (node: HTMLDivElement) => void;

Added property Clerk.__internal_unmountConfigureDirectorySync

Subpath ./no-rhc

🟢 Additions (2)

Added: Clerk.__internal_mountConfigureDirectorySync
+ __internal_mountConfigureDirectorySync: (node: HTMLDivElement, props?: ConfigureSSOProps) => void;

Added property Clerk.__internal_mountConfigureDirectorySync

Added: Clerk.__internal_unmountConfigureDirectorySync
+ __internal_unmountConfigureDirectorySync: (node: HTMLDivElement) => void;

Added property Clerk.__internal_unmountConfigureDirectorySync


@clerk/shared

Current version: 4.30.2
Recommended bump: MINOR → 4.31.0

Subpath ./internal/clerk-js/componentGuards

🟢 Additions (1)

Added: disabledSelfServeDirectorySyncFeature
+ disabledSelfServeDirectorySyncFeature: ComponentGuard

Added variable disabledSelfServeDirectorySyncFeature

Subpath ./internal/clerk-js/warnings

🟡 Non-breaking Changes (1)

Modified: warnings
// ... 7 unchanged lines elided ...
    cannotRenderSignInComponentWhenSessionExists: string;
    cannotRenderSignInComponentWhenTaskExists: string;
    cannotRenderComponentWhenUserDoesNotExist: string;
-   createCannotRenderComponentWhenOrgDoesNotExist: (componentName: "OrganizationProfile" | "InviteMembers" | "ConfigureSSO") => string;
+   createCannotRenderComponentWhenOrgDoesNotExist: (componentName: "OrganizationProfile" | "InviteMembers" | "ConfigureSSO" | "ConfigureDirectorySync") => string;
    createCannotRenderComponentWhenPermissionIsMissing: (componentName: "InviteMembers", permission: string) => string;
-   cannotRenderAnyOrganizationComponent: (componentName: "OrganizationProfile" | "InviteMembers" | "OrganizationSwitcher" | "OrganizationList" | "CreateOrganization" | "TaskChooseOrganization" | "ConfigureSSO") => string;
+   cannotRenderAnyOrganizationComponent: (componentName: "OrganizationProfile" | "InviteMembers" | "OrganizationSwitcher" | "OrganizationList" | "CreateOrganization" | "TaskChooseOrganization" | "ConfigureSSO" | "ConfigureDirectorySync") => string;
    cannotRenderAnyBillingComponent: (componentName: "PricingTable" | "Checkout" | "PlanDetails") => string;
    cannotOpenUserProfile: string;
    cannotOpenCheckout: string;
    cannotOpenSignInOrSignUp: string;
    cannotRenderAPIKeysComponent: string;
    cannotRenderAPIKeysComponentForOrgWhenUnauthorized: string;
    cannotRenderAPIKeysComponentForUserWhenDisabled: string;
    cannotRenderAPIKeysComponentForOrgWhenDisabled: string;
    cannotRenderOAuthConsentComponentWhenUserDoesNotExist: string;
    cannotRenderConfigureSSOComponentWhenUserDoesNotExist: string;
    cannotRenderConfigureSSOComponentWhenDisabled: string;
+   cannotRenderConfigureDirectorySyncComponentWhenDisabled: string;
    cannotRenderConfigureSSOComponentWhenEmailAddressDisabled: string;
  }

Static analyzer: Breaking change in variable warnings: Type changed: {proxyUrlAsFunctionNotSupported:string;domainAsFunctionNotSupported:string;cannotRenderComponentWhenSessionExists:strin…{proxyUrlAsFunctionNotSupported:string;domainAsFunctionNotSupported:string;cannotRenderComponentWhenSessionExists:strin…

🤖 AI review (reclassified as non-breaking) (90%): The changes are purely additive: two new union arms ("ConfigureDirectorySync") are added to the componentName parameter types of createCannotRenderComponentWhenOrgDoesNotExist and cannotRenderAnyOrganizationComponent (widening input types, which is non-breaking), and a new string property cannotRenderConfigureDirectorySyncComponentWhenDisabled is added to the object (adding a new property to an output/read object is non-breaking). No existing properties or function signatures were narrowed or removed.

Subpath ./types

🟡 Non-breaking Changes (3)

Modified: __internal_AttemptToEnableEnvironmentSettingParams
  type __internal_AttemptToEnableEnvironmentSettingParams = {
    for: 'organizations';
-   caller: 'OrganizationSwitcher' | 'OrganizationProfile' | 'InviteMembers' | 'OrganizationList' | 'CreateOrganization' | 'TaskChooseOrganization' | 'ConfigureSSO' | 'useOrganizationList' | 'useOrganization';
+   caller: 'OrganizationSwitcher' | 'OrganizationProfile' | 'InviteMembers' | 'OrganizationList' | 'CreateOrganization' | 'TaskChooseOrganization' | 'ConfigureSSO' | 'ConfigureDirectorySync' | 'useOrganizationList' | 'useOrganization';
    onClose?: () => void;
  };

Static analyzer: Breaking change in type alias __internal_AttemptToEnableEnvironmentSettingParams: Type changed: {for:'organizations';caller:'ConfigureSSO'|'CreateOrganization'|'InviteMembers'|'OrganizationList'|'OrganizationProfile…{for:'organizations';caller:'ConfigureDirectorySync'|'ConfigureSSO'|'CreateOrganization'|'InviteMembers'|'OrganizationL…

🤖 AI review (reclassified as non-breaking) (90%): The caller union in __internal_AttemptToEnableEnvironmentSettingParams is widened by adding 'ConfigureDirectorySync'; this type is used as an input parameter, so widening an input union is non-breaking for existing callers who pass one of the previously-valid literals.

Modified: __internal_LocalizationResource
// ... 1108 unchanged lines elided ...
          tooltip__noRole: LocalizationValue;
          tooltipLabel: LocalizationValue;
        };
+       directorySyncSection: {
+         title: LocalizationValue;
+         badge__unconfigured: LocalizationValue;
+         badge__active: LocalizationValue;
+         badge__inactive: LocalizationValue;
+         description: LocalizationValue;
+         primaryButton__startConfiguration: LocalizationValue;
+         menuAction__edit: LocalizationValue;
+         menuAction__activate: LocalizationValue;
+         menuAction__deactivate: LocalizationValue;
+         menuAction__remove: LocalizationValue;
+         removeDialog: {
+           title: LocalizationValue;
+           subtitle: LocalizationValue;
+           confirmButton: LocalizationValue;
+         };
+       };
      };
      membersPage: {
        detailsTitle__emptyRow: LocalizationValue;
// ... 963 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) (75%): __internal_LocalizationResource is used as the base for DeepPartial<DeepLocalizationWithoutObjects<...>> (an output/extension type), and the elided diff (17 extra lines) most likely represents new optional localization keys being added; adding new properties to a type consumers only extend or read is non-breaking.

Modified: ProfileSectionId
- type ProfileSectionId = 'profile' | 'username' | 'emailAddresses' | 'phoneNumbers' | 'connectedAccounts' | 'enterpriseAccounts' | 'web3Wallets' | 'password' | 'passkeys' | 'mfa' | 'danger' | 'activeDevices' | 'organizationProfile' | 'organizationDanger' | 'organizationDomains' | 'manageVerifiedDomains' | 'subscriptionsList' | 'paymentMethods' | 'sso' | 'ssoStatus' | 'enableSso' | 'ssoDomain' | 'ssoConfiguration' | 'configureAgain' | 'resetSso' | 'testSsoUrl' | 'testResults' | 'accountCredits';
+ type ProfileSectionId = 'profile' | 'username' | 'emailAddresses' | 'phoneNumbers' | 'connectedAccounts' | 'enterpriseAccounts' | 'web3Wallets' | 'password' | 'passkeys' | 'mfa' | 'danger' | 'activeDevices' | 'organizationProfile' | 'organizationDanger' | 'organizationDomains' | 'manageVerifiedDomains' | 'subscriptionsList' | 'paymentMethods' | 'sso' | 'directorySync' | 'ssoStatus' | 'enableSso' | 'ssoDomain' | 'ssoConfiguration' | 'configureAgain' | 'resetSso' | 'testSsoUrl' | 'testResults' | 'accountCredits';

Static analyzer: Breaking change in type alias ProfileSectionId: Type changed: 'accountCredits'|'activeDevices'|'configureAgain'|'connectedAccounts'|'danger'|'emailAddresses'|'enableSso'|'enterprise…'accountCredits'|'activeDevices'|'configureAgain'|'connectedAccounts'|'danger'|'directorySync'|'emailAddresses'|'enable…

🤖 AI review (reclassified as non-breaking) (85%): ProfileSectionId is widened by adding 'directorySync' to the union; MenuId (which includes ProfileSectionId) is an output/discriminated-ID type and existing consumers who switch or compare against known literals are unaffected by the addition of a new variant.

🟢 Additions (2)

Added: Clerk.__internal_mountConfigureDirectorySync
+ __internal_mountConfigureDirectorySync: (targetNode: HTMLDivElement, props?: ConfigureSSOProps) => void;

Added property Clerk.__internal_mountConfigureDirectorySync

Added: Clerk.__internal_unmountConfigureDirectorySync
+ __internal_unmountConfigureDirectorySync: (targetNode: HTMLDivElement) => void;

Added property Clerk.__internal_unmountConfigureDirectorySync


Report generated by Break Check

Last ran on dc73c4c.

@coderabbitai

coderabbitai Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

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

Review profile: ASSERTIVE

Plan: Team

Run ID: e4371702-c936-4a6a-88a2-28e8e4b9df1c

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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

kalafut and others added 4 commits September 1, 2026 13:37
- @clerk/clerk-js: __internal_mountConfigureDirectorySync with guards
  mirroring ConfigureSSO's (orgs enabled, active org, self-serve
  directory sync feature).
- @clerk/ui: ConfigureDirectorySync wizard over the organization's
  enterprise connection and directory (show-once token held in wizard
  session state, read-only attribute mapping from the directory, test step
  polls provisioned users), plus a Directory Sync section on the Security
  page. Google-provider connections are directed to the Dashboard.
1. Mock directory.update()/delete() on the resource instead of the removed organization.updateDirectorySync/deleteDirectorySync; also mock getDomains so a retry loop can't wedge the page's loading gate.
2. Security section + wizard:show spinner while loading and an error alert on failure instead of falsely rendering "unconfigured"; wizard shows the skeleton while loading.
3. Standalone mount:wrapped in the shared ConfigureSSOProtect permission gate.
4. Clerk API surface:added __internal_(un)mountConfigureDirectorySync to the shared Clerk interface and IsomorphicClerk, so framework SDKs can reach the mount; added @clerk/react to the changeset.
5. Activate step:"Done"/"Skip for now" render only when the host supplies onExit (they were no-ops standalone).
6. Navbar:DirectorySyncNavbar is now a thin wrapper over ConfigureSSONavbar (with a new title prop), restoring mobile behavior.
7. TestSyncStep:|| instead of ?? so an empty display name falls through.
8. Bundle limits: bumped via bundlewatch:fix (554KB / 81KB).
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.

1 participant