feat: LUKS2 encryption, boot sequence fixes, onboarding auth, CI/CD
Some checks failed
Build Archipelago ISO / build-iso (push) Has been cancelled
Some checks failed
Build Archipelago ISO / build-iso (push) Has been cancelled
- LUKS2 full-partition encryption for /var/lib/archipelago/ (TASK-42) 4-partition layout: BIOS + EFI + root (30GB) + encrypted data AES-256-XTS with AES-NI detection, ChaCha20 fallback for ARM Auto-unlock via crypttab + random key file - Fix EFI boot errors: remove shim-signed, clean shim artifacts - Fix first-boot sequence: always show boot animation before onboarding - Fix stale localStorage causing login instead of onboarding (BUG-47) - Add auth.setup + auth.isSetup RPC handlers for password on clean install - Add onboarding methods to UNAUTHENTICATED_METHODS (DID sign 403 fix) - FileBrowser bundled in unbundled ISO, fix auto-login Secure cookie (BUG-46) - Kiosk mode: xorg/chromium in rootfs, toggle script, MOTD instructions - Add Gitea Actions CI/CD workflow for automatic ISO builds Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -65,7 +65,9 @@ class FileBrowserClient {
|
||||
const token = text.replace(/^"|"$/g, '')
|
||||
// Store token as cookie — the only auth mechanism we use
|
||||
const expires = new Date(Date.now() + 24 * 60 * 60 * 1000).toUTCString()
|
||||
document.cookie = `auth=${token}; path=/app/filebrowser; SameSite=Strict; Secure; expires=${expires}`
|
||||
// Only set Secure flag on HTTPS — on HTTP it silently prevents the cookie from being stored
|
||||
const secure = window.location.protocol === 'https:' ? '; Secure' : ''
|
||||
document.cookie = `auth=${token}; path=/app/filebrowser; SameSite=Lax${secure}; expires=${expires}`
|
||||
this._authenticated = true
|
||||
return true
|
||||
} catch {
|
||||
|
||||
@@ -38,6 +38,19 @@ async function quickHealthCheck(): Promise<boolean> {
|
||||
}
|
||||
}
|
||||
|
||||
async function checkOnboarded(): Promise<boolean> {
|
||||
try {
|
||||
const result = await Promise.race([
|
||||
isOnboardingComplete(),
|
||||
new Promise<boolean>((resolve) => setTimeout(() => resolve(false), 3000)),
|
||||
])
|
||||
return result
|
||||
} catch {
|
||||
// Backend unreachable — fall back to localStorage only as last resort
|
||||
return localStorage.getItem('neode_onboarding_complete') === '1'
|
||||
}
|
||||
}
|
||||
|
||||
async function proceedToApp() {
|
||||
const devMode = import.meta.env.VITE_DEV_MODE
|
||||
if (devMode === 'setup' || devMode === 'existing') {
|
||||
@@ -45,23 +58,10 @@ async function proceedToApp() {
|
||||
return
|
||||
}
|
||||
|
||||
const localComplete = localStorage.getItem('neode_onboarding_complete') === '1'
|
||||
if (localComplete) {
|
||||
router.replace('/login').catch(() => {})
|
||||
return
|
||||
}
|
||||
|
||||
let seenOnboarding = false
|
||||
try {
|
||||
const result = await Promise.race([
|
||||
isOnboardingComplete(),
|
||||
new Promise<boolean>((resolve) => setTimeout(() => resolve(false), 3000)),
|
||||
])
|
||||
seenOnboarding = result
|
||||
} catch {
|
||||
seenOnboarding = false
|
||||
}
|
||||
router.replace(seenOnboarding ? '/login' : '/onboarding/intro').catch(() => {})
|
||||
// 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(() => {})
|
||||
}
|
||||
|
||||
function onServerReady() {
|
||||
@@ -98,14 +98,23 @@ onMounted(async () => {
|
||||
return
|
||||
}
|
||||
|
||||
// Production: quick health check
|
||||
// Production: check server health
|
||||
const isUp = await quickHealthCheck()
|
||||
|
||||
if (isUp) {
|
||||
proceedToApp()
|
||||
return
|
||||
// Server is up — check if onboarding is complete
|
||||
const onboarded = await checkOnboarded()
|
||||
if (onboarded) {
|
||||
// Returning user, server is up — go straight to login
|
||||
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.
|
||||
}
|
||||
|
||||
// Server not ready — show boot screen
|
||||
// Server not ready OR first boot — show boot screen
|
||||
showBootScreen.value = true
|
||||
})
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user