Fix 401 race condition: wire getAccessToken at module level
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:
@@ -1,15 +1,17 @@
|
|||||||
import createClient, { type Middleware } from 'openapi-fetch';
|
import createClient, { type Middleware } from 'openapi-fetch';
|
||||||
import type { paths } from './schema';
|
import type { paths } from './schema';
|
||||||
import { config } from '../config';
|
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 = () => {};
|
let onUnauthorized: () => void = () => {};
|
||||||
|
|
||||||
export function configureAuth(opts: {
|
export function configureAuth(opts: {
|
||||||
getAccessToken: () => string | null;
|
getAccessToken?: () => string | null;
|
||||||
onUnauthorized: () => void;
|
onUnauthorized: () => void;
|
||||||
}) {
|
}) {
|
||||||
getAccessToken = opts.getAccessToken;
|
if (opts.getAccessToken) getAccessToken = opts.getAccessToken;
|
||||||
onUnauthorized = opts.onUnauthorized;
|
onUnauthorized = opts.onUnauthorized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,10 +7,9 @@ export function useAuth() {
|
|||||||
const { accessToken, isAuthenticated, refresh, logout } = useAuthStore();
|
const { accessToken, isAuthenticated, refresh, logout } = useAuthStore();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
// Wire API client to auth store
|
// Wire onUnauthorized handler (needs navigate from router context)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
configureAuth({
|
configureAuth({
|
||||||
getAccessToken: () => useAuthStore.getState().accessToken,
|
|
||||||
onUnauthorized: async () => {
|
onUnauthorized: async () => {
|
||||||
const ok = await useAuthStore.getState().refresh();
|
const ok = await useAuthStore.getState().refresh();
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
|
|||||||
Reference in New Issue
Block a user