From 3b38aec5dd11aa009539e0cd3bef2542ad43a06e Mon Sep 17 00:00:00 2001 From: Nikos Douvlis Date: Fri, 15 Nov 2024 11:28:33 +0200 Subject: [PATCH] fix(clerk-js): Correctly handle async requires_captcha error --- packages/clerk-js/src/core/resources/Session.ts | 2 +- packages/clerk-js/src/core/resources/SignUp.ts | 6 +++--- packages/clerk-js/src/utils/captcha/getCaptchaToken.ts | 4 ++-- packages/clerk-js/src/utils/captcha/hcaptcha.ts | 3 ++- packages/clerk-js/src/utils/captcha/turnstile.ts | 10 +++++----- packages/clerk-js/src/utils/captcha/types.ts | 5 +++++ 6 files changed, 18 insertions(+), 12 deletions(-) diff --git a/packages/clerk-js/src/core/resources/Session.ts b/packages/clerk-js/src/core/resources/Session.ts index 51327c3f2d..a687388cb0 100644 --- a/packages/clerk-js/src/core/resources/Session.ts +++ b/packages/clerk-js/src/core/resources/Session.ts @@ -274,7 +274,7 @@ export class Session extends BaseResource implements SessionResource { const createTokenWithCaptchaProtection = async () => { try { - return Token.create(path, params); + return await Token.create(path, params); } catch (e) { if (isClerkAPIResponseError(e) && e.errors[0].code === 'requires_captcha') { const captchaParams = await this.#triggerCaptchaChallenge(); diff --git a/packages/clerk-js/src/core/resources/SignUp.ts b/packages/clerk-js/src/core/resources/SignUp.ts index d003904bcf..85b123ca34 100644 --- a/packages/clerk-js/src/core/resources/SignUp.ts +++ b/packages/clerk-js/src/core/resources/SignUp.ts @@ -90,15 +90,15 @@ export class SignUp extends BaseResource implements SignUpResource { captchaPublicKeyInvisible ) { try { - const { captchaToken, captchaWidgetTypeUsed } = await getCaptchaToken({ + const captchaParams = await getCaptchaToken({ siteKey: captchaSiteKey, widgetType: captchaWidgetType, invisibleSiteKey: captchaPublicKeyInvisible, scriptUrl: captchaURL, captchaProvider, }); - paramsWithCaptcha.captchaToken = captchaToken; - paramsWithCaptcha.captchaWidgetType = captchaWidgetTypeUsed; + paramsWithCaptcha.captchaToken = captchaParams.captchaToken; + paramsWithCaptcha.captchaWidgetType = captchaParams.captchaWidgetType; } catch (e) { if (e.captchaError) { paramsWithCaptcha.captchaError = e.captchaError; diff --git a/packages/clerk-js/src/utils/captcha/getCaptchaToken.ts b/packages/clerk-js/src/utils/captcha/getCaptchaToken.ts index 5bb407fb50..9003d1ea5a 100644 --- a/packages/clerk-js/src/utils/captcha/getCaptchaToken.ts +++ b/packages/clerk-js/src/utils/captcha/getCaptchaToken.ts @@ -1,11 +1,11 @@ import { getHCaptchaToken } from './hcaptcha'; import { getTurnstileToken } from './turnstile'; -import type { CaptchaOptions } from './types'; +import type { CaptchaOptions, GetCaptchaTokenReturn } from './types'; /* * This is a temporary solution to test different captcha providers, until we decide on a single one. */ -export const getCaptchaToken = (opts: CaptchaOptions) => { +export const getCaptchaToken = (opts: CaptchaOptions): Promise => { if (opts.captchaProvider === 'hcaptcha') { return getHCaptchaToken(opts); } else { diff --git a/packages/clerk-js/src/utils/captcha/hcaptcha.ts b/packages/clerk-js/src/utils/captcha/hcaptcha.ts index 79bd42269c..8f74f2d66c 100644 --- a/packages/clerk-js/src/utils/captcha/hcaptcha.ts +++ b/packages/clerk-js/src/utils/captcha/hcaptcha.ts @@ -1,6 +1,7 @@ /// import { loadScript } from '@clerk/shared/loadScript'; +import type { CaptchaWidgetType } from '@clerk/types'; import { CAPTCHA_ELEMENT_ID, CAPTCHA_INVISIBLE_CLASSNAME } from './constants'; import type { CaptchaOptions } from './types'; @@ -115,5 +116,5 @@ export const getHCaptchaToken = async (captchaOptions: CaptchaOptions) => { } } - return { captchaToken, captchaWidgetTypeUsed: isInvisibleWidget ? 'invisible' : 'smart' }; + return { captchaToken, captchaWidgetType: (isInvisibleWidget ? 'invisible' : 'smart') as CaptchaWidgetType }; }; diff --git a/packages/clerk-js/src/utils/captcha/turnstile.ts b/packages/clerk-js/src/utils/captcha/turnstile.ts index 7edd403638..37f07c8c7e 100644 --- a/packages/clerk-js/src/utils/captcha/turnstile.ts +++ b/packages/clerk-js/src/utils/captcha/turnstile.ts @@ -129,14 +129,14 @@ export const getTurnstileToken = async (opts: CaptchaOptions) => { let retries = 0; let widgetContainerQuerySelector: string | undefined; // The backend uses this to determine which Turnstile site-key was used in order to verify the token - let captchaWidgetTypeUsed: CaptchaWidgetType = null; + let captchaWidgetType: CaptchaWidgetType = null; // modal if (modalContainerQuerySelector && modalWrapperQuerySelector) { // if invisible is selected but modal is provided, // we're going to render the invisible widget in the modal // but we won't show the modal as it will never escalate to interactive mode - captchaWidgetTypeUsed = widgetType; + captchaWidgetType = widgetType; widgetContainerQuerySelector = modalContainerQuerySelector; await openModal?.(); await waitForElement(modalContainerQuerySelector); @@ -146,7 +146,7 @@ export const getTurnstileToken = async (opts: CaptchaOptions) => { if (!widgetContainerQuerySelector && widgetType === 'smart') { const visibleDiv = document.getElementById(CAPTCHA_ELEMENT_ID); if (visibleDiv) { - captchaWidgetTypeUsed = 'smart'; + captchaWidgetType = 'smart'; widgetContainerQuerySelector = `#${CAPTCHA_ELEMENT_ID}`; visibleDiv.style.display = 'block'; } else { @@ -159,7 +159,7 @@ export const getTurnstileToken = async (opts: CaptchaOptions) => { // invisible widget for which we create the container automatically if (!widgetContainerQuerySelector) { turnstileSiteKey = invisibleSiteKey; - captchaWidgetTypeUsed = 'invisible'; + captchaWidgetType = 'invisible'; widgetContainerQuerySelector = `.${CAPTCHA_INVISIBLE_CLASSNAME}`; const div = document.createElement('div'); div.classList.add(CAPTCHA_INVISIBLE_CLASSNAME); @@ -242,5 +242,5 @@ export const getTurnstileToken = async (opts: CaptchaOptions) => { } } - return { captchaToken, captchaWidgetTypeUsed: captchaWidgetTypeUsed }; + return { captchaToken, captchaWidgetType }; }; diff --git a/packages/clerk-js/src/utils/captcha/types.ts b/packages/clerk-js/src/utils/captcha/types.ts index fed812467c..ac38b190ed 100644 --- a/packages/clerk-js/src/utils/captcha/types.ts +++ b/packages/clerk-js/src/utils/captcha/types.ts @@ -11,3 +11,8 @@ export type CaptchaOptions = { openModal?: () => Promise; closeModal?: () => Promise; }; + +export type GetCaptchaTokenReturn = { + captchaToken: string; + captchaWidgetType: CaptchaWidgetType; +};