fix: bundle FileBrowser, auto-login tty1, boot/auth debug logging

- ISO build: configure insecure registry for root podman so FileBrowser
  image can be pulled during build (was failing with HTTPS error)
- Auto-login on tty1 so no password prompt on console
- RootRedirect: persistent debug logging to sessionStorage
  (view in DevTools > Application > Session Storage > archipelago_boot_log)
- Logs: health check, onboarding state, routing decisions, 401 handling

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-27 11:12:31 +00:00
parent 1fe72860fb
commit 546481bc15
2 changed files with 48 additions and 18 deletions

View File

@@ -21,6 +21,14 @@ import BootScreen from '@/components/BootScreen.vue'
const router = useRouter()
const showBootScreen = ref(false)
function log(msg: string, data?: unknown) {
const ts = new Date().toISOString()
const entry = `[RootRedirect ${ts}] ${msg}` + (data !== undefined ? ` ${JSON.stringify(data)}` : '')
console.log(entry)
const prev = sessionStorage.getItem('archipelago_boot_log') || ''
sessionStorage.setItem('archipelago_boot_log', prev + entry + '\n')
}
async function quickHealthCheck(): Promise<boolean> {
try {
const ac = new AbortController()
@@ -32,8 +40,11 @@ async function quickHealthCheck(): Promise<boolean> {
signal: ac.signal,
})
clearTimeout(t)
return res.status !== 502 && res.status !== 503
} catch {
const ok = res.status !== 502 && res.status !== 503
log('healthCheck', { status: res.status, ok })
return ok
} catch (e) {
log('healthCheck FAILED', { error: String(e) })
return false
}
}
@@ -44,24 +55,27 @@ async function checkOnboarded(): Promise<boolean> {
isOnboardingComplete(),
new Promise<boolean>((resolve) => setTimeout(() => resolve(false), 3000)),
])
log('checkOnboarded', { result })
return result
} catch {
// Backend unreachable — fall back to localStorage only as last resort
return localStorage.getItem('neode_onboarding_complete') === '1'
} catch (e) {
const fallback = localStorage.getItem('neode_onboarding_complete') === '1'
log('checkOnboarded ERROR, localStorage fallback', { error: String(e), fallback })
return fallback
}
}
async function proceedToApp() {
const devMode = import.meta.env.VITE_DEV_MODE
if (devMode === 'setup' || devMode === 'existing') {
log('proceedToApp devMode', { devMode })
router.replace('/login').catch(() => {})
return
}
// Always check backend for authoritative onboarding state
// (localStorage can be stale from a previous install on the same IP)
const onboarded = await checkOnboarded()
router.replace(onboarded ? '/login' : '/onboarding/intro').catch(() => {})
const dest = onboarded ? '/login' : '/onboarding/intro'
log('proceedToApp navigating', { onboarded, dest })
router.replace(dest).catch(() => {})
}
function onServerReady() {
@@ -74,44 +88,42 @@ function onServerReady() {
onMounted(async () => {
const devMode = import.meta.env.VITE_DEV_MODE
log('mounted', { devMode, from_boot: sessionStorage.getItem('archipelago_from_boot'), from_splash: sessionStorage.getItem('archipelago_from_splash') })
// Coming back from boot screen — let App.vue's SplashScreen take over
if (sessionStorage.getItem('archipelago_from_boot') === '1') {
log('from_boot=1, deferring to SplashScreen')
return
}
// Splash already completed this session — go to app
if (sessionStorage.getItem('archipelago_from_splash') === '1') {
log('from_splash=1, proceedToApp')
proceedToApp()
return
}
// Standard dev modes
if (devMode === 'setup' || devMode === 'existing') {
log('devMode shortcut', { devMode })
proceedToApp()
return
}
// Boot dev mode — always show boot screen (first load only)
if (devMode === 'boot') {
log('devMode=boot, showing boot screen')
showBootScreen.value = true
return
}
// Production: check server health
const isUp = await quickHealthCheck()
log('production flow', { isUp })
if (isUp) {
// Server is up — check if onboarding is complete
const onboarded = await checkOnboarded()
if (onboarded) {
// Returning user, server is up — go straight to login
log('server up + onboarded → proceedToApp')
proceedToApp()
return
}
// First boot: server is up but onboarding not done yet.
// Show boot animation anyway — it lets services fully warm up
// (containers, DID resolver, etc.) before onboarding starts.
log('server up + NOT onboarded → boot screen')
}
// Server not ready OR first boot — show boot screen