fix: alpha release hardening — onboarding, security, and ISO build

- Convert "Choose Your Path" screen to informative (read-only cards)
- Harden "Choose Your Setup" (gray out Coming Soon options, auto-select Fresh Start)
- Auto-fetch DID on mount with retry and auto-advance after success
- Improve backup download for mobile compatibility
- Add retry logic to verify step with graceful skip option
- Route verify → done → login for complete onboarding flow
- Add AIUI install confirmation via custom event (SEC-001)
- Add file path whitelist for AIUI file access (SEC-002)
- Add log redaction for container logs sent to AIUI (SEC-003)
- Add Secure flag to session cookie in production (SEC-004)
- Fix ISO build script to handle zstd compression errors gracefully
- Sync archipelago.service from live server

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-06 13:00:28 +00:00
co-authored by Claude Opus 4.6
parent e55fd3baf0
commit 589adb8b18
10 changed files with 252 additions and 198 deletions
+22 -11
View File
@@ -104,16 +104,27 @@ async function signChallenge() {
isSigning.value = true
errorMessage.value = ''
try {
const challenge = generateChallenge()
const { signature: sig } = await rpcClient.signChallenge(challenge)
signature.value = sig
verified.value = true
} catch (err) {
errorMessage.value = err instanceof Error ? err.message : 'Failed to sign challenge. Please try again.'
} finally {
isSigning.value = false
for (let attempt = 0; attempt < 3; attempt++) {
try {
const challenge = generateChallenge()
const { signature: sig } = await rpcClient.signChallenge(challenge)
signature.value = sig
verified.value = true
isSigning.value = false
return
} catch (err) {
const msg = err instanceof Error ? err.message : ''
const isRetryable = /502|503|timeout|fetch|network/i.test(msg)
if (!isRetryable || attempt === 2) {
errorMessage.value = isRetryable
? 'Server is not reachable. You can retry or skip this step.'
: (msg || 'Failed to sign challenge. You can retry or skip this step.')
} else {
await new Promise((r) => setTimeout(r, 1000 * (attempt + 1)))
}
}
}
isSigning.value = false
}
async function proceed() {
@@ -122,7 +133,7 @@ async function proceed() {
} catch {
/* localStorage fallback ensures we can proceed */
}
router.push('/login').catch(() => {})
router.push('/onboarding/done').catch(() => {})
}
async function skipForNow() {
@@ -131,7 +142,7 @@ async function skipForNow() {
} catch {
/* localStorage fallback ensures we can proceed */
}
router.push('/login').catch(() => {})
router.push('/onboarding/done').catch(() => {})
}
</script>