Lokasi ngalangkungan proxy:   [ UP ]  
[Ngawartoskeun bug]   [Panyetelan cookie]                
Skip to content

feat(ui): <ConfigureSSO /> POC#8491

Open
LauraBeatris wants to merge 16 commits intomainfrom
laura/poc-e2e
Open

feat(ui): <ConfigureSSO /> POC#8491
LauraBeatris wants to merge 16 commits intomainfrom
laura/poc-e2e

Conversation

@LauraBeatris
Copy link
Copy Markdown
Member

@LauraBeatris LauraBeatris commented May 6, 2026

Description

⚠️ proof of concept for the upcoming state of <ConfigureSSO />, it contains a rough UI/UX but allows the end-user to create a connection e2e

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:

@LauraBeatris LauraBeatris self-assigned this May 6, 2026
@vercel
Copy link
Copy Markdown

vercel Bot commented May 6, 2026

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

Project Deployment Actions Updated (UTC)
clerk-js-sandbox Ready Ready Preview, Comment May 6, 2026 7:34pm

Request Review

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 6, 2026

🦋 Changeset detected

Latest commit: 0e44641

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

This PR includes changesets to release 2 packages
Name Type
@clerk/ui Patch
@clerk/chrome-extension 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

@LauraBeatris LauraBeatris marked this pull request as ready for review May 6, 2026 19:32
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 6, 2026

Open in StackBlitz

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/dev-cli

npm i https://pkg.pr.new/@clerk/dev-cli@8491

@clerk/expo

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

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/hono

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

@clerk/localizations

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

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/react

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

@clerk/react-router

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

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/ui

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

@clerk/upgrade

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

@clerk/vue

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

commit: 0e44641

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 6, 2026

📝 Walkthrough

Walkthrough

This pull request adds a comprehensive multi-step SSO configuration wizard to the Clerk UI library. The changes introduce a new ConfigureSSO flow with seven steps (provider selection, email verification, app configuration, testing, and confirmation), complete with context-based state management, wizard routing, and localization support. The PR also includes API payload restructuring to flatten SAML/OIDC enterprise connection fields, a runtime guard preventing SSO configuration without an authenticated user, and extended theming support for the new wizard UI components.

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes


Details

Rationale: This is a substantial feature addition spanning 26+ files with high logic density and heterogeneous changes. The wizard implementation contains complex routing and navigation logic (554 lines), the step components feature varied patterns (email verification with OTP, URL polling for test runs, clipboard handling), the context system manages stateful flow with nested wizard delegation, and the API payload transformation requires careful verification of field mapping semantics. The changes affect multiple packages with integration points across clerk-js (guards), shared (types/warnings), localizations, and ui (components, contexts, appearance, flow metadata). While some steps follow repetitive patterns, each requires distinct reasoning regarding error handling, state synchronization, and wizard integration.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 72.73% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(ui): <ConfigureSSO /> POC' clearly indicates this is a new UI feature introducing a proof-of-concept for the ConfigureSSO component, which aligns with the substantial changes adding wizard-based SSO configuration.
Description check ✅ Passed The description appropriately describes the changeset as a proof-of-concept for ConfigureSSO with a rough UI/UX that enables end-to-end connection creation, which directly relates to the widespread addition of wizard steps, context providers, and enterprise connection handling throughout the codebase.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 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 `@packages/ui/src/components/ConfigureSSO/ConfigureSSO.tsx`:
- Around line 148-179: The wizard incorrectly skips the ProvideEmail step when
any user.emailAddresses exist; update ConfigureSSOWizard flow to require/select
a domain-specific email instead: replace the hasEmailAddress boolean with logic
that checks for an email matching the target/work domain (or introduce explicit
state like selectedEmail / targetEmail) and only skip rendering the ProvideEmail
step if a matching domain email is found; ensure ProvideEmail sets selectedEmail
and pass that selectedEmail (instead of reading user.emailAddresses or primary)
into VerifyDomainStep so VerifyDomainStep verifies the chosen target email for
the enterprise connection.

