@frontegg/redux-store 6.165.0-alpha.9 → 6.166.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/index.d.ts +1 -0
- package/auth/LoginState/index.js +2 -1
- package/auth/LoginState/saga.d.ts +7 -1
- package/auth/LoginState/saga.js +22 -16
- package/auth/StepUpState/consts.d.ts +4 -0
- package/auth/StepUpState/consts.js +6 -1
- package/auth/StepUpState/index.d.ts +4 -1
- package/auth/StepUpState/index.js +5 -1
- package/auth/StepUpState/interfaces.d.ts +12 -0
- package/auth/StepUpState/saga.js +2 -0
- package/auth/StepUpState/stepUpHostedLogin.saga.d.ts +12 -0
- package/auth/StepUpState/stepUpHostedLogin.saga.js +24 -0
- package/auth/StepUpState/utils.d.ts +18 -4
- package/auth/StepUpState/utils.js +32 -5
- package/auth/index.d.ts +1 -0
- package/auth/reducer.d.ts +1 -0
- package/index.js +1 -1
- package/node/auth/LoginState/index.js +7 -0
- package/node/auth/LoginState/saga.js +20 -13
- package/node/auth/StepUpState/consts.js +8 -2
- package/node/auth/StepUpState/index.js +19 -1
- package/node/auth/StepUpState/saga.js +2 -0
- package/node/auth/StepUpState/stepUpHostedLogin.saga.js +29 -0
- package/node/auth/StepUpState/utils.js +35 -6
- package/node/index.js +1 -1
- package/package.json +2 -2
|
@@ -238,3 +238,4 @@ declare type DispatchedActions = {
|
|
|
238
238
|
export declare type LoginActions = DispatchedActions;
|
|
239
239
|
export { loginState, reducers as loginReducers, actions as loginActions };
|
|
240
240
|
export { getRedirectUrl, getSearchParam } from './utils';
|
|
241
|
+
export { defaultFronteggRoutes } from './consts';
|
package/auth/LoginState/index.js
CHANGED
|
@@ -139,4 +139,5 @@ const actions = {
|
|
|
139
139
|
*/
|
|
140
140
|
const Matcher = {};
|
|
141
141
|
export { loginState, reducers as loginReducers, actions as loginActions };
|
|
142
|
-
export { getRedirectUrl, getSearchParam } from './utils';
|
|
142
|
+
export { getRedirectUrl, getSearchParam } from './utils';
|
|
143
|
+
export { defaultFronteggRoutes } from './consts';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CallEffect } from 'redux-saga/effects';
|
|
2
|
-
import { ISamlMetadata } from '@frontegg/rest-api';
|
|
2
|
+
import { ISamlMetadata, ResolvedTenantResult } from '@frontegg/rest-api';
|
|
3
3
|
import { AuthState } from '../interfaces';
|
|
4
4
|
export declare function refreshMetadata(): Generator<import("redux-saga/effects").PutEffect<{
|
|
5
5
|
payload: Partial<AuthState>;
|
|
@@ -15,6 +15,12 @@ export declare function loadSSOPublicConfigurationFunction(): Generator<import("
|
|
|
15
15
|
}>;
|
|
16
16
|
export declare function refreshToken(): Generator<import("redux-saga/effects").SelectEffect | CallEffect<any>, void, AuthState>;
|
|
17
17
|
export declare function refreshTokenForSocialLogins(): Generator<import("redux-saga/effects").SelectEffect | CallEffect<any>, void, AuthState>;
|
|
18
|
+
export declare function requestHostedLoginAuthorize(additionalParams?: Record<string, string>): Generator<any, void, {
|
|
19
|
+
routes: any;
|
|
20
|
+
context: any;
|
|
21
|
+
onRedirectTo: any;
|
|
22
|
+
urlStrategy: any;
|
|
23
|
+
} & string & ResolvedTenantResult>;
|
|
18
24
|
export declare function loginSagas(): Generator<import("redux-saga/effects").ForkEffect<never>, void, unknown>;
|
|
19
25
|
export { afterAuthNavigation } from './sagas/afterAuthNavigation.saga';
|
|
20
26
|
export { mfaWithAuthenticator } from './sagas/mfaWithAuthenticator.saga';
|
package/auth/LoginState/saga.js
CHANGED
|
@@ -34,10 +34,11 @@ import { getSearchParam, TENANT_ID_PARAM_KEY, isMfaRequired, isOauthCallbackRout
|
|
|
34
34
|
import { errorHandler, GTMEventAction, reportGTMEvent } from '../../utils';
|
|
35
35
|
import { authStrategyLoginStepMap } from './consts';
|
|
36
36
|
import { isEntitlementsDeeplyEqual } from '../Entitlements';
|
|
37
|
-
import {
|
|
37
|
+
import { loadCustomLoginRoutes } from '../CustomLoginState/saga';
|
|
38
38
|
import { FronteggNativeModule } from '../../toolkit';
|
|
39
39
|
import { afterAuthenticationStateUpdate, shouldShowPromptPasskeys } from './saga.utils';
|
|
40
|
-
import { afterAuthNavigation, loginWithMfa, preVerifyMFASMSForLogin, verifyMFASMSForLogin, preVerifyMFAWebAuthnForLogin, verifyMFAWebAuthnForLogin, preVerifyMFAEmailCodeForLogin, verifyMFAEmailCodeForLogin } from './sagas';
|
|
40
|
+
import { afterAuthNavigation, loginWithMfa, preVerifyMFASMSForLogin, verifyMFASMSForLogin, preVerifyMFAWebAuthnForLogin, verifyMFAWebAuthnForLogin, preVerifyMFAEmailCodeForLogin, verifyMFAEmailCodeForLogin, afterStepUpAuthNavigation } from './sagas';
|
|
41
|
+
import { SHOULD_STEP_UP_KEY } from '../StepUpState/consts';
|
|
41
42
|
|
|
42
43
|
/******************************************************************
|
|
43
44
|
*** ****
|
|
@@ -349,17 +350,8 @@ function* requestAuthorize({
|
|
|
349
350
|
payload: firstTime
|
|
350
351
|
}) {
|
|
351
352
|
const calls = [];
|
|
352
|
-
const
|
|
353
|
-
|
|
354
|
-
/*
|
|
355
|
-
// waiting for refreshToken to be loaded is only necessary for custom login
|
|
356
|
-
// but doing this will degrade the loading performance in around 500 ms
|
|
357
|
-
// so we will wait for the refreshToken only if there is tenantResolver
|
|
358
|
-
*/
|
|
359
|
-
yield call(refreshToken);
|
|
360
|
-
} else {
|
|
361
|
-
calls.push(call(refreshToken));
|
|
362
|
-
}
|
|
353
|
+
const callsAfterRefresh = [];
|
|
354
|
+
calls.push(call(refreshToken));
|
|
363
355
|
if (firstTime) {
|
|
364
356
|
yield put(actions.setState({
|
|
365
357
|
isLoading: true
|
|
@@ -370,9 +362,17 @@ function* requestAuthorize({
|
|
|
370
362
|
calls.push(call(loadSSOPublicConfigurationFunction));
|
|
371
363
|
calls.push(call(loadVendorPublicInfo));
|
|
372
364
|
calls.push(call(refreshMetadata));
|
|
373
|
-
|
|
365
|
+
/*
|
|
366
|
+
We will load custom login routes only if custom login is enabled
|
|
367
|
+
In order to check if custom login is enabled without the tenant alias (search-param/sub-domain)
|
|
368
|
+
we have to wait for the user state (refreshToken request)
|
|
369
|
+
*/
|
|
370
|
+
callsAfterRefresh.push(call(loadCustomLoginRoutes));
|
|
374
371
|
}
|
|
375
372
|
yield all(calls);
|
|
373
|
+
if (callsAfterRefresh.length > 0) {
|
|
374
|
+
yield all(callsAfterRefresh);
|
|
375
|
+
}
|
|
376
376
|
yield put(actions.setState({
|
|
377
377
|
isLoading: false
|
|
378
378
|
}));
|
|
@@ -510,7 +510,7 @@ function* refreshOrRequestHostedLoginAuthorizeV2({
|
|
|
510
510
|
yield requestHostedLoginAuthorize(additionalParams);
|
|
511
511
|
}
|
|
512
512
|
}
|
|
513
|
-
function* requestHostedLoginAuthorize(additionalParams) {
|
|
513
|
+
export function* requestHostedLoginAuthorize(additionalParams) {
|
|
514
514
|
const {
|
|
515
515
|
routes,
|
|
516
516
|
context,
|
|
@@ -620,7 +620,13 @@ function* handleHostedLoginCallback({
|
|
|
620
620
|
}));
|
|
621
621
|
console.error('Failed to exchangeOAuthTokens', e);
|
|
622
622
|
} finally {
|
|
623
|
-
|
|
623
|
+
const isStepUpFlow = window.localStorage.getItem(SHOULD_STEP_UP_KEY);
|
|
624
|
+
window.localStorage.removeItem(SHOULD_STEP_UP_KEY);
|
|
625
|
+
if (isStepUpFlow) {
|
|
626
|
+
yield afterStepUpAuthNavigation();
|
|
627
|
+
} else {
|
|
628
|
+
yield afterAuthNavigation();
|
|
629
|
+
}
|
|
624
630
|
}
|
|
625
631
|
}
|
|
626
632
|
function* changePhoneNumberWithVerification(_ref4) {
|
|
@@ -15,3 +15,7 @@ export declare const AMR_ADDITIONAL_VALUE: string[];
|
|
|
15
15
|
* Used for scenarios when we logout for re-login and then should redirect to step up page
|
|
16
16
|
*/
|
|
17
17
|
export declare const SHOULD_STEP_UP_KEY = "SHOULD_STEP_UP";
|
|
18
|
+
/**
|
|
19
|
+
* The name of the query param that contains the max age of the step up
|
|
20
|
+
*/
|
|
21
|
+
export declare const STEP_UP_MAX_AGE_PARAM_NAME = "maxAge";
|
|
@@ -17,4 +17,9 @@ export const AMR_ADDITIONAL_VALUE = ['otp', 'sms', 'hwk'];
|
|
|
17
17
|
* SHOULD_STEP_UP_KEY local storage key
|
|
18
18
|
* Used for scenarios when we logout for re-login and then should redirect to step up page
|
|
19
19
|
*/
|
|
20
|
-
export const SHOULD_STEP_UP_KEY = 'SHOULD_STEP_UP';
|
|
20
|
+
export const SHOULD_STEP_UP_KEY = 'SHOULD_STEP_UP';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The name of the query param that contains the max age of the step up
|
|
24
|
+
*/
|
|
25
|
+
export const STEP_UP_MAX_AGE_PARAM_NAME = 'maxAge';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { IPreVerifyMFA, IVerifyMFASMS, IVerifyMFAEmailCode } from '@frontegg/rest-api';
|
|
2
|
-
import { IGenerateStepUpSession, IStepUpWithAuthenticator, StepUpState } from './interfaces';
|
|
2
|
+
import { IGenerateStepUpSession, IStepUpHostedLogin, IStepUpWithAuthenticator, StepUpState } from './interfaces';
|
|
3
3
|
import { WithCallback } from '../../interfaces';
|
|
4
4
|
import { IPreVerifyMFAWebAuthNForLoginResponse, IVerifyMFAWebAuthnPayload, WithDeviceId } from '../LoginState/interfaces';
|
|
5
5
|
declare const stepUpState: StepUpState;
|
|
@@ -108,6 +108,7 @@ declare const reducers: {
|
|
|
108
108
|
};
|
|
109
109
|
};
|
|
110
110
|
declare const actions: {
|
|
111
|
+
stepUpHostedLogin: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[IStepUpHostedLogin], IStepUpHostedLogin, string, never, never>;
|
|
111
112
|
generateStepUpSession: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[WithCallback<IGenerateStepUpSession, boolean>], WithCallback<IGenerateStepUpSession, boolean>, string, never, never>;
|
|
112
113
|
stepUpWithAuthenticator: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[WithCallback<IStepUpWithAuthenticator, boolean>], WithCallback<IStepUpWithAuthenticator, boolean>, string, never, never>;
|
|
113
114
|
preVerifyMFASMSForStepUp: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[WithCallback<WithDeviceId<IPreVerifyMFA>, boolean>], WithCallback<WithDeviceId<IPreVerifyMFA>, boolean>, string, never, never>;
|
|
@@ -125,6 +126,7 @@ declare type DispatchedActions = {
|
|
|
125
126
|
setStepUpState: (state: Partial<StepUpState>) => void;
|
|
126
127
|
resetStepUpState: () => void;
|
|
127
128
|
generateStepUpSession: (payload: WithCallback<IGenerateStepUpSession>) => void;
|
|
129
|
+
stepUpHostedLogin: (payload: IStepUpHostedLogin) => void;
|
|
128
130
|
stepUpWithAuthenticator: (payload: WithCallback<IStepUpWithAuthenticator>) => void;
|
|
129
131
|
preVerifyMFASMSForStepUp: (payload: WithCallback<WithDeviceId<IPreVerifyMFA>>) => void;
|
|
130
132
|
verifyMFASMSForStepUp: (payload: WithCallback<WithDeviceId<IVerifyMFASMS>>) => void;
|
|
@@ -136,3 +138,4 @@ declare type DispatchedActions = {
|
|
|
136
138
|
export declare type StepUpActions = DispatchedActions;
|
|
137
139
|
export { stepUpState, reducers as stepUpReducers, actions as stepUpActions };
|
|
138
140
|
export * from './utils';
|
|
141
|
+
export { STEP_UP_MAX_AGE_PARAM_NAME, SHOULD_STEP_UP_KEY } from './consts';
|
|
@@ -13,6 +13,9 @@ const reducers = {
|
|
|
13
13
|
})
|
|
14
14
|
};
|
|
15
15
|
const actions = {
|
|
16
|
+
stepUpHostedLogin: createAction(`${authStoreName}/stepUpHostedLogin`, payload => ({
|
|
17
|
+
payload
|
|
18
|
+
})),
|
|
16
19
|
generateStepUpSession: createAction(`${authStoreName}/generateStepUpSession`, payload => ({
|
|
17
20
|
payload
|
|
18
21
|
})),
|
|
@@ -51,4 +54,5 @@ const actions = {
|
|
|
51
54
|
*/
|
|
52
55
|
const Matcher = {};
|
|
53
56
|
export { stepUpState, reducers as stepUpReducers, actions as stepUpActions };
|
|
54
|
-
export * from './utils';
|
|
57
|
+
export * from './utils';
|
|
58
|
+
export { STEP_UP_MAX_AGE_PARAM_NAME, SHOULD_STEP_UP_KEY } from './consts';
|
|
@@ -21,3 +21,15 @@ export interface IStepUpWithAuthenticator {
|
|
|
21
21
|
mfaToken: string;
|
|
22
22
|
value: string;
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Step up hosted login options
|
|
26
|
+
*/
|
|
27
|
+
export interface IStepUpHostedLogin {
|
|
28
|
+
maxAge?: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Step up options (for stepUp function)
|
|
32
|
+
*/
|
|
33
|
+
export interface StepUpOptions {
|
|
34
|
+
maxAge?: number;
|
|
35
|
+
}
|
package/auth/StepUpState/saga.js
CHANGED
|
@@ -5,6 +5,7 @@ import { preVerifyMFASMS, verifyMFASMS } from '../LoginState/sagas/mfaWithSMS.sa
|
|
|
5
5
|
import { preVerifyMFAWebAuthn, verifyMFAWebAuthn } from '../LoginState/sagas/mfaWithWebAuthn.saga';
|
|
6
6
|
import { verifyMFAEmailCode, preVerifyMFAEmailCode } from '../LoginState/sagas/mfaWithEmailCode.saga';
|
|
7
7
|
import { generateStepUpSession } from './generateStepUpSession.saga';
|
|
8
|
+
import { stepUpHostedLogin } from './stepUpHostedLogin.saga';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Step up with authenticator app
|
|
@@ -93,6 +94,7 @@ export function* preVerifyMFAEmailCodeForStepUp({
|
|
|
93
94
|
yield preVerifyMFAEmailCode(payload, actions.setStepUpState);
|
|
94
95
|
}
|
|
95
96
|
export function* stepUpSagas() {
|
|
97
|
+
yield takeLeading(actions.stepUpHostedLogin, stepUpHostedLogin);
|
|
96
98
|
yield takeLeading(actions.generateStepUpSession, generateStepUpSession);
|
|
97
99
|
yield takeLeading(actions.stepUpWithAuthenticator, stepUpWithAuthenticator);
|
|
98
100
|
yield takeLeading(actions.preVerifyMFASMSForStepUp, preVerifyMFASMSForStepUp);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { PayloadAction } from '@reduxjs/toolkit';
|
|
2
|
+
import { IStepUpHostedLogin } from './interfaces';
|
|
3
|
+
/**
|
|
4
|
+
* Step up for hosted login apps
|
|
5
|
+
* @param payload.maxAge
|
|
6
|
+
*/
|
|
7
|
+
export declare function stepUpHostedLogin({ payload }: PayloadAction<IStepUpHostedLogin>): Generator<Generator<any, void, {
|
|
8
|
+
routes: any;
|
|
9
|
+
context: any;
|
|
10
|
+
onRedirectTo: any;
|
|
11
|
+
urlStrategy: any;
|
|
12
|
+
} & string & import("@frontegg/rest-api").ResolvedTenantResult>, void, unknown>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { requestHostedLoginAuthorize } from '../LoginState/saga';
|
|
2
|
+
import { ACR_VALUE, SHOULD_STEP_UP_KEY } from './consts';
|
|
3
|
+
import { setAfterAuthRedirectUrlForStepUp } from './utils';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Step up for hosted login apps
|
|
7
|
+
* @param payload.maxAge
|
|
8
|
+
*/
|
|
9
|
+
export function* stepUpHostedLogin({
|
|
10
|
+
payload
|
|
11
|
+
}) {
|
|
12
|
+
const params = {
|
|
13
|
+
acr_values: ACR_VALUE
|
|
14
|
+
};
|
|
15
|
+
const {
|
|
16
|
+
maxAge
|
|
17
|
+
} = payload || {};
|
|
18
|
+
if (maxAge !== undefined) {
|
|
19
|
+
params.max_age = maxAge.toString();
|
|
20
|
+
}
|
|
21
|
+
setAfterAuthRedirectUrlForStepUp();
|
|
22
|
+
window.localStorage.setItem(SHOULD_STEP_UP_KEY, 'true');
|
|
23
|
+
yield requestHostedLoginAuthorize(params);
|
|
24
|
+
}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
import { RedirectOptions } from '@frontegg/rest-api';
|
|
2
|
+
export interface IsSteppedUpOptions {
|
|
3
|
+
maxAge?: number;
|
|
4
|
+
}
|
|
5
|
+
export interface SteppedUpJWTValues {
|
|
2
6
|
amr?: string[];
|
|
3
7
|
acr?: string;
|
|
4
8
|
auth_time?: number;
|
|
5
|
-
maxAge?: number;
|
|
6
9
|
}
|
|
7
10
|
/**
|
|
8
11
|
* @param options.amr
|
|
@@ -11,5 +14,16 @@ interface IsSteppedUpOptions {
|
|
|
11
14
|
* @param options.maxAge - max age of step up
|
|
12
15
|
* @returns true when the user is stepped up, false otherwise
|
|
13
16
|
*/
|
|
14
|
-
export declare const isSteppedUp: (
|
|
15
|
-
|
|
17
|
+
export declare const isSteppedUp: (user?: SteppedUpJWTValues | null | undefined, { maxAge }?: IsSteppedUpOptions) => boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Set the url and query params in the local storage FRONTEGG_AFTER_AUTH_REDIRECT_URL value
|
|
20
|
+
*/
|
|
21
|
+
export declare function setAfterAuthRedirectUrlForStepUp(): void;
|
|
22
|
+
/**
|
|
23
|
+
* Redirects to the step up url with the max age param and set the redirect url in the local storage
|
|
24
|
+
* The redirect url will be used after the step up flow is done
|
|
25
|
+
* @param stepUpUrl - step up url to redirect to
|
|
26
|
+
* @param onRedirectTo - redirect to function
|
|
27
|
+
* @param maxAge - max age of step up
|
|
28
|
+
*/
|
|
29
|
+
export declare const redirectByStepUpUrl: (stepUpUrl: string, onRedirectTo: (path: string, opts?: RedirectOptions | undefined) => void, maxAge?: number | undefined) => void;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FRONTEGG_AFTER_AUTH_REDIRECT_URL } from '../../constants';
|
|
2
|
+
import { ACR_VALUE, AMR_MFA_VALUE, AMR_ADDITIONAL_VALUE, STEP_UP_MAX_AGE_PARAM_NAME } from './consts';
|
|
2
3
|
/**
|
|
3
4
|
* @param options.amr
|
|
4
5
|
* @param options.acr
|
|
@@ -6,12 +7,15 @@ import { ACR_VALUE, AMR_MFA_VALUE, AMR_ADDITIONAL_VALUE } from './consts';
|
|
|
6
7
|
* @param options.maxAge - max age of step up
|
|
7
8
|
* @returns true when the user is stepped up, false otherwise
|
|
8
9
|
*/
|
|
9
|
-
export const isSteppedUp = ({
|
|
10
|
-
amr = [],
|
|
11
|
-
acr = '',
|
|
12
|
-
auth_time,
|
|
10
|
+
export const isSteppedUp = (user, {
|
|
13
11
|
maxAge
|
|
14
12
|
} = {}) => {
|
|
13
|
+
if (!user) return false;
|
|
14
|
+
const {
|
|
15
|
+
amr = [],
|
|
16
|
+
acr = '',
|
|
17
|
+
auth_time
|
|
18
|
+
} = user;
|
|
15
19
|
if (maxAge && auth_time) {
|
|
16
20
|
// when user is logged in for a long time (more than maxAge, but jwt is still valid because it's not refreshed yet)
|
|
17
21
|
const isMaxAgeValid = Date.now() / 1000 - auth_time <= maxAge;
|
|
@@ -21,4 +25,27 @@ export const isSteppedUp = ({
|
|
|
21
25
|
const isAMRIncludesMFA = amr.indexOf(AMR_MFA_VALUE) !== -1;
|
|
22
26
|
const isAMRIncludesMethod = AMR_ADDITIONAL_VALUE.find(method => amr.indexOf(method)) !== undefined;
|
|
23
27
|
return isACRValid && isAMRIncludesMFA && isAMRIncludesMethod;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Set the url and query params in the local storage FRONTEGG_AFTER_AUTH_REDIRECT_URL value
|
|
32
|
+
*/
|
|
33
|
+
export function setAfterAuthRedirectUrlForStepUp() {
|
|
34
|
+
const encodedRedirectUrl = window.location.pathname + window.location.search;
|
|
35
|
+
window.localStorage.setItem(FRONTEGG_AFTER_AUTH_REDIRECT_URL, encodedRedirectUrl);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Redirects to the step up url with the max age param and set the redirect url in the local storage
|
|
40
|
+
* The redirect url will be used after the step up flow is done
|
|
41
|
+
* @param stepUpUrl - step up url to redirect to
|
|
42
|
+
* @param onRedirectTo - redirect to function
|
|
43
|
+
* @param maxAge - max age of step up
|
|
44
|
+
*/
|
|
45
|
+
export const redirectByStepUpUrl = (stepUpUrl, onRedirectTo, maxAge) => {
|
|
46
|
+
setAfterAuthRedirectUrlForStepUp();
|
|
47
|
+
const maxAgePart = maxAge !== undefined ? `?${STEP_UP_MAX_AGE_PARAM_NAME}=${maxAge}` : '';
|
|
48
|
+
onRedirectTo(`${stepUpUrl}${maxAgePart}`, {
|
|
49
|
+
refresh: false
|
|
50
|
+
});
|
|
24
51
|
};
|
package/auth/index.d.ts
CHANGED
|
@@ -495,6 +495,7 @@ declare const _default: {
|
|
|
495
495
|
} | undefined, string, never, never>;
|
|
496
496
|
loginViaSocialLogin: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[import("./SocialLogins/interfaces").ILoginViaSocialLoginPayload], import("./SocialLogins/interfaces").ILoginViaSocialLoginPayload, string, never, never>;
|
|
497
497
|
setSocialLoginError: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[import("@frontegg/rest-api").ISetSocialLoginError], import("@frontegg/rest-api").ISetSocialLoginError, string, never, never>;
|
|
498
|
+
stepUpHostedLogin: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[import("./StepUpState/interfaces").IStepUpHostedLogin], import("./StepUpState/interfaces").IStepUpHostedLogin, string, never, never>;
|
|
498
499
|
generateStepUpSession: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[import("..").WithCallback<import("./StepUpState/interfaces").IGenerateStepUpSession, boolean>], import("..").WithCallback<import("./StepUpState/interfaces").IGenerateStepUpSession, boolean>, string, never, never>;
|
|
499
500
|
stepUpWithAuthenticator: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[import("..").WithCallback<import("./StepUpState/interfaces").IStepUpWithAuthenticator, boolean>], import("..").WithCallback<import("./StepUpState/interfaces").IStepUpWithAuthenticator, boolean>, string, never, never>;
|
|
500
501
|
preVerifyMFASMSForStepUp: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[import("..").WithCallback<import("./LoginState/interfaces").WithDeviceId<import("@frontegg/rest-api").IPreVerifyMFA>, boolean>], import("..").WithCallback<import("./LoginState/interfaces").WithDeviceId<import("@frontegg/rest-api").IPreVerifyMFA>, boolean>, string, never, never>;
|
package/auth/reducer.d.ts
CHANGED
|
@@ -453,6 +453,7 @@ declare const actions: {
|
|
|
453
453
|
} | undefined, string, never, never>;
|
|
454
454
|
loginViaSocialLogin: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[import(".").ILoginViaSocialLoginPayload], import(".").ILoginViaSocialLoginPayload, string, never, never>;
|
|
455
455
|
setSocialLoginError: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[import("@frontegg/rest-api").ISetSocialLoginError], import("@frontegg/rest-api").ISetSocialLoginError, string, never, never>;
|
|
456
|
+
stepUpHostedLogin: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[import(".").IStepUpHostedLogin], import(".").IStepUpHostedLogin, string, never, never>;
|
|
456
457
|
generateStepUpSession: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[import("..").WithCallback<import(".").IGenerateStepUpSession, boolean>], import("..").WithCallback<import(".").IGenerateStepUpSession, boolean>, string, never, never>;
|
|
457
458
|
stepUpWithAuthenticator: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[import("..").WithCallback<import(".").IStepUpWithAuthenticator, boolean>], import("..").WithCallback<import(".").IStepUpWithAuthenticator, boolean>, string, never, never>;
|
|
458
459
|
preVerifyMFASMSForStepUp: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[import("..").WithCallback<import(".").WithDeviceId<import("@frontegg/rest-api").IPreVerifyMFA>, boolean>], import("..").WithCallback<import(".").WithDeviceId<import("@frontegg/rest-api").IPreVerifyMFA>, boolean>, string, never, never>;
|
package/index.js
CHANGED
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
+
Object.defineProperty(exports, "defaultFronteggRoutes", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _consts.defaultFronteggRoutes;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
6
12
|
Object.defineProperty(exports, "getRedirectUrl", {
|
|
7
13
|
enumerable: true,
|
|
8
14
|
get: function () {
|
|
@@ -21,6 +27,7 @@ var _interfaces = require("./interfaces");
|
|
|
21
27
|
var _utils = require("../utils");
|
|
22
28
|
var _constants = require("../../constants");
|
|
23
29
|
var _utils2 = require("./utils");
|
|
30
|
+
var _consts = require("./consts");
|
|
24
31
|
const loginState = {
|
|
25
32
|
flow: _interfaces.LoginFlow.Login,
|
|
26
33
|
step: _interfaces.LoginStep.preLogin,
|
|
@@ -22,6 +22,7 @@ Object.defineProperty(exports, "mfaWithAuthenticator", {
|
|
|
22
22
|
exports.refreshMetadata = refreshMetadata;
|
|
23
23
|
exports.refreshToken = refreshToken;
|
|
24
24
|
exports.refreshTokenForSocialLogins = refreshTokenForSocialLogins;
|
|
25
|
+
exports.requestHostedLoginAuthorize = requestHostedLoginAuthorize;
|
|
25
26
|
var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
|
|
26
27
|
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
27
28
|
var _effects = require("redux-saga/effects");
|
|
@@ -47,6 +48,7 @@ var _saga4 = require("../CustomLoginState/saga");
|
|
|
47
48
|
var _toolkit = require("../../toolkit");
|
|
48
49
|
var _saga5 = require("./saga.utils");
|
|
49
50
|
var _sagas = require("./sagas");
|
|
51
|
+
var _consts2 = require("../StepUpState/consts");
|
|
50
52
|
var _afterAuthNavigation = require("./sagas/afterAuthNavigation.saga");
|
|
51
53
|
var _mfaWithAuthenticator = require("./sagas/mfaWithAuthenticator.saga");
|
|
52
54
|
const _excluded = ["callback"],
|
|
@@ -374,17 +376,8 @@ function* requestAuthorize({
|
|
|
374
376
|
payload: firstTime
|
|
375
377
|
}) {
|
|
376
378
|
const calls = [];
|
|
377
|
-
const
|
|
378
|
-
|
|
379
|
-
/*
|
|
380
|
-
// waiting for refreshToken to be loaded is only necessary for custom login
|
|
381
|
-
// but doing this will degrade the loading performance in around 500 ms
|
|
382
|
-
// so we will wait for the refreshToken only if there is tenantResolver
|
|
383
|
-
*/
|
|
384
|
-
yield (0, _effects.call)(refreshToken);
|
|
385
|
-
} else {
|
|
386
|
-
calls.push((0, _effects.call)(refreshToken));
|
|
387
|
-
}
|
|
379
|
+
const callsAfterRefresh = [];
|
|
380
|
+
calls.push((0, _effects.call)(refreshToken));
|
|
388
381
|
if (firstTime) {
|
|
389
382
|
yield (0, _effects.put)(_reducer.actions.setState({
|
|
390
383
|
isLoading: true
|
|
@@ -395,9 +388,17 @@ function* requestAuthorize({
|
|
|
395
388
|
calls.push((0, _effects.call)(loadSSOPublicConfigurationFunction));
|
|
396
389
|
calls.push((0, _effects.call)(_saga2.loadVendorPublicInfo));
|
|
397
390
|
calls.push((0, _effects.call)(refreshMetadata));
|
|
398
|
-
|
|
391
|
+
/*
|
|
392
|
+
We will load custom login routes only if custom login is enabled
|
|
393
|
+
In order to check if custom login is enabled without the tenant alias (search-param/sub-domain)
|
|
394
|
+
we have to wait for the user state (refreshToken request)
|
|
395
|
+
*/
|
|
396
|
+
callsAfterRefresh.push((0, _effects.call)(_saga4.loadCustomLoginRoutes));
|
|
399
397
|
}
|
|
400
398
|
yield (0, _effects.all)(calls);
|
|
399
|
+
if (callsAfterRefresh.length > 0) {
|
|
400
|
+
yield (0, _effects.all)(callsAfterRefresh);
|
|
401
|
+
}
|
|
401
402
|
yield (0, _effects.put)(_reducer.actions.setState({
|
|
402
403
|
isLoading: false
|
|
403
404
|
}));
|
|
@@ -645,7 +646,13 @@ function* handleHostedLoginCallback({
|
|
|
645
646
|
}));
|
|
646
647
|
console.error('Failed to exchangeOAuthTokens', e);
|
|
647
648
|
} finally {
|
|
648
|
-
|
|
649
|
+
const isStepUpFlow = window.localStorage.getItem(_consts2.SHOULD_STEP_UP_KEY);
|
|
650
|
+
window.localStorage.removeItem(_consts2.SHOULD_STEP_UP_KEY);
|
|
651
|
+
if (isStepUpFlow) {
|
|
652
|
+
yield (0, _sagas.afterStepUpAuthNavigation)();
|
|
653
|
+
} else {
|
|
654
|
+
yield (0, _sagas.afterAuthNavigation)();
|
|
655
|
+
}
|
|
649
656
|
}
|
|
650
657
|
}
|
|
651
658
|
function* changePhoneNumberWithVerification(_ref4) {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.SHOULD_STEP_UP_KEY = exports.AMR_MFA_VALUE = exports.AMR_ADDITIONAL_VALUE = exports.ACR_VALUE = void 0;
|
|
6
|
+
exports.STEP_UP_MAX_AGE_PARAM_NAME = exports.SHOULD_STEP_UP_KEY = exports.AMR_MFA_VALUE = exports.AMR_ADDITIONAL_VALUE = exports.ACR_VALUE = void 0;
|
|
7
7
|
/**
|
|
8
8
|
* The required ACR (Authorization Context Reference) value for the step up flow
|
|
9
9
|
*/
|
|
@@ -27,4 +27,10 @@ const AMR_ADDITIONAL_VALUE = ['otp', 'sms', 'hwk'];
|
|
|
27
27
|
*/
|
|
28
28
|
exports.AMR_ADDITIONAL_VALUE = AMR_ADDITIONAL_VALUE;
|
|
29
29
|
const SHOULD_STEP_UP_KEY = 'SHOULD_STEP_UP';
|
|
30
|
-
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The name of the query param that contains the max age of the step up
|
|
33
|
+
*/
|
|
34
|
+
exports.SHOULD_STEP_UP_KEY = SHOULD_STEP_UP_KEY;
|
|
35
|
+
const STEP_UP_MAX_AGE_PARAM_NAME = 'maxAge';
|
|
36
|
+
exports.STEP_UP_MAX_AGE_PARAM_NAME = STEP_UP_MAX_AGE_PARAM_NAME;
|
|
@@ -6,8 +6,22 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
var _exportNames = {
|
|
7
7
|
stepUpState: true,
|
|
8
8
|
stepUpReducers: true,
|
|
9
|
-
stepUpActions: true
|
|
9
|
+
stepUpActions: true,
|
|
10
|
+
STEP_UP_MAX_AGE_PARAM_NAME: true,
|
|
11
|
+
SHOULD_STEP_UP_KEY: true
|
|
10
12
|
};
|
|
13
|
+
Object.defineProperty(exports, "SHOULD_STEP_UP_KEY", {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: function () {
|
|
16
|
+
return _consts.SHOULD_STEP_UP_KEY;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports, "STEP_UP_MAX_AGE_PARAM_NAME", {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
get: function () {
|
|
22
|
+
return _consts.STEP_UP_MAX_AGE_PARAM_NAME;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
11
25
|
exports.stepUpState = exports.stepUpReducers = exports.stepUpActions = void 0;
|
|
12
26
|
var _toolkit = require("@reduxjs/toolkit");
|
|
13
27
|
var _utils = require("../utils");
|
|
@@ -24,6 +38,7 @@ Object.keys(_utils2).forEach(function (key) {
|
|
|
24
38
|
}
|
|
25
39
|
});
|
|
26
40
|
});
|
|
41
|
+
var _consts = require("./consts");
|
|
27
42
|
const stepUpState = {
|
|
28
43
|
loading: false,
|
|
29
44
|
mfaDevices: undefined,
|
|
@@ -38,6 +53,9 @@ const reducers = {
|
|
|
38
53
|
};
|
|
39
54
|
exports.stepUpReducers = reducers;
|
|
40
55
|
const actions = {
|
|
56
|
+
stepUpHostedLogin: (0, _toolkit.createAction)(`${_constants.authStoreName}/stepUpHostedLogin`, payload => ({
|
|
57
|
+
payload
|
|
58
|
+
})),
|
|
41
59
|
generateStepUpSession: (0, _toolkit.createAction)(`${_constants.authStoreName}/generateStepUpSession`, payload => ({
|
|
42
60
|
payload
|
|
43
61
|
})),
|
|
@@ -18,6 +18,7 @@ var _mfaWithSMS = require("../LoginState/sagas/mfaWithSMS.saga");
|
|
|
18
18
|
var _mfaWithWebAuthn = require("../LoginState/sagas/mfaWithWebAuthn.saga");
|
|
19
19
|
var _mfaWithEmailCode = require("../LoginState/sagas/mfaWithEmailCode.saga");
|
|
20
20
|
var _generateStepUpSession = require("./generateStepUpSession.saga");
|
|
21
|
+
var _stepUpHostedLogin = require("./stepUpHostedLogin.saga");
|
|
21
22
|
/**
|
|
22
23
|
* Step up with authenticator app
|
|
23
24
|
* @param payload.callback - callback function to be called after the verification is done
|
|
@@ -105,6 +106,7 @@ function* preVerifyMFAEmailCodeForStepUp({
|
|
|
105
106
|
yield (0, _mfaWithEmailCode.preVerifyMFAEmailCode)(payload, _reducer.actions.setStepUpState);
|
|
106
107
|
}
|
|
107
108
|
function* stepUpSagas() {
|
|
109
|
+
yield (0, _effects.takeLeading)(_reducer.actions.stepUpHostedLogin, _stepUpHostedLogin.stepUpHostedLogin);
|
|
108
110
|
yield (0, _effects.takeLeading)(_reducer.actions.generateStepUpSession, _generateStepUpSession.generateStepUpSession);
|
|
109
111
|
yield (0, _effects.takeLeading)(_reducer.actions.stepUpWithAuthenticator, stepUpWithAuthenticator);
|
|
110
112
|
yield (0, _effects.takeLeading)(_reducer.actions.preVerifyMFASMSForStepUp, preVerifyMFASMSForStepUp);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.stepUpHostedLogin = stepUpHostedLogin;
|
|
7
|
+
var _saga = require("../LoginState/saga");
|
|
8
|
+
var _consts = require("./consts");
|
|
9
|
+
var _utils = require("./utils");
|
|
10
|
+
/**
|
|
11
|
+
* Step up for hosted login apps
|
|
12
|
+
* @param payload.maxAge
|
|
13
|
+
*/
|
|
14
|
+
function* stepUpHostedLogin({
|
|
15
|
+
payload
|
|
16
|
+
}) {
|
|
17
|
+
const params = {
|
|
18
|
+
acr_values: _consts.ACR_VALUE
|
|
19
|
+
};
|
|
20
|
+
const {
|
|
21
|
+
maxAge
|
|
22
|
+
} = payload || {};
|
|
23
|
+
if (maxAge !== undefined) {
|
|
24
|
+
params.max_age = maxAge.toString();
|
|
25
|
+
}
|
|
26
|
+
(0, _utils.setAfterAuthRedirectUrlForStepUp)();
|
|
27
|
+
window.localStorage.setItem(_consts.SHOULD_STEP_UP_KEY, 'true');
|
|
28
|
+
yield (0, _saga.requestHostedLoginAuthorize)(params);
|
|
29
|
+
}
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.isSteppedUp = void 0;
|
|
6
|
+
exports.redirectByStepUpUrl = exports.isSteppedUp = void 0;
|
|
7
|
+
exports.setAfterAuthRedirectUrlForStepUp = setAfterAuthRedirectUrlForStepUp;
|
|
8
|
+
var _constants = require("../../constants");
|
|
7
9
|
var _consts = require("./consts");
|
|
8
10
|
/**
|
|
9
11
|
* @param options.amr
|
|
@@ -12,12 +14,15 @@ var _consts = require("./consts");
|
|
|
12
14
|
* @param options.maxAge - max age of step up
|
|
13
15
|
* @returns true when the user is stepped up, false otherwise
|
|
14
16
|
*/
|
|
15
|
-
const isSteppedUp = ({
|
|
16
|
-
amr = [],
|
|
17
|
-
acr = '',
|
|
18
|
-
auth_time,
|
|
17
|
+
const isSteppedUp = (user, {
|
|
19
18
|
maxAge
|
|
20
19
|
} = {}) => {
|
|
20
|
+
if (!user) return false;
|
|
21
|
+
const {
|
|
22
|
+
amr = [],
|
|
23
|
+
acr = '',
|
|
24
|
+
auth_time
|
|
25
|
+
} = user;
|
|
21
26
|
if (maxAge && auth_time) {
|
|
22
27
|
// when user is logged in for a long time (more than maxAge, but jwt is still valid because it's not refreshed yet)
|
|
23
28
|
const isMaxAgeValid = Date.now() / 1000 - auth_time <= maxAge;
|
|
@@ -28,4 +33,28 @@ const isSteppedUp = ({
|
|
|
28
33
|
const isAMRIncludesMethod = _consts.AMR_ADDITIONAL_VALUE.find(method => amr.indexOf(method)) !== undefined;
|
|
29
34
|
return isACRValid && isAMRIncludesMFA && isAMRIncludesMethod;
|
|
30
35
|
};
|
|
31
|
-
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Set the url and query params in the local storage FRONTEGG_AFTER_AUTH_REDIRECT_URL value
|
|
39
|
+
*/
|
|
40
|
+
exports.isSteppedUp = isSteppedUp;
|
|
41
|
+
function setAfterAuthRedirectUrlForStepUp() {
|
|
42
|
+
const encodedRedirectUrl = window.location.pathname + window.location.search;
|
|
43
|
+
window.localStorage.setItem(_constants.FRONTEGG_AFTER_AUTH_REDIRECT_URL, encodedRedirectUrl);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Redirects to the step up url with the max age param and set the redirect url in the local storage
|
|
48
|
+
* The redirect url will be used after the step up flow is done
|
|
49
|
+
* @param stepUpUrl - step up url to redirect to
|
|
50
|
+
* @param onRedirectTo - redirect to function
|
|
51
|
+
* @param maxAge - max age of step up
|
|
52
|
+
*/
|
|
53
|
+
const redirectByStepUpUrl = (stepUpUrl, onRedirectTo, maxAge) => {
|
|
54
|
+
setAfterAuthRedirectUrlForStepUp();
|
|
55
|
+
const maxAgePart = maxAge !== undefined ? `?${_consts.STEP_UP_MAX_AGE_PARAM_NAME}=${maxAge}` : '';
|
|
56
|
+
onRedirectTo(`${stepUpUrl}${maxAgePart}`, {
|
|
57
|
+
refresh: false
|
|
58
|
+
});
|
|
59
|
+
};
|
|
60
|
+
exports.redirectByStepUpUrl = redirectByStepUpUrl;
|
package/node/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frontegg/redux-store",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.166.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.0.1",
|
|
10
|
-
"@frontegg/rest-api": "3.1.
|
|
10
|
+
"@frontegg/rest-api": "3.1.56",
|
|
11
11
|
"@reduxjs/toolkit": "1.8.5",
|
|
12
12
|
"fast-deep-equal": "3.1.3",
|
|
13
13
|
"redux-saga": "^1.2.1",
|