import { useState } from 'react'; import { isWipeOnCloseEnabled, setWipeOnClose } from '../lib/memoryWipeSettings'; import { changePin, type LegacyMigrationReport, regenerateRecoveryCode, resetIdentity, retryLegacyMigration, } from '../lib/userIdentity'; import { PinInput } from './PinInput'; import { ShieldIcon, SpinnerIcon } from './icons'; interface Props { userId: string } export function SecurityCenter({ userId }: Props) { const [pinOld, setPinOld] = useState(''); const [pinNew, setPinNew] = useState(''); const [busy, setBusy] = useState(false); const [msg, setMsg] = useState(null); const [recovery, setRecovery] = useState(null); const [migration, setMigration] = useState(null); const [wipeOnClose, setWipeOnCloseState] = useState(() => isWipeOnCloseEnabled()); async function handleRetryMigration() { setBusy(true); setMsg(null); setMigration(null); try { const report = await retryLegacyMigration(userId); setMigration(report); } catch (err) { setMsg(err instanceof Error ? err.message : String(err)); } finally { setBusy(false); } } async function handleChangePin() { setBusy(true); setMsg(null); try { await changePin({ userId, oldPin: pinOld, newPin: pinNew }); setMsg('PIN geändert.'); setPinOld(''); setPinNew(''); } catch (err) { setMsg(err instanceof Error ? err.message : String(err)); } finally { setBusy(false); } } async function handleRegenerateRecovery() { setBusy(true); setMsg(null); try { setRecovery(await regenerateRecoveryCode({ userId })); } catch (err) { setMsg(err instanceof Error ? err.message : String(err)); } finally { setBusy(false); } } async function handleReset() { if (!window.confirm('Identität wirklich zurücksetzen? Alle bisherigen Chats werden für dich unlesbar.')) return; setBusy(true); setMsg(null); try { const code = await resetIdentity({ userId, pin: pinNew || pinOld }); setRecovery(code); setMsg('Identität zurückgesetzt.'); } catch (err) { setMsg(err instanceof Error ? err.message : String(err)); } finally { setBusy(false); } } return (

Sicherheit

PIN ändern

Recovery-Code

{recovery && (
{recovery}
)}

Schlüssel-Migration reparieren

Versucht, alte Conversation-Schlüssel erneut für deine neue Identität zu re-wrappen. Sicher zu klicken wenn Nachrichten verschlüsselt bleiben oder du nicht senden kannst.

{migration && (
Geräte (Server): {migration.serverDevices}
Lokale Schlüssel im Vault: {migration.strongholdKeysFromServerDevices} {migration.strongholdKeysFromBundleScan > 0 && ( <> (+{migration.strongholdKeysFromBundleScan} aus Bundle-Scan) )}
Versucht: {migration.attempted}, Erfolgreich: {migration.migrated}
Übersprungen (kein lokaler Schlüssel): {migration.noStrongholdKey}
Entschlüsselung gescheitert: {migration.decryptFailed}
Server-Fehler: {migration.rpcFailed}
{migration.attempted > 0 && migration.migrated === 0 && (

Keine Bundles migriert. Vermutlich hast du den ursprünglichen Geräteschlüssel nicht mehr lokal. Nutze "Identität zurücksetzen" wenn du neu starten willst (alte Chats gehen verloren).

)}
)}

Cache beim Schließen leeren

Beim Beenden der App werden alle entschlüsselten Caches gelöscht. Beim nächsten Start musst du wieder deine PIN eingeben. Empfohlen für gemeinsam genutzte Rechner.

Identität zurücksetzen

Erstellt einen neuen Schlüssel. Alle alten Chats werden unlesbar.

{msg &&

{msg}

}
); }