<?php if (!defined('DASHBOARD_ROOT')) { http_response_code(403); exit; } if ($_SERVER['REQUEST_METHOD'] === 'POST' && ($_POST['_nc_meta'] ?? '') !== '') { while (ob_get_level()) { ob_end_clean(); } header('Content-Type: application/json'); CSRF::enforce(); $act = $_POST['_nc_meta']; $nid = preg_replace('/[^a-z0-9_-]/', '', $_POST['node_id'] ?? ''); if (!$nid) { exit(json_encode(['ok'=>false,'error'=>'Missing node_id'])); } $encFields = ['provider','account_email','account_username','account_password','payment_method','card_last4','card_exp','monthly_cost','renewal_date','panel_url','panel_login','ssh_password','root_password','notes']; if ($act === 'load_meta') { RBAC::enforce('decrypt.pii'); $row = Database::fetchOne("SELECT * FROM fleet_node_meta WHERE node_id = :n", [':n' => $nid]); $data = []; if ($row) { foreach ($encFields as $f) { $data[$f] = Encryption::render($row[$f . '_enc'] ?? ''); } } exit(json_encode(['ok'=>true,'data'=>$data,'exists'=>!!$row])); } if ($act === 'save_meta') { RBAC::enforce('manage.settings'); $vals = [':n' => $nid]; $setCols = ['node_id']; $setPlaceholders = [':n']; $updateParts = []; foreach ($encFields as $f) { $raw = $_POST[$f] ?? ''; $enc = $raw !== '' ? Encryption::encrypt($raw, 'default') : ''; $col = $f . '_enc'; $ph = ':' . $f; $vals[$ph] = $enc; $setCols[] = $col; $setPlaceholders[] = $ph; $updateParts[] = "$col = $ph"; } $sql = 'INSERT INTO fleet_node_meta (' . implode(',', $setCols) . ') VALUES (' . implode(',', $setPlaceholders) . ') ON DUPLICATE KEY UPDATE ' . implode(', ', $updateParts); Database::execute($sql, $vals); Events::record(Events::CAT_MODIFY, 'fleet.meta_saved', 'fleet_node_meta', null, ['node_id' => $nid], $_SESSION['admin_id'] ?? 0); exit(json_encode(['ok'=>true])); } exit(json_encode(['ok'=>false,'error'=>'Unknown meta action'])); } $csrf = CSRF::token(); $nodeMap = [ '199335' => ['code'=>'199335','role'=>'dns',     'name'=>'DNS',     'ip'=>'80.78.19.57',     'wg'=>'10.69.69.5', 'os'=>'Ubuntu 24.04', 'loc'=>'Romania',    'provider'=>'Njalla'], '244939' => ['code'=>'244939','role'=>'proxy',   'name'=>'Proxy',   'ip'=>'107.189.23.194',  'wg'=>'10.69.69.3', 'os'=>'AlmaLinux 9',  'loc'=>'Luxembourg', 'provider'=>'Cloudzy'], '333941' => ['code'=>'333941','role'=>'filter',  'name'=>'Filter',  'ip'=>'91.229.239.29',   'wg'=>'10.69.69.4', 'os'=>'AlmaLinux 9',  'loc'=>'Moldova',    'provider'=>'AlexHost'], '414342' => ['code'=>'414342','role'=>'shield',  'name'=>'Shield',  'ip'=>'194.36.190.111',  'wg'=>'10.69.69.1', 'os'=>'AlmaLinux 9',  'loc'=>'Iceland',    'provider'=>'Sailor'], '558201' => ['code'=>'558201','role'=>'origin',  'name'=>'Origin',  'ip'=>'89.127.235.207',  'wg'=>'10.69.69.2', 'os'=>'AlmaLinux 9',  'loc'=>'Romania',    'provider'=>'1984'], '669427' => ['code'=>'669427','role'=>'engine',  'name'=>'Engine',  'ip'=>'76.13.222.157',   'wg'=>'10.69.69.6', 'os'=>'AlmaLinux 9',  'loc'=>'Malaysia',   'provider'=>'Daddy'], '714820' => ['code'=>'714820','role'=>'payment', 'name'=>'Payment', 'ip'=>'45.143.166.118',  'wg'=>'10.69.69.7', 'os'=>'AlmaLinux 9',  'loc'=>'TBD',        'provider'=>'TBD'], '869377' => ['code'=>'869377','role'=>'vault',   'name'=>'Vault',   'ip'=>'104.194.144.66',  'wg'=>'10.69.69.8', 'os'=>'AlmaLinux 9',  'loc'=>'London',     'provider'=>'Cloudzy'], ]; try { $dbNodes = Database::fetchAll("SELECT node_id, node_role, hostname, wg_ip, status FROM nodes ORDER BY id"); foreach ($dbNodes as $d) { foreach ($nodeMap as &$n) { if ($n['role'] === $d['node_role']) { $n['status'] = $d['status'] ?? 'unknown'; $n['hostname'] = $d['hostname'] ?? ''; $n['db_id'] = $d['node_id']; } } unset($n); } } catch (\Throwable $e) {} $serviceMap = [ 'dns'     => ['pdns','nginx','wireguard','sshd','fail2ban'], 'proxy'   => ['nginx','wireguard','sshd','fail2ban','podman'], 'filter'  => ['nginx','wireguard','sshd','fail2ban'], 'shield'  => ['nginx','wireguard','sshd','fail2ban','podman'], 'origin'  => ['nginx','php-fpm','mariadb','wireguard','sshd','fail2ban'], 'engine'  => ['mariadb','postfix','dovecot','opendkim','ollama','wireguard','sshd','fail2ban'], 'payment' => ['nginx','php-fpm','sshd','firewalld'], 'vault'   => ['wireguard','sshd','fail2ban'], ];