@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
@@ -0,0 +1,9 @@
1
+ import { buildPasswordRotationActions } from '../../auth/PasswordRotationState';
2
+ import { PasswordRotationStep } from '../../toolkit';
3
+ import { mockActionsExpect } from '../helpers';
4
+ export default ((store, api, actions) => {
5
+ const originalActions = buildPasswordRotationActions(store, api, actions);
6
+ const mockedActions = mockActionsExpect(originalActions, ['setStep']);
7
+ mockedActions.setStep(PasswordRotationStep.success);
8
+ return mockedActions;
9
+ });
@@ -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
- const shouldShowPrompt = await actions.__shouldShowPromptPasskeys();
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,
@@ -472,50 +472,67 @@ var _default = (store, api, sharedActions) => {
472
472
  preserveQueryParams: true
473
473
  });
474
474
  } else {
475
- const loginState = store.auth.loginState;
476
- const isAuthenticated = !!user.accessToken;
477
- if (user.id) {
478
- localStorage.setItem('userId', user.id);
479
- }
480
- actions.afterAuthenticationStateUpdate({
481
- user,
482
- tenants,
483
- activeTenant
484
- }, {
485
- loginState: {
486
- flow: loginState.flow,
487
- quickLoginToRegister: loginState.quickLoginToRegister,
488
- email,
475
+ const [securityCenterLoginFlows, passwordRotationFlagEnabled] = await actions.getFeatureFlags(['security-center-show-login-flows', 'password-rotation']);
476
+ if (passwordRotationFlagEnabled && (0, _helpers3.isResetPasswordRequired)(user, store.root.appName)) {
477
+ setLoginState({
478
+ step: _interfaces.LoginStep.passwordRotationExpired,
489
479
  loading: false,
490
- error: undefined,
491
- mfaToken: user.mfaToken,
492
- step: loginState.flow === _interfaces.LoginFlow.Login ? _interfaces.LoginStep.success : loginState.step,
480
+ resetPasswordToken: user.resetPasswordToken,
481
+ userId: user.userId
482
+ });
483
+ } else {
484
+ const loginState = store.auth.loginState;
485
+ const isAuthenticated = !!user.accessToken;
486
+ if (user.id) {
487
+ localStorage.setItem('userId', user.id);
488
+ }
489
+ actions.afterAuthenticationStateUpdate({
490
+ user,
493
491
  tenants,
494
- tenantsLoading: true,
495
- isBreachedPassword: user.isBreachedPassword
496
- },
497
- isAuthenticated
498
- });
499
- const [securityCenterLoginFlows] = await actions.getFeatureFlags(['security-center-show-login-flows']);
500
- if (loginState.flow === _interfaces.LoginFlow.Login) {
501
- if (securityCenterLoginFlows && user.isBreachedPassword && !isAuthenticated) {
502
- setLoginState({
503
- step: _interfaces.LoginStep.breachedPassword,
504
- loading: false
505
- });
506
- } else {
507
- if (isAuthenticated) {
508
- const shouldShowPrompt = await actions.__shouldShowPromptPasskeys();
509
- if (shouldShowPrompt) {
510
- setLoginState({
511
- step: _interfaces.LoginStep.promptPasskeys,
512
- loading: false
513
- });
514
- onRedirectTo(routes.loginUrl, {
515
- preserveQueryParams: true
516
- });
517
- } else {
518
- await actions.afterAuthNavigation();
492
+ activeTenant
493
+ }, {
494
+ loginState: {
495
+ flow: loginState.flow,
496
+ quickLoginToRegister: loginState.quickLoginToRegister,
497
+ email,
498
+ loading: false,
499
+ error: undefined,
500
+ mfaToken: user.mfaToken,
501
+ step: loginState.flow === _interfaces.LoginFlow.Login ? _interfaces.LoginStep.success : loginState.step,
502
+ tenants,
503
+ tenantsLoading: true,
504
+ isBreachedPassword: user.isBreachedPassword
505
+ },
506
+ isAuthenticated
507
+ });
508
+ if (loginState.flow === _interfaces.LoginFlow.Login) {
509
+ if (securityCenterLoginFlows && user.isBreachedPassword && !isAuthenticated) {
510
+ setLoginState({
511
+ step: _interfaces.LoginStep.breachedPassword,
512
+ loading: false
513
+ });
514
+ } else {
515
+ if (isAuthenticated) {
516
+ const shouldShowPasswordRotationPrompt = (0, _helpers2.shouldShowPasswordRotationPromptFunc)(user);
517
+ if (passwordRotationFlagEnabled && shouldShowPasswordRotationPrompt) {
518
+ setLoginState({
519
+ step: _interfaces.LoginStep.passwordRotationNotification,
520
+ loading: false
521
+ });
522
+ } else {
523
+ const shouldShowPromptPasskeys = await actions.__shouldShowPromptPasskeys();
524
+ if (shouldShowPromptPasskeys) {
525
+ setLoginState({
526
+ step: _interfaces.LoginStep.promptPasskeys,
527
+ loading: false
528
+ });
529
+ onRedirectTo(routes.loginUrl, {
530
+ preserveQueryParams: true
531
+ });
532
+ } else {
533
+ await actions.afterAuthNavigation();
534
+ }
535
+ }
519
536
  }
520
537
  }
521
538
  }
@@ -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
- const shouldShowPrompt = await actions.__shouldShowPromptPasskeys();
59
- if (shouldShowPrompt) {
59
+ if (passwordRotationFlagEnabled && (0, _helpers2.isResetPasswordRequired)(user, store.root.appName)) {
60
60
  actions.setLoginState({
61
- step: _interfaces.LoginStep.promptPasskeys,
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
- await actions.afterAuthNavigation();
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;
@@ -29,6 +29,8 @@ exports.LoginStep = LoginStep;
29
29
  LoginStep["promptPasskeys"] = "promptPasskeys";
30
30
  LoginStep["breachedPassword"] = "breachedPassword";
31
31
  LoginStep["breachedPasswordSuccess"] = "breachedPasswordSuccess";
32
+ LoginStep["passwordRotationExpired"] = "passwordRotationExpired";
33
+ LoginStep["passwordRotationNotification"] = "passwordRotationNotification";
32
34
  LoginStep["magicLinkPostLoginSuccess"] = "magicLinkPostLoginSuccess";
33
35
  })(LoginStep || (exports.LoginStep = LoginStep = {}));
34
36
  let LoginFlow;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _default = (store, api, sharedActions) => {
8
+ const setPasswordRotationState = payload => {
9
+ Object.assign(store.auth.passwordRotationState, payload);
10
+ };
11
+ const setStep = step => {
12
+ setPasswordRotationState({
13
+ step
14
+ });
15
+ };
16
+ return {
17
+ setStep
18
+ };
19
+ };
20
+ exports.default = _default;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ Object.defineProperty(exports, "buildPasswordRotationActions", {
8
+ enumerable: true,
9
+ get: function () {
10
+ return _actions.default;
11
+ }
12
+ });
13
+ Object.defineProperty(exports, "createPasswordRotationState", {
14
+ enumerable: true,
15
+ get: function () {
16
+ return _state.default;
17
+ }
18
+ });
19
+ var _state = _interopRequireDefault(require("./state"));
20
+ var _actions = _interopRequireDefault(require("./actions"));
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.PasswordRotationStep = void 0;
7
+ let PasswordRotationStep;
8
+ exports.PasswordRotationStep = PasswordRotationStep;
9
+ (function (PasswordRotationStep) {
10
+ PasswordRotationStep["success"] = "success";
11
+ PasswordRotationStep["notification"] = "notification";
12
+ })(PasswordRotationStep || (exports.PasswordRotationStep = PasswordRotationStep = {}));
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.initialState = exports.default = void 0;
7
+ var _interfaces = require("./interfaces");
8
+ var _proxy = require("../../toolkit/proxy");
9
+ const initialState = {
10
+ step: _interfaces.PasswordRotationStep.notification
11
+ };
12
+ exports.initialState = initialState;
13
+ var _default = overrideState => (0, _proxy.createProxy)(initialState, overrideState);
14
+ exports.default = _default;
@@ -6,17 +6,18 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  var _exportNames = {
8
8
  isMfaRequired: true,
9
+ isResetPasswordRequired: true,
9
10
  mapMetaDataObjectToActions: true,
10
11
  getUri: true,
11
12
  extractPhoneNumber: true,
12
13
  isAuthRoute: true
13
14
  };
14
- exports.mapMetaDataObjectToActions = exports.isMfaRequired = exports.isAuthRoute = exports.getUri = exports.extractPhoneNumber = void 0;
15
+ exports.mapMetaDataObjectToActions = exports.isResetPasswordRequired = exports.isMfaRequired = exports.isAuthRoute = exports.getUri = exports.extractPhoneNumber = void 0;
15
16
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
16
17
  var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
17
18
  var _restApi = require("@frontegg/rest-api");
18
19
  var _consts = require("./LoginState/consts");
19
- var _helpers = require("./LoginState/helpers");
20
+ var _helpers = require("./Entitlements/helpers");
20
21
  Object.keys(_helpers).forEach(function (key) {
21
22
  if (key === "default" || key === "__esModule") return;
22
23
  if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
@@ -28,7 +29,7 @@ Object.keys(_helpers).forEach(function (key) {
28
29
  }
29
30
  });
30
31
  });
31
- var _helpers2 = require("./StepUpState/helpers");
32
+ var _helpers2 = require("./LoginState/helpers");
32
33
  Object.keys(_helpers2).forEach(function (key) {
33
34
  if (key === "default" || key === "__esModule") return;
34
35
  if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
@@ -40,7 +41,7 @@ Object.keys(_helpers2).forEach(function (key) {
40
41
  }
41
42
  });
42
43
  });
43
- var _helpers3 = require("./Entitlements/helpers");
44
+ var _helpers3 = require("./StepUpState/helpers");
44
45
  Object.keys(_helpers3).forEach(function (key) {
45
46
  if (key === "default" || key === "__esModule") return;
46
47
  if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
@@ -60,13 +61,23 @@ const isMfaRequired = (user, appName) => {
60
61
  contextHolder.setAccessToken(null);
61
62
  contextHolder.setUser(null);
62
63
  return true;
63
- } else {
64
- contextHolder.setAccessToken(user.accessToken);
65
- contextHolder.setUser(user);
66
- return false;
67
64
  }
65
+ contextHolder.setAccessToken(user.accessToken);
66
+ contextHolder.setUser(user);
67
+ return false;
68
68
  };
69
69
  exports.isMfaRequired = isMfaRequired;
70
+ const isResetPasswordRequired = (user, appName) => {
71
+ const contextHolder = _restApi.ContextHolder.for(appName);
72
+ if (user.resetPasswordToken) {
73
+ contextHolder.setAccessToken(null);
74
+ return true;
75
+ }
76
+ contextHolder.setAccessToken(user.accessToken);
77
+ contextHolder.setUser(user);
78
+ return false;
79
+ };
80
+ exports.isResetPasswordRequired = isResetPasswordRequired;
70
81
  const mapMetaDataObjectToActions = (obj, path = []) => {
71
82
  return Object.entries(obj).reduce((acc, [key, value]) => {
72
83
  if (typeof value === 'object') {