diff --git a/INSTALL.md b/INSTALL.md index 33629cd..6e1e4c1 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -117,6 +117,9 @@ Set: - `redis.password` -> the value from step 3 - `base_url` -> `https://svxportal.example.com` (used in the e-mail links) - `mail.from` -> the sender address for verification / reset mails +- `mqtt.node_broker_host` / `mqtt.node_broker_port` -> the MQTT broker address + shown to node owners on the node pages (your public TLS port, usually 8883). + Without these the node MQTT page returns `mqtt_broker_not_configured`. E-mail: with only `mail.from` set, PHP's `mail()` is used, which needs a working local MTA (`/usr/sbin/sendmail`, e.g. `msmtp-mta` or `postfix`). diff --git a/auth/config.php.example b/auth/config.php.example index 0e6d4b6..48605b0 100644 --- a/auth/config.php.example +++ b/auth/config.php.example @@ -16,6 +16,17 @@ return [ 'cookie_samesite' => 'Lax', ], 'mail' => [ 'from' => 'no-reply@example.com' ], + // MQTT. pub_* = the broker the PORTAL publishes node commands to (can also be set + // in the web admin, Redis overrides these). node_broker_* = the broker address + // shown to node owners for their node's MQTT client (usually your public TLS port). + 'mqtt' => [ + 'pub_host' => '127.0.0.1', + 'pub_port' => 1883, + 'pub_user' => '', + 'pub_pass' => '', + 'node_broker_host' => 'svx.example.com', + 'node_broker_port' => 8883, + ], 'base_url' => 'https://svx.example.com', // Canonical TG list JSON file (SVX source of truth; DMR uses Redis instead). // Must be writable by the web user (www-data) and readable by svxdr. diff --git a/auth/node_cmd_api.php b/auth/node_cmd_api.php index 5ee6ed1..94c65fd 100644 --- a/auth/node_cmd_api.php +++ b/auth/node_cmd_api.php @@ -48,6 +48,18 @@ function provision_call(string $sub, string $cs, ?string $pw = null): array { } // ===== Node-owner actions: read / (re)generate this node's MQTT credentials ===== +// Broker the NODES connect to (host:port shown to the node owner). Runtime config, +// never hardcoded: auth/config.php 'mqtt' => ['node_broker_host' => ..., 'node_broker_port' => ...]. +function node_broker(): array { + $c = cfg()['mqtt'] ?? []; + $host = trim((string)($c['node_broker_host'] ?? '')); + $port = (int)($c['node_broker_port'] ?? 0); + if ($host === '' || $port <= 0) + json_out(['ok' => false, 'error' => 'mqtt_broker_not_configured', + 'detail' => "set mqtt.node_broker_host / node_broker_port in auth/config.php"], 500); + return ['broker_host' => $host, 'broker_port' => $port]; +} + if ($action === 'mqtt_node_get' || $action === 'mqtt_node_provision') { $cs = require_callsign($in, 'valid_amateur_callsign'); if (!user_owns_node($uuid, $cs)) json_out(['ok' => false, 'error' => 'not_your_node'], 403); @@ -57,8 +69,7 @@ if ($action === 'mqtt_node_get' || $action === 'mqtt_node_provision') { if ($action === 'mqtt_node_get') { $rec = redis()->hGetAll($key) ?: []; json_out(['ok' => true, 'provisioned' => !empty($rec['pass']), - 'username' => $user, 'password' => $rec['pass'] ?? '', - 'broker_host' => 'svx.sa7aux.se', 'broker_port' => 8883]); + 'username' => $user, 'password' => $rec['pass'] ?? ''] + node_broker()); } // provision / regenerate @@ -70,8 +81,7 @@ if ($action === 'mqtt_node_get' || $action === 'mqtt_node_provision') { redis()->hSet($key, 'pass', $pw); redis()->hSet($key, 'ts', (string)time()); redis()->hSet($key, 'by', $uuid); - json_out(['ok' => true, 'username' => $user, 'password' => $pw, - 'broker_host' => 'svx.sa7aux.se', 'broker_port' => 8883]); + json_out(['ok' => true, 'username' => $user, 'password' => $pw] + node_broker()); } // ===== Portal MQTT publish settings (admin) =====