fix: enable remote dashboard access by acquiring auth cookie on startup

When accessing the dashboard remotely (--host 0.0.0.0), all API calls
returned 401 because the frontend never acquired an auth_token cookie.
Added initializeAuth() that fetches /api/auth/token before React renders,
so the browser has the cookie before any TanStack Query hooks fire.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
catlog22
2026-03-26 23:36:44 +08:00
parent 25d4764d7f
commit e83063bd29
2 changed files with 24 additions and 3 deletions

View File

@@ -232,6 +232,25 @@ export async function initializeCsrfToken(): Promise<void> {
}
}
// ========== Auth Initialization ==========
/**
* Acquire auth cookie from server.
* On localhost the auth middleware bypasses public paths, so the cookie is
* redundant but harmless. For remote access (--host 0.0.0.0) the cookie
* is required — without it every API call returns 401.
*
* Must be called once before the React tree renders so that TanStack Query
* hooks already have the cookie when they fire their first requests.
*/
export async function initializeAuth(): Promise<void> {
try {
await fetch('/api/auth/token', { credentials: 'same-origin' });
} catch {
// Server may not be reachable yet — localhost public-path bypass still works
}
}
// ========== Base Fetch Wrapper ==========
/**

View File

@@ -7,14 +7,16 @@ import 'react-resizable/css/styles.css'
import 'xterm/css/xterm.css'
import { loadMessagesForLocale, getInitialLocale } from './lib/i18n'
import { logWebVitals } from './lib/webVitals'
import { initializeAuth } from './lib/api'
async function bootstrapApplication() {
const rootElement = document.getElementById('root')
if (!rootElement) throw new Error('Failed to find the root element')
// CSRF token initialization is deferred to first mutating request
// This eliminates network RTT from app startup path
// See: ccw/frontend/src/lib/api.ts - fetchApi handles lazy token fetch
// Acquire auth cookie before rendering required for remote access (--host 0.0.0.0).
// On localhost, auth middleware bypasses public paths so this is harmless.
await initializeAuth()
const locale = await getInitialLocale()
// Load only the active locale's messages (lazy load secondary on demand)