let refreshTokenFn = null;
export const setRefreshTokenFunction = (fn) => {
refreshTokenFn = fn;
};
const API = axios.create({
baseURL: appConfig.baseUrl,
headers: {
"Content-Type": "application/json",
"platform": "web",
},
});
let isRefreshing = false;
let failedRequestsQueue = [];
let hasRefreshedOnce = false;
const processQueue = (error, token) => {
failedRequestsQueue.forEach((request) => {
if (error) {
request.reject(error);
} else {
request.resolve(token);
}
});
failedRequestsQueue = [];
};
const handleSessionExpired = () => {
signOut({ callbackUrl: "/buyer/auth/sign-in" });
return Promise.reject(new Error("Session expired. Please log in again."));
};
const responseInterceptorError = async (error) => {
const originalRequest = error.config;
if (error?.response?.status === 401) {
debugger;
if (hasRefreshedOnce) {
return handleSessionExpired();
}
const session = await getSession();
if (session?.user?.remember === "false") {
signOut({ callbackUrl: "/buyer/auth/sign-in" });
return Promise.reject(new Error("Session expired. Please log in again."));
}
if (isRefreshing) {
return new Promise((resolve, reject) => {
failedRequestsQueue.push({ resolve, reject });
})
.then((token) => {
originalRequest.headers.Authorization = `Bearer ${token}`;
return API(originalRequest);
})
.catch((err) => Promise.reject(err));
}
isRefreshing = true;
try {
if (!refreshTokenFn) {
throw new Error("Refresh token function not set");
}
const result = await refreshTokenFn();
const updatedSession = await getSession();
const newAccessToken = updatedSession?.user?.access;
if (!newAccessToken) {
throw new Error("Failed to refresh access token");
}
processQueue(null, newAccessToken);
originalRequest.headers.Authorization = `Bearer ${newAccessToken}`;
hasRefreshedOnce = true;
return API(originalRequest);
} catch (refreshError) {
processQueue(refreshError, null);
signOut({ callbackUrl: "/buyer/auth/sign-in" });
return Promise.reject(refreshError);
} finally {
isRefreshing = false;
}
}
return Promise.reject(error);
};
API.interceptors.request.use(requestInterceptor, requestInterceptorError);
API.interceptors.response.use((response) => response,responseInterceptorError);
export default API;