From 4a9266e249ef3e774845efb0fa96dc8e55653e6e Mon Sep 17 00:00:00 2001 From: cclohmar Date: Thu, 6 Aug 2026 15:32:10 +0100 Subject: [PATCH] =?UTF-8?q?feat:=20auth=20management=20card=20in=20Setting?= =?UTF-8?q?s=20=E2=80=94=20edit=20master/viewer,=20enable/disable?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/app.js | 58 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 47 insertions(+), 11 deletions(-) diff --git a/public/app.js b/public/app.js index 6b58374..87305ad 100644 --- a/public/app.js +++ b/public/app.js @@ -11,6 +11,7 @@ let config = null; document.addEventListener('DOMContentLoaded', async () => { setupTabs(); await loadStatus(); + await loadConfig(); await loadCameras(); renderLiveGrid(); renderPlaybackCameras(); @@ -65,6 +66,14 @@ async function loadStatus() { } } +async function loadConfig() { + try { + const r = await fetch(API + '/config'); + const j = await r.json(); + if (j.success) config = j.data; + } catch(e) { config = {}; } +} + // ── Cameras ── async function loadCameras() { try { @@ -259,7 +268,27 @@ async function renderCameraCards() { `; return; } - container.innerHTML = cameras.map(c => ` + container.innerHTML = ` +
+

🔐 Authentication

+
+
+

Master (full access)

+ + +
+
+

Viewer (live wall only, port 8090)

+ + +
+
+
+
+ +
+
+ ` + cameras.map(c => `

📷 ${c.name || 'Unnamed'} ${c.ip} ⚙️ Config @@ -354,9 +383,23 @@ document.getElementById('btn-save').addEventListener('click', async () => { }); try { - // Include auth settings if present (first-run wizard). - const adminUser = document.getElementById('wiz-admin-user')?.value; - const adminPass = document.getElementById('wiz-admin-pass')?.value; + // Include auth settings from the management card. + const authEnabled = document.querySelector('[data-auth="auth-enabled"]')?.checked || false; + const masterUser = document.querySelector('[data-auth="master-user"]')?.value || ''; + const masterPass = document.querySelector('[data-auth="master-pass"]')?.value || ''; + const viewerUser = document.querySelector('[data-auth="viewer-user"]')?.value || ''; + const viewerPass = document.querySelector('[data-auth="viewer-pass"]')?.value || ''; + const viewerEnabled = document.querySelector('[data-auth="viewer-enabled"]')?.checked || false; + + cfg.auth = cfg.auth || {}; + cfg.auth.enabled = authEnabled; + cfg.auth.master = cfg.auth.master || {}; + cfg.auth.master.username = masterUser; + cfg.auth.viewer = cfg.auth.viewer || {}; + cfg.auth.viewer.username = viewerUser; + cfg.auth.viewer.enabled = viewerEnabled || false; + if (masterPass) { cfg.auth.master.password = masterPass; cfg.auth.master.enabled = true; } + if (viewerPass) { cfg.auth.viewer.password = viewerPass; } // Fetch current config, then post updated version. const cr = await fetch(API + '/config'); @@ -364,13 +407,6 @@ document.getElementById('btn-save').addEventListener('click', async () => { const cfg = cj.data || {}; cfg.cameras = updatedCameras; - // Set auth if admin credentials were provided. - if (adminUser && adminPass) { - cfg.auth = cfg.auth || {}; - cfg.auth.enabled = true; - cfg.auth.master = { username: adminUser, password: adminPass, enabled: true }; - } - const r = await fetch(API + '/config', { method: 'POST', headers: { 'Content-Type': 'application/json' },