mirror of
https://github.com/Tria-plc/emaui.git
synced 2026-08-30 02:58:12 +00:00
feat: implement concurrent-safe token refreshing with session-aware error handling
This commit is contained in:
@@ -2,7 +2,8 @@ import { useEffect, useState, type ReactNode } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { PageLoader } from '@ema-platform/ui';
|
||||
import { authStorage } from '../utils/auth-storage';
|
||||
import { hydrateAuth, logout, setUser } from '../store/auth.slice';
|
||||
import { hydrateAuth, logout, setToken, setUser } from '../store/auth.slice';
|
||||
import { refreshAccessToken } from '../utils/refresh-token';
|
||||
import type { AuthUser } from '../types/auth.types';
|
||||
|
||||
const BASE_API_URL =
|
||||
@@ -38,10 +39,27 @@ export function AuthBootstrap({ children }: { children: ReactNode }) {
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`${BASE_API_URL}/auth/me`, {
|
||||
let response = await fetch(`${BASE_API_URL}/auth/me`, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
});
|
||||
|
||||
// An expired access token is the normal state after a day away — spend
|
||||
// the refresh token before deciding the session is over. Without this
|
||||
// a lapsed token logs the user out on load even though the credential
|
||||
// to renew it is sitting right next to it in storage.
|
||||
if (response.status === 401 || response.status === 403) {
|
||||
try {
|
||||
const fresh = await refreshAccessToken();
|
||||
dispatch(setToken(fresh));
|
||||
response = await fetch(`${BASE_API_URL}/auth/me`, {
|
||||
headers: { Authorization: `Bearer ${fresh}` },
|
||||
});
|
||||
} catch {
|
||||
// No refresh token, or the server rejected it — fall through to
|
||||
// the logout below.
|
||||
}
|
||||
}
|
||||
|
||||
if (response.ok) {
|
||||
const user = (await response.json()) as AuthUser;
|
||||
// Keep the persisted session as the source of truth when it is
|
||||
|
||||
Reference in New Issue
Block a user