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