@frontegg/redux-store 7.129.0 → 7.131.0-alpha.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/hostedLoginAuthorize.actions.d.ts +3 -1
- package/auth/LoginState/actions/hostedLoginAuthorize.actions.js +23 -5
- package/auth/LoginState/actions/index.d.ts +8 -1
- package/auth/LoginState/actions/index.js +155 -35
- package/auth/LoginState/actions/mfaWithAuthenticator.actions.js +3 -0
- package/auth/LoginState/actions/mfaWithEmailCode.actions.js +3 -0
- package/auth/LoginState/actions/mfaWithSMS.actions.js +3 -0
- package/auth/LoginState/actions/mfaWithWebAuthn.actions.js +3 -0
- package/auth/SocialLoginState/actions.js +3 -0
- package/auth/TeamState/actions/activation-link.actions.js +1 -1
- package/auth/TenantsState/actions.js +8 -1
- package/helpers/handlers.d.ts +4 -1
- package/helpers/handlers.js +4 -1
- package/index.js +1 -1
- package/mocks/auth-mocks/loginActions.mocks.d.ts +8 -1
- package/node/auth/LoginState/actions/hostedLoginAuthorize.actions.js +22 -4
- package/node/auth/LoginState/actions/index.js +151 -31
- package/node/auth/LoginState/actions/mfaWithAuthenticator.actions.js +3 -0
- package/node/auth/LoginState/actions/mfaWithEmailCode.actions.js +3 -0
- package/node/auth/LoginState/actions/mfaWithSMS.actions.js +3 -0
- package/node/auth/LoginState/actions/mfaWithWebAuthn.actions.js +3 -0
- package/node/auth/SocialLoginState/actions.js +3 -0
- package/node/auth/TeamState/actions/activation-link.actions.js +1 -1
- package/node/auth/TenantsState/actions.js +7 -0
- package/node/helpers/handlers.js +5 -1
- package/node/index.js +1 -1
- package/package.json +2 -2
|
@@ -8,7 +8,9 @@ declare const _default: (store: FronteggState, api: RestApi, sharedActions: Shar
|
|
|
8
8
|
firstTime?: boolean;
|
|
9
9
|
loginDirectAction?: LoginDirectAction;
|
|
10
10
|
}) => Promise<void>;
|
|
11
|
-
__requestHostedLoginAuthorize: (additionalParams?: Record<string, string
|
|
11
|
+
__requestHostedLoginAuthorize: (additionalParams?: Record<string, string>, { forceTenantId }?: {
|
|
12
|
+
forceTenantId?: boolean;
|
|
13
|
+
}) => Promise<void>;
|
|
12
14
|
__requestHostedLoginSilentAuthorize: () => Promise<void>;
|
|
13
15
|
handleHostedLoginCallback: (payload: HostedLoginCallback) => Promise<void>;
|
|
14
16
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
|
-
import { createRandomString, generateCodeChallenge, GTMEventAction, refreshTokenWithRetry, reportGTMEvent } from '../../../helpers';
|
|
2
|
+
import { createRandomString, generateCodeChallenge, GTMEventAction, isSsoEnforcementError, refreshTokenWithRetry, reportGTMEvent } from '../../../helpers';
|
|
3
3
|
import { HOSTED_LOGIN_VERIFIER_KEY } from '../../../constants';
|
|
4
|
+
import { isEnforceSsoOnTenantAccessEnabled } from '@frontegg/rest-api';
|
|
4
5
|
import { getBaseNameWithoutSlashSuffix, getSearchParam, isOauthCallbackRoute, TENANT_ID_PARAM_KEY } from '../helpers';
|
|
5
6
|
import { getUri, getUrlDerivedStepUp, isSteppedUp, redirectByStepUpUrl } from '../../helpers';
|
|
6
7
|
import { SHOULD_STEP_UP_KEY } from '../../StepUpState/consts';
|
|
@@ -21,7 +22,17 @@ export default ((store, api, sharedActions) => {
|
|
|
21
22
|
return await authApi.silentOAuthRefreshTokenV3(tokens);
|
|
22
23
|
});
|
|
23
24
|
} else {
|
|
24
|
-
|
|
25
|
+
try {
|
|
26
|
+
response = await api.auth.silentOAuthRefreshTokenV2();
|
|
27
|
+
} catch (error) {
|
|
28
|
+
var _store$auth$user, _error$errorContext;
|
|
29
|
+
const tenantId = (_store$auth$user = store.auth.user) == null ? void 0 : _store$auth$user.tenantId;
|
|
30
|
+
if (!isEnforceSsoOnTenantAccessEnabled(store.root.appName) || !isSsoEnforcementError(error) || ((_error$errorContext = error.errorContext) == null ? void 0 : _error$errorContext.ssoRequired) !== false || !tenantId) {
|
|
31
|
+
throw error;
|
|
32
|
+
}
|
|
33
|
+
// one retry for the tenant of the current token (a cold reload has no user yet: no retry)
|
|
34
|
+
response = await api.auth.silentOAuthRefreshTokenV2(tenantId);
|
|
35
|
+
}
|
|
25
36
|
}
|
|
26
37
|
if ((_response = response) != null && _response.user) {
|
|
27
38
|
await actions.afterAuthenticationStateUpdate(response, {
|
|
@@ -32,7 +43,14 @@ export default ((store, api, sharedActions) => {
|
|
|
32
43
|
throw new Error(`couldn't refresh user token with oauth service`);
|
|
33
44
|
}
|
|
34
45
|
};
|
|
35
|
-
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @param options.forceTenantId the tenantId in additionalParams wins over the resolved and the page's tenant
|
|
49
|
+
* (sending the user to that tenant's SSO); other callers keep their custom login tenant
|
|
50
|
+
*/
|
|
51
|
+
const requestHostedLoginAuthorize = async (additionalParams, {
|
|
52
|
+
forceTenantId = false
|
|
53
|
+
} = {}) => {
|
|
36
54
|
var _store$auth$customLog;
|
|
37
55
|
const {
|
|
38
56
|
routes,
|
|
@@ -79,7 +97,7 @@ export default ((store, api, sharedActions) => {
|
|
|
79
97
|
code_challenge_method: 'S256',
|
|
80
98
|
nonce
|
|
81
99
|
}, additionalParams);
|
|
82
|
-
if (context.tenantResolver) {
|
|
100
|
+
if (context.tenantResolver && !forceTenantId) {
|
|
83
101
|
var _context$tenantResolv;
|
|
84
102
|
const resolvedTenantResult = await ((_context$tenantResolv = context.tenantResolver) == null ? void 0 : _context$tenantResolv.call(context));
|
|
85
103
|
if (resolvedTenantResult != null && resolvedTenantResult.tenant) {
|
|
@@ -87,7 +105,7 @@ export default ((store, api, sharedActions) => {
|
|
|
87
105
|
}
|
|
88
106
|
}
|
|
89
107
|
const tenantId = getSearchParam(TENANT_ID_PARAM_KEY);
|
|
90
|
-
if (tenantId) {
|
|
108
|
+
if (tenantId && !forceTenantId) {
|
|
91
109
|
params['tenantId'] = tenantId;
|
|
92
110
|
}
|
|
93
111
|
if (FronteggNativeModule.isAvailable('closeWindow')) {
|
|
@@ -37,7 +37,9 @@ declare const _default: (store: FronteggState, api: RestApi, sharedActions: Shar
|
|
|
37
37
|
firstTime?: boolean;
|
|
38
38
|
loginDirectAction?: import("../interfaces").LoginDirectAction;
|
|
39
39
|
}) => Promise<void>;
|
|
40
|
-
__requestHostedLoginAuthorize: (additionalParams?: Record<string, string
|
|
40
|
+
__requestHostedLoginAuthorize: (additionalParams?: Record<string, string>, { forceTenantId }?: {
|
|
41
|
+
forceTenantId?: boolean;
|
|
42
|
+
}) => Promise<void>;
|
|
41
43
|
__requestHostedLoginSilentAuthorize: () => Promise<void>;
|
|
42
44
|
handleHostedLoginCallback: (payload: import("../interfaces").HostedLoginCallback) => Promise<void>;
|
|
43
45
|
setLoginState: (state: Partial<LoginState>) => void;
|
|
@@ -75,5 +77,10 @@ declare const _default: (store: FronteggState, api: RestApi, sharedActions: Shar
|
|
|
75
77
|
resetBreachedPassword: (payload: IForgotPassword) => Promise<void>;
|
|
76
78
|
refreshTokenForSocialLogins: () => Promise<void>;
|
|
77
79
|
__refreshToken: () => Promise<void>;
|
|
80
|
+
__redirectToSsoForTenant: ({ tenantId, address }: {
|
|
81
|
+
tenantId: string;
|
|
82
|
+
address: string;
|
|
83
|
+
}) => Promise<void>;
|
|
84
|
+
__redirectToSsoIfRequired: (e: unknown) => Promise<boolean>;
|
|
78
85
|
};
|
|
79
86
|
export default _default;
|
|
@@ -1,20 +1,21 @@
|
|
|
1
|
-
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
|
|
2
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
|
|
3
|
+
const _excluded = ["authenticatedUrl"],
|
|
4
|
+
_excluded2 = ["callback", "error"],
|
|
5
5
|
_excluded3 = ["callback"],
|
|
6
6
|
_excluded4 = ["callback"],
|
|
7
7
|
_excluded5 = ["callback"],
|
|
8
|
-
_excluded6 = ["callback"
|
|
9
|
-
_excluded7 = ["callback"],
|
|
8
|
+
_excluded6 = ["callback"],
|
|
9
|
+
_excluded7 = ["callback", "events"],
|
|
10
10
|
_excluded8 = ["callback"],
|
|
11
|
-
_excluded9 = ["
|
|
12
|
-
_excluded10 = ["
|
|
11
|
+
_excluded9 = ["callback"],
|
|
12
|
+
_excluded10 = ["user"],
|
|
13
13
|
_excluded11 = ["callback"],
|
|
14
14
|
_excluded12 = ["callback"],
|
|
15
15
|
_excluded13 = ["callback"],
|
|
16
16
|
_excluded14 = ["callback"],
|
|
17
|
-
_excluded15 = ["callback"]
|
|
17
|
+
_excluded15 = ["callback"],
|
|
18
|
+
_excluded16 = ["callback"];
|
|
18
19
|
import afterAuthNavigationActions from './afterAuthNavigation.actions';
|
|
19
20
|
import handleVerifyMFAResponseActions from './handleVerifyMFAResponse.actions';
|
|
20
21
|
import mfaRequiredStateActions from './mfaRequiredState.actions';
|
|
@@ -23,17 +24,17 @@ import mfaWithEmailCodeActions from './mfaWithEmailCode.actions';
|
|
|
23
24
|
import mfaWithSMSActions from './mfaWithSMS.actions';
|
|
24
25
|
import mfaWithWebAuthnActions from './mfaWithWebAuthn.actions';
|
|
25
26
|
import { LoginFlow, LoginStep } from '../interfaces';
|
|
26
|
-
import { base64urlDecode, deepResetState, delay, errorHandler, errorTraceId, GTMEventAction, publicKeyCredentialToJSON, refreshTokenWithRetry, reportGTMEvent, retryIfNeeded, withRetryConfig } from '../../../helpers';
|
|
27
|
+
import { base64urlDecode, deepResetState, delay, errorHandler, errorTraceId, GTMEventAction, isSsoEnforcementError, publicKeyCredentialToJSON, refreshTokenWithRetry, reportGTMEvent, retryIfNeeded, withRetryConfig } from '../../../helpers';
|
|
27
28
|
import { initialState } from '../state';
|
|
28
29
|
import { getSearchParam, isEmailPayload, isUsernamePayload, shouldShowPasswordRotationPromptFunc, TENANT_ID_PARAM_KEY } from '../helpers';
|
|
29
|
-
import { AuthStrategyEnum, ContextHolder, FeatureFlags, getTabTenantFromSessionStorage, removeTabTenantFromSessionStorage, WebAuthnDeviceType, PreLoginAddressType } from '@frontegg/rest-api';
|
|
30
|
+
import { AuthStrategyEnum, ContextHolder, isEnforceSsoOnTenantAccessEnabled, FeatureFlags, getTabTenantFromSessionStorage, removeTabTenantFromSessionStorage, setTabTenantInSessionStorage, WebAuthnDeviceType, PreLoginAddressType } from '@frontegg/rest-api';
|
|
30
31
|
import hostedLoginAuthorizeActions from './hostedLoginAuthorize.actions';
|
|
31
32
|
import { clearHostedOAuthState } from '../oauthStorage';
|
|
32
33
|
import { SHOULD_STEP_UP_KEY } from '../../StepUpState/consts';
|
|
33
34
|
import { FronteggNativeModule, isEntitlementsDeeplyEqual } from '../../../toolkit';
|
|
34
35
|
import { REQUEST_NAME, UserVerifiedOriginTypes } from '../../interfaces';
|
|
35
|
-
import { authStrategyLoginStepMap, defaultOnRedirectTo } from '../consts';
|
|
36
|
-
import { isMfaRequired, isResetPasswordRequired } from '../../helpers';
|
|
36
|
+
import { authStrategyLoginStepMap, defaultFronteggRoutes, defaultOnRedirectTo } from '../consts';
|
|
37
|
+
import { isMfaRequired, isResetPasswordRequired, setAfterAuthRedirectUrlForStepUp } from '../../helpers';
|
|
37
38
|
import { MFAStep } from '../../MfaState/interfaces';
|
|
38
39
|
import { SamlVendors } from '../../SSOState/interfaces';
|
|
39
40
|
import { DEFAULT_RETRY_CONFIG } from '../../../constants';
|
|
@@ -43,8 +44,83 @@ export default ((store, api, sharedActions) => {
|
|
|
43
44
|
const actions = sharedActions;
|
|
44
45
|
const contextHolder = ContextHolder.for(store.root.appName);
|
|
45
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Sends the user to log in through the tenant's SSO and back to the current page afterwards.
|
|
49
|
+
* @protected
|
|
50
|
+
*/
|
|
51
|
+
const __redirectToSsoForTenant = async ({
|
|
52
|
+
tenantId,
|
|
53
|
+
address
|
|
54
|
+
}) => {
|
|
55
|
+
// on an auth page (login, tenant chooser, social / magic link / SSO callback) keep the destination the login
|
|
56
|
+
// already saved: the page itself is not one to come back to
|
|
57
|
+
const _defaultFronteggRoute = _extends({}, defaultFronteggRoutes, store.auth.routes),
|
|
58
|
+
authRoutes = _objectWithoutPropertiesLoose(_defaultFronteggRoute, _excluded);
|
|
59
|
+
const isOnAuthPage = Object.values(authRoutes).some(route => typeof route === 'string' && !!route && window.location.pathname.endsWith(route));
|
|
60
|
+
if (!isOnAuthPage) {
|
|
61
|
+
setAfterAuthRedirectUrlForStepUp();
|
|
62
|
+
}
|
|
63
|
+
if (store.auth.hostedLoginBox) {
|
|
64
|
+
var _window$localStorage;
|
|
65
|
+
// as loginWithRedirect does, but the SSO tenant wins over the custom login tenant
|
|
66
|
+
(_window$localStorage = window.localStorage) == null ? void 0 : _window$localStorage.removeItem(SHOULD_STEP_UP_KEY);
|
|
67
|
+
await actions.__requestHostedLoginAuthorize({
|
|
68
|
+
prompt: 'login',
|
|
69
|
+
tenantId
|
|
70
|
+
}, {
|
|
71
|
+
forceTenantId: true
|
|
72
|
+
});
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
store.auth.onRedirectTo(address, {
|
|
76
|
+
refresh: true
|
|
77
|
+
});
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Sends the user to the tenant's SSO when a login or tenant switch is refused because that tenant requires it
|
|
82
|
+
* (e.g. an invitation into a tenant whose SSO covers the user's email). The SSO login lands in that tenant.
|
|
83
|
+
* @returns true when redirected, so the caller doesn't show the error
|
|
84
|
+
* @protected
|
|
85
|
+
*/
|
|
86
|
+
const __redirectToSsoIfRequired = async e => {
|
|
87
|
+
if (!isEnforceSsoOnTenantAccessEnabled(store.root.appName) || !isSsoEnforcementError(e) || !e.errorContext.ssoRequired) {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
await __redirectToSsoForTenant(e.errorContext);
|
|
91
|
+
return true;
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* Handles a hosted (OAuth) token refresh refused because the tenant requires SSO.
|
|
95
|
+
* ssoRequired: true sends the user to SSO, like login. ssoRequired: false renews once more for the tenant of the
|
|
96
|
+
* current token, which keeps the session: OAuth doesn't use up the refresh token on this refusal.
|
|
97
|
+
* @returns true when handled, false when the caller should log out
|
|
98
|
+
* @private
|
|
99
|
+
*/
|
|
100
|
+
const __handleSsoEnforcementRefreshError = async (e, isSsoEnforcementRetry, refreshForTenant) => {
|
|
101
|
+
var _store$auth$user;
|
|
102
|
+
if (!isEnforceSsoOnTenantAccessEnabled(store.root.appName) || !isSsoEnforcementError(e)) {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
if (await __redirectToSsoIfRequired(e)) {
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
const currentTenantId = (_store$auth$user = store.auth.user) == null ? void 0 : _store$auth$user.tenantId;
|
|
109
|
+
if (isSsoEnforcementRetry || !currentTenantId) {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
if (contextHolder.isSessionPerTenantEnabled()) {
|
|
113
|
+
setTabTenantInSessionStorage(currentTenantId);
|
|
114
|
+
}
|
|
115
|
+
await refreshForTenant(currentTenantId);
|
|
116
|
+
return true;
|
|
117
|
+
};
|
|
118
|
+
|
|
46
119
|
/** @private */
|
|
47
|
-
const __refreshTokenHosted = async (
|
|
120
|
+
const __refreshTokenHosted = async ({
|
|
121
|
+
tenantId,
|
|
122
|
+
isSsoEnforcementRetry = false
|
|
123
|
+
} = {}) => {
|
|
48
124
|
const user = store.auth.user;
|
|
49
125
|
if (!(user != null && user.refreshToken)) {
|
|
50
126
|
contextHolder.setAccessToken(null);
|
|
@@ -56,7 +132,7 @@ export default ((store, api, sharedActions) => {
|
|
|
56
132
|
return;
|
|
57
133
|
}
|
|
58
134
|
try {
|
|
59
|
-
const tabTenantId = getTabTenantFromSessionStorage(store.root.appName);
|
|
135
|
+
const tabTenantId = tenantId != null ? tenantId : getTabTenantFromSessionStorage(store.root.appName);
|
|
60
136
|
const body = _extends({
|
|
61
137
|
grant_type: 'refresh_token',
|
|
62
138
|
refresh_token: user == null ? void 0 : user.refreshToken
|
|
@@ -71,6 +147,13 @@ export default ((store, api, sharedActions) => {
|
|
|
71
147
|
isAuthenticated: true
|
|
72
148
|
});
|
|
73
149
|
} catch (e) {
|
|
150
|
+
const retry = tenantId => __refreshTokenHosted({
|
|
151
|
+
tenantId,
|
|
152
|
+
isSsoEnforcementRetry: true
|
|
153
|
+
});
|
|
154
|
+
if (await __handleSsoEnforcementRefreshError(e, isSsoEnforcementRetry, retry)) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
74
157
|
contextHolder.setAccessToken(null);
|
|
75
158
|
contextHolder.setUser(null);
|
|
76
159
|
actions.setAuthState({
|
|
@@ -132,6 +215,10 @@ export default ((store, api, sharedActions) => {
|
|
|
132
215
|
});
|
|
133
216
|
}
|
|
134
217
|
} catch (e) {
|
|
218
|
+
// a refused identity refresh has already used up the refresh token: no retry, only the SSO redirect
|
|
219
|
+
if (await __redirectToSsoIfRequired(e)) {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
135
222
|
contextHolder.setAccessToken(null);
|
|
136
223
|
contextHolder.setUser(null);
|
|
137
224
|
actions.setAuthState({
|
|
@@ -142,7 +229,9 @@ export default ((store, api, sharedActions) => {
|
|
|
142
229
|
};
|
|
143
230
|
|
|
144
231
|
/** @private */
|
|
145
|
-
const __refreshTokenWithNativeTokens = async (
|
|
232
|
+
const __refreshTokenWithNativeTokens = async ({
|
|
233
|
+
isSsoEnforcementRetry = false
|
|
234
|
+
} = {}) => {
|
|
146
235
|
try {
|
|
147
236
|
const authApi = api.auth;
|
|
148
237
|
const response = await refreshTokenWithRetry(async () => {
|
|
@@ -156,6 +245,13 @@ export default ((store, api, sharedActions) => {
|
|
|
156
245
|
isAuthenticated: true
|
|
157
246
|
});
|
|
158
247
|
} catch (e) {
|
|
248
|
+
// native tokens can't name a tenant: the retry relies on the tab tenant only
|
|
249
|
+
const retry = () => __refreshTokenWithNativeTokens({
|
|
250
|
+
isSsoEnforcementRetry: true
|
|
251
|
+
});
|
|
252
|
+
if (await __handleSsoEnforcementRefreshError(e, isSsoEnforcementRetry, retry)) {
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
159
255
|
contextHolder.setAccessToken(null);
|
|
160
256
|
contextHolder.setUser(null);
|
|
161
257
|
actions.setAuthState({
|
|
@@ -189,9 +285,9 @@ export default ((store, api, sharedActions) => {
|
|
|
189
285
|
* @private
|
|
190
286
|
*/
|
|
191
287
|
const __handleUnnecessaryEntitlementsUpdate = async updatedUser => {
|
|
192
|
-
var _store$auth$
|
|
288
|
+
var _store$auth$user2;
|
|
193
289
|
// @ts-ignore TODO: fix entitlements state type
|
|
194
|
-
const oldEntitlements = (_store$auth$
|
|
290
|
+
const oldEntitlements = (_store$auth$user2 = store.auth.user) == null ? void 0 : _store$auth$user2.entitlements;
|
|
195
291
|
if (isEntitlementsDeeplyEqual(oldEntitlements, updatedUser == null ? void 0 : updatedUser.entitlements)) {
|
|
196
292
|
// set the previous entitlements object
|
|
197
293
|
return _extends({}, updatedUser, {
|
|
@@ -359,7 +455,7 @@ export default ((store, api, sharedActions) => {
|
|
|
359
455
|
callback,
|
|
360
456
|
error
|
|
361
457
|
} = _ref3,
|
|
362
|
-
body = _objectWithoutPropertiesLoose(_ref3,
|
|
458
|
+
body = _objectWithoutPropertiesLoose(_ref3, _excluded2);
|
|
363
459
|
const publicPolicy = store.auth.securityPolicyState.publicPolicy.policy;
|
|
364
460
|
if (!(publicPolicy != null && publicPolicy.authStrategy)) {
|
|
365
461
|
actions.setLoginState({
|
|
@@ -668,6 +764,9 @@ export default ((store, api, sharedActions) => {
|
|
|
668
764
|
} catch (e) {
|
|
669
765
|
contextHolder.setAccessToken(null);
|
|
670
766
|
contextHolder.setUser(null);
|
|
767
|
+
if (await __redirectToSsoIfRequired(e)) {
|
|
768
|
+
return;
|
|
769
|
+
}
|
|
671
770
|
callback == null ? void 0 : callback(false, e);
|
|
672
771
|
setLoginState({
|
|
673
772
|
email,
|
|
@@ -752,7 +851,7 @@ export default ((store, api, sharedActions) => {
|
|
|
752
851
|
const {
|
|
753
852
|
callback
|
|
754
853
|
} = _payload,
|
|
755
|
-
payload = _objectWithoutPropertiesLoose(_payload,
|
|
854
|
+
payload = _objectWithoutPropertiesLoose(_payload, _excluded3);
|
|
756
855
|
try {
|
|
757
856
|
setLoginState({
|
|
758
857
|
loading: true
|
|
@@ -782,7 +881,7 @@ export default ((store, api, sharedActions) => {
|
|
|
782
881
|
const {
|
|
783
882
|
callback
|
|
784
883
|
} = _payload,
|
|
785
|
-
payload = _objectWithoutPropertiesLoose(_payload,
|
|
884
|
+
payload = _objectWithoutPropertiesLoose(_payload, _excluded4);
|
|
786
885
|
try {
|
|
787
886
|
setLoginState({
|
|
788
887
|
loading: true
|
|
@@ -807,7 +906,7 @@ export default ((store, api, sharedActions) => {
|
|
|
807
906
|
const {
|
|
808
907
|
callback
|
|
809
908
|
} = _payload,
|
|
810
|
-
payload = _objectWithoutPropertiesLoose(_payload,
|
|
909
|
+
payload = _objectWithoutPropertiesLoose(_payload, _excluded5);
|
|
811
910
|
try {
|
|
812
911
|
setLoginState({
|
|
813
912
|
loading: true
|
|
@@ -828,7 +927,7 @@ export default ((store, api, sharedActions) => {
|
|
|
828
927
|
const {
|
|
829
928
|
callback
|
|
830
929
|
} = _payload,
|
|
831
|
-
payload = _objectWithoutPropertiesLoose(_payload,
|
|
930
|
+
payload = _objectWithoutPropertiesLoose(_payload, _excluded6);
|
|
832
931
|
try {
|
|
833
932
|
var _username;
|
|
834
933
|
setLoginState({
|
|
@@ -872,7 +971,7 @@ export default ((store, api, sharedActions) => {
|
|
|
872
971
|
callback,
|
|
873
972
|
events
|
|
874
973
|
} = _payload,
|
|
875
|
-
payload = _objectWithoutPropertiesLoose(_payload,
|
|
974
|
+
payload = _objectWithoutPropertiesLoose(_payload, _excluded7);
|
|
876
975
|
try {
|
|
877
976
|
setLoginState({
|
|
878
977
|
loading: true
|
|
@@ -963,6 +1062,9 @@ export default ((store, api, sharedActions) => {
|
|
|
963
1062
|
callback == null ? void 0 : callback(true);
|
|
964
1063
|
}
|
|
965
1064
|
} catch (e) {
|
|
1065
|
+
if (await __redirectToSsoIfRequired(e)) {
|
|
1066
|
+
return;
|
|
1067
|
+
}
|
|
966
1068
|
setLoginState({
|
|
967
1069
|
error: errorHandler(e, 'Failed to authenticate')
|
|
968
1070
|
});
|
|
@@ -1000,7 +1102,7 @@ export default ((store, api, sharedActions) => {
|
|
|
1000
1102
|
const {
|
|
1001
1103
|
callback
|
|
1002
1104
|
} = payload,
|
|
1003
|
-
body = _objectWithoutPropertiesLoose(payload,
|
|
1105
|
+
body = _objectWithoutPropertiesLoose(payload, _excluded8);
|
|
1004
1106
|
try {
|
|
1005
1107
|
var _options$allowCredent;
|
|
1006
1108
|
actions.setPasskeysState({
|
|
@@ -1040,7 +1142,7 @@ export default ((store, api, sharedActions) => {
|
|
|
1040
1142
|
const {
|
|
1041
1143
|
callback
|
|
1042
1144
|
} = payload,
|
|
1043
|
-
body = _objectWithoutPropertiesLoose(payload,
|
|
1145
|
+
body = _objectWithoutPropertiesLoose(payload, _excluded9);
|
|
1044
1146
|
try {
|
|
1045
1147
|
var _publicKey$response$u;
|
|
1046
1148
|
actions.setPasskeysState({
|
|
@@ -1060,7 +1162,7 @@ export default ((store, api, sharedActions) => {
|
|
|
1060
1162
|
{
|
|
1061
1163
|
user
|
|
1062
1164
|
} = _await$api$auth$webAu,
|
|
1063
|
-
rest = _objectWithoutPropertiesLoose(_await$api$auth$webAu,
|
|
1165
|
+
rest = _objectWithoutPropertiesLoose(_await$api$auth$webAu, _excluded10);
|
|
1064
1166
|
if (isMfaRequired(user, store.root.appName)) {
|
|
1065
1167
|
const {
|
|
1066
1168
|
routes,
|
|
@@ -1099,6 +1201,9 @@ export default ((store, api, sharedActions) => {
|
|
|
1099
1201
|
}
|
|
1100
1202
|
// callback?.(true);
|
|
1101
1203
|
} catch (e) {
|
|
1204
|
+
if (await __redirectToSsoIfRequired(e)) {
|
|
1205
|
+
return;
|
|
1206
|
+
}
|
|
1102
1207
|
setLoginState({
|
|
1103
1208
|
error: errorHandler(e)
|
|
1104
1209
|
});
|
|
@@ -1144,7 +1249,7 @@ export default ((store, api, sharedActions) => {
|
|
|
1144
1249
|
const {
|
|
1145
1250
|
callback
|
|
1146
1251
|
} = payload,
|
|
1147
|
-
body = _objectWithoutPropertiesLoose(payload,
|
|
1252
|
+
body = _objectWithoutPropertiesLoose(payload, _excluded11);
|
|
1148
1253
|
try {
|
|
1149
1254
|
setLoginState({
|
|
1150
1255
|
loading: true
|
|
@@ -1209,7 +1314,7 @@ export default ((store, api, sharedActions) => {
|
|
|
1209
1314
|
const {
|
|
1210
1315
|
callback
|
|
1211
1316
|
} = _payload,
|
|
1212
|
-
payload = _objectWithoutPropertiesLoose(_payload,
|
|
1317
|
+
payload = _objectWithoutPropertiesLoose(_payload, _excluded12);
|
|
1213
1318
|
setLoginState({
|
|
1214
1319
|
loading: true
|
|
1215
1320
|
});
|
|
@@ -1244,7 +1349,7 @@ export default ((store, api, sharedActions) => {
|
|
|
1244
1349
|
const {
|
|
1245
1350
|
callback
|
|
1246
1351
|
} = _payload,
|
|
1247
|
-
payload = _objectWithoutPropertiesLoose(_payload,
|
|
1352
|
+
payload = _objectWithoutPropertiesLoose(_payload, _excluded13);
|
|
1248
1353
|
setLoginState({
|
|
1249
1354
|
loading: true
|
|
1250
1355
|
});
|
|
@@ -1270,7 +1375,7 @@ export default ((store, api, sharedActions) => {
|
|
|
1270
1375
|
const {
|
|
1271
1376
|
callback
|
|
1272
1377
|
} = _payload,
|
|
1273
|
-
payload = _objectWithoutPropertiesLoose(_payload,
|
|
1378
|
+
payload = _objectWithoutPropertiesLoose(_payload, _excluded14);
|
|
1274
1379
|
setLoginState({
|
|
1275
1380
|
loading: true
|
|
1276
1381
|
});
|
|
@@ -1293,7 +1398,7 @@ export default ((store, api, sharedActions) => {
|
|
|
1293
1398
|
const {
|
|
1294
1399
|
callback
|
|
1295
1400
|
} = _payload,
|
|
1296
|
-
payload = _objectWithoutPropertiesLoose(_payload,
|
|
1401
|
+
payload = _objectWithoutPropertiesLoose(_payload, _excluded15);
|
|
1297
1402
|
setLoginState({
|
|
1298
1403
|
loading: true
|
|
1299
1404
|
});
|
|
@@ -1320,7 +1425,7 @@ export default ((store, api, sharedActions) => {
|
|
|
1320
1425
|
const {
|
|
1321
1426
|
callback
|
|
1322
1427
|
} = _payload,
|
|
1323
|
-
payload = _objectWithoutPropertiesLoose(_payload,
|
|
1428
|
+
payload = _objectWithoutPropertiesLoose(_payload, _excluded16);
|
|
1324
1429
|
setLoginState({
|
|
1325
1430
|
loading: true
|
|
1326
1431
|
});
|
|
@@ -1388,7 +1493,10 @@ export default ((store, api, sharedActions) => {
|
|
|
1388
1493
|
};
|
|
1389
1494
|
|
|
1390
1495
|
/** @private */
|
|
1391
|
-
const __refreshTokenHostedSocialLogins = async (
|
|
1496
|
+
const __refreshTokenHostedSocialLogins = async ({
|
|
1497
|
+
tenantId,
|
|
1498
|
+
isSsoEnforcementRetry = false
|
|
1499
|
+
} = {}) => {
|
|
1392
1500
|
const {
|
|
1393
1501
|
user: currentUser
|
|
1394
1502
|
} = store.auth;
|
|
@@ -1402,7 +1510,7 @@ export default ((store, api, sharedActions) => {
|
|
|
1402
1510
|
return;
|
|
1403
1511
|
}
|
|
1404
1512
|
try {
|
|
1405
|
-
const tabTenantId = getTabTenantFromSessionStorage(store.root.appName);
|
|
1513
|
+
const tabTenantId = tenantId != null ? tenantId : getTabTenantFromSessionStorage(store.root.appName);
|
|
1406
1514
|
const body = _extends({
|
|
1407
1515
|
grant_type: 'refresh_token',
|
|
1408
1516
|
refresh_token: currentUser == null ? void 0 : currentUser.refreshToken
|
|
@@ -1417,6 +1525,13 @@ export default ((store, api, sharedActions) => {
|
|
|
1417
1525
|
isAuthenticated: true
|
|
1418
1526
|
});
|
|
1419
1527
|
} catch (e) {
|
|
1528
|
+
const retry = tenantId => __refreshTokenHostedSocialLogins({
|
|
1529
|
+
tenantId,
|
|
1530
|
+
isSsoEnforcementRetry: true
|
|
1531
|
+
});
|
|
1532
|
+
if (await __handleSsoEnforcementRefreshError(e, isSsoEnforcementRetry, retry)) {
|
|
1533
|
+
return;
|
|
1534
|
+
}
|
|
1420
1535
|
contextHolder.setAccessToken(null);
|
|
1421
1536
|
contextHolder.setUser(null);
|
|
1422
1537
|
actions.setAuthState({
|
|
@@ -1487,6 +1602,9 @@ export default ((store, api, sharedActions) => {
|
|
|
1487
1602
|
}
|
|
1488
1603
|
}
|
|
1489
1604
|
} catch (e) {
|
|
1605
|
+
if (await __redirectToSsoIfRequired(e)) {
|
|
1606
|
+
return;
|
|
1607
|
+
}
|
|
1490
1608
|
contextHolder.setAccessToken(null);
|
|
1491
1609
|
contextHolder.setUser(null);
|
|
1492
1610
|
actions.setAuthState({
|
|
@@ -1533,6 +1651,8 @@ export default ((store, api, sharedActions) => {
|
|
|
1533
1651
|
resetBreachedPassword,
|
|
1534
1652
|
refreshTokenForSocialLogins,
|
|
1535
1653
|
// protected
|
|
1536
|
-
__refreshToken
|
|
1654
|
+
__refreshToken,
|
|
1655
|
+
__redirectToSsoForTenant,
|
|
1656
|
+
__redirectToSsoIfRequired
|
|
1537
1657
|
}, hostedLoginAuthorizeActions(store, api, sharedActions), afterAuthNavigationActions(store, api, sharedActions), handleVerifyMFAResponseActions(store, api, sharedActions), mfaRequiredStateActions(store, api, sharedActions), mfaWithAuthenticatorActions(store, api, sharedActions), mfaWithEmailCodeActions(store, api, sharedActions), mfaWithSMSActions(store, api, sharedActions), mfaWithWebAuthnActions(store, api, sharedActions));
|
|
1538
1658
|
});
|
|
@@ -145,6 +145,9 @@ export default ((store, api, sharedActions) => {
|
|
|
145
145
|
}
|
|
146
146
|
return await __postLoginMfaAuthenticator(isAuthenticated, user, callback);
|
|
147
147
|
} catch (e) {
|
|
148
|
+
if (await actions.__redirectToSsoIfRequired(e)) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
148
151
|
setLoadingAction({
|
|
149
152
|
loading: false,
|
|
150
153
|
error: errorHandler(e)
|
|
@@ -157,6 +157,9 @@ export default ((store, api, sharedActions) => {
|
|
|
157
157
|
loading: false
|
|
158
158
|
});
|
|
159
159
|
} catch (e) {
|
|
160
|
+
if (await actions.__redirectToSsoIfRequired(e)) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
160
163
|
setSocialLoginsState({
|
|
161
164
|
loading: false,
|
|
162
165
|
error: errorHandler(e, 'Failed to authenticate'),
|
|
@@ -60,7 +60,7 @@ export default ((store, api, sharedActions) => {
|
|
|
60
60
|
callback
|
|
61
61
|
} = payload,
|
|
62
62
|
body = _objectWithoutPropertiesLoose(payload, _excluded3);
|
|
63
|
-
await __activateLinkTryCatch(TeamStateKeys.RESEND_INVITATION_LINK,
|
|
63
|
+
await __activateLinkTryCatch(TeamStateKeys.RESEND_INVITATION_LINK, body.email, callback, async () => {
|
|
64
64
|
await api.auth.resendInvitationEmail(body);
|
|
65
65
|
callback == null ? void 0 : callback(true);
|
|
66
66
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { initialState } from './state';
|
|
2
2
|
import { deepResetState } from '../../helpers';
|
|
3
|
-
import { getCurrentUserTenantsFunction } from '@frontegg/rest-api';
|
|
3
|
+
import { ContextHolder, getCurrentUserTenantsFunction, setTabTenantInSessionStorage } from '@frontegg/rest-api';
|
|
4
4
|
export default ((store, api, sharedActions) => {
|
|
5
5
|
const actions = sharedActions;
|
|
6
6
|
const setTenantsState = state => {
|
|
@@ -51,6 +51,13 @@ export default ((store, api, sharedActions) => {
|
|
|
51
51
|
}) : actions.setAuthState({
|
|
52
52
|
isLoading: false
|
|
53
53
|
});
|
|
54
|
+
if (await actions.__redirectToSsoIfRequired(e)) {
|
|
55
|
+
// the tab comes back from SSO in the target tenant, not the one the failed switch restored
|
|
56
|
+
if (ContextHolder.for(store.root.appName).isSessionPerTenantEnabled()) {
|
|
57
|
+
setTabTenantInSessionStorage(tenantId);
|
|
58
|
+
}
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
54
61
|
callback == null ? void 0 : callback(false, e);
|
|
55
62
|
}
|
|
56
63
|
};
|
package/helpers/handlers.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import { FronteggApiError } from '@frontegg/rest-api';
|
|
1
|
+
import { FronteggApiError, SsoEnforcementErrorContext } from '@frontegg/rest-api';
|
|
2
2
|
export declare const isFronteggApiError: (error: unknown | Error | FronteggApiError) => error is FronteggApiError;
|
|
3
|
+
export declare const isSsoEnforcementError: (error: unknown) => error is FronteggApiError & {
|
|
4
|
+
errorContext: SsoEnforcementErrorContext;
|
|
5
|
+
};
|
|
3
6
|
export declare const isError: (error: any) => error is Error;
|
|
4
7
|
export declare const errorHandler: <T>(error: unknown, fallback?: T) => FronteggApiError | T;
|
package/helpers/handlers.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import { FronteggApiError, GENERIC_ERROR_MESSAGE, GENERIC_ERROR_CODE } from '@frontegg/rest-api';
|
|
1
|
+
import { FronteggApiError, GENERIC_ERROR_MESSAGE, GENERIC_ERROR_CODE, SSO_REQUIRED_FOR_TENANT_ERROR_CODE } from '@frontegg/rest-api';
|
|
2
2
|
export const isFronteggApiError = error => Boolean(error == null ? void 0 : error.statusCode);
|
|
3
|
+
|
|
4
|
+
// ER-01079 (disabled user / expired tenant) is not this: it still logs out
|
|
5
|
+
export const isSsoEnforcementError = error => isFronteggApiError(error) && error.errorCode === SSO_REQUIRED_FOR_TENANT_ERROR_CODE;
|
|
3
6
|
export const isError = error => {
|
|
4
7
|
if (error instanceof Error) {
|
|
5
8
|
return true;
|
package/index.js
CHANGED
|
@@ -33,7 +33,9 @@ declare const _default: (store: FronteggState, api: RestApi, sharedActions: Shar
|
|
|
33
33
|
firstTime?: boolean;
|
|
34
34
|
loginDirectAction?: import("../..").LoginDirectAction;
|
|
35
35
|
}) => Promise<void>;
|
|
36
|
-
__requestHostedLoginAuthorize: (additionalParams?: Record<string, string
|
|
36
|
+
__requestHostedLoginAuthorize: (additionalParams?: Record<string, string>, { forceTenantId }?: {
|
|
37
|
+
forceTenantId?: boolean;
|
|
38
|
+
}) => Promise<void>;
|
|
37
39
|
__requestHostedLoginSilentAuthorize: () => Promise<void>;
|
|
38
40
|
handleHostedLoginCallback: (payload: import("../..").HostedLoginCallback) => Promise<void>;
|
|
39
41
|
setLoginState: (state: Partial<import("../..").LoginState>) => void;
|
|
@@ -71,5 +73,10 @@ declare const _default: (store: FronteggState, api: RestApi, sharedActions: Shar
|
|
|
71
73
|
resetBreachedPassword: (payload: import("dist/@frontegg/rest-api").IForgotPassword) => Promise<void>;
|
|
72
74
|
refreshTokenForSocialLogins: () => Promise<void>;
|
|
73
75
|
__refreshToken: () => Promise<void>;
|
|
76
|
+
__redirectToSsoForTenant: ({ tenantId, address }: {
|
|
77
|
+
tenantId: string;
|
|
78
|
+
address: string;
|
|
79
|
+
}) => Promise<void>;
|
|
80
|
+
__redirectToSsoIfRequired: (e: unknown) => Promise<boolean>;
|
|
74
81
|
};
|
|
75
82
|
export default _default;
|
|
@@ -8,6 +8,7 @@ exports.default = void 0;
|
|
|
8
8
|
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
9
9
|
var _helpers = require("../../../helpers");
|
|
10
10
|
var _constants = require("../../../constants");
|
|
11
|
+
var _restApi = require("@frontegg/rest-api");
|
|
11
12
|
var _helpers2 = require("../helpers");
|
|
12
13
|
var _helpers3 = require("../../helpers");
|
|
13
14
|
var _consts = require("../../StepUpState/consts");
|
|
@@ -28,7 +29,17 @@ var _default = (store, api, sharedActions) => {
|
|
|
28
29
|
return await authApi.silentOAuthRefreshTokenV3(tokens);
|
|
29
30
|
});
|
|
30
31
|
} else {
|
|
31
|
-
|
|
32
|
+
try {
|
|
33
|
+
response = await api.auth.silentOAuthRefreshTokenV2();
|
|
34
|
+
} catch (error) {
|
|
35
|
+
var _store$auth$user, _error$errorContext;
|
|
36
|
+
const tenantId = (_store$auth$user = store.auth.user) == null ? void 0 : _store$auth$user.tenantId;
|
|
37
|
+
if (!(0, _restApi.isEnforceSsoOnTenantAccessEnabled)(store.root.appName) || !(0, _helpers.isSsoEnforcementError)(error) || ((_error$errorContext = error.errorContext) == null ? void 0 : _error$errorContext.ssoRequired) !== false || !tenantId) {
|
|
38
|
+
throw error;
|
|
39
|
+
}
|
|
40
|
+
// one retry for the tenant of the current token (a cold reload has no user yet: no retry)
|
|
41
|
+
response = await api.auth.silentOAuthRefreshTokenV2(tenantId);
|
|
42
|
+
}
|
|
32
43
|
}
|
|
33
44
|
if ((_response = response) != null && _response.user) {
|
|
34
45
|
await actions.afterAuthenticationStateUpdate(response, {
|
|
@@ -39,7 +50,14 @@ var _default = (store, api, sharedActions) => {
|
|
|
39
50
|
throw new Error(`couldn't refresh user token with oauth service`);
|
|
40
51
|
}
|
|
41
52
|
};
|
|
42
|
-
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @param options.forceTenantId the tenantId in additionalParams wins over the resolved and the page's tenant
|
|
56
|
+
* (sending the user to that tenant's SSO); other callers keep their custom login tenant
|
|
57
|
+
*/
|
|
58
|
+
const requestHostedLoginAuthorize = async (additionalParams, {
|
|
59
|
+
forceTenantId = false
|
|
60
|
+
} = {}) => {
|
|
43
61
|
var _store$auth$customLog;
|
|
44
62
|
const {
|
|
45
63
|
routes,
|
|
@@ -86,7 +104,7 @@ var _default = (store, api, sharedActions) => {
|
|
|
86
104
|
code_challenge_method: 'S256',
|
|
87
105
|
nonce
|
|
88
106
|
}, additionalParams);
|
|
89
|
-
if (context.tenantResolver) {
|
|
107
|
+
if (context.tenantResolver && !forceTenantId) {
|
|
90
108
|
var _context$tenantResolv;
|
|
91
109
|
const resolvedTenantResult = await ((_context$tenantResolv = context.tenantResolver) == null ? void 0 : _context$tenantResolv.call(context));
|
|
92
110
|
if (resolvedTenantResult != null && resolvedTenantResult.tenant) {
|
|
@@ -94,7 +112,7 @@ var _default = (store, api, sharedActions) => {
|
|
|
94
112
|
}
|
|
95
113
|
}
|
|
96
114
|
const tenantId = (0, _helpers2.getSearchParam)(_helpers2.TENANT_ID_PARAM_KEY);
|
|
97
|
-
if (tenantId) {
|
|
115
|
+
if (tenantId && !forceTenantId) {
|
|
98
116
|
params['tenantId'] = tenantId;
|
|
99
117
|
}
|
|
100
118
|
if (_toolkit.FronteggNativeModule.isAvailable('closeWindow')) {
|
|
@@ -5,8 +5,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
7
|
exports.default = void 0;
|
|
8
|
-
var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
|
|
9
8
|
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
9
|
+
var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
|
|
10
10
|
var _afterAuthNavigation = _interopRequireDefault(require("./afterAuthNavigation.actions"));
|
|
11
11
|
var _handleVerifyMFAResponse = _interopRequireDefault(require("./handleVerifyMFAResponse.actions"));
|
|
12
12
|
var _mfaRequiredState = _interopRequireDefault(require("./mfaRequiredState.actions"));
|
|
@@ -29,29 +29,105 @@ var _helpers3 = require("../../helpers");
|
|
|
29
29
|
var _interfaces3 = require("../../MfaState/interfaces");
|
|
30
30
|
var _interfaces4 = require("../../SSOState/interfaces");
|
|
31
31
|
var _constants = require("../../../constants");
|
|
32
|
-
const _excluded = ["
|
|
33
|
-
_excluded2 = ["callback"],
|
|
32
|
+
const _excluded = ["authenticatedUrl"],
|
|
33
|
+
_excluded2 = ["callback", "error"],
|
|
34
34
|
_excluded3 = ["callback"],
|
|
35
35
|
_excluded4 = ["callback"],
|
|
36
36
|
_excluded5 = ["callback"],
|
|
37
|
-
_excluded6 = ["callback"
|
|
38
|
-
_excluded7 = ["callback"],
|
|
37
|
+
_excluded6 = ["callback"],
|
|
38
|
+
_excluded7 = ["callback", "events"],
|
|
39
39
|
_excluded8 = ["callback"],
|
|
40
|
-
_excluded9 = ["
|
|
41
|
-
_excluded10 = ["
|
|
40
|
+
_excluded9 = ["callback"],
|
|
41
|
+
_excluded10 = ["user"],
|
|
42
42
|
_excluded11 = ["callback"],
|
|
43
43
|
_excluded12 = ["callback"],
|
|
44
44
|
_excluded13 = ["callback"],
|
|
45
45
|
_excluded14 = ["callback"],
|
|
46
|
-
_excluded15 = ["callback"]
|
|
46
|
+
_excluded15 = ["callback"],
|
|
47
|
+
_excluded16 = ["callback"];
|
|
47
48
|
const SSO_REDIRECT_DELAY_MS = 2000;
|
|
48
49
|
const isUsableRedirect = onRedirectTo => typeof onRedirectTo === 'function' && onRedirectTo !== _consts2.defaultOnRedirectTo;
|
|
49
50
|
var _default = (store, api, sharedActions) => {
|
|
50
51
|
const actions = sharedActions;
|
|
51
52
|
const contextHolder = _restApi.ContextHolder.for(store.root.appName);
|
|
52
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Sends the user to log in through the tenant's SSO and back to the current page afterwards.
|
|
56
|
+
* @protected
|
|
57
|
+
*/
|
|
58
|
+
const __redirectToSsoForTenant = async ({
|
|
59
|
+
tenantId,
|
|
60
|
+
address
|
|
61
|
+
}) => {
|
|
62
|
+
// on an auth page (login, tenant chooser, social / magic link / SSO callback) keep the destination the login
|
|
63
|
+
// already saved: the page itself is not one to come back to
|
|
64
|
+
const _defaultFronteggRoute = (0, _extends2.default)({}, _consts2.defaultFronteggRoutes, store.auth.routes),
|
|
65
|
+
authRoutes = (0, _objectWithoutPropertiesLoose2.default)(_defaultFronteggRoute, _excluded);
|
|
66
|
+
const isOnAuthPage = Object.values(authRoutes).some(route => typeof route === 'string' && !!route && window.location.pathname.endsWith(route));
|
|
67
|
+
if (!isOnAuthPage) {
|
|
68
|
+
(0, _helpers3.setAfterAuthRedirectUrlForStepUp)();
|
|
69
|
+
}
|
|
70
|
+
if (store.auth.hostedLoginBox) {
|
|
71
|
+
var _window$localStorage;
|
|
72
|
+
// as loginWithRedirect does, but the SSO tenant wins over the custom login tenant
|
|
73
|
+
(_window$localStorage = window.localStorage) == null ? void 0 : _window$localStorage.removeItem(_consts.SHOULD_STEP_UP_KEY);
|
|
74
|
+
await actions.__requestHostedLoginAuthorize({
|
|
75
|
+
prompt: 'login',
|
|
76
|
+
tenantId
|
|
77
|
+
}, {
|
|
78
|
+
forceTenantId: true
|
|
79
|
+
});
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
store.auth.onRedirectTo(address, {
|
|
83
|
+
refresh: true
|
|
84
|
+
});
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Sends the user to the tenant's SSO when a login or tenant switch is refused because that tenant requires it
|
|
89
|
+
* (e.g. an invitation into a tenant whose SSO covers the user's email). The SSO login lands in that tenant.
|
|
90
|
+
* @returns true when redirected, so the caller doesn't show the error
|
|
91
|
+
* @protected
|
|
92
|
+
*/
|
|
93
|
+
const __redirectToSsoIfRequired = async e => {
|
|
94
|
+
if (!(0, _restApi.isEnforceSsoOnTenantAccessEnabled)(store.root.appName) || !(0, _helpers.isSsoEnforcementError)(e) || !e.errorContext.ssoRequired) {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
await __redirectToSsoForTenant(e.errorContext);
|
|
98
|
+
return true;
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* Handles a hosted (OAuth) token refresh refused because the tenant requires SSO.
|
|
102
|
+
* ssoRequired: true sends the user to SSO, like login. ssoRequired: false renews once more for the tenant of the
|
|
103
|
+
* current token, which keeps the session: OAuth doesn't use up the refresh token on this refusal.
|
|
104
|
+
* @returns true when handled, false when the caller should log out
|
|
105
|
+
* @private
|
|
106
|
+
*/
|
|
107
|
+
const __handleSsoEnforcementRefreshError = async (e, isSsoEnforcementRetry, refreshForTenant) => {
|
|
108
|
+
var _store$auth$user;
|
|
109
|
+
if (!(0, _restApi.isEnforceSsoOnTenantAccessEnabled)(store.root.appName) || !(0, _helpers.isSsoEnforcementError)(e)) {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
if (await __redirectToSsoIfRequired(e)) {
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
const currentTenantId = (_store$auth$user = store.auth.user) == null ? void 0 : _store$auth$user.tenantId;
|
|
116
|
+
if (isSsoEnforcementRetry || !currentTenantId) {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
if (contextHolder.isSessionPerTenantEnabled()) {
|
|
120
|
+
(0, _restApi.setTabTenantInSessionStorage)(currentTenantId);
|
|
121
|
+
}
|
|
122
|
+
await refreshForTenant(currentTenantId);
|
|
123
|
+
return true;
|
|
124
|
+
};
|
|
125
|
+
|
|
53
126
|
/** @private */
|
|
54
|
-
const __refreshTokenHosted = async (
|
|
127
|
+
const __refreshTokenHosted = async ({
|
|
128
|
+
tenantId,
|
|
129
|
+
isSsoEnforcementRetry = false
|
|
130
|
+
} = {}) => {
|
|
55
131
|
const user = store.auth.user;
|
|
56
132
|
if (!(user != null && user.refreshToken)) {
|
|
57
133
|
contextHolder.setAccessToken(null);
|
|
@@ -63,7 +139,7 @@ var _default = (store, api, sharedActions) => {
|
|
|
63
139
|
return;
|
|
64
140
|
}
|
|
65
141
|
try {
|
|
66
|
-
const tabTenantId = (0, _restApi.getTabTenantFromSessionStorage)(store.root.appName);
|
|
142
|
+
const tabTenantId = tenantId != null ? tenantId : (0, _restApi.getTabTenantFromSessionStorage)(store.root.appName);
|
|
67
143
|
const body = (0, _extends2.default)({
|
|
68
144
|
grant_type: 'refresh_token',
|
|
69
145
|
refresh_token: user == null ? void 0 : user.refreshToken
|
|
@@ -78,6 +154,13 @@ var _default = (store, api, sharedActions) => {
|
|
|
78
154
|
isAuthenticated: true
|
|
79
155
|
});
|
|
80
156
|
} catch (e) {
|
|
157
|
+
const retry = tenantId => __refreshTokenHosted({
|
|
158
|
+
tenantId,
|
|
159
|
+
isSsoEnforcementRetry: true
|
|
160
|
+
});
|
|
161
|
+
if (await __handleSsoEnforcementRefreshError(e, isSsoEnforcementRetry, retry)) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
81
164
|
contextHolder.setAccessToken(null);
|
|
82
165
|
contextHolder.setUser(null);
|
|
83
166
|
actions.setAuthState({
|
|
@@ -139,6 +222,10 @@ var _default = (store, api, sharedActions) => {
|
|
|
139
222
|
});
|
|
140
223
|
}
|
|
141
224
|
} catch (e) {
|
|
225
|
+
// a refused identity refresh has already used up the refresh token: no retry, only the SSO redirect
|
|
226
|
+
if (await __redirectToSsoIfRequired(e)) {
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
142
229
|
contextHolder.setAccessToken(null);
|
|
143
230
|
contextHolder.setUser(null);
|
|
144
231
|
actions.setAuthState({
|
|
@@ -149,7 +236,9 @@ var _default = (store, api, sharedActions) => {
|
|
|
149
236
|
};
|
|
150
237
|
|
|
151
238
|
/** @private */
|
|
152
|
-
const __refreshTokenWithNativeTokens = async (
|
|
239
|
+
const __refreshTokenWithNativeTokens = async ({
|
|
240
|
+
isSsoEnforcementRetry = false
|
|
241
|
+
} = {}) => {
|
|
153
242
|
try {
|
|
154
243
|
const authApi = api.auth;
|
|
155
244
|
const response = await (0, _helpers.refreshTokenWithRetry)(async () => {
|
|
@@ -163,6 +252,13 @@ var _default = (store, api, sharedActions) => {
|
|
|
163
252
|
isAuthenticated: true
|
|
164
253
|
});
|
|
165
254
|
} catch (e) {
|
|
255
|
+
// native tokens can't name a tenant: the retry relies on the tab tenant only
|
|
256
|
+
const retry = () => __refreshTokenWithNativeTokens({
|
|
257
|
+
isSsoEnforcementRetry: true
|
|
258
|
+
});
|
|
259
|
+
if (await __handleSsoEnforcementRefreshError(e, isSsoEnforcementRetry, retry)) {
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
166
262
|
contextHolder.setAccessToken(null);
|
|
167
263
|
contextHolder.setUser(null);
|
|
168
264
|
actions.setAuthState({
|
|
@@ -196,9 +292,9 @@ var _default = (store, api, sharedActions) => {
|
|
|
196
292
|
* @private
|
|
197
293
|
*/
|
|
198
294
|
const __handleUnnecessaryEntitlementsUpdate = async updatedUser => {
|
|
199
|
-
var _store$auth$
|
|
295
|
+
var _store$auth$user2;
|
|
200
296
|
// @ts-ignore TODO: fix entitlements state type
|
|
201
|
-
const oldEntitlements = (_store$auth$
|
|
297
|
+
const oldEntitlements = (_store$auth$user2 = store.auth.user) == null ? void 0 : _store$auth$user2.entitlements;
|
|
202
298
|
if ((0, _toolkit.isEntitlementsDeeplyEqual)(oldEntitlements, updatedUser == null ? void 0 : updatedUser.entitlements)) {
|
|
203
299
|
// set the previous entitlements object
|
|
204
300
|
return (0, _extends2.default)({}, updatedUser, {
|
|
@@ -366,7 +462,7 @@ var _default = (store, api, sharedActions) => {
|
|
|
366
462
|
callback,
|
|
367
463
|
error
|
|
368
464
|
} = _ref3,
|
|
369
|
-
body = (0, _objectWithoutPropertiesLoose2.default)(_ref3,
|
|
465
|
+
body = (0, _objectWithoutPropertiesLoose2.default)(_ref3, _excluded2);
|
|
370
466
|
const publicPolicy = store.auth.securityPolicyState.publicPolicy.policy;
|
|
371
467
|
if (!(publicPolicy != null && publicPolicy.authStrategy)) {
|
|
372
468
|
actions.setLoginState({
|
|
@@ -675,6 +771,9 @@ var _default = (store, api, sharedActions) => {
|
|
|
675
771
|
} catch (e) {
|
|
676
772
|
contextHolder.setAccessToken(null);
|
|
677
773
|
contextHolder.setUser(null);
|
|
774
|
+
if (await __redirectToSsoIfRequired(e)) {
|
|
775
|
+
return;
|
|
776
|
+
}
|
|
678
777
|
callback == null ? void 0 : callback(false, e);
|
|
679
778
|
setLoginState({
|
|
680
779
|
email,
|
|
@@ -759,7 +858,7 @@ var _default = (store, api, sharedActions) => {
|
|
|
759
858
|
const {
|
|
760
859
|
callback
|
|
761
860
|
} = _payload,
|
|
762
|
-
payload = (0, _objectWithoutPropertiesLoose2.default)(_payload,
|
|
861
|
+
payload = (0, _objectWithoutPropertiesLoose2.default)(_payload, _excluded3);
|
|
763
862
|
try {
|
|
764
863
|
setLoginState({
|
|
765
864
|
loading: true
|
|
@@ -789,7 +888,7 @@ var _default = (store, api, sharedActions) => {
|
|
|
789
888
|
const {
|
|
790
889
|
callback
|
|
791
890
|
} = _payload,
|
|
792
|
-
payload = (0, _objectWithoutPropertiesLoose2.default)(_payload,
|
|
891
|
+
payload = (0, _objectWithoutPropertiesLoose2.default)(_payload, _excluded4);
|
|
793
892
|
try {
|
|
794
893
|
setLoginState({
|
|
795
894
|
loading: true
|
|
@@ -814,7 +913,7 @@ var _default = (store, api, sharedActions) => {
|
|
|
814
913
|
const {
|
|
815
914
|
callback
|
|
816
915
|
} = _payload,
|
|
817
|
-
payload = (0, _objectWithoutPropertiesLoose2.default)(_payload,
|
|
916
|
+
payload = (0, _objectWithoutPropertiesLoose2.default)(_payload, _excluded5);
|
|
818
917
|
try {
|
|
819
918
|
setLoginState({
|
|
820
919
|
loading: true
|
|
@@ -835,7 +934,7 @@ var _default = (store, api, sharedActions) => {
|
|
|
835
934
|
const {
|
|
836
935
|
callback
|
|
837
936
|
} = _payload,
|
|
838
|
-
payload = (0, _objectWithoutPropertiesLoose2.default)(_payload,
|
|
937
|
+
payload = (0, _objectWithoutPropertiesLoose2.default)(_payload, _excluded6);
|
|
839
938
|
try {
|
|
840
939
|
var _username;
|
|
841
940
|
setLoginState({
|
|
@@ -879,7 +978,7 @@ var _default = (store, api, sharedActions) => {
|
|
|
879
978
|
callback,
|
|
880
979
|
events
|
|
881
980
|
} = _payload,
|
|
882
|
-
payload = (0, _objectWithoutPropertiesLoose2.default)(_payload,
|
|
981
|
+
payload = (0, _objectWithoutPropertiesLoose2.default)(_payload, _excluded7);
|
|
883
982
|
try {
|
|
884
983
|
setLoginState({
|
|
885
984
|
loading: true
|
|
@@ -970,6 +1069,9 @@ var _default = (store, api, sharedActions) => {
|
|
|
970
1069
|
callback == null ? void 0 : callback(true);
|
|
971
1070
|
}
|
|
972
1071
|
} catch (e) {
|
|
1072
|
+
if (await __redirectToSsoIfRequired(e)) {
|
|
1073
|
+
return;
|
|
1074
|
+
}
|
|
973
1075
|
setLoginState({
|
|
974
1076
|
error: (0, _helpers.errorHandler)(e, 'Failed to authenticate')
|
|
975
1077
|
});
|
|
@@ -1007,7 +1109,7 @@ var _default = (store, api, sharedActions) => {
|
|
|
1007
1109
|
const {
|
|
1008
1110
|
callback
|
|
1009
1111
|
} = payload,
|
|
1010
|
-
body = (0, _objectWithoutPropertiesLoose2.default)(payload,
|
|
1112
|
+
body = (0, _objectWithoutPropertiesLoose2.default)(payload, _excluded8);
|
|
1011
1113
|
try {
|
|
1012
1114
|
var _options$allowCredent;
|
|
1013
1115
|
actions.setPasskeysState({
|
|
@@ -1047,7 +1149,7 @@ var _default = (store, api, sharedActions) => {
|
|
|
1047
1149
|
const {
|
|
1048
1150
|
callback
|
|
1049
1151
|
} = payload,
|
|
1050
|
-
body = (0, _objectWithoutPropertiesLoose2.default)(payload,
|
|
1152
|
+
body = (0, _objectWithoutPropertiesLoose2.default)(payload, _excluded9);
|
|
1051
1153
|
try {
|
|
1052
1154
|
var _publicKey$response$u;
|
|
1053
1155
|
actions.setPasskeysState({
|
|
@@ -1067,7 +1169,7 @@ var _default = (store, api, sharedActions) => {
|
|
|
1067
1169
|
{
|
|
1068
1170
|
user
|
|
1069
1171
|
} = _await$api$auth$webAu,
|
|
1070
|
-
rest = (0, _objectWithoutPropertiesLoose2.default)(_await$api$auth$webAu,
|
|
1172
|
+
rest = (0, _objectWithoutPropertiesLoose2.default)(_await$api$auth$webAu, _excluded10);
|
|
1071
1173
|
if ((0, _helpers3.isMfaRequired)(user, store.root.appName)) {
|
|
1072
1174
|
const {
|
|
1073
1175
|
routes,
|
|
@@ -1106,6 +1208,9 @@ var _default = (store, api, sharedActions) => {
|
|
|
1106
1208
|
}
|
|
1107
1209
|
// callback?.(true);
|
|
1108
1210
|
} catch (e) {
|
|
1211
|
+
if (await __redirectToSsoIfRequired(e)) {
|
|
1212
|
+
return;
|
|
1213
|
+
}
|
|
1109
1214
|
setLoginState({
|
|
1110
1215
|
error: (0, _helpers.errorHandler)(e)
|
|
1111
1216
|
});
|
|
@@ -1151,7 +1256,7 @@ var _default = (store, api, sharedActions) => {
|
|
|
1151
1256
|
const {
|
|
1152
1257
|
callback
|
|
1153
1258
|
} = payload,
|
|
1154
|
-
body = (0, _objectWithoutPropertiesLoose2.default)(payload,
|
|
1259
|
+
body = (0, _objectWithoutPropertiesLoose2.default)(payload, _excluded11);
|
|
1155
1260
|
try {
|
|
1156
1261
|
setLoginState({
|
|
1157
1262
|
loading: true
|
|
@@ -1216,7 +1321,7 @@ var _default = (store, api, sharedActions) => {
|
|
|
1216
1321
|
const {
|
|
1217
1322
|
callback
|
|
1218
1323
|
} = _payload,
|
|
1219
|
-
payload = (0, _objectWithoutPropertiesLoose2.default)(_payload,
|
|
1324
|
+
payload = (0, _objectWithoutPropertiesLoose2.default)(_payload, _excluded12);
|
|
1220
1325
|
setLoginState({
|
|
1221
1326
|
loading: true
|
|
1222
1327
|
});
|
|
@@ -1251,7 +1356,7 @@ var _default = (store, api, sharedActions) => {
|
|
|
1251
1356
|
const {
|
|
1252
1357
|
callback
|
|
1253
1358
|
} = _payload,
|
|
1254
|
-
payload = (0, _objectWithoutPropertiesLoose2.default)(_payload,
|
|
1359
|
+
payload = (0, _objectWithoutPropertiesLoose2.default)(_payload, _excluded13);
|
|
1255
1360
|
setLoginState({
|
|
1256
1361
|
loading: true
|
|
1257
1362
|
});
|
|
@@ -1277,7 +1382,7 @@ var _default = (store, api, sharedActions) => {
|
|
|
1277
1382
|
const {
|
|
1278
1383
|
callback
|
|
1279
1384
|
} = _payload,
|
|
1280
|
-
payload = (0, _objectWithoutPropertiesLoose2.default)(_payload,
|
|
1385
|
+
payload = (0, _objectWithoutPropertiesLoose2.default)(_payload, _excluded14);
|
|
1281
1386
|
setLoginState({
|
|
1282
1387
|
loading: true
|
|
1283
1388
|
});
|
|
@@ -1300,7 +1405,7 @@ var _default = (store, api, sharedActions) => {
|
|
|
1300
1405
|
const {
|
|
1301
1406
|
callback
|
|
1302
1407
|
} = _payload,
|
|
1303
|
-
payload = (0, _objectWithoutPropertiesLoose2.default)(_payload,
|
|
1408
|
+
payload = (0, _objectWithoutPropertiesLoose2.default)(_payload, _excluded15);
|
|
1304
1409
|
setLoginState({
|
|
1305
1410
|
loading: true
|
|
1306
1411
|
});
|
|
@@ -1327,7 +1432,7 @@ var _default = (store, api, sharedActions) => {
|
|
|
1327
1432
|
const {
|
|
1328
1433
|
callback
|
|
1329
1434
|
} = _payload,
|
|
1330
|
-
payload = (0, _objectWithoutPropertiesLoose2.default)(_payload,
|
|
1435
|
+
payload = (0, _objectWithoutPropertiesLoose2.default)(_payload, _excluded16);
|
|
1331
1436
|
setLoginState({
|
|
1332
1437
|
loading: true
|
|
1333
1438
|
});
|
|
@@ -1395,7 +1500,10 @@ var _default = (store, api, sharedActions) => {
|
|
|
1395
1500
|
};
|
|
1396
1501
|
|
|
1397
1502
|
/** @private */
|
|
1398
|
-
const __refreshTokenHostedSocialLogins = async (
|
|
1503
|
+
const __refreshTokenHostedSocialLogins = async ({
|
|
1504
|
+
tenantId,
|
|
1505
|
+
isSsoEnforcementRetry = false
|
|
1506
|
+
} = {}) => {
|
|
1399
1507
|
const {
|
|
1400
1508
|
user: currentUser
|
|
1401
1509
|
} = store.auth;
|
|
@@ -1409,7 +1517,7 @@ var _default = (store, api, sharedActions) => {
|
|
|
1409
1517
|
return;
|
|
1410
1518
|
}
|
|
1411
1519
|
try {
|
|
1412
|
-
const tabTenantId = (0, _restApi.getTabTenantFromSessionStorage)(store.root.appName);
|
|
1520
|
+
const tabTenantId = tenantId != null ? tenantId : (0, _restApi.getTabTenantFromSessionStorage)(store.root.appName);
|
|
1413
1521
|
const body = (0, _extends2.default)({
|
|
1414
1522
|
grant_type: 'refresh_token',
|
|
1415
1523
|
refresh_token: currentUser == null ? void 0 : currentUser.refreshToken
|
|
@@ -1424,6 +1532,13 @@ var _default = (store, api, sharedActions) => {
|
|
|
1424
1532
|
isAuthenticated: true
|
|
1425
1533
|
});
|
|
1426
1534
|
} catch (e) {
|
|
1535
|
+
const retry = tenantId => __refreshTokenHostedSocialLogins({
|
|
1536
|
+
tenantId,
|
|
1537
|
+
isSsoEnforcementRetry: true
|
|
1538
|
+
});
|
|
1539
|
+
if (await __handleSsoEnforcementRefreshError(e, isSsoEnforcementRetry, retry)) {
|
|
1540
|
+
return;
|
|
1541
|
+
}
|
|
1427
1542
|
contextHolder.setAccessToken(null);
|
|
1428
1543
|
contextHolder.setUser(null);
|
|
1429
1544
|
actions.setAuthState({
|
|
@@ -1494,6 +1609,9 @@ var _default = (store, api, sharedActions) => {
|
|
|
1494
1609
|
}
|
|
1495
1610
|
}
|
|
1496
1611
|
} catch (e) {
|
|
1612
|
+
if (await __redirectToSsoIfRequired(e)) {
|
|
1613
|
+
return;
|
|
1614
|
+
}
|
|
1497
1615
|
contextHolder.setAccessToken(null);
|
|
1498
1616
|
contextHolder.setUser(null);
|
|
1499
1617
|
actions.setAuthState({
|
|
@@ -1540,7 +1658,9 @@ var _default = (store, api, sharedActions) => {
|
|
|
1540
1658
|
resetBreachedPassword,
|
|
1541
1659
|
refreshTokenForSocialLogins,
|
|
1542
1660
|
// protected
|
|
1543
|
-
__refreshToken
|
|
1661
|
+
__refreshToken,
|
|
1662
|
+
__redirectToSsoForTenant,
|
|
1663
|
+
__redirectToSsoIfRequired
|
|
1544
1664
|
}, (0, _hostedLoginAuthorize.default)(store, api, sharedActions), (0, _afterAuthNavigation.default)(store, api, sharedActions), (0, _handleVerifyMFAResponse.default)(store, api, sharedActions), (0, _mfaRequiredState.default)(store, api, sharedActions), (0, _mfaWithAuthenticator.default)(store, api, sharedActions), (0, _mfaWithEmailCode.default)(store, api, sharedActions), (0, _mfaWithSMS.default)(store, api, sharedActions), (0, _mfaWithWebAuthn.default)(store, api, sharedActions));
|
|
1545
1665
|
};
|
|
1546
1666
|
exports.default = _default;
|
|
@@ -152,6 +152,9 @@ var _default = (store, api, sharedActions) => {
|
|
|
152
152
|
}
|
|
153
153
|
return await __postLoginMfaAuthenticator(isAuthenticated, user, callback);
|
|
154
154
|
} catch (e) {
|
|
155
|
+
if (await actions.__redirectToSsoIfRequired(e)) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
155
158
|
setLoadingAction({
|
|
156
159
|
loading: false,
|
|
157
160
|
error: (0, _helpers.errorHandler)(e)
|
|
@@ -75,6 +75,9 @@ var _default = (store, api, sharedActions) => {
|
|
|
75
75
|
});
|
|
76
76
|
callback == null ? void 0 : callback(true);
|
|
77
77
|
} catch (e) {
|
|
78
|
+
if (await actions.__redirectToSsoIfRequired(e)) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
78
81
|
setLoadingAction({
|
|
79
82
|
loading: false,
|
|
80
83
|
error: (0, _helpers.errorHandler)(e)
|
|
@@ -80,6 +80,9 @@ var _default = (store, api, sharedActions) => {
|
|
|
80
80
|
});
|
|
81
81
|
callback == null ? void 0 : callback(true);
|
|
82
82
|
} catch (e) {
|
|
83
|
+
if (await actions.__redirectToSsoIfRequired(e)) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
83
86
|
setLoadingAction({
|
|
84
87
|
loading: false,
|
|
85
88
|
error: (0, _helpers.errorHandler)(e)
|
|
@@ -94,6 +94,9 @@ var _default = (store, api, sharedActions) => {
|
|
|
94
94
|
});
|
|
95
95
|
callback == null ? void 0 : callback(true);
|
|
96
96
|
} catch (e) {
|
|
97
|
+
if (await actions.__redirectToSsoIfRequired(e)) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
97
100
|
setLoadingAction({
|
|
98
101
|
loading: false,
|
|
99
102
|
error: (0, _helpers.errorHandler)(e)
|
|
@@ -164,6 +164,9 @@ var _default = (store, api, sharedActions) => {
|
|
|
164
164
|
loading: false
|
|
165
165
|
});
|
|
166
166
|
} catch (e) {
|
|
167
|
+
if (await actions.__redirectToSsoIfRequired(e)) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
167
170
|
setSocialLoginsState({
|
|
168
171
|
loading: false,
|
|
169
172
|
error: (0, _helpers.errorHandler)(e, 'Failed to authenticate'),
|
|
@@ -67,7 +67,7 @@ var _default = (store, api, sharedActions) => {
|
|
|
67
67
|
callback
|
|
68
68
|
} = payload,
|
|
69
69
|
body = (0, _objectWithoutPropertiesLoose2.default)(payload, _excluded3);
|
|
70
|
-
await __activateLinkTryCatch(_interfaces.TeamStateKeys.RESEND_INVITATION_LINK,
|
|
70
|
+
await __activateLinkTryCatch(_interfaces.TeamStateKeys.RESEND_INVITATION_LINK, body.email, callback, async () => {
|
|
71
71
|
await api.auth.resendInvitationEmail(body);
|
|
72
72
|
callback == null ? void 0 : callback(true);
|
|
73
73
|
});
|
|
@@ -57,6 +57,13 @@ var _default = (store, api, sharedActions) => {
|
|
|
57
57
|
}) : actions.setAuthState({
|
|
58
58
|
isLoading: false
|
|
59
59
|
});
|
|
60
|
+
if (await actions.__redirectToSsoIfRequired(e)) {
|
|
61
|
+
// the tab comes back from SSO in the target tenant, not the one the failed switch restored
|
|
62
|
+
if (_restApi.ContextHolder.for(store.root.appName).isSessionPerTenantEnabled()) {
|
|
63
|
+
(0, _restApi.setTabTenantInSessionStorage)(tenantId);
|
|
64
|
+
}
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
60
67
|
callback == null ? void 0 : callback(false, e);
|
|
61
68
|
}
|
|
62
69
|
};
|
package/node/helpers/handlers.js
CHANGED
|
@@ -3,10 +3,14 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.isFronteggApiError = exports.isError = exports.errorHandler = void 0;
|
|
6
|
+
exports.isSsoEnforcementError = exports.isFronteggApiError = exports.isError = exports.errorHandler = void 0;
|
|
7
7
|
var _restApi = require("@frontegg/rest-api");
|
|
8
8
|
const isFronteggApiError = error => Boolean(error == null ? void 0 : error.statusCode);
|
|
9
|
+
|
|
10
|
+
// ER-01079 (disabled user / expired tenant) is not this: it still logs out
|
|
9
11
|
exports.isFronteggApiError = isFronteggApiError;
|
|
12
|
+
const isSsoEnforcementError = error => isFronteggApiError(error) && error.errorCode === _restApi.SSO_REQUIRED_FOR_TENANT_ERROR_CODE;
|
|
13
|
+
exports.isSsoEnforcementError = isSsoEnforcementError;
|
|
10
14
|
const isError = error => {
|
|
11
15
|
if (error instanceof Error) {
|
|
12
16
|
return true;
|
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.131.0-alpha.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.131.0-alpha.0",
|
|
11
11
|
"fast-deep-equal": "3.1.3",
|
|
12
12
|
"get-value": "^3.0.1",
|
|
13
13
|
"proxy-compare": "^3.0.0",
|