"use client"; import { useState } from "react"; import { Loader2, ShieldCheck, ShieldOff } from "lucide-react"; import { toast } from "sonner"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { authClient, useSession } from "@/lib/auth-client"; export function TwoFactorSetup() { const { data: session } = useSession(); const [isLoading, setIsLoading] = useState(false); const [showEnableDialog, setShowEnableDialog] = useState(false); const [showDisableDialog, setShowDisableDialog] = useState(false); const [password, setPassword] = useState(""); const [totpUri, setTotpUri] = useState(""); const [verificationCode, setVerificationCode] = useState(""); const [backupCodes, setBackupCodes] = useState([]); const [step, setStep] = useState<"password" | "qr" | "verify" | "backup">("password"); const is2FAEnabled = (session?.user as { twoFactorEnabled?: boolean })?.twoFactorEnabled; async function handleEnable() { if (step === "password") { setIsLoading(true); try { const result = await authClient.twoFactor.enable({ password }); if (result.error) { toast.error(result.error.message || "Failed to enable 2FA"); return; } setTotpUri(result.data?.totpURI || ""); setBackupCodes(result.data?.backupCodes || []); setStep("qr"); } catch (error) { toast.error("An error occurred"); } finally { setIsLoading(false); } } else if (step === "verify") { setIsLoading(true); try { const result = await authClient.twoFactor.verifyTotp({ code: verificationCode, }); if (result.error) { toast.error(result.error.message || "Invalid code"); return; } setStep("backup"); toast.success("Two-factor authentication enabled!"); } catch (error) { toast.error("An error occurred"); } finally { setIsLoading(false); } } } async function handleDisable() { setIsLoading(true); try { const result = await authClient.twoFactor.disable({ password }); if (result.error) { toast.error(result.error.message || "Failed to disable 2FA"); return; } toast.success("Two-factor authentication disabled"); setShowDisableDialog(false); setPassword(""); } catch (error) { toast.error("An error occurred"); } finally { setIsLoading(false); } } function resetDialog() { setStep("password"); setPassword(""); setTotpUri(""); setVerificationCode(""); setBackupCodes([]); } return (
{is2FAEnabled ? (

Two-factor authentication is enabled

Your account is protected with an authenticator app

) : (

Two-factor authentication is disabled

Add an extra layer of security to your account

)} {/* Enable 2FA Dialog */} { setShowEnableDialog(open); if (!open) resetDialog(); }}> {step === "password" && "Enable Two-Factor Authentication"} {step === "qr" && "Scan QR Code"} {step === "verify" && "Verify Code"} {step === "backup" && "Save Backup Codes"} {step === "password" && "Enter your password to continue"} {step === "qr" && "Scan this QR code with your authenticator app"} {step === "verify" && "Enter the 6-digit code from your authenticator app"} {step === "backup" && "Save these backup codes in a safe place"} {step === "password" && (
setPassword(e.target.value)} disabled={isLoading} />
)} {step === "qr" && (
{/* QR Code would be rendered here - using a placeholder */}

Scan with your authenticator app or enter manually:

{totpUri}
)} {step === "verify" && (
setVerificationCode(e.target.value)} placeholder="000000" maxLength={6} className="text-center text-2xl tracking-widest" disabled={isLoading} />
)} {step === "backup" && (
{backupCodes.map((code, i) => ( {code} ))}

Each code can only be used once. Store them securely.

)} {step === "backup" ? ( ) : step !== "qr" && ( )}
{/* Disable 2FA Dialog */} Disable Two-Factor Authentication Enter your password to disable two-factor authentication
setPassword(e.target.value)} disabled={isLoading} />
); }