From b12c1c3a82941f2767ade8f497db56933415b94d Mon Sep 17 00:00:00 2001 From: Mohamed Bassem Date: Sun, 30 Nov 2025 00:01:07 +0000 Subject: feat: add support for turnstile on signup --- apps/web/components/signup/SignUpForm.tsx | 42 +++++++++++++++++++++++++++++++ apps/web/lib/clientConfig.tsx | 1 + apps/web/package.json | 1 + 3 files changed, 44 insertions(+) (limited to 'apps') diff --git a/apps/web/components/signup/SignUpForm.tsx b/apps/web/components/signup/SignUpForm.tsx index a1e8dadf..bd4a1cf2 100644 --- a/apps/web/components/signup/SignUpForm.tsx +++ b/apps/web/components/signup/SignUpForm.tsx @@ -25,6 +25,7 @@ import { Input } from "@/components/ui/input"; import { useClientConfig } from "@/lib/clientConfig"; import { api } from "@/lib/trpc"; import { zodResolver } from "@hookform/resolvers/zod"; +import { Turnstile } from "@marsidev/react-turnstile"; import { TRPCClientError } from "@trpc/client"; import { AlertCircle, UserX } from "lucide-react"; import { signIn } from "next-auth/react"; @@ -43,11 +44,13 @@ export default function SignUpForm() { name: "", password: "", confirmPassword: "", + turnstileToken: "", }, }); const [errorMessage, setErrorMessage] = useState(""); const router = useRouter(); const clientConfig = useClientConfig(); + const turnstileSiteKey = clientConfig.turnstile?.siteKey; const createUserMutation = api.users.create.useMutation(); @@ -97,6 +100,14 @@ export default function SignUpForm() {
{ + if (turnstileSiteKey && !value.turnstileToken) { + form.setError("turnstileToken", { + type: "manual", + message: "Please complete the verification challenge", + }); + return; + } + form.clearErrors("turnstileToken"); try { await createUserMutation.mutateAsync(value); } catch (e) { @@ -205,6 +216,37 @@ export default function SignUpForm() { )} /> + {turnstileSiteKey && ( + ( + + Verification + + { + field.onChange(token); + form.clearErrors("turnstileToken"); + }} + onExpire={() => field.onChange("")} + onError={() => { + field.onChange(""); + form.setError("turnstileToken", { + type: "manual", + message: + "Verification failed, please reload the challenge", + }); + }} + /> + + + + )} + /> + )} + ({ disableSignups: false, disablePasswordAuth: false, }, + turnstile: null, inference: { isConfigured: false, inferredTagLang: "english", diff --git a/apps/web/package.json b/apps/web/package.json index 67ce2560..0c53490d 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -32,6 +32,7 @@ "@lexical/plain-text": "^0.20.2", "@lexical/react": "^0.20.2", "@lexical/rich-text": "^0.20.2", + "@marsidev/react-turnstile": "^1.3.1", "@radix-ui/react-collapsible": "^1.1.11", "@radix-ui/react-dialog": "^1.1.14", "@radix-ui/react-dropdown-menu": "^2.1.15", -- cgit v1.2.3-70-g09d2