import { useState } from 'react'; import { useMutation } from '@tanstack/react-query'; import { ShieldOff } from 'lucide-react'; import { useTranslation } from 'react-i18next'; import { api, ApiError } from '../api/client'; import { Button } from './Button'; import { useToast } from '../contexts/ToastContext'; import { useAuth } from '../contexts/AuthContext'; interface AdminDisableTwoFactorProps { userId: number; username: string; } /** * Edit user: remove a user's 2FA (TOTP, email codes and backup codes), for a * user locked out of their authenticator. Admin-only, like the route. Not shown * on your own account, which has its own 2FA settings. The route asks for the * admin's own password unless the admin has none (LDAP and OIDC accounts, * unless they were given one). */ export function AdminDisableTwoFactor({ userId, username }: AdminDisableTwoFactorProps) { const { t } = useTranslation(); const { showToast } = useToast(); const { authEnabled, isAdmin, user } = useAuth(); const [confirming, setConfirming] = useState(false); const [password, setPassword] = useState(''); // Set when the route asks for a password the sign-in type did not suggest: // an LDAP or SSO account that was given a local password in Edit user. const [passwordAsked, setPasswordAsked] = useState(false); const needsPassword = passwordAsked || user?.auth_source === 'local'; const disableMutation = useMutation({ mutationFn: () => api.admin2FADisable(userId, needsPassword ? password : null), onSuccess: (response) => { setConfirming(false); setPassword(''); if (response.had_2fa) { showToast(t('users.form.twoFaRemoved', { username }), 'success'); } else { showToast(t('users.form.twoFaNoneToRemove', { username }), 'info'); } }, onError: (error: Error) => { if (!needsPassword && error instanceof ApiError && error.status === 401) { setPasswordAsked(true); showToast(t('users.form.twoFaPasswordNeeded'), 'info'); return; } showToast(error.message, 'error'); }, }); if (!authEnabled || !isAdmin || user?.id === userId) return null; return (
{t('users.form.twoFaTitle')}
{t('users.form.twoFaHint')}