UNPKG

phx-react

Version:

PHX REACT

169 lines 8.43 kB
"use strict"; exports.__esModule = true; exports.PHXAxiosInstance = void 0; var tslib_1 = require("tslib"); var axios_1 = tslib_1.__importDefault(require("axios")); var async_lock_1 = tslib_1.__importDefault(require("async-lock")); var read_env_config_1 = require("./read-env-config"); var constants_1 = require("./utils/constants"); var saveCookiesClient_1 = tslib_1.__importDefault(require("./components/Func/saveCookiesClient")); var getCookieSession_1 = tslib_1.__importDefault(require("./components/Func/getCookieSession")); var headers_1 = require("next/headers"); var js_cookie_1 = tslib_1.__importDefault(require("js-cookie")); var sessionStore_1 = require("./components/Func/sessionStore"); var lock = new async_lock_1["default"](); var isServer = typeof window === 'undefined'; var publicUrl = (0, read_env_config_1.getEnv)('NEXT_PUBLIC_API_GATEWAY', process.env.NEXT_PUBLIC_API_GATEWAY); var internalUrl = (0, read_env_config_1.getEnv)('NEXT_PUBLIC_API_GATEWAY_INTERNAL', process.env.NEXT_PUBLIC_API_GATEWAY_INTERNAL); var PHXAxiosInstance = axios_1["default"].create({ baseURL: publicUrl }); exports.PHXAxiosInstance = PHXAxiosInstance; // === GLOBAL CACHE === var accessTokenCache = null; var refreshingPromise = null; // Lấy header (cookie + origin) khi chạy SSR var getAuthHeaders = function () { if (!isServer) return {}; var cookieStore = (0, headers_1.cookies)(); var cookieHeader = cookieStore .getAll() .map(function (_a) { var name = _a.name, value = _a.value; return "".concat(name, "=").concat(value); }) .join('; '); return { Cookie: cookieHeader, hostname: (0, headers_1.headers)().get('origin') || undefined }; }; // Lưu lại refresh token từ header của response (chỉ SSR) var saveRefreshTokenServer = function (response) { var _a; var setCookieHeader = ((_a = response.headers['set-cookie']) === null || _a === void 0 ? void 0 : _a[0]) || ''; var match = setCookieHeader.match(/refresh_token=([^;]+)/); var refreshToken = (match === null || match === void 0 ? void 0 : match[1]) || ''; (0, headers_1.cookies)().set(constants_1.COOKIE_REFRESH_TOKEN, refreshToken, { path: '/', httpOnly: true, secure: true, sameSite: 'none', expires: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000) }); }; // Hàm refresh access token, chỉ gọi 1 lần duy nhất tại một thời điểm var refreshAccessToken = function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) { if (!refreshingPromise) { refreshingPromise = lock.acquire(constants_1.COOKIE_REFRESH_TOKEN, function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () { var url, response, newToken, currentSession, err_1; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 2, 3, 4]); url = "".concat(isServer ? (0, headers_1.headers)().get('origin') : '', "/api/authenticate/refresh-token"); return [4 /*yield*/, axios_1["default"].post(url, {}, { headers: getAuthHeaders() })]; case 1: response = _a.sent(); newToken = response.data.token; 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; (0, saveCookiesClient_1["default"])({ value: tslib_1.__assign(tslib_1.__assign({}, currentSession), { access_token: newToken }) }); // Cập nhật cache accessTokenCache = newToken; // Lưu refresh token phía server nếu SSR if (isServer) { saveRefreshTokenServer(response); } return [2 /*return*/, newToken]; case 2: err_1 = _a.sent(); (0, sessionStore_1.clearSession)(); if (isServer) { (0, headers_1.cookies)()["delete"](constants_1.COOKIE_SESSION_SIGN_IN); } js_cookie_1["default"].remove(constants_1.COOKIE_SESSION_SIGN_IN); if (!isServer) { window.location.href = constants_1.loginPage; } throw err_1; case 3: refreshingPromise = null; return [7 /*endfinally*/]; case 4: return [2 /*return*/]; } }); }); }); } return [2 /*return*/, refreshingPromise]; }); }); }; // Request interceptor: luôn thêm Authorization nếu có access_token PHXAxiosInstance.interceptors.request.use(function (config) { return tslib_1.__awaiter(void 0, void 0, void 0, function () { var token, session, err_2, fresh; var _a; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: config.headers = config.headers || {}; token = accessTokenCache; if (!token) { session = (0, getCookieSession_1["default"])(); token = (session === null || session === void 0 ? void 0 : session.access_token) || null; if (token) accessTokenCache = token; } if (!token) return [3 /*break*/, 7]; config.headers.Authorization = "Bearer ".concat(token); if (!isServer) return [3 /*break*/, 7]; _b.label = 1; case 1: _b.trys.push([1, 3, , 7]); return [4 /*yield*/, axios_1["default"].post("".concat(internalUrl, "/authen/authenticate"), {}, { headers: tslib_1.__assign({ Authorization: "Bearer ".concat(token) }, getAuthHeaders()) })]; case 2: _b.sent(); return [3 /*break*/, 7]; case 3: err_2 = _b.sent(); if (!(((_a = err_2.response) === null || _a === void 0 ? void 0 : _a.status) === 401)) return [3 /*break*/, 5]; return [4 /*yield*/, refreshAccessToken()]; case 4: fresh = _b.sent(); config.headers.Authorization = "Bearer ".concat(fresh); return [3 /*break*/, 6]; case 5: throw err_2; case 6: return [3 /*break*/, 7]; case 7: return [2 /*return*/, config]; } }); }); }); // Response interceptor: bắt lỗi 401, gọi refresh và retry PHXAxiosInstance.interceptors.response.use(function (res) { return res; }, function (error) { return tslib_1.__awaiter(void 0, void 0, void 0, function () { var originalRequest, newToken, e_1; var _a; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: originalRequest = error.config; if (!(((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 401 && !originalRequest._retry)) return [3 /*break*/, 4]; originalRequest._retry = true; _b.label = 1; case 1: _b.trys.push([1, 3, , 4]); return [4 /*yield*/, refreshAccessToken()]; case 2: newToken = _b.sent(); originalRequest.headers = originalRequest.headers || {}; originalRequest.headers.Authorization = "Bearer ".concat(newToken); return [2 /*return*/, PHXAxiosInstance(originalRequest)]; case 3: e_1 = _b.sent(); return [2 /*return*/, Promise.reject(e_1)]; case 4: return [2 /*return*/, Promise.reject(error)]; } }); }); }); //# sourceMappingURL=axiosInstance.js.map