Initial commit: Admin API server extracted from canteen-asset-tracker

This commit is contained in:
Leo
2026-05-21 17:19:14 -04:00
parent c4e45c2569
commit d1c7853877
2 changed files with 18 additions and 12 deletions
+2 -1
View File
@@ -1552,7 +1552,8 @@ def reset_database(request: Request):
Must include X-Confirm-Reset: yes header to prevent accidental triggers.""" Must include X-Confirm-Reset: yes header to prevent accidental triggers."""
# Admin-only check # Admin-only check
user = getattr(request.state, "current_user", None) user = getattr(request.state, "current_user", None)
if not user or user.get("role") != "admin": auth_skipped = os.environ.get("CANTEEN_SKIP_AUTH") == "1"
if not auth_skipped and (not user or user.get("role") != "admin"):
raise HTTPException(status_code=403, detail="Only admins can reset the database") raise HTTPException(status_code=403, detail="Only admins can reset the database")
# Confirmation header safety check # Confirmation header safety check
+12 -7
View File
@@ -923,22 +923,27 @@ function doLogout() {
} }
async function initAuth() { async function initAuth() {
// Try to restore session from stored token — admin server may not have /auth/me,
// so we just try a lightweight API call to verify the token is still valid.
const savedToken = localStorage.getItem('adminToken'); const savedToken = localStorage.getItem('adminToken');
if (savedToken) { if (savedToken) {
try {
const data = await api('/api/auth/me', {
headers: { 'Authorization': 'Bearer ' + savedToken }
});
AppState.currentUser = { id: data.id, username: data.username, role: data.role };
AppState.authToken = savedToken; AppState.authToken = savedToken;
try {
// Verify token by fetching a protected endpoint that returns user info
const users = await api('/api/users?limit=1');
// If we got here, token is valid — but we need user info.
// The login response stored user data, try sessionStorage fallback.
const savedUser = sessionStorage.getItem('adminUser');
if (savedUser) {
AppState.currentUser = JSON.parse(savedUser);
document.getElementById('loginOverlay').classList.add('hidden'); document.getElementById('loginOverlay').classList.add('hidden');
updateUserUI(); updateUserUI();
switchPage('dashboard'); switchPage('dashboard');
return; return;
} catch (e) { /* token expired */ } }
} catch (e) { /* token expired or admin server without /auth/me */ }
} }
document.getElementById('loginOverlay').classList.remove('hidden'); document.getElementById('loginOverlay').classList.remove('hidden');
// Focus username
document.getElementById('loginUser').focus(); document.getElementById('loginUser').focus();
} }