@frontegg/redux-store 6.155.0-alpha.0 → 6.155.0-alpha.2

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 (61) hide show
  1. package/auth/ActivateState/saga.js +3 -2
  2. package/auth/ApiTokensState/index.d.ts +0 -8
  3. package/auth/LoginState/index.d.ts +1 -1
  4. package/auth/LoginState/index.js +1 -1
  5. package/auth/LoginState/interfaces.d.ts +5 -0
  6. package/auth/LoginState/saga.d.ts +3 -17
  7. package/auth/LoginState/saga.js +19 -383
  8. package/auth/LoginState/saga.utils.d.ts +12 -0
  9. package/auth/LoginState/saga.utils.js +47 -0
  10. package/auth/LoginState/sagas/afterAuthNavigation.saga.d.ts +19 -0
  11. package/auth/LoginState/sagas/afterAuthNavigation.saga.js +82 -0
  12. package/auth/LoginState/sagas/handleVerifyMFAResponse.saga.d.ts +52 -0
  13. package/auth/LoginState/sagas/handleVerifyMFAResponse.saga.js +80 -0
  14. package/auth/LoginState/sagas/index.d.ts +7 -0
  15. package/auth/LoginState/sagas/index.js +7 -0
  16. package/auth/LoginState/{mfaRequiredState.saga.d.ts → sagas/mfaRequiredState.saga.d.ts} +3 -3
  17. package/auth/LoginState/{mfaRequiredState.saga.js → sagas/mfaRequiredState.saga.js} +3 -3
  18. package/auth/LoginState/sagas/mfaWithAuthenticator.saga.d.ts +40 -0
  19. package/auth/LoginState/sagas/mfaWithAuthenticator.saga.js +140 -0
  20. package/auth/LoginState/sagas/mfaWithEmailCode.saga.d.ts +71 -0
  21. package/auth/LoginState/sagas/mfaWithEmailCode.saga.js +96 -0
  22. package/auth/LoginState/sagas/mfaWithSMS.saga.d.ts +77 -0
  23. package/auth/LoginState/sagas/mfaWithSMS.saga.js +107 -0
  24. package/auth/LoginState/sagas/mfaWithWebAuthn.saga.d.ts +81 -0
  25. package/auth/LoginState/sagas/mfaWithWebAuthn.saga.js +119 -0
  26. package/auth/LoginState/utils.d.ts +2 -1
  27. package/auth/LoginState/utils.js +6 -1
  28. package/auth/MfaState/saga.js +1 -1
  29. package/auth/SignUp/saga.js +1 -1
  30. package/auth/StepUpState/index.d.ts +16 -3
  31. package/auth/StepUpState/index.js +22 -3
  32. package/auth/StepUpState/interfaces.d.ts +9 -0
  33. package/auth/StepUpState/saga.d.ts +131 -6
  34. package/auth/StepUpState/saga.js +110 -41
  35. package/auth/index.d.ts +6 -0
  36. package/auth/interfaces.d.ts +1 -0
  37. package/auth/reducer.d.ts +6 -0
  38. package/index.d.ts +1 -1
  39. package/index.js +2 -2
  40. package/node/auth/ActivateState/saga.js +3 -2
  41. package/node/auth/LoginState/index.js +6 -0
  42. package/node/auth/LoginState/saga.js +54 -410
  43. package/node/auth/LoginState/saga.utils.js +55 -0
  44. package/node/auth/LoginState/sagas/afterAuthNavigation.saga.js +89 -0
  45. package/node/auth/LoginState/sagas/handleVerifyMFAResponse.saga.js +87 -0
  46. package/node/auth/LoginState/sagas/index.js +82 -0
  47. package/node/auth/LoginState/{mfaRequiredState.saga.js → sagas/mfaRequiredState.saga.js} +3 -3
  48. package/node/auth/LoginState/sagas/mfaWithAuthenticator.saga.js +147 -0
  49. package/node/auth/LoginState/sagas/mfaWithEmailCode.saga.js +106 -0
  50. package/node/auth/LoginState/sagas/mfaWithSMS.saga.js +116 -0
  51. package/node/auth/LoginState/sagas/mfaWithWebAuthn.saga.js +128 -0
  52. package/node/auth/LoginState/utils.js +6 -1
  53. package/node/auth/MfaState/saga.js +1 -1
  54. package/node/auth/SignUp/saga.js +1 -1
  55. package/node/auth/StepUpState/index.js +21 -8
  56. package/node/auth/StepUpState/saga.js +115 -41
  57. package/node/index.js +5 -5
  58. package/package.json +1 -1
  59. package/auth/StepUpState/utils.d.ts +0 -3
  60. package/auth/StepUpState/utils.js +0 -10
  61. package/node/auth/StepUpState/utils.js +0 -19
