my own status page
at main 41 lines 978 B view raw
1import type { Env } from "./types"; 2 3interface TailscaleDevice { 4 hostname: string; 5 connectedToControl: boolean; 6 lastSeen: string; 7 os: string; 8} 9 10const KV_KEY = "tailscale_devices"; 11 12export async function refreshDevices(env: Env): Promise<void> { 13 if (!env.TAILSCALE_API_KEY) return; 14 15 const res = await fetch( 16 "https://api.tailscale.com/api/v2/tailnet/-/devices?fields=default", 17 { 18 headers: { 19 Authorization: `Bearer ${env.TAILSCALE_API_KEY}`, 20 }, 21 }, 22 ); 23 24 if (!res.ok) return; 25 26 const data: { devices: TailscaleDevice[] } = await res.json(); 27 await env.KV.put(KV_KEY, JSON.stringify(data.devices)); 28} 29 30export async function getDeviceStatus( 31 env: Env, 32 hostname: string, 33): Promise<boolean> { 34 const cached = await env.KV.get(KV_KEY, "json"); 35 if (!cached) return false; 36 const devices = cached as TailscaleDevice[]; 37 const device = devices.find( 38 (d) => d.hostname.toLowerCase() === hostname.toLowerCase(), 39 ); 40 return device?.connectedToControl ?? false; 41}