media-rip/frontend/src/router.ts
xpltd 1592407658 First-run admin setup wizard, password persistence, forced setup gate
- Admin enabled by default (was opt-in via env var)
- New /admin/status (public) and /admin/setup (first-run only) endpoints
- Setup endpoint locked after first use (returns 403)
- Admin password persisted to SQLite config table (survives restarts)
- Change password now persists to DB (was in-memory only)
- Frontend router guard forces /admin redirect until setup is complete
- AdminSetup.vue wizard: username + password + confirm
- Public config exposes admin_enabled/admin_setup_complete for frontend
- TLS warning only fires when password is actually configured
2026-03-21 20:01:13 -05:00

56 lines
1.3 KiB
TypeScript

import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(),
routes: [
{
path: '/',
name: 'home',
component: () => import('@/components/MainView.vue'),
},
{
path: '/admin',
name: 'admin',
component: () => import('@/components/AdminPanel.vue'),
},
],
})
// Cache the admin status check — fetched once per page load
let adminStatusCache: { enabled: boolean; setup_complete: boolean } | null = null
async function fetchAdminStatus() {
if (adminStatusCache) return adminStatusCache
try {
const res = await fetch('/api/admin/status')
if (res.ok) {
adminStatusCache = await res.json()
return adminStatusCache
}
} catch {
// Network error — let navigation proceed
}
return null
}
/** Clear the cached admin status — call after setup completes. */
export function clearAdminStatusCache() {
adminStatusCache = null
}
router.beforeEach(async (to) => {
// Skip if already heading to admin
if (to.name === 'admin') return true
const status = await fetchAdminStatus()
if (!status) return true // Can't determine — let it through
// Force setup if admin is enabled but no password set
if (status.enabled && !status.setup_complete) {
return { name: 'admin' }
}
return true
})
export default router