alarms.ts

2.3 KB · raw

1import { ensureSettingsLoaded, getSettings, lock } from "./vault";2import { isRecoveryConfirmPending } from "./recovery-pending";34const AUTO_LOCK_ALARM = "autolock";5const DEFAULT_AUTO_LOCK_MINUTES = 5;6const MIN_IDLE_SECONDS = 15;78function resolveAutoLockMinutes(): number {9  const setting = getSettings().autoLockMinutes;10  if (typeof setting !== "number") return DEFAULT_AUTO_LOCK_MINUTES;11  return setting; // 0 = never12}1314export function touchAutoLock(): void {15  if (!chrome.alarms?.clear || !chrome.alarms?.create) return;16  chrome.alarms.clear(AUTO_LOCK_ALARM);17  const minutes = resolveAutoLockMinutes();18  if (minutes <= 0) return; // "never"19  chrome.alarms.create(AUTO_LOCK_ALARM, { delayInMinutes: minutes });20}2122export function clearAutoLock(): void {23  if (!chrome.alarms?.clear) return;24  chrome.alarms.clear(AUTO_LOCK_ALARM);25}2627export async function setupAutoLock(): Promise<void> {28  await ensureSettingsLoaded();29  if (!chrome.idle?.setDetectionInterval) return;30  const minutes = resolveAutoLockMinutes();31  const seconds = minutes > 0 ? Math.max(MIN_IDLE_SECONDS, minutes * 60) : MIN_IDLE_SECONDS;32  chrome.idle.setDetectionInterval(seconds);33}3435function broadcastLocked(): void {36  // Reach the popup (and any other extension UI context) via runtime.37  chrome.runtime?.sendMessage?.({ type: "VAULT_LOCKED" })?.catch?.(() => {});38  // Reach content scripts via tabs. Tabs without Peach content scripts39  // loaded will reject the sendMessage; ignore those.40  try {41    chrome.tabs.query({}, (tabs) => {42      for (const tab of tabs) {43        if (tab.id === undefined) continue;44        chrome.tabs.sendMessage(tab.id, { type: "VAULT_LOCKED" }).catch(() => {});45      }46    });47  } catch {48    // tabs permission may not be available in all contexts49  }50}5152if (chrome.alarms?.onAlarm?.addListener) {53  chrome.alarms.onAlarm.addListener(async (alarm) => {54    if (alarm.name !== AUTO_LOCK_ALARM) return;55    if (await isRecoveryConfirmPending()) return;56    await lock();57    broadcastLocked();58  });59}6061if (chrome.idle?.onStateChanged) {62  chrome.idle.onStateChanged.addListener(async (state) => {63    if (resolveAutoLockMinutes() <= 0) return;64    if (state !== "idle" && state !== "locked") return;65    if (await isRecoveryConfirmPending()) return;66    await lock();67    broadcastLocked();68  });69}