phx-react
Version:
PHX REACT
109 lines • 4.98 kB
JavaScript
;
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