From 570436e24b01b9fbfbf0d134ed8eafa6d628d3f9 Mon Sep 17 00:00:00 2001 From: Theodore Li Date: Tue, 7 Apr 2026 12:43:43 -0700 Subject: [PATCH 1/3] fix(signup): fix turnstile key loading --- apps/sim/app/(auth)/signup/signup-form.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/sim/app/(auth)/signup/signup-form.tsx b/apps/sim/app/(auth)/signup/signup-form.tsx index 5573690072..55a0508ec1 100644 --- a/apps/sim/app/(auth)/signup/signup-form.tsx +++ b/apps/sim/app/(auth)/signup/signup-form.tsx @@ -99,7 +99,11 @@ function SignupFormContent({ const [showEmailValidationError, setShowEmailValidationError] = useState(false) const [formError, setFormError] = useState(null) const turnstileRef = useRef(null) - const turnstileSiteKey = useMemo(() => getEnv('NEXT_PUBLIC_TURNSTILE_SITE_KEY'), []) + const [turnstileSiteKey, setTurnstileSiteKey] = useState() + + useEffect(() => { + setTurnstileSiteKey(getEnv('NEXT_PUBLIC_TURNSTILE_SITE_KEY')) + }, []) const redirectUrl = useMemo( () => searchParams.get('redirect') || searchParams.get('callbackUrl') || '', [searchParams] From 5b0ed00127994621df249842ccd8e0242f05b530 Mon Sep 17 00:00:00 2001 From: Theodore Li Date: Tue, 7 Apr 2026 14:36:57 -0700 Subject: [PATCH 2/3] fix(login): fix captcha header passing --- apps/sim/app/(auth)/login/login-form.tsx | 34 +++++++++++++++++++++- apps/sim/app/(auth)/signup/signup-form.tsx | 6 ++-- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/apps/sim/app/(auth)/login/login-form.tsx b/apps/sim/app/(auth)/login/login-form.tsx index 8a43548acb..4ae5a532f8 100644 --- a/apps/sim/app/(auth)/login/login-form.tsx +++ b/apps/sim/app/(auth)/login/login-form.tsx @@ -1,6 +1,7 @@ 'use client' -import { useRef, useState } from 'react' +import { useEffect, useRef, useState } from 'react' +import { Turnstile, type TurnstileInstance } from '@marsidev/react-turnstile' import { createLogger } from '@sim/logger' import { Eye, EyeOff, Loader2 } from 'lucide-react' import Link from 'next/link' @@ -86,6 +87,12 @@ export default function LoginPage({ const [passwordErrors, setPasswordErrors] = useState([]) const [showValidationError, setShowValidationError] = useState(false) const [formError, setFormError] = useState(null) + const turnstileRef = useRef(null) + const [turnstileSiteKey, setTurnstileSiteKey] = useState() + + useEffect(() => { + setTurnstileSiteKey(getEnv('NEXT_PUBLIC_TURNSTILE_SITE_KEY')) + }, []) const callbackUrlParam = searchParams?.get('callbackUrl') const isValidCallbackUrl = callbackUrlParam ? validateCallbackUrl(callbackUrlParam) : false const invalidCallbackRef = useRef(false) @@ -163,6 +170,20 @@ export default function LoginPage({ const safeCallbackUrl = callbackUrl let errorHandled = false + let token: string | undefined + const widget = turnstileRef.current + if (turnstileSiteKey && widget) { + try { + widget.reset() + widget.execute() + token = await widget.getResponsePromise() + } catch { + setFormError('Captcha verification failed. Please try again.') + setIsLoading(false) + return + } + } + setFormError(null) const result = await client.signIn.email( { @@ -171,6 +192,9 @@ export default function LoginPage({ callbackURL: safeCallbackUrl, }, { + headers: { + ...(token ? { 'x-captcha-response': token } : {}), + }, onError: (ctx: any) => { logger.error('Login error:', ctx.error) @@ -441,6 +465,14 @@ export default function LoginPage({ )} + {turnstileSiteKey && ( + + )} + {formError && (

{formError}

diff --git a/apps/sim/app/(auth)/signup/signup-form.tsx b/apps/sim/app/(auth)/signup/signup-form.tsx index 55a0508ec1..14c6de0118 100644 --- a/apps/sim/app/(auth)/signup/signup-form.tsx +++ b/apps/sim/app/(auth)/signup/signup-form.tsx @@ -270,10 +270,8 @@ function SignupFormContent({ name: sanitizedName, }, { - fetchOptions: { - headers: { - ...(token ? { 'x-captcha-response': token } : {}), - }, + headers: { + ...(token ? { 'x-captcha-response': token } : {}), }, onError: (ctx) => { logger.error('Signup error:', ctx.error) From 99bfc998bb46291cc8342d537f352498aef8667a Mon Sep 17 00:00:00 2001 From: Theodore Li Date: Tue, 7 Apr 2026 15:12:36 -0700 Subject: [PATCH 3/3] Catch user already exists, remove login form captcha --- apps/sim/app/(auth)/login/login-form.tsx | 34 +--------------------- apps/sim/app/(auth)/signup/signup-form.tsx | 5 +--- 2 files changed, 2 insertions(+), 37 deletions(-) diff --git a/apps/sim/app/(auth)/login/login-form.tsx b/apps/sim/app/(auth)/login/login-form.tsx index 4ae5a532f8..8a43548acb 100644 --- a/apps/sim/app/(auth)/login/login-form.tsx +++ b/apps/sim/app/(auth)/login/login-form.tsx @@ -1,7 +1,6 @@ 'use client' -import { useEffect, useRef, useState } from 'react' -import { Turnstile, type TurnstileInstance } from '@marsidev/react-turnstile' +import { useRef, useState } from 'react' import { createLogger } from '@sim/logger' import { Eye, EyeOff, Loader2 } from 'lucide-react' import Link from 'next/link' @@ -87,12 +86,6 @@ export default function LoginPage({ const [passwordErrors, setPasswordErrors] = useState([]) const [showValidationError, setShowValidationError] = useState(false) const [formError, setFormError] = useState(null) - const turnstileRef = useRef(null) - const [turnstileSiteKey, setTurnstileSiteKey] = useState() - - useEffect(() => { - setTurnstileSiteKey(getEnv('NEXT_PUBLIC_TURNSTILE_SITE_KEY')) - }, []) const callbackUrlParam = searchParams?.get('callbackUrl') const isValidCallbackUrl = callbackUrlParam ? validateCallbackUrl(callbackUrlParam) : false const invalidCallbackRef = useRef(false) @@ -170,20 +163,6 @@ export default function LoginPage({ const safeCallbackUrl = callbackUrl let errorHandled = false - let token: string | undefined - const widget = turnstileRef.current - if (turnstileSiteKey && widget) { - try { - widget.reset() - widget.execute() - token = await widget.getResponsePromise() - } catch { - setFormError('Captcha verification failed. Please try again.') - setIsLoading(false) - return - } - } - setFormError(null) const result = await client.signIn.email( { @@ -192,9 +171,6 @@ export default function LoginPage({ callbackURL: safeCallbackUrl, }, { - headers: { - ...(token ? { 'x-captcha-response': token } : {}), - }, onError: (ctx: any) => { logger.error('Login error:', ctx.error) @@ -465,14 +441,6 @@ export default function LoginPage({
)} - {turnstileSiteKey && ( - - )} - {formError && (

{formError}

diff --git a/apps/sim/app/(auth)/signup/signup-form.tsx b/apps/sim/app/(auth)/signup/signup-form.tsx index 14c6de0118..afb27cd729 100644 --- a/apps/sim/app/(auth)/signup/signup-form.tsx +++ b/apps/sim/app/(auth)/signup/signup-form.tsx @@ -280,10 +280,7 @@ function SignupFormContent({ let errorCode = 'unknown' if (ctx.error.code?.includes('USER_ALREADY_EXISTS')) { errorCode = 'user_already_exists' - errorMessage.push( - 'An account with this email already exists. Please sign in instead.' - ) - setEmailError(errorMessage[0]) + setEmailError('An account with this email already exists. Please sign in instead.') } else if ( ctx.error.code?.includes('BAD_REQUEST') || ctx.error.message?.includes('Email and password sign up is not enabled')