sync-network.ts

1.7 KB · raw

1export interface NetworkInfo {2  ssid?: string;3  bssid?: string;4  isTailscale: boolean;5  ipAddress?: string;6}78export function isTailscaleIP(ip: string): boolean {9  const parts = ip.split('.').map(Number);10  if (parts.length !== 4 || parts.some(isNaN)) return false;11  const [a, b] = parts;12  return a === 100 && b >= 64 && b <= 127;13}1415export async function isOnTailscale(): Promise<boolean> {16  try {17    if (typeof chrome === 'undefined' || !(chrome as unknown as { system?: { network?: { getNetworkInterfaces: () => Promise<Array<{ address: string }>> } } }).system?.network) return false;18    const networkApi = (chrome as unknown as { system: { network: { getNetworkInterfaces: () => Promise<Array<{ address: string }>> } } }).system.network;19    const interfaces = await networkApi.getNetworkInterfaces();20    return interfaces.some((iface) => isTailscaleIP(iface.address));21  } catch {22    return false;23  }24}2526export async function getCurrentNetwork(): Promise<NetworkInfo> {27  const info: NetworkInfo = { isTailscale: false };2829  try {30    const chromeTyped = chrome as unknown as { system?: { network?: { getNetworkInterfaces: () => Promise<Array<{ address: string; name?: string }>> } } };31    if (chromeTyped.system?.network) {32      const networkApi = chromeTyped.system.network;33      const interfaces = await networkApi.getNetworkInterfaces();34      const tailscaleIface = interfaces.find((iface) => isTailscaleIP(iface.address));35      if (tailscaleIface) {36        info.isTailscale = true;37        info.ipAddress = tailscaleIface.address;38      } else if (interfaces.length > 0) {39        info.ipAddress = interfaces[0].address;40      }41    }42  } catch {43    // Fallback: network info not available44  }4546  return info;47}