In `@packages/ui/src/components/ConfigureSSO/steps/ConfigureCreateAppStep.tsx`:
- Around line 42-60: The auto-create path can leave
hasAttemptedCreateRef.current true on failure causing an unrecoverable spinner;
update the effect around createEnterpriseConnection (which uses
hasAttemptedCreateRef, setIsCreating, card.setError) so that on rejection you
clear/reset hasAttemptedCreateRef.current (or set a local failed flag) and set
an error state via card.setError (or another piece of state) to surface a retry
UI; ensure the render branch that currently checks !enterpriseConnection shows
an error/retry when hasAttemptedCreateRef indicates a failed attempt (instead of
always rendering the spinner) and keep setIsCreating(false) on both success and
failure.

In `@packages/ui/src/components/ConfigureSSO/steps/TestConfigurationStep.tsx`:
- Around line 37-39: The current code launches a test via
user.createEnterpriseConnectionTestRun and then polls for any successful run,
which allows old runs to incorrectly mark the step complete and cannot detect a
specific run failure; capture the run id returned by
createEnterpriseConnectionTestRun (store it alongside setTestUrl), then change
the polling logic (the code that currently calls
getEnterpriseConnectionTestRuns) to query the specific run by id (or filter by
runId) and inspect that run's terminal status, proceeding only when that run's
status is "success" and treating "failure" as a terminal error (stop spinner and
surface an error) so that only the newly created run controls completion of
TestConfigurationStep.
🪄 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), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 4ba31d44-1f6e-4de6-b1a7-150bfc68c86f

📥 Commits

Reviewing files that changed from the base of the PR and between d7317c1 and 0e44641.

