diff --git a/extension/src/popup/components/settings-security.ts b/extension/src/popup/components/settings-security.ts index 9bb6da7..71926be 100644 --- a/extension/src/popup/components/settings-security.ts +++ b/extension/src/popup/components/settings-security.ts @@ -1,17 +1,329 @@ -// extension/src/popup/components/settings-security.ts -// Stub — real implementation provided by Stream C (DEV-C). +/// Security settings section — three-state Recovery QR + Trusted Devices panel. +/// +/// Exported contract: +/// renderSecuritySection(container, sessionHandle): renders into `container` +/// teardownSecuritySection(): removes any open QR modal + +import { sendMessage, escapeHtml } from '../../shared/state'; +import type { Device } from '../../shared/types'; + +// --- Relative time helper --- + +function relativeTime(unixSec: number): string { + const now = Math.floor(Date.now() / 1000); + const diff = now - unixSec; + if (diff < 60) return 'just now'; + if (diff < 3600) return `${Math.floor(diff / 60)}m ago`; + if (diff < 86400) return `${Math.floor(diff / 3600)}h ago`; + if (diff < 2592000) return `${Math.floor(diff / 86400)}d ago`; + return `${Math.floor(diff / 2592000)}mo ago`; +} + +// --- Modal helpers --- + +const MODAL_ID = 'relicario-qr-modal'; + +function removeModal(): void { + document.getElementById(MODAL_ID)?.remove(); +} + +function showQrModal(svgContent: string): void { + removeModal(); + + const overlay = document.createElement('div'); + overlay.id = MODAL_ID; + overlay.style.cssText = [ + 'position:fixed', 'inset:0', 'z-index:9999', + 'background:rgba(0,0,0,0.85)', + 'display:flex', 'flex-direction:column', + 'align-items:center', 'justify-content:center', + 'padding:16px', 'box-sizing:border-box', + ].join(';'); + + overlay.innerHTML = ` +
Scan with the Relicario app to recover your reference image secret.
+ Keep this page in a safe physical location.