path(); $data = is_file($path) ? json_decode((string) @file_get_contents($path), true) : null; if (! is_array($data)) { return ['configured' => false, 'at' => 0, 'stale' => true]; } $at = (int) ($data['at'] ?? 0); $stale = $at < (time() - self::STALE_AFTER); if (empty($data['configured'])) { return ['configured' => false, 'at' => $at, 'stale' => $stale]; } $peers = []; foreach ((array) ($data['peers'] ?? []) as $p) { if (! is_array($p)) { continue; } $hs = (int) ($p['latest_handshake'] ?? 0); $peers[] = [ 'name' => (string) ($p['name'] ?? ''), 'pubkey' => (string) ($p['pubkey'] ?? ''), 'endpoint' => (string) ($p['endpoint'] ?? ''), 'latest_handshake' => $hs, 'rx' => (int) ($p['rx'] ?? 0), 'tx' => (int) ($p['tx'] ?? 0), 'online' => $hs > (time() - self::ONLINE_WITHIN), ]; } return [ 'configured' => true, 'at' => $at, 'stale' => $stale, 'gate' => [ 'marker' => (bool) ($data['gate']['marker'] ?? false), 'chain' => (bool) ($data['gate']['chain'] ?? false), 'ssh' => (bool) ($data['gate']['ssh'] ?? false), ], 'wg_quick' => (string) ($data['wg_quick'] ?? 'inactive'), 'server' => [ 'subnet' => (string) ($data['server']['subnet'] ?? ''), 'server_ip' => (string) ($data['server']['server_ip'] ?? ''), 'port' => (int) ($data['server']['port'] ?? 0), 'endpoint' => (string) ($data['server']['endpoint'] ?? ''), 'dns' => (string) ($data['server']['dns'] ?? ''), // Not rendered by the page, but part of the /wg-status.json response contract (API consumers). 'pubkey' => (string) ($data['server']['pubkey'] ?? ''), ], 'peers' => $peers, ]; } }