⛔ Files ignored due to path filters (1)
  • packages/ui/src/icons/duotone-at-symbol.svg is excluded by !**/*.svg
📒 Files selected for processing (25)
  • .changeset/lucky-tables-learn.md
  • packages/clerk-js/src/core/clerk.ts
  • packages/clerk-js/src/core/resources/User.ts
  • packages/clerk-js/src/core/resources/__tests__/User.test.ts
  • packages/localizations/src/en-US.ts
  • packages/shared/src/internal/clerk-js/warnings.ts
  • packages/shared/src/types/localization.ts
  • packages/ui/src/components/ConfigureSSO/ConfigureSSO.tsx
  • packages/ui/src/components/ConfigureSSO/ConfigureSSOContext.tsx
  • packages/ui/src/components/ConfigureSSO/steps/ConfigureCreateAppStep.tsx
  • packages/ui/src/components/ConfigureSSO/steps/ConfirmationStep.tsx
  • packages/ui/src/components/ConfigureSSO/steps/ProvideEmailStep.tsx
  • packages/ui/src/components/ConfigureSSO/steps/SelectProviderStep.tsx
  • packages/ui/src/components/ConfigureSSO/steps/StepLayout.tsx
  • packages/ui/src/components/ConfigureSSO/steps/TestConfigurationStep.tsx
  • packages/ui/src/components/ConfigureSSO/steps/VerifyDomainStep.tsx
  • packages/ui/src/components/ConfigureSSO/steps/index.ts
  • packages/ui/src/components/ConfigureSSO/wizard/ConfigureSSOWizard.tsx
  • packages/ui/src/components/ConfigureSSO/wizard/ConfigureSSOWizardContext.tsx
  • packages/ui/src/components/ConfigureSSO/wizard/index.ts
  • packages/ui/src/components/ConfigureSSO/wizard/types.ts
  • packages/ui/src/customizables/elementDescriptors.ts
  • packages/ui/src/elements/contexts/index.tsx
  • packages/ui/src/icons/index.ts
  • packages/ui/src/internal/appearance.ts

Comment on lines +148 to +179
const hasEmailAddress = Boolean(user?.emailAddresses?.length);

return (
<ConfigureSSOWizard>
<ConfigureSSOWizard.Step
id='select-provider'
path='select-provider'
label='Select provider'
>
<SelectProviderStep />
</ConfigureSSOWizard.Step>
<ConfigureSSOWizard.Step
id='verify-email-domain'
path='verify-email-domain'
label='Verify domain'
>
<ConfigureSSOWizard>
{!hasEmailAddress && (
<ConfigureSSOWizard.Step
id='provide-email'
path='provide-email'
>
<ProvideEmail />
</ConfigureSSOWizard.Step>
)}
<ConfigureSSOWizard.Step
id='verify-domain'
path='verify-domain'
>
<VerifyDomainStep />
</ConfigureSSOWizard.Step>
</ConfigureSSOWizard>
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.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Don't skip the add-email path just because the user has some email address.

hasEmailAddress only checks user.emailAddresses.length, so users who are already signed in with a personal address bypass ProvideEmail. VerifyDomainStep then reuses the current primary/unverified address, which means this flow can't collect and verify the work-domain email required for the enterprise connection. That breaks the end-to-end Configure SSO path for a common account shape; the wizard needs to track/select an email for the target domain rather than treating “any email exists” as sufficient.

🤖 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/ui/src/components/ConfigureSSO/ConfigureSSO.tsx` around lines 148 -
179, The wizard incorrectly skips the ProvideEmail step when any
user.emailAddresses exist; update ConfigureSSOWizard flow to require/select a
domain-specific email instead: replace the hasEmailAddress boolean with logic
that checks for an email matching the target/work domain (or introduce explicit
state like selectedEmail / targetEmail) and only skip rendering the ProvideEmail
step if a matching domain email is found; ensure ProvideEmail sets selectedEmail
and pass that selectedEmail (instead of reading user.emailAddresses or primary)
into VerifyDomainStep so VerifyDomainStep verifies the chosen target email for
the enterprise connection.

Comment on lines +42 to +60
React.useEffect(() => {
if (enterpriseConnection || !selectedProvider || !emailDomain || hasAttemptedCreateRef.current) {
return;
}

hasAttemptedCreateRef.current = true;
setIsCreating(true);
card.setError(undefined);

createEnterpriseConnection({
provider: selectedProvider,
name: buildConnectionName(selectedProvider, emailDomain),
})
.catch(err => handleError(err as Error, [], card.setError))
.finally(() => setIsCreating(false));
// `card` is intentionally omitted: `useCardState()` returns a new
// object every render, which would refire this effect indefinitely
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [enterpriseConnection, selectedProvider, emailDomain, createEnterpriseConnection]);
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.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Make the auto-create failure path recoverable.

If createEnterpriseConnection() fails here, hasAttemptedCreateRef stays true while enterpriseConnection stays undefined, so the branch at Line 108 keeps rendering the spinner forever and the user has no retry path. The same dead-end happens if this step is reached without the prerequisites needed to start creation. Please render an error/retry state when creation cannot proceed, instead of treating !enterpriseConnection as "still loading".

Also applies to: 108-119

🤖 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/ui/src/components/ConfigureSSO/steps/ConfigureCreateAppStep.tsx`
around lines 42 - 60, The auto-create path can leave
hasAttemptedCreateRef.current true on failure causing an unrecoverable spinner;
update the effect around createEnterpriseConnection (which uses
hasAttemptedCreateRef, setIsCreating, card.setError) so that on rejection you
clear/reset hasAttemptedCreateRef.current (or set a local failed flag) and set
an error state via card.setError (or another piece of state) to surface a retry
UI; ensure the render branch that currently checks !enterpriseConnection shows
an error/retry when hasAttemptedCreateRef indicates a failed attempt (instead of
always rendering the spinner) and keep setIsCreating(false) on both success and
failure.

Comment on lines +37 to +39
user
.createEnterpriseConnectionTestRun(enterpriseConnection.id)
.then(({ url }) => setTestUrl(url))
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.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Track the specific test run instead of polling for any prior success.

This step marks the check as complete as soon as getEnterpriseConnectionTestRuns(..., { status: ['success'] }) returns any row, so an older successful run on the same connection will enable Continue immediately even if the URL created here was never used. The inverse case is broken too: a newly failed run is indistinguishable from “still waiting”, so the user can sit on the spinner forever after a bad test. Please tie the poll to the run started at Line 38 and inspect that run’s terminal status before enabling progression.

Also applies to: 59-67

🤖 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/ui/src/components/ConfigureSSO/steps/TestConfigurationStep.tsx`
around lines 37 - 39, The current code launches a test via
user.createEnterpriseConnectionTestRun and then polls for any successful run,
which allows old runs to incorrectly mark the step complete and cannot detect a
specific run failure; capture the run id returned by
createEnterpriseConnectionTestRun (store it alongside setTestUrl), then change
the polling logic (the code that currently calls
getEnterpriseConnectionTestRuns) to query the specific run by id (or filter by
runId) and inspect that run's terminal status, proceeding only when that run's
status is "success" and treating "failure" as a terminal error (stop spinner and
surface an error) so that only the newly created run controls completion of
TestConfigurationStep.

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