Files
reflector-dashboard/auth/my_nodes.php
T

87 lines
2.9 KiB
PHP

<?php
/*
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version. See the LICENSE file for details.
*/
declare(strict_types=1);
require __DIR__ . '/lib.php';
$uuid = require_login();
$me = acct_get($uuid);
$my_calls = acct_all_calls($uuid); // primary + admin-added extra/club calls
$my_email = strtolower(trim($me['email'] ?? ''));
if (!$my_calls && $my_email === '') {
json_out(['ok' => true, 'nodes' => []]);
}
// Fetch reflector status via cURL
$ch = curl_init('http://127.0.0.1:8098/api/status');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 5,
CURLOPT_CONNECTTIMEOUT => 2,
]);
$json = curl_exec($ch);
$err = curl_error($ch);
curl_close($ch);
if ($json === false || $json === '') {
json_out(['ok' => false, 'error' => 'Cannot reach reflector API' . ($err ? ": $err" : '')], 502);
}
$data = json_decode($json, true);
if (!is_array($data) || !isset($data['nodes'])) {
json_out(['ok' => false, 'error' => 'Invalid reflector response'], 502);
}
$r = redis();
// Match nodes belonging to this user
$my_nodes = [];
foreach ($data['nodes'] as $node_call => $node_info) {
// Only LOCAL client nodes: skip remote trunk nodes (other reflectors'
// clients relayed over trunks) and bridge/gateway infrastructure.
if (!empty($node_info['remoteTrunk'])) continue;
if (stripos((string)($node_info['sw'] ?? ''), 'bridge') !== false) continue;
$sysop = strtoupper(trim($node_info['sysop'] ?? ''));
$match = false;
if ($my_calls && $sysop !== '' && in_array($sysop, $my_calls, true)) $match = true;
if (!$match && $my_calls && calls_match_node($my_calls, (string)$node_call)) $match = true;
// Also match if user is a node admin
if (!$match && $my_calls) {
$admins = $r->sMembers(rkey("node_admins:" . strtoupper($node_call)));
if (is_array($admins)) {
foreach ($my_calls as $c) {
if (in_array($c, $admins, true)) { $match = true; break; }
}
}
}
if ($match) {
// Add node admins info — sysop is always default admin
$stored_admins = $r->sMembers(rkey("node_admins:" . strtoupper($node_call)));
if (!is_array($stored_admins)) $stored_admins = [];
$all_admins = $stored_admins;
if ($sysop !== '' && !in_array($sysop, $all_admins, true)) {
array_unshift($all_admins, $sysop);
}
sort($all_admins);
$node_info['node_admins'] = $all_admins;
$my_nodes[$node_call] = $node_info;
}
}
json_out(['ok' => true, 'nodes' => $my_nodes]);