Fix emergency token being rejected by axios interceptor

Non-JWT tokens (like emergency access tokens) were treated as expired
by isTokenExpired(), triggering a MSAL silent refresh that fails and
clears the token. Fix: non-JWT tokens are treated as never-expired and
skip the 401-retry refresh path.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Vadym Samoilenko 2026-03-23 19:14:31 +00:00
parent 4f88c8b565
commit eaa518b443

View file

@ -14,11 +14,14 @@ export function registerTokenRefresher(fn: TokenRefresher) {
function isTokenExpired(token: string): boolean {
try {
const payload = JSON.parse(atob(token.split('.')[1]))
const parts = token.split('.')
if (parts.length !== 3) return false // not a JWT (e.g. emergency token) — never expires
const payload = JSON.parse(atob(parts[1]))
if (!payload.exp) return false
// Refresh 60s before actual expiry
return payload.exp * 1000 < Date.now() + 60_000
} catch {
return true
return false
}
}
@ -43,12 +46,14 @@ api.interceptors.request.use(async (config) => {
return config
})
// On 401 — try once more with a fresh token, then reload
// On 401 — try once more with a fresh token (JWT only), then reload
api.interceptors.response.use(
res => res,
async (error) => {
const originalRequest = error.config
if (error.response?.status === 401 && !originalRequest._retry && _refreshToken) {
const currentToken = sessionStorage.getItem('ac_access_token') ?? ''
const isJwt = currentToken.split('.').length === 3
if (error.response?.status === 401 && !originalRequest._retry && _refreshToken && isJwt) {
originalRequest._retry = true
try {
const fresh = await _refreshToken()