Files
reflector-dashboard/auth/admin_bans_api.php
T
bjorneandClaude Fable 5.1 25b481e2ae Public web-only release: SvxPortal front-end + auth backend, install templates and INSTALL.md
Stripped from the internal repo: per-box deploy trees, Go services (nodelist/astmeta/proxy/svxdr),
deploy/sync scripts and all secrets. Config templates for nginx, PHP-FPM, Redis and tmpfiles
live in install/ with CHANGEME placeholders.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-26 23:07:05 +02:00

40 lines
1.2 KiB
PHP

<?php
declare(strict_types=1);
require __DIR__ . '/lib.php';
// Global callsign bans (mirrors the DMR site's bans.php). A Redis SET of base
// callsigns; list is visible to admin (LVL2+), add/remove are LVL3-only.
$acting_uuid = require_login();
$acting_level = acct_admin_level($acting_uuid);
if ($acting_level < 2) json_out(['ok'=>false,'error'=>'forbidden'], 403);
$j = json_in();
$action = (string)($j['action'] ?? 'list');
$r = redis();
if ($action === 'list') {
$cs = $r->sMembers(global_bans_key());
if (!is_array($cs)) $cs = [];
sort($cs);
json_out(['ok'=>true, 'callsigns'=>$cs, 'can_write'=>$acting_level >= 3]);
}
csrf_check();
if ($acting_level < 3) json_out(['ok'=>false,'error'=>'lvl3_required'], 403);
if ($action === 'add') {
$cs = base_call((string)($j['value'] ?? ''));
if ($cs === '' || !preg_match('/^[A-Z0-9]+$/', $cs)) json_out(['ok'=>false,'error'=>'invalid_callsign'], 400);
$r->sAdd(global_bans_key(), $cs);
json_out(['ok'=>true]);
}
if ($action === 'remove') {
$cs = base_call((string)($j['value'] ?? ''));
if ($cs === '') json_out(['ok'=>false,'error'=>'invalid_callsign'], 400);
$r->sRem(global_bans_key(), $cs);
json_out(['ok'=>true]);
}
json_out(['ok'=>false,'error'=>'unknown_action'], 400);