@frontegg/redux-store 7.114.0 → 7.116.0

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.
@@ -1,8 +1,8 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
- import { createRandomString, generateCodeChallenge, GTMEventAction, reportGTMEvent } from '../../../helpers';
2
+ import { createRandomString, generateCodeChallenge, GTMEventAction, refreshTokenWithRetry, reportGTMEvent } from '../../../helpers';
3
3
  import { HOSTED_LOGIN_VERIFIER_KEY } from '../../../constants';
4
4
  import { getBaseNameWithoutSlashSuffix, getSearchParam, isOauthCallbackRoute, TENANT_ID_PARAM_KEY } from '../helpers';
5
- import { getUri, isSteppedUp } from '../../helpers';
5
+ import { getUri, getUrlDerivedStepUp, isSteppedUp, redirectByStepUpUrl } from '../../helpers';
6
6
  import { SHOULD_STEP_UP_KEY } from '../../StepUpState/consts';
7
7
  import { FronteggNativeModule } from '../../../toolkit';
8
8
  export default ((store, api, sharedActions) => {
@@ -15,8 +15,11 @@ export default ((store, api, sharedActions) => {
15
15
  var _response;
16
16
  let response;
17
17
  if (FronteggNativeModule.isGetTokensAvailable()) {
18
- const tokens = await FronteggNativeModule.getTokens();
19
- response = await api.auth.silentOAuthRefreshTokenV3(tokens);
18
+ const authApi = api.auth;
19
+ response = await refreshTokenWithRetry(async () => {
20
+ const tokens = await FronteggNativeModule.getTokens();
21
+ return await authApi.silentOAuthRefreshTokenV3(tokens);
22
+ });
20
23
  } else {
21
24
  response = await api.auth.silentOAuthRefreshTokenV2();
22
25
  }
@@ -114,7 +117,7 @@ export default ((store, api, sharedActions) => {
114
117
  }
115
118
  };
116
119
  const refreshOrRequestHostedLoginAuthorizeV2 = async payload => {
117
- var _localStorage2, _additionalParams;
120
+ var _additionalParams;
118
121
  const {
119
122
  shouldRedirectToLogin,
120
123
  firstTime,
@@ -123,8 +126,12 @@ export default ((store, api, sharedActions) => {
123
126
  let {
124
127
  additionalParams
125
128
  } = payload != null ? payload : {};
126
- // when the user pause the step up flow we may still have the key in the local storage in hosted - Remove it
127
- (_localStorage2 = localStorage) == null ? void 0 : _localStorage2.removeItem(SHOULD_STEP_UP_KEY);
129
+ const urlDerivedStepUp = getUrlDerivedStepUp();
130
+ const isNativeStepUp = FronteggNativeModule.isGetTokensAvailable() && urlDerivedStepUp.isStepUpRequested;
131
+ if (!isNativeStepUp) {
132
+ var _localStorage2;
133
+ (_localStorage2 = localStorage) == null ? void 0 : _localStorage2.removeItem(SHOULD_STEP_UP_KEY);
134
+ }
128
135
  if (firstTime) {
129
136
  const urlStrategy = store.root.urlStrategy;
130
137
  const activeUri = getUri(urlStrategy);
@@ -146,6 +153,22 @@ export default ((store, api, sharedActions) => {
146
153
  if (((_additionalParams = additionalParams) == null ? void 0 : _additionalParams['prompt']) === 'login') {
147
154
  return await requestHostedLoginAuthorize(additionalParams);
148
155
  }
156
+ if (isNativeStepUp && !isSteppedUp(store.auth.user, {
157
+ maxAge: urlDerivedStepUp.maxAge
158
+ })) {
159
+ const {
160
+ routes,
161
+ onRedirectTo
162
+ } = store.auth;
163
+ if (routes.stepUpUrl && !window.location.href.includes(routes.stepUpUrl)) {
164
+ window.localStorage.setItem(SHOULD_STEP_UP_KEY, 'true');
165
+ actions.setAuthState({
166
+ isLoading: true
167
+ });
168
+ redirectByStepUpUrl(routes.stepUpUrl, onRedirectTo, urlDerivedStepUp.maxAge);
169
+ return;
170
+ }
171
+ }
149
172
  try {
150
173
  if (disableSilentRefresh) {
151
174
  throw new Error('silent refresh is disabled');
@@ -23,7 +23,7 @@ import mfaWithEmailCodeActions from './mfaWithEmailCode.actions';
23
23
  import mfaWithSMSActions from './mfaWithSMS.actions';
24
24
  import mfaWithWebAuthnActions from './mfaWithWebAuthn.actions';
25
25
  import { LoginFlow, LoginStep } from '../interfaces';
26
- import { base64urlDecode, deepResetState, delay, errorHandler, errorTraceId, GTMEventAction, publicKeyCredentialToJSON, reportGTMEvent, retryIfNeeded, withRetryConfig } from '../../../helpers';
26
+ import { base64urlDecode, deepResetState, delay, errorHandler, errorTraceId, GTMEventAction, publicKeyCredentialToJSON, refreshTokenWithRetry, reportGTMEvent, retryIfNeeded, withRetryConfig } from '../../../helpers';
27
27
  import { initialState } from '../state';
28
28
  import { getSearchParam, isEmailPayload, isUsernamePayload, shouldShowPasswordRotationPromptFunc, TENANT_ID_PARAM_KEY } from '../helpers';
29
29
  import { AuthStrategyEnum, ContextHolder, FeatureFlags, getTabTenantFromSessionStorage, removeTabTenantFromSessionStorage, WebAuthnDeviceType } from '@frontegg/rest-api';
@@ -40,6 +40,7 @@ import { DEFAULT_RETRY_CONFIG } from '../../../constants';
40
40
  export default ((store, api, sharedActions) => {
41
41
  const actions = sharedActions;
42
42
  const contextHolder = ContextHolder.for(store.root.appName);
43
+
43
44
  /** @private */
44
45
  const __refreshTokenHosted = async () => {
45
46
  const user = store.auth.user;
@@ -98,7 +99,7 @@ export default ((store, api, sharedActions) => {
98
99
  user,
99
100
  tenants = [],
100
101
  activeTenant
101
- } = await api.auth.refreshTokenV3();
102
+ } = await refreshTokenWithRetry(() => api.auth.refreshTokenV3());
102
103
  if (isMfaRequired(user, store.root.appName)) {
103
104
  const mfaRequiredState = await actions.getMfaRequiredState(user);
104
105
  actions.setAuthState(mfaRequiredState);
@@ -141,8 +142,11 @@ export default ((store, api, sharedActions) => {
141
142
  /** @private */
142
143
  const __refreshTokenWithNativeTokens = async () => {
143
144
  try {
144
- const tokens = await FronteggNativeModule.getTokens();
145
- const response = await api.auth.silentOAuthRefreshTokenV3(tokens);
145
+ const authApi = api.auth;
146
+ const response = await refreshTokenWithRetry(async () => {
147
+ const tokens = await FronteggNativeModule.getTokens();
148
+ return await authApi.silentOAuthRefreshTokenV3(tokens);
149
+ });
146
150
  const updatedUser = await __handleUnnecessaryEntitlementsUpdate(response.user);
147
151
  actions.afterAuthenticationStateUpdate(_extends({}, response, {
148
152
  user: updatedUser
@@ -1391,7 +1395,7 @@ export default ((store, api, sharedActions) => {
1391
1395
  user,
1392
1396
  tenants = [],
1393
1397
  activeTenant
1394
- } = await api.auth.refreshTokenV3();
1398
+ } = await refreshTokenWithRetry(() => api.auth.refreshTokenV3());
1395
1399
  if (isMfaRequired(user, store.root.appName)) {
1396
1400
  const mfaRequiredState = await actions.getMfaRequiredState(user);
1397
1401
  actions.setAuthState(mfaRequiredState);
@@ -15,6 +15,11 @@ export interface SteppedUpJWTValues {
15
15
  * @returns true when the user is stepped up, false otherwise
16
16
  */
17
17
  export declare const isSteppedUp: (user?: SteppedUpJWTValues | null, { maxAge }?: IsSteppedUpOptions) => boolean;
18
+ export interface UrlDerivedStepUp {
19
+ isStepUpRequested: boolean;
20
+ maxAge?: number;
21
+ }
22
+ export declare const getUrlDerivedStepUp: () => UrlDerivedStepUp;
18
23
  /**
19
24
  * Set the url and query params in the local storage FRONTEGG_AFTER_AUTH_REDIRECT_URL value
20
25
  */
@@ -16,16 +16,38 @@ export const isSteppedUp = (user, {
16
16
  acr = '',
17
17
  auth_time
18
18
  } = user;
19
- if (maxAge && auth_time) {
20
- // when user is logged in for a long time (more than maxAge, but jwt is still valid because it's not refreshed yet)
21
- const isMaxAgeValid = Date.now() / 1000 - auth_time <= maxAge;
22
- if (!isMaxAgeValid) return false;
19
+ if (maxAge) {
20
+ // max_age requires a verifiable, fresh auth_time; a missing or stale one is not stepped up.
21
+ if (!auth_time || Date.now() / 1000 - auth_time > maxAge) {
22
+ return false;
23
+ }
23
24
  }
24
25
  const isACRValid = acr === ACR_VALUE;
25
26
  const isAMRIncludesMFA = amr.indexOf(AMR_MFA_VALUE) !== -1;
26
27
  const isAMRIncludesMethod = AMR_ADDITIONAL_VALUE.find(method => amr.indexOf(method)) !== undefined;
27
28
  return isACRValid && isAMRIncludesMFA && isAMRIncludesMethod;
28
29
  };
30
+ export const getUrlDerivedStepUp = () => {
31
+ if (typeof window === 'undefined') {
32
+ return {
33
+ isStepUpRequested: false
34
+ };
35
+ }
36
+ try {
37
+ const params = new URLSearchParams(window.location.search);
38
+ const acrValues = params.get('acr_values');
39
+ const maxAgeParam = params.get('max_age');
40
+ const maxAge = maxAgeParam !== null && maxAgeParam !== '' ? Number(maxAgeParam) : undefined;
41
+ return {
42
+ isStepUpRequested: acrValues === ACR_VALUE,
43
+ maxAge: maxAge !== undefined && Number.isFinite(maxAge) ? maxAge : undefined
44
+ };
45
+ } catch {
46
+ return {
47
+ isStepUpRequested: false
48
+ };
49
+ }
50
+ };
29
51
 
30
52
  /**
31
53
  * Set the url and query params in the local storage FRONTEGG_AFTER_AUTH_REDIRECT_URL value
@@ -5,3 +5,4 @@ export * from './encoders';
5
5
  export * from './random';
6
6
  export * from './gtm';
7
7
  export * from './sha256';
8
+ export * from './refreshTokenRetry';
package/helpers/index.js CHANGED
@@ -4,4 +4,5 @@ export * from './converters';
4
4
  export * from './encoders';
5
5
  export * from './random';
6
6
  export * from './gtm';
7
- export * from './sha256';
7
+ export * from './sha256';
8
+ export * from './refreshTokenRetry';
@@ -0,0 +1,2 @@
1
+ export declare const shouldRetryRefreshTokenError: (error: unknown) => boolean;
2
+ export declare const refreshTokenWithRetry: <T>(refreshRequest: () => Promise<T>) => Promise<T>;
@@ -0,0 +1,36 @@
1
+ import { delay } from './common';
2
+ const REFRESH_TOKEN_RETRY_DELAYS = [1000, 2000];
3
+ const getRefreshTokenErrorStatusCode = error => {
4
+ var _ref, _apiError$statusCode, _apiError$response;
5
+ const apiError = error;
6
+ return (_ref = (_apiError$statusCode = apiError.statusCode) != null ? _apiError$statusCode : apiError.status) != null ? _ref : (_apiError$response = apiError.response) == null ? void 0 : _apiError$response.status;
7
+ };
8
+ export const shouldRetryRefreshTokenError = error => {
9
+ var _message$toLowerCase, _message;
10
+ const statusCode = getRefreshTokenErrorStatusCode(error);
11
+ const errorName = error == null ? void 0 : error.name;
12
+ const errorMessage = (_message$toLowerCase = error == null ? void 0 : (_message = error.message) == null ? void 0 : _message.toLowerCase()) != null ? _message$toLowerCase : '';
13
+ if (statusCode === 401 || statusCode === 403) {
14
+ return false;
15
+ }
16
+ if (statusCode === 410) {
17
+ return true;
18
+ }
19
+ if (statusCode !== undefined) {
20
+ return statusCode === 0 || statusCode >= 500 && statusCode < 600;
21
+ }
22
+ return errorName === 'AbortError' || errorMessage.includes('network') || errorMessage.includes('failed to fetch') || errorMessage.includes('fetch failed') || errorMessage.includes('load failed') || errorMessage.includes('native_bridge_timeout');
23
+ };
24
+ export const refreshTokenWithRetry = async refreshRequest => {
25
+ for (let attempt = 0; attempt <= REFRESH_TOKEN_RETRY_DELAYS.length; attempt++) {
26
+ try {
27
+ return await refreshRequest();
28
+ } catch (error) {
29
+ if (attempt >= REFRESH_TOKEN_RETRY_DELAYS.length || !shouldRetryRefreshTokenError(error)) {
30
+ throw error;
31
+ }
32
+ await delay(REFRESH_TOKEN_RETRY_DELAYS[attempt]);
33
+ }
34
+ }
35
+ return await refreshRequest();
36
+ };
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /** @license Frontegg v7.114.0
1
+ /** @license Frontegg v7.116.0
2
2
  *
3
3
  * This source code is licensed under the MIT license found in the
4
4
  * LICENSE file in the root directory of this source tree.
@@ -22,8 +22,11 @@ var _default = (store, api, sharedActions) => {
22
22
  var _response;
23
23
  let response;
24
24
  if (_toolkit.FronteggNativeModule.isGetTokensAvailable()) {
25
- const tokens = await _toolkit.FronteggNativeModule.getTokens();
26
- response = await api.auth.silentOAuthRefreshTokenV3(tokens);
25
+ const authApi = api.auth;
26
+ response = await (0, _helpers.refreshTokenWithRetry)(async () => {
27
+ const tokens = await _toolkit.FronteggNativeModule.getTokens();
28
+ return await authApi.silentOAuthRefreshTokenV3(tokens);
29
+ });
27
30
  } else {
28
31
  response = await api.auth.silentOAuthRefreshTokenV2();
29
32
  }
@@ -121,7 +124,7 @@ var _default = (store, api, sharedActions) => {
121
124
  }
122
125
  };
123
126
  const refreshOrRequestHostedLoginAuthorizeV2 = async payload => {
124
- var _localStorage2, _additionalParams;
127
+ var _additionalParams;
125
128
  const {
126
129
  shouldRedirectToLogin,
127
130
  firstTime,
@@ -130,8 +133,12 @@ var _default = (store, api, sharedActions) => {
130
133
  let {
131
134
  additionalParams
132
135
  } = payload != null ? payload : {};
133
- // when the user pause the step up flow we may still have the key in the local storage in hosted - Remove it
134
- (_localStorage2 = localStorage) == null ? void 0 : _localStorage2.removeItem(_consts.SHOULD_STEP_UP_KEY);
136
+ const urlDerivedStepUp = (0, _helpers3.getUrlDerivedStepUp)();
137
+ const isNativeStepUp = _toolkit.FronteggNativeModule.isGetTokensAvailable() && urlDerivedStepUp.isStepUpRequested;
138
+ if (!isNativeStepUp) {
139
+ var _localStorage2;
140
+ (_localStorage2 = localStorage) == null ? void 0 : _localStorage2.removeItem(_consts.SHOULD_STEP_UP_KEY);
141
+ }
135
142
  if (firstTime) {
136
143
  const urlStrategy = store.root.urlStrategy;
137
144
  const activeUri = (0, _helpers3.getUri)(urlStrategy);
@@ -153,6 +160,22 @@ var _default = (store, api, sharedActions) => {
153
160
  if (((_additionalParams = additionalParams) == null ? void 0 : _additionalParams['prompt']) === 'login') {
154
161
  return await requestHostedLoginAuthorize(additionalParams);
155
162
  }
163
+ if (isNativeStepUp && !(0, _helpers3.isSteppedUp)(store.auth.user, {
164
+ maxAge: urlDerivedStepUp.maxAge
165
+ })) {
166
+ const {
167
+ routes,
168
+ onRedirectTo
169
+ } = store.auth;
170
+ if (routes.stepUpUrl && !window.location.href.includes(routes.stepUpUrl)) {
171
+ window.localStorage.setItem(_consts.SHOULD_STEP_UP_KEY, 'true');
172
+ actions.setAuthState({
173
+ isLoading: true
174
+ });
175
+ (0, _helpers3.redirectByStepUpUrl)(routes.stepUpUrl, onRedirectTo, urlDerivedStepUp.maxAge);
176
+ return;
177
+ }
178
+ }
156
179
  try {
157
180
  if (disableSilentRefresh) {
158
181
  throw new Error('silent refresh is disabled');
@@ -47,6 +47,7 @@ const _excluded = ["callback", "error"],
47
47
  var _default = (store, api, sharedActions) => {
48
48
  const actions = sharedActions;
49
49
  const contextHolder = _restApi.ContextHolder.for(store.root.appName);
50
+
50
51
  /** @private */
51
52
  const __refreshTokenHosted = async () => {
52
53
  const user = store.auth.user;
@@ -105,7 +106,7 @@ var _default = (store, api, sharedActions) => {
105
106
  user,
106
107
  tenants = [],
107
108
  activeTenant
108
- } = await api.auth.refreshTokenV3();
109
+ } = await (0, _helpers.refreshTokenWithRetry)(() => api.auth.refreshTokenV3());
109
110
  if ((0, _helpers3.isMfaRequired)(user, store.root.appName)) {
110
111
  const mfaRequiredState = await actions.getMfaRequiredState(user);
111
112
  actions.setAuthState(mfaRequiredState);
@@ -148,8 +149,11 @@ var _default = (store, api, sharedActions) => {
148
149
  /** @private */
149
150
  const __refreshTokenWithNativeTokens = async () => {
150
151
  try {
151
- const tokens = await _toolkit.FronteggNativeModule.getTokens();
152
- const response = await api.auth.silentOAuthRefreshTokenV3(tokens);
152
+ const authApi = api.auth;
153
+ const response = await (0, _helpers.refreshTokenWithRetry)(async () => {
154
+ const tokens = await _toolkit.FronteggNativeModule.getTokens();
155
+ return await authApi.silentOAuthRefreshTokenV3(tokens);
156
+ });
153
157
  const updatedUser = await __handleUnnecessaryEntitlementsUpdate(response.user);
154
158
  actions.afterAuthenticationStateUpdate((0, _extends2.default)({}, response, {
155
159
  user: updatedUser
@@ -1398,7 +1402,7 @@ var _default = (store, api, sharedActions) => {
1398
1402
  user,
1399
1403
  tenants = [],
1400
1404
  activeTenant
1401
- } = await api.auth.refreshTokenV3();
1405
+ } = await (0, _helpers.refreshTokenWithRetry)(() => api.auth.refreshTokenV3());
1402
1406
  if ((0, _helpers3.isMfaRequired)(user, store.root.appName)) {
1403
1407
  const mfaRequiredState = await actions.getMfaRequiredState(user);
1404
1408
  actions.setAuthState(mfaRequiredState);
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.redirectByStepUpUrl = exports.isSteppedUp = void 0;
6
+ exports.redirectByStepUpUrl = exports.isSteppedUp = exports.getUrlDerivedStepUp = void 0;
7
7
  exports.setAfterAuthRedirectUrlForStepUp = setAfterAuthRedirectUrlForStepUp;
8
8
  var _constants = require("../../constants");
9
9
  var _consts = require("./consts");
@@ -23,21 +23,44 @@ const isSteppedUp = (user, {
23
23
  acr = '',
24
24
  auth_time
25
25
  } = user;
26
- if (maxAge && auth_time) {
27
- // when user is logged in for a long time (more than maxAge, but jwt is still valid because it's not refreshed yet)
28
- const isMaxAgeValid = Date.now() / 1000 - auth_time <= maxAge;
29
- if (!isMaxAgeValid) return false;
26
+ if (maxAge) {
27
+ // max_age requires a verifiable, fresh auth_time; a missing or stale one is not stepped up.
28
+ if (!auth_time || Date.now() / 1000 - auth_time > maxAge) {
29
+ return false;
30
+ }
30
31
  }
31
32
  const isACRValid = acr === _consts.ACR_VALUE;
32
33
  const isAMRIncludesMFA = amr.indexOf(_consts.AMR_MFA_VALUE) !== -1;
33
34
  const isAMRIncludesMethod = _consts.AMR_ADDITIONAL_VALUE.find(method => amr.indexOf(method)) !== undefined;
34
35
  return isACRValid && isAMRIncludesMFA && isAMRIncludesMethod;
35
36
  };
37
+ exports.isSteppedUp = isSteppedUp;
38
+ const getUrlDerivedStepUp = () => {
39
+ if (typeof window === 'undefined') {
40
+ return {
41
+ isStepUpRequested: false
42
+ };
43
+ }
44
+ try {
45
+ const params = new URLSearchParams(window.location.search);
46
+ const acrValues = params.get('acr_values');
47
+ const maxAgeParam = params.get('max_age');
48
+ const maxAge = maxAgeParam !== null && maxAgeParam !== '' ? Number(maxAgeParam) : undefined;
49
+ return {
50
+ isStepUpRequested: acrValues === _consts.ACR_VALUE,
51
+ maxAge: maxAge !== undefined && Number.isFinite(maxAge) ? maxAge : undefined
52
+ };
53
+ } catch {
54
+ return {
55
+ isStepUpRequested: false
56
+ };
57
+ }
58
+ };
36
59
 
37
60
  /**
38
61
  * Set the url and query params in the local storage FRONTEGG_AFTER_AUTH_REDIRECT_URL value
39
62
  */
40
- exports.isSteppedUp = isSteppedUp;
63
+ exports.getUrlDerivedStepUp = getUrlDerivedStepUp;
41
64
  function setAfterAuthRedirectUrlForStepUp() {
42
65
  const encodedRedirectUrl = window.location.pathname + window.location.search;
43
66
  window.localStorage.setItem(_constants.FRONTEGG_AFTER_AUTH_REDIRECT_URL, encodedRedirectUrl);
@@ -79,4 +79,15 @@ Object.keys(_sha).forEach(function (key) {
79
79
  return _sha[key];
80
80
  }
81
81
  });
82
+ });
83
+ var _refreshTokenRetry = require("./refreshTokenRetry");
84
+ Object.keys(_refreshTokenRetry).forEach(function (key) {
85
+ if (key === "default" || key === "__esModule") return;
86
+ if (key in exports && exports[key] === _refreshTokenRetry[key]) return;
87
+ Object.defineProperty(exports, key, {
88
+ enumerable: true,
89
+ get: function () {
90
+ return _refreshTokenRetry[key];
91
+ }
92
+ });
82
93
  });
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.shouldRetryRefreshTokenError = exports.refreshTokenWithRetry = void 0;
7
+ var _common = require("./common");
8
+ const REFRESH_TOKEN_RETRY_DELAYS = [1000, 2000];
9
+ const getRefreshTokenErrorStatusCode = error => {
10
+ var _ref, _apiError$statusCode, _apiError$response;
11
+ const apiError = error;
12
+ return (_ref = (_apiError$statusCode = apiError.statusCode) != null ? _apiError$statusCode : apiError.status) != null ? _ref : (_apiError$response = apiError.response) == null ? void 0 : _apiError$response.status;
13
+ };
14
+ const shouldRetryRefreshTokenError = error => {
15
+ var _message$toLowerCase, _message;
16
+ const statusCode = getRefreshTokenErrorStatusCode(error);
17
+ const errorName = error == null ? void 0 : error.name;
18
+ const errorMessage = (_message$toLowerCase = error == null ? void 0 : (_message = error.message) == null ? void 0 : _message.toLowerCase()) != null ? _message$toLowerCase : '';
19
+ if (statusCode === 401 || statusCode === 403) {
20
+ return false;
21
+ }
22
+ if (statusCode === 410) {
23
+ return true;
24
+ }
25
+ if (statusCode !== undefined) {
26
+ return statusCode === 0 || statusCode >= 500 && statusCode < 600;
27
+ }
28
+ return errorName === 'AbortError' || errorMessage.includes('network') || errorMessage.includes('failed to fetch') || errorMessage.includes('fetch failed') || errorMessage.includes('load failed') || errorMessage.includes('native_bridge_timeout');
29
+ };
30
+ exports.shouldRetryRefreshTokenError = shouldRetryRefreshTokenError;
31
+ const refreshTokenWithRetry = async refreshRequest => {
32
+ for (let attempt = 0; attempt <= REFRESH_TOKEN_RETRY_DELAYS.length; attempt++) {
33
+ try {
34
+ return await refreshRequest();
35
+ } catch (error) {
36
+ if (attempt >= REFRESH_TOKEN_RETRY_DELAYS.length || !shouldRetryRefreshTokenError(error)) {
37
+ throw error;
38
+ }
39
+ await (0, _common.delay)(REFRESH_TOKEN_RETRY_DELAYS[attempt]);
40
+ }
41
+ }
42
+ return await refreshRequest();
43
+ };
44
+ exports.refreshTokenWithRetry = refreshTokenWithRetry;
package/node/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /** @license Frontegg v7.114.0
1
+ /** @license Frontegg v7.116.0
2
2
  *
3
3
  * This source code is licensed under the MIT license found in the
4
4
  * LICENSE file in the root directory of this source tree.
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@frontegg/redux-store",
3
- "version": "7.114.0",
3
+ "version": "7.116.0",
4
4
  "main": "./node/index.js",
5
5
  "license": "MIT",
6
6
  "author": "Frontegg LTD",
7
7
  "dependencies": {
8
8
  "@babel/runtime": "^7.18.6",
9
9
  "@frontegg/entitlements-javascript-commons": "1.1.2",
10
- "@frontegg/rest-api": "7.114.0",
10
+ "@frontegg/rest-api": "7.116.0",
11
11
  "fast-deep-equal": "3.1.3",
12
12
  "get-value": "^3.0.1",
13
13
  "proxy-compare": "^3.0.0",