@frontegg/redux-store 7.59.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 +2 -2
- 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/helpers.d.ts +1 -1
- package/auth/helpers.js +1 -1
- package/auth/interfaces.d.ts +2 -0
- package/index.js +1 -1
- package/mocks/auth-mocks/loginActions.mocks.d.ts +1 -1
- package/node/auth/LoginState/actions/handleVerifyMFAResponse.actions.js +29 -12
- package/node/auth/LoginState/actions/index.js +1 -1
- package/node/auth/LoginState/actions/mfaWithAuthenticator.actions.js +26 -8
- package/node/auth/LoginState/helpers.js +6 -2
- package/node/auth/helpers.js +3 -3
- package/node/index.js +1 -1
- 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,7 +25,7 @@ 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';
|
|
@@ -506,7 +506,7 @@ export default ((store, api, sharedActions) => {
|
|
|
506
506
|
});
|
|
507
507
|
} else {
|
|
508
508
|
if (isAuthenticated) {
|
|
509
|
-
const shouldShowPasswordRotationPrompt = user
|
|
509
|
+
const shouldShowPasswordRotationPrompt = shouldShowPasswordRotationPromptFunc(user);
|
|
510
510
|
if (passwordRotationFlagEnabled && shouldShowPasswordRotationPrompt) {
|
|
511
511
|
setLoginState({
|
|
512
512
|
step: LoginStep.passwordRotationNotification,
|
|
@@ -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
|
};
|
package/auth/helpers.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
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
8
|
export declare const isResetPasswordRequired: (user: ILoginResponse, appName: string) => boolean;
|
|
9
9
|
export declare const mapMetaDataObjectToActions: (obj: any, path?: string[]) => CommitChangeDto[];
|
package/auth/helpers.js
CHANGED
|
@@ -4,9 +4,9 @@ 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) {
|
package/auth/interfaces.d.ts
CHANGED
|
@@ -129,6 +129,8 @@ export interface User extends IUserProfile {
|
|
|
129
129
|
resetToken?: string;
|
|
130
130
|
passwordExpiresIn?: number;
|
|
131
131
|
notificationPeriod?: number;
|
|
132
|
+
resetPasswordToken?: string;
|
|
133
|
+
userId?: string;
|
|
132
134
|
}
|
|
133
135
|
export interface Routes {
|
|
134
136
|
routes: AuthPageRoutes;
|
package/index.js
CHANGED
|
@@ -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>;
|
|
@@ -7,6 +7,7 @@ exports.default = _default;
|
|
|
7
7
|
var _restApi = require("@frontegg/rest-api");
|
|
8
8
|
var _interfaces = require("../../MfaState/interfaces");
|
|
9
9
|
var _interfaces2 = require("../interfaces");
|
|
10
|
+
var _helpers = require("../../helpers");
|
|
10
11
|
function _default(store, api, sharedActions) {
|
|
11
12
|
const actions = sharedActions;
|
|
12
13
|
|
|
@@ -31,26 +32,42 @@ function _default(store, api, sharedActions) {
|
|
|
31
32
|
* Additional steps for after MFA authentication with authenticator app handler for login flow
|
|
32
33
|
* @param isAuthenticated
|
|
33
34
|
*/
|
|
34
|
-
const postHandleVerifyMFAResponseForLogin = async isAuthenticated => {
|
|
35
|
+
const postHandleVerifyMFAResponseForLogin = async (isAuthenticated, user) => {
|
|
35
36
|
const loginState = store.auth.loginState;
|
|
36
37
|
const mfaStep = store.auth.mfaState.step;
|
|
37
|
-
const [securityCenterLoginFlows] = await getFeatureFlags(['security-center-show-login-flows']);
|
|
38
|
+
const [securityCenterLoginFlows, passwordRotationFlagEnabled] = await actions.getFeatureFlags(['security-center-show-login-flows', 'password-rotation']);
|
|
38
39
|
if (loginState.flow === _interfaces2.LoginFlow.Login) {
|
|
39
40
|
if (securityCenterLoginFlows && loginState.isBreachedPassword && !isAuthenticated) {
|
|
40
41
|
actions.setLoginState({
|
|
41
42
|
step: _interfaces2.LoginStep.breachedPassword,
|
|
42
43
|
loading: false
|
|
43
44
|
});
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (passwordRotationFlagEnabled && (0, _helpers.isResetPasswordRequired)(user, store.root.appName)) {
|
|
48
|
+
actions.setLoginState({
|
|
49
|
+
step: _interfaces2.LoginStep.passwordRotationExpired,
|
|
50
|
+
loading: false,
|
|
51
|
+
resetPasswordToken: user.resetPasswordToken,
|
|
52
|
+
userId: user.userId
|
|
53
|
+
});
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (passwordRotationFlagEnabled && (0, _helpers.shouldShowPasswordRotationPromptFunc)(user)) {
|
|
57
|
+
actions.setLoginState({
|
|
58
|
+
step: _interfaces2.LoginStep.passwordRotationNotification,
|
|
59
|
+
loading: false
|
|
60
|
+
});
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const shouldShowPasskeysPrompt = await actions.__shouldShowPromptPasskeys();
|
|
64
|
+
if (mfaStep === _interfaces.MFAStep.smsVerifyCode && shouldShowPasskeysPrompt) {
|
|
65
|
+
actions.setLoginState({
|
|
66
|
+
step: _interfaces2.LoginStep.promptPasskeys,
|
|
67
|
+
loading: false
|
|
68
|
+
});
|
|
44
69
|
} else {
|
|
45
|
-
|
|
46
|
-
if (mfaStep === _interfaces.MFAStep.smsVerifyCode && shouldShowPrompt) {
|
|
47
|
-
actions.setLoginState({
|
|
48
|
-
step: _interfaces2.LoginStep.promptPasskeys,
|
|
49
|
-
loading: false
|
|
50
|
-
});
|
|
51
|
-
} else {
|
|
52
|
-
await actions.afterAuthNavigation();
|
|
53
|
-
}
|
|
70
|
+
await actions.afterAuthNavigation();
|
|
54
71
|
}
|
|
55
72
|
}
|
|
56
73
|
};
|
|
@@ -87,7 +104,7 @@ function _default(store, api, sharedActions) {
|
|
|
87
104
|
if (isStepUp) {
|
|
88
105
|
return await postHandleVerifyMFAResponseForStepUp();
|
|
89
106
|
}
|
|
90
|
-
return await postHandleVerifyMFAResponseForLogin(isAuthenticated);
|
|
107
|
+
return await postHandleVerifyMFAResponseForLogin(isAuthenticated, user);
|
|
91
108
|
};
|
|
92
109
|
return {
|
|
93
110
|
postHandleVerifyMFAResponseForStepUp,
|
|
@@ -513,7 +513,7 @@ var _default = (store, api, sharedActions) => {
|
|
|
513
513
|
});
|
|
514
514
|
} else {
|
|
515
515
|
if (isAuthenticated) {
|
|
516
|
-
const shouldShowPasswordRotationPrompt =
|
|
516
|
+
const shouldShowPasswordRotationPrompt = (0, _helpers2.shouldShowPasswordRotationPromptFunc)(user);
|
|
517
517
|
if (passwordRotationFlagEnabled && shouldShowPasswordRotationPrompt) {
|
|
518
518
|
setLoginState({
|
|
519
519
|
step: _interfaces.LoginStep.passwordRotationNotification,
|
|
@@ -9,6 +9,7 @@ var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runt
|
|
|
9
9
|
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
10
10
|
var _interfaces = require("../interfaces");
|
|
11
11
|
var _helpers = require("../../../helpers");
|
|
12
|
+
var _helpers2 = require("../../helpers");
|
|
12
13
|
const _excluded = ["callback"];
|
|
13
14
|
var _default = (store, api, sharedActions) => {
|
|
14
15
|
const actions = sharedActions;
|
|
@@ -45,24 +46,41 @@ var _default = (store, api, sharedActions) => {
|
|
|
45
46
|
* Handle after MFA authentication with authenticator app for login
|
|
46
47
|
* @private
|
|
47
48
|
*/
|
|
48
|
-
async function __postLoginMfaAuthenticator(isAuthenticated, callback) {
|
|
49
|
+
async function __postLoginMfaAuthenticator(isAuthenticated, user, callback) {
|
|
49
50
|
const loginState = store.auth.loginState;
|
|
50
51
|
if (loginState.flow !== _interfaces.LoginFlow.Login) return;
|
|
51
|
-
const [securityCenterLoginFlows] = await actions.getFeatureFlags(['security-center-show-login-flows']);
|
|
52
|
+
const [securityCenterLoginFlows, passwordRotationFlagEnabled] = await actions.getFeatureFlags(['security-center-show-login-flows', 'password-rotation']);
|
|
52
53
|
if (securityCenterLoginFlows && loginState.isBreachedPassword && !isAuthenticated) {
|
|
53
54
|
actions.setLoginState({
|
|
54
55
|
step: _interfaces.LoginStep.breachedPassword,
|
|
55
56
|
loading: false
|
|
56
57
|
});
|
|
57
58
|
} else {
|
|
58
|
-
|
|
59
|
-
if (shouldShowPrompt) {
|
|
59
|
+
if (passwordRotationFlagEnabled && (0, _helpers2.isResetPasswordRequired)(user, store.root.appName)) {
|
|
60
60
|
actions.setLoginState({
|
|
61
|
-
step: _interfaces.LoginStep.
|
|
62
|
-
loading: false
|
|
61
|
+
step: _interfaces.LoginStep.passwordRotationExpired,
|
|
62
|
+
loading: false,
|
|
63
|
+
resetPasswordToken: user.resetPasswordToken,
|
|
64
|
+
userId: user.userId
|
|
63
65
|
});
|
|
64
66
|
} else {
|
|
65
|
-
|
|
67
|
+
const shouldShowPasswordRotationPrompt = (0, _helpers2.shouldShowPasswordRotationPromptFunc)(user);
|
|
68
|
+
if (passwordRotationFlagEnabled && shouldShowPasswordRotationPrompt) {
|
|
69
|
+
actions.setLoginState({
|
|
70
|
+
step: _interfaces.LoginStep.passwordRotationNotification,
|
|
71
|
+
loading: false
|
|
72
|
+
});
|
|
73
|
+
} else {
|
|
74
|
+
const shouldShowPrompt = await actions.__shouldShowPromptPasskeys();
|
|
75
|
+
if (shouldShowPrompt) {
|
|
76
|
+
actions.setLoginState({
|
|
77
|
+
step: _interfaces.LoginStep.promptPasskeys,
|
|
78
|
+
loading: false
|
|
79
|
+
});
|
|
80
|
+
} else {
|
|
81
|
+
await actions.afterAuthNavigation();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
66
84
|
}
|
|
67
85
|
}
|
|
68
86
|
callback == null ? void 0 : callback(true);
|
|
@@ -116,7 +134,7 @@ var _default = (store, api, sharedActions) => {
|
|
|
116
134
|
if (isStepUp) {
|
|
117
135
|
return await __postStepUpMfaAuthenticator(callback);
|
|
118
136
|
}
|
|
119
|
-
return await __postLoginMfaAuthenticator(isAuthenticated, callback);
|
|
137
|
+
return await __postLoginMfaAuthenticator(isAuthenticated, user, callback);
|
|
120
138
|
} catch (e) {
|
|
121
139
|
setLoadingAction({
|
|
122
140
|
loading: false,
|
|
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.isAbsoluteUrl = exports.getSearchParamsFromUrl = exports.getSearchParam = exports.getRedirectUrl = exports.getPathAndSearchParamsFromUrl = exports.getNumberOfMfaDevices = exports.getMfaStepForNotEnrolledUsers = exports.getMfaStepForEnrolledUsers = exports.getBaseNameWithoutSlashSuffix = exports.TENANT_ID_PARAM_KEY = void 0;
|
|
7
7
|
exports.isEmailPayload = isEmailPayload;
|
|
8
|
-
exports.isOauthCallbackRoute = void 0;
|
|
8
|
+
exports.shouldShowPasswordRotationPromptFunc = exports.isOauthCallbackRoute = void 0;
|
|
9
9
|
var _restApi = require("@frontegg/rest-api");
|
|
10
10
|
var _interfaces = require("../MfaState/interfaces");
|
|
11
11
|
const isAbsoluteUrl = path => {
|
|
@@ -151,4 +151,8 @@ const getBaseNameWithoutSlashSuffix = state => {
|
|
|
151
151
|
}
|
|
152
152
|
return basename;
|
|
153
153
|
};
|
|
154
|
-
exports.getBaseNameWithoutSlashSuffix = getBaseNameWithoutSlashSuffix;
|
|
154
|
+
exports.getBaseNameWithoutSlashSuffix = getBaseNameWithoutSlashSuffix;
|
|
155
|
+
const shouldShowPasswordRotationPromptFunc = user => {
|
|
156
|
+
return user.passwordExpiresIn !== undefined && user.notificationPeriod !== undefined && user.passwordExpiresIn <= user.notificationPeriod;
|
|
157
|
+
};
|
|
158
|
+
exports.shouldShowPasswordRotationPromptFunc = shouldShowPasswordRotationPromptFunc;
|
package/node/auth/helpers.js
CHANGED
|
@@ -17,7 +17,7 @@ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")
|
|
|
17
17
|
var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
|
|
18
18
|
var _restApi = require("@frontegg/rest-api");
|
|
19
19
|
var _consts = require("./LoginState/consts");
|
|
20
|
-
var _helpers = require("./
|
|
20
|
+
var _helpers = require("./Entitlements/helpers");
|
|
21
21
|
Object.keys(_helpers).forEach(function (key) {
|
|
22
22
|
if (key === "default" || key === "__esModule") return;
|
|
23
23
|
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
@@ -29,7 +29,7 @@ Object.keys(_helpers).forEach(function (key) {
|
|
|
29
29
|
}
|
|
30
30
|
});
|
|
31
31
|
});
|
|
32
|
-
var _helpers2 = require("./
|
|
32
|
+
var _helpers2 = require("./LoginState/helpers");
|
|
33
33
|
Object.keys(_helpers2).forEach(function (key) {
|
|
34
34
|
if (key === "default" || key === "__esModule") return;
|
|
35
35
|
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
@@ -41,7 +41,7 @@ Object.keys(_helpers2).forEach(function (key) {
|
|
|
41
41
|
}
|
|
42
42
|
});
|
|
43
43
|
});
|
|
44
|
-
var _helpers3 = require("./
|
|
44
|
+
var _helpers3 = require("./StepUpState/helpers");
|
|
45
45
|
Object.keys(_helpers3).forEach(function (key) {
|
|
46
46
|
if (key === "default" || key === "__esModule") return;
|
|
47
47
|
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
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.60.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.60.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",
|