mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-22 17:51:12 -05:00
feat: Add CAPTCHA to login
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user