UNPKG

phx-react

Version:

PHX REACT

109 lines 4.98 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PHXAxiosInstance = void 0; const tslib_1 = require("tslib"); const axios_1 = tslib_1.__importDefault(require("axios")); const async_lock_1 = tslib_1.__importDefault(require("async-lock")); const read_env_config_1 = require("./read-env-config"); const constants_1 = require("./utils/constants"); const saveCookiesClient_1 = tslib_1.__importDefault(require("./components/Func/saveCookiesClient")); const getCookieSession_1 = tslib_1.__importDefault(require("./components/Func/getCookieSession")); const sessionStore_1 = require("./components/Func/sessionStore"); const js_cookie_1 = tslib_1.__importDefault(require("js-cookie")); const save_local_storage_1 = require("./components/Func/save-local-storage"); const lock = new async_lock_1.default(); const isServer = typeof window === 'undefined'; const publicUrl = (0, read_env_config_1.getEnv)('NEXT_PUBLIC_API_GATEWAY', process.env.NEXT_PUBLIC_API_GATEWAY); const internalUrl = (0, read_env_config_1.getEnv)('NEXT_PUBLIC_API_GATEWAY_INTERNAL', process.env.NEXT_PUBLIC_API_GATEWAY_INTERNAL); const PHXAxiosInstance = axios_1.default.create({ baseURL: publicUrl, }); exports.PHXAxiosInstance = PHXAxiosInstance; // === GLOBAL CACHE === let accessTokenCache = null; let refreshingPromise = null; // Hàm refresh access token, chỉ gọi 1 lần duy nhất tại một thời điểm const refreshAccessToken = async () => { if (!refreshingPromise) { refreshingPromise = lock.acquire(constants_1.COOKIE_REFRESH_TOKEN, async () => { try { const url = `/api/authenticate/refresh-token`; const response = await axios_1.default.post(url, {}); const newToken = response.data.token; const currentSession = (0, getCookieSession_1.default)(); // Lưu lại vào cookie phía client currentSession === null || currentSession === void 0 ? true : delete currentSession.access_token; // vì chuyển đổi sang lưu vào local storage nên phải xóa cookie js_cookie_1.default.remove(constants_1.COOKIE_SESSION_SIGN_IN); (0, saveCookiesClient_1.default)({ value: { ...currentSession, access_token: newToken } }); // Cập nhật cache accessTokenCache = newToken; return newToken; } catch (err) { (0, sessionStore_1.clearSession)(); js_cookie_1.default.remove(constants_1.COOKIE_SESSION_SIGN_IN); (0, save_local_storage_1.deleteLocalStorage)(constants_1.COOKIE_SESSION_SIGN_IN); if (!isServer) { window.location.href = constants_1.loginPage; } throw err; } finally { refreshingPromise = null; } }); } return refreshingPromise; }; // Request interceptor: luôn thêm Authorization nếu có access_token PHXAxiosInstance.interceptors.request.use(async (config) => { var _a; config.headers = config.headers || {}; // Ưu tiên lấy token từ cache let token = accessTokenCache; if (!token) { const session = (0, getCookieSession_1.default)(); token = (session === null || session === void 0 ? void 0 : session.access_token) || null; if (token) accessTokenCache = token; } if (token) { config.headers.Authorization = `Bearer ${token}`; // Nếu đang SSR, validate trước if (isServer) { try { await axios_1.default.post(`${internalUrl}/authen/authenticate`, {}, { headers: { Authorization: `Bearer ${token}` } }); } catch (err) { if (((_a = err.response) === null || _a === void 0 ? void 0 : _a.status) === 401) { const fresh = await refreshAccessToken(); config.headers.Authorization = `Bearer ${fresh}`; } else { throw err; } } } } return config; }); // Response interceptor: bắt lỗi 401, gọi refresh và retry PHXAxiosInstance.interceptors.response.use((res) => res, async (error) => { var _a; const originalRequest = error.config; if (((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 401 && !originalRequest._retry) { originalRequest._retry = true; try { const newToken = await refreshAccessToken(); originalRequest.headers = originalRequest.headers || {}; originalRequest.headers.Authorization = `Bearer ${newToken}`; return PHXAxiosInstance(originalRequest); } catch (e) { return Promise.reject(e); } } return Promise.reject(error); }); //# sourceMappingURL=axiosInstance.js.map