feat(ext/sw): add session inactivity timer with configurable timeout

Implements a service-worker-side session timer that locks the vault
after a configurable period of inactivity (default 15 min). Supports
two modes: 'inactivity' (timer-based) and 'every_time' (no timer).
Config persists via chrome.storage.local and is exposed through
get_session_config / update_session_config popup messages.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
adlee-was-taken
2026-04-27 02:24:26 -04:00
parent bd13854f59
commit 86621f075f
5 changed files with 192 additions and 1 deletions

View File

@@ -0,0 +1,50 @@
/// Session inactivity timer.
///
/// Two modes:
/// - `inactivity`: fires the expiry callback after N minutes of no
/// resetTimer() calls (i.e. no popup/vault-tab messages).
/// - `every_time`: no timer — the session is cleared on every popup close
/// (handled elsewhere). resetTimer() is a no-op.
import type { SessionTimeoutConfig } from '../shared/messages';
let config: SessionTimeoutConfig = { mode: 'inactivity', minutes: 15 };
let timerId: ReturnType<typeof setTimeout> | null = null;
let expiredCallback: (() => void) | null = null;
/** Register the callback invoked when the inactivity timer fires. */
export function onExpired(cb: () => void): void {
expiredCallback = cb;
}
/** Return the current session timeout config. */
export function getConfig(): SessionTimeoutConfig {
return config;
}
/** Update the config. Also stops any running timer (caller should
* resetTimer() afterwards if the session is still active). */
export function setConfig(c: SessionTimeoutConfig): void {
config = c;
stopTimer();
}
/** Clear and restart the inactivity timer. No-op when mode is `every_time`. */
export function resetTimer(): void {
stopTimer();
if (config.mode !== 'inactivity') return;
const ms = config.minutes * 60 * 1000;
timerId = setTimeout(() => {
timerId = null;
if (expiredCallback) expiredCallback();
}, ms);
}
/** Cancel any pending timer without changing config. */
export function stopTimer(): void {
if (timerId !== null) {
clearTimeout(timerId);
timerId = null;
}
}