feat: rootless podman, session hardening, boot stability, sidebar fix
Rootless podman migration (TASK-11): - Remove sudo from all podman calls in PodmanClient + 8 backend files - Remove sudo from all podman/docker calls in deploy script - Restore full systemd security hardening: NoNewPrivileges, RestrictAddressFamilies, MemoryDenyWriteExecute, RestrictRealtime, RestrictNamespaces, RestrictSUIDSGID, SystemCallFilter, ProtectSystem=strict - Enable loginctl linger for rootless container persistence - Remove Ollama from auto-deploy (marketplace-only) Session & auth hardening: - Increase MAX_CONCURRENT_SESSIONS 20→50 (prevents eviction storms) - Debounced 401 redirect in rpc-client.ts (prevents redirect storms) Boot stability: - optimize-debian.sh: adds chrony, swap, removes policy-rc.d - deploy script: pre-restart chrony + swap setup - ISO build: chrony package, swap file creation - BootScreen: no longer clears localStorage (prevents splash replay) - RootRedirect: sole owner of localStorage clearing on server ready UI fixes: - Sidebar opacity default changed from 0→visible (fixes missing sidebar after page-persistence login without entrance animation) - Console.log/error wrapped in import.meta.env.DEV guards - Remove unused route import from RootRedirect Beta tracking: - CLAUDE.md: beta freeze protocol added - MASTER_PLAN.md: TASK-11, TASK-17, phase structure - BETA-PROGRESS.md: initial tracking doc - Tagged v1.2.0-alpha.1 as pre-rootless baseline Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -21,6 +21,7 @@ function getCsrfToken(): string | null {
|
||||
}
|
||||
|
||||
class RPCClient {
|
||||
private static _sessionExpiredRedirecting = false
|
||||
private baseUrl: string
|
||||
|
||||
constructor(baseUrl: string = '/rpc/v1') {
|
||||
@@ -55,9 +56,16 @@ class RPCClient {
|
||||
clearTimeout(timeoutId)
|
||||
|
||||
if (!response.ok) {
|
||||
// Session expired — redirect to login
|
||||
// Session expired — debounced redirect to login
|
||||
// Use a single shared timeout to prevent redirect storms when
|
||||
// multiple parallel requests all get 401 at once
|
||||
if (response.status === 401 && method !== 'auth.login') {
|
||||
window.location.href = '/login'
|
||||
if (!RPCClient._sessionExpiredRedirecting) {
|
||||
RPCClient._sessionExpiredRedirecting = true
|
||||
setTimeout(() => {
|
||||
window.location.href = '/login'
|
||||
}, 300)
|
||||
}
|
||||
throw new Error('Session expired')
|
||||
}
|
||||
const err = new Error(`HTTP ${response.status}: ${response.statusText}`)
|
||||
|
||||
Reference in New Issue
Block a user