"use client"; import { useEffect, useState } from "react"; import { useRouter, useSearchParams } from "next/navigation"; import { Notice } from "@/components/ui"; export function MfaView() { const [st, setSt] = useState<{ enrolled: boolean; fresh: boolean; setup: { base32: string; uri: string } | null } | null>(null); const [code, setCode] = useState(""); const [err, setErr] = useState(null); const router = useRouter(); const sp = useSearchParams(); useEffect(() => { fetch("/api/admin/mfa").then((r) => r.json()).then(setSt); }, []); const submit = async () => { setErr(null); const r = await fetch("/api/admin/mfa", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ code, base32: st?.setup?.base32 }) }); if (!r.ok) { setErr("Code invalide"); return; } const next = sp.get("next") && sp.get("next")!.startsWith("/admin") ? sp.get("next")! : "/admin"; router.push(next); router.refresh(); }; if (!st) return

Chargement…

; return (

Vérification forte

{!st.enrolled && st.setup && (

Activer l'application d'authentification

Ajoutez cette clé dans votre application TOTP (1Password, Google Authenticator, Authy…), puis entrez le code généré.

{st.setup.base32}

Ouvrir dans l'application (otpauth://)
)}
{err && {err}}
Le code courriel seul ne suffit pas pour les actions d'administration : un second facteur TOTP est exigé et renouvelé toutes les 30 minutes. Chaque action est journalisée (append-only).
); }