// Pending vouched devices — audit fix MV-7. // // Compatibility reader for pending devices created by older builds. Current // same-vault manifests are admitted directly, but stored requests remain // actionable until the user confirms or rejects them in Settings. // // Storage: chrome.storage.local, same locality rules as paired-devices.ts — // these records contain public keys and must not roam through a third-party // sync back-end. export interface PendingVouchedDevice { deviceId: string; deviceName: string; deviceType: string; longTermPublicKeyHex: string; signingPublicKeyHex: string; wsPort?: number; /** pairedAt claimed by the vouching manifest — carried through on confirm. */ pairedAt: number; receivedAt: number; /** deviceId of the extension whose signed manifest vouched for this device. */ vouchedByDeviceId: string; } const PENDING_KEY = "peach_pending_vouched_devices_v1"; export async function listPendingVouchedDevices(): Promise { try { const result = await chrome.storage.local.get(PENDING_KEY); const value = (result as Record)[PENDING_KEY]; if (!Array.isArray(value)) return []; return value.filter(isPendingVouchedDevice); } catch { return []; } } export async function getPendingVouchedDevice( deviceId: string, ): Promise { const pending = await listPendingVouchedDevices(); return pending.find((d) => d.deviceId === deviceId) ?? null; } export async function removePendingVouchedDevice(deviceId: string): Promise { const pending = await listPendingVouchedDevices(); await chrome.storage.local.set({ [PENDING_KEY]: pending.filter((d) => d.deviceId !== deviceId), }); } function isPendingVouchedDevice(x: unknown): x is PendingVouchedDevice { if (typeof x !== "object" || x === null) return false; const r = x as Record; return ( typeof r.deviceId === "string" && !!r.deviceId && typeof r.deviceName === "string" && typeof r.deviceType === "string" && typeof r.longTermPublicKeyHex === "string" && /^[0-9a-f]{64}$/.test(r.longTermPublicKeyHex as string) && typeof r.signingPublicKeyHex === "string" && /^[0-9a-f]{64}$/.test(r.signingPublicKeyHex as string) && typeof r.receivedAt === "number" && typeof r.vouchedByDeviceId === "string" ); }