First push

This commit is contained in:
2026-03-11 10:14:26 -04:00
parent eaf4dbbc3b
commit 20ed0eeadb
11 changed files with 1333 additions and 1 deletions

167
nodes.php Normal file
View File

@@ -0,0 +1,167 @@
<?php
require_once __DIR__ . '/includes/functions.php';
$errors = [];
$success = '';
// ── Handle POST ───────────────────────────────────────────────────────────────
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$action = $_POST['action'] ?? '';
if ($action === 'delete') {
$id = (int)($_POST['id'] ?? 0);
if ($id > 0) {
delete_node($id);
$success = 'Node deleted.';
}
} elseif (in_array($action, ['add', 'edit'], true)) {
$id = $action === 'edit' ? (int)($_POST['id'] ?? 0) : null;
$data = [
'name' => trim($_POST['name'] ?? ''),
'api_url' => rtrim(trim($_POST['api_url'] ?? ''), '/'),
'username' => trim($_POST['username'] ?? 'admin'),
'password' => $_POST['password'] ?? '',
'verify_ssl' => isset($_POST['verify_ssl']) ? 1 : 0,
'enabled' => isset($_POST['enabled']) ? 1 : 0,
];
if ($data['name'] === '') $errors[] = 'Name is required.';
if ($data['api_url'] === '') $errors[] = 'API URL is required.';
if ($data['password'] === '' && $action === 'add') $errors[] = 'Password is required.';
// On edit, keep existing password if field left blank
if ($action === 'edit' && $data['password'] === '') {
$existing = get_node($id);
$data['password'] = $existing['password'] ?? '';
}
if (empty($errors)) {
upsert_node($data, $id);
$success = $action === 'add' ? 'Node added.' : 'Node updated.';
}
}
}
$nodes = get_all_nodes();
$edit_node = null;
if (isset($_GET['edit'])) {
$edit_node = get_node((int)$_GET['edit']);
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Nodes portspoof concentrator</title>
<style>
<?php include __DIR__ . '/includes/style.php'; ?>
</style>
</head>
<body>
<header>
<h1>portspoof<span>concentrator</span></h1>
<nav>
<a href="index.php">Dashboard</a>
<a href="nodes.php" class="active">Nodes</a>
</nav>
</header>
<main>
<?php if ($success): ?>
<div class="alert ok"><?= h($success) ?></div>
<?php endif; ?>
<?php foreach ($errors as $e): ?>
<div class="alert err"><?= h($e) ?></div>
<?php endforeach; ?>
<section class="card">
<h2><?= $edit_node ? 'Edit node' : 'Add node' ?></h2>
<form method="post">
<input type="hidden" name="action" value="<?= $edit_node ? 'edit' : 'add' ?>">
<?php if ($edit_node): ?>
<input type="hidden" name="id" value="<?= (int)$edit_node['id'] ?>">
<?php endif; ?>
<label>Name
<input type="text" name="name" required
value="<?= h($edit_node['name'] ?? '') ?>">
</label>
<label>API URL &nbsp;<small>e.g. https://192.168.1.10:8080</small>
<input type="url" name="api_url" required
value="<?= h($edit_node['api_url'] ?? '') ?>">
</label>
<label>Username
<input type="text" name="username"
value="<?= h($edit_node['username'] ?? 'admin') ?>">
</label>
<label>Password <?= $edit_node ? '<small>(leave blank to keep current)</small>' : '' ?>
<input type="password" name="password" <?= $edit_node ? '' : 'required' ?>>
</label>
<label class="inline">
<input type="checkbox" name="verify_ssl"
<?= ($edit_node['verify_ssl'] ?? 0) ? 'checked' : '' ?>>
Verify SSL certificate
</label>
<label class="inline">
<input type="checkbox" name="enabled"
<?= ($edit_node['enabled'] ?? 1) ? 'checked' : '' ?>>
Enabled
</label>
<button type="submit"><?= $edit_node ? 'Save changes' : 'Add node' ?></button>
<?php if ($edit_node): ?>
&nbsp;<a href="nodes.php">Cancel</a>
<?php endif; ?>
</form>
</section>
<section class="card">
<h2>Configured nodes</h2>
<?php if (empty($nodes)): ?>
<p class="muted">No nodes yet. Add one above.</p>
<?php else: ?>
<table>
<thead>
<tr>
<th>Name</th>
<th>API URL</th>
<th>SSL verify</th>
<th>Enabled</th>
<th>Last fetched</th>
<th></th>
</tr>
</thead>
<tbody>
<?php foreach ($nodes as $n): ?>
<tr>
<td><?= h($n['name']) ?></td>
<td><code><?= h($n['api_url']) ?></code></td>
<td><?= $n['verify_ssl'] ? 'yes' : 'no' ?></td>
<td><?= $n['enabled'] ? '<span class="badge ok">yes</span>' : '<span class="badge">no</span>' ?></td>
<td><?= $n['last_fetched_at'] ? h($n['last_fetched_at']) : '<span class="muted">never</span>' ?></td>
<td class="actions">
<a href="nodes.php?edit=<?= (int)$n['id'] ?>">edit</a>
<form method="post" style="display:inline"
onsubmit="return confirm('Delete node <?= h(addslashes($n['name'])) ?>?')">
<input type="hidden" name="action" value="delete">
<input type="hidden" name="id" value="<?= (int)$n['id'] ?>">
<button type="submit" class="link-btn danger">delete</button>
</form>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
</section>
</main>
</body>
</html>