sync-storage.ts

4.2 KB · raw

1import type { TrustedNetwork, PairedDevice } from '../shared/sync-types';23const TRUSTED_NETWORKS_KEY = 'peach_trusted_networks';4const PAIRED_DEVICES_KEY = 'peach_paired_devices';56// ---------------------------------------------------------------------------7// Trusted Networks8// ---------------------------------------------------------------------------910export async function getTrustedNetworks(): Promise<TrustedNetwork[]> {11  try {12    const result = await chrome.storage.local.get(TRUSTED_NETWORKS_KEY);13    return (result as { peach_trusted_networks?: TrustedNetwork[] })[TRUSTED_NETWORKS_KEY] ?? [];14  } catch {15    return [];16  }17}1819export async function addTrustedNetwork(network: TrustedNetwork): Promise<void> {20  try {21    const networks = await getTrustedNetworks();22    networks.push(network);23    await chrome.storage.local.set({ [TRUSTED_NETWORKS_KEY]: networks });24  } catch (err) {25    throw new Error(`Failed to add trusted network: ${err}`);26  }27}2829export async function removeTrustedNetwork(addedAt: number): Promise<void> {30  try {31    const networks = await getTrustedNetworks();32    const filtered = networks.filter((n) => n.addedAt !== addedAt);33    await chrome.storage.local.set({ [TRUSTED_NETWORKS_KEY]: filtered });34  } catch (err) {35    throw new Error(`Failed to remove trusted network: ${err}`);36  }37}3839export async function isCurrentNetworkTrusted(): Promise<boolean> {40  try {41    const networks = await getTrustedNetworks();42    if (networks.length === 0) return false;4344    // eslint-disable-next-line @typescript-eslint/no-explicit-any45    const systemNetwork = (chrome as any).system?.network;46    const interfaces: Array<{ name: string; address: string; prefixLength?: number }> =47      systemNetwork ? await systemNetwork.getNetworkInterfaces() : [];4849    const hasTailscaleIp = interfaces.some((iface) => isTailscaleAddress(iface.address));5051    for (const network of networks) {52      if (network.isTailscale && hasTailscaleIp) return true;53    }5455    return false;56  } catch {57    return false;58  }59}6061function isTailscaleAddress(address: string): boolean {62  const parts = address.split('.').map(Number);63  if (parts.length !== 4 || parts.some(isNaN)) return false;64  const [a, b] = parts;65  return a === 100 && b >= 64 && b <= 127;66}6768// ---------------------------------------------------------------------------69// Paired Devices70// ---------------------------------------------------------------------------7172export async function getPairedDevices(): Promise<PairedDevice[]> {73  try {74    const result = await chrome.storage.local.get(PAIRED_DEVICES_KEY);75    return (result as { peach_paired_devices?: PairedDevice[] })[PAIRED_DEVICES_KEY] ?? [];76  } catch {77    return [];78  }79}8081export async function addPairedDevice(device: PairedDevice): Promise<void> {82  try {83    const devices = await getPairedDevices();84    const exists = devices.some((d) => d.deviceId === device.deviceId);85    if (exists) throw new Error(`Device ${device.deviceId} is already paired`);86    devices.push(device);87    await chrome.storage.local.set({ [PAIRED_DEVICES_KEY]: devices });88  } catch (err) {89    throw new Error(`Failed to add paired device: ${err}`);90  }91}9293export async function removePairedDevice(deviceId: string): Promise<void> {94  try {95    const devices = await getPairedDevices();96    const filtered = devices.filter((d) => d.deviceId !== deviceId);97    await chrome.storage.local.set({ [PAIRED_DEVICES_KEY]: filtered });98  } catch (err) {99    throw new Error(`Failed to remove paired device: ${err}`);100  }101}102103export async function updatePairedDevice(deviceId: string, updates: Partial<PairedDevice>): Promise<void> {104  try {105    const devices = await getPairedDevices();106    const index = devices.findIndex((d) => d.deviceId === deviceId);107    if (index === -1) throw new Error(`Device ${deviceId} not found`);108    devices[index] = { ...devices[index], ...updates, deviceId };109    await chrome.storage.local.set({ [PAIRED_DEVICES_KEY]: devices });110  } catch (err) {111    throw new Error(`Failed to update paired device: ${err}`);112  }113}114115export async function getPairedDevice(deviceId: string): Promise<PairedDevice | undefined> {116  try {117    const devices = await getPairedDevices();118    return devices.find((d) => d.deviceId === deviceId);119  } catch {120    return undefined;121  }122}