Fix 401 race condition: wire getAccessToken at module level
All checks were successful
CI / build (push) Successful in 1m9s
CI / docker (push) Successful in 47s
CI / deploy (push) Successful in 29s

The auth store loads tokens from localStorage synchronously at import
time, but configureAuth() was deferred to a useEffect — so the first
API requests fired before the token getter was wired, causing 401s on
hard refresh. Now getAccessToken reads from the store by default.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-03-13 22:09:46 +01:00
parent 96a5b00b99
commit 6794e4c234
2 changed files with 6 additions and 5 deletions

View File

@@ -1,15 +1,17 @@
import createClient, { type Middleware } from 'openapi-fetch';
import type { paths } from './schema';
import { config } from '../config';
import { useAuthStore } from '../auth/auth-store';
let getAccessToken: () => string | null = () => null;
let getAccessToken: () => string | null = () =>
useAuthStore.getState().accessToken;
let onUnauthorized: () => void = () => {};
export function configureAuth(opts: {
getAccessToken: () => string | null;
getAccessToken?: () => string | null;
onUnauthorized: () => void;
}) {
getAccessToken = opts.getAccessToken;
if (opts.getAccessToken) getAccessToken = opts.getAccessToken;
onUnauthorized = opts.onUnauthorized;
}

View File

@@ -7,10 +7,9 @@ export function useAuth() {
const { accessToken, isAuthenticated, refresh, logout } = useAuthStore();
const navigate = useNavigate();
// Wire API client to auth store
// Wire onUnauthorized handler (needs navigate from router context)
useEffect(() => {
configureAuth({
getAccessToken: () => useAuthStore.getState().accessToken,
onUnauthorized: async () => {
const ok = await useAuthStore.getState().refresh();
if (!ok) {