75 lines
3.5 KiB
PHP
75 lines
3.5 KiB
PHP
<?php
|
|
/*
|
|
* SvxPortal — web front-end for SvxReflector
|
|
* Copyright (C) 2026 SA7AUX (Björn)
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify it under
|
|
* the terms of the GNU Affero General Public License as published by the Free
|
|
* Software Foundation, either version 3 of the License, or (at your option) any
|
|
* later version. See the LICENSE file for details.
|
|
*/
|
|
declare(strict_types=1);
|
|
require __DIR__ . '/lib.php';
|
|
start_session();
|
|
$uuid = $_SESSION['uid'] ?? null;
|
|
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';
|
|
require __DIR__ . '/header.php';
|
|
?>
|
|
<div class="container py-4" style="max-width:640px;">
|
|
<div class="panel">
|
|
<h5 class="mb-3">MQTT publish settings</h5>
|
|
<div class="text-secondary small mb-3">Where the portal publishes node commands (the broker it connects to for <span class="mono">mosquitto_pub</span>). Nodes set their own broker host/port on the node dashboard.</div>
|
|
<div class="row g-2">
|
|
<div class="col-8"><label class="form-label">Broker host</label>
|
|
<input class="form-control form-control-sm mono" id="m_host" placeholder="127.0.0.1"></div>
|
|
<div class="col-4"><label class="form-label">Port</label>
|
|
<input class="form-control form-control-sm mono" id="m_port" placeholder="1883"></div>
|
|
<div class="col-6"><label class="form-label">Username</label>
|
|
<input class="form-control form-control-sm mono" id="m_user" placeholder="portal-pub"></div>
|
|
<div class="col-6"><label class="form-label">Password</label>
|
|
<input class="form-control form-control-sm mono" id="m_pass" type="password" placeholder="enter password"></div>
|
|
</div>
|
|
<div class="d-flex gap-2 mt-3 align-items-center">
|
|
<button class="btn btn-primary btn-sm" id="btnSave" type="button">Save</button>
|
|
<span id="msg" class="small text-secondary"></span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<script>
|
|
var CSRF = '';
|
|
function api(body){
|
|
return fetch('/auth/node_cmd_api.php', {method:'POST', credentials:'same-origin',
|
|
headers:{'Content-Type':'application/json','X-CSRF-Token':CSRF},
|
|
body:JSON.stringify(body)}).then(function(r){return r.json();});
|
|
}
|
|
function load(){
|
|
api({action:'mqtt_get'}).then(function(j){
|
|
if(!j||!j.ok) return;
|
|
document.getElementById('m_host').value = j.host || '';
|
|
document.getElementById('m_port').value = j.port || '';
|
|
document.getElementById('m_user').value = j.user || '';
|
|
document.getElementById('m_pass').placeholder = j.pass_set ? 'unchanged — blank keeps it' : 'enter password';
|
|
});
|
|
}
|
|
document.getElementById('btnSave').addEventListener('click', function(){
|
|
var msg = document.getElementById('msg');
|
|
api({action:'mqtt_set',
|
|
host: document.getElementById('m_host').value.trim(),
|
|
port: parseInt(document.getElementById('m_port').value, 10) || 1883,
|
|
user: document.getElementById('m_user').value.trim(),
|
|
pass: document.getElementById('m_pass').value})
|
|
.then(function(j){
|
|
if(j && j.ok){ msg.textContent='Saved.'; msg.style.color='#00e676'; document.getElementById('m_pass').value=''; load(); }
|
|
else { msg.textContent = (j && j.error) || 'Save failed'; msg.style.color='#ff5252'; }
|
|
});
|
|
});
|
|
fetch('/auth/me.php',{credentials:'same-origin'}).then(function(r){return r.json();})
|
|
.then(function(j){ if(j&&j.csrf_token) CSRF=j.csrf_token; load(); }).catch(load);
|
|
</script>
|
|
<?php require __DIR__ . '/footer.php'; ?>
|