feat(ui): Support signUpIfMissing with Clerk <SignIn> component#7928
feat(ui): Support signUpIfMissing with Clerk <SignIn> component#7928dmoerner wants to merge 16 commits into
Conversation
The `<SignIn>` component can already be used in a sign-in-or-sign-up flow (`CombinedFlow`) under certain conditions. When strict enumeration protection is enabled, make that combined flow pass the `signUpIfMissing` parameter to the backend to allow an enumeration-safe combined flow. Previously, attempting to use a combined flow with strict enumeration protection enabled was silently broken. Under the hood, the backend treats sign up if missing as an account transfer. We therefore add support for this account transfer logic when handling first factor verification in the combined sign in flow when strict enumeration protection is enabled.
🦋 Changeset detectedLatest commit: 77325fd The changes in this PR will be included in the next version bump. This PR includes changesets to release 23 packages
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 |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository YAML (base), Repository UI (inherited) Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (56)
✅ Files skipped from review due to trivial changes (21)
📝 WalkthroughWalkthroughAdds support for a combined sign-in-or-sign-up flow gated by enumeration protection. Introduces attack-protection settings, transferable verification handling, sign-up transfer orchestration, conditional sign-in creation, localization updates, fixtures, tests, and release metadata. ChangesEnumeration Protection & Transfer Flow
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant SignInUI as SignIn UI
participant Clerk as Clerk Client
participant Backend
User->>SignInUI: Submit identifier
SignInUI->>Backend: signIn.create({ signUpIfMissing: true })
Backend-->>SignInUI: transferable verification status
SignInUI->>Backend: signUp.create({ transfer: true, unsafeMetadata })
Backend-->>SignInUI: complete or missing_requirements
alt complete
SignInUI->>Clerk: setActive(session)
Clerk-->>User: Navigate to after-sign-up URL
else missing_requirements
SignInUI-->>User: Navigate to ../create/continue
end
Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/clerk-js/src/core/resources/SignIn.ts`:
- Around line 311-312: SignInFuture.waitForEmailLinkVerification currently
treats only 'verified' and 'expired' as terminal statuses, which causes
transferable flows started by createEmailLinkFlow to poll indefinitely; update
the status check inside SignInFuture.waitForEmailLinkVerification to include
'transferable' alongside 'verified' and 'expired' so the polling loop calls
stop()/resolves when status === 'transferable', ensuring transferable email-link
flows terminate properly.
ℹ️ Review info
Configuration used: Repository YAML (base), Organization UI (inherited)
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (15)
.changeset/fancy-candies-slide.mdpackages/clerk-js/src/core/clerk.tspackages/clerk-js/src/core/resources/SignIn.tspackages/clerk-js/src/core/resources/UserSettings.tspackages/shared/src/errors/emailLinkError.tspackages/shared/src/types/userSettings.tspackages/ui/src/components/SignIn/SignInFactorOneCodeForm.tsxpackages/ui/src/components/SignIn/SignInFactorOneEmailLinkCard.tsxpackages/ui/src/components/SignIn/SignInStart.tsxpackages/ui/src/components/SignIn/__tests__/SignInFactorOneTransfer.test.tsxpackages/ui/src/components/SignIn/__tests__/SignInStart.test.tsxpackages/ui/src/components/SignIn/__tests__/handleSignUpIfMissingTransfer.test.tspackages/ui/src/components/SignIn/handleSignUpIfMissingTransfer.tspackages/ui/src/test/fixture-helpers.tspackages/ui/src/test/fixtures.ts
This is connected to custom flows and was missed in the previous PRs supporting custom flows. Let's add it now while we are here.
| const res = await this.#resource.__internal_baseGet(); | ||
| const status = res.firstFactorVerification.status; | ||
| if (status === 'verified' || status === 'expired') { | ||
| if (status === 'verified' || status === 'expired' || status === 'transferable') { |
There was a problem hiding this comment.
This change is not necessary for Clerk builtin components but was missed in #7749. As suggested by CodeRabbit, let's just fix it now.
@clerk/astro
@clerk/backend
@clerk/chrome-extension
@clerk/clerk-js
@clerk/electron
@clerk/electron-passkeys
@clerk/eslint-plugin
@clerk/expo
@clerk/expo-passkeys
@clerk/express
@clerk/fastify
@clerk/hono
@clerk/localizations
@clerk/nextjs
@clerk/nuxt
@clerk/react
@clerk/react-router
@clerk/shared
@clerk/tanstack-react-start
@clerk/testing
@clerk/ui
@clerk/upgrade
@clerk/vue
commit: |
|
|
|
Working scenarios I tested locally:
Scenarios I didn't test locally:
Under investigation:
|
|
Hello 👋 We currently close PRs after 60 days of inactivity. It's been 50 days since the last update here. If we missed this PR, please reply here. Otherwise, we'll close this PR in 10 days. Thanks for being a part of the Clerk community! 🙏 |
…mponents Reconcile the signUpIfMissing extraction with main's protect-check support: route protect-gated sign-ups to the /protect-check challenge in the shared navigateToNextStepSignUp helper (used by both the OAuth callback and the sign-in transfer flow), threading signUpProtectCheckUrl through all call sites. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
API Changes Report
Summary
@clerk/sharedCurrent version: 4.25.1 Subpath
|
- Keep transferred sign-ups inside the combined <SignIn> flow: navigate to the nested create/... routes via relative paths and reuse the context's navigateOnSetActive instead of absolute signUpUrl-based URLs, which forced a full page reload and broke apps without a standalone SignUp route (virtual/modal routing included). - Make UserSettingsJSON.attack_protection optional and deep-normalize it in UserSettings.fromJSON so partial payloads can't crash consumers. - Derive a shared signUpIfMissingEnabled predicate in useSignInContext instead of re-deriving eligibility in three components. - Resolve the OTP card before transferring so it can't be left spinning. - Drop the redundant missingFields param from navigateToNextStepSignUp. - Extract the terminal email-link verification status check shared by the two SignIn polling loops. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The link-click tab of a signUpIfMissing email-link flow previously showed 'Successfully signed in', but the user is not signed in yet - the email was verified and the original tab continues the flow as a sign-up. Render a dedicated 'Email verified' card (new signIn.emailLink.verifiedTransferable localization keys) driven by the __clerk_status=transferable query param. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Description
The
<SignIn>component can already be used in a sign-in-or-sign-up flow (CombinedFlow) under certain conditions. When strict enumeration protection is enabled, make that combined flow pass thesignUpIfMissingparameter to the backend to allow an enumeration-safe combined flow. Previously, attempting to use a combined flow with strict enumeration protection enabled was silently broken.Under the hood, the backend treats sign up if missing as an account transfer. We therefore add support for this account transfer logic when handling first factor verification in the combined sign in flow when strict enumeration protection is enabled.
Fixes USER-4769.
We should merge this in coordination with documentation and a Changelog release, since it will change existing behavior (although with a fix for something that is currently broken)
Checklist
pnpm testruns as expected.pnpm buildruns as expected.Type of change
Summary by CodeRabbit