import type { TrustedNetwork } from '../shared/sync-types'; import { getTrustedNetworks, addTrustedNetwork as storageAddTrustedNetwork } from './sync-storage'; export interface NetworkInfo { ssid?: string; bssid?: string; isTailscale: boolean; ipAddress?: string; } export function isTailscaleIP(ip: string): boolean { const parts = ip.split('.').map(Number); if (parts.length !== 4 || parts.some(isNaN)) return false; const [a, b] = parts; return a === 100 && b >= 64 && b <= 127; } export async function isOnTailscale(): Promise { try { if (typeof chrome === 'undefined' || !(chrome as unknown as { system?: { network?: { getNetworkInterfaces: () => Promise> } } }).system?.network) return false; const networkApi = (chrome as unknown as { system: { network: { getNetworkInterfaces: () => Promise> } } }).system.network; const interfaces = await networkApi.getNetworkInterfaces(); return interfaces.some((iface) => isTailscaleIP(iface.address)); } catch { return false; } } export async function getCurrentNetwork(): Promise { const info: NetworkInfo = { isTailscale: false }; try { const chromeTyped = chrome as unknown as { system?: { network?: { getNetworkInterfaces: () => Promise> } } }; if (chromeTyped.system?.network) { const networkApi = chromeTyped.system.network; const interfaces = await networkApi.getNetworkInterfaces(); const tailscaleIface = interfaces.find((iface) => isTailscaleIP(iface.address)); if (tailscaleIface) { info.isTailscale = true; info.ipAddress = tailscaleIface.address; } else if (interfaces.length > 0) { info.ipAddress = interfaces[0].address; } } } catch { // Fallback: network info not available } return info; } export async function isCurrentNetworkTrusted(): Promise { try { const networks = await getTrustedNetworks(); if (networks.length === 0) return false; if (typeof chrome !== 'undefined') { const chromeTyped = chrome as unknown as { system?: { network?: { getNetworkInterfaces: () => Promise> } } }; if (chromeTyped.system?.network) { const interfaces = await chromeTyped.system.network.getNetworkInterfaces(); const hasTailscaleIp = interfaces.some((iface) => isTailscaleIP(iface.address)); for (const network of networks) { if (network.isTailscale && hasTailscaleIp) return true; } } } return false; } catch { return false; } } export async function trustCurrentNetwork(): Promise { const network = await getCurrentNetwork(); const trusted: TrustedNetwork = { isTailscale: network.isTailscale, addedAt: Date.now(), }; if (network.ssid) trusted.ssid = network.ssid; if (network.bssid) trusted.bssid = network.bssid; if (network.ipAddress) { trusted.isTailscale = isTailscaleIP(network.ipAddress) || network.isTailscale; } await storageAddTrustedNetwork(trusted); }