"use client"; import React, { useState } from "react"; export default function UserSettingsPage() { const [mfaEnabled, setMfaEnabled] = useState(false); const [qrSecret, setQrSecret] = useState(null); const [qrUri, setQrUri] = useState(null); const [totpCode, setTotpCode] = useState(""); const [recoveryCodes, setRecoveryCodes] = useState(null); const [appPasswords, setAppPasswords] = useState<{ id: string; label: string; created: string }[]>([]); const [newAppPassLabel, setNewAppPassLabel] = useState(""); const [generatedAppPass, setGeneratedAppPass] = useState(null); const [message, setMessage] = useState(null); const startTotpEnrollment = async () => { try { const res = await fetch("/api/v1/user/mfa/totp/enroll", { method: "POST" }); const data = await res.json(); setQrSecret(data.secret); setQrUri(data.uri); } catch { setMessage("Failed to initiate 2FA enrollment"); } }; const confirmTotpEnrollment = async (e: React.FormEvent) => { e.preventDefault(); try { const res = await fetch("/api/v1/user/mfa/totp/confirm", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ secret: qrSecret, code: totpCode }), }); const data = await res.json(); if (!res.ok) throw new Error(data.message || "TOTP verification failed"); setMfaEnabled(true); setRecoveryCodes(data.recovery_codes); setQrSecret(null); setMessage("2FA successfully enabled! Save your recovery codes."); } catch (err: unknown) { setMessage(err instanceof Error ? err.message : "Error confirming 2FA"); } }; const createNewAppPassword = (e: React.FormEvent) => { e.preventDefault(); if (!newAppPassLabel) return; const rawPass = `lmp_${Math.random().toString(36).substring(2, 10)}-${Math.random().toString(36).substring(2, 10)}`; setAppPasswords([...appPasswords, { id: Date.now().toString(), label: newAppPassLabel, created: "Just now" }]); setGeneratedAppPass(rawPass); setNewAppPassLabel(""); }; return (

Security & Account Settings

Manage 2FA TOTP (RFC 6238), App Passwords, and active webmail sessions.

{message && (
{message}
)} {/* 2FA TOTP SECTION */}

Two-Factor Authentication (TOTP RFC 6238)

Protect your webmail session with Google Authenticator, Aegis, Authy, or 1Password.

{mfaEnabled ? "2FA ENABLED" : "2FA DISABLED"}
{!mfaEnabled && !qrSecret && ( )} {qrSecret && (
Step 1: Scan this URI in your authenticator app or copy the secret key.
Secret: {qrSecret}
URI: {qrUri}
setTotpCode(e.target.value)} placeholder="Enter 6-digit code" maxLength={6} required className="px-4 py-2 rounded-lg bg-slate-950 border border-slate-800 text-white text-xs font-mono text-center tracking-wider focus:outline-none focus:border-indigo-500" />
)} {recoveryCodes && (

10 Recovery Codes (Argon2id Hashed)

Store these recovery codes in a safe password manager. Each code can be used once.

{recoveryCodes.map((code, idx) => (
{code}
))}
)}
{/* APP PASSWORDS SECTION (ADR-010) */}

App Passwords (IMAP / SMTP Clients)

Thunderbird, iOS Mail, and Android clients do not support 2FA. Generate dedicated high-entropy passwords for IMAP/SMTP.

setNewAppPassLabel(e.target.value)} placeholder="App Label (e.g. Thunderbird Laptop)" required className="flex-1 px-4 py-2 text-xs rounded-lg bg-slate-900 border border-slate-800 text-white placeholder-slate-500 focus:outline-none focus:border-indigo-500" />
{generatedAppPass && (
App Password Generated:
{generatedAppPass}

Copy this password now. It will not be shown again.

)}
{appPasswords.length === 0 ? (
No app passwords generated yet.
) : ( appPasswords.map((ap) => (
{ap.label} Created: {ap.created}
Revoke
)) )}
{/* ACTIVE SESSIONS SECTION */}

Active Webmail Sessions

Individually revocable sessions with surface isolation.

Current Webmail Browser Session
Cookie: Path=/user | Aud: lambdamail:user
ACTIVE
); }