@frontegg/redux-store 7.115.0 → 7.117.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,5 +1,5 @@
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
5
  import { getUri, getUrlDerivedStepUp, isSteppedUp, redirectByStepUpUrl } from '../../helpers';
@@ -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
  }
@@ -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);
@@ -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.115.0
1
+ /** @license Frontegg v7.117.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
  }
@@ -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);
@@ -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.115.0
1
+ /** @license Frontegg v7.117.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.115.0",
3
+ "version": "7.117.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.115.0",
10
+ "@frontegg/rest-api": "7.117.0",
11
11
  "fast-deep-equal": "3.1.3",
12
12
  "get-value": "^3.0.1",
13
13
  "proxy-compare": "^3.0.0",