diff --git a/.changeset/nasty-melons-cross.md b/.changeset/nasty-melons-cross.md new file mode 100644 index 00000000000..e0c69c28bc3 --- /dev/null +++ b/.changeset/nasty-melons-cross.md @@ -0,0 +1,6 @@ +--- +"@clerk/clerk-js": patch +"@clerk/shared": patch +--- + +Only retry the OAuth flow if the captcha check failed. diff --git a/packages/clerk-js/src/core/resources/SignUp.ts b/packages/clerk-js/src/core/resources/SignUp.ts index bdd505be2fa..5f239241227 100644 --- a/packages/clerk-js/src/core/resources/SignUp.ts +++ b/packages/clerk-js/src/core/resources/SignUp.ts @@ -1,4 +1,5 @@ import { Poller } from '@clerk/shared'; +import { isCaptchaError, isClerkAPIResponseError } from '@clerk/shared/error'; import type { AttemptEmailAddressVerificationParams, AttemptPhoneNumberVerificationParams, @@ -271,12 +272,15 @@ export class SignUp extends BaseResource implements SignUpResource { return continueSignUp && this.id ? this.update(params) : this.create(params); }; - const { verifications } = await authenticateFn().catch(async () => { + const { verifications } = await authenticateFn().catch(async e => { // If captcha verification failed because the environment has changed, we need // to reload the environment and try again one more time with the new environment. // If this fails again, we will let the caller handle the error accordingly. - await SignUp.clerk.__unstable__environment!.reload(); - return authenticateFn(); + if (isClerkAPIResponseError(e) && isCaptchaError(e)) { + await SignUp.clerk.__unstable__environment!.reload(); + return authenticateFn(); + } + throw e; }); const { externalAccount } = verifications; diff --git a/packages/shared/src/error.ts b/packages/shared/src/error.ts index f570fd99f02..e7ef7b56dc1 100644 --- a/packages/shared/src/error.ts +++ b/packages/shared/src/error.ts @@ -6,6 +6,10 @@ export function isUnauthorizedError(e: any): boolean { return code === 'authentication_invalid' && status === 401; } +export function isCaptchaError(e: ClerkAPIResponseError): boolean { + return ['captcha_invalid', 'captcha_not_enabled', 'captcha_missing_token'].includes(e.errors[0].code); +} + export function is4xxError(e: any): boolean { const status = e?.status; return !!status && status >= 400 && status < 500;