mirror of
https://github.com/Tria-plc/emaui.git
synced 2026-09-01 18:13:28 +00:00
65 lines
2.1 KiB
TypeScript
65 lines
2.1 KiB
TypeScript
import { fetchBaseQuery, type BaseQueryFn } from "@reduxjs/toolkit/query/react";
|
|
import type { FetchArgs, FetchBaseQueryError } from "@reduxjs/toolkit/query";
|
|
import { resolveSessionContext } from "../session";
|
|
|
|
/**
|
|
* The one place the backend URL is resolved: VITE_BASE_API_URL from the env,
|
|
* falling back to the local dev API (3001 — the portal itself owns 3000 for
|
|
* the Fayda redirect). Import this; do not re-derive it.
|
|
*/
|
|
export const BASE_API_URL =
|
|
(import.meta as { env?: Record<string, string> }).env?.[
|
|
"VITE_BASE_API_URL"
|
|
]?.trim() || "http://localhost:3000/api";
|
|
|
|
let _onTokenExpired: (() => Promise<string>) | null = null;
|
|
let _onAuthFailure: (() => void) | null = null;
|
|
|
|
export function configureTokenRefresh(config: {
|
|
onTokenExpired: () => Promise<string>;
|
|
onAuthFailure: () => void;
|
|
}) {
|
|
_onTokenExpired = config.onTokenExpired;
|
|
_onAuthFailure = config.onAuthFailure;
|
|
}
|
|
|
|
export const baseQueryWithReauth: BaseQueryFn<
|
|
string | FetchArgs,
|
|
unknown,
|
|
FetchBaseQueryError
|
|
> = async (args, api, extraOptions) => {
|
|
const baseQuery = fetchBaseQuery({
|
|
baseUrl: BASE_API_URL,
|
|
prepareHeaders: (headers) => {
|
|
const { token, sessionHeaders } = resolveSessionContext(
|
|
api.getState() as { auth?: { token?: string } },
|
|
);
|
|
if (token) headers.set("Authorization", `Bearer ${token}`);
|
|
Object.entries(sessionHeaders).forEach(([k, v]) => headers.set(k, v));
|
|
return headers;
|
|
},
|
|
});
|
|
|
|
let result = await baseQuery(args, api, extraOptions);
|
|
|
|
if (result.error?.status === 401) {
|
|
if (_onTokenExpired) {
|
|
try {
|
|
await _onTokenExpired();
|
|
result = await baseQuery(args, api, extraOptions);
|
|
} catch (err) {
|
|
// Only a rejected refresh token ends the session. A network blip or a
|
|
// 5xx leaves the original 401 for the screen to report, rather than
|
|
// throwing the user out of a session that is still valid.
|
|
if ((err as { sessionExpired?: boolean })?.sessionExpired) {
|
|
_onAuthFailure?.();
|
|
}
|
|
}
|
|
} else {
|
|
_onAuthFailure?.();
|
|
}
|
|
}
|
|
|
|
return result;
|
|
};
|