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:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user