phx-uikit 1.0.219 → 1.0.221
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -3,87 +3,38 @@ exports.__esModule = true;
|
|
|
3
3
|
exports.PHXAxiosInstance = void 0;
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
5
|
var axios_1 = tslib_1.__importDefault(require("axios"));
|
|
6
|
+
var async_lock_1 = tslib_1.__importDefault(require("async-lock"));
|
|
6
7
|
var read_env_config_1 = require("./read-env-config");
|
|
7
8
|
var constants_1 = require("./utils/constants");
|
|
8
9
|
var saveCookiesClient_1 = tslib_1.__importDefault(require("./components/Func/saveCookiesClient"));
|
|
9
10
|
var getCookieSession_1 = tslib_1.__importDefault(require("./components/Func/getCookieSession"));
|
|
10
11
|
var headers_1 = require("next/headers");
|
|
11
|
-
|
|
12
|
-
// @ts-ignore
|
|
13
|
-
if (!globalThis.__PHX_REFRESH__) {
|
|
14
|
-
// @ts-ignore
|
|
15
|
-
globalThis.__PHX_REFRESH__ = {
|
|
16
|
-
isRefreshing: false,
|
|
17
|
-
failedQueue: []
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
// @ts-ignore
|
|
21
|
-
var getRefreshState = function () { return globalThis.__PHX_REFRESH__; };
|
|
12
|
+
var lock = new async_lock_1["default"]();
|
|
22
13
|
var publicUrl = (0, read_env_config_1.getEnv)('NEXT_PUBLIC_API_GATEWAY', process.env.NEXT_PUBLIC_API_GATEWAY);
|
|
23
14
|
var internalUrl = (0, read_env_config_1.getEnv)('NEXT_PUBLIC_API_GATEWAY_INTERNAL', process.env.NEXT_PUBLIC_API_GATEWAY_INTERNAL);
|
|
24
15
|
var isServer = typeof window === 'undefined';
|
|
25
|
-
var processQueue = function (error, token) {
|
|
26
|
-
if (token === void 0) { token = null; }
|
|
27
|
-
var failedQueue = getRefreshState().failedQueue;
|
|
28
|
-
failedQueue.forEach(function (prom) {
|
|
29
|
-
if (error) {
|
|
30
|
-
prom.reject(error);
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
33
|
-
prom.resolve(token);
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
getRefreshState().failedQueue = [];
|
|
37
|
-
};
|
|
38
16
|
var PHXAxiosInstance = axios_1["default"].create({
|
|
39
17
|
baseURL: publicUrl
|
|
40
18
|
});
|
|
41
19
|
exports.PHXAxiosInstance = PHXAxiosInstance;
|
|
20
|
+
// Lấy header (cookie + origin) khi chạy SSR
|
|
42
21
|
var getAuthHeaders = function () {
|
|
43
|
-
if (isServer)
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
return {};
|
|
22
|
+
if (!isServer)
|
|
23
|
+
return {};
|
|
24
|
+
var cookieStore = (0, headers_1.cookies)();
|
|
25
|
+
var cookieHeader = cookieStore
|
|
26
|
+
.getAll()
|
|
27
|
+
.map(function (_a) {
|
|
28
|
+
var name = _a.name, value = _a.value;
|
|
29
|
+
return "".concat(name, "=").concat(value);
|
|
30
|
+
})
|
|
31
|
+
.join('; ');
|
|
32
|
+
return {
|
|
33
|
+
Cookie: cookieHeader,
|
|
34
|
+
hostname: (0, headers_1.headers)().get('origin') || undefined
|
|
35
|
+
};
|
|
58
36
|
};
|
|
59
|
-
|
|
60
|
-
var response, newToken, currentSession, err_1;
|
|
61
|
-
return tslib_1.__generator(this, function (_a) {
|
|
62
|
-
switch (_a.label) {
|
|
63
|
-
case 0:
|
|
64
|
-
_a.trys.push([0, 2, , 3]);
|
|
65
|
-
return [4 /*yield*/, axios_1["default"].post("".concat(isServer ? (0, headers_1.headers)().get('origin') : '', "/api/authenticate/refresh-token"), {}, {
|
|
66
|
-
headers: getAuthHeaders()
|
|
67
|
-
})];
|
|
68
|
-
case 1:
|
|
69
|
-
response = _a.sent();
|
|
70
|
-
newToken = response.data.token;
|
|
71
|
-
currentSession = (0, getCookieSession_1["default"])();
|
|
72
|
-
(0, saveCookiesClient_1["default"])({ value: tslib_1.__assign(tslib_1.__assign({}, currentSession), { access_token: newToken }) });
|
|
73
|
-
if (isServer) {
|
|
74
|
-
saveRefreshTokenServer(response);
|
|
75
|
-
}
|
|
76
|
-
return [2 /*return*/, newToken];
|
|
77
|
-
case 2:
|
|
78
|
-
err_1 = _a.sent();
|
|
79
|
-
if (!isServer) {
|
|
80
|
-
window.location.href = constants_1.loginPage;
|
|
81
|
-
}
|
|
82
|
-
throw err_1;
|
|
83
|
-
case 3: return [2 /*return*/];
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
}); };
|
|
37
|
+
// Lưu lại refresh token từ header của response (chỉ SSR)
|
|
87
38
|
var saveRefreshTokenServer = function (response) {
|
|
88
39
|
var _a;
|
|
89
40
|
var setCookieHeader = ((_a = response.headers['set-cookie']) === null || _a === void 0 ? void 0 : _a[0]) || '';
|
|
@@ -97,23 +48,65 @@ var saveRefreshTokenServer = function (response) {
|
|
|
97
48
|
expires: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000)
|
|
98
49
|
});
|
|
99
50
|
};
|
|
51
|
+
// Gọi API refresh-token, đồng bộ hoá với AsyncLock
|
|
52
|
+
var refreshAccessToken = function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
53
|
+
return tslib_1.__generator(this, function (_a) {
|
|
54
|
+
return [2 /*return*/, lock.acquire('refresh_token', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
55
|
+
var currentSession, existing, url, response, newToken, updatedSession, err_1;
|
|
56
|
+
return tslib_1.__generator(this, function (_a) {
|
|
57
|
+
switch (_a.label) {
|
|
58
|
+
case 0:
|
|
59
|
+
currentSession = (0, getCookieSession_1["default"])();
|
|
60
|
+
existing = currentSession === null || currentSession === void 0 ? void 0 : currentSession.access_token;
|
|
61
|
+
if (existing)
|
|
62
|
+
return [2 /*return*/, existing
|
|
63
|
+
// Thực sự gọi API refresh
|
|
64
|
+
];
|
|
65
|
+
_a.label = 1;
|
|
66
|
+
case 1:
|
|
67
|
+
_a.trys.push([1, 3, , 4]);
|
|
68
|
+
url = "".concat(isServer ? (0, headers_1.headers)().get('origin') : '', "/api/authenticate/refresh-token");
|
|
69
|
+
return [4 /*yield*/, axios_1["default"].post(url, {}, { headers: getAuthHeaders() })];
|
|
70
|
+
case 2:
|
|
71
|
+
response = _a.sent();
|
|
72
|
+
newToken = response.data.token;
|
|
73
|
+
updatedSession = (0, getCookieSession_1["default"])();
|
|
74
|
+
(0, saveCookiesClient_1["default"])({
|
|
75
|
+
value: tslib_1.__assign(tslib_1.__assign({}, updatedSession), { access_token: newToken })
|
|
76
|
+
});
|
|
77
|
+
// Lưu refresh token SSR nếu cần
|
|
78
|
+
if (isServer)
|
|
79
|
+
saveRefreshTokenServer(response);
|
|
80
|
+
return [2 /*return*/, newToken];
|
|
81
|
+
case 3:
|
|
82
|
+
err_1 = _a.sent();
|
|
83
|
+
if (!isServer) {
|
|
84
|
+
window.location.href = constants_1.loginPage;
|
|
85
|
+
}
|
|
86
|
+
throw err_1;
|
|
87
|
+
case 4: return [2 /*return*/];
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
}); })];
|
|
91
|
+
});
|
|
92
|
+
}); };
|
|
93
|
+
// Request interceptor: luôn thêm Authorization nếu có access_token
|
|
100
94
|
PHXAxiosInstance.interceptors.request.use(function (config) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
101
|
-
var
|
|
95
|
+
var session, token, err_2, fresh;
|
|
102
96
|
var _a;
|
|
103
97
|
return tslib_1.__generator(this, function (_b) {
|
|
104
98
|
switch (_b.label) {
|
|
105
99
|
case 0:
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
if (!
|
|
109
|
-
config.headers
|
|
100
|
+
session = (0, getCookieSession_1["default"])();
|
|
101
|
+
token = session === null || session === void 0 ? void 0 : session.access_token;
|
|
102
|
+
if (!token) return [3 /*break*/, 7];
|
|
103
|
+
config.headers = config.headers || {};
|
|
104
|
+
config.headers.Authorization = "Bearer ".concat(token);
|
|
110
105
|
if (!isServer) return [3 /*break*/, 7];
|
|
111
106
|
_b.label = 1;
|
|
112
107
|
case 1:
|
|
113
108
|
_b.trys.push([1, 3, , 7]);
|
|
114
|
-
return [4 /*yield*/, axios_1["default"].post("".concat(internalUrl, "/authen/authenticate"), {}, {
|
|
115
|
-
headers: tslib_1.__assign({ Authorization: "Bearer ".concat(authTokenCookie) }, getAuthHeaders())
|
|
116
|
-
})];
|
|
109
|
+
return [4 /*yield*/, axios_1["default"].post("".concat(internalUrl, "/authen/authenticate"), {}, { headers: tslib_1.__assign({ Authorization: "Bearer ".concat(token) }, getAuthHeaders()) })];
|
|
117
110
|
case 2:
|
|
118
111
|
_b.sent();
|
|
119
112
|
return [3 /*break*/, 7];
|
|
@@ -122,8 +115,8 @@ PHXAxiosInstance.interceptors.request.use(function (config) { return tslib_1.__a
|
|
|
122
115
|
if (!(((_a = err_2.response) === null || _a === void 0 ? void 0 : _a.status) === 401)) return [3 /*break*/, 5];
|
|
123
116
|
return [4 /*yield*/, refreshAccessToken()];
|
|
124
117
|
case 4:
|
|
125
|
-
|
|
126
|
-
config.headers.Authorization = "Bearer ".concat(
|
|
118
|
+
fresh = _b.sent();
|
|
119
|
+
config.headers.Authorization = "Bearer ".concat(fresh);
|
|
127
120
|
return [3 /*break*/, 6];
|
|
128
121
|
case 5: throw err_2;
|
|
129
122
|
case 6: return [3 /*break*/, 7];
|
|
@@ -131,45 +124,29 @@ PHXAxiosInstance.interceptors.request.use(function (config) { return tslib_1.__a
|
|
|
131
124
|
}
|
|
132
125
|
});
|
|
133
126
|
}); });
|
|
134
|
-
|
|
135
|
-
|
|
127
|
+
// Response interceptor: bắt 401, gọi refresh và retry
|
|
128
|
+
PHXAxiosInstance.interceptors.response.use(function (res) { return res; }, function (error) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
129
|
+
var originalRequest, newToken, e_1;
|
|
136
130
|
var _a;
|
|
137
131
|
return tslib_1.__generator(this, function (_b) {
|
|
138
132
|
switch (_b.label) {
|
|
139
133
|
case 0:
|
|
140
134
|
originalRequest = error.config;
|
|
141
|
-
|
|
142
|
-
if (!(((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 401 && !originalRequest._retry)) return [3 /*break*/, 5];
|
|
143
|
-
if (refreshState.isRefreshing) {
|
|
144
|
-
return [2 /*return*/, new Promise(function (resolve, reject) {
|
|
145
|
-
refreshState.failedQueue.push({
|
|
146
|
-
resolve: function (token) {
|
|
147
|
-
originalRequest.headers.Authorization = 'Bearer ' + token;
|
|
148
|
-
resolve(PHXAxiosInstance(originalRequest));
|
|
149
|
-
},
|
|
150
|
-
reject: function (err) { return reject(err); }
|
|
151
|
-
});
|
|
152
|
-
})];
|
|
153
|
-
}
|
|
135
|
+
if (!(((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 401 && originalRequest._retry !== true)) return [3 /*break*/, 4];
|
|
154
136
|
originalRequest._retry = true;
|
|
155
|
-
refreshState.isRefreshing = true;
|
|
156
137
|
_b.label = 1;
|
|
157
138
|
case 1:
|
|
158
|
-
_b.trys.push([1, 3,
|
|
139
|
+
_b.trys.push([1, 3, , 4]);
|
|
159
140
|
return [4 /*yield*/, refreshAccessToken()];
|
|
160
141
|
case 2:
|
|
161
142
|
newToken = _b.sent();
|
|
162
|
-
|
|
143
|
+
originalRequest.headers = originalRequest.headers || {};
|
|
163
144
|
originalRequest.headers.Authorization = "Bearer ".concat(newToken);
|
|
164
145
|
return [2 /*return*/, PHXAxiosInstance(originalRequest)];
|
|
165
146
|
case 3:
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
case 4:
|
|
170
|
-
refreshState.isRefreshing = false;
|
|
171
|
-
return [7 /*endfinally*/];
|
|
172
|
-
case 5: return [2 /*return*/, Promise.reject(error)];
|
|
147
|
+
e_1 = _b.sent();
|
|
148
|
+
return [2 /*return*/, Promise.reject(e_1)];
|
|
149
|
+
case 4: return [2 /*return*/, Promise.reject(error)];
|
|
173
150
|
}
|
|
174
151
|
});
|
|
175
152
|
}); });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"axiosInstance.js","sourceRoot":"","sources":["../../src/axiosInstance.ts"],"names":[],"mappings":";;;;AAAA,
|
|
1
|
+
{"version":3,"file":"axiosInstance.js","sourceRoot":"","sources":["../../src/axiosInstance.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,85 +1,36 @@
|
|
|
1
1
|
import { __assign, __awaiter, __generator } from "tslib";
|
|
2
2
|
import axios from 'axios';
|
|
3
|
+
import AsyncLock from 'async-lock';
|
|
3
4
|
import { getEnv } from './read-env-config';
|
|
4
5
|
import { COOKIE_REFRESH_TOKEN, loginPage } from './utils/constants';
|
|
5
6
|
import saveCookiesClient from './components/Func/saveCookiesClient';
|
|
6
7
|
import PHXFuncGetCookieSession from './components/Func/getCookieSession';
|
|
7
8
|
import { cookies, headers } from 'next/headers';
|
|
8
|
-
|
|
9
|
-
// @ts-ignore
|
|
10
|
-
if (!globalThis.__PHX_REFRESH__) {
|
|
11
|
-
// @ts-ignore
|
|
12
|
-
globalThis.__PHX_REFRESH__ = {
|
|
13
|
-
isRefreshing: false,
|
|
14
|
-
failedQueue: []
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
// @ts-ignore
|
|
18
|
-
var getRefreshState = function () { return globalThis.__PHX_REFRESH__; };
|
|
9
|
+
var lock = new AsyncLock();
|
|
19
10
|
var publicUrl = getEnv('NEXT_PUBLIC_API_GATEWAY', process.env.NEXT_PUBLIC_API_GATEWAY);
|
|
20
11
|
var internalUrl = getEnv('NEXT_PUBLIC_API_GATEWAY_INTERNAL', process.env.NEXT_PUBLIC_API_GATEWAY_INTERNAL);
|
|
21
12
|
var isServer = typeof window === 'undefined';
|
|
22
|
-
var processQueue = function (error, token) {
|
|
23
|
-
if (token === void 0) { token = null; }
|
|
24
|
-
var failedQueue = getRefreshState().failedQueue;
|
|
25
|
-
failedQueue.forEach(function (prom) {
|
|
26
|
-
if (error) {
|
|
27
|
-
prom.reject(error);
|
|
28
|
-
}
|
|
29
|
-
else {
|
|
30
|
-
prom.resolve(token);
|
|
31
|
-
}
|
|
32
|
-
});
|
|
33
|
-
getRefreshState().failedQueue = [];
|
|
34
|
-
};
|
|
35
13
|
var PHXAxiosInstance = axios.create({
|
|
36
14
|
baseURL: publicUrl
|
|
37
15
|
});
|
|
16
|
+
// Lấy header (cookie + origin) khi chạy SSR
|
|
38
17
|
var getAuthHeaders = function () {
|
|
39
|
-
if (isServer)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
return {};
|
|
18
|
+
if (!isServer)
|
|
19
|
+
return {};
|
|
20
|
+
var cookieStore = cookies();
|
|
21
|
+
var cookieHeader = cookieStore
|
|
22
|
+
.getAll()
|
|
23
|
+
.map(function (_a) {
|
|
24
|
+
var name = _a.name, value = _a.value;
|
|
25
|
+
return "".concat(name, "=").concat(value);
|
|
26
|
+
})
|
|
27
|
+
.join('; ');
|
|
28
|
+
return {
|
|
29
|
+
Cookie: cookieHeader,
|
|
30
|
+
hostname: headers().get('origin') || undefined
|
|
31
|
+
};
|
|
54
32
|
};
|
|
55
|
-
|
|
56
|
-
var response, newToken, currentSession, err_1;
|
|
57
|
-
return __generator(this, function (_a) {
|
|
58
|
-
switch (_a.label) {
|
|
59
|
-
case 0:
|
|
60
|
-
_a.trys.push([0, 2, , 3]);
|
|
61
|
-
return [4 /*yield*/, axios.post("".concat(isServer ? headers().get('origin') : '', "/api/authenticate/refresh-token"), {}, {
|
|
62
|
-
headers: getAuthHeaders()
|
|
63
|
-
})];
|
|
64
|
-
case 1:
|
|
65
|
-
response = _a.sent();
|
|
66
|
-
newToken = response.data.token;
|
|
67
|
-
currentSession = PHXFuncGetCookieSession();
|
|
68
|
-
saveCookiesClient({ value: __assign(__assign({}, currentSession), { access_token: newToken }) });
|
|
69
|
-
if (isServer) {
|
|
70
|
-
saveRefreshTokenServer(response);
|
|
71
|
-
}
|
|
72
|
-
return [2 /*return*/, newToken];
|
|
73
|
-
case 2:
|
|
74
|
-
err_1 = _a.sent();
|
|
75
|
-
if (!isServer) {
|
|
76
|
-
window.location.href = loginPage;
|
|
77
|
-
}
|
|
78
|
-
throw err_1;
|
|
79
|
-
case 3: return [2 /*return*/];
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
}); };
|
|
33
|
+
// Lưu lại refresh token từ header của response (chỉ SSR)
|
|
83
34
|
var saveRefreshTokenServer = function (response) {
|
|
84
35
|
var _a;
|
|
85
36
|
var setCookieHeader = ((_a = response.headers['set-cookie']) === null || _a === void 0 ? void 0 : _a[0]) || '';
|
|
@@ -93,23 +44,65 @@ var saveRefreshTokenServer = function (response) {
|
|
|
93
44
|
expires: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000)
|
|
94
45
|
});
|
|
95
46
|
};
|
|
47
|
+
// Gọi API refresh-token, đồng bộ hoá với AsyncLock
|
|
48
|
+
var refreshAccessToken = function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
49
|
+
return __generator(this, function (_a) {
|
|
50
|
+
return [2 /*return*/, lock.acquire('refresh_token', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
51
|
+
var currentSession, existing, url, response, newToken, updatedSession, err_1;
|
|
52
|
+
return __generator(this, function (_a) {
|
|
53
|
+
switch (_a.label) {
|
|
54
|
+
case 0:
|
|
55
|
+
currentSession = PHXFuncGetCookieSession();
|
|
56
|
+
existing = currentSession === null || currentSession === void 0 ? void 0 : currentSession.access_token;
|
|
57
|
+
if (existing)
|
|
58
|
+
return [2 /*return*/, existing
|
|
59
|
+
// Thực sự gọi API refresh
|
|
60
|
+
];
|
|
61
|
+
_a.label = 1;
|
|
62
|
+
case 1:
|
|
63
|
+
_a.trys.push([1, 3, , 4]);
|
|
64
|
+
url = "".concat(isServer ? headers().get('origin') : '', "/api/authenticate/refresh-token");
|
|
65
|
+
return [4 /*yield*/, axios.post(url, {}, { headers: getAuthHeaders() })];
|
|
66
|
+
case 2:
|
|
67
|
+
response = _a.sent();
|
|
68
|
+
newToken = response.data.token;
|
|
69
|
+
updatedSession = PHXFuncGetCookieSession();
|
|
70
|
+
saveCookiesClient({
|
|
71
|
+
value: __assign(__assign({}, updatedSession), { access_token: newToken })
|
|
72
|
+
});
|
|
73
|
+
// Lưu refresh token SSR nếu cần
|
|
74
|
+
if (isServer)
|
|
75
|
+
saveRefreshTokenServer(response);
|
|
76
|
+
return [2 /*return*/, newToken];
|
|
77
|
+
case 3:
|
|
78
|
+
err_1 = _a.sent();
|
|
79
|
+
if (!isServer) {
|
|
80
|
+
window.location.href = loginPage;
|
|
81
|
+
}
|
|
82
|
+
throw err_1;
|
|
83
|
+
case 4: return [2 /*return*/];
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}); })];
|
|
87
|
+
});
|
|
88
|
+
}); };
|
|
89
|
+
// Request interceptor: luôn thêm Authorization nếu có access_token
|
|
96
90
|
PHXAxiosInstance.interceptors.request.use(function (config) { return __awaiter(void 0, void 0, void 0, function () {
|
|
97
|
-
var
|
|
91
|
+
var session, token, err_2, fresh;
|
|
98
92
|
var _a;
|
|
99
93
|
return __generator(this, function (_b) {
|
|
100
94
|
switch (_b.label) {
|
|
101
95
|
case 0:
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
if (!
|
|
105
|
-
config.headers
|
|
96
|
+
session = PHXFuncGetCookieSession();
|
|
97
|
+
token = session === null || session === void 0 ? void 0 : session.access_token;
|
|
98
|
+
if (!token) return [3 /*break*/, 7];
|
|
99
|
+
config.headers = config.headers || {};
|
|
100
|
+
config.headers.Authorization = "Bearer ".concat(token);
|
|
106
101
|
if (!isServer) return [3 /*break*/, 7];
|
|
107
102
|
_b.label = 1;
|
|
108
103
|
case 1:
|
|
109
104
|
_b.trys.push([1, 3, , 7]);
|
|
110
|
-
return [4 /*yield*/, axios.post("".concat(internalUrl, "/authen/authenticate"), {}, {
|
|
111
|
-
headers: __assign({ Authorization: "Bearer ".concat(authTokenCookie) }, getAuthHeaders())
|
|
112
|
-
})];
|
|
105
|
+
return [4 /*yield*/, axios.post("".concat(internalUrl, "/authen/authenticate"), {}, { headers: __assign({ Authorization: "Bearer ".concat(token) }, getAuthHeaders()) })];
|
|
113
106
|
case 2:
|
|
114
107
|
_b.sent();
|
|
115
108
|
return [3 /*break*/, 7];
|
|
@@ -118,8 +111,8 @@ PHXAxiosInstance.interceptors.request.use(function (config) { return __awaiter(v
|
|
|
118
111
|
if (!(((_a = err_2.response) === null || _a === void 0 ? void 0 : _a.status) === 401)) return [3 /*break*/, 5];
|
|
119
112
|
return [4 /*yield*/, refreshAccessToken()];
|
|
120
113
|
case 4:
|
|
121
|
-
|
|
122
|
-
config.headers.Authorization = "Bearer ".concat(
|
|
114
|
+
fresh = _b.sent();
|
|
115
|
+
config.headers.Authorization = "Bearer ".concat(fresh);
|
|
123
116
|
return [3 /*break*/, 6];
|
|
124
117
|
case 5: throw err_2;
|
|
125
118
|
case 6: return [3 /*break*/, 7];
|
|
@@ -127,45 +120,29 @@ PHXAxiosInstance.interceptors.request.use(function (config) { return __awaiter(v
|
|
|
127
120
|
}
|
|
128
121
|
});
|
|
129
122
|
}); });
|
|
130
|
-
|
|
131
|
-
|
|
123
|
+
// Response interceptor: bắt 401, gọi refresh và retry
|
|
124
|
+
PHXAxiosInstance.interceptors.response.use(function (res) { return res; }, function (error) { return __awaiter(void 0, void 0, void 0, function () {
|
|
125
|
+
var originalRequest, newToken, e_1;
|
|
132
126
|
var _a;
|
|
133
127
|
return __generator(this, function (_b) {
|
|
134
128
|
switch (_b.label) {
|
|
135
129
|
case 0:
|
|
136
130
|
originalRequest = error.config;
|
|
137
|
-
|
|
138
|
-
if (!(((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 401 && !originalRequest._retry)) return [3 /*break*/, 5];
|
|
139
|
-
if (refreshState.isRefreshing) {
|
|
140
|
-
return [2 /*return*/, new Promise(function (resolve, reject) {
|
|
141
|
-
refreshState.failedQueue.push({
|
|
142
|
-
resolve: function (token) {
|
|
143
|
-
originalRequest.headers.Authorization = 'Bearer ' + token;
|
|
144
|
-
resolve(PHXAxiosInstance(originalRequest));
|
|
145
|
-
},
|
|
146
|
-
reject: function (err) { return reject(err); }
|
|
147
|
-
});
|
|
148
|
-
})];
|
|
149
|
-
}
|
|
131
|
+
if (!(((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 401 && originalRequest._retry !== true)) return [3 /*break*/, 4];
|
|
150
132
|
originalRequest._retry = true;
|
|
151
|
-
refreshState.isRefreshing = true;
|
|
152
133
|
_b.label = 1;
|
|
153
134
|
case 1:
|
|
154
|
-
_b.trys.push([1, 3,
|
|
135
|
+
_b.trys.push([1, 3, , 4]);
|
|
155
136
|
return [4 /*yield*/, refreshAccessToken()];
|
|
156
137
|
case 2:
|
|
157
138
|
newToken = _b.sent();
|
|
158
|
-
|
|
139
|
+
originalRequest.headers = originalRequest.headers || {};
|
|
159
140
|
originalRequest.headers.Authorization = "Bearer ".concat(newToken);
|
|
160
141
|
return [2 /*return*/, PHXAxiosInstance(originalRequest)];
|
|
161
142
|
case 3:
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
case 4:
|
|
166
|
-
refreshState.isRefreshing = false;
|
|
167
|
-
return [7 /*endfinally*/];
|
|
168
|
-
case 5: return [2 /*return*/, Promise.reject(error)];
|
|
143
|
+
e_1 = _b.sent();
|
|
144
|
+
return [2 /*return*/, Promise.reject(e_1)];
|
|
145
|
+
case 4: return [2 /*return*/, Promise.reject(error)];
|
|
169
146
|
}
|
|
170
147
|
});
|
|
171
148
|
}); });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"axiosInstance.js","sourceRoot":"","sources":["../../src/axiosInstance.ts"],"names":[],"mappings":";AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"axiosInstance.js","sourceRoot":"","sources":["../../src/axiosInstance.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "phx-uikit",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.221",
|
|
4
4
|
"description": "PHX REACT",
|
|
5
5
|
"main": "./dist/cjs/index.js",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -55,6 +55,7 @@
|
|
|
55
55
|
"@storybook/testing-library": "^0.0.14-next.2",
|
|
56
56
|
"@tailwindcss/forms": "^0.5.3",
|
|
57
57
|
"@testing-library/react": "^15.0.6",
|
|
58
|
+
"@types/async-lock": "^1.4.2",
|
|
58
59
|
"@types/crypto-js": "^4.2.2",
|
|
59
60
|
"@types/jest": "^29.5.11",
|
|
60
61
|
"@types/js-cookie": "^3.0.3",
|
|
@@ -95,6 +96,7 @@
|
|
|
95
96
|
]
|
|
96
97
|
},
|
|
97
98
|
"dependencies": {
|
|
99
|
+
"async-lock": "^1.4.1",
|
|
98
100
|
"axios": "^1.5.0",
|
|
99
101
|
"crypto-js": "^4.2.0",
|
|
100
102
|
"date-fns": "^2.30.0",
|