antaeus.keycloak.react 2.6.0 → 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 +36 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +37 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -165,6 +165,20 @@ var isTransientNetworkError = (error) => {
|
|
|
165
165
|
}
|
|
166
166
|
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");
|
|
167
167
|
};
|
|
168
|
+
var isInvalidRefreshTokenError = (error) => {
|
|
169
|
+
if (error instanceof oidcClientTs.ErrorResponse) {
|
|
170
|
+
const code = error.error?.toLowerCase?.();
|
|
171
|
+
if (code === "invalid_grant" || code === "invalid_token") {
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
const description = error.error_description?.toLowerCase?.();
|
|
175
|
+
if (description?.includes("refresh token")) {
|
|
176
|
+
return true;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
const message = error.message?.toLowerCase?.() ?? "";
|
|
180
|
+
return message.includes("invalid_grant") || message.includes("refresh token") || message.includes("invalid token");
|
|
181
|
+
};
|
|
168
182
|
function useTokenLifecycle(options) {
|
|
169
183
|
const {
|
|
170
184
|
config,
|
|
@@ -255,6 +269,20 @@ function useTokenLifecycle(options) {
|
|
|
255
269
|
onRefreshSuccess?.();
|
|
256
270
|
} catch (error) {
|
|
257
271
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
272
|
+
if (isInvalidRefreshTokenError(err)) {
|
|
273
|
+
log("Refresh token rejected by the identity provider, clearing stored session");
|
|
274
|
+
setIsRefreshTokenExpired(true);
|
|
275
|
+
onRefreshTokenExpired?.();
|
|
276
|
+
const key = getStorageKey();
|
|
277
|
+
localStorage.removeItem(key);
|
|
278
|
+
try {
|
|
279
|
+
await auth.removeUser();
|
|
280
|
+
} catch (removeError) {
|
|
281
|
+
log("Error removing user after invalid refresh token:", removeError);
|
|
282
|
+
}
|
|
283
|
+
onRefreshError?.(err);
|
|
284
|
+
throw err;
|
|
285
|
+
}
|
|
258
286
|
if (isTransientNetworkError(err)) {
|
|
259
287
|
const reason = isNavigatorOffline() ? "offline" : "network";
|
|
260
288
|
deferredRefreshReasonRef.current = reason;
|
|
@@ -285,6 +313,7 @@ function useTokenLifecycle(options) {
|
|
|
285
313
|
onRefreshError,
|
|
286
314
|
onRefreshTokenExpired,
|
|
287
315
|
enqueueRetry,
|
|
316
|
+
getStorageKey,
|
|
288
317
|
log
|
|
289
318
|
]);
|
|
290
319
|
const checkAndRefreshTokens = react.useCallback(async () => {
|
|
@@ -438,16 +467,21 @@ function useTokenLifecycle(options) {
|
|
|
438
467
|
if (hasCheckedOnStartup.current) {
|
|
439
468
|
const hasUser = Boolean(auth.user);
|
|
440
469
|
const hasRefreshToken = Boolean(auth.user?.refresh_token);
|
|
441
|
-
if (
|
|
470
|
+
if (!auth.isAuthenticated && (!supportsRefreshTokens || !hasUser || !hasRefreshToken)) {
|
|
442
471
|
hasCheckedOnStartup.current = false;
|
|
443
472
|
}
|
|
444
473
|
}
|
|
445
|
-
}, [auth.isAuthenticated, auth.
|
|
474
|
+
}, [auth.isAuthenticated, auth.user, supportsRefreshTokens]);
|
|
446
475
|
react.useEffect(() => {
|
|
447
476
|
if (auth.user && !auth.isLoading) {
|
|
448
477
|
storeFirstLoginTime();
|
|
449
478
|
}
|
|
450
479
|
}, [auth.user, auth.isLoading, storeFirstLoginTime]);
|
|
480
|
+
react.useEffect(() => {
|
|
481
|
+
if (auth.isAuthenticated && isRefreshTokenExpired) {
|
|
482
|
+
setIsRefreshTokenExpired(false);
|
|
483
|
+
}
|
|
484
|
+
}, [auth.isAuthenticated, isRefreshTokenExpired]);
|
|
451
485
|
react.useEffect(() => {
|
|
452
486
|
if (!auth.isAuthenticated || auth.isLoading) {
|
|
453
487
|
return;
|