fix(setup,ui): risolve errori setup + logo SVG theme-aware

- setup: corregge path templates (sibling di api/, non figlio) e firma TemplateResponse
- setup: invalida sessione client dopo operazioni che ruotano l'API key (init DB, creazione admin, cambio password, attivazione utente)
- api_client: include il nome del campo nei messaggi di errore 422 (FastAPI validation)
- ui: nuovo componente _app_logo.html (SVG inline theme-aware) usato su login e navbar
This commit is contained in:
Adriano Dal Pastro
2026-05-20 07:42:49 +00:00
parent 182aa9fa9a
commit 6772e3166a
6 changed files with 80 additions and 19 deletions
+2 -2
View File
@@ -26,7 +26,7 @@ from src.backend.services.measurement_service import calculate_pass_fail
router = APIRouter(prefix="/api/setup", tags=["setup"])
_templates_dir = Path(__file__).resolve().parent.parent / "templates"
_templates_dir = Path(__file__).resolve().parent.parent.parent / "templates"
templates = Jinja2Templates(directory=str(_templates_dir))
@@ -215,7 +215,7 @@ async def _seed_default_station(session: AsyncSession, admin_user: User) -> None
async def setup_page(request: Request):
"""Serve the setup page HTML."""
_check_setup_enabled()
return templates.TemplateResponse("setup/setup.html", {"request": request})
return templates.TemplateResponse(request, "setup/setup.html")
@router.get("/status")
+19
View File
@@ -559,6 +559,19 @@
return data;
}
/* Setup operations rotate api_keys (DB init, admin creation, password
* change, user (de)activation). Any Flask session held in this browser
* still carries the old key, so we clear it to force a fresh /auth/login. */
async function invalidateClientSession() {
try {
await fetch('/auth/logout', {
method: 'POST',
credentials: 'same-origin',
redirect: 'manual',
});
} catch (_) { /* best-effort */ }
}
/* ------------------------------------------------------------------ */
/* Check DB status */
/* ------------------------------------------------------------------ */
@@ -635,6 +648,7 @@
try {
const data = await apiPost('/init-db', { password: setupPassword });
showToast(data.message, 'success');
await invalidateClientSession();
await checkStatus();
} catch (e) {
showToast(e.message, 'error');
@@ -667,6 +681,7 @@
admin_display_name: display,
});
showToast(data.message, 'success');
await invalidateClientSession();
// Clear form
document.getElementById('admin-username').value = '';
document.getElementById('admin-password').value = '';
@@ -690,6 +705,7 @@
if (data.measurements_created) msg += ', measurements: ' + data.measurements_created;
msg += ')';
showToast(msg, 'success');
await invalidateClientSession();
await loadUsers();
} catch (e) {
showToast(e.message, 'error');
@@ -876,6 +892,7 @@
if (pwd) body.user_password = pwd;
var data = await apiPost('/manage-user', body);
showToast(data.message, 'success');
await invalidateClientSession();
closeModal('modal-user');
await loadUsers();
} catch (e) {
@@ -908,6 +925,7 @@
new_password: newPwd,
});
showToast(data.message, 'success');
await invalidateClientSession();
closeModal('modal-password');
} catch (e) {
showToast(e.message, 'error');
@@ -924,6 +942,7 @@
user_id: userId,
});
showToast(data.message, 'success');
await invalidateClientSession();
await loadUsers();
} catch (e) {
showToast(e.message, 'error');