1234567891011121314export interface SyncAlert {15 type:16 | "REMOTE_PASSWORD_CHANGE"17 | "REMOTE_DELETE"18 | "DEVICE_KEY_ROTATED"19 | "DEVICE_REVOKED";20 212223 entryId: string;24 entryTitle: string;25 2627 deviceName: string;28 timestamp: number;29}3031const SYNC_ALERTS_KEY = "peach_pending_sync_alerts_v1";3233const MAX_PENDING_ALERTS = 200;3435export async function recordSyncAlerts(alerts: SyncAlert[]): Promise<void> {36 if (alerts.length === 0) return;37 const existing = await readAlerts();38 const merged = [...existing, ...alerts].slice(-MAX_PENDING_ALERTS);39 try {40 await chrome.storage.local.set({ [SYNC_ALERTS_KEY]: merged });41 } catch {42 43 }44}4546export async function getPendingSyncAlerts(): Promise<SyncAlert[]> {47 return readAlerts();48}4950export async function clearPendingSyncAlerts(): Promise<void> {51 try {52 await chrome.storage.local.remove(SYNC_ALERTS_KEY);53 } catch {54 55 }56}5758async function readAlerts(): Promise<SyncAlert[]> {59 try {60 const result = await chrome.storage.local.get(SYNC_ALERTS_KEY);61 const value = (result as Record<string, unknown>)[SYNC_ALERTS_KEY];62 if (!Array.isArray(value)) return [];63 return value.filter(isSyncAlert);64 } catch {65 return [];66 }67}6869function isSyncAlert(x: unknown): x is SyncAlert {70 if (typeof x !== "object" || x === null) return false;71 const r = x as Record<string, unknown>;72 return (73 (r.type === "REMOTE_PASSWORD_CHANGE" ||74 r.type === "REMOTE_DELETE" ||75 r.type === "DEVICE_KEY_ROTATED" ||76 r.type === "DEVICE_REVOKED") &&77 typeof r.entryId === "string" &&78 typeof r.entryTitle === "string" &&79 typeof r.deviceName === "string" &&80 typeof r.timestamp === "number"81 );82}