feat: Add CAPTCHA to login

This commit is contained in:
gpt-engineer-app[bot]
2025-09-29 02:51:23 +00:00
parent 974a55b2e0
commit 8248242c55

View File

@@ -23,6 +23,8 @@ export default function Auth() {
const [showPassword, setShowPassword] = useState(false); const [showPassword, setShowPassword] = useState(false);
const [captchaToken, setCaptchaToken] = useState<string | null>(null); const [captchaToken, setCaptchaToken] = useState<string | null>(null);
const [captchaKey, setCaptchaKey] = useState(0); const [captchaKey, setCaptchaKey] = useState(0);
const [signInCaptchaToken, setSignInCaptchaToken] = useState<string | null>(null);
const [signInCaptchaKey, setSignInCaptchaKey] = useState(0);
const [formData, setFormData] = useState({ const [formData, setFormData] = useState({
email: '', email: '',
password: '', password: '',
@@ -40,13 +42,28 @@ export default function Auth() {
const handleSignIn = async (e: React.FormEvent) => { const handleSignIn = async (e: React.FormEvent) => {
e.preventDefault(); e.preventDefault();
setLoading(true); setLoading(true);
// Validate CAPTCHA
if (!signInCaptchaToken) {
toast({
variant: "destructive",
title: "CAPTCHA required",
description: "Please complete the CAPTCHA verification."
});
setLoading(false);
return;
}
try { try {
const { const {
data, data,
error error
} = await supabase.auth.signInWithPassword({ } = await supabase.auth.signInWithPassword({
email: formData.email, email: formData.email,
password: formData.password password: formData.password,
options: {
captchaToken: signInCaptchaToken
}
}); });
if (error) throw error; if (error) throw error;
toast({ toast({
@@ -56,6 +73,10 @@ export default function Auth() {
const redirectTo = searchParams.get('redirect') || '/'; const redirectTo = searchParams.get('redirect') || '/';
navigate(redirectTo); navigate(redirectTo);
} catch (error: any) { } catch (error: any) {
// Reset CAPTCHA on error
setSignInCaptchaToken(null);
setSignInCaptchaKey(prev => prev + 1);
toast({ toast({
variant: "destructive", variant: "destructive",
title: "Sign in failed", title: "Sign in failed",
@@ -248,7 +269,24 @@ export default function Auth() {
</div> </div>
</div> </div>
<Button type="submit" className="w-full bg-accent hover:bg-accent/90 text-accent-foreground" disabled={loading}> <div className="space-y-2">
<Label>Security Verification</Label>
<TurnstileCaptcha
key={signInCaptchaKey}
onSuccess={setSignInCaptchaToken}
onError={() => setSignInCaptchaToken(null)}
onExpire={() => setSignInCaptchaToken(null)}
siteKey={import.meta.env.VITE_TURNSTILE_SITE_KEY}
theme="auto"
className="flex justify-center"
/>
</div>
<Button
type="submit"
className="w-full bg-accent hover:bg-accent/90 text-accent-foreground"
disabled={loading || !signInCaptchaToken}
>
{loading ? "Signing in..." : "Sign In"} {loading ? "Signing in..." : "Sign In"}
</Button> </Button>
</form> </form>