"use client"; import { useActionState, useEffect, useState, useTransition } from "react"; import { useRouter } from "next/navigation"; import { Check, KeyRound, Loader2, ShieldCheck, ShieldOff } from "lucide-react"; import { toast } from "sonner"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { disableMfaAction, initialMfaActionState, regenerateRecoveryCodesAction, startMfaEnrollAction, verifyMfaEnrollAction, } from "@/lib/appwrite/mfa-actions"; type EnrollStage = | { kind: "idle" } | { kind: "loading" } | { kind: "verify"; uri: string; secret: string } | { kind: "done"; recoveryCodes: string[] }; export function MfaPanel({ initiallyEnabled }: { initiallyEnabled: boolean }) { const router = useRouter(); const [enabled, setEnabled] = useState(initiallyEnabled); const [stage, setStage] = useState({ kind: "idle" }); const [verifyState, verifyAction, verifying] = useActionState( verifyMfaEnrollAction, initialMfaActionState, ); const [busy, startTransition] = useTransition(); useEffect(() => { if (verifyState.ok && verifyState.recoveryCodes) { setEnabled(true); setStage({ kind: "done", recoveryCodes: verifyState.recoveryCodes }); toast.success("2FA etkinleştirildi."); router.refresh(); } else if (verifyState.error) { toast.error(verifyState.error); } }, [verifyState, router]); function beginEnroll() { setStage({ kind: "loading" }); startTransition(async () => { const res = await startMfaEnrollAction(); if (res.ok && res.uri && res.secret) { setStage({ kind: "verify", uri: res.uri, secret: res.secret }); } else { toast.error(res.error ?? "Başlatılamadı."); setStage({ kind: "idle" }); } }); } function onDisable() { if ( !window.confirm( "2FA devre dışı bırakılsın mı? Hesabınız sadece şifre ile korunacak.", ) ) return; startTransition(async () => { const res = await disableMfaAction(); if (res.ok) { setEnabled(false); setStage({ kind: "idle" }); toast.success("2FA devre dışı bırakıldı."); router.refresh(); } else { toast.error(res.error ?? "Devre dışı bırakılamadı."); } }); } function onRegenerateCodes() { startTransition(async () => { const res = await regenerateRecoveryCodesAction(); if (res.ok && res.recoveryCodes) { setStage({ kind: "done", recoveryCodes: res.recoveryCodes }); toast.success("Yeni yedek kodlar oluşturuldu — eskileri geçersiz."); } else { toast.error(res.error ?? "Üretilemedi."); } }); } if (enabled && stage.kind !== "done") { return (
Aktif Authenticator uygulaması ile giriş yapıyorsunuz.
); } if (stage.kind === "done") { return (

Yedek kodlarınız

Telefonunuza erişiminizi kaybederseniz bu kodlardan biriyle giriş yapabilirsiniz. Her kod tek seferlik. Şimdi güvenli bir yere kaydedin — bu sayfadan çıktığınızda tekrar gösterilmez.

            {stage.recoveryCodes.map((c) => (
              {c}
            ))}
          
); } if (stage.kind === "verify") { const otpauthQrUrl = `https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=${encodeURIComponent(stage.uri)}`; return (
{/* eslint-disable-next-line @next/next/no-img-element */} QR kodu

Authenticator uygulamanızı açın, QR kodu tarayın.

Tarayamıyorsanız bu kodu manuel girin:

{stage.secret}
{verifyState.error && (

{verifyState.error}

)}
); } return (
Pasif Hesabınız yalnızca şifre ile korunuyor.
); }