@cemiar/auth-sdk 1.0.20 → 1.0.22
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.
|
@@ -5,12 +5,11 @@ export declare class CemiarAuthClient implements CemiarAuthClientInstance {
|
|
|
5
5
|
private readonly tenantId;
|
|
6
6
|
private readonly auds;
|
|
7
7
|
private readonly redirectUrl?;
|
|
8
|
-
private storage;
|
|
9
|
-
private readonly onTokenChange?;
|
|
10
8
|
private readonly onAuthFailure?;
|
|
11
|
-
private
|
|
9
|
+
private storage;
|
|
12
10
|
private loginMethod;
|
|
13
|
-
private
|
|
11
|
+
private isRefreshing;
|
|
12
|
+
private failedQueue;
|
|
14
13
|
constructor(config: CemiarAuthClientConfig);
|
|
15
14
|
getAccessToken(): string | null;
|
|
16
15
|
setAccessToken(token: string | null): void;
|
|
@@ -24,9 +23,8 @@ export declare class CemiarAuthClient implements CemiarAuthClientInstance {
|
|
|
24
23
|
createApiClient(options: CreateApiClientOptions): AxiosInstance;
|
|
25
24
|
attachInterceptors(instance: AxiosInstance): AxiosInstance;
|
|
26
25
|
private addAuthHeader;
|
|
26
|
+
private processQueue;
|
|
27
27
|
private handleResponseError;
|
|
28
|
-
private queueTokenRefresh;
|
|
29
|
-
private handleAuthFailure;
|
|
30
28
|
private loadLoginMethodFromStorage;
|
|
31
29
|
private persistLoginMethod;
|
|
32
30
|
private getCurrentLoginMethod;
|
|
@@ -15,31 +15,27 @@ function extractAccessToken(data) {
|
|
|
15
15
|
}
|
|
16
16
|
export class CemiarAuthClient {
|
|
17
17
|
constructor(config) {
|
|
18
|
-
var _a, _b
|
|
18
|
+
var _a, _b;
|
|
19
19
|
this.storage = createDefaultTokenStorage();
|
|
20
|
-
this.
|
|
20
|
+
this.isRefreshing = false;
|
|
21
|
+
this.failedQueue = [];
|
|
21
22
|
this.baseUrl = normalizeBaseUrl(config.baseUrl || "http://localhost:3000") + "/auth";
|
|
22
23
|
this.tenantId = config.tenantId;
|
|
23
24
|
this.auds = parseAuds(config.auds);
|
|
24
25
|
this.redirectUrl =
|
|
25
26
|
(_a = config.redirectUrl) !== null && _a !== void 0 ? _a : (isBrowser ? `${window.location.origin}/auth/microsoft/callback` : undefined);
|
|
26
|
-
this.
|
|
27
|
+
this.storage = (_b = config.storage) !== null && _b !== void 0 ? _b : createDefaultTokenStorage();
|
|
27
28
|
this.onAuthFailure = config.onAuthFailure;
|
|
28
|
-
this.logoutRedirectUrl =
|
|
29
|
-
(_b = config.logoutRedirectUrl) !== null && _b !== void 0 ? _b : (isBrowser ? `${window.location.origin}/login` : undefined);
|
|
30
|
-
this.storage = (_c = config.storage) !== null && _c !== void 0 ? _c : createDefaultTokenStorage();
|
|
31
29
|
this.loginMethod = this.loadLoginMethodFromStorage();
|
|
32
30
|
}
|
|
33
31
|
getAccessToken() {
|
|
34
32
|
return this.storage.getToken();
|
|
35
33
|
}
|
|
36
34
|
setAccessToken(token) {
|
|
37
|
-
var _a;
|
|
38
35
|
this.storage.setToken(token);
|
|
39
36
|
if (token === null) {
|
|
40
37
|
this.persistLoginMethod(null);
|
|
41
38
|
}
|
|
42
|
-
(_a = this.onTokenChange) === null || _a === void 0 ? void 0 : _a.call(this, token);
|
|
43
39
|
}
|
|
44
40
|
async authPost(path, body, withCredentials = true) {
|
|
45
41
|
const url = `${this.baseUrl}${path}`;
|
|
@@ -133,40 +129,55 @@ export class CemiarAuthClient {
|
|
|
133
129
|
}
|
|
134
130
|
return config;
|
|
135
131
|
}
|
|
132
|
+
processQueue(error, token = null) {
|
|
133
|
+
this.failedQueue.forEach(request => {
|
|
134
|
+
if (error) {
|
|
135
|
+
request.reject(error);
|
|
136
|
+
}
|
|
137
|
+
else if (token) {
|
|
138
|
+
request.resolve(token);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
this.failedQueue = [];
|
|
142
|
+
}
|
|
136
143
|
async handleResponseError(error, instance) {
|
|
137
|
-
var _a;
|
|
144
|
+
var _a, _b;
|
|
138
145
|
const status = (_a = error.response) === null || _a === void 0 ? void 0 : _a.status;
|
|
139
146
|
const originalRequest = error.config;
|
|
140
147
|
if (status !== 401 || !originalRequest || originalRequest._retry) {
|
|
141
148
|
return Promise.reject(error);
|
|
142
149
|
}
|
|
150
|
+
// If already refreshing, queue this request to wait for the token
|
|
151
|
+
if (this.isRefreshing) {
|
|
152
|
+
return new Promise((resolve, reject) => {
|
|
153
|
+
this.failedQueue.push({ resolve, reject });
|
|
154
|
+
}).then(token => {
|
|
155
|
+
if (originalRequest.headers) {
|
|
156
|
+
originalRequest.headers.Authorization = `Bearer ${token}`;
|
|
157
|
+
}
|
|
158
|
+
return instance(originalRequest);
|
|
159
|
+
});
|
|
160
|
+
}
|
|
143
161
|
originalRequest._retry = true;
|
|
162
|
+
this.isRefreshing = true;
|
|
144
163
|
try {
|
|
145
|
-
const newToken = await this.
|
|
164
|
+
const { accessToken: newToken } = await this.refreshToken();
|
|
165
|
+
this.processQueue(null, newToken);
|
|
146
166
|
if (originalRequest.headers) {
|
|
147
167
|
originalRequest.headers.Authorization = `Bearer ${newToken}`;
|
|
148
168
|
}
|
|
149
|
-
|
|
169
|
+
const response = await instance(originalRequest);
|
|
170
|
+
return response;
|
|
150
171
|
}
|
|
151
172
|
catch (refreshError) {
|
|
152
|
-
this.
|
|
173
|
+
this.processQueue(refreshError, null);
|
|
174
|
+
this.setAccessToken(null);
|
|
175
|
+
(_b = this.onAuthFailure) === null || _b === void 0 ? void 0 : _b.call(this);
|
|
153
176
|
return Promise.reject(refreshError);
|
|
154
177
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
if (!this.refreshPromise) {
|
|
158
|
-
this.refreshPromise = this.refreshToken()
|
|
159
|
-
.then(tokens => tokens.accessToken)
|
|
160
|
-
.finally(() => {
|
|
161
|
-
this.refreshPromise = null;
|
|
162
|
-
});
|
|
178
|
+
finally {
|
|
179
|
+
this.isRefreshing = false;
|
|
163
180
|
}
|
|
164
|
-
return this.refreshPromise;
|
|
165
|
-
}
|
|
166
|
-
handleAuthFailure() {
|
|
167
|
-
var _a;
|
|
168
|
-
this.setAccessToken(null);
|
|
169
|
-
(_a = this.onAuthFailure) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
170
181
|
}
|
|
171
182
|
loadLoginMethodFromStorage() {
|
|
172
183
|
if (!isBrowser || !("localStorage" in globalThis)) {
|
package/dist/shared/Types.d.ts
CHANGED