feat: Pi hotspot SSID/password configurable from Settings page

- Settings page: SSID + password fields in In-car access card
- GET /api/hotspot reads current SSID (password never returned)
- POST /api/hotspot updates via nmcli (Hotspot-local profile on wlan0)
- deploy/yaris-hotspot.sudoers for privileged nmcli access
- Password is write-only with placeholder hint
This commit is contained in:
Mathieu Moran
2026-08-12 05:15:55 -04:00
parent c0aed4a997
commit 336815b49c
4 changed files with 118 additions and 1 deletions
+47
View File
@@ -45,6 +45,52 @@ const fields = {
clearRemoteApiKey: document.getElementById('clear-remote-api-key'),
};
// ── Pi hotspot (separate from main settings form) ──────────────────────────
const apSsid = document.getElementById('ap-ssid');
const apPassword = document.getElementById('ap-password');
const apSave = document.getElementById('ap-save');
const apMessage = document.getElementById('ap-message');
function showApMessage(text, kind) {
apMessage.textContent = text;
apMessage.className = `alert alert-${kind} py-2 mb-3`;
apMessage.hidden = false;
}
async function loadApConfig() {
try {
const r = await fetch('/api/hotspot');
if (!r.ok) throw new Error('Cannot load hotspot config');
const d = await r.json();
apSsid.value = d.ssid || '';
} catch (e) {
apSsid.placeholder = '(cannot read)';
}
}
apSave.addEventListener('click', async function () {
apSave.disabled = true;
apMessage.hidden = true;
try {
const r = await fetch('/api/hotspot', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
ssid: apSsid.value.trim(),
password: apPassword.value,
}),
});
const d = await r.json();
if (!r.ok) throw new Error(d.error || 'Save failed');
apPassword.value = '';
showApMessage(d.message || 'Hotspot updated. Change takes effect on next restart or mode switch.', 'success');
} catch (e) {
showApMessage(e.message, 'danger');
} finally {
apSave.disabled = false;
}
});
function showMessage(text, kind) {
message.textContent = text;
message.className = `alert alert-${kind}`;
@@ -485,4 +531,5 @@ loadDeviceConfig();
loadRemoteConfig();
loadUploadHealth();
loadUplinkStatus();
loadApConfig();
setInterval(loadUplinkStatus, 15000);