-
Notifications
You must be signed in to change notification settings - Fork 436
feat(clerk-js): Add sign_up_if_missing for SignIn.create #7749
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat(clerk-js): Add sign_up_if_missing for SignIn.create #7749
Conversation
We are building a new sign-in-or-sign-up flow compatible with strict enumeration protection. It is meant to complement our existing sign-in-or-sign-up flow. Our current sign-in-or-sign-up flow is managed by the SDKs: We start with a sign in attempt, and on a 422 (when an account does not exist), we redirect to a sign up. The flow is thus: Sign In (422) -> Sign Up (200) -> Attempt Verifications for VerifiedAtSignUp identifiers (200). This is vulnerable to user enumeration attacks because the attacker sees the sign in to sign up redirect before they prove their identity by completing a verification. When `sign_up_if_missing` is passed as a param when POSTing a sign in, instead we do the following: Sign In (200) -> Attempt Verification for Identifier (200) -> Create User and Session. (In future work this third step will be modified to support adding additional information to the user, either via AccountTransfer or Session Tasks). This is enumeration safe, because you only see if an account already existed or was created after you verify your identity. This PR is the first step in SDK support for this new flow. We add support for the optional `sign_up_if_missing` param on `SignIn`. We also add captcha support for `SignIn`. This is all optional and currently in testing with custom components. Support in Clerk components will be in future PRs.
🦋 Changeset detectedLatest commit: 396be4e The changes in this PR will be included in the next version bump. This PR includes changesets to release 20 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.
|
| finalParams = { ...finalParams, ...captchaParams }; | ||
| } | ||
|
|
||
| if (params.transfer && this.shouldBypassCaptchaForAttempt(params)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check guards against an attacker who tries to make a fake transfer and then changes strategy at the same time, which would be an attempt to get around WAF rules and Captcha rules that exclude transfers. We already guard against this on the backend on both sign in and sign up, but in the SDK we were only checking it on sign up. So I took this opportunity to also add the check on sign in.
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThis pull request adds CAPTCHA support to 🚥 Pre-merge checks | ✅ 4 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. No actionable comments were generated in the recent review. 🎉 Comment |
@clerk/agent-toolkit
@clerk/astro
@clerk/backend
@clerk/chrome-extension
@clerk/clerk-js
@clerk/dev-cli
@clerk/expo
@clerk/expo-passkeys
@clerk/express
@clerk/fastify
@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: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@packages/clerk-js/src/core/resources/SignIn.ts`:
- Around line 185-192: The code accesses nested properties on
SignIn.clerk.client without guarding signUp/verifications/externalAccount;
change the retrieval of strategy in the SignIn transfer branch to use safe
checks (e.g. optional chaining or explicit null checks) so you do const strategy
= SignIn.clerk.client?.signUp?.verifications?.externalAccount?.strategy and only
assign (finalParams as TransferParams).strategy = strategy as
TransferParams['strategy'] if strategy is not undefined/null; update the logic
inside the transfer block (related to shouldBypassCaptchaForAttempt and
finalParams assignment) to avoid any potential TypeError from missing
intermediate objects.
- Around line 621-629: The transfer branch accesses
SignIn.clerk.client!.signUp.verifications.externalAccount.strategy directly
which can throw if signUp/verifications/externalAccount is undefined; update the
condition inside the captchaOauthBypass check to use optional chaining (e.g.,
SignIn.clerk.client?.signUp?.verifications?.externalAccount?.strategy) and
compare safely (guarding null/undefined) so the predicate returns false when the
nested property is missing, ensuring the transfer path doesn't cause a runtime
error.
| captcha_token?: string; | ||
| captcha_error?: unknown; | ||
| captcha_widget_type?: string | null; | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My intention with these types was for SignInCreateParams to match what we send to FAPI, which is why I added to the discriminated union. Another approach would be to reserve it for what is passed into the SDK method, and use implicit typing or just Record<string,unknown> for what we sent to FAPI. The latter approach actually fits better what we already do on sign up but it felt haphazard to me.
…custom-flow-with-captcha-in-sdk
Description
We are building a new sign-in-or-sign-up flow compatible with strict enumeration protection. It is meant to complement our existing sign-in-or-sign-up flow.
Our current sign-in-or-sign-up flow is managed by the SDKs: We start with a sign in attempt, and on a 422 (when an account does not exist), we redirect to a sign up. The flow is thus: Sign In (422) -> Sign Up (200) -> Attempt Verifications for VerifiedAtSignUp identifiers (200). This is vulnerable to user enumeration attacks because the attacker sees the sign in to sign up redirect before they prove their identity by completing a verification.
When
sign_up_if_missingis passed as a param when POSTing a sign in, instead we do the following: Sign In (200) -> Attempt Verification for Identifier (200) -> Create User and Session. (In future work this third step will be modified to support adding additional information to the user, either via AccountTransfer or Session Tasks). This is enumeration safe, because you only see if an account already existed or was created after you verify your identity.This PR is the first step in SDK support for this new flow. We add support for the optional
sign_up_if_missingparam onSignIn. We also add captcha support forSignIn. This is all optional and currently in testing with custom components. Support in Clerk components will be in future PRs.Fixes USER-4596
Checklist
pnpm testruns as expected.pnpm buildruns as expected.Type of change
Summary by CodeRabbit
sign_up_if_missingparameter, enabling seamless user sign-up fallback during sign-in.