@@ -7,13 +7,14 @@ const _excluded = ["callback", "events"],
7
7
  import { call, delay, put, select, takeLeading } from 'redux-saga/effects';
8
8
  import { api, ContextHolder } from '@frontegg/rest-api';
9
9
  import { actions } from '../reducer';
10
- import { afterAuthNavigation, afterAuthenticationStateUpdate } from '../LoginState/saga';
11
- import { getMfaRequiredState } from '../LoginState/mfaRequiredState.saga';
10
+ import { afterAuthNavigation } from '../LoginState/saga';
12
11
  import { UserVeirifedOriginTypes } from '../interfaces';
13
12
  import { ActivateAccountStep } from './interfaces';
14
13
  import { TeamStateKeys } from '../TeamState/interfaces';
15
14
  import { GTMEventAction, errorHandler, reportGTMEvent } from '../../utils';
16
15
  import { isMfaRequired } from '../LoginState/utils';
16
+ import { afterAuthenticationStateUpdate } from '../LoginState/saga.utils';
17
+ import { getMfaRequiredState } from '../LoginState/sagas/mfaRequiredState.saga';
17
18
  function* preActivateAccount({
18
19
  payload: {
19
20
  userId,
@@ -45,10 +45,6 @@ declare const reducers: {
45
45
  resetPhoneNumberState: import("..").ResetPhoneNumberState;
46
46
  ssoState: import("..").SSOState;
47
47
  profileState: import("..").ProfileState;
48
- /**
49
- * if you see error in matcher that's mean the DispatchAction does not
50
- * contains the same functions in reducers and actions
51
- */
52
48
  mfaState: import("..").MFAState;
53
49
  teamState: import("..").TeamState;
54
50
  groupsState: import("..").GroupsState;
@@ -97,10 +93,6 @@ declare const reducers: {
97
93
  resetPhoneNumberState: import("..").ResetPhoneNumberState;
98
94
  ssoState: import("..").SSOState;
99
95
  profileState: import("..").ProfileState;
100
- /**
101
- * if you see error in matcher that's mean the DispatchAction does not
102
- * contains the same functions in reducers and actions
103
- */
104
96
  mfaState: import("..").MFAState;
105
97
  teamState: import("..").TeamState;
106
98
  groupsState: import("..").GroupsState;
@@ -234,4 +234,4 @@ declare type DispatchedActions = {
234
234
  };
235
235
  export declare type LoginActions = DispatchedActions;
236
236
  export { loginState, reducers as loginReducers, actions as loginActions };
237
- export { getRedirectUrl } from './utils';
237
+ export { getRedirectUrl, getSearchParam } from './utils';
@@ -139,4 +139,4 @@ const actions = {
139
139
  */
140
140
  const Matcher = {};
141
141
  export { loginState, reducers as loginReducers, actions as loginActions };
142
- export { getRedirectUrl } from './utils';
142
+ export { getRedirectUrl, getSearchParam } from './utils';
@@ -98,6 +98,11 @@ export declare type IVerifyMFAWebAuthnPayload = WithCallback<WithDeviceId<Omit<I
98
98
  export interface IRecoverMFATokenPayload extends WithCallback<IRecoverMFAToken> {
99
99
  recaptchaToken?: string;
100
100
  }
101
+ /**
102
+ * Type for action to set the loading state
103
+ * @param options.loading - true if in loading state
104
+ * @param options.error - error if in error state
105
+ */
101
106
  export declare type SetLoadingAction = ({ loading, error }: {
102
107
  loading?: boolean;
103
108
  error?: unknown;
@@ -1,16 +1,6 @@
1
1
  import { CallEffect } from 'redux-saga/effects';
2
- import { ISamlMetadata, IWebAuthnDevices, ILoginResponseV3 } from '@frontegg/rest-api';
2
+ import { ISamlMetadata } from '@frontegg/rest-api';
3
3
  import { AuthState } from '../interfaces';
4
- export declare function afterAuthenticationStateUpdate({ user, tenants, activeTenant }: ILoginResponseV3, additionalUpdate?: Partial<AuthState>): Generator<import("redux-saga/effects").SelectEffect | import("redux-saga/effects").PutEffect<{
5
- payload: Partial<AuthState>;
6
- type: string;
7
- }>, void, AuthState>;
8
- export declare function afterAuthNavigation(): Generator<import("redux-saga/effects").SelectEffect | Promise<unknown> | CallEffect<void>, void, {
9
- routes: any;
10
- includeQueryParam: any;
11
- enforceRedirectToSameSite?: false | undefined;
12
- allowedRedirectOrigins?: never[] | undefined;
13
- } & string>;
14
4
  export declare function refreshMetadata(): Generator<import("redux-saga/effects").PutEffect<{
15
5
  payload: Partial<AuthState>;
16
6
  type: string;
@@ -25,11 +15,7 @@ export declare function loadSSOPublicConfigurationFunction(): Generator<import("
25
15
  }>;
26
16
  export declare function refreshToken(): Generator<import("redux-saga/effects").SelectEffect | CallEffect<any>, void, AuthState>;
27
17
  export declare function refreshTokenForSocialLogins(): Generator<import("redux-saga/effects").SelectEffect | CallEffect<any>, void, AuthState>;
28
- export declare function shouldShowPromptPasskeys(): Generator<import("redux-saga/effects").SelectEffect | CallEffect<boolean[]> | CallEffect<IWebAuthnDevices> | import("redux-saga/effects").PutEffect<{
29
- payload: Partial<import("../..").PasskeysState>;
30
- type: string;
31
- }>, boolean, {
32
- publicAuthStrategyPolicy: any;
33
- } & boolean[] & IWebAuthnDevices>;
34
18
  export declare function loginSagas(): Generator<import("redux-saga/effects").ForkEffect<never>, void, unknown>;
19
+ export { afterAuthNavigation } from './sagas/afterAuthNavigation.saga';
20
+ export { mfaWithAuthenticator } from './sagas/mfaWithAuthenticator.saga';
35
21
  export declare function loginSagasMock(): Generator<import("redux-saga/effects").ForkEffect<never>, void, unknown>;
@@ -14,35 +14,38 @@ const _excluded = ["callback"],
14
14
  _excluded12 = ["callback"],
15
15
  _excluded13 = ["callback"],
16
16
  _excluded14 = ["callback"],
17
- _excluded15 = ["callback"],
18
- _excluded16 = ["callback", "deviceId"],
19
- _excluded17 = ["callback"],
20
- _excluded18 = ["callback"],
21
- _excluded19 = ["callback", "deviceId"],
22
- _excluded20 = ["callback", "deviceId"],
23
- _excluded21 = ["callback", "deviceId"];
17
+ _excluded15 = ["callback"];
24
18
  import { all, call, put, select, takeLeading } from 'redux-saga/effects';
25
19
  import { api, AuthStrategyEnum, ContextHolder, fetch, WebAuthnDeviceType } from '@frontegg/rest-api';
26
20
  import { actions } from '../reducer';
27
- import { FRONTEGG_AFTER_AUTH_REDIRECT_URL, HOSTED_LOGIN_VERIFIER_KEY } from '../../constants';
21
+ import { HOSTED_LOGIN_VERIFIER_KEY } from '../../constants';
28
22
  import { UserVeirifedOriginTypes } from '../interfaces';
29
23
  import { LoginFlow, LoginStep } from './interfaces';
30
- import { getMfaRequiredState } from './mfaRequiredState.saga';
24
+ import { getMfaRequiredState } from './sagas/mfaRequiredState.saga';
31
25
  import { loadAllowSignUps } from '../SignUp/saga';
32
26
  import { MFAStep } from '../MfaState/interfaces';
33
27
  import { dummyIps, userDemo } from '../dummy';
34
28
  import { SamlVendors } from '../SSOState/interfaces';
35
29
  import { loadVendorPublicInfo } from '../../vendor/saga';
36
30
  import { createRandomString, generateCodeChallenge, getFeatureFlags } from '../../helpers';
37
- import { base64urlDecode, delay, publicKeyCredentialToJSON } from '../utils';
31
+ import { base64urlDecode, publicKeyCredentialToJSON } from '../utils';
38
32
  import { loadPublicAuthStrategiesPolicy } from '../Security/SecurityPolicyState/saga';
39
- import { getPasskeysVendorPolicy } from '../PasskeysState/helpers';
40
- import { getPathAndSearchParamsFromUrl, getRedirectUrl, getSearchParam, TENANT_ID_PARAM_KEY, isMfaRequired, isOauthCallbackRoute, isEmailPayload } from './utils';
33
+ import { getSearchParam, TENANT_ID_PARAM_KEY, isMfaRequired, isOauthCallbackRoute, isEmailPayload } from './utils';
41
34
  import { errorHandler, GTMEventAction, reportGTMEvent } from '../../utils';
42
35
  import { authStrategyLoginStepMap } from './consts';
43
36
  import { isEntitlementsDeeplyEqual } from '../Entitlements';
44
37
  import { customLoginEnabled, loadCustomLoginRoutes } from '../CustomLoginState/saga';
45
38
  import { FronteggNativeModule } from '../../toolkit';
39
+ import { afterAuthenticationStateUpdate, shouldShowPromptPasskeys } from './saga.utils';
40
+ import { afterAuthNavigation, loginWithMfa, preVerifyMFASMSForLogin, verifyMFASMSForLogin, preVerifyMFAWebAuthnForLogin, verifyMFAWebAuthnForLogin, preVerifyMFAEmailCodeForLogin, verifyMFAEmailCodeForLogin } from './sagas';
41
+
42
+ /******************************************************************
43
+ *** ****
44
+ *** PLEASE DO NOT ADD CODE TO THIS FILE ****
45
+ *** NEW SAGAS - ADD AS A NEW FILE IN THE SAGAS FOLDER ****
46
+ *** EXISTING SAGAS - MOVE TO THE SAGAS FOLDER WHEN TOUCHING IT ****
47
+ *** ****
48
+ *******************************************************************/
46
49
 
47
50
  /**
48
51
  * Prevent unnecessary entitlements reference update inside the user object by
@@ -64,65 +67,6 @@ function* handleUnnecessaryEntitlementsUpdate(updatedUser) {
64
67
  }
65
68
  return updatedUser;
66
69
  }
67
- export function* afterAuthenticationStateUpdate({
68
- user,
69
- tenants = [],
70
- activeTenant
71
- }, additionalUpdate = {}) {
72
- const {
73
- tenantsState: currentTenantsState
74
- } = yield select(state => state.auth);
75
- yield put(actions.setState(_extends({
76
- user,
77
- tenantsState: _extends({}, currentTenantsState, {
78
- tenants,
79
- activeTenant,
80
- loading: false
81
- })
82
- }, additionalUpdate)));
83
- }
84
- export function* afterAuthNavigation() {
85
- const onRedirectTo = ContextHolder.onRedirectTo;
86
- const {
87
- routes,
88
- includeQueryParam,
89
- enforceRedirectToSameSite = false,
90
- allowedRedirectOrigins = []
91
- } = yield select(state => state.auth);
92
- const {
93
- loginUrl,
94
- logoutUrl,
95
- socialLoginCallbackUrl,
96
- activateUrl
97
- } = routes;
98
- let {
99
- authenticatedUrl,
100
- customLoginAuthenticatedUrl
101
- } = routes;
102
- if (!customLoginAuthenticatedUrl) {
103
- yield call(loadCustomLoginRoutes);
104
- customLoginAuthenticatedUrl = yield select(state => {
105
- var _state$auth$routes;
106
- return (_state$auth$routes = state.auth.routes) == null ? void 0 : _state$auth$routes.customLoginAuthenticatedUrl;
107
- });
108
- }
109
- const afterAuthRedirect = window.localStorage.getItem(FRONTEGG_AFTER_AUTH_REDIRECT_URL);
110
- if (afterAuthRedirect && ![loginUrl, logoutUrl, socialLoginCallbackUrl, activateUrl].includes(afterAuthRedirect)) {
111
- authenticatedUrl = afterAuthRedirect;
112
- }
113
- window.localStorage.removeItem(FRONTEGG_AFTER_AUTH_REDIRECT_URL);
114
- yield delay(200);
115
- put(actions.resetLoginState());
116
- const redirectUrl = getRedirectUrl({
117
- authenticatedUrl: customLoginAuthenticatedUrl ? getPathAndSearchParamsFromUrl(customLoginAuthenticatedUrl) : authenticatedUrl,
118
- includeQueryParam,
119
- enforceRedirectToSameSite,
120
- allowedRedirectOrigins
121
- });
122
- onRedirectTo(redirectUrl, {
123
- refresh: redirectUrl.startsWith('http')
124
- });
125
- }
126
70
  export function* refreshMetadata() {
127
71
  let ssoACS;
128
72
  try {
@@ -783,30 +727,6 @@ function* passwordlessPreLogin(_ref7) {
783
727
  callback == null ? void 0 : callback();
784
728
  }
785
729
  }
786
- export function* shouldShowPromptPasskeys() {
787
- const {
788
- publicAuthStrategyPolicy
789
- } = yield select(state => state.auth.securityPolicyState);
790
- const {
791
- policy
792
- } = publicAuthStrategyPolicy;
793
- const isPasskeysEnabledByVendor = getPasskeysVendorPolicy(policy);
794
- const isLoggedInWithPasskeys = localStorage.getItem('preferred-login-method') === 'Passkeys';
795
- const isMarkedDontShowAgainPrompt = localStorage.getItem('dont-show-again-prompt-passkeys') === 'true';
796
- const [showPasskeys] = yield call(getFeatureFlags, ['show-passkeys-new']);
797
- if (!showPasskeys || !isPasskeysEnabledByVendor || isLoggedInWithPasskeys || isMarkedDontShowAgainPrompt) {
798
- return false;
799
- } else {
800
- const {
801
- devices
802
- } = yield call(api.auth.getWebAuthnDevices);
803
- yield put(actions.setPasskeysState({
804
- devices: devices != null ? devices : []
805
- }));
806
- const numOfDevices = !(devices != null && devices.length) ? 0 : devices.length;
807
- return numOfDevices === 0;
808
- }
809
- }
810
730
  function* passwordlessPostLogin(_ref8) {
811
731
  let {
812
732
  payload: {
@@ -1340,82 +1260,6 @@ function* login({
1340
1260
  }));
1341
1261
  }
1342
1262
  }
1343
- function* loginWithMfa({
1344
- payload: {
1345
- mfaToken,
1346
- value,
1347
- rememberDevice,
1348
- callback
1349
- }
1350
- }) {
1351
- yield put(actions.setLoginState({
1352
- loading: true
1353
- }));
1354
- try {
1355
- const {
1356
- user,
1357
- tenants = [],
1358
- activeTenant
1359
- } = yield call(api.auth.loginWithMfaV2, {
1360
- mfaToken,
1361
- value,
1362
- rememberDevice
1363
- });
1364
- const {
1365
- loginState
1366
- } = yield select(state => state.auth);
1367
- const step = loginState.flow === LoginFlow.Login ? LoginStep.success : loginState.step;
1368
- const isAuthenticated = !!user.accessToken;
1369
- yield call(afterAuthenticationStateUpdate, {
1370
- user,
1371
- tenants,
1372
- activeTenant
1373
- }, {
1374
- loginState: {
1375
- flow: loginState.flow,
1376
- quickLoginToRegister: loginState.quickLoginToRegister,
1377
- loading: false,
1378
- step,
1379
- error: undefined,
1380
- tenants
1381
- },
1382
- isAuthenticated
1383
- });
1384
- if (user.id) {
1385
- localStorage.setItem('userId', user.id);
1386
- }
1387
- yield put(actions.setLoginState({
1388
- error: undefined,
1389
- loading: false
1390
- }));
1391
- const [securityCenterLoginFlows] = yield call(getFeatureFlags, ['security-center-show-login-flows']);
1392
- if (loginState.flow === LoginFlow.Login) {
1393
- if (securityCenterLoginFlows && loginState.isBreachedPassword && !isAuthenticated) {
1394
- yield put(actions.setLoginState({
1395
- step: LoginStep.breachedPassword,
1396
- loading: false
1397
- }));
1398
- } else {
1399
- const shouldShowPrompt = yield call(shouldShowPromptPasskeys);
1400
- if (shouldShowPrompt) {
1401
- yield put(actions.setLoginState({
1402
- step: LoginStep.promptPasskeys,
1403
- loading: false
1404
- }));
1405
- } else {
1406
- yield afterAuthNavigation();
1407
- }
1408
- }
1409
- }
1410
- callback == null ? void 0 : callback(true);
1411
- } catch (e) {
1412
- yield put(actions.setLoginState({
1413
- error: errorHandler(e),
1414
- loading: false
1415
- }));
1416
- callback == null ? void 0 : callback(false, e);
1417
- }
1418
- }
1419
1263
  function* recoverMfa({
1420
1264
  payload
1421
1265
  }) {
@@ -1501,50 +1345,6 @@ function* handleEnrollMFAResponse({
1501
1345
  localStorage.setItem('userId', user.id);
1502
1346
  }
1503
1347
  }
1504
- function* handleVerifyMFAResponse({
1505
- user,
1506
- tenants,
1507
- activeTenant
1508
- }) {
1509
- const {
1510
- loginState
1511
- } = yield select(state => state.auth);
1512
- yield put(actions.setUser(user));
1513
- yield put(actions.setTenantsState({
1514
- tenants,
1515
- activeTenant,
1516
- loading: false
1517
- }));
1518
- if (user.id) {
1519
- localStorage.setItem('userId', user.id);
1520
- }
1521
- const {
1522
- step: mfaStep
1523
- } = yield select(state => state.auth.mfaState);
1524
- const [securityCenterLoginFlows] = yield call(getFeatureFlags, ['security-center-show-login-flows']);
1525
- const isAuthenticated = !!user.accessToken;
1526
- if (loginState.flow === LoginFlow.Login) {
1527
- if (securityCenterLoginFlows && loginState.isBreachedPassword && !isAuthenticated) {
1528
- yield put(actions.setLoginState({
1529
- step: LoginStep.breachedPassword,
1530
- loading: false
1531
- }));
1532
- } else {
1533
- const shouldShowPrompt = yield call(shouldShowPromptPasskeys);
1534
- if (mfaStep === MFAStep.smsVerifyCode && shouldShowPrompt) {
1535
- yield put(actions.setLoginState({
1536
- step: LoginStep.promptPasskeys,
1537
- loading: false
1538
- }));
1539
- } else {
1540
- yield afterAuthNavigation();
1541
- }
1542
- }
1543
- }
1544
- yield put(actions.setState({
1545
- isAuthenticated
1546
- }));
1547
- }
1548
1348
  function* preEnrollMFASMSForLogin(_ref13) {
1549
1349
  let {
1550
1350
  payload: {
@@ -1689,172 +1489,6 @@ function* enrollMFAAuthenticatorAppForLogin(_ref17) {
1689
1489
  callback == null ? void 0 : callback(null);
1690
1490
  }
1691
1491
  }
1692
- function* preVerifyMFASMSForLogin(_ref18) {
1693
- let {
1694
- payload: {
1695
- callback,
1696
- deviceId
1697
- }
1698
- } = _ref18,
1699
- payload = _objectWithoutPropertiesLoose(_ref18.payload, _excluded16);
1700
- yield put(actions.setLoginState({
1701
- loading: true
1702
- }));
1703
- try {
1704
- const data = yield call(api.auth.preVerifyMFASMSForLogin, deviceId, payload);
1705
- yield put(actions.setMfaState({
1706
- otcToken: data.otcToken,
1707
- step: MFAStep.smsVerifyCode,
1708
- phoneNumber: data.phoneNumber
1709
- }));
1710
- yield put(actions.setLoginState({
1711
- loading: false
1712
- }));
1713
- callback == null ? void 0 : callback(true);
1714
- } catch (e) {
1715
- yield put(actions.setLoginState({
1716
- loading: false,
1717
- error: errorHandler(e)
1718
- }));
1719
- callback == null ? void 0 : callback(null);
1720
- }
1721
- }
1722
- function* preVerifyMFAEmailCode(_ref19) {
1723
- let {
1724
- payload: {
1725
- callback
1726
- }
1727
- } = _ref19,
1728
- payload = _objectWithoutPropertiesLoose(_ref19.payload, _excluded17);
1729
- try {
1730
- const data = yield call(api.auth.preVerifyMFAEmailCode, payload);
1731
- yield put(actions.setMfaState({
1732
- otcToken: data.otcToken,
1733
- step: MFAStep.emailVerifyCode
1734
- }));
1735
- callback == null ? void 0 : callback(true);
1736
- } catch (e) {
1737
- yield put(actions.setLoginState({
1738
- error: errorHandler(e)
1739
- }));
1740
- callback == null ? void 0 : callback(null);
1741
- }
1742
- }
1743
- function* verifyMFAEmailCode(_ref20) {
1744
- let {
1745
- payload: {
1746
- callback
1747
- }
1748
- } = _ref20,
1749
- payload = _objectWithoutPropertiesLoose(_ref20.payload, _excluded18);
1750
- yield put(actions.setLoginState({
1751
- loading: true
1752
- }));
1753
- try {
1754
- const data = yield call(api.auth.verifyMFAEmailCodeV2, payload);
1755
- yield handleVerifyMFAResponse(data);
1756
- yield put(actions.setLoginState({
1757
- loading: false
1758
- }));
1759
- callback == null ? void 0 : callback(true);
1760
- } catch (e) {
1761
- yield put(actions.setLoginState({
1762
- loading: false,
1763
- error: errorHandler(e)
1764
- }));
1765
- callback == null ? void 0 : callback(null);
1766
- }
1767
- }
1768
- function* verifyMFASMSForLogin(_ref21) {
1769
- let {
1770
- payload: {
1771
- callback,
1772
- deviceId
1773
- }
1774
- } = _ref21,
1775
- payload = _objectWithoutPropertiesLoose(_ref21.payload, _excluded19);
1776
- yield put(actions.setLoginState({
1777
- loading: true
1778
- }));
1779
- try {
1780
- const data = yield call(api.auth.verifyMFASMSForLoginV2, deviceId, payload);
1781
- yield handleVerifyMFAResponse(data);
1782
- yield put(actions.setLoginState({
1783
- loading: false
1784
- }));
1785
- callback == null ? void 0 : callback(true);
1786
- } catch (e) {
1787
- yield put(actions.setLoginState({
1788
- loading: false,
1789
- error: errorHandler(e)
1790
- }));
1791
- callback == null ? void 0 : callback(null);
1792
- }
1793
- }
1794
- function* preVerifyMFAWebAuthnForLogin(_ref22) {
1795
- let {
1796
- payload: {
1797
- callback,
1798
- deviceId
1799
- }
1800
- } = _ref22,
1801
- payload = _objectWithoutPropertiesLoose(_ref22.payload, _excluded20);
1802
- yield put(actions.setLoginState({
1803
- loading: true
1804
- }));
1805
- try {
1806
- var _data$options$allowCr;
1807
- const data = yield call(api.auth.preVerifyMFAWebAuthnForLogin, deviceId, payload);
1808
- const options = _extends({}, data.options, {
1809
- challenge: base64urlDecode(data.options.challenge),
1810
- allowCredentials: (_data$options$allowCr = data.options.allowCredentials) == null ? void 0 : _data$options$allowCr.map(credentials => _extends({}, credentials, {
1811
- id: base64urlDecode(credentials.id)
1812
- }))
1813
- });
1814
- yield put(actions.setLoginState({
1815
- loading: false
1816
- }));
1817
- callback == null ? void 0 : callback({
1818
- options,
1819
- webauthnToken: data.webauthnToken
1820
- });
1821
- } catch (e) {
1822
- yield put(actions.setLoginState({
1823
- loading: false,
1824
- error: errorHandler(e)
1825
- }));
1826
- callback == null ? void 0 : callback(null);
1827
- }
1828
- }
1829
- function* verifyMFAWebAuthnForLogin(_ref23) {
1830
- let {
1831
- payload: {
1832
- callback,
1833
- deviceId
1834
- }
1835
- } = _ref23,
1836
- payload = _objectWithoutPropertiesLoose(_ref23.payload, _excluded21);
1837
- yield put(actions.setLoginState({
1838
- loading: true
1839
- }));
1840
- try {
1841
- const publicKey = publicKeyCredentialToJSON(payload.publicKey);
1842
- const data = yield call(api.auth.verifyMFAWebAuthnForLoginV2, deviceId, _extends({}, payload, {
1843
- options: publicKey
1844
- }));
1845
- yield handleVerifyMFAResponse(data);
1846
- yield put(actions.setLoginState({
1847
- loading: false
1848
- }));
1849
- callback == null ? void 0 : callback(true);
1850
- } catch (e) {
1851
- yield put(actions.setLoginState({
1852
- loading: false,
1853
- error: errorHandler(e)
1854
- }));
1855
- callback == null ? void 0 : callback(null);
1856
- }
1857
- }
1858
1492
  function* resetBreachedPassword({
1859
1493
  payload
1860
1494
  }) {
@@ -1912,10 +1546,12 @@ export function* loginSagas() {
1912
1546
  yield takeLeading(actions.verifyMFASMSForLogin, verifyMFASMSForLogin);
1913
1547
  yield takeLeading(actions.preVerifyMFAWebAuthnForLogin, preVerifyMFAWebAuthnForLogin);
1914
1548
  yield takeLeading(actions.verifyMFAWebAuthnForLogin, verifyMFAWebAuthnForLogin);
1915
- yield takeLeading(actions.preVerifyMFAEmailCode, preVerifyMFAEmailCode);
1916
- yield takeLeading(actions.verifyMFAEmailCode, verifyMFAEmailCode);
1549
+ yield takeLeading(actions.preVerifyMFAEmailCode, preVerifyMFAEmailCodeForLogin);
1550
+ yield takeLeading(actions.verifyMFAEmailCode, verifyMFAEmailCodeForLogin);
1917
1551
  yield takeLeading(actions.resetBreachedPassword, resetBreachedPassword);
1918
1552
  }
1553
+ export { afterAuthNavigation } from './sagas/afterAuthNavigation.saga';
1554
+ export { mfaWithAuthenticator } from './sagas/mfaWithAuthenticator.saga';
1919
1555
 
1920
1556
  /*********************************
1921
1557
  * Preview Sagas
@@ -0,0 +1,12 @@
1
+ import { ILoginResponseV3, IWebAuthnDevices } from '@frontegg/rest-api';
2
+ import { AuthState } from '../interfaces';
3
+ export declare function shouldShowPromptPasskeys(): Generator<import("redux-saga/effects").SelectEffect | import("redux-saga/effects").CallEffect<boolean[]> | import("redux-saga/effects").CallEffect<IWebAuthnDevices> | import("redux-saga/effects").PutEffect<{
4
+ payload: Partial<import("..").PasskeysState>;
5
+ type: string;
6
+ }>, boolean, {
7
+ publicAuthStrategyPolicy: any;
8
+ } & boolean[] & IWebAuthnDevices>;
9
+ export declare function afterAuthenticationStateUpdate({ user, tenants, activeTenant }: ILoginResponseV3, additionalUpdate?: Partial<AuthState>): Generator<import("redux-saga/effects").SelectEffect | import("redux-saga/effects").PutEffect<{
10
+ payload: Partial<AuthState>;
11
+ type: string;
12
+ }>, void, AuthState>;
@@ -0,0 +1,47 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import { call, put, select } from 'redux-saga/effects';
3
+ import { api } from '@frontegg/rest-api';
4
+ import { actions } from '../reducer';
5
+ import { getPasskeysVendorPolicy } from '../PasskeysState/helpers';
6
+ import { getFeatureFlags } from '../../helpers';
7
+ export function* shouldShowPromptPasskeys() {
8
+ const {
9
+ publicAuthStrategyPolicy
10
+ } = yield select(state => state.auth.securityPolicyState);
11
+ const {
12
+ policy
13
+ } = publicAuthStrategyPolicy;
14
+ const isPasskeysEnabledByVendor = getPasskeysVendorPolicy(policy);
15
+ const isLoggedInWithPasskeys = localStorage.getItem('preferred-login-method') === 'Passkeys';
16
+ const isMarkedDontShowAgainPrompt = localStorage.getItem('dont-show-again-prompt-passkeys') === 'true';
17
+ const [showPasskeys] = yield call(getFeatureFlags, ['show-passkeys-new']);
18
+ if (!showPasskeys || !isPasskeysEnabledByVendor || isLoggedInWithPasskeys || isMarkedDontShowAgainPrompt) {
19
+ return false;
20
+ } else {
21
+ const {
22
+ devices
23
+ } = yield call(api.auth.getWebAuthnDevices);
24
+ yield put(actions.setPasskeysState({
25
+ devices: devices != null ? devices : []
26
+ }));
27
+ const numOfDevices = !(devices != null && devices.length) ? 0 : devices.length;
28
+ return numOfDevices === 0;
29
+ }
30
+ }
31
+ export function* afterAuthenticationStateUpdate({
32
+ user,
33
+ tenants = [],
34
+ activeTenant
35
+ }, additionalUpdate = {}) {
36
+ const {
37
+ tenantsState: currentTenantsState
38
+ } = yield select(state => state.auth);
39
+ yield put(actions.setState(_extends({
40
+ user,
41
+ tenantsState: _extends({}, currentTenantsState, {
42
+ tenants,
43
+ activeTenant,
44
+ loading: false
45
+ })
46
+ }, additionalUpdate)));
47
+ }
@@ -0,0 +1,19 @@
1
+ import { Action } from '@reduxjs/toolkit';
2
+ /**
3
+ * Utility to share after auth navigation flow between login and step up
4
+ * @param resetStateAction reset state action
5
+ * @param customLoginAuthenticatedUrl custom login authenticated url if exists
6
+ */
7
+ export declare function afterAuthNavigationUtil(resetStateAction: () => Action, customLoginAuthenticatedUrl?: string): Generator<import("redux-saga/effects").CallEffect<true> | import("redux-saga/effects").CallEffect<string>, void, string>;
8
+ /**
9
+ * After auth navigation for login flow
10
+ */
11
+ export declare function afterAuthNavigation(): Generator<import("redux-saga/effects").SelectEffect | import("redux-saga/effects").CallEffect<void>, void, {
12
+ routes: {
13
+ customLoginAuthenticatedUrl: any;
14
+ };
15
+ } & string>;
16
+ /**
17
+ * After auth navigation for step up flow
18
+ */
19
+ export declare function afterStepUpAuthNavigation(): Generator<import("redux-saga/effects").CallEffect<void>, void, unknown>;