fix: batch beta fixes — 13 issues from 2026-03-28 testing
Some checks failed
Build Archipelago ISO (dev) / build-iso (push) Has been cancelled
Some checks failed
Build Archipelago ISO (dev) / build-iso (push) Has been cancelled
Frontend (neode-ui): - Login double-enter: change @keyup.enter to @keydown.enter (#10) - Login loop on LAN: post-login session verify before navigation (#12) - Splash flash: reorder isReady/showSplash, add black fallback div (#7) - Skip button text: remove "skip this step" from onboarding (#8) - Password UI: import existing ChangePasswordSection in Settings (#11) - Arrow key focus trap: add tab-order fallback when spatial nav fails (#13) ISO/Boot (image-recipe): - Step counter: TOTAL_STEPS=7 → 8 to match actual step count - GRUB theme: add desktop-image-scale-method stretch, widen menu - Boot noise: add loglevel=0, rd.systemd.show_status=false to kernel - USB removal: copy reboot script to tmpfs, exec from there - Tor setup: rewrite python3 JSON generation as bash heredoc - Doctor/reconcile: copy scripts into rootfs, fix missing file errors - zstd: add to rootfs packages for initramfs compression Docs: - BETA-ISSUES-20260328.md: full issue tracker - INSTALL-SCREENS-DESIGN.md: editable TUI mockups 522 tests pass, vue-tsc clean. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -56,7 +56,7 @@
|
||||
autocomplete="off"
|
||||
class="w-full px-4 py-3 bg-transparent border border-white/20 rounded-lg text-white placeholder-white/40 focus:outline-none focus:border-white/40 focus:ring-1 focus:ring-white/20 transition-colors"
|
||||
:placeholder="t('login.enterPasswordSetup')"
|
||||
@keyup.enter="handleSetupWithSound"
|
||||
@keydown.enter="handleSetupWithSound"
|
||||
:disabled="loading || formDisabled"
|
||||
/>
|
||||
</div>
|
||||
@@ -72,7 +72,7 @@
|
||||
autocomplete="off"
|
||||
class="w-full px-4 py-3 bg-transparent border border-white/20 rounded-lg text-white placeholder-white/40 focus:outline-none focus:border-white/40 focus:ring-1 focus:ring-white/20 transition-colors"
|
||||
:placeholder="t('login.confirmPasswordPlaceholder')"
|
||||
@keyup.enter="handleSetupWithSound"
|
||||
@keydown.enter="handleSetupWithSound"
|
||||
:disabled="loading || formDisabled"
|
||||
/>
|
||||
</div>
|
||||
@@ -156,7 +156,7 @@
|
||||
autocomplete="off"
|
||||
class="w-full px-4 py-3 bg-transparent border border-white/20 rounded-lg text-white placeholder-white/40 focus:outline-none focus:border-white/40 focus:ring-1 focus:ring-white/20 transition-colors"
|
||||
:placeholder="t('login.enterPasswordPlaceholder')"
|
||||
@keyup.enter="handleLoginWithSound"
|
||||
@keydown.enter="handleLoginWithSound"
|
||||
:disabled="loading || formDisabled"
|
||||
/>
|
||||
</div>
|
||||
@@ -424,6 +424,14 @@ async function handleLogin() {
|
||||
setTimeout(() => totpInputRef.value?.focus(), 100)
|
||||
return
|
||||
}
|
||||
// Verify session cookie works before navigating (prevents login loop on LAN)
|
||||
try {
|
||||
await rpcClient.call({ method: 'server.echo', params: { message: 'session-check' } })
|
||||
} catch {
|
||||
error.value = 'Login succeeded but session could not be established. Try clearing cookies and refreshing.'
|
||||
store.logout()
|
||||
return
|
||||
}
|
||||
stopSynthwave()
|
||||
whooshAway.value = true
|
||||
playLoginSuccessWhoosh()
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<!-- Content Area -->
|
||||
<div class="flex flex-col items-center gap-4 sm:gap-6 mb-4 sm:mb-6 px-3 sm:px-4">
|
||||
<div class="w-full max-w-[600px] space-y-4 sm:space-y-6">
|
||||
<p v-if="serverStarting" class="text-orange-400/80 text-sm">Server is still starting up. You can try again shortly or skip this step.</p>
|
||||
<p v-if="serverStarting" class="text-orange-400/80 text-sm">Server is still starting up. Please try again shortly.</p>
|
||||
<p v-else-if="errorMessage" class="text-red-400 text-sm">{{ errorMessage }}</p>
|
||||
<!-- Passphrase Input -->
|
||||
<div class="path-option-card cursor-default px-4 py-4 sm:px-6 sm:py-6">
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
<!-- Content Area -->
|
||||
<div class="flex flex-col items-center gap-6 mb-6">
|
||||
<p v-if="serverStarting" class="text-orange-400/80 text-sm">Server is still starting up. You can try again shortly or skip this step.</p>
|
||||
<p v-if="serverStarting" class="text-orange-400/80 text-sm">Server is still starting up. Please try again shortly.</p>
|
||||
<p v-else-if="errorMessage" class="text-red-400 text-sm">{{ errorMessage }}</p>
|
||||
<!-- Sign Button (if not verified yet) -->
|
||||
<button
|
||||
@@ -127,7 +127,7 @@ async function signChallenge() {
|
||||
if (isRetryable) {
|
||||
serverStarting.value = true
|
||||
} else {
|
||||
errorMessage.value = msg || 'Failed to sign challenge. You can retry or skip this step.'
|
||||
errorMessage.value = msg || 'Failed to sign challenge. Please try again.'
|
||||
}
|
||||
} else {
|
||||
await new Promise((r) => setTimeout(r, 1000 * (attempt + 1)))
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
import AccountSection from '@/views/settings/AccountSection.vue'
|
||||
import ChangePasswordSection from '@/views/settings/ChangePasswordSection.vue'
|
||||
import SystemSection from '@/views/settings/SystemSection.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="pb-6">
|
||||
<AccountSection />
|
||||
<ChangePasswordSection />
|
||||
<SystemSection />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user