@frontegg/redux-store 7.58.0 → 7.60.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/handleVerifyMFAResponse.actions.d.ts +2 -2
- package/auth/LoginState/actions/handleVerifyMFAResponse.actions.js +29 -12
- package/auth/LoginState/actions/index.d.ts +2 -2
- package/auth/LoginState/actions/index.js +61 -44
- package/auth/LoginState/actions/mfaWithAuthenticator.actions.js +26 -8
- package/auth/LoginState/helpers.d.ts +4 -2
- package/auth/LoginState/helpers.js +3 -0
- package/auth/LoginState/interfaces.d.ts +6 -0
- package/auth/LoginState/interfaces.js +2 -0
- package/auth/PasswordRotationState/actions.d.ts +6 -0
- package/auth/PasswordRotationState/actions.js +13 -0
- package/auth/PasswordRotationState/index.d.ts +3 -0
- package/auth/PasswordRotationState/index.js +3 -0
- package/auth/PasswordRotationState/interfaces.d.ts +7 -0
- package/auth/PasswordRotationState/interfaces.js +5 -0
- package/auth/PasswordRotationState/state.d.ts +4 -0
- package/auth/PasswordRotationState/state.js +6 -0
- package/auth/helpers.d.ts +2 -1
- package/auth/helpers.js +14 -5
- package/auth/index.d.ts +5 -1
- package/auth/index.js +5 -0
- package/auth/interfaces.d.ts +7 -0
- package/index.js +1 -1
- package/mocks/auth-mocks/index.js +4 -1
- package/mocks/auth-mocks/loginActions.mocks.d.ts +1 -1
- package/mocks/auth-mocks/passwordRotationActions.mocks.d.ts +6 -0
- package/mocks/auth-mocks/passwordRotationActions.mocks.js +9 -0
- package/node/auth/LoginState/actions/handleVerifyMFAResponse.actions.js +29 -12
- package/node/auth/LoginState/actions/index.js +59 -42
- package/node/auth/LoginState/actions/mfaWithAuthenticator.actions.js +26 -8
- package/node/auth/LoginState/helpers.js +6 -2
- package/node/auth/LoginState/interfaces.js +2 -0
- package/node/auth/PasswordRotationState/actions.js +20 -0
- package/node/auth/PasswordRotationState/index.js +20 -0
- package/node/auth/PasswordRotationState/interfaces.js +12 -0
- package/node/auth/PasswordRotationState/state.js +14 -0
- package/node/auth/helpers.js +19 -8
- package/node/auth/index.js +40 -24
- package/node/index.js +1 -1
- package/node/mocks/auth-mocks/index.js +4 -1
- package/node/mocks/auth-mocks/passwordRotationActions.mocks.js +16 -0
- package/package.json +2 -2
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { ILoginResponseV3 } from '@frontegg/rest-api';
|
|
1
|
+
import { ILoginResponse, ILoginResponseV3 } from '@frontegg/rest-api';
|
|
2
2
|
import { FronteggState, RestApi, SharedActions } from '../../../interfaces';
|
|
3
3
|
export default function (store: FronteggState, api: RestApi, sharedActions: SharedActions): {
|
|
4
4
|
postHandleVerifyMFAResponseForStepUp: () => Promise<void>;
|
|
5
|
-
postHandleVerifyMFAResponseForLogin: (isAuthenticated: boolean) => Promise<void>;
|
|
5
|
+
postHandleVerifyMFAResponseForLogin: (isAuthenticated: boolean, user: ILoginResponse) => Promise<void>;
|
|
6
6
|
handleVerifyMFAResponse: (payload: ILoginResponseV3, isStepUp?: boolean) => Promise<void>;
|
|
7
7
|
getFeatureFlags: (flags: string[]) => Promise<boolean[]>;
|
|
8
8
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { FeatureFlags } from '@frontegg/rest-api';
|
|
2
2
|
import { MFAStep } from '../../MfaState/interfaces';
|
|
3
3
|
import { LoginFlow, LoginStep } from '../interfaces';
|
|
4
|
+
import { isResetPasswordRequired, shouldShowPasswordRotationPromptFunc } from '../../helpers';
|
|
4
5
|
export default function (store, api, sharedActions) {
|
|
5
6
|
const actions = sharedActions;
|
|
6
7
|
|
|
@@ -25,26 +26,42 @@ export default function (store, api, sharedActions) {
|
|
|
25
26
|
* Additional steps for after MFA authentication with authenticator app handler for login flow
|
|
26
27
|
* @param isAuthenticated
|
|
27
28
|
*/
|
|
28
|
-
const postHandleVerifyMFAResponseForLogin = async isAuthenticated => {
|
|
29
|
+
const postHandleVerifyMFAResponseForLogin = async (isAuthenticated, user) => {
|
|
29
30
|
const loginState = store.auth.loginState;
|
|
30
31
|
const mfaStep = store.auth.mfaState.step;
|
|
31
|
-
const [securityCenterLoginFlows] = await getFeatureFlags(['security-center-show-login-flows']);
|
|
32
|
+
const [securityCenterLoginFlows, passwordRotationFlagEnabled] = await actions.getFeatureFlags(['security-center-show-login-flows', 'password-rotation']);
|
|
32
33
|
if (loginState.flow === LoginFlow.Login) {
|
|
33
34
|
if (securityCenterLoginFlows && loginState.isBreachedPassword && !isAuthenticated) {
|
|
34
35
|
actions.setLoginState({
|
|
35
36
|
step: LoginStep.breachedPassword,
|
|
36
37
|
loading: false
|
|
37
38
|
});
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (passwordRotationFlagEnabled && isResetPasswordRequired(user, store.root.appName)) {
|
|
42
|
+
actions.setLoginState({
|
|
43
|
+
step: LoginStep.passwordRotationExpired,
|
|
44
|
+
loading: false,
|
|
45
|
+
resetPasswordToken: user.resetPasswordToken,
|
|
46
|
+
userId: user.userId
|
|
47
|
+
});
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (passwordRotationFlagEnabled && shouldShowPasswordRotationPromptFunc(user)) {
|
|
51
|
+
actions.setLoginState({
|
|
52
|
+
step: LoginStep.passwordRotationNotification,
|
|
53
|
+
loading: false
|
|
54
|
+
});
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const shouldShowPasskeysPrompt = await actions.__shouldShowPromptPasskeys();
|
|
58
|
+
if (mfaStep === MFAStep.smsVerifyCode && shouldShowPasskeysPrompt) {
|
|
59
|
+
actions.setLoginState({
|
|
60
|
+
step: LoginStep.promptPasskeys,
|
|
61
|
+
loading: false
|
|
62
|
+
});
|
|
38
63
|
} else {
|
|
39
|
-
|
|
40
|
-
if (mfaStep === MFAStep.smsVerifyCode && shouldShowPrompt) {
|
|
41
|
-
actions.setLoginState({
|
|
42
|
-
step: LoginStep.promptPasskeys,
|
|
43
|
-
loading: false
|
|
44
|
-
});
|
|
45
|
-
} else {
|
|
46
|
-
await actions.afterAuthNavigation();
|
|
47
|
-
}
|
|
64
|
+
await actions.afterAuthNavigation();
|
|
48
65
|
}
|
|
49
66
|
}
|
|
50
67
|
};
|
|
@@ -81,7 +98,7 @@ export default function (store, api, sharedActions) {
|
|
|
81
98
|
if (isStepUp) {
|
|
82
99
|
return await postHandleVerifyMFAResponseForStepUp();
|
|
83
100
|
}
|
|
84
|
-
return await postHandleVerifyMFAResponseForLogin(isAuthenticated);
|
|
101
|
+
return await postHandleVerifyMFAResponseForLogin(isAuthenticated, user);
|
|
85
102
|
};
|
|
86
103
|
return {
|
|
87
104
|
postHandleVerifyMFAResponseForStepUp,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FronteggState, RestApi, SharedActions, WithCallback } from '../../../interfaces';
|
|
2
2
|
import { FronteggNextJSSession, IEnrollMFAWebAuthnPayload, IPasswordlessPostLoginPayload, IPreEnrollMFAWebAuthNForLoginResponse, IQuickSmsPasswordlessPreLoginPayload, IRecoverMFATokenPayload, IVerifyNewWebAuthnDevicePayload, IWebAuthnPostLoginPayload, LoginState } from '../interfaces';
|
|
3
|
-
import { IChangePhoneNumberWithVerification, ICreateNewDeviceSessionResponse, IEnrollMFAAuthenticatorApp, IEnrollMFASMS, IForgotPassword, ILogin, ILoginResponseV3, IPasswordlessPreLogin, IPostLogin, IPreEnrollMFA, IPreEnrollMFASMS, IPreLogin, IVerifyChangePhoneNumber, IVerifyInviteToken, IWebAuthnPreLogin, IWebAuthnPreLoginResponse } from '@frontegg/rest-api';
|
|
3
|
+
import { IChangePhoneNumberWithVerification, ICreateNewDeviceSessionResponse, IEnrollMFAAuthenticatorApp, IEnrollMFASMS, IForgotPassword, ILogin, ILoginResponse, ILoginResponseV3, IPasswordlessPreLogin, IPostLogin, IPreEnrollMFA, IPreEnrollMFASMS, IPreLogin, IVerifyChangePhoneNumber, IVerifyInviteToken, IWebAuthnPreLogin, IWebAuthnPreLoginResponse } from '@frontegg/rest-api';
|
|
4
4
|
import { AuthState, UserIPData } from '../../interfaces';
|
|
5
5
|
import { MFAState } from '../../MfaState/interfaces';
|
|
6
6
|
declare const _default: (store: FronteggState, api: RestApi, sharedActions: SharedActions) => {
|
|
@@ -23,7 +23,7 @@ declare const _default: (store: FronteggState, api: RestApi, sharedActions: Shar
|
|
|
23
23
|
loginState: Partial<LoginState>;
|
|
24
24
|
}>;
|
|
25
25
|
postHandleVerifyMFAResponseForStepUp: () => Promise<void>;
|
|
26
|
-
postHandleVerifyMFAResponseForLogin: (isAuthenticated: boolean) => Promise<void>;
|
|
26
|
+
postHandleVerifyMFAResponseForLogin: (isAuthenticated: boolean, user: ILoginResponse) => Promise<void>;
|
|
27
27
|
handleVerifyMFAResponse: (payload: ILoginResponseV3, isStepUp?: boolean) => Promise<void>;
|
|
28
28
|
getFeatureFlags: (flags: string[]) => Promise<boolean[]>;
|
|
29
29
|
afterAuthNavigationUtil: (resetStateAction: (() => void) | (() => Promise<void>), options?: import("../interfaces").AfterAuthNavigationUtilOptions) => Promise<void>;
|
|
@@ -25,13 +25,13 @@ import mfaWithWebAuthnActions from './mfaWithWebAuthn.actions';
|
|
|
25
25
|
import { LoginFlow, LoginStep } from '../interfaces';
|
|
26
26
|
import { base64urlDecode, deepResetState, delay, errorHandler, errorTraceId, GTMEventAction, publicKeyCredentialToJSON, reportGTMEvent, retryIfNeeded, withRetryConfig } from '../../../helpers';
|
|
27
27
|
import { initialState } from '../state';
|
|
28
|
-
import { getSearchParam, isEmailPayload, TENANT_ID_PARAM_KEY } from '../helpers';
|
|
28
|
+
import { getSearchParam, isEmailPayload, shouldShowPasswordRotationPromptFunc, TENANT_ID_PARAM_KEY } from '../helpers';
|
|
29
29
|
import { AuthStrategyEnum, ContextHolder, removeTabTenantFromSessionStorage, WebAuthnDeviceType } from '@frontegg/rest-api';
|
|
30
30
|
import hostedLoginAuthorizeActions from './hostedLoginAuthorize.actions';
|
|
31
31
|
import { FronteggNativeModule, isEntitlementsDeeplyEqual } from '../../../toolkit';
|
|
32
32
|
import { REQUEST_NAME, UserVerifiedOriginTypes } from '../../interfaces';
|
|
33
33
|
import { authStrategyLoginStepMap } from '../consts';
|
|
34
|
-
import { isMfaRequired } from '../../helpers';
|
|
34
|
+
import { isMfaRequired, isResetPasswordRequired } from '../../helpers';
|
|
35
35
|
import { MFAStep } from '../../MfaState/interfaces';
|
|
36
36
|
import { SamlVendors } from '../../SSOState/interfaces';
|
|
37
37
|
import { DEFAULT_RETRY_CONFIG } from '../../../constants';
|
|
@@ -465,50 +465,67 @@ export default ((store, api, sharedActions) => {
|
|
|
465
465
|
preserveQueryParams: true
|
|
466
466
|
});
|
|
467
467
|
} else {
|
|
468
|
-
const
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
}
|
|
473
|
-
actions.afterAuthenticationStateUpdate({
|
|
474
|
-
user,
|
|
475
|
-
tenants,
|
|
476
|
-
activeTenant
|
|
477
|
-
}, {
|
|
478
|
-
loginState: {
|
|
479
|
-
flow: loginState.flow,
|
|
480
|
-
quickLoginToRegister: loginState.quickLoginToRegister,
|
|
481
|
-
email,
|
|
468
|
+
const [securityCenterLoginFlows, passwordRotationFlagEnabled] = await actions.getFeatureFlags(['security-center-show-login-flows', 'password-rotation']);
|
|
469
|
+
if (passwordRotationFlagEnabled && isResetPasswordRequired(user, store.root.appName)) {
|
|
470
|
+
setLoginState({
|
|
471
|
+
step: LoginStep.passwordRotationExpired,
|
|
482
472
|
loading: false,
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
473
|
+
resetPasswordToken: user.resetPasswordToken,
|
|
474
|
+
userId: user.userId
|
|
475
|
+
});
|
|
476
|
+
} else {
|
|
477
|
+
const loginState = store.auth.loginState;
|
|
478
|
+
const isAuthenticated = !!user.accessToken;
|
|
479
|
+
if (user.id) {
|
|
480
|
+
localStorage.setItem('userId', user.id);
|
|
481
|
+
}
|
|
482
|
+
actions.afterAuthenticationStateUpdate({
|
|
483
|
+
user,
|
|
486
484
|
tenants,
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
step: LoginStep.
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
485
|
+
activeTenant
|
|
486
|
+
}, {
|
|
487
|
+
loginState: {
|
|
488
|
+
flow: loginState.flow,
|
|
489
|
+
quickLoginToRegister: loginState.quickLoginToRegister,
|
|
490
|
+
email,
|
|
491
|
+
loading: false,
|
|
492
|
+
error: undefined,
|
|
493
|
+
mfaToken: user.mfaToken,
|
|
494
|
+
step: loginState.flow === LoginFlow.Login ? LoginStep.success : loginState.step,
|
|
495
|
+
tenants,
|
|
496
|
+
tenantsLoading: true,
|
|
497
|
+
isBreachedPassword: user.isBreachedPassword
|
|
498
|
+
},
|
|
499
|
+
isAuthenticated
|
|
500
|
+
});
|
|
501
|
+
if (loginState.flow === LoginFlow.Login) {
|
|
502
|
+
if (securityCenterLoginFlows && user.isBreachedPassword && !isAuthenticated) {
|
|
503
|
+
setLoginState({
|
|
504
|
+
step: LoginStep.breachedPassword,
|
|
505
|
+
loading: false
|
|
506
|
+
});
|
|
507
|
+
} else {
|
|
508
|
+
if (isAuthenticated) {
|
|
509
|
+
const shouldShowPasswordRotationPrompt = shouldShowPasswordRotationPromptFunc(user);
|
|
510
|
+
if (passwordRotationFlagEnabled && shouldShowPasswordRotationPrompt) {
|
|
511
|
+
setLoginState({
|
|
512
|
+
step: LoginStep.passwordRotationNotification,
|
|
513
|
+
loading: false
|
|
514
|
+
});
|
|
515
|
+
} else {
|
|
516
|
+
const shouldShowPromptPasskeys = await actions.__shouldShowPromptPasskeys();
|
|
517
|
+
if (shouldShowPromptPasskeys) {
|
|
518
|
+
setLoginState({
|
|
519
|
+
step: LoginStep.promptPasskeys,
|
|
520
|
+
loading: false
|
|
521
|
+
});
|
|
522
|
+
onRedirectTo(routes.loginUrl, {
|
|
523
|
+
preserveQueryParams: true
|
|
524
|
+
});
|
|
525
|
+
} else {
|
|
526
|
+
await actions.afterAuthNavigation();
|
|
527
|
+
}
|
|
528
|
+
}
|
|
512
529
|
}
|
|
513
530
|
}
|
|
514
531
|
}
|
|
@@ -3,6 +3,7 @@ import _extends from "@babel/runtime/helpers/esm/extends";
|
|
|
3
3
|
const _excluded = ["callback"];
|
|
4
4
|
import { LoginFlow, LoginStep } from '../interfaces';
|
|
5
5
|
import { errorHandler } from '../../../helpers';
|
|
6
|
+
import { isResetPasswordRequired, shouldShowPasswordRotationPromptFunc } from '../../helpers';
|
|
6
7
|
export default ((store, api, sharedActions) => {
|
|
7
8
|
const actions = sharedActions;
|
|
8
9
|
|
|
@@ -38,24 +39,41 @@ export default ((store, api, sharedActions) => {
|
|
|
38
39
|
* Handle after MFA authentication with authenticator app for login
|
|
39
40
|
* @private
|
|
40
41
|
*/
|
|
41
|
-
async function __postLoginMfaAuthenticator(isAuthenticated, callback) {
|
|
42
|
+
async function __postLoginMfaAuthenticator(isAuthenticated, user, callback) {
|
|
42
43
|
const loginState = store.auth.loginState;
|
|
43
44
|
if (loginState.flow !== LoginFlow.Login) return;
|
|
44
|
-
const [securityCenterLoginFlows] = await actions.getFeatureFlags(['security-center-show-login-flows']);
|
|
45
|
+
const [securityCenterLoginFlows, passwordRotationFlagEnabled] = await actions.getFeatureFlags(['security-center-show-login-flows', 'password-rotation']);
|
|
45
46
|
if (securityCenterLoginFlows && loginState.isBreachedPassword && !isAuthenticated) {
|
|
46
47
|
actions.setLoginState({
|
|
47
48
|
step: LoginStep.breachedPassword,
|
|
48
49
|
loading: false
|
|
49
50
|
});
|
|
50
51
|
} else {
|
|
51
|
-
|
|
52
|
-
if (shouldShowPrompt) {
|
|
52
|
+
if (passwordRotationFlagEnabled && isResetPasswordRequired(user, store.root.appName)) {
|
|
53
53
|
actions.setLoginState({
|
|
54
|
-
step: LoginStep.
|
|
55
|
-
loading: false
|
|
54
|
+
step: LoginStep.passwordRotationExpired,
|
|
55
|
+
loading: false,
|
|
56
|
+
resetPasswordToken: user.resetPasswordToken,
|
|
57
|
+
userId: user.userId
|
|
56
58
|
});
|
|
57
59
|
} else {
|
|
58
|
-
|
|
60
|
+
const shouldShowPasswordRotationPrompt = shouldShowPasswordRotationPromptFunc(user);
|
|
61
|
+
if (passwordRotationFlagEnabled && shouldShowPasswordRotationPrompt) {
|
|
62
|
+
actions.setLoginState({
|
|
63
|
+
step: LoginStep.passwordRotationNotification,
|
|
64
|
+
loading: false
|
|
65
|
+
});
|
|
66
|
+
} else {
|
|
67
|
+
const shouldShowPrompt = await actions.__shouldShowPromptPasskeys();
|
|
68
|
+
if (shouldShowPrompt) {
|
|
69
|
+
actions.setLoginState({
|
|
70
|
+
step: LoginStep.promptPasskeys,
|
|
71
|
+
loading: false
|
|
72
|
+
});
|
|
73
|
+
} else {
|
|
74
|
+
await actions.afterAuthNavigation();
|
|
75
|
+
}
|
|
76
|
+
}
|
|
59
77
|
}
|
|
60
78
|
}
|
|
61
79
|
callback == null ? void 0 : callback(true);
|
|
@@ -109,7 +127,7 @@ export default ((store, api, sharedActions) => {
|
|
|
109
127
|
if (isStepUp) {
|
|
110
128
|
return await __postStepUpMfaAuthenticator(callback);
|
|
111
129
|
}
|
|
112
|
-
return await __postLoginMfaAuthenticator(isAuthenticated, callback);
|
|
130
|
+
return await __postLoginMfaAuthenticator(isAuthenticated, user, callback);
|
|
113
131
|
} catch (e) {
|
|
114
132
|
setLoadingAction({
|
|
115
133
|
loading: false,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { IEmailPasswordlessPreLogin, IPasswordlessPreLogin, MFAStrategyEnum, UserMFADevicesResponse } from '@frontegg/rest-api';
|
|
2
|
-
import { MFAStep } from '../MfaState/interfaces';
|
|
1
|
+
import { IEmailPasswordlessPreLogin, ILoginResponse, IPasswordlessPreLogin, MFAStrategyEnum, UserMFADevicesResponse } from '@frontegg/rest-api';
|
|
3
2
|
import { FronteggState } from '../../interfaces';
|
|
3
|
+
import { User } from '../interfaces';
|
|
4
|
+
import { MFAStep } from '../MfaState/interfaces';
|
|
4
5
|
export declare const isAbsoluteUrl: (path: string) => boolean;
|
|
5
6
|
export declare const getRedirectUrl: ({ authenticatedUrl, enforceRedirectToSameSite, allowedRedirectOrigins, includeQueryParam, }: {
|
|
6
7
|
authenticatedUrl: string;
|
|
@@ -29,3 +30,4 @@ export declare const getMfaStepForNotEnrolledUsers: (mfaStrategies: MFAStrategyE
|
|
|
29
30
|
export declare const isOauthCallbackRoute: (activeUri: string) => boolean;
|
|
30
31
|
export declare function isEmailPayload(payload: IPasswordlessPreLogin): payload is IEmailPasswordlessPreLogin;
|
|
31
32
|
export declare const getBaseNameWithoutSlashSuffix: (state: FronteggState) => string | null;
|
|
33
|
+
export declare const shouldShowPasswordRotationPromptFunc: (user: ILoginResponse | User) => boolean;
|
|
@@ -132,4 +132,7 @@ export const getBaseNameWithoutSlashSuffix = state => {
|
|
|
132
132
|
return basename.slice(0, -1);
|
|
133
133
|
}
|
|
134
134
|
return basename;
|
|
135
|
+
};
|
|
136
|
+
export const shouldShowPasswordRotationPromptFunc = user => {
|
|
137
|
+
return user.passwordExpiresIn !== undefined && user.notificationPeriod !== undefined && user.passwordExpiresIn <= user.notificationPeriod;
|
|
135
138
|
};
|
|
@@ -17,6 +17,8 @@ export declare enum LoginStep {
|
|
|
17
17
|
'promptPasskeys' = "promptPasskeys",
|
|
18
18
|
'breachedPassword' = "breachedPassword",
|
|
19
19
|
'breachedPasswordSuccess' = "breachedPasswordSuccess",
|
|
20
|
+
'passwordRotationExpired' = "passwordRotationExpired",
|
|
21
|
+
'passwordRotationNotification' = "passwordRotationNotification",
|
|
20
22
|
'magicLinkPostLoginSuccess' = "magicLinkPostLoginSuccess"
|
|
21
23
|
}
|
|
22
24
|
export declare enum LoginFlow {
|
|
@@ -49,6 +51,10 @@ export interface LoginState {
|
|
|
49
51
|
quickLoginToRegister?: QuickLoginStrategy;
|
|
50
52
|
changePhoneId?: string;
|
|
51
53
|
isBreachedPassword?: boolean;
|
|
54
|
+
resetPasswordToken?: string;
|
|
55
|
+
passwordExpiresIn?: number;
|
|
56
|
+
notificationPeriod?: number;
|
|
57
|
+
userId?: string;
|
|
52
58
|
}
|
|
53
59
|
export interface HostedLoginCallback {
|
|
54
60
|
code: string;
|
|
@@ -16,6 +16,8 @@ export let LoginStep;
|
|
|
16
16
|
LoginStep["promptPasskeys"] = "promptPasskeys";
|
|
17
17
|
LoginStep["breachedPassword"] = "breachedPassword";
|
|
18
18
|
LoginStep["breachedPasswordSuccess"] = "breachedPasswordSuccess";
|
|
19
|
+
LoginStep["passwordRotationExpired"] = "passwordRotationExpired";
|
|
20
|
+
LoginStep["passwordRotationNotification"] = "passwordRotationNotification";
|
|
19
21
|
LoginStep["magicLinkPostLoginSuccess"] = "magicLinkPostLoginSuccess";
|
|
20
22
|
})(LoginStep || (LoginStep = {}));
|
|
21
23
|
export let LoginFlow;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { FronteggState, RestApi, SharedActions } from '../../interfaces';
|
|
2
|
+
import { PasswordRotationStep } from './interfaces';
|
|
3
|
+
declare const _default: (store: FronteggState, api: RestApi, sharedActions: SharedActions) => {
|
|
4
|
+
setStep: (step: PasswordRotationStep) => void;
|
|
5
|
+
};
|
|
6
|
+
export default _default;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export default ((store, api, sharedActions) => {
|
|
2
|
+
const setPasswordRotationState = payload => {
|
|
3
|
+
Object.assign(store.auth.passwordRotationState, payload);
|
|
4
|
+
};
|
|
5
|
+
const setStep = step => {
|
|
6
|
+
setPasswordRotationState({
|
|
7
|
+
step
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
return {
|
|
11
|
+
setStep
|
|
12
|
+
};
|
|
13
|
+
});
|
package/auth/helpers.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { CommitChangeDto, ILoginResponse, ISignUpUser } from '@frontegg/rest-api';
|
|
2
2
|
import { FronteggState } from '../interfaces';
|
|
3
3
|
import { AuthPageRoutes } from './interfaces';
|
|
4
|
+
export * from './Entitlements/helpers';
|
|
4
5
|
export * from './LoginState/helpers';
|
|
5
6
|
export * from './StepUpState/helpers';
|
|
6
|
-
export * from './Entitlements/helpers';
|
|
7
7
|
export declare const isMfaRequired: (user: ILoginResponse, appName: string) => boolean;
|
|
8
|
+
export declare const isResetPasswordRequired: (user: ILoginResponse, appName: string) => boolean;
|
|
8
9
|
export declare const mapMetaDataObjectToActions: (obj: any, path?: string[]) => CommitChangeDto[];
|
|
9
10
|
export declare const getUri: (urlStrategy: FronteggState["root"]["urlStrategy"]) => string;
|
|
10
11
|
export declare const extractPhoneNumber: ({ phoneNumber, ...rest }: ISignUpUser) => {
|
package/auth/helpers.js
CHANGED
|
@@ -4,20 +4,29 @@ const _excluded = ["phoneNumber"],
|
|
|
4
4
|
_excluded2 = ["authenticatedUrl"];
|
|
5
5
|
import { ContextHolder } from '@frontegg/rest-api';
|
|
6
6
|
import { defaultFronteggRoutes } from './LoginState/consts';
|
|
7
|
+
export * from './Entitlements/helpers';
|
|
7
8
|
export * from './LoginState/helpers';
|
|
8
9
|
export * from './StepUpState/helpers';
|
|
9
|
-
export * from './Entitlements/helpers';
|
|
10
10
|
export const isMfaRequired = (user, appName) => {
|
|
11
11
|
const contextHolder = ContextHolder.for(appName);
|
|
12
12
|
if (user.mfaRequired && user.mfaToken) {
|
|
13
13
|
contextHolder.setAccessToken(null);
|
|
14
14
|
contextHolder.setUser(null);
|
|
15
15
|
return true;
|
|
16
|
-
} else {
|
|
17
|
-
contextHolder.setAccessToken(user.accessToken);
|
|
18
|
-
contextHolder.setUser(user);
|
|
19
|
-
return false;
|
|
20
16
|
}
|
|
17
|
+
contextHolder.setAccessToken(user.accessToken);
|
|
18
|
+
contextHolder.setUser(user);
|
|
19
|
+
return false;
|
|
20
|
+
};
|
|
21
|
+
export const isResetPasswordRequired = (user, appName) => {
|
|
22
|
+
const contextHolder = ContextHolder.for(appName);
|
|
23
|
+
if (user.resetPasswordToken) {
|
|
24
|
+
contextHolder.setAccessToken(null);
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
contextHolder.setAccessToken(user.accessToken);
|
|
28
|
+
contextHolder.setUser(user);
|
|
29
|
+
return false;
|
|
21
30
|
};
|
|
22
31
|
export const mapMetaDataObjectToActions = (obj, path = []) => {
|
|
23
32
|
return Object.entries(obj).reduce((acc, [key, value]) => {
|
package/auth/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { buildApiTokensActions } from './ApiTokensState';
|
|
|
8
8
|
import { buildApplicationsActions } from './ApplicationsState';
|
|
9
9
|
import { buildCustomLoginActions } from './CustomLoginState';
|
|
10
10
|
import { buildForgotPasswordActions } from './ForgotPasswordState';
|
|
11
|
+
import { buildPasswordRotationActions } from './PasswordRotationState';
|
|
11
12
|
import { buildGroupsActions } from './GroupsState';
|
|
12
13
|
import { buildGroupsDialogsActions } from './GroupsDialogsState';
|
|
13
14
|
import { buildImpersonateActions } from './ImpersonateState';
|
|
@@ -42,6 +43,7 @@ export * from './CustomLoginState/interfaces';
|
|
|
42
43
|
export * from './Entitlements/interfaces';
|
|
43
44
|
export * from './Entitlements/helpers';
|
|
44
45
|
export * from './ForgotPasswordState/interfaces';
|
|
46
|
+
export * from './PasswordRotationState/interfaces';
|
|
45
47
|
export * from './GroupsState/interfaces';
|
|
46
48
|
export * from './GroupsDialogsState/interfaces';
|
|
47
49
|
export * from './ImpersonateState/interfaces';
|
|
@@ -77,6 +79,7 @@ export type ApplicationsActions = ReturnType<typeof buildApplicationsActions>;
|
|
|
77
79
|
export type CustomLoginActions = ReturnType<typeof buildCustomLoginActions>;
|
|
78
80
|
export type EntitlementsActions = ReturnType<typeof buildEntitlementsActions>;
|
|
79
81
|
export type ForgotPasswordActions = ReturnType<typeof buildForgotPasswordActions>;
|
|
82
|
+
export type PasswordRotationActions = ReturnType<typeof buildPasswordRotationActions>;
|
|
80
83
|
export type GroupsActions = ReturnType<typeof buildGroupsActions>;
|
|
81
84
|
export type GroupsDialogsActions = ReturnType<typeof buildGroupsDialogsActions>;
|
|
82
85
|
export type ImpersonateActions = ReturnType<typeof buildImpersonateActions>;
|
|
@@ -111,6 +114,7 @@ export type AuthStateActions = {
|
|
|
111
114
|
customLoginActions: CustomLoginActions;
|
|
112
115
|
entitlementsActions: EntitlementsActions;
|
|
113
116
|
forgotPasswordActions: ForgotPasswordActions;
|
|
117
|
+
passwordRotationActions: PasswordRotationActions;
|
|
114
118
|
groupsActions: GroupsActions;
|
|
115
119
|
groupsDialogsActions: GroupsDialogsActions;
|
|
116
120
|
impersonateActions: ImpersonateActions;
|
|
@@ -143,4 +147,4 @@ export type AuthActions = {
|
|
|
143
147
|
setErrorByRequestName: (payload: SingleErrorByRequestDataPayload) => void;
|
|
144
148
|
resetAuthState: () => void;
|
|
145
149
|
setUser: (user: User | null) => void;
|
|
146
|
-
} & AcceptInvitationActions & AccountSettingsActions & UnlockAccountActions & ActivateAccountActions & ApiTokensActions & ApplicationsActions & CustomLoginActions & EntitlementsActions & ForgotPasswordActions & GroupsActions & GroupsDialogsActions & ImpersonateActions & LoginActions & MfaActions & AllAccountsActions & AllAccountsDialogActions & PasskeysActions & ProfileActions & ProvisioningActions & ResetPhoneNumberActions & RolesActions & RestrictionsActions & SecurityCenterActions & SecurityPolicyActions & SessionsPolicyActions & SessionsActions & SignUpActions & SmsActions & SocialLoginActions & SSOActions & StepUpActions & TeamActions & TenantsActions;
|
|
150
|
+
} & AcceptInvitationActions & AccountSettingsActions & UnlockAccountActions & ActivateAccountActions & ApiTokensActions & ApplicationsActions & CustomLoginActions & EntitlementsActions & ForgotPasswordActions & PasswordRotationActions & GroupsActions & GroupsDialogsActions & ImpersonateActions & LoginActions & MfaActions & AllAccountsActions & AllAccountsDialogActions & PasskeysActions & ProfileActions & ProvisioningActions & ResetPhoneNumberActions & RolesActions & RestrictionsActions & SecurityCenterActions & SecurityPolicyActions & SessionsPolicyActions & SessionsActions & SignUpActions & SmsActions & SocialLoginActions & SSOActions & StepUpActions & TeamActions & TenantsActions;
|
package/auth/index.js
CHANGED
|
@@ -10,6 +10,7 @@ import { buildApiTokensActions, createApiTokensState } from './ApiTokensState';
|
|
|
10
10
|
import { buildApplicationsActions, createApplicationsState } from './ApplicationsState';
|
|
11
11
|
import { buildCustomLoginActions, createCustomLoginState } from './CustomLoginState';
|
|
12
12
|
import { buildForgotPasswordActions, createForgotPasswordState } from './ForgotPasswordState';
|
|
13
|
+
import { buildPasswordRotationActions, createPasswordRotationState } from './PasswordRotationState';
|
|
13
14
|
import { buildGroupsActions, createGroupsState } from './GroupsState';
|
|
14
15
|
import { buildGroupsDialogsActions, createGroupsDialogsState } from './GroupsDialogsState';
|
|
15
16
|
import { buildImpersonateActions, createImpersonateState } from './ImpersonateState';
|
|
@@ -47,6 +48,7 @@ export * from './CustomLoginState/interfaces';
|
|
|
47
48
|
export * from './Entitlements/interfaces';
|
|
48
49
|
export * from './Entitlements/helpers';
|
|
49
50
|
export * from './ForgotPasswordState/interfaces';
|
|
51
|
+
export * from './PasswordRotationState/interfaces';
|
|
50
52
|
export * from './GroupsState/interfaces';
|
|
51
53
|
export * from './GroupsDialogsState/interfaces';
|
|
52
54
|
export * from './ImpersonateState/interfaces';
|
|
@@ -100,6 +102,7 @@ export const createAuthState = _overrideState => {
|
|
|
100
102
|
applicationsState: createApplicationsState(overrideState == null ? void 0 : overrideState.applicationsState),
|
|
101
103
|
customLoginState: createCustomLoginState(overrideState == null ? void 0 : overrideState.customLoginState),
|
|
102
104
|
forgotPasswordState: createForgotPasswordState(overrideState == null ? void 0 : overrideState.forgotPasswordState),
|
|
105
|
+
passwordRotationState: createPasswordRotationState(overrideState == null ? void 0 : overrideState.passwordRotationState),
|
|
103
106
|
groupsState: createGroupsState(overrideState == null ? void 0 : overrideState.groupsState),
|
|
104
107
|
groupsDialogsState: createGroupsDialogsState(overrideState == null ? void 0 : overrideState.groupsDialogsState),
|
|
105
108
|
impersonateState: createImpersonateState(overrideState == null ? void 0 : overrideState.impersonateState),
|
|
@@ -165,6 +168,7 @@ export const buildAuthActions = (store, api, actions, snapshotAuthState) => {
|
|
|
165
168
|
const customLoginActions = buildCustomLoginActions(store, api, actions);
|
|
166
169
|
const entitlementsActions = buildEntitlementsActions(store, api, actions);
|
|
167
170
|
const forgotPasswordActions = buildForgotPasswordActions(store, api, actions);
|
|
171
|
+
const passwordRotationActions = buildPasswordRotationActions(store, api, actions);
|
|
168
172
|
const groupsActions = buildGroupsActions(store, api, actions);
|
|
169
173
|
const groupsDialogsActions = buildGroupsDialogsActions(store, api, actions);
|
|
170
174
|
const impersonateActions = buildImpersonateActions(store, api, actions);
|
|
@@ -199,6 +203,7 @@ export const buildAuthActions = (store, api, actions, snapshotAuthState) => {
|
|
|
199
203
|
customLoginActions,
|
|
200
204
|
entitlementsActions,
|
|
201
205
|
forgotPasswordActions,
|
|
206
|
+
passwordRotationActions,
|
|
202
207
|
groupsActions,
|
|
203
208
|
groupsDialogsActions,
|
|
204
209
|
impersonateActions,
|
package/auth/interfaces.d.ts
CHANGED
|
@@ -30,6 +30,7 @@ import type { TenantsState } from './TenantsState/interfaces';
|
|
|
30
30
|
import type { IAllAccountsDialogsState, IAllAccountsState } from './MSP/interfaces';
|
|
31
31
|
import { ApplicationsState } from './ApplicationsState/interfaces';
|
|
32
32
|
import { UnlockAccountState } from './UnlockAccountState/interfaces';
|
|
33
|
+
import { PasswordRotationState } from '../toolkit';
|
|
33
34
|
export declare enum REQUEST_NAME {
|
|
34
35
|
LOAD_FEATURE_FLAGS = "LOAD_FEATURE_FLAGS,",
|
|
35
36
|
LOAD_ADMIN_BOX_METADATA = "LOAD_ADMIN_BOX_METADATA,",
|
|
@@ -80,6 +81,7 @@ export interface AuthState extends Routes, PluginOptions {
|
|
|
80
81
|
apiTokensState: ApiTokensState;
|
|
81
82
|
customLoginState: CustomLoginState;
|
|
82
83
|
forgotPasswordState: ForgotPasswordState;
|
|
84
|
+
passwordRotationState: PasswordRotationState;
|
|
83
85
|
groupsState: GroupsState;
|
|
84
86
|
groupsDialogsState: GroupsDialogsState;
|
|
85
87
|
impersonateState: ImpersonateState;
|
|
@@ -124,6 +126,11 @@ export interface User extends IUserProfile {
|
|
|
124
126
|
amr?: string[];
|
|
125
127
|
acr?: string;
|
|
126
128
|
auth_time?: number;
|
|
129
|
+
resetToken?: string;
|
|
130
|
+
passwordExpiresIn?: number;
|
|
131
|
+
notificationPeriod?: number;
|
|
132
|
+
resetPasswordToken?: string;
|
|
133
|
+
userId?: string;
|
|
127
134
|
}
|
|
128
135
|
export interface Routes {
|
|
129
136
|
routes: AuthPageRoutes;
|
package/index.js
CHANGED
|
@@ -12,6 +12,7 @@ import buildApplicationsActions from './applicationsActions.mocks';
|
|
|
12
12
|
import buildCustomLoginActions from './customLoginActions.mocks';
|
|
13
13
|
import buildEntitlementsActions from './entitlementsActions.mocks';
|
|
14
14
|
import buildForgotPasswordActions from './forgotPasswordActions.mocks';
|
|
15
|
+
import buildPasswordRotationActions from './passwordRotationActions.mocks';
|
|
15
16
|
import buildGroupsActions from './groupsActions.mocks';
|
|
16
17
|
/* contains reducers only no need to mock */
|
|
17
18
|
import { buildGroupsDialogsActions } from '../../auth/GroupsDialogsState';
|
|
@@ -49,6 +50,7 @@ export const buildAuthActions = (store, api, actions, snapshotAuthState) => {
|
|
|
49
50
|
const customLoginActions = buildCustomLoginActions(store, api, actions);
|
|
50
51
|
const entitlementsActions = buildEntitlementsActions(store, api, actions);
|
|
51
52
|
const forgotPasswordActions = buildForgotPasswordActions(store, api, actions);
|
|
53
|
+
const passwordRotationActions = buildPasswordRotationActions(store, api, actions);
|
|
52
54
|
const groupsActions = buildGroupsActions(store, api, actions);
|
|
53
55
|
const groupsDialogsActions = buildGroupsDialogsActions(store, api, actions);
|
|
54
56
|
const impersonateActions = buildImpersonateActions(store, api, actions);
|
|
@@ -83,6 +85,7 @@ export const buildAuthActions = (store, api, actions, snapshotAuthState) => {
|
|
|
83
85
|
customLoginActions,
|
|
84
86
|
entitlementsActions,
|
|
85
87
|
forgotPasswordActions,
|
|
88
|
+
passwordRotationActions,
|
|
86
89
|
groupsActions,
|
|
87
90
|
groupsDialogsActions,
|
|
88
91
|
impersonateActions,
|
|
@@ -142,7 +145,7 @@ export const buildAuthActions = (store, api, actions, snapshotAuthState) => {
|
|
|
142
145
|
setErrorByRequestName,
|
|
143
146
|
resetAuthState,
|
|
144
147
|
setUser
|
|
145
|
-
}, acceptInvitationActions, accountSettingsActions, activateAccountActions, unlockAccountActions, allAccountsActions, allAccountsDialogActions, apiTokensActions, applicationsActions, customLoginActions, entitlementsActions, forgotPasswordActions, groupsActions, groupsDialogsActions, impersonateActions, loginActions, mfaActions, passkeysActions, profileActions, provisioningActions, resetPhoneNumberActions, restrictionsActions, rolesActions, securityCenterActions, securityPolicyActions, sessionsActions, sessionsPolicyActions, signUpActions, smsActions, socialLoginActions, ssoActions, stepUpActions, teamActions, tenantsActions);
|
|
148
|
+
}, acceptInvitationActions, accountSettingsActions, activateAccountActions, unlockAccountActions, allAccountsActions, allAccountsDialogActions, apiTokensActions, applicationsActions, customLoginActions, entitlementsActions, forgotPasswordActions, passwordRotationActions, groupsActions, groupsDialogsActions, impersonateActions, loginActions, mfaActions, passkeysActions, profileActions, provisioningActions, resetPhoneNumberActions, restrictionsActions, rolesActions, securityCenterActions, securityPolicyActions, sessionsActions, sessionsPolicyActions, signUpActions, smsActions, socialLoginActions, ssoActions, stepUpActions, teamActions, tenantsActions);
|
|
146
149
|
return {
|
|
147
150
|
authActions,
|
|
148
151
|
authStateActions
|
|
@@ -19,7 +19,7 @@ declare const _default: (store: FronteggState, api: RestApi, sharedActions: Shar
|
|
|
19
19
|
loginState: Partial<import("../..").LoginState>;
|
|
20
20
|
}>;
|
|
21
21
|
postHandleVerifyMFAResponseForStepUp: () => Promise<void>;
|
|
22
|
-
postHandleVerifyMFAResponseForLogin: (isAuthenticated: boolean) => Promise<void>;
|
|
22
|
+
postHandleVerifyMFAResponseForLogin: (isAuthenticated: boolean, user: import("dist/@frontegg/rest-api").ILoginResponse) => Promise<void>;
|
|
23
23
|
handleVerifyMFAResponse: (payload: import("dist/@frontegg/rest-api").ILoginResponseV3, isStepUp?: boolean) => Promise<void>;
|
|
24
24
|
getFeatureFlags: (flags: string[]) => Promise<boolean[]>;
|
|
25
25
|
afterAuthNavigationUtil: (resetStateAction: (() => void) | (() => Promise<void>), options?: import("../..").AfterAuthNavigationUtilOptions) => Promise<void>;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { FronteggState, RestApi, SharedActions } from '../../interfaces';
|
|
2
|
+
import { PasswordRotationStep } from '../../toolkit';
|
|
3
|
+
declare const _default: (store: FronteggState, api: RestApi, actions: SharedActions) => {
|
|
4
|
+
setStep: (step: PasswordRotationStep) => void;
|
|
5
|
+
};
|
|
6
|
+
export default _default;
|