antaeus.keycloak.react 2.6.1 → 2.6.2
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.
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +35 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createContext, useContext, useState, useRef, useCallback, useEffect, useMemo } from 'react';
|
|
2
2
|
import { useAuth as useAuth$1, AuthContext, AuthProvider } from 'react-oidc-context';
|
|
3
|
-
import { WebStorageStateStore, User } from 'oidc-client-ts';
|
|
3
|
+
import { WebStorageStateStore, User, ErrorResponse } from 'oidc-client-ts';
|
|
4
4
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
5
5
|
import { useLocation } from 'react-router-dom';
|
|
6
6
|
import { QRCodeSVG } from 'qrcode.react';
|
|
@@ -162,6 +162,20 @@ var isTransientNetworkError = (error) => {
|
|
|
162
162
|
}
|
|
163
163
|
return message.includes("network") || message.includes("failed to fetch") || message.includes("fetch") || message.includes("timeout") || message.includes("temporarily unavailable") || message.includes("dns") || message.includes("offline");
|
|
164
164
|
};
|
|
165
|
+
var isInvalidRefreshTokenError = (error) => {
|
|
166
|
+
if (error instanceof ErrorResponse) {
|
|
167
|
+
const code = error.error?.toLowerCase?.();
|
|
168
|
+
if (code === "invalid_grant" || code === "invalid_token") {
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
const description = error.error_description?.toLowerCase?.();
|
|
172
|
+
if (description?.includes("refresh token")) {
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
const message = error.message?.toLowerCase?.() ?? "";
|
|
177
|
+
return message.includes("invalid_grant") || message.includes("refresh token") || message.includes("invalid token");
|
|
178
|
+
};
|
|
165
179
|
function useTokenLifecycle(options) {
|
|
166
180
|
const {
|
|
167
181
|
config,
|
|
@@ -252,6 +266,20 @@ function useTokenLifecycle(options) {
|
|
|
252
266
|
onRefreshSuccess?.();
|
|
253
267
|
} catch (error) {
|
|
254
268
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
269
|
+
if (isInvalidRefreshTokenError(err)) {
|
|
270
|
+
log("Refresh token rejected by the identity provider, clearing stored session");
|
|
271
|
+
setIsRefreshTokenExpired(true);
|
|
272
|
+
onRefreshTokenExpired?.();
|
|
273
|
+
const key = getStorageKey();
|
|
274
|
+
localStorage.removeItem(key);
|
|
275
|
+
try {
|
|
276
|
+
await auth.removeUser();
|
|
277
|
+
} catch (removeError) {
|
|
278
|
+
log("Error removing user after invalid refresh token:", removeError);
|
|
279
|
+
}
|
|
280
|
+
onRefreshError?.(err);
|
|
281
|
+
throw err;
|
|
282
|
+
}
|
|
255
283
|
if (isTransientNetworkError(err)) {
|
|
256
284
|
const reason = isNavigatorOffline() ? "offline" : "network";
|
|
257
285
|
deferredRefreshReasonRef.current = reason;
|
|
@@ -282,6 +310,7 @@ function useTokenLifecycle(options) {
|
|
|
282
310
|
onRefreshError,
|
|
283
311
|
onRefreshTokenExpired,
|
|
284
312
|
enqueueRetry,
|
|
313
|
+
getStorageKey,
|
|
285
314
|
log
|
|
286
315
|
]);
|
|
287
316
|
const checkAndRefreshTokens = useCallback(async () => {
|
|
@@ -445,6 +474,11 @@ function useTokenLifecycle(options) {
|
|
|
445
474
|
storeFirstLoginTime();
|
|
446
475
|
}
|
|
447
476
|
}, [auth.user, auth.isLoading, storeFirstLoginTime]);
|
|
477
|
+
useEffect(() => {
|
|
478
|
+
if (auth.isAuthenticated && isRefreshTokenExpired) {
|
|
479
|
+
setIsRefreshTokenExpired(false);
|
|
480
|
+
}
|
|
481
|
+
}, [auth.isAuthenticated, isRefreshTokenExpired]);
|
|
448
482
|
useEffect(() => {
|
|
449
483
|
if (!auth.isAuthenticated || auth.isLoading) {
|
|
450
484
|
return;
|