fix: auth, container resilience, ISO build, gamepad polish
- fix: login disconnect — verify session before WebSocket connect - fix: 403 on app install — distinguish CSRF vs RBAC errors, only retry CSRF - fix: health monitor now watches ALL containers (removed skip list for backend services like nbxplorer, databases, UI containers) - fix: server.get-state added to CSRF-exempt list (read-only) - fix: ISO build includes container-specs.sh and lib/common.sh in rootfs so reconcile actually works on fresh installs - fix: gamepad nav — improved Server tab zone nav, focus styles, autofocus - chore: move L484 web-only apps to Services tab - chore: install store for cross-view install tracking Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -78,11 +78,22 @@ class RPCClient {
|
||||
}
|
||||
throw new Error('Session expired')
|
||||
}
|
||||
// CSRF 403: retry twice after delay (cookie may have been
|
||||
// updated by a concurrent Set-Cookie response not yet visible to JS)
|
||||
if (response.status === 403 && attempt < maxRetries - 1) {
|
||||
await new Promise((r) => setTimeout(r, 500))
|
||||
continue
|
||||
// 403: read body to distinguish CSRF (retryable) from RBAC (permanent)
|
||||
if (response.status === 403) {
|
||||
let reason = ''
|
||||
try {
|
||||
const body: RPCResponse<unknown> = await response.json()
|
||||
reason = body.error?.message || ''
|
||||
} catch { /* body parse failed */ }
|
||||
|
||||
const isCsrf = !reason || reason.toLowerCase().includes('csrf')
|
||||
if (isCsrf && attempt < maxRetries - 1) {
|
||||
// CSRF mismatch — cookie may have been updated by a concurrent
|
||||
// Set-Cookie response not yet visible to JS. Retry after delay.
|
||||
await new Promise((r) => setTimeout(r, 500))
|
||||
continue
|
||||
}
|
||||
throw new Error(reason || `HTTP 403: Forbidden`)
|
||||
}
|
||||
const err = new Error(`HTTP ${response.status}: ${response.statusText}`)
|
||||
const isRetryable = response.status === 502 || response.status === 503
|
||||
|
||||
Reference in New Issue
Block a user