import { useEffect, useState } from 'react' import api from '../utils/api' /** * TOTP einrichten: QR-Code und Geheimnis anzeigen, Code bestätigen, Wiederherstellungscodes einmal zeigen. */ export default function TotpSetupCard({ onEnabled }) { const [secret, setSecret] = useState('') const [otpauthUri, setOtpauthUri] = useState('') const [qrDataUrl, setQrDataUrl] = useState('') const [code, setCode] = useState('') const [recoveryCodes, setRecoveryCodes] = useState([]) const [error, setError] = useState('') const [busy, setBusy] = useState(false) useEffect(() => { if (!otpauthUri) { setQrDataUrl('') return undefined } let cancelled = false import('qrcode') .then((mod) => { const QRCode = typeof mod.toDataURL === 'function' ? mod : mod.default return QRCode.toDataURL(otpauthUri, { width: 240, margin: 2, errorCorrectionLevel: 'M', color: { dark: '#000000', light: '#ffffff' }, }) }) .then((url) => { if (!cancelled) setQrDataUrl(url) }) .catch(() => { if (!cancelled) setQrDataUrl('') }) return () => { cancelled = true } }, [otpauthUri]) const start = async () => { setError('') setBusy(true) try { const data = await api.setupTotp() setSecret(data.secret || '') setOtpauthUri(data.otpauth_uri || '') setRecoveryCodes([]) } catch (err) { setError(err.message || 'Einrichtung fehlgeschlagen') } finally { setBusy(false) } } const confirm = async (e) => { e.preventDefault() setError('') setBusy(true) try { const data = await api.confirmTotp(code.trim()) if (data?.token) localStorage.setItem('authToken', data.token) setRecoveryCodes(Array.isArray(data?.recovery_codes) ? data.recovery_codes : []) setSecret('') setOtpauthUri('') setCode('') } catch (err) { setError(err.message || 'Code nicht akzeptiert') } finally { setBusy(false) } } return (

Zwei-Faktor-Anmeldung

Authenticator-App öffnen, ein Konto hinzufügen und den QR-Code scannen. Wenn das Scannen nicht klappt, das Geheimnis darunter manuell eintragen.

{error ? (

{error}

) : null} {!secret && recoveryCodes.length === 0 ? ( ) : null} {secret ? (
{qrDataUrl ? (
QR-Code zum Einrichten in der Authenticator-App
) : null}

{secret}

setCode(e.target.value)} />
) : null} {recoveryCodes.length > 0 ? (

Diese acht Codes jetzt sichern. Die Seite bleibt stehen, bis du unten bestätigst. Ein Neuladen löscht die Anzeige. Neue Codes kannst du danach in den Einstellungen erzeugen.