From 2a78a4d70d9388649531179ad36956173cf6d4a3 Mon Sep 17 00:00:00 2001 From: Stefanos Anagnostou Date: Wed, 19 Feb 2025 13:34:33 +0200 Subject: [PATCH 1/2] fix(clerk-js): Utilize the property of Turnstile --- .changeset/sixty-ways-melt.md | 5 +++++ packages/clerk-js/src/core/auth/CaptchaHeartbeat.ts | 2 +- packages/clerk-js/src/core/fraudProtection.ts | 2 +- packages/clerk-js/src/core/resources/SignUp.ts | 2 +- packages/clerk-js/src/utils/captcha/CaptchaChallenge.ts | 6 ++++-- packages/clerk-js/src/utils/captcha/turnstile.ts | 7 +++++++ packages/clerk-js/src/utils/captcha/types.ts | 1 + 7 files changed, 20 insertions(+), 5 deletions(-) create mode 100644 .changeset/sixty-ways-melt.md diff --git a/.changeset/sixty-ways-melt.md b/.changeset/sixty-ways-melt.md new file mode 100644 index 00000000000..0dfbf9df4bb --- /dev/null +++ b/.changeset/sixty-ways-melt.md @@ -0,0 +1,5 @@ +--- +'@clerk/clerk-js': patch +--- + +Pass the `action` property to Turnstile diff --git a/packages/clerk-js/src/core/auth/CaptchaHeartbeat.ts b/packages/clerk-js/src/core/auth/CaptchaHeartbeat.ts index 7cedcdcd7d5..bb5ae11ca83 100644 --- a/packages/clerk-js/src/core/auth/CaptchaHeartbeat.ts +++ b/packages/clerk-js/src/core/auth/CaptchaHeartbeat.ts @@ -27,7 +27,7 @@ export class CaptchaHeartbeat { } try { - const params = await this.captchaChallenge.invisible(); + const params = await this.captchaChallenge.invisible({ action: 'heartbeat' }); await this.clerk.client.sendCaptchaToken(params); } catch { // Ignore unhandled errors diff --git a/packages/clerk-js/src/core/fraudProtection.ts b/packages/clerk-js/src/core/fraudProtection.ts index 81055e29cc7..1456c91ee11 100644 --- a/packages/clerk-js/src/core/fraudProtection.ts +++ b/packages/clerk-js/src/core/fraudProtection.ts @@ -62,6 +62,6 @@ export class FraudProtection { } public managedChallenge(clerk: Clerk) { - return new this.CaptchaChallengeImpl(clerk).managedInModal(); + return new this.CaptchaChallengeImpl(clerk).managedInModal({ action: 'verify' }); } } diff --git a/packages/clerk-js/src/core/resources/SignUp.ts b/packages/clerk-js/src/core/resources/SignUp.ts index b55cd110e67..f6ee3777dd7 100644 --- a/packages/clerk-js/src/core/resources/SignUp.ts +++ b/packages/clerk-js/src/core/resources/SignUp.ts @@ -86,7 +86,7 @@ export class SignUp extends BaseResource implements SignUpResource { if (!__BUILD_DISABLE_RHC__ && !this.clientBypass() && !this.shouldBypassCaptchaForAttempt(params)) { const captchaChallenge = new CaptchaChallenge(SignUp.clerk); - const captchaParams = await captchaChallenge.managedOrInvisible(); + const captchaParams = await captchaChallenge.managedOrInvisible({ action: 'signup' }); if (!captchaParams) { throw new ClerkRuntimeError('', { code: 'captcha_unavailable' }); } diff --git a/packages/clerk-js/src/utils/captcha/CaptchaChallenge.ts b/packages/clerk-js/src/utils/captcha/CaptchaChallenge.ts index 8afa872e11e..3f3b5dfe278 100644 --- a/packages/clerk-js/src/utils/captcha/CaptchaChallenge.ts +++ b/packages/clerk-js/src/utils/captcha/CaptchaChallenge.ts @@ -11,7 +11,7 @@ export class CaptchaChallenge { * This will always use the non-interactive variant of the CAPTCHA challenge and will * always use the fallback key. */ - public async invisible() { + public async invisible(opts?: Partial) { const { captchaSiteKey, canUseCaptcha, captchaPublicKeyInvisible } = retrieveCaptchaInfo(this.clerk); if (canUseCaptcha && captchaSiteKey && captchaPublicKeyInvisible) { @@ -20,6 +20,7 @@ export class CaptchaChallenge { invisibleSiteKey: captchaPublicKeyInvisible, widgetType: 'invisible', captchaProvider: 'turnstile', + action: opts?.action, }).catch(e => { if (e.captchaError) { return { captchaError: e.captchaError }; @@ -65,12 +66,13 @@ export class CaptchaChallenge { * Similar to managed() but will render the CAPTCHA challenge in a modal * managed by clerk-js itself. */ - public async managedInModal() { + public async managedInModal(opts?: Partial) { return this.managedOrInvisible({ modalWrapperQuerySelector: '#cl-modal-captcha-wrapper', modalContainerQuerySelector: '#cl-modal-captcha-container', openModal: () => this.clerk.__internal_openBlankCaptchaModal(), closeModal: () => this.clerk.__internal_closeBlankCaptchaModal(), + action: opts?.action, }); } } diff --git a/packages/clerk-js/src/utils/captcha/turnstile.ts b/packages/clerk-js/src/utils/captcha/turnstile.ts index 1d2724cb07d..44734c15c63 100644 --- a/packages/clerk-js/src/utils/captcha/turnstile.ts +++ b/packages/clerk-js/src/utils/captcha/turnstile.ts @@ -58,6 +58,12 @@ interface RenderOptions { * @default 'always' */ appearance?: 'always' | 'execute' | 'interaction-only'; + /** + * A customer value that can be used to differentiate widgets under the same sitekey + * in analytics and which is returned upon validation. This can only contain up to + * 32 alphanumeric characters including _ and -. + */ + action?: string; } interface Turnstile { @@ -166,6 +172,7 @@ export const getTurnstileToken = async (opts: CaptchaOptions) => { const id = captcha.render(widgetContainerQuerySelector, { sitekey: turnstileSiteKey, appearance: 'interaction-only', + action: opts.action, retry: 'never', 'refresh-expired': 'auto', callback: function (token: string) { diff --git a/packages/clerk-js/src/utils/captcha/types.ts b/packages/clerk-js/src/utils/captcha/types.ts index d7cb1eb2c5f..9271baacf4a 100644 --- a/packages/clerk-js/src/utils/captcha/types.ts +++ b/packages/clerk-js/src/utils/captcha/types.ts @@ -9,6 +9,7 @@ export type CaptchaOptions = { modalWrapperQuerySelector?: string; openModal?: () => Promise; closeModal?: () => Promise; + action?: 'verify' | 'signup' | 'heartbeat'; }; export type GetCaptchaTokenReturn = { From 0c2114b95bdb7c9ada5be43c8df36315d4ef938a Mon Sep 17 00:00:00 2001 From: Stefanos Anagnostou Date: Thu, 20 Feb 2025 10:21:45 +0200 Subject: [PATCH 2/2] fix jsdoc --- packages/clerk-js/src/utils/captcha/turnstile.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/clerk-js/src/utils/captcha/turnstile.ts b/packages/clerk-js/src/utils/captcha/turnstile.ts index 44734c15c63..984bdfbc5f3 100644 --- a/packages/clerk-js/src/utils/captcha/turnstile.ts +++ b/packages/clerk-js/src/utils/captcha/turnstile.ts @@ -59,7 +59,7 @@ interface RenderOptions { */ appearance?: 'always' | 'execute' | 'interaction-only'; /** - * A customer value that can be used to differentiate widgets under the same sitekey + * A custom value that can be used to differentiate widgets under the same sitekey * in analytics and which is returned upon validation. This can only contain up to * 32 alphanumeric characters including _ and -. */