@frontegg/redux-store 7.112.0 → 7.114.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.
@@ -4,9 +4,17 @@ import { FRONTEGG_AFTER_AUTH_REDIRECT_URL } from '../../../constants';
4
4
  import { SHOULD_STEP_UP_KEY } from '../../StepUpState/consts';
5
5
  import { delay } from '../../../helpers';
6
6
  import { isSteppedUp } from '../../StepUpState/helpers';
7
+ import { clearHostedOAuthState, isHostedOAuthStateExpired } from '../oauthStorage';
7
8
  export default ((store, api, sharedActions) => {
8
9
  const actions = sharedActions;
9
10
 
11
+ // Drop only stale (expired) hosted OAuth state so a fresh, in-progress flow is never affected.
12
+ const clearExpiredHostedOAuthState = () => {
13
+ if (isHostedOAuthStateExpired()) {
14
+ clearHostedOAuthState();
15
+ }
16
+ };
17
+
10
18
  /**
11
19
  * @param url
12
20
  * @returns url without the origin if it's the same origin as the current window origin
@@ -95,6 +103,7 @@ export default ((store, api, sharedActions) => {
95
103
  * @param options custom login authenticated url if exists
96
104
  */
97
105
  const afterAuthNavigationUtil = async (resetStateAction, options = {}) => {
106
+ clearExpiredHostedOAuthState();
98
107
  const {
99
108
  customLoginAuthenticatedUrl,
100
109
  forceStepUpUrl,
@@ -129,6 +138,9 @@ export default ((store, api, sharedActions) => {
129
138
  }
130
139
  await delay(200);
131
140
  await resetStateAction();
141
+ if (redirectUrl.startsWith('http')) {
142
+ clearHostedOAuthState();
143
+ }
132
144
  onRedirectTo(redirectUrl, {
133
145
  refresh: redirectUrl.startsWith('http')
134
146
  });
@@ -28,6 +28,8 @@ 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';
30
30
  import hostedLoginAuthorizeActions from './hostedLoginAuthorize.actions';
31
+ import { clearHostedOAuthState } from '../oauthStorage';
32
+ import { SHOULD_STEP_UP_KEY } from '../../StepUpState/consts';
31
33
  import { FronteggNativeModule, isEntitlementsDeeplyEqual } from '../../../toolkit';
32
34
  import { REQUEST_NAME, UserVerifiedOriginTypes } from '../../interfaces';
33
35
  import { authStrategyLoginStepMap } from '../consts';
@@ -136,8 +138,33 @@ export default ((store, api, sharedActions) => {
136
138
  }
137
139
  };
138
140
 
141
+ /** @private */
142
+ const __refreshTokenWithNativeTokens = async () => {
143
+ try {
144
+ const tokens = await FronteggNativeModule.getTokens();
145
+ const response = await api.auth.silentOAuthRefreshTokenV3(tokens);
146
+ const updatedUser = await __handleUnnecessaryEntitlementsUpdate(response.user);
147
+ actions.afterAuthenticationStateUpdate(_extends({}, response, {
148
+ user: updatedUser
149
+ }), {
150
+ isAuthenticated: true
151
+ });
152
+ } catch (e) {
153
+ contextHolder.setAccessToken(null);
154
+ contextHolder.setUser(null);
155
+ actions.setAuthState({
156
+ user: null,
157
+ isAuthenticated: false
158
+ });
159
+ }
160
+ };
161
+
139
162
  /** @protected */
140
163
  const __refreshToken = async () => {
164
+ if (FronteggNativeModule.isGetTokensAvailable()) {
165
+ await __refreshTokenWithNativeTokens();
166
+ return;
167
+ }
141
168
  const hostedLoginBox = store.auth.hostedLoginBox;
142
169
  if (hostedLoginBox) {
143
170
  await __refreshTokenHosted();
@@ -603,6 +630,17 @@ export default ((store, api, sharedActions) => {
603
630
  });
604
631
  }
605
632
  };
633
+ const clearLogoutLocalState = ({
634
+ keepHostedOAuthState = false
635
+ } = {}) => {
636
+ if (contextHolder.isSessionPerTenantEnabled()) {
637
+ removeTabTenantFromSessionStorage();
638
+ }
639
+ // Step-up re-login goes through silentLogout but still needs the hosted OAuth state to finish the client flow.
640
+ if (!keepHostedOAuthState) {
641
+ clearHostedOAuthState();
642
+ }
643
+ };
606
644
  const logout = async payload => {
607
645
  const hostedLoginBox = store.auth.hostedLoginBox;
608
646
  actions.setAuthState({
@@ -617,23 +655,22 @@ export default ((store, api, sharedActions) => {
617
655
  } catch {
618
656
  /* empty */
619
657
  }
620
- if (contextHolder.isSessionPerTenantEnabled()) {
621
- removeTabTenantFromSessionStorage();
622
- }
658
+ clearLogoutLocalState();
623
659
  actions.resetAuthState();
624
660
  await actions.requestAuthorize(true);
625
661
  payload == null ? void 0 : payload();
626
662
  };
627
663
  const silentLogout = async payload => {
628
- var _payload$callbackTime;
664
+ var _window2, _payload$callbackTime;
629
665
  try {
630
666
  await api.auth.logout();
631
667
  } catch {
632
668
  /* empty */
633
669
  }
634
- if (contextHolder.isSessionPerTenantEnabled()) {
635
- removeTabTenantFromSessionStorage();
636
- }
670
+ const isStepUpInProgress = !!((_window2 = window) != null && _window2.localStorage.getItem(SHOULD_STEP_UP_KEY));
671
+ clearLogoutLocalState({
672
+ keepHostedOAuthState: isStepUpInProgress
673
+ });
637
674
  setTimeout(() => {
638
675
  var _payload$callback3;
639
676
  return payload == null ? void 0 : (_payload$callback3 = payload.callback) == null ? void 0 : _payload$callback3.call(payload, true);
@@ -0,0 +1,19 @@
1
+ export declare const FRONTEGG_OAUTH_LOGIN_HINT = "FRONTEGG_OAUTH_LOGIN_HINT";
2
+ export declare const FRONTEGG_OAUTH_LOGIN_DIRECT_ACTION = "FRONTEGG_OAUTH_LOGIN_DIRECT_ACTION";
3
+ export declare const FRONTEGG_OAUTH_ORGANIZATION = "FRONTEGG_OAUTH_ORGANIZATION";
4
+ export declare const FRONTEGG_OAUTH_STEP_UP_ACR_VALUES = "FRONTEGG_OAUTH_STEP_UP_ACR_VALUES";
5
+ export declare const FRONTEGG_OAUTH_STEP_UP_MAX_AGE = "FRONTEGG_OAUTH_STEP_UP_MAX_AGE";
6
+ export declare const FRONTEGG_OAUTH_TENANT_ID = "FRONTEGG_OAUTH_TENANT_ID";
7
+ export declare const FRONTEGG_OAUTH_APP_ID = "FRONTEGG_OAUTH_APP_ID";
8
+ export declare const FRONTEGG_OAUTH_STATE_AFTER_LOGIN = "FRONTEGG_OAUTH_STATE_AFTER_LOGIN";
9
+ export declare const FRONTEGG_OAUTH_INVITATION_TOKEN_KEY = "FRONTEGG_OAUTH_INVITATION_TOKEN_KEY";
10
+ export declare const FRONTEGG_OAUTH_REDIRECT_AFTER_LOGIN = "FRONTEGG_OAUTH_REDIRECT_AFTER_LOGIN";
11
+ export declare const FRONTEGG_AUTHENTICATION_FLOWS_REDIRECT_AFTER_LOGIN = "FRONTEGG_AUTHENTICATION_FLOWS_REDIRECT_AFTER_LOGIN";
12
+ export declare const FRONTEGG_OAUTH_SILENT_REDIRECT_ADDRESS = "FRONTEGG_OAUTH_SILENT_REDIRECT_ADDRESS";
13
+ export declare const FRONTEGG_OAUTH_STATE_SAVED_AT = "FRONTEGG_OAUTH_STATE_SAVED_AT";
14
+ /** Slightly under typical Redis OAuth session TTL to avoid stale postlogin attempts. */
15
+ export declare const HOSTED_OAUTH_STATE_MAX_AGE_MS: number;
16
+ export declare const HOSTED_OAUTH_STORAGE_KEYS: readonly ["FRONTEGG_OAUTH_REDIRECT_AFTER_LOGIN", "FRONTEGG_OAUTH_STATE_AFTER_LOGIN", "FRONTEGG_OAUTH_STATE_SAVED_AT", "FRONTEGG_AUTHENTICATION_FLOWS_REDIRECT_AFTER_LOGIN", "FRONTEGG_OAUTH_INVITATION_TOKEN_KEY", "FRONTEGG_OAUTH_ORGANIZATION", "FRONTEGG_OAUTH_TENANT_ID", "FRONTEGG_OAUTH_STEP_UP_ACR_VALUES", "FRONTEGG_OAUTH_STEP_UP_MAX_AGE", "FRONTEGG_OAUTH_APP_ID", "FRONTEGG_OAUTH_LOGIN_HINT", "FRONTEGG_OAUTH_LOGIN_DIRECT_ACTION", "FRONTEGG_OAUTH_SILENT_REDIRECT_ADDRESS"];
17
+ export declare function clearHostedOAuthState(): void;
18
+ export declare function markHostedOAuthStateSaved(): void;
19
+ export declare function isHostedOAuthStateExpired(): boolean;
@@ -0,0 +1,74 @@
1
+ export const FRONTEGG_OAUTH_LOGIN_HINT = 'FRONTEGG_OAUTH_LOGIN_HINT';
2
+ export const FRONTEGG_OAUTH_LOGIN_DIRECT_ACTION = 'FRONTEGG_OAUTH_LOGIN_DIRECT_ACTION';
3
+ export const FRONTEGG_OAUTH_ORGANIZATION = 'FRONTEGG_OAUTH_ORGANIZATION';
4
+ export const FRONTEGG_OAUTH_STEP_UP_ACR_VALUES = 'FRONTEGG_OAUTH_STEP_UP_ACR_VALUES';
5
+ export const FRONTEGG_OAUTH_STEP_UP_MAX_AGE = 'FRONTEGG_OAUTH_STEP_UP_MAX_AGE';
6
+ export const FRONTEGG_OAUTH_TENANT_ID = 'FRONTEGG_OAUTH_TENANT_ID';
7
+ export const FRONTEGG_OAUTH_APP_ID = 'FRONTEGG_OAUTH_APP_ID';
8
+ export const FRONTEGG_OAUTH_STATE_AFTER_LOGIN = 'FRONTEGG_OAUTH_STATE_AFTER_LOGIN';
9
+ export const FRONTEGG_OAUTH_INVITATION_TOKEN_KEY = 'FRONTEGG_OAUTH_INVITATION_TOKEN_KEY';
10
+ export const FRONTEGG_OAUTH_REDIRECT_AFTER_LOGIN = 'FRONTEGG_OAUTH_REDIRECT_AFTER_LOGIN';
11
+ export const FRONTEGG_AUTHENTICATION_FLOWS_REDIRECT_AFTER_LOGIN = 'FRONTEGG_AUTHENTICATION_FLOWS_REDIRECT_AFTER_LOGIN';
12
+ export const FRONTEGG_OAUTH_SILENT_REDIRECT_ADDRESS = 'FRONTEGG_OAUTH_SILENT_REDIRECT_ADDRESS';
13
+ export const FRONTEGG_OAUTH_STATE_SAVED_AT = 'FRONTEGG_OAUTH_STATE_SAVED_AT';
14
+
15
+ /** Slightly under typical Redis OAuth session TTL to avoid stale postlogin attempts. */
16
+ export const HOSTED_OAUTH_STATE_MAX_AGE_MS = 23 * 60 * 60 * 1000;
17
+ export const HOSTED_OAUTH_STORAGE_KEYS = [FRONTEGG_OAUTH_REDIRECT_AFTER_LOGIN, FRONTEGG_OAUTH_STATE_AFTER_LOGIN, FRONTEGG_OAUTH_STATE_SAVED_AT, FRONTEGG_AUTHENTICATION_FLOWS_REDIRECT_AFTER_LOGIN, FRONTEGG_OAUTH_INVITATION_TOKEN_KEY, FRONTEGG_OAUTH_ORGANIZATION, FRONTEGG_OAUTH_TENANT_ID, FRONTEGG_OAUTH_STEP_UP_ACR_VALUES, FRONTEGG_OAUTH_STEP_UP_MAX_AGE, FRONTEGG_OAUTH_APP_ID, FRONTEGG_OAUTH_LOGIN_HINT, FRONTEGG_OAUTH_LOGIN_DIRECT_ACTION, FRONTEGG_OAUTH_SILENT_REDIRECT_ADDRESS];
18
+ function removeHostedOAuthCookie(key) {
19
+ document.cookie = `${encodeURIComponent(key)}=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/`;
20
+ }
21
+ function getStoredHostedOAuthValue(key) {
22
+ const fromLocalStorage = window.localStorage.getItem(key);
23
+ if (fromLocalStorage) {
24
+ return fromLocalStorage;
25
+ }
26
+ const fromSessionStorage = window.sessionStorage.getItem(key);
27
+ if (fromSessionStorage) {
28
+ return fromSessionStorage;
29
+ }
30
+ const decodedName = encodeURIComponent(key);
31
+ const cookies = document.cookie.split(';');
32
+ for (let cookie of cookies) {
33
+ cookie = cookie.trim();
34
+ if (cookie.indexOf(`${decodedName}=`) === 0) {
35
+ return decodeURIComponent(cookie.substring(decodedName.length + 1));
36
+ }
37
+ }
38
+ return null;
39
+ }
40
+ export function clearHostedOAuthState() {
41
+ if (typeof window === 'undefined') {
42
+ return;
43
+ }
44
+ HOSTED_OAUTH_STORAGE_KEYS.forEach(key => {
45
+ window.localStorage.removeItem(key);
46
+ window.sessionStorage.removeItem(key);
47
+ removeHostedOAuthCookie(key);
48
+ });
49
+ }
50
+ export function markHostedOAuthStateSaved() {
51
+ if (typeof window === 'undefined') {
52
+ return;
53
+ }
54
+ const value = Date.now().toString();
55
+ window.localStorage.setItem(FRONTEGG_OAUTH_STATE_SAVED_AT, value);
56
+ window.sessionStorage.setItem(FRONTEGG_OAUTH_STATE_SAVED_AT, value);
57
+ const expires = new Date();
58
+ expires.setTime(expires.getTime() + HOSTED_OAUTH_STATE_MAX_AGE_MS);
59
+ document.cookie = `${encodeURIComponent(FRONTEGG_OAUTH_STATE_SAVED_AT)}=${encodeURIComponent(value)};expires=${expires.toUTCString()};path=/`;
60
+ }
61
+ export function isHostedOAuthStateExpired() {
62
+ if (typeof window === 'undefined') {
63
+ return false;
64
+ }
65
+ const savedAt = getStoredHostedOAuthValue(FRONTEGG_OAUTH_STATE_SAVED_AT);
66
+ if (!savedAt) {
67
+ return false;
68
+ }
69
+ const savedAtMs = Number(savedAt);
70
+ if (Number.isNaN(savedAtMs)) {
71
+ return false;
72
+ }
73
+ return Date.now() - savedAtMs > HOSTED_OAUTH_STATE_MAX_AGE_MS;
74
+ }
@@ -70,7 +70,8 @@ export default ((store, api, sharedActions) => {
70
70
  jwt
71
71
  });
72
72
  const tenantsUsersCountArray = await api.tenants.getTenantsUsersCount({
73
- tenantIds: items.map(tenant => tenant.tenantId)
73
+ tenantIds: items.map(tenant => tenant.tenantId),
74
+ excludeInvisibleUsers: true
74
75
  }, {
75
76
  jwt
76
77
  });
@@ -100,7 +101,8 @@ export default ((store, api, sharedActions) => {
100
101
  _links
101
102
  } = await api.tenants.searchSubTenants(searchSubTenantsQueryParams);
102
103
  const tenantsUsersCountArray = await api.tenants.getTenantsUsersCount({
103
- tenantIds: items.map(i => i.tenantId)
104
+ tenantIds: items.map(i => i.tenantId),
105
+ excludeInvisibleUsers: true
104
106
  });
105
107
  const accountsWithUsersCount = getAccountsWithUsersCount({
106
108
  items
@@ -812,7 +814,8 @@ export default ((store, api, sharedActions) => {
812
814
  try {
813
815
  var _tenantUsersCount$;
814
816
  const tenantUsersCount = await api.tenants.getTenantsUsersCount({
815
- tenantIds: [activeTenant == null ? void 0 : activeTenant.tenantId]
817
+ tenantIds: [activeTenant == null ? void 0 : activeTenant.tenantId],
818
+ excludeInvisibleUsers: true
816
819
  });
817
820
  const rootAccount = {
818
821
  name: activeTenant == null ? void 0 : activeTenant.name,
@@ -859,7 +862,8 @@ export default ((store, api, sharedActions) => {
859
862
  jwt
860
863
  });
861
864
  const [numberOfUsersArray, parentsAccounts, subAccountsAmount] = await Promise.all([api.tenants.getTenantsUsersCount({
862
- tenantIds: [(_accountSettings$tena = accountSettings == null ? void 0 : accountSettings.tenantId) != null ? _accountSettings$tena : '']
865
+ tenantIds: [(_accountSettings$tena = accountSettings == null ? void 0 : accountSettings.tenantId) != null ? _accountSettings$tena : ''],
866
+ excludeInvisibleUsers: true
863
867
  }, {
864
868
  jwt
865
869
  }), api.tenants.getParentTenants({
@@ -913,7 +917,8 @@ export default ((store, api, sharedActions) => {
913
917
  value: true
914
918
  });
915
919
  const numberOfUsersArray = await api.tenants.getTenantsUsersCount({
916
- tenantIds: [tenantId]
920
+ tenantIds: [tenantId],
921
+ excludeInvisibleUsers: true
917
922
  }, {
918
923
  jwt
919
924
  });
package/auth/index.d.ts CHANGED
@@ -76,6 +76,7 @@ export * from './UsernamesState/interfaces';
76
76
  export * from './UsersEmailsPolicyState/interfaces';
77
77
  export * from './interfaces';
78
78
  export { FORGOT_PASSWORD_ERROR_KEYS };
79
+ export * from './LoginState/oauthStorage';
79
80
  export declare const createAuthState: (_overrideState?: DeepPartial<AuthState>) => AuthState;
80
81
  export declare const buildAuthActions: (store: FronteggState, api: RestApi, actions: FronteggActions, snapshotAuthState: AuthState) => [AuthActions, AuthStateActions];
81
82
  export type AcceptInvitationActions = ReturnType<typeof buildAcceptInvitationActions>;
package/auth/index.js CHANGED
@@ -80,6 +80,7 @@ export * from './UsernamesState/interfaces';
80
80
  export * from './UsersEmailsPolicyState/interfaces';
81
81
  export * from './interfaces';
82
82
  export { FORGOT_PASSWORD_ERROR_KEYS };
83
+ export * from './LoginState/oauthStorage';
83
84
  export const createAuthState = _overrideState => {
84
85
  const _ref = _overrideState != null ? _overrideState : {},
85
86
  {
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /** @license Frontegg v7.112.0
1
+ /** @license Frontegg v7.114.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.
@@ -11,9 +11,17 @@ var _constants = require("../../../constants");
11
11
  var _consts = require("../../StepUpState/consts");
12
12
  var _helpers2 = require("../../../helpers");
13
13
  var _helpers3 = require("../../StepUpState/helpers");
14
+ var _oauthStorage = require("../oauthStorage");
14
15
  var _default = (store, api, sharedActions) => {
15
16
  const actions = sharedActions;
16
17
 
18
+ // Drop only stale (expired) hosted OAuth state so a fresh, in-progress flow is never affected.
19
+ const clearExpiredHostedOAuthState = () => {
20
+ if ((0, _oauthStorage.isHostedOAuthStateExpired)()) {
21
+ (0, _oauthStorage.clearHostedOAuthState)();
22
+ }
23
+ };
24
+
17
25
  /**
18
26
  * @param url
19
27
  * @returns url without the origin if it's the same origin as the current window origin
@@ -102,6 +110,7 @@ var _default = (store, api, sharedActions) => {
102
110
  * @param options custom login authenticated url if exists
103
111
  */
104
112
  const afterAuthNavigationUtil = async (resetStateAction, options = {}) => {
113
+ clearExpiredHostedOAuthState();
105
114
  const {
106
115
  customLoginAuthenticatedUrl,
107
116
  forceStepUpUrl,
@@ -136,6 +145,9 @@ var _default = (store, api, sharedActions) => {
136
145
  }
137
146
  await (0, _helpers2.delay)(200);
138
147
  await resetStateAction();
148
+ if (redirectUrl.startsWith('http')) {
149
+ (0, _oauthStorage.clearHostedOAuthState)();
150
+ }
139
151
  onRedirectTo(redirectUrl, {
140
152
  refresh: redirectUrl.startsWith('http')
141
153
  });
@@ -20,9 +20,11 @@ var _state = require("../state");
20
20
  var _helpers2 = require("../helpers");
21
21
  var _restApi = require("@frontegg/rest-api");
22
22
  var _hostedLoginAuthorize = _interopRequireDefault(require("./hostedLoginAuthorize.actions"));
23
+ var _oauthStorage = require("../oauthStorage");
24
+ var _consts = require("../../StepUpState/consts");
23
25
  var _toolkit = require("../../../toolkit");
24
26
  var _interfaces2 = require("../../interfaces");
25
- var _consts = require("../consts");
27
+ var _consts2 = require("../consts");
26
28
  var _helpers3 = require("../../helpers");
27
29
  var _interfaces3 = require("../../MfaState/interfaces");
28
30
  var _interfaces4 = require("../../SSOState/interfaces");
@@ -143,8 +145,33 @@ var _default = (store, api, sharedActions) => {
143
145
  }
144
146
  };
145
147
 
148
+ /** @private */
149
+ const __refreshTokenWithNativeTokens = async () => {
150
+ try {
151
+ const tokens = await _toolkit.FronteggNativeModule.getTokens();
152
+ const response = await api.auth.silentOAuthRefreshTokenV3(tokens);
153
+ const updatedUser = await __handleUnnecessaryEntitlementsUpdate(response.user);
154
+ actions.afterAuthenticationStateUpdate((0, _extends2.default)({}, response, {
155
+ user: updatedUser
156
+ }), {
157
+ isAuthenticated: true
158
+ });
159
+ } catch (e) {
160
+ contextHolder.setAccessToken(null);
161
+ contextHolder.setUser(null);
162
+ actions.setAuthState({
163
+ user: null,
164
+ isAuthenticated: false
165
+ });
166
+ }
167
+ };
168
+
146
169
  /** @protected */
147
170
  const __refreshToken = async () => {
171
+ if (_toolkit.FronteggNativeModule.isGetTokensAvailable()) {
172
+ await __refreshTokenWithNativeTokens();
173
+ return;
174
+ }
148
175
  const hostedLoginBox = store.auth.hostedLoginBox;
149
176
  if (hostedLoginBox) {
150
177
  await __refreshTokenHosted();
@@ -610,6 +637,17 @@ var _default = (store, api, sharedActions) => {
610
637
  });
611
638
  }
612
639
  };
640
+ const clearLogoutLocalState = ({
641
+ keepHostedOAuthState = false
642
+ } = {}) => {
643
+ if (contextHolder.isSessionPerTenantEnabled()) {
644
+ (0, _restApi.removeTabTenantFromSessionStorage)();
645
+ }
646
+ // Step-up re-login goes through silentLogout but still needs the hosted OAuth state to finish the client flow.
647
+ if (!keepHostedOAuthState) {
648
+ (0, _oauthStorage.clearHostedOAuthState)();
649
+ }
650
+ };
613
651
  const logout = async payload => {
614
652
  const hostedLoginBox = store.auth.hostedLoginBox;
615
653
  actions.setAuthState({
@@ -624,23 +662,22 @@ var _default = (store, api, sharedActions) => {
624
662
  } catch {
625
663
  /* empty */
626
664
  }
627
- if (contextHolder.isSessionPerTenantEnabled()) {
628
- (0, _restApi.removeTabTenantFromSessionStorage)();
629
- }
665
+ clearLogoutLocalState();
630
666
  actions.resetAuthState();
631
667
  await actions.requestAuthorize(true);
632
668
  payload == null ? void 0 : payload();
633
669
  };
634
670
  const silentLogout = async payload => {
635
- var _payload$callbackTime;
671
+ var _window2, _payload$callbackTime;
636
672
  try {
637
673
  await api.auth.logout();
638
674
  } catch {
639
675
  /* empty */
640
676
  }
641
- if (contextHolder.isSessionPerTenantEnabled()) {
642
- (0, _restApi.removeTabTenantFromSessionStorage)();
643
- }
677
+ const isStepUpInProgress = !!((_window2 = window) != null && _window2.localStorage.getItem(_consts.SHOULD_STEP_UP_KEY));
678
+ clearLogoutLocalState({
679
+ keepHostedOAuthState: isStepUpInProgress
680
+ });
644
681
  setTimeout(() => {
645
682
  var _payload$callback3;
646
683
  return payload == null ? void 0 : (_payload$callback3 = payload.callback) == null ? void 0 : _payload$callback3.call(payload, true);
@@ -773,7 +810,7 @@ var _default = (store, api, sharedActions) => {
773
810
  username: (_username = username) != null ? _username : ''
774
811
  }));
775
812
  // @ts-ignore
776
- const step = _consts.authStrategyLoginStepMap[payload.type];
813
+ const step = _consts2.authStrategyLoginStepMap[payload.type];
777
814
  setLoginState({
778
815
  step,
779
816
  loading: false,
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.HOSTED_OAUTH_STORAGE_KEYS = exports.HOSTED_OAUTH_STATE_MAX_AGE_MS = exports.FRONTEGG_OAUTH_TENANT_ID = exports.FRONTEGG_OAUTH_STEP_UP_MAX_AGE = exports.FRONTEGG_OAUTH_STEP_UP_ACR_VALUES = exports.FRONTEGG_OAUTH_STATE_SAVED_AT = exports.FRONTEGG_OAUTH_STATE_AFTER_LOGIN = exports.FRONTEGG_OAUTH_SILENT_REDIRECT_ADDRESS = exports.FRONTEGG_OAUTH_REDIRECT_AFTER_LOGIN = exports.FRONTEGG_OAUTH_ORGANIZATION = exports.FRONTEGG_OAUTH_LOGIN_HINT = exports.FRONTEGG_OAUTH_LOGIN_DIRECT_ACTION = exports.FRONTEGG_OAUTH_INVITATION_TOKEN_KEY = exports.FRONTEGG_OAUTH_APP_ID = exports.FRONTEGG_AUTHENTICATION_FLOWS_REDIRECT_AFTER_LOGIN = void 0;
7
+ exports.clearHostedOAuthState = clearHostedOAuthState;
8
+ exports.isHostedOAuthStateExpired = isHostedOAuthStateExpired;
9
+ exports.markHostedOAuthStateSaved = markHostedOAuthStateSaved;
10
+ const FRONTEGG_OAUTH_LOGIN_HINT = 'FRONTEGG_OAUTH_LOGIN_HINT';
11
+ exports.FRONTEGG_OAUTH_LOGIN_HINT = FRONTEGG_OAUTH_LOGIN_HINT;
12
+ const FRONTEGG_OAUTH_LOGIN_DIRECT_ACTION = 'FRONTEGG_OAUTH_LOGIN_DIRECT_ACTION';
13
+ exports.FRONTEGG_OAUTH_LOGIN_DIRECT_ACTION = FRONTEGG_OAUTH_LOGIN_DIRECT_ACTION;
14
+ const FRONTEGG_OAUTH_ORGANIZATION = 'FRONTEGG_OAUTH_ORGANIZATION';
15
+ exports.FRONTEGG_OAUTH_ORGANIZATION = FRONTEGG_OAUTH_ORGANIZATION;
16
+ const FRONTEGG_OAUTH_STEP_UP_ACR_VALUES = 'FRONTEGG_OAUTH_STEP_UP_ACR_VALUES';
17
+ exports.FRONTEGG_OAUTH_STEP_UP_ACR_VALUES = FRONTEGG_OAUTH_STEP_UP_ACR_VALUES;
18
+ const FRONTEGG_OAUTH_STEP_UP_MAX_AGE = 'FRONTEGG_OAUTH_STEP_UP_MAX_AGE';
19
+ exports.FRONTEGG_OAUTH_STEP_UP_MAX_AGE = FRONTEGG_OAUTH_STEP_UP_MAX_AGE;
20
+ const FRONTEGG_OAUTH_TENANT_ID = 'FRONTEGG_OAUTH_TENANT_ID';
21
+ exports.FRONTEGG_OAUTH_TENANT_ID = FRONTEGG_OAUTH_TENANT_ID;
22
+ const FRONTEGG_OAUTH_APP_ID = 'FRONTEGG_OAUTH_APP_ID';
23
+ exports.FRONTEGG_OAUTH_APP_ID = FRONTEGG_OAUTH_APP_ID;
24
+ const FRONTEGG_OAUTH_STATE_AFTER_LOGIN = 'FRONTEGG_OAUTH_STATE_AFTER_LOGIN';
25
+ exports.FRONTEGG_OAUTH_STATE_AFTER_LOGIN = FRONTEGG_OAUTH_STATE_AFTER_LOGIN;
26
+ const FRONTEGG_OAUTH_INVITATION_TOKEN_KEY = 'FRONTEGG_OAUTH_INVITATION_TOKEN_KEY';
27
+ exports.FRONTEGG_OAUTH_INVITATION_TOKEN_KEY = FRONTEGG_OAUTH_INVITATION_TOKEN_KEY;
28
+ const FRONTEGG_OAUTH_REDIRECT_AFTER_LOGIN = 'FRONTEGG_OAUTH_REDIRECT_AFTER_LOGIN';
29
+ exports.FRONTEGG_OAUTH_REDIRECT_AFTER_LOGIN = FRONTEGG_OAUTH_REDIRECT_AFTER_LOGIN;
30
+ const FRONTEGG_AUTHENTICATION_FLOWS_REDIRECT_AFTER_LOGIN = 'FRONTEGG_AUTHENTICATION_FLOWS_REDIRECT_AFTER_LOGIN';
31
+ exports.FRONTEGG_AUTHENTICATION_FLOWS_REDIRECT_AFTER_LOGIN = FRONTEGG_AUTHENTICATION_FLOWS_REDIRECT_AFTER_LOGIN;
32
+ const FRONTEGG_OAUTH_SILENT_REDIRECT_ADDRESS = 'FRONTEGG_OAUTH_SILENT_REDIRECT_ADDRESS';
33
+ exports.FRONTEGG_OAUTH_SILENT_REDIRECT_ADDRESS = FRONTEGG_OAUTH_SILENT_REDIRECT_ADDRESS;
34
+ const FRONTEGG_OAUTH_STATE_SAVED_AT = 'FRONTEGG_OAUTH_STATE_SAVED_AT';
35
+
36
+ /** Slightly under typical Redis OAuth session TTL to avoid stale postlogin attempts. */
37
+ exports.FRONTEGG_OAUTH_STATE_SAVED_AT = FRONTEGG_OAUTH_STATE_SAVED_AT;
38
+ const HOSTED_OAUTH_STATE_MAX_AGE_MS = 23 * 60 * 60 * 1000;
39
+ exports.HOSTED_OAUTH_STATE_MAX_AGE_MS = HOSTED_OAUTH_STATE_MAX_AGE_MS;
40
+ const HOSTED_OAUTH_STORAGE_KEYS = [FRONTEGG_OAUTH_REDIRECT_AFTER_LOGIN, FRONTEGG_OAUTH_STATE_AFTER_LOGIN, FRONTEGG_OAUTH_STATE_SAVED_AT, FRONTEGG_AUTHENTICATION_FLOWS_REDIRECT_AFTER_LOGIN, FRONTEGG_OAUTH_INVITATION_TOKEN_KEY, FRONTEGG_OAUTH_ORGANIZATION, FRONTEGG_OAUTH_TENANT_ID, FRONTEGG_OAUTH_STEP_UP_ACR_VALUES, FRONTEGG_OAUTH_STEP_UP_MAX_AGE, FRONTEGG_OAUTH_APP_ID, FRONTEGG_OAUTH_LOGIN_HINT, FRONTEGG_OAUTH_LOGIN_DIRECT_ACTION, FRONTEGG_OAUTH_SILENT_REDIRECT_ADDRESS];
41
+ exports.HOSTED_OAUTH_STORAGE_KEYS = HOSTED_OAUTH_STORAGE_KEYS;
42
+ function removeHostedOAuthCookie(key) {
43
+ document.cookie = `${encodeURIComponent(key)}=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/`;
44
+ }
45
+ function getStoredHostedOAuthValue(key) {
46
+ const fromLocalStorage = window.localStorage.getItem(key);
47
+ if (fromLocalStorage) {
48
+ return fromLocalStorage;
49
+ }
50
+ const fromSessionStorage = window.sessionStorage.getItem(key);
51
+ if (fromSessionStorage) {
52
+ return fromSessionStorage;
53
+ }
54
+ const decodedName = encodeURIComponent(key);
55
+ const cookies = document.cookie.split(';');
56
+ for (let cookie of cookies) {
57
+ cookie = cookie.trim();
58
+ if (cookie.indexOf(`${decodedName}=`) === 0) {
59
+ return decodeURIComponent(cookie.substring(decodedName.length + 1));
60
+ }
61
+ }
62
+ return null;
63
+ }
64
+ function clearHostedOAuthState() {
65
+ if (typeof window === 'undefined') {
66
+ return;
67
+ }
68
+ HOSTED_OAUTH_STORAGE_KEYS.forEach(key => {
69
+ window.localStorage.removeItem(key);
70
+ window.sessionStorage.removeItem(key);
71
+ removeHostedOAuthCookie(key);
72
+ });
73
+ }
74
+ function markHostedOAuthStateSaved() {
75
+ if (typeof window === 'undefined') {
76
+ return;
77
+ }
78
+ const value = Date.now().toString();
79
+ window.localStorage.setItem(FRONTEGG_OAUTH_STATE_SAVED_AT, value);
80
+ window.sessionStorage.setItem(FRONTEGG_OAUTH_STATE_SAVED_AT, value);
81
+ const expires = new Date();
82
+ expires.setTime(expires.getTime() + HOSTED_OAUTH_STATE_MAX_AGE_MS);
83
+ document.cookie = `${encodeURIComponent(FRONTEGG_OAUTH_STATE_SAVED_AT)}=${encodeURIComponent(value)};expires=${expires.toUTCString()};path=/`;
84
+ }
85
+ function isHostedOAuthStateExpired() {
86
+ if (typeof window === 'undefined') {
87
+ return false;
88
+ }
89
+ const savedAt = getStoredHostedOAuthValue(FRONTEGG_OAUTH_STATE_SAVED_AT);
90
+ if (!savedAt) {
91
+ return false;
92
+ }
93
+ const savedAtMs = Number(savedAt);
94
+ if (Number.isNaN(savedAtMs)) {
95
+ return false;
96
+ }
97
+ return Date.now() - savedAtMs > HOSTED_OAUTH_STATE_MAX_AGE_MS;
98
+ }
@@ -77,7 +77,8 @@ var _default = (store, api, sharedActions) => {
77
77
  jwt
78
78
  });
79
79
  const tenantsUsersCountArray = await api.tenants.getTenantsUsersCount({
80
- tenantIds: items.map(tenant => tenant.tenantId)
80
+ tenantIds: items.map(tenant => tenant.tenantId),
81
+ excludeInvisibleUsers: true
81
82
  }, {
82
83
  jwt
83
84
  });
@@ -107,7 +108,8 @@ var _default = (store, api, sharedActions) => {
107
108
  _links
108
109
  } = await api.tenants.searchSubTenants(searchSubTenantsQueryParams);
109
110
  const tenantsUsersCountArray = await api.tenants.getTenantsUsersCount({
110
- tenantIds: items.map(i => i.tenantId)
111
+ tenantIds: items.map(i => i.tenantId),
112
+ excludeInvisibleUsers: true
111
113
  });
112
114
  const accountsWithUsersCount = (0, _helpers2.getAccountsWithUsersCount)({
113
115
  items
@@ -819,7 +821,8 @@ var _default = (store, api, sharedActions) => {
819
821
  try {
820
822
  var _tenantUsersCount$;
821
823
  const tenantUsersCount = await api.tenants.getTenantsUsersCount({
822
- tenantIds: [activeTenant == null ? void 0 : activeTenant.tenantId]
824
+ tenantIds: [activeTenant == null ? void 0 : activeTenant.tenantId],
825
+ excludeInvisibleUsers: true
823
826
  });
824
827
  const rootAccount = {
825
828
  name: activeTenant == null ? void 0 : activeTenant.name,
@@ -866,7 +869,8 @@ var _default = (store, api, sharedActions) => {
866
869
  jwt
867
870
  });
868
871
  const [numberOfUsersArray, parentsAccounts, subAccountsAmount] = await Promise.all([api.tenants.getTenantsUsersCount({
869
- tenantIds: [(_accountSettings$tena = accountSettings == null ? void 0 : accountSettings.tenantId) != null ? _accountSettings$tena : '']
872
+ tenantIds: [(_accountSettings$tena = accountSettings == null ? void 0 : accountSettings.tenantId) != null ? _accountSettings$tena : ''],
873
+ excludeInvisibleUsers: true
870
874
  }, {
871
875
  jwt
872
876
  }), api.tenants.getParentTenants({
@@ -920,7 +924,8 @@ var _default = (store, api, sharedActions) => {
920
924
  value: true
921
925
  });
922
926
  const numberOfUsersArray = await api.tenants.getTenantsUsersCount({
923
- tenantIds: [tenantId]
927
+ tenantIds: [tenantId],
928
+ excludeInvisibleUsers: true
924
929
  }, {
925
930
  jwt
926
931
  });
@@ -513,6 +513,18 @@ Object.keys(_interfaces37).forEach(function (key) {
513
513
  }
514
514
  });
515
515
  });
516
+ var _oauthStorage = require("./LoginState/oauthStorage");
517
+ Object.keys(_oauthStorage).forEach(function (key) {
518
+ if (key === "default" || key === "__esModule") return;
519
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
520
+ if (key in exports && exports[key] === _oauthStorage[key]) return;
521
+ Object.defineProperty(exports, key, {
522
+ enumerable: true,
523
+ get: function () {
524
+ return _oauthStorage[key];
525
+ }
526
+ });
527
+ });
516
528
  const _excluded = ["routes"],
517
529
  _excluded2 = ["requestName"];
518
530
  const createAuthState = _overrideState => {
package/node/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /** @license Frontegg v7.112.0
1
+ /** @license Frontegg v7.114.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.112.0",
3
+ "version": "7.114.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.112.0",
10
+ "@frontegg/rest-api": "7.114.0",
11
11
  "fast-deep-equal": "3.1.3",
12
12
  "get-value": "^3.0.1",
13
13
  "proxy-compare": "^3.0.0",