fix(auth): treat expired JWTs as no identity, improve logout and token verification flow, and bump deps

This commit is contained in:
2026-03-04 01:11:19 +00:00
parent 89b9d01628
commit 34d40f7370
11 changed files with 1232 additions and 1581 deletions

View File

@@ -238,9 +238,12 @@ interface IActionContext {
}
const getActionContext = (): IActionContext => {
return {
identity: loginStatePart.getState().identity,
};
const identity = loginStatePart.getState().identity;
// Treat expired JWTs as no identity — prevents stale persisted sessions from firing requests
if (identity && identity.expiresAt && identity.expiresAt < Date.now()) {
return { identity: null };
}
return { identity };
};
// Login Action
@@ -271,24 +274,23 @@ export const loginAction = loginStatePart.createAction<{
}
});
// Logout Action
// Logout Action — always clears state, even if identity is expired/missing
export const logoutAction = loginStatePart.createAction(async (statePartArg) => {
const context = getActionContext();
if (!context.identity) return statePartArg.getState();
const typedRequest = new plugins.domtools.plugins.typedrequest.TypedRequest<
interfaces.requests.IReq_AdminLogout
>('/typedrequest', 'adminLogout');
try {
await typedRequest.fire({
identity: context.identity,
});
} catch (error) {
console.error('Logout error:', error);
// Try to notify server, but don't block logout if identity is missing/expired
if (context.identity) {
const typedRequest = new plugins.domtools.plugins.typedrequest.TypedRequest<
interfaces.requests.IReq_AdminLogout
>('/typedrequest', 'adminLogout');
try {
await typedRequest.fire({ identity: context.identity });
} catch (error) {
console.error('Logout error:', error);
}
}
// Clear login state regardless
// Always clear login state
return {
identity: null,
isLoggedIn: false,
@@ -1338,6 +1340,12 @@ async function dispatchCombinedRefreshAction() {
}
} catch (error) {
console.error('Combined refresh failed:', error);
// If the error looks like an auth failure (invalid JWT), force re-login
const errMsg = String(error);
if (errMsg.includes('invalid') || errMsg.includes('unauthorized') || errMsg.includes('401')) {
await loginStatePart.dispatchAction(logoutAction, null);
window.location.reload();
}
}
}