DEV-C P2: an active autofiller never opens the popup, so under the old rule it got force-locked despite continuous use. Inverts the rule: reset on all messages except a documented exclusion set (only get_autofill_candidates today). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
65 lines
2.0 KiB
TypeScript
65 lines
2.0 KiB
TypeScript
/// 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;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Content-callable message types that should NOT reset the inactivity timer.
|
|
*
|
|
* Rationale: a content script reading available autofill candidates is a
|
|
* passive query — it shouldn't keep the vault alive indefinitely while the
|
|
* user isn't actually interacting with it.
|
|
*
|
|
* Today this is the only known passive read; if a future content message
|
|
* is also passive, add it here with a one-line justification.
|
|
*/
|
|
export const READ_ONLY_CONTENT_CALLABLE: ReadonlySet<string> = new Set([
|
|
'get_autofill_candidates',
|
|
]);
|