123456789101112export interface SyncAlert {13 type: "DEVICE_KEY_ROTATED" | "DEVICE_REVOKED";14 151617 entryId: string;18 entryTitle: string;19 2021 deviceName: string;22 timestamp: number;23}2425const SYNC_ALERTS_KEY = "peach_pending_sync_alerts_v1";2627const MAX_PENDING_ALERTS = 200;2829export async function recordSyncAlerts(alerts: SyncAlert[]): Promise<void> {30 const securityAlerts = alerts.filter(isSyncAlert);31 if (securityAlerts.length === 0) return;32 const existing = await readAlerts();33 const merged = [...existing, ...securityAlerts].slice(-MAX_PENDING_ALERTS);34 try {35 await chrome.storage.local.set({ [SYNC_ALERTS_KEY]: merged });36 } catch {37 38 }39}4041export async function getPendingSyncAlerts(): Promise<SyncAlert[]> {42 return readAlerts();43}4445export async function clearPendingSyncAlerts(): Promise<void> {46 try {47 await chrome.storage.local.remove(SYNC_ALERTS_KEY);48 } catch {49 50 }51}5253async function readAlerts(): Promise<SyncAlert[]> {54 try {55 const result = await chrome.storage.local.get(SYNC_ALERTS_KEY);56 const value = (result as Record<string, unknown>)[SYNC_ALERTS_KEY];57 if (!Array.isArray(value)) return [];58 return value.filter(isSyncAlert);59 } catch {60 return [];61 }62}6364function isSyncAlert(x: unknown): x is SyncAlert {65 if (typeof x !== "object" || x === null) return false;66 const r = x as Record<string, unknown>;67 return (68 (r.type === "DEVICE_KEY_ROTATED" ||69 r.type === "DEVICE_REVOKED") &&70 typeof r.entryId === "string" &&71 typeof r.entryTitle === "string" &&72 typeof r.deviceName === "string" &&73 typeof r.timestamp === "number"74 );75}