v1.8.8: fix admin auth — hide main until token verified, block unauthenticated access

This commit is contained in:
2026-05-28 20:34:06 +00:00
parent 49b5b195c3
commit 82879656c0
13 changed files with 351 additions and 4 deletions
+5 -1
View File
@@ -139,7 +139,11 @@ class ClaudeKeyUpdate(BaseModel):
def root(): return FileResponse("/opt/rag/static/index.html")
@app.get("/admin")
def admin_ui(): return FileResponse("/opt/rag/static/admin.html")
def admin_ui(request: Request):
from fastapi.responses import RedirectResponse
# Check for JWT in cookie or let the frontend handle auth redirect
token = request.cookies.get("admin_token") or request.headers.get("Authorization","").replace("Bearer ","")
return FileResponse("/opt/rag/static/admin.html")
@app.get("/library")
def library_ui(): return FileResponse("/opt/rag/static/library.html")
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -52341,3 +52341,339 @@ $3
del
$13
unacked_mutex
*5
$3
SET
$13
unacked_mutex
$32
d61b49c05acf11f199e682dacbd0314b
$4
PXAT
$13
1779998712204
*2
$3
del
$13
unacked_mutex
*5
$3
SET
$13
unacked_mutex
$32
11b803425ad011f199e682dacbd0314b
$4
PXAT
$13
1779998812216
*2
$3
del
$13
unacked_mutex
*5
$3
SET
$13
unacked_mutex
$32
4d5521f05ad011f199e682dacbd0314b
$4
PXAT
$13
1779998912232
*2
$3
del
$13
unacked_mutex
*5
$3
SET
$13
unacked_mutex
$32
88f1e3245ad011f199e682dacbd0314b
$4
PXAT
$13
1779999012244
*2
$3
del
$13
unacked_mutex
*5
$3
SET
$13
unacked_mutex
$32
c48f3cd85ad011f199e682dacbd0314b
$4
PXAT
$13
1779999112261
*2
$3
del
$13
unacked_mutex
*5
$3
SET
$13
unacked_mutex
$32
002bfd585ad111f199e682dacbd0314b
$4
PXAT
$13
1779999212274
*2
$3
del
$13
unacked_mutex
*5
$3
SET
$13
unacked_mutex
$32
3bc9bd785ad111f199e682dacbd0314b
$4
PXAT
$13
1779999312294
*2
$3
del
$13
unacked_mutex
*5
$3
SET
$13
unacked_mutex
$32
776677f45ad111f199e682dacbd0314b
$4
PXAT
$13
1779999412306
*2
$3
del
$13
unacked_mutex
*5
$3
SET
$13
unacked_mutex
$32
b303b34e5ad111f199e682dacbd0314b
$4
PXAT
$13
1779999512322
*2
$3
del
$13
unacked_mutex
*5
$3
SET
$13
unacked_mutex
$32
eea070225ad111f199e682dacbd0314b
$4
PXAT
$13
1779999612335
*2
$3
del
$13
unacked_mutex
*5
$3
SET
$13
unacked_mutex
$32
2a3dd3ea5ad211f199e682dacbd0314b
$4
PXAT
$13
1779999712352
*2
$3
del
$13
unacked_mutex
*5
$3
SET
$13
unacked_mutex
$32
65da99105ad211f199e682dacbd0314b
$4
PXAT
$13
1779999812365
*2
$3
del
$13
unacked_mutex
*5
$3
SET
$13
unacked_mutex
$32
a177f62a5ad211f199e682dacbd0314b
$4
PXAT
$13
1779999912382
*2
$3
del
$13
unacked_mutex
*5
$3
SET
$13
unacked_mutex
$32
dd14b89e5ad211f199e682dacbd0314b
$4
PXAT
$13
1780000012395
*2
$3
del
$13
unacked_mutex
*5
$3
SET
$13
unacked_mutex
$32
18b1ee445ad311f199e682dacbd0314b
$4
PXAT
$13
1780000112411
*2
$3
del
$13
unacked_mutex
*5
$3
SET
$13
unacked_mutex
$32
544ed9445ad311f199e682dacbd0314b
$4
PXAT
$13
1780000212425
*2
$3
del
$13
unacked_mutex
*5
$3
SET
$13
unacked_mutex
$32
8feb767e5ad311f199e682dacbd0314b
$4
PXAT
$13
1780000312437
*2
$3
del
$13
unacked_mutex
*5
$3
SET
$13
unacked_mutex
$32
cb882ea25ad311f199e682dacbd0314b
$4
PXAT
$13
1780000412449
*2
$3
del
$13
unacked_mutex
*5
$3
SET
$13
unacked_mutex
$32
0724da465ad411f199e682dacbd0314b
$4
PXAT
$13
1780000512462
*2
$3
del
$13
unacked_mutex
*5
$3
SET
$13
unacked_mutex
$32
42c17b405ad411f199e682dacbd0314b
$4
PXAT
$13
1780000612474
*2
$3
del
$13
unacked_mutex
*5
$3
SET
$13
unacked_mutex
$32
7e5e1dd45ad411f199e682dacbd0314b
$4
PXAT
$13
1780000712486
*2
$3
del
$13
unacked_mutex
+10 -3
View File
@@ -388,7 +388,7 @@ a[role=button]:active {
</aside>
<!-- Main -->
<div id="main" class="lg:ml-64 min-h-screen">
<div id="main" class="lg:ml-64 min-h-screen" style="display:none">
<!-- Top bar (mobile) -->
<header class="lg:hidden sticky top-0 z-20 glass border-b border-primary/20 px-4 py-3 flex items-center gap-3">
<button onclick="openSidebar()" class="text-on-surface-variant hover:text-primary">
@@ -1657,17 +1657,24 @@ async function saveClaudeKey() {
// ── Auto-login on page load ───────────────────────────────────────────────────
if (JWT_TOKEN) {
document.getElementById('login').style.display = 'none';
// Verify token before showing admin
fetch('/auth/me', {headers:{'Authorization':'Bearer '+JWT_TOKEN}})
.then(r => r.ok ? r.json() : null)
.then(u => {
if (!u || u.role !== 'admin') {
JWT_TOKEN = ''; localStorage.removeItem('admin_jwt');
document.getElementById('login').style.display = 'flex';
document.getElementById('main').style.display = 'none';
} else {
document.getElementById('login').style.display = 'none';
document.getElementById('main').style.display = '';
loadOverview();
}
}).catch(() => { loadOverview(); }); // network error — stay logged in
}).catch(() => {
// Network error — show login to be safe
document.getElementById('login').style.display = 'flex';
document.getElementById('main').style.display = 'none';
});
}
// ── Nav init ──────────────────────────────────────────────────────────────────