recovery-pending.ts

1.7 KB · raw

1// Background-owned state set while the user has just created or rotated a2// vault identity and is confirming their recovery words. It intentionally3// never lives in chrome.storage.local: content scripts can read/write local4// storage unless the browser supports and has applied a trusted-context gate.5// Chrome's session storage is in-memory and trusted-context-only by default;6// Firefox falls back to this background module's memory for the same process.78const KEY = "peach_recovery_pending";9const RECOVERY_CONFIRM_WINDOW_MS = 10 * 60 * 1000;10let inMemoryDeadline = 0;1112function sessionStorage(): chrome.storage.StorageArea | undefined {13  return chrome.storage?.session;14}1516export async function isRecoveryConfirmPending(): Promise<boolean> {17  try {18    const session = sessionStorage();19    if (!session) return inMemoryDeadline > Date.now();20    const out = await session.get(KEY);21    const deadline = (out as Record<string, unknown>)[KEY];22    if (typeof deadline === "number" && deadline > Date.now()) return true;23    await clearRecoveryConfirmPending();24    return false;25  } catch {26    return inMemoryDeadline > Date.now();27  }28}2930export async function setRecoveryConfirmPending(): Promise<void> {31  const deadline = Date.now() + RECOVERY_CONFIRM_WINDOW_MS;32  try {33    const session = sessionStorage();34    if (session) {35      await session.set({ [KEY]: deadline });36      return;37    }38  } catch { /* use the in-memory fallback */ }39  inMemoryDeadline = deadline;40}4142export async function clearRecoveryConfirmPending(): Promise<void> {43  try {44    const session = sessionStorage();45    if (session) {46      await session.remove(KEY);47    }48  } catch { /* best-effort */ }49  inMemoryDeadline = 0;50}