@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.
- package/auth/LoginState/actions/afterAuthNavigation.actions.js +12 -0
- package/auth/LoginState/actions/index.js +44 -7
- package/auth/LoginState/oauthStorage.d.ts +19 -0
- package/auth/LoginState/oauthStorage.js +74 -0
- package/auth/MSP/actions.js +10 -5
- package/auth/index.d.ts +1 -0
- package/auth/index.js +1 -0
- package/index.js +1 -1
- package/node/auth/LoginState/actions/afterAuthNavigation.actions.js +12 -0
- package/node/auth/LoginState/actions/index.js +46 -9
- package/node/auth/LoginState/oauthStorage.js +98 -0
- package/node/auth/MSP/actions.js +10 -5
- package/node/auth/index.js +12 -0
- package/node/index.js +1 -1
- package/package.json +2 -2
|
@@ -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
|
-
|
|
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
|
-
|
|
635
|
-
|
|
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
|
+
}
|
package/auth/MSP/actions.js
CHANGED
|
@@ -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
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
642
|
-
|
|
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 =
|
|
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
|
+
}
|
package/node/auth/MSP/actions.js
CHANGED
|
@@ -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
|
});
|
package/node/auth/index.js
CHANGED
|
@@ -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
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frontegg/redux-store",
|
|
3
|
-
"version": "7.
|
|
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.
|
|
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",
|