@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.
Files changed (42) hide show
  1. package/auth/LoginState/actions/handleVerifyMFAResponse.actions.d.ts +2 -2
  2. package/auth/LoginState/actions/handleVerifyMFAResponse.actions.js +29 -12
  3. package/auth/LoginState/actions/index.d.ts +2 -2
  4. package/auth/LoginState/actions/index.js +61 -44
  5. package/auth/LoginState/actions/mfaWithAuthenticator.actions.js +26 -8
  6. package/auth/LoginState/helpers.d.ts +4 -2
  7. package/auth/LoginState/helpers.js +3 -0
  8. package/auth/LoginState/interfaces.d.ts +6 -0
  9. package/auth/LoginState/interfaces.js +2 -0
  10. package/auth/PasswordRotationState/actions.d.ts +6 -0
  11. package/auth/PasswordRotationState/actions.js +13 -0
  12. package/auth/PasswordRotationState/index.d.ts +3 -0
  13. package/auth/PasswordRotationState/index.js +3 -0
  14. package/auth/PasswordRotationState/interfaces.d.ts +7 -0
  15. package/auth/PasswordRotationState/interfaces.js +5 -0
  16. package/auth/PasswordRotationState/state.d.ts +4 -0
  17. package/auth/PasswordRotationState/state.js +6 -0
  18. package/auth/helpers.d.ts +2 -1
  19. package/auth/helpers.js +14 -5
  20. package/auth/index.d.ts +5 -1
  21. package/auth/index.js +5 -0
  22. package/auth/interfaces.d.ts +7 -0
  23. package/index.js +1 -1
  24. package/mocks/auth-mocks/index.js +4 -1
  25. package/mocks/auth-mocks/loginActions.mocks.d.ts +1 -1
  26. package/mocks/auth-mocks/passwordRotationActions.mocks.d.ts +6 -0
  27. package/mocks/auth-mocks/passwordRotationActions.mocks.js +9 -0
  28. package/node/auth/LoginState/actions/handleVerifyMFAResponse.actions.js +29 -12
  29. package/node/auth/LoginState/actions/index.js +59 -42
  30. package/node/auth/LoginState/actions/mfaWithAuthenticator.actions.js +26 -8
  31. package/node/auth/LoginState/helpers.js +6 -2
  32. package/node/auth/LoginState/interfaces.js +2 -0
  33. package/node/auth/PasswordRotationState/actions.js +20 -0
  34. package/node/auth/PasswordRotationState/index.js +20 -0
  35. package/node/auth/PasswordRotationState/interfaces.js +12 -0
  36. package/node/auth/PasswordRotationState/state.js +14 -0
  37. package/node/auth/helpers.js +19 -8
  38. package/node/auth/index.js +40 -24
  39. package/node/index.js +1 -1
  40. package/node/mocks/auth-mocks/index.js +4 -1
  41. package/node/mocks/auth-mocks/passwordRotationActions.mocks.js +16 -0
  42. 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
- const shouldShowPrompt = await actions.__shouldShowPromptPasskeys();
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 loginState = store.auth.loginState;
469
- const isAuthenticated = !!user.accessToken;
470
- if (user.id) {
471
- localStorage.setItem('userId', user.id);
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
- error: undefined,
484
- mfaToken: user.mfaToken,
485
- step: loginState.flow === LoginFlow.Login ? LoginStep.success : loginState.step,
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
- tenantsLoading: true,
488
- isBreachedPassword: user.isBreachedPassword
489
- },
490
- isAuthenticated
491
- });
492
- const [securityCenterLoginFlows] = await actions.getFeatureFlags(['security-center-show-login-flows']);
493
- if (loginState.flow === LoginFlow.Login) {
494
- if (securityCenterLoginFlows && user.isBreachedPassword && !isAuthenticated) {
495
- setLoginState({
496
- step: LoginStep.breachedPassword,
497
- loading: false
498
- });
499
- } else {
500
- if (isAuthenticated) {
501
- const shouldShowPrompt = await actions.__shouldShowPromptPasskeys();
502
- if (shouldShowPrompt) {
503
- setLoginState({
504
- step: LoginStep.promptPasskeys,
505
- loading: false
506
- });
507
- onRedirectTo(routes.loginUrl, {
508
- preserveQueryParams: true
509
- });
510
- } else {
511
- await actions.afterAuthNavigation();
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
- const shouldShowPrompt = await actions.__shouldShowPromptPasskeys();
52
- if (shouldShowPrompt) {
52
+ if (passwordRotationFlagEnabled && isResetPasswordRequired(user, store.root.appName)) {
53
53
  actions.setLoginState({
54
- step: LoginStep.promptPasskeys,
55
- loading: false
54
+ step: LoginStep.passwordRotationExpired,
55
+ loading: false,
56
+ resetPasswordToken: user.resetPasswordToken,
57
+ userId: user.userId
56
58
  });
57
59
  } else {
58
- await actions.afterAuthNavigation();
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
+ });
@@ -0,0 +1,3 @@
1
+ import createPasswordRotationState from './state';
2
+ import buildPasswordRotationActions from './actions';
3
+ export { createPasswordRotationState, buildPasswordRotationActions };
@@ -0,0 +1,3 @@
1
+ import createPasswordRotationState from './state';
2
+ import buildPasswordRotationActions from './actions';
3
+ export { createPasswordRotationState, buildPasswordRotationActions };
@@ -0,0 +1,7 @@
1
+ export declare enum PasswordRotationStep {
2
+ 'success' = "success",
3
+ 'notification' = "notification"
4
+ }
5
+ export interface PasswordRotationState {
6
+ step: PasswordRotationStep;
7
+ }
@@ -0,0 +1,5 @@
1
+ export let PasswordRotationStep;
2
+ (function (PasswordRotationStep) {
3
+ PasswordRotationStep["success"] = "success";
4
+ PasswordRotationStep["notification"] = "notification";
5
+ })(PasswordRotationStep || (PasswordRotationStep = {}));
@@ -0,0 +1,4 @@
1
+ import { PasswordRotationState } from './interfaces';
2
+ export declare const initialState: PasswordRotationState;
3
+ declare const _default: (overrideState?: Partial<PasswordRotationState>) => PasswordRotationState;
4
+ export default _default;
@@ -0,0 +1,6 @@
1
+ import { PasswordRotationStep } from './interfaces';
2
+ import { createProxy } from '../../toolkit/proxy';
3
+ export const initialState = {
4
+ step: PasswordRotationStep.notification
5
+ };
6
+ export default (overrideState => createProxy(initialState, overrideState));
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,
@@ -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
@@ -1,4 +1,4 @@
1
- /** @license Frontegg v7.58.0
1
+ /** @license Frontegg v7.60.0-alpha.0
2
2
  *
3
3
  * This source code is licensed under the MIT license found in the
4
4
  * LICENSE file in the root directory of this source tree.
@@ -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;