Rename display name: SvxPortal -> Reflector Dashboard (technical identifiers unchanged)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
2026-09-27 01:02:05 +02:00
co-authored by Claude Fable 5.1
parent d4c19b0eb4
commit 3d0896912c
99 changed files with 137 additions and 137 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
SvxPortal auth drop-in
Reflector Dashboard auth drop-in
Endpoints:
- /svxportal/auth/login.php (POST JSON {user, pass})
+3 -3
View File
@@ -1,6 +1,6 @@
# SvxPortal — installation HOWTO
# Reflector Dashboard — installation HOWTO
SvxPortal is the web front-end for a SvxReflector: node map, monitor,
Reflector Dashboard is the web front-end for a SvxReflector: node map, monitor,
last-heard, talkgroup list, user accounts and reflector admin pages. It has
two parts, both in this repository:
@@ -171,7 +171,7 @@ If you do not have one, add an SMTP relay instead and no MTA is needed:
```php
'mail' => [
'from' => 'no-reply@example.com',
'from_name' => 'SvxPortal',
'from_name' => 'Reflector Dashboard',
'host' => 'smtp.example.com', // SSL SMTP (implicit TLS)
'port' => 465,
'user' => 'smtp-user',
+1 -1
View File
@@ -1,4 +1,4 @@
# SvxPortal web
# Reflector Dashboard web
Web front-end for a [SvxReflector](https://github.com/sm0svx/svxlink): live node
list and map, monitor, last-heard, talkgroup list, user accounts with e-mail
+1 -1
View File
@@ -1,4 +1,4 @@
// SvxPortal — web front-end for SvxReflector
// Reflector Dashboard — web front-end for SvxReflector
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+1 -1
View File
@@ -1,4 +1,4 @@
// SvxPortal — web front-end for SvxReflector
// Reflector Dashboard — web front-end for SvxReflector
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+2 -2
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
@@ -18,7 +18,7 @@ $me = acct_get($uuid);
$lvl = acct_admin_level($uuid);
if ($lvl < 2) { header('Location: /'); exit; }
$page_title = 'Admin · Accounts — SvxPortal';
$page_title = 'Admin · Accounts — Reflector Dashboard';
require __DIR__ . '/header.php';
?>
+1 -1
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
+1 -1
View File
@@ -1,4 +1,4 @@
// SvxPortal — web front-end for SvxReflector
// Reflector Dashboard — web front-end for SvxReflector
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+2 -2
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
@@ -18,7 +18,7 @@ $me = acct_get($uuid);
$lvl = acct_admin_level($uuid);
if ($lvl < 2) { header('Location: /'); exit; }
$page_title = 'Admin · Global Bans — SvxPortal';
$page_title = 'Admin · Global Bans — Reflector Dashboard';
require __DIR__ . '/header.php';
?>
<div class="container py-4" style="max-width:800px;">
+1 -1
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
+1 -1
View File
@@ -1,4 +1,4 @@
// SvxPortal — web front-end for SvxReflector
// Reflector Dashboard — web front-end for SvxReflector
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+2 -2
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
@@ -18,7 +18,7 @@ $me = acct_get($uuid);
$lvl = acct_admin_level($uuid);
if ($lvl < 2) { header('Location: /'); exit; }
$page_title = 'Admin · Certificates — SvxPortal';
$page_title = 'Admin · Certificates — Reflector Dashboard';
require __DIR__ . '/header.php';
?>
<div class="container py-4" style="max-width:900px;">
+1 -1
View File
@@ -1,4 +1,4 @@
// SvxPortal — web front-end for SvxReflector
// Reflector Dashboard — web front-end for SvxReflector
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+2 -2
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
@@ -18,7 +18,7 @@ $me = acct_get($uuid);
$lvl = acct_admin_level($uuid);
if ($lvl < 2) { header('Location: /'); exit; }
$page_title = 'Admin · Config — SvxPortal';
$page_title = 'Admin · Config — Reflector Dashboard';
require __DIR__ . '/header.php';
?>
<div class="container py-4" style="max-width:800px;">
+1 -1
View File
@@ -1,4 +1,4 @@
// SvxPortal — web front-end for SvxReflector
// Reflector Dashboard — web front-end for SvxReflector
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+2 -2
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
@@ -18,7 +18,7 @@ $me = acct_get($uuid);
$lvl = acct_admin_level($uuid);
if ($lvl < 2) { header('Location: /'); exit; }
$page_title = 'Admin · Control — SvxPortal';
$page_title = 'Admin · Control — Reflector Dashboard';
require __DIR__ . '/header.php';
?>
<div class="container py-4" style="max-width:800px;">
+2 -2
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
@@ -17,7 +17,7 @@ if (!is_string($uuid) || $uuid === '') { header('Location: /'); exit; }
$me = acct_get($uuid);
if (acct_admin_level($uuid) < 2) { header('Location: /'); exit; }
$page_title = 'Admin · MQTT — SvxPortal';
$page_title = 'Admin · MQTT — Reflector Dashboard';
require __DIR__ . '/header.php';
?>
<div class="container py-4" style="max-width:640px;">
+1 -1
View File
@@ -1,4 +1,4 @@
// SvxPortal — web front-end for SvxReflector
// Reflector Dashboard — web front-end for SvxReflector
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+2 -2
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
@@ -18,7 +18,7 @@ $me = acct_get($uuid);
$lvl = acct_admin_level($uuid);
if ($lvl < 2) { header('Location: /'); exit; }
$page_title = 'Admin · Node Auth — SvxPortal';
$page_title = 'Admin · Node Auth — Reflector Dashboard';
require __DIR__ . '/header.php';
?>
<div class="container py-4" style="max-width:900px;">
+1 -1
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
+1 -1
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
+1 -1
View File
@@ -1,4 +1,4 @@
// SvxPortal — web front-end for SvxReflector
// Reflector Dashboard — web front-end for SvxReflector
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+2 -2
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
@@ -19,7 +19,7 @@ if (!is_string($uuid) || $uuid === '') { header('Location: /'); exit; }
// a read-only table.
$lvl = acct_admin_level($uuid);
$page_title = 'TG List — SvxPortal';
$page_title = 'TG List — Reflector Dashboard';
require __DIR__ . '/header.php';
?>
<div class="container py-4" style="max-width:1000px;">
+1 -1
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
+1 -1
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
+1 -1
View File
@@ -1,4 +1,4 @@
<!-- SvxPortal — Copyright (C) 2026 SA7AUX (Björn) — SPDX-License-Identifier: AGPL-3.0-or-later — see LICENSE -->
<!-- Reflector Dashboard — Copyright (C) 2026 SA7AUX (Björn) — SPDX-License-Identifier: AGPL-3.0-or-later — see LICENSE -->
</main>
<footer style="text-align:center; padding:16px; color:rgba(0,255,255,.4); font-size:.75rem; border-top:1px solid rgba(0,255,255,.15);">
&copy; 2026 SA7AUX. All rights reserved.
+4 -4
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
@@ -53,13 +53,13 @@ $link = $base . '/auth/reset_password.php?tid=' . urlencode($tid) . '&token=' .
$name = $acct['firstname'] ?? $callsign;
$body = "Hello {$name},\n\n";
$body .= "A password reset was requested for your SvxPortal account ({$callsign}).\n\n";
$body .= "A password reset was requested for your Reflector Dashboard account ({$callsign}).\n\n";
$body .= "Click the link below to set a new password:\n\n";
$body .= "{$link}\n\n";
$body .= "This link is valid for 1 hour.\n\n";
$body .= "If you did not request this, you can ignore this email.\n\n";
$body .= "73,\nSvxPortal";
$body .= "73,\nReflector Dashboard";
mail_send($email, "Password reset - SvxPortal", $body);
mail_send($email, "Password reset - Reflector Dashboard", $body);
json_out(['ok' => true, 'message' => 'If the account exists, a reset link has been sent.']);
+2 -2
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
@@ -21,7 +21,7 @@ header('Cache-Control: no-store');
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title><?= $page_title ?? 'SvxPortal' ?></title>
<title><?= $page_title ?? 'Reflector Dashboard' ?></title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
:root{ color-scheme:dark; --bg:#000; --fg:#00ffff; --fg2:rgba(0,255,255,.75); --line:rgba(0,255,255,.35); }
+2 -2
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
@@ -404,7 +404,7 @@ function mail_send(string $to, string $subject, string $body): bool {
$user = $m['user'] ?? '';
if ($host !== '' && $user !== '') {
return smtp_send_ssl($host, (int)($m['port'] ?? 465), $user, (string)($m['pass'] ?? ''),
$from, (string)($m['from_name'] ?? 'SvxPortal'), $to, $subject, $body);
$from, (string)($m['from_name'] ?? 'Reflector Dashboard'), $to, $subject, $body);
}
$headers = "From: $from\r\nContent-Type: text/plain; charset=UTF-8\r\n";
return @mail($to, $subject, $body, $headers);
+1 -1
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
+1 -1
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
+1 -1
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
+1 -1
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
+1 -1
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
+1 -1
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
+1 -1
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
+1 -1
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
+1 -1
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
+1 -1
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
+1 -1
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
+1 -1
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
+1 -1
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
+1 -1
View File
@@ -1,4 +1,4 @@
// SvxPortal — web front-end for SvxReflector
// Reflector Dashboard — web front-end for SvxReflector
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+2 -2
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
@@ -114,7 +114,7 @@ do {
$admin_nodes = array_values(array_unique($admin_nodes));
sort($admin_nodes);
$page_title = 'Profile — SvxPortal';
$page_title = 'Profile — Reflector Dashboard';
require __DIR__ . '/header.php';
?>
+1 -1
View File
@@ -1,4 +1,4 @@
// SvxPortal — web front-end for SvxReflector
// Reflector Dashboard — web front-end for SvxReflector
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+1 -1
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
+4 -4
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
@@ -54,10 +54,10 @@ $link = $base . '/auth/verify.php?tid=' . urlencode($tid) . '&token=' . urlencod
$first = (string)($me['firstname'] ?? '');
$call = (string)($me['callsign'] ?? '');
$body = "Hello {$first},\n\n";
$body .= "Here is a new email verification link for your SvxPortal account ({$call}):\n\n";
$body .= "Here is a new email verification link for your Reflector Dashboard account ({$call}):\n\n";
$body .= "{$link}\n\n";
$body .= "This link is valid for 24 hours.\n\n";
$body .= "73,\nSvxPortal";
$sent = mail_send($email, "Verify your email - SvxPortal", $body);
$body .= "73,\nReflector Dashboard";
$sent = mail_send($email, "Verify your email - Reflector Dashboard", $body);
json_out(['ok' => true, 'email_sent' => $sent]);
+4 -4
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
@@ -49,7 +49,7 @@ function he(string $s): string { return htmlspecialchars($s, ENT_QUOTES, 'UTF-8'
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Reset Password — SvxPortal</title>
<title>Reset Password — Reflector Dashboard</title>
<style>
:root{ color-scheme:dark; --bg:#000; --fg:#00ffff; --fg2:rgba(0,255,255,.75); --line:rgba(0,255,255,.35); }
html, body{ height:100%; background:var(--bg); color:var(--fg); margin:0; font-family:system-ui,sans-serif; }
@@ -69,10 +69,10 @@ function he(string $s): string { return htmlspecialchars($s, ENT_QUOTES, 'UTF-8'
<h3 style="margin-top:0;">Reset Password</h3>
<?php if ($done): ?>
<div class="ok">Password changed successfully!</div>
<p><a href="/">Back to SvxPortal</a></p>
<p><a href="/">Back to Reflector Dashboard</a></p>
<?php elseif ($error && ($_SERVER['REQUEST_METHOD'] !== 'POST' || $tid === '' || $token === '')): ?>
<div class="err"><?=he($error)?></div>
<p><a href="/">Back to SvxPortal</a></p>
<p><a href="/">Back to Reflector Dashboard</a></p>
<?php else: ?>
<?php if ($error): ?><div class="err"><?=he($error)?></div><?php endif; ?>
<form method="post">
+4 -4
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
@@ -99,12 +99,12 @@ $r->expire($k, 60 * 60 * 24);
$base = rtrim(cfg()['base_url'], '/');
$link = $base . '/auth/verify.php?tid=' . urlencode($tid) . '&token=' . urlencode($secret);
$body = "Hello {$firstname},\n\n";
$body .= "Thank you for registering on SvxPortal with callsign {$callsign}.\n\n";
$body .= "Thank you for registering on Reflector Dashboard with callsign {$callsign}.\n\n";
$body .= "Please verify your email address by clicking the link below:\n\n";
$body .= "{$link}\n\n";
$body .= "This link is valid for 24 hours.\n\n";
$body .= "After email verification, an administrator will review and activate your account.\n\n";
$body .= "73,\nSvxPortal";
$mail_sent = mail_send($email, "Verify your email - SvxPortal", $body);
$body .= "73,\nReflector Dashboard";
$mail_sent = mail_send($email, "Verify your email - Reflector Dashboard", $body);
json_out(['ok' => true, 'callsign' => $callsign, 'email_sent' => $mail_sent]);
+1 -1
View File
@@ -1,4 +1,4 @@
// SvxPortal — web front-end for SvxReflector
// Reflector Dashboard — web front-end for SvxReflector
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+2 -2
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
@@ -19,7 +19,7 @@ $lvl = acct_admin_level($uuid);
// who are NOT admins use the separate self-service page (admin_tglist.php).
if ($lvl < 2) { header('Location: /'); exit; }
$page_title = 'Admin · TG List — SvxPortal';
$page_title = 'Admin · TG List — Reflector Dashboard';
require __DIR__ . '/header.php';
?>
<div class="container py-4" style="max-width:1000px;">
+1 -1
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
+1 -1
View File
@@ -1,4 +1,4 @@
// SvxPortal — web front-end for SvxReflector
// Reflector Dashboard — web front-end for SvxReflector
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+2 -2
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
@@ -15,7 +15,7 @@ start_session();
$uuid = $_SESSION['uid'] ?? null;
if (!is_string($uuid) || $uuid === '') { header('Location: /'); exit; }
$page_title = 'Request a TG — SvxPortal';
$page_title = 'Request a TG — Reflector Dashboard';
require __DIR__ . '/header.php';
?>
<div class="container py-4" style="max-width:640px;">
+1 -1
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
+1 -1
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
+2 -2
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
@@ -47,5 +47,5 @@ header('Content-Type: text/html; charset=utf-8');
echo "<!doctype html><meta charset='utf-8'><title>Verified</title><body style='font-family:system-ui;background:#000;color:#0ff;padding:20px;'>
<h2>OK</h2>
<div>Your e-mail is verified. Your account is now registered and waiting for an admin to approve it &mdash; once that is done you can sign in.</div>
<div style='margin-top:12px;'><a href='/svxportal/' style='color:#0ff;'>Back to SvxPortal</a></div>
<div style='margin-top:12px;'><a href='/svxportal/' style='color:#0ff;'>Back to Reflector Dashboard</a></div>
</body>";
+1 -1
View File
@@ -1,4 +1,4 @@
// SvxPortal — web front-end for SvxReflector
// Reflector Dashboard — web front-end for SvxReflector
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+1 -1
View File
@@ -417,7 +417,7 @@
"repo": "web",
"hash": "a703cfb",
"type": "feature",
"summary": "SvxPortal remembers the last view across reloads (Ctrl+Shift+R lands where you were), and TG Monitor gets a search box — type a TG number to see who is on it, or a callsign/node to see which talkgroups it is on"
"summary": "Reflector Dashboard remembers the last view across reloads (Ctrl+Shift+R lands where you were), and TG Monitor gets a search box — type a TG number to see who is on it, or a callsign/node to see which talkgroups it is on"
},
{
"date": "2026-07-28",
+1 -1
View File
@@ -1,4 +1,4 @@
// SvxPortal — web front-end for SvxReflector
// Reflector Dashboard — web front-end for SvxReflector
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+1 -1
View File
@@ -1,4 +1,4 @@
// SvxPortal — web front-end for SvxReflector
// Reflector Dashboard — web front-end for SvxReflector
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+1 -1
View File
@@ -1,4 +1,4 @@
// SvxPortal — web front-end for SvxReflector
// Reflector Dashboard — web front-end for SvxReflector
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+4 -4
View File
@@ -1,11 +1,11 @@
<!doctype html>
<!-- SvxPortal — Copyright (C) 2026 SA7AUX (Björn) — SPDX-License-Identifier: AGPL-3.0-or-later — see LICENSE -->
<!-- Reflector Dashboard — Copyright (C) 2026 SA7AUX (Björn) — SPDX-License-Identifier: AGPL-3.0-or-later — see LICENSE -->
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Help &amp; Guides — SvxPortal | SvxLink nodes, reflector, build from source</title>
<meta name="description" content="SvxPortal help &amp; guides: register your SvxLink node, certificates, talkgroups and trunks — plus how to compile SvxLink from source on Debian, Ubuntu and Raspberry Pi, and how to find the right deb packages.">
<title>Help &amp; Guides — Reflector Dashboard | SvxLink nodes, reflector, build from source</title>
<meta name="description" content="Reflector Dashboard help &amp; guides: register your SvxLink node, certificates, talkgroups and trunks — plus how to compile SvxLink from source on Debian, Ubuntu and Raspberry Pi, and how to find the right deb packages.">
<link rel="canonical" href="https://svxportal.sa7aux.se/help.html">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
@@ -55,7 +55,7 @@
<body>
<nav class="navbar navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="/">SvxPortal</a>
<a class="navbar-brand" href="/">Reflector Dashboard</a>
<span class="navbar-text small me-auto ms-3">Help</span>
<a href="/" class="btn btn-sm btn-outline-secondary" onclick="if(history.length>1){history.back();return false;}">Back</a>
</div>
+1 -1
View File
@@ -1,4 +1,4 @@
// SvxPortal — web front-end for SvxReflector
// Reflector Dashboard — web front-end for SvxReflector
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+1 -1
View File
@@ -1,4 +1,4 @@
// SvxPortal — web front-end for SvxReflector
// Reflector Dashboard — web front-end for SvxReflector
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+5 -5
View File
@@ -1,5 +1,5 @@
<!doctype html>
<!-- SvxPortal — Copyright (C) 2026 SA7AUX (Björn) — SPDX-License-Identifier: AGPL-3.0-or-later — see LICENSE -->
<!-- Reflector Dashboard — Copyright (C) 2026 SA7AUX (Björn) — SPDX-License-Identifier: AGPL-3.0-or-later — see LICENSE -->
<html lang="en">
<head>
<meta charset="utf-8" />
@@ -8,18 +8,18 @@
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<title>SvxPortal — SvxLink Reflector | Nodes, Lastheard, CTCSS &amp; Map</title>
<meta name="description" content="SvxPortal — live dashboard for the SA7AUX SvxLink reflector: connected nodes, reflector clients, talkgroup monitor, lastheard, CTCSS tone table and node map for amateur radio / ham radio." />
<title>Reflector Dashboard — SvxLink Reflector | Nodes, Lastheard, CTCSS &amp; Map</title>
<meta name="description" content="Reflector Dashboard — live dashboard for the SA7AUX SvxLink reflector: connected nodes, reflector clients, talkgroup monitor, lastheard, CTCSS tone table and node map for amateur radio / ham radio." />
<link rel="canonical" href="https://svxportal.sa7aux.se/" />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://svxportal.sa7aux.se/" />
<meta property="og:title" content="SvxPortal — SvxLink Reflector" />
<meta property="og:title" content="Reflector Dashboard — SvxLink Reflector" />
<meta property="og:description" content="Live nodes, lastheard, talkgroup monitor, CTCSS table and map for the SA7AUX SvxLink reflector." />
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebSite",
"name": "SvxPortal",
"name": "Reflector Dashboard",
"url": "https://svxportal.sa7aux.se/",
"description": "Live dashboard for the SA7AUX SvxLink amateur radio reflector",
"publisher": { "@type": "Organization", "name": "SA7AUX", "url": "https://sa7aux.se/" }
+1 -1
View File
@@ -1,4 +1,4 @@
# SvxPortal web — nginx server block.
# Reflector Dashboard web — nginx server block.
# Install: sudo cp install/nginx-svxportal.conf /etc/nginx/sites-available/svxportal
# sudo ln -s /etc/nginx/sites-available/svxportal /etc/nginx/sites-enabled/
# sudo nginx -t && sudo systemctl reload nginx
+1 -1
View File
@@ -1,4 +1,4 @@
# Dedicated Redis instance for SvxPortal (unix socket only, no TCP port).
# Dedicated Redis instance for Reflector Dashboard (unix socket only, no TCP port).
# Install: sudo cp install/redis-svxportal.conf /etc/redis/redis-svxportal.conf
# sudo mkdir -p /var/lib/redis-svxportal && sudo chown redis:redis /var/lib/redis-svxportal
# sudo systemctl enable --now redis-server@svxportal
+3 -3
View File
@@ -1,4 +1,4 @@
# Example svxreflector.conf as used together with SvxPortal (layout of a live reflector).
# Example svxreflector.conf as used together with Reflector Dashboard (layout of a live reflector).
# All secrets are CHANGEME, hostnames are my.domain.com / peer.domain.com. Adjust to your site.
# The web admin pages read this file to find CERT_PKI_DIR and to manage [USERS]/[PASSWORDS].
#
@@ -68,7 +68,7 @@ SUBJECT_ALT_NAME=DNS:my.domain.com,IP:192.0.2.1
EMAIL_ADDRESS=admin@my.domain.com
# [USERS] maps a node callsign to a password-group name; [PASSWORDS] holds the
# group's secret. SvxPortal's "svxreflector-users" helper adds entries of the
# group's secret. Reflector Dashboard's "svxreflector-users" helper adds entries of the
# form CALL=CALL here (one group per node). Several nodes may share one group.
[USERS]
MYCALL-AC=MYCALL-AC
@@ -114,7 +114,7 @@ SECRET_dmr=CHANGEME
SECRET_pbx=CHANGEME
###################################################################
# MQTT status publishing (used by the node control pages in SvxPortal).
# MQTT status publishing (used by the node control pages in Reflector Dashboard).
[MQTT]
HOST=127.0.0.1
PORT=1883
+1 -1
View File
@@ -1,4 +1,4 @@
# svxdr — live-data daemon for SvxPortal. Install:
# svxdr — live-data daemon for Reflector Dashboard. Install:
# sudo cp install/systemd/svxdr.service /etc/systemd/system/ && sudo systemctl daemon-reload && sudo systemctl enable --now svxdr
# Build and configure per INSTALL.md section 9.
[Unit]
+1 -1
View File
@@ -1,4 +1,4 @@
// SvxPortal — web front-end for SvxReflector
// Reflector Dashboard — web front-end for SvxReflector
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+1 -1
View File
@@ -1,4 +1,4 @@
// SvxPortal — web front-end for SvxReflector
// Reflector Dashboard — web front-end for SvxReflector
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+1 -1
View File
@@ -1,4 +1,4 @@
// SvxPortal — web front-end for SvxReflector
// Reflector Dashboard — web front-end for SvxReflector
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+1 -1
View File
@@ -1,4 +1,4 @@
// SvxPortal — web front-end for SvxReflector
// Reflector Dashboard — web front-end for SvxReflector
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+1 -1
View File
@@ -1,4 +1,4 @@
// SvxPortal — web front-end for SvxReflector
// Reflector Dashboard — web front-end for SvxReflector
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+1 -1
View File
@@ -1,4 +1,4 @@
// SvxPortal — web front-end for SvxReflector
// Reflector Dashboard — web front-end for SvxReflector
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+1 -1
View File
@@ -1,4 +1,4 @@
// SvxPortal — web front-end for SvxReflector
// Reflector Dashboard — web front-end for SvxReflector
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+1 -1
View File
@@ -1,4 +1,4 @@
// SvxPortal — web front-end for SvxReflector
// Reflector Dashboard — web front-end for SvxReflector
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+1 -1
View File
@@ -1,4 +1,4 @@
// SvxPortal — web front-end for SvxReflector
// Reflector Dashboard — web front-end for SvxReflector
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+1 -1
View File
@@ -1,4 +1,4 @@
// SvxPortal — web front-end for SvxReflector
// Reflector Dashboard — web front-end for SvxReflector
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+1 -1
View File
@@ -1,4 +1,4 @@
// SvxPortal — web front-end for SvxReflector
// Reflector Dashboard — web front-end for SvxReflector
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+1 -1
View File
@@ -1,4 +1,4 @@
// SvxPortal — web front-end for SvxReflector
// Reflector Dashboard — web front-end for SvxReflector
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env php
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
@@ -13,7 +13,7 @@
declare(strict_types=1);
/*
* svx-mkadmin.php — interaktiv provisionering av ett SvxPortal-konto (t.ex. admin).
* svx-mkadmin.php — interaktiv provisionering av ett Reflector Dashboard-konto (t.ex. admin).
*
* Återanvänder portalens EGEN auth/lib.php, så redis-anslutning (socket/lösen/db),
* nyckelprefix, uuid-generering, callsign-normalisering och lösenordshashning
+1 -1
View File
@@ -1,4 +1,4 @@
// svxdr — live-data daemon for SvxPortal (nodelist + proxy + astmeta + xlink)
// svxdr — live-data daemon for Reflector Dashboard (nodelist + proxy + astmeta + xlink)
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+1 -1
View File
@@ -1,4 +1,4 @@
// svxdr — live-data daemon for SvxPortal (nodelist + proxy + astmeta + xlink)
// svxdr — live-data daemon for Reflector Dashboard (nodelist + proxy + astmeta + xlink)
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+1 -1
View File
@@ -1,4 +1,4 @@
// svxdr — live-data daemon for SvxPortal (nodelist + proxy + astmeta + xlink)
// svxdr — live-data daemon for Reflector Dashboard (nodelist + proxy + astmeta + xlink)
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+1 -1
View File
@@ -1,4 +1,4 @@
// svxdr — live-data daemon for SvxPortal (nodelist + proxy + astmeta + xlink)
// svxdr — live-data daemon for Reflector Dashboard (nodelist + proxy + astmeta + xlink)
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+1 -1
View File
@@ -1,4 +1,4 @@
// svxdr — live-data daemon for SvxPortal (nodelist + proxy + astmeta + xlink)
// svxdr — live-data daemon for Reflector Dashboard (nodelist + proxy + astmeta + xlink)
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+1 -1
View File
@@ -1,4 +1,4 @@
// svxdr — live-data daemon for SvxPortal (nodelist + proxy + astmeta + xlink)
// svxdr — live-data daemon for Reflector Dashboard (nodelist + proxy + astmeta + xlink)
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+1 -1
View File
@@ -1,4 +1,4 @@
// svxdr — live-data daemon for SvxPortal (nodelist + proxy + astmeta + xlink)
// svxdr — live-data daemon for Reflector Dashboard (nodelist + proxy + astmeta + xlink)
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+1 -1
View File
@@ -1,4 +1,4 @@
// svxdr — live-data daemon for SvxPortal (nodelist + proxy + astmeta + xlink)
// svxdr — live-data daemon for Reflector Dashboard (nodelist + proxy + astmeta + xlink)
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+1 -1
View File
@@ -1,4 +1,4 @@
// svxdr — live-data daemon for SvxPortal (nodelist + proxy + astmeta + xlink)
// svxdr — live-data daemon for Reflector Dashboard (nodelist + proxy + astmeta + xlink)
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+1 -1
View File
@@ -1,4 +1,4 @@
// svxdr — live-data daemon for SvxPortal (nodelist + proxy + astmeta + xlink)
// svxdr — live-data daemon for Reflector Dashboard (nodelist + proxy + astmeta + xlink)
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+1 -1
View File
@@ -1,4 +1,4 @@
// svxdr — live-data daemon for SvxPortal (nodelist + proxy + astmeta + xlink)
// svxdr — live-data daemon for Reflector Dashboard (nodelist + proxy + astmeta + xlink)
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+1 -1
View File
@@ -1,4 +1,4 @@
// SvxPortal — web front-end for SvxReflector
// Reflector Dashboard — web front-end for SvxReflector
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+1 -1
View File
@@ -1,6 +1,6 @@
<?php
/*
* SvxPortal — web front-end for SvxReflector
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
+1 -1
View File
@@ -1,4 +1,4 @@
// SvxPortal — web front-end for SvxReflector
// Reflector Dashboard — web front-end for SvxReflector
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+1 -1
View File
@@ -1,4 +1,4 @@
// SvxPortal — web front-end for SvxReflector
// Reflector Dashboard — web front-end for SvxReflector
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//
+1 -1
View File
@@ -1,4 +1,4 @@
// SvxPortal — web front-end for SvxReflector
// Reflector Dashboard — web front-end for SvxReflector
// Copyright (C) 2026 SA7AUX (Björn)
// SPDX-License-Identifier: AGPL-3.0-or-later
//