diff options
Diffstat (limited to 'apps/web')
| -rw-r--r-- | apps/web/components/signup/SignUpForm.tsx | 42 | ||||
| -rw-r--r-- | apps/web/lib/clientConfig.tsx | 1 | ||||
| -rw-r--r-- | apps/web/package.json | 1 |
3 files changed, 44 insertions, 0 deletions
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() { <Form {...form}> <form onSubmit={form.handleSubmit(async (value) => { + 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 && ( + <FormField + control={form.control} + name="turnstileToken" + render={({ field }) => ( + <FormItem> + <FormLabel>Verification</FormLabel> + <FormControl> + <Turnstile + siteKey={turnstileSiteKey} + onSuccess={(token) => { + field.onChange(token); + form.clearErrors("turnstileToken"); + }} + onExpire={() => field.onChange("")} + onError={() => { + field.onChange(""); + form.setError("turnstileToken", { + type: "manual", + message: + "Verification failed, please reload the challenge", + }); + }} + /> + </FormControl> + <FormMessage /> + </FormItem> + )} + /> + )} + <ActionButton type="submit" loading={ diff --git a/apps/web/lib/clientConfig.tsx b/apps/web/lib/clientConfig.tsx index 03089e49..9331a7af 100644 --- a/apps/web/lib/clientConfig.tsx +++ b/apps/web/lib/clientConfig.tsx @@ -10,6 +10,7 @@ export const ClientConfigCtx = createContext<ClientConfig>({ 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", |
