ba629d89dda6
L12/COR-011: add foreground idle autolock interval for native (Android)
- time
- 2026-05-16 05:26 UTC · 5 months ago
- machine
- koh2
- parent
- 54d245d5cf0f
↓ peach-browser-ba629d89.tar.gzatlas at this save
files changed1 file
src/popup/App.tsx+27 −0src/popup/App.tsx+27 −0
@@ -502,6 +502,33 @@502502 stopSyncPolling();503503 });504504 }505+506+ // L12/COR-011: foreground idle autolock. appStateChange only fires when507+ // the OS backgrounds the app — if the user idles with the screen on,508+ // chrome.alarms is no-op'd in Capacitor so the vault would stay open509+ // indefinitely. Poll every 30s and lock if elapsed since last user510+ // interaction exceeds autoLockMinutes.511+ let lastUserActivityAt = Date.now();512+ const bumpActivity = () => { lastUserActivityAt = Date.now(); };513+ const ACTIVITY_EVENTS = ["touchstart", "click", "keydown", "input"] as const;514+ for (const ev of ACTIVITY_EVENTS) {515+ document.addEventListener(ev, bumpActivity, { passive: true, capture: true });516+ }517+ const idleLockInterval = setInterval(() => {518+ const minutes = autoLockMinutes();519+ if (!minutes || minutes <= 0) return;520+ const elapsed = Date.now() - lastUserActivityAt;521+ if (elapsed >= minutes * 60_000) {522+ lastUserActivityAt = Date.now();523+ handleHeaderLock();524+ }525+ }, 30_000);526+ onCleanup(() => {527+ clearInterval(idleLockInterval);528+ for (const ev of ACTIVITY_EVENTS) {529+ document.removeEventListener(ev, bumpActivity, { capture: true });530+ }531+ });505532 }506533 507534 // Background auto-lock broadcasts VAULT_LOCKED so the popup drops stale