import { useCallback, useEffect, useState, type ReactNode } from "react"; import { useTranslation } from "react-i18next"; import { toast } from "sonner"; import { ShieldOff } from "lucide-react"; import { Button } from "@/components/button"; import { pluginKey } from "@/lib/plugin-i18n"; import { getUserSecondFactors, resetUserSecondFactors, type UserSecondFactorSummary, } from "@/api/auth-methods-api"; /** * Every second factor a user enrolled in, including ones whose plugin is off * (which is what locks a user out), with a reset for all of them. */ export function AdminSecondFactorsSection({ userId, username, heading, requestConfirm, onReset, }: { userId: string; username: string; heading: ReactNode; requestConfirm: (message: string, onConfirm: () => void) => void; onReset: () => void; }) { const { t } = useTranslation(); const [factors, setFactors] = useState([]); const [working, setWorking] = useState(false); const load = useCallback(() => { getUserSecondFactors(userId) .then(setFactors) .catch(() => setFactors([])); }, [userId]); useEffect(() => { load(); }, [load]); async function reset() { setWorking(true); try { await resetUserSecondFactors(userId); toast.success(t("admin.secondFactorsResetSuccess")); onReset(); load(); } catch { toast.error(t("admin.secondFactorsResetFailed")); } finally { setWorking(false); } } return (
{heading} {factors.length === 0 ? ( {t("admin.secondFactorsNone")} ) : (
{factors.map((factor) => (
{factor.labelKey ? t( factor.pluginId === "core" ? factor.labelKey : pluginKey(factor.pluginId, factor.labelKey), { defaultValue: factor.factorId }, ) : factor.factorId} {!factor.available && ( {t("admin.secondFactorUnavailable")} )}
))}
)} {factors.length > 0 && ( )}
); }