mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-10-04 06:15:09 +00:00
Optional web login, off by default: a device that sets no password behaves exactly as before. Set under General > Security; then every page and API route needs a session login or an API token (Authorization: Bearer). Loopback, the Wi-Fi setup flow in AP mode, static files, captive-portal probes and a reduced /api/v3/health stay open. Secrets live in the web_auth section of config_secrets.json and no API returns them. scripts/reset_web_password.py turns login off. Stacked on #674. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1059,6 +1059,16 @@
|
||||
${field('mqtt-topic', 'Command topic', c.mqtt_topic)}
|
||||
${field('mqtt-client-id', 'Client ID', c.mqtt_client_id)}
|
||||
${field('mqtt-api-base', 'LEDMatrix API base', c.ledmatrix_api_base)}
|
||||
<label class="block">
|
||||
<span class="text-xs font-medium text-gray-700">LEDMatrix API token</span>
|
||||
<input id="mqtt-api-token" type="password" value="" autocomplete="off"
|
||||
placeholder="${data.api_token_set ? 'unchanged — leave blank to keep' : 'none set'}"
|
||||
class="mt-1 w-full px-2 py-1.5 text-sm border border-gray-300 rounded-md">
|
||||
<span class="text-xs text-gray-500">
|
||||
Only when web login is on and the bridge runs on another machine (General > Security).
|
||||
${data.api_token_set ? '<button type="button" id="mqtt-clear-api-token" class="text-red-600 hover:underline ml-1">Clear it</button>' : ''}
|
||||
</span>
|
||||
</label>
|
||||
${field('mqtt-timeout', 'Request timeout (s)', c.request_timeout, 'number', 'min="1" max="300"')}
|
||||
${field('mqtt-duration', 'On-demand duration (s, blank = default)', c.on_demand_duration, 'number', 'min="1" max="86400"')}
|
||||
<label class="block">
|
||||
@@ -1113,6 +1123,8 @@
|
||||
|
||||
const clearBtn = document.getElementById('mqtt-clear-password');
|
||||
if (clearBtn) clearBtn.addEventListener('click', () => clearMqttPassword());
|
||||
const clearTokenBtn = document.getElementById('mqtt-clear-api-token');
|
||||
if (clearTokenBtn) clearTokenBtn.addEventListener('click', () => clearMqttApiToken());
|
||||
}
|
||||
|
||||
window.loadMqttBridge = function() {
|
||||
@@ -1145,6 +1157,8 @@
|
||||
// Only send a password when one was typed; blank means "leave it alone".
|
||||
const pw = val('mqtt-password');
|
||||
if (pw) body.mqtt_password = pw;
|
||||
const apiToken = val('mqtt-api-token');
|
||||
if (apiToken) body.ledmatrix_api_token = apiToken;
|
||||
return body;
|
||||
}
|
||||
|
||||
@@ -1180,6 +1194,21 @@
|
||||
.catch(err => showResult('result-mqtt-save', false, 'Request failed: ' + err.message));
|
||||
}
|
||||
|
||||
function clearMqttApiToken() {
|
||||
if (!confirm('Remove the stored LEDMatrix API token from the bridge settings?')) return;
|
||||
fetch(MQTT_BRIDGE_URL + '/config', {
|
||||
method: 'PUT',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({clear_api_token: true})
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(d => {
|
||||
showResult('result-mqtt-save', d.status === 'success', d.message || 'Token cleared');
|
||||
loadMqttBridge();
|
||||
})
|
||||
.catch(err => showResult('result-mqtt-save', false, 'Request failed: ' + err.message));
|
||||
}
|
||||
|
||||
window.installMqttBridge = function() {
|
||||
// Installing pulls dependencies, so it is slower than the other actions
|
||||
// and worth saying so rather than leaving a spinner unexplained.
|
||||
|
||||
Reference in New Issue
Block a user