@frontegg/redux-store 4.39.1 → 4.39.2-dashboard

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/audits/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { b as auditsStoreName } from '../constants-f7891ee3.js';
2
- export { b as auditsStoreName } from '../constants-f7891ee3.js';
1
+ import { b as auditsStoreName } from '../constants-4d9682b2.js';
2
+ export { b as auditsStoreName } from '../constants-4d9682b2.js';
3
3
  import { createAction, createSlice } from '@reduxjs/toolkit';
4
4
  import { takeEvery, select as select$1, put, call, all } from 'redux-saga/effects';
5
5
  import { api } from '@frontegg/rest-api';
@@ -1,5 +1,5 @@
1
1
  import { ILogin, ILoginWithMfa, IPasswordlessPostLogin, IPasswordlessPreLogin, IPostLogin, IPreLogin, IRecoverMFAToken } from '@frontegg/rest-api';
2
- import { LoginState } from './interfaces';
2
+ import { HostedLoginCallback, LoginState } from './interfaces';
3
3
  import { WithCallback } from '../../interfaces';
4
4
  import { IVerifyInviteToken } from '@frontegg/rest-api';
5
5
  declare const loginState: LoginState;
@@ -71,6 +71,8 @@ declare const reducers: {
71
71
  };
72
72
  declare const actions: {
73
73
  requestAuthorize: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[(boolean | undefined)?], boolean, string, never, never>;
74
+ requestHostedLoginAuthorize: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<string>;
75
+ handleHostedLoginCallback: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[HostedLoginCallback], HostedLoginCallback, string, never, never>;
74
76
  afterAuthNavigation: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<string>;
75
77
  preLogin: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[WithCallback<IPreLogin & {
76
78
  recaptchaToken?: string | undefined;
@@ -100,6 +102,8 @@ declare type DispatchedActions = {
100
102
  setLoginState: (state: Partial<LoginState>) => void;
101
103
  resetLoginState: () => void;
102
104
  requestAuthorize: (payload?: boolean) => void;
105
+ requestHostedLoginAuthorize: () => void;
106
+ handleHostedLoginCallback: (payload: HostedLoginCallback) => void;
103
107
  afterAuthNavigation: () => void;
104
108
  preLogin: (payload: WithCallback<IPreLogin & {
105
109
  recaptchaToken?: string;
@@ -28,3 +28,8 @@ export interface LoginState {
28
28
  inviteTokenError?: string;
29
29
  isNewUser?: boolean;
30
30
  }
31
+ export interface HostedLoginCallback {
32
+ code: string;
33
+ state?: string;
34
+ nonce?: string;
35
+ }
@@ -1,5 +1,5 @@
1
1
  import { CallEffect } from 'redux-saga/effects';
2
- import { ILoginResponse, ISamlMetadata, IAllowedToRememberMfaDevice } from '@frontegg/rest-api';
2
+ import { IAllowedToRememberMfaDevice, ILoginResponse, ISamlMetadata } from '@frontegg/rest-api';
3
3
  import { AuthState } from '../interfaces';
4
4
  import { LoginStep } from './interfaces';
5
5
  export declare function afterAuthNavigation(): Generator<import("redux-saga/effects").SelectEffect | CallEffect<true>, void, {
@@ -19,7 +19,7 @@ export declare function loadSSOPublicConfigurationFunction(): Generator<import("
19
19
  isActive: any;
20
20
  }>;
21
21
  export declare const isMfaRequired: (user: ILoginResponse) => boolean;
22
- export declare function getMfaRequiredState(user: any): Generator<CallEffect<IAllowedToRememberMfaDevice>, {
22
+ export declare function getMfaRequiredState(user: any): Generator<import("redux-saga/effects").SelectEffect | CallEffect<IAllowedToRememberMfaDevice>, {
23
23
  loginState: {
24
24
  mfaToken: any;
25
25
  mfaRequired: any;
@@ -30,10 +30,15 @@ export declare function getMfaRequiredState(user: any): Generator<CallEffect<IAl
30
30
  tenants: never[];
31
31
  allowRememberMfaDevice: any;
32
32
  mfaDeviceExpiration: any;
33
+ ssoRedirectUrl?: string | undefined;
34
+ email?: string | undefined;
35
+ inviteTokenTenantName?: string | undefined;
36
+ inviteTokenError?: string | undefined;
37
+ isNewUser?: boolean | undefined;
33
38
  };
34
39
  user: undefined;
35
40
  isAuthenticated: boolean;
36
- }, {
41
+ }, AuthState & {
37
42
  isAllowedToRemember: any;
38
43
  mfaDeviceExpiration: any;
39
44
  }>;
@@ -43,7 +48,7 @@ export declare function refreshToken(): Generator<import("redux-saga/effects").S
43
48
  }> | import("redux-saga/effects").PutEffect<{
44
49
  payload: Partial<AuthState>;
45
50
  type: string;
46
- }> | Generator<CallEffect<IAllowedToRememberMfaDevice>, {
51
+ }> | Generator<import("redux-saga/effects").SelectEffect | CallEffect<IAllowedToRememberMfaDevice>, {
47
52
  loginState: {
48
53
  mfaToken: any;
49
54
  mfaRequired: any;
@@ -54,10 +59,15 @@ export declare function refreshToken(): Generator<import("redux-saga/effects").S
54
59
  tenants: never[];
55
60
  allowRememberMfaDevice: any;
56
61
  mfaDeviceExpiration: any;
62
+ ssoRedirectUrl?: string | undefined;
63
+ email?: string | undefined;
64
+ inviteTokenTenantName?: string | undefined;
65
+ inviteTokenError?: string | undefined;
66
+ isNewUser?: boolean | undefined;
57
67
  };
58
68
  user: undefined;
59
69
  isAuthenticated: boolean;
60
- }, {
70
+ }, AuthState & {
61
71
  isAllowedToRemember: any;
62
72
  mfaDeviceExpiration: any;
63
73
  }> | CallEffect<ILoginResponse> | import("redux-saga/effects").PutEffect<{
@@ -65,9 +75,7 @@ export declare function refreshToken(): Generator<import("redux-saga/effects").S
65
75
  callback?: ((data: import("@frontegg/rest-api").ITenantsResponse[] | null, error?: string | undefined) => void) | undefined;
66
76
  } | undefined;
67
77
  type: string;
68
- }>, void, {
69
- routes: any;
70
- } & import("@frontegg/rest-api").IUserProfile & {
78
+ }>, void, AuthState & import("@frontegg/rest-api").IUserProfile & {
71
79
  mfaRequired: boolean;
72
80
  accessToken: string;
73
81
  refreshToken: string;
package/auth/index.d.ts CHANGED
@@ -170,6 +170,8 @@ declare const _default: {
170
170
  loginViaSocialLogin: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[import("@frontegg/rest-api").ILoginViaSocialLogin], import("@frontegg/rest-api").ILoginViaSocialLogin, string, never, never>;
171
171
  setSocialLoginError: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[import("@frontegg/rest-api").ISetSocialLoginError], import("@frontegg/rest-api").ISetSocialLoginError, string, never, never>;
172
172
  requestAuthorize: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[(boolean | undefined)?], boolean, string, never, never>;
173
+ requestHostedLoginAuthorize: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<string>;
174
+ handleHostedLoginCallback: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[import("./LoginState/interfaces").HostedLoginCallback], import("./LoginState/interfaces").HostedLoginCallback, string, never, never>;
173
175
  afterAuthNavigation: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<string>;
174
176
  preLogin: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[import("../interfaces").WithCallback<import("@frontegg/rest-api").IPreLogin & {
175
177
  recaptchaToken?: string | undefined;
package/auth/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import { createAction, createSlice } from '@reduxjs/toolkit';
2
- import { a as authStoreName, F as FRONTEGG_AFTER_AUTH_REDIRECT_URL } from '../constants-f7891ee3.js';
3
- export { a as authStoreName } from '../constants-f7891ee3.js';
4
- import { __rest } from 'tslib';
2
+ import { a as authStoreName, F as FRONTEGG_AFTER_AUTH_REDIRECT_URL, H as HOSTED_LOGIN_VERIFIER_KEY } from '../constants-4d9682b2.js';
3
+ export { a as authStoreName } from '../constants-4d9682b2.js';
4
+ import { __awaiter, __rest } from 'tslib';
5
5
  import { takeLeading, put, select, call, takeEvery, delay as delay$1, all, retry, takeLatest } from 'redux-saga/effects';
6
6
  import { AuthStrategyEnum, api, ContextHolder } from '@frontegg/rest-api';
7
7
  export { AuthStrategyEnum } from '@frontegg/rest-api';
8
- import { l as loadVendorPublicInfo } from '../saga-afaced62.js';
8
+ import { l as loadVendorPublicInfo } from '../saga-b6529ffb.js';
9
9
  import { v4 } from 'uuid';
10
10
 
11
11
  const resetStateByKey = (key, initialState) => (state) => (Object.assign(Object.assign({}, state), { [key]: initialState[key] }));
@@ -65,6 +65,8 @@ const reducers$e = {
65
65
  };
66
66
  const actions$f = {
67
67
  requestAuthorize: createAction(`${authStoreName}/requestAuthorize`, (payload = false) => ({ payload })),
68
+ requestHostedLoginAuthorize: createAction(`${authStoreName}/requestHostedLoginAuthorize`),
69
+ handleHostedLoginCallback: createAction(`${authStoreName}/handleHostedLoginCallback`, (payload) => ({ payload })),
68
70
  afterAuthNavigation: createAction(`${authStoreName}/afterAuthNavigation`),
69
71
  preLogin: createAction(`${authStoreName}/preLogin`, (payload) => ({ payload })),
70
72
  postLogin: createAction(`${authStoreName}/postLogin`, (payload) => ({ payload })),
@@ -479,7 +481,8 @@ const initialState = Object.assign({ routes: {
479
481
  socialLoginCallbackUrl: '/account/social/success',
480
482
  signUpUrl: '/account/sign-up',
481
483
  oidcRedirectUrl: '/account/oidc/callback',
482
- magicLinkCallbackUrl: '/account/login/magic-link'
484
+ magicLinkCallbackUrl: '/account/login/magic-link',
485
+ hostedLoginRedirectUrl: '/oauth/callback'
483
486
  }, onRedirectTo: () => { } }, reinitializeState);
484
487
 
485
488
  const { reducer, actions: sliceActions } = createSlice({
@@ -505,6 +508,24 @@ function omitProps(props, keys) {
505
508
  });
506
509
  return newProps;
507
510
  }
511
+ function generateCodeChallenge(codeVerifier) {
512
+ return __awaiter(this, void 0, void 0, function* () {
513
+ const digest = yield crypto.subtle.digest('SHA-256', new TextEncoder().encode(codeVerifier));
514
+ // @ts-ignore
515
+ return btoa(String.fromCharCode(...new Uint8Array(digest)))
516
+ .replace(/=/g, '')
517
+ .replace(/\+/g, '-')
518
+ .replace(/\//g, '_');
519
+ });
520
+ }
521
+ function createRandomString(length = 16) {
522
+ let text = '';
523
+ const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
524
+ for (let i = 0; i < length; i++) {
525
+ text += possible.charAt(Math.floor(Math.random() * possible.length));
526
+ }
527
+ return text;
528
+ }
508
529
  const readFileAsText = (file) => new Promise((resolve, reject) => {
509
530
  const reader = new FileReader();
510
531
  reader.readAsText(file);
@@ -1028,6 +1049,7 @@ const isMfaRequired = (user) => {
1028
1049
  function* getMfaRequiredState(user) {
1029
1050
  let setMfaState = {};
1030
1051
  let step = LoginStep.loginWithTwoFactor;
1052
+ const { loginState } = yield select((state) => state.auth);
1031
1053
  const { isAllowedToRemember, mfaDeviceExpiration } = yield call(api.auth.checkIfAllowToRememberMfaDevice, user.mfaToken);
1032
1054
  if (user.hasOwnProperty('mfaEnrolled') && !user.mfaEnrolled) {
1033
1055
  setMfaState = {
@@ -1041,22 +1063,12 @@ function* getMfaRequiredState(user) {
1041
1063
  };
1042
1064
  step = LoginStep.forceTwoFactor;
1043
1065
  }
1044
- return Object.assign(Object.assign({ user: undefined, isAuthenticated: false }, setMfaState), { loginState: {
1045
- mfaToken: user.mfaToken,
1046
- mfaRequired: user.mfaRequired,
1047
- loading: false,
1048
- error: undefined,
1049
- step,
1050
- tenantsLoading: true,
1051
- tenants: [],
1052
- allowRememberMfaDevice: isAllowedToRemember,
1053
- mfaDeviceExpiration,
1054
- } });
1066
+ return Object.assign(Object.assign({ user: undefined, isAuthenticated: false }, setMfaState), { loginState: Object.assign(Object.assign({}, loginState), { mfaToken: user.mfaToken, mfaRequired: user.mfaRequired, loading: false, error: undefined, step, tenantsLoading: true, tenants: [], allowRememberMfaDevice: isAllowedToRemember, mfaDeviceExpiration }) });
1055
1067
  }
1056
1068
  function* refreshToken() {
1057
1069
  try {
1058
1070
  const onRedirectTo = ContextHolder.onRedirectTo;
1059
- const { routes } = yield select((state) => state.auth);
1071
+ const { routes, loginState } = yield select((state) => state.auth);
1060
1072
  const user = yield call(api.auth.refreshToken);
1061
1073
  if (isMfaRequired(user)) {
1062
1074
  const mfaRequiredState = yield getMfaRequiredState(user);
@@ -1066,9 +1078,14 @@ function* refreshToken() {
1066
1078
  else {
1067
1079
  yield put(actions.loadTenants());
1068
1080
  yield put(actions.setState({ user, isAuthenticated: true }));
1069
- if ([routes.loginUrl, routes.socialLoginCallbackUrl, routes.signupUrl, routes.oidcRedirectUrl].includes(window.location.pathname) ||
1081
+ if ([routes.loginUrl, routes.socialLoginCallbackUrl, routes.signUpUrl, routes.oidcRedirectUrl].includes(window.location.pathname) ||
1070
1082
  (window.location.pathname.endsWith(routes.activateUrl) && user.verified)) {
1071
- yield afterAuthNavigation();
1083
+ if (loginState.isNewUser && routes.signUpSuccessUrl && routes.socialLoginCallbackUrl === window.location.pathname) {
1084
+ onRedirectTo(routes.signUpSuccessUrl, { refresh: routes.signUpSuccessUrl.startsWith('http') });
1085
+ }
1086
+ else {
1087
+ yield afterAuthNavigation();
1088
+ }
1072
1089
  }
1073
1090
  }
1074
1091
  }
@@ -1093,6 +1110,47 @@ function* requestAuthorize({ payload: firstTime }) {
1093
1110
  yield all(calls);
1094
1111
  yield put(actions.setState({ isLoading: false }));
1095
1112
  }
1113
+ function* requestHostedLoginAuthorize() {
1114
+ const { routes, baseUrl, clientId, onRedirectTo } = yield select((state) => (Object.assign({ routes: state.auth.routes, onRedirectTo: state.auth.onRedirectTo }, state.root.context)));
1115
+ // Generate the relevant params for the redirect
1116
+ const nonce = createRandomString();
1117
+ const code_verifier = createRandomString();
1118
+ const code_challenge = yield call(generateCodeChallenge, code_verifier);
1119
+ // We are saving the verifier in session storage to be able to validate the response
1120
+ sessionStorage.setItem(HOSTED_LOGIN_VERIFIER_KEY, code_verifier);
1121
+ const redirectUrl = `${window.location.origin}${routes.hostedLoginRedirectUrl}`;
1122
+ // Hard coded for now
1123
+ const oauthUrl = `${baseUrl}/oauth/authorize`;
1124
+ const params = {
1125
+ response_type: 'code',
1126
+ client_id: clientId || 'INVALID-CLIENT-ID',
1127
+ scope: 'openid email profile',
1128
+ redirect_uri: redirectUrl,
1129
+ code_challenge: code_challenge,
1130
+ code_challenge_method: 'S256',
1131
+ nonce,
1132
+ };
1133
+ const searchParams = new URLSearchParams(params);
1134
+ const url = `${oauthUrl}?${searchParams.toString()}`;
1135
+ onRedirectTo(url, { refresh: true });
1136
+ }
1137
+ function* handleHostedLoginCallback({ payload }) {
1138
+ // Hard coded for now
1139
+ const code_verifier = sessionStorage.getItem(HOSTED_LOGIN_VERIFIER_KEY) || 'INVALID-CODE-VERIFIER';
1140
+ const routes = yield select((state) => state.auth.routes);
1141
+ const redirectUrl = `${window.location.origin}${routes.hostedLoginRedirectUrl}`;
1142
+ const body = {
1143
+ code: payload.code,
1144
+ redirect_uri: redirectUrl,
1145
+ code_verifier,
1146
+ grant_type: 'authorization_code',
1147
+ };
1148
+ const user = yield call(api.auth.exchangeOAuthTokens, body);
1149
+ // TODO: Validate nonce and aud
1150
+ yield put(actions.setState({ user, isAuthenticated: true }));
1151
+ yield put(actions.loadTenants());
1152
+ yield afterAuthNavigation();
1153
+ }
1096
1154
  function* passwordlessPreLogin(_a) {
1097
1155
  var _b = _a.payload, { callback } = _b, payload = __rest(_b, ["callback"]);
1098
1156
  try {
@@ -1325,6 +1383,8 @@ function* silentLogout({ payload }) {
1325
1383
  }
1326
1384
  function* loginSagas() {
1327
1385
  yield takeLeading(actions.requestAuthorize, requestAuthorize);
1386
+ yield takeLeading(actions.requestHostedLoginAuthorize, requestHostedLoginAuthorize);
1387
+ yield takeLeading(actions.handleHostedLoginCallback, handleHostedLoginCallback);
1328
1388
  yield takeLeading(actions.preLogin, preLogin);
1329
1389
  yield takeLeading(actions.postLogin, postLogin);
1330
1390
  yield takeLeading(actions.login, login);
@@ -2448,6 +2508,7 @@ function* loginViaSocialLogin({ payload }) {
2448
2508
  const { email, isNewUser } = yield call(api.auth.loginViaSocialLogin, payload);
2449
2509
  yield put(actions.setLoginState({ email, isNewUser }));
2450
2510
  yield refreshToken();
2511
+ yield put(actions.setSocialLoginsState({ loading: false }));
2451
2512
  }
2452
2513
  catch (e) {
2453
2514
  yield put(actions.setSocialLoginsState({ loading: false, error: (_a = e.message) !== null && _a !== void 0 ? _a : 'Failed to authenticate', firstLoad: false }));
@@ -106,5 +106,9 @@ export declare type AuthPageRoutes = {
106
106
  * after sign up success url
107
107
  */
108
108
  signUpSuccessUrl?: string;
109
+ /**
110
+ * hosted login callback redirect url
111
+ */
112
+ hostedLoginRedirectUrl?: string;
109
113
  };
110
114
  export {};
package/auth/reducer.d.ts CHANGED
@@ -144,6 +144,8 @@ declare const actions: {
144
144
  loginViaSocialLogin: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[import("@frontegg/rest-api").ILoginViaSocialLogin], import("@frontegg/rest-api").ILoginViaSocialLogin, string, never, never>;
145
145
  setSocialLoginError: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[import("@frontegg/rest-api").ISetSocialLoginError], import("@frontegg/rest-api").ISetSocialLoginError, string, never, never>;
146
146
  requestAuthorize: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[(boolean | undefined)?], boolean, string, never, never>;
147
+ requestHostedLoginAuthorize: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<string>;
148
+ handleHostedLoginCallback: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[import(".").HostedLoginCallback], import(".").HostedLoginCallback, string, never, never>;
147
149
  afterAuthNavigation: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<string>;
148
150
  preLogin: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[import("../interfaces").WithCallback<import("@frontegg/rest-api").IPreLogin & {
149
151
  recaptchaToken?: string | undefined;
@@ -1,5 +1,5 @@
1
- import { c as connectivityStoreName } from '../constants-f7891ee3.js';
2
- export { c as connectivityStoreName } from '../constants-f7891ee3.js';
1
+ import { c as connectivityStoreName } from '../constants-4d9682b2.js';
2
+ export { c as connectivityStoreName } from '../constants-4d9682b2.js';
3
3
  import { createAction, createSlice } from '@reduxjs/toolkit';
4
4
  import { __rest } from 'tslib';
5
5
  import { takeEvery, takeLatest, put, all, call, select } from 'redux-saga/effects';
@@ -1,8 +1,9 @@
1
1
  const FRONTEGG_AFTER_AUTH_REDIRECT_URL = 'FRONTEGG_AFTER_AUTH_REDIRECT_URL';
2
+ const HOSTED_LOGIN_VERIFIER_KEY = 'HOSTED_LOGIN_VERIFIER_KEY';
2
3
  const authStoreName = 'auth';
3
4
  const connectivityStoreName = 'connectivity';
4
5
  const auditsStoreName = 'auditLogs';
5
6
  const subscriptionsStoreName = 'subscriptions';
6
7
  const vendorStoreName = 'vendor';
7
8
 
8
- export { FRONTEGG_AFTER_AUTH_REDIRECT_URL as F, authStoreName as a, auditsStoreName as b, connectivityStoreName as c, subscriptionsStoreName as s, vendorStoreName as v };
9
+ export { FRONTEGG_AFTER_AUTH_REDIRECT_URL as F, HOSTED_LOGIN_VERIFIER_KEY as H, authStoreName as a, auditsStoreName as b, connectivityStoreName as c, subscriptionsStoreName as s, vendorStoreName as v };
package/constants.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export declare const FRONTEGG_AFTER_AUTH_REDIRECT_URL = "FRONTEGG_AFTER_AUTH_REDIRECT_URL";
2
+ export declare const HOSTED_LOGIN_VERIFIER_KEY = "HOSTED_LOGIN_VERIFIER_KEY";
2
3
  export declare const authStoreName = "auth";
3
4
  export declare const connectivityStoreName = "connectivity";
4
5
  export declare const auditsStoreName = "auditLogs";
package/helpers.d.ts CHANGED
@@ -1,3 +1,5 @@
1
1
  export declare function omitProps<T>(props: any, keys: string[]): T;
2
2
  export declare function generateActionCreator(storeName: string): <Payload>(key: string, withPayload?: boolean | undefined) => import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[Payload], Payload, string, never, never> | import("@reduxjs/toolkit").ActionCreatorWithoutPayload<string>;
3
+ export declare function generateCodeChallenge(codeVerifier: string): Promise<string>;
4
+ export declare function createRandomString(length?: number): string;
3
5
  export declare const readFileAsText: (file: File) => Promise<string>;
package/index.d.ts CHANGED
@@ -4,6 +4,7 @@ import { AuditsState } from './audits/interfaces';
4
4
  import { IConnectivityState } from './connectivity/interfaces';
5
5
  import { SubscriptionsState } from './subscriptions/interfaces';
6
6
  import { VendorState } from './vendor/interfaces';
7
+ import { OldAuditsState } from './audits/backward-compatibility';
7
8
  export { default as auth } from './auth';
8
9
  export { default as audits } from './audits';
9
10
  export { default as connectivity } from './connectivity';
@@ -19,7 +20,8 @@ export * from './toolkit';
19
20
  export declare type FronteggState = {
20
21
  root: RootState;
21
22
  auth: AuthState;
22
- audits: AuditsState;
23
+ auditLogs: AuditsState;
24
+ audits: OldAuditsState;
23
25
  connectivity: IConnectivityState;
24
26
  subscriptions: SubscriptionsState;
25
27
  vendor: VendorState;
package/index.js CHANGED
@@ -5,9 +5,9 @@ export { CheckoutEvent, CheckoutStatus, PaymentMethodType, PaymentProvider, Subs
5
5
  export { default as vendor } from './vendor/index.js';
6
6
  export { createFronteggStore } from './toolkit/index.js';
7
7
  export { AuthStrategyEnum } from '@frontegg/rest-api';
8
- export { b as auditsStoreName, a as authStoreName, c as connectivityStoreName, s as subscriptionsStoreName, v as vendorStoreName } from './constants-f7891ee3.js';
8
+ export { b as auditsStoreName, a as authStoreName, c as connectivityStoreName, s as subscriptionsStoreName, v as vendorStoreName } from './constants-4d9682b2.js';
9
9
  export { a as actions, d as defaultItemsPerPage, i as initialState, r as reducer, b as sagas, s as storeName } from './saga-7a267fe0.js';
10
- export { a as vendorActions, i as vendorInitialState, r as vendorReducers, s as vendorSagas } from './saga-afaced62.js';
10
+ export { a as vendorActions, i as vendorInitialState, r as vendorReducers, s as vendorSagas } from './saga-b6529ffb.js';
11
11
  export { bindActionCreators, combineReducers, configureStore, createSelector, createSlice, getDefaultMiddleware } from '@reduxjs/toolkit';
12
12
  export { all, call, delay, put, select, takeEvery, takeLatest } from 'redux-saga/effects';
13
13
  export { default as createSagaMiddleware } from 'redux-saga';
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var constants = require('../constants-b305f261.js');
5
+ var constants = require('../constants-52e37c08.js');
6
6
  var toolkit = require('@reduxjs/toolkit');
7
7
  var effects = require('redux-saga/effects');
8
8
  var restApi = require('@frontegg/rest-api');
@@ -4,10 +4,10 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var toolkit = require('@reduxjs/toolkit');
6
6
  var restApi = require('@frontegg/rest-api');
7
- var constants = require('../constants-b305f261.js');
7
+ var constants = require('../constants-52e37c08.js');
8
8
  var tslib = require('tslib');
9
9
  var effects = require('redux-saga/effects');
10
- var saga = require('../saga-508b308b.js');
10
+ var saga = require('../saga-633c17d2.js');
11
11
  var uuid = require('uuid');
12
12
 
13
13
  const resetStateByKey = (key, initialState) => (state) => (Object.assign(Object.assign({}, state), { [key]: initialState[key] }));
@@ -67,6 +67,8 @@ const reducers$e = {
67
67
  };
68
68
  const actions$f = {
69
69
  requestAuthorize: toolkit.createAction(`${constants.authStoreName}/requestAuthorize`, (payload = false) => ({ payload })),
70
+ requestHostedLoginAuthorize: toolkit.createAction(`${constants.authStoreName}/requestHostedLoginAuthorize`),
71
+ handleHostedLoginCallback: toolkit.createAction(`${constants.authStoreName}/handleHostedLoginCallback`, (payload) => ({ payload })),
70
72
  afterAuthNavigation: toolkit.createAction(`${constants.authStoreName}/afterAuthNavigation`),
71
73
  preLogin: toolkit.createAction(`${constants.authStoreName}/preLogin`, (payload) => ({ payload })),
72
74
  postLogin: toolkit.createAction(`${constants.authStoreName}/postLogin`, (payload) => ({ payload })),
@@ -481,7 +483,8 @@ const initialState = Object.assign({ routes: {
481
483
  socialLoginCallbackUrl: '/account/social/success',
482
484
  signUpUrl: '/account/sign-up',
483
485
  oidcRedirectUrl: '/account/oidc/callback',
484
- magicLinkCallbackUrl: '/account/login/magic-link'
486
+ magicLinkCallbackUrl: '/account/login/magic-link',
487
+ hostedLoginRedirectUrl: '/oauth/callback'
485
488
  }, onRedirectTo: () => { } }, reinitializeState);
486
489
 
487
490
  const { reducer, actions: sliceActions } = toolkit.createSlice({
@@ -507,6 +510,24 @@ function omitProps(props, keys) {
507
510
  });
508
511
  return newProps;
509
512
  }
513
+ function generateCodeChallenge(codeVerifier) {
514
+ return tslib.__awaiter(this, void 0, void 0, function* () {
515
+ const digest = yield crypto.subtle.digest('SHA-256', new TextEncoder().encode(codeVerifier));
516
+ // @ts-ignore
517
+ return btoa(String.fromCharCode(...new Uint8Array(digest)))
518
+ .replace(/=/g, '')
519
+ .replace(/\+/g, '-')
520
+ .replace(/\//g, '_');
521
+ });
522
+ }
523
+ function createRandomString(length = 16) {
524
+ let text = '';
525
+ const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
526
+ for (let i = 0; i < length; i++) {
527
+ text += possible.charAt(Math.floor(Math.random() * possible.length));
528
+ }
529
+ return text;
530
+ }
510
531
  const readFileAsText = (file) => new Promise((resolve, reject) => {
511
532
  const reader = new FileReader();
512
533
  reader.readAsText(file);
@@ -1030,6 +1051,7 @@ const isMfaRequired = (user) => {
1030
1051
  function* getMfaRequiredState(user) {
1031
1052
  let setMfaState = {};
1032
1053
  let step = exports.LoginStep.loginWithTwoFactor;
1054
+ const { loginState } = yield effects.select((state) => state.auth);
1033
1055
  const { isAllowedToRemember, mfaDeviceExpiration } = yield effects.call(restApi.api.auth.checkIfAllowToRememberMfaDevice, user.mfaToken);
1034
1056
  if (user.hasOwnProperty('mfaEnrolled') && !user.mfaEnrolled) {
1035
1057
  setMfaState = {
@@ -1043,22 +1065,12 @@ function* getMfaRequiredState(user) {
1043
1065
  };
1044
1066
  step = exports.LoginStep.forceTwoFactor;
1045
1067
  }
1046
- return Object.assign(Object.assign({ user: undefined, isAuthenticated: false }, setMfaState), { loginState: {
1047
- mfaToken: user.mfaToken,
1048
- mfaRequired: user.mfaRequired,
1049
- loading: false,
1050
- error: undefined,
1051
- step,
1052
- tenantsLoading: true,
1053
- tenants: [],
1054
- allowRememberMfaDevice: isAllowedToRemember,
1055
- mfaDeviceExpiration,
1056
- } });
1068
+ return Object.assign(Object.assign({ user: undefined, isAuthenticated: false }, setMfaState), { loginState: Object.assign(Object.assign({}, loginState), { mfaToken: user.mfaToken, mfaRequired: user.mfaRequired, loading: false, error: undefined, step, tenantsLoading: true, tenants: [], allowRememberMfaDevice: isAllowedToRemember, mfaDeviceExpiration }) });
1057
1069
  }
1058
1070
  function* refreshToken() {
1059
1071
  try {
1060
1072
  const onRedirectTo = restApi.ContextHolder.onRedirectTo;
1061
- const { routes } = yield effects.select((state) => state.auth);
1073
+ const { routes, loginState } = yield effects.select((state) => state.auth);
1062
1074
  const user = yield effects.call(restApi.api.auth.refreshToken);
1063
1075
  if (isMfaRequired(user)) {
1064
1076
  const mfaRequiredState = yield getMfaRequiredState(user);
@@ -1068,9 +1080,14 @@ function* refreshToken() {
1068
1080
  else {
1069
1081
  yield effects.put(actions.loadTenants());
1070
1082
  yield effects.put(actions.setState({ user, isAuthenticated: true }));
1071
- if ([routes.loginUrl, routes.socialLoginCallbackUrl, routes.signupUrl, routes.oidcRedirectUrl].includes(window.location.pathname) ||
1083
+ if ([routes.loginUrl, routes.socialLoginCallbackUrl, routes.signUpUrl, routes.oidcRedirectUrl].includes(window.location.pathname) ||
1072
1084
  (window.location.pathname.endsWith(routes.activateUrl) && user.verified)) {
1073
- yield afterAuthNavigation();
1085
+ if (loginState.isNewUser && routes.signUpSuccessUrl && routes.socialLoginCallbackUrl === window.location.pathname) {
1086
+ onRedirectTo(routes.signUpSuccessUrl, { refresh: routes.signUpSuccessUrl.startsWith('http') });
1087
+ }
1088
+ else {
1089
+ yield afterAuthNavigation();
1090
+ }
1074
1091
  }
1075
1092
  }
1076
1093
  }
@@ -1095,6 +1112,47 @@ function* requestAuthorize({ payload: firstTime }) {
1095
1112
  yield effects.all(calls);
1096
1113
  yield effects.put(actions.setState({ isLoading: false }));
1097
1114
  }
1115
+ function* requestHostedLoginAuthorize() {
1116
+ const { routes, baseUrl, clientId, onRedirectTo } = yield effects.select((state) => (Object.assign({ routes: state.auth.routes, onRedirectTo: state.auth.onRedirectTo }, state.root.context)));
1117
+ // Generate the relevant params for the redirect
1118
+ const nonce = createRandomString();
1119
+ const code_verifier = createRandomString();
1120
+ const code_challenge = yield effects.call(generateCodeChallenge, code_verifier);
1121
+ // We are saving the verifier in session storage to be able to validate the response
1122
+ sessionStorage.setItem(constants.HOSTED_LOGIN_VERIFIER_KEY, code_verifier);
1123
+ const redirectUrl = `${window.location.origin}${routes.hostedLoginRedirectUrl}`;
1124
+ // Hard coded for now
1125
+ const oauthUrl = `${baseUrl}/oauth/authorize`;
1126
+ const params = {
1127
+ response_type: 'code',
1128
+ client_id: clientId || 'INVALID-CLIENT-ID',
1129
+ scope: 'openid email profile',
1130
+ redirect_uri: redirectUrl,
1131
+ code_challenge: code_challenge,
1132
+ code_challenge_method: 'S256',
1133
+ nonce,
1134
+ };
1135
+ const searchParams = new URLSearchParams(params);
1136
+ const url = `${oauthUrl}?${searchParams.toString()}`;
1137
+ onRedirectTo(url, { refresh: true });
1138
+ }
1139
+ function* handleHostedLoginCallback({ payload }) {
1140
+ // Hard coded for now
1141
+ const code_verifier = sessionStorage.getItem(constants.HOSTED_LOGIN_VERIFIER_KEY) || 'INVALID-CODE-VERIFIER';
1142
+ const routes = yield effects.select((state) => state.auth.routes);
1143
+ const redirectUrl = `${window.location.origin}${routes.hostedLoginRedirectUrl}`;
1144
+ const body = {
1145
+ code: payload.code,
1146
+ redirect_uri: redirectUrl,
1147
+ code_verifier,
1148
+ grant_type: 'authorization_code',
1149
+ };
1150
+ const user = yield effects.call(restApi.api.auth.exchangeOAuthTokens, body);
1151
+ // TODO: Validate nonce and aud
1152
+ yield effects.put(actions.setState({ user, isAuthenticated: true }));
1153
+ yield effects.put(actions.loadTenants());
1154
+ yield afterAuthNavigation();
1155
+ }
1098
1156
  function* passwordlessPreLogin(_a) {
1099
1157
  var _b = _a.payload, { callback } = _b, payload = tslib.__rest(_b, ["callback"]);
1100
1158
  try {
@@ -1327,6 +1385,8 @@ function* silentLogout({ payload }) {
1327
1385
  }
1328
1386
  function* loginSagas() {
1329
1387
  yield effects.takeLeading(actions.requestAuthorize, requestAuthorize);
1388
+ yield effects.takeLeading(actions.requestHostedLoginAuthorize, requestHostedLoginAuthorize);
1389
+ yield effects.takeLeading(actions.handleHostedLoginCallback, handleHostedLoginCallback);
1330
1390
  yield effects.takeLeading(actions.preLogin, preLogin);
1331
1391
  yield effects.takeLeading(actions.postLogin, postLogin);
1332
1392
  yield effects.takeLeading(actions.login, login);
@@ -2450,6 +2510,7 @@ function* loginViaSocialLogin({ payload }) {
2450
2510
  const { email, isNewUser } = yield effects.call(restApi.api.auth.loginViaSocialLogin, payload);
2451
2511
  yield effects.put(actions.setLoginState({ email, isNewUser }));
2452
2512
  yield refreshToken();
2513
+ yield effects.put(actions.setSocialLoginsState({ loading: false }));
2453
2514
  }
2454
2515
  catch (e) {
2455
2516
  yield effects.put(actions.setSocialLoginsState({ loading: false, error: (_a = e.message) !== null && _a !== void 0 ? _a : 'Failed to authenticate', firstLoad: false }));
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var constants = require('../constants-b305f261.js');
5
+ var constants = require('../constants-52e37c08.js');
6
6
  var toolkit = require('@reduxjs/toolkit');
7
7
  var tslib = require('tslib');
8
8
  var effects = require('redux-saga/effects');
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  const FRONTEGG_AFTER_AUTH_REDIRECT_URL = 'FRONTEGG_AFTER_AUTH_REDIRECT_URL';
4
+ const HOSTED_LOGIN_VERIFIER_KEY = 'HOSTED_LOGIN_VERIFIER_KEY';
4
5
  const authStoreName = 'auth';
5
6
  const connectivityStoreName = 'connectivity';
6
7
  const auditsStoreName = 'auditLogs';
@@ -8,6 +9,7 @@ const subscriptionsStoreName = 'subscriptions';
8
9
  const vendorStoreName = 'vendor';
9
10
 
10
11
  exports.FRONTEGG_AFTER_AUTH_REDIRECT_URL = FRONTEGG_AFTER_AUTH_REDIRECT_URL;
12
+ exports.HOSTED_LOGIN_VERIFIER_KEY = HOSTED_LOGIN_VERIFIER_KEY;
11
13
  exports.auditsStoreName = auditsStoreName;
12
14
  exports.authStoreName = authStoreName;
13
15
  exports.connectivityStoreName = connectivityStoreName;
package/node/index.js CHANGED
@@ -10,8 +10,8 @@ var vendor_index = require('./vendor/index.js');
10
10
  var saga = require('./saga-b0d1a607.js');
11
11
  var toolkit_index = require('./toolkit/index.js');
12
12
  var restApi = require('@frontegg/rest-api');
13
- var constants = require('./constants-b305f261.js');
14
- var saga$1 = require('./saga-508b308b.js');
13
+ var constants = require('./constants-52e37c08.js');
14
+ var saga$1 = require('./saga-633c17d2.js');
15
15
  var toolkit = require('@reduxjs/toolkit');
16
16
  var effects = require('redux-saga/effects');
17
17
  var createSagaMiddleware = require('redux-saga');
@@ -2,7 +2,7 @@
2
2
 
3
3
  var effects = require('redux-saga/effects');
4
4
  var restApi = require('@frontegg/rest-api');
5
- var constants = require('./constants-b305f261.js');
5
+ var constants = require('./constants-52e37c08.js');
6
6
  var toolkit = require('@reduxjs/toolkit');
7
7
 
8
8
  const reducers = {
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var constants = require('../constants-b305f261.js');
5
+ var constants = require('../constants-52e37c08.js');
6
6
  var toolkit = require('@reduxjs/toolkit');
7
7
  var effects = require('redux-saga/effects');
8
8
  var restApi = require('@frontegg/rest-api');
@@ -12,9 +12,9 @@ var saga = require('../saga-b0d1a607.js');
12
12
  var connectivity_index = require('../connectivity/index.js');
13
13
  var subscriptions_index = require('../subscriptions/index.js');
14
14
  var vendor_index = require('../vendor/index.js');
15
- require('../constants-b305f261.js');
15
+ require('../constants-52e37c08.js');
16
16
  require('tslib');
17
- require('../saga-508b308b.js');
17
+ require('../saga-633c17d2.js');
18
18
  require('uuid');
19
19
 
20
20
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
@@ -2,8 +2,8 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var saga = require('../saga-508b308b.js');
6
- var constants = require('../constants-b305f261.js');
5
+ var saga = require('../saga-633c17d2.js');
6
+ var constants = require('../constants-52e37c08.js');
7
7
  require('redux-saga/effects');
8
8
  require('@frontegg/rest-api');
9
9
  require('@reduxjs/toolkit');
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "@frontegg/redux-store",
3
3
  "libName": "FronteggReduxStore",
4
- "version": "4.39.1",
4
+ "version": "4.39.2-dashboard",
5
5
  "author": "Frontegg LTD",
6
6
  "main": "./node/index.js",
7
7
  "module": "./index.js",
8
8
  "types": "./index.d.ts",
9
9
  "dependencies": {
10
- "@frontegg/rest-api": "2.10.46",
10
+ "@frontegg/rest-api": "2.10.47",
11
11
  "@reduxjs/toolkit": "^1.5.0",
12
12
  "redux-saga": "^1.1.0",
13
13
  "tslib": "^2.3.1",
14
14
  "uuid": "^8.3.0"
15
15
  }
16
- }
16
+ }
@@ -1,6 +1,6 @@
1
1
  import { takeEvery, put } from 'redux-saga/effects';
2
2
  import { api } from '@frontegg/rest-api';
3
- import { v as vendorStoreName } from './constants-f7891ee3.js';
3
+ import { v as vendorStoreName } from './constants-4d9682b2.js';
4
4
  import { createAction, createSlice } from '@reduxjs/toolkit';
5
5
 
6
6
  const reducers = {
@@ -1,5 +1,5 @@
1
- import { s as subscriptionsStoreName } from '../constants-f7891ee3.js';
2
- export { s as subscriptionsStoreName } from '../constants-f7891ee3.js';
1
+ import { s as subscriptionsStoreName } from '../constants-4d9682b2.js';
2
+ export { s as subscriptionsStoreName } from '../constants-4d9682b2.js';
3
3
  import { createSlice, createAction, combineReducers } from '@reduxjs/toolkit';
4
4
  import { takeEvery, select, put, call, delay, all } from 'redux-saga/effects';
5
5
  import { ISubscriptionStatus, PaymentMethodType as PaymentMethodType$1, api, ProviderType } from '@frontegg/rest-api';
package/toolkit/index.js CHANGED
@@ -11,9 +11,9 @@ import connectivityStore from '../connectivity/index.js';
11
11
  import subscriptionsStore from '../subscriptions/index.js';
12
12
  import vendorStore from '../vendor/index.js';
13
13
  import { s as storeName, i as initialState$1, r as reducer, b as sagas } from '../saga-7a267fe0.js';
14
- import '../constants-f7891ee3.js';
14
+ import '../constants-4d9682b2.js';
15
15
  import 'tslib';
16
- import '../saga-afaced62.js';
16
+ import '../saga-b6529ffb.js';
17
17
  import 'uuid';
18
18
 
19
19
  const initialState = {
package/vendor/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import { s as sagas, i as initialState, r as reducer, a as actions } from '../saga-afaced62.js';
2
- export { a as vendorActions, i as vendorInitialState, r as vendorReducers, s as vendorSagas } from '../saga-afaced62.js';
3
- import { v as vendorStoreName } from '../constants-f7891ee3.js';
4
- export { v as vendorStoreName } from '../constants-f7891ee3.js';
1
+ import { s as sagas, i as initialState, r as reducer, a as actions } from '../saga-b6529ffb.js';
2
+ export { a as vendorActions, i as vendorInitialState, r as vendorReducers, s as vendorSagas } from '../saga-b6529ffb.js';
3
+ import { v as vendorStoreName } from '../constants-4d9682b2.js';
4
+ export { v as vendorStoreName } from '../constants-4d9682b2.js';
5
5
  import 'redux-saga/effects';
6
6
  import '@frontegg/rest-api';
7
7
  import '@reduxjs/toolkit';