diff --git a/.changeset/blue-cloths-create.md b/.changeset/blue-cloths-create.md new file mode 100644 index 00000000000..1fbc195cee1 --- /dev/null +++ b/.changeset/blue-cloths-create.md @@ -0,0 +1,5 @@ +--- +'@clerk/clerk-js': minor +--- + +[Experimental] Add support for captcha to Signal SignUp diff --git a/packages/clerk-js/src/core/resources/SignUp.ts b/packages/clerk-js/src/core/resources/SignUp.ts index 3f1f5626129..8f9aee5b12e 100644 --- a/packages/clerk-js/src/core/resources/SignUp.ts +++ b/packages/clerk-js/src/core/resources/SignUp.ts @@ -8,6 +8,7 @@ import type { AuthenticateWithPopupParams, AuthenticateWithRedirectParams, AuthenticateWithWeb3Params, + CaptchaWidgetType, CreateEmailLinkFlowReturn, PrepareEmailAddressVerificationParams, PreparePhoneNumberVerificationParams, @@ -487,11 +488,35 @@ class SignUpFuture implements SignUpFutureResource { return this.resource.unverifiedFields; } + private async getCaptchaToken(): Promise<{ + captchaToken?: string; + captchaWidgetType?: CaptchaWidgetType; + captchaError?: unknown; + }> { + const captchaChallenge = new CaptchaChallenge(SignUp.clerk); + const response = await captchaChallenge.managedOrInvisible({ action: 'signup' }); + if (!response) { + throw new Error('Captcha challenge failed'); + } + + const { captchaError, captchaToken, captchaWidgetType } = response; + return { captchaToken, captchaWidgetType, captchaError }; + } + async password({ emailAddress, password }: { emailAddress: string; password: string }): Promise<{ error: unknown }> { return runAsyncResourceTask(this.resource, async () => { + const { captchaToken, captchaWidgetType, captchaError } = await this.getCaptchaToken(); + await this.resource.__internal_basePost({ path: this.resource.pathRoot, - body: { emailAddress, password }, + body: { + strategy: 'password', + emailAddress, + password, + captchaToken, + captchaWidgetType, + captchaError, + }, }); }); } diff --git a/packages/clerk-js/src/utils/captcha/CaptchaChallenge.ts b/packages/clerk-js/src/utils/captcha/CaptchaChallenge.ts index f7b81bb0f6a..27cf632bc84 100644 --- a/packages/clerk-js/src/utils/captcha/CaptchaChallenge.ts +++ b/packages/clerk-js/src/utils/captcha/CaptchaChallenge.ts @@ -1,3 +1,5 @@ +import type { CaptchaWidgetType } from '@clerk/types'; + import type { Clerk } from '../../core/resources/internal'; import { getCaptchaToken } from './getCaptchaToken'; import { retrieveCaptchaInfo } from './retrieveCaptchaInfo'; @@ -42,7 +44,12 @@ export class CaptchaChallenge { * * Managed challenged start as non-interactive and escalate to interactive if necessary. */ - public async managedOrInvisible(opts?: Partial) { + public async managedOrInvisible( + opts?: Partial, + ): Promise< + | { captchaError?: string; captchaAction?: string; captchaToken?: string; captchaWidgetType?: CaptchaWidgetType } + | undefined + > { const { captchaSiteKey, canUseCaptcha, captchaWidgetType, captchaProvider, captchaPublicKeyInvisible, nonce } = retrieveCaptchaInfo(this.clerk);