@frontegg/redux-store 7.104.0-alpha.0 → 7.104.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.
@@ -7,7 +7,15 @@ declare const _default: (store: FronteggState, api: RestApi, sharedActions: Shar
7
7
  resetForgotPasswordState: () => void;
8
8
  forgotPassword: (payload: IForgotPasswordPayload) => Promise<void>;
9
9
  resetPassword: (payload: IResetPasswordPayload) => Promise<void>;
10
- loadPasswordConfig: (payload?: IGetUserPasswordConfig) => Promise<void>;
10
+ loadPasswordConfig: (payload?: IGetUserPasswordConfig & {
11
+ signal?: AbortSignal;
12
+ }) => Promise<void>;
13
+ validateResetPasswordToken: (payload: {
14
+ userId: string;
15
+ token: string;
16
+ skipValidation?: boolean;
17
+ signal?: AbortSignal;
18
+ }) => Promise<void>;
11
19
  determinePasswordRecoveryStrategy: (payload: IDeterminePasswordRecoveryStrategyPayload) => Promise<void>;
12
20
  sendPasswordRecoveryEmail: () => Promise<void>;
13
21
  sendPasswordRecoverySms: () => Promise<void>;
@@ -3,7 +3,7 @@ const _excluded = ["callback"];
3
3
  import { PasswordRecoveryStrategyEnum } from '@frontegg/rest-api';
4
4
  import { ForgotPasswordStep } from './interfaces';
5
5
  import { initialState } from './state';
6
- import { errorHandler, deepResetState } from '../../helpers';
6
+ import { errorHandler, deepResetState, isFronteggApiError } from '../../helpers';
7
7
  import { FORGOT_PASSWORD_ERROR_KEYS } from './consts';
8
8
  export default ((store, api, sharedActions) => {
9
9
  const actions = sharedActions;
@@ -129,7 +129,8 @@ export default ((store, api, sharedActions) => {
129
129
  error: undefined,
130
130
  userId: response.userId,
131
131
  token: response.token,
132
- step: ForgotPasswordStep.resetPasswordPage
132
+ step: ForgotPasswordStep.resetPasswordPage,
133
+ resetTokenValidationStatus: 'valid'
133
134
  });
134
135
  } catch (e) {
135
136
  setForgotPasswordState({
@@ -206,18 +207,81 @@ export default ((store, api, sharedActions) => {
206
207
  loading: true
207
208
  });
208
209
  try {
209
- const passwordConfig = await api.auth.loadPasswordConfig(payload);
210
+ var _payload$signal;
211
+ const passwordConfig = await api.auth.loadPasswordConfig(payload ? {
212
+ userId: payload.userId
213
+ } : undefined);
214
+ if (payload != null && (_payload$signal = payload.signal) != null && _payload$signal.aborted) return;
210
215
  setForgotPasswordState({
211
216
  loading: false,
212
217
  passwordConfig
213
218
  });
214
219
  } catch (e) {
220
+ var _payload$signal2;
221
+ if (payload != null && (_payload$signal2 = payload.signal) != null && _payload$signal2.aborted) return;
215
222
  setForgotPasswordState({
216
223
  loading: false,
217
224
  error: errorHandler(e)
218
225
  });
219
226
  }
220
227
  };
228
+ const validateResetPasswordToken = async payload => {
229
+ if (payload.skipValidation || store.auth.forgotPasswordState.resetTokenValidationStatus === 'valid') {
230
+ var _payload$signal3;
231
+ if (!((_payload$signal3 = payload.signal) != null && _payload$signal3.aborted)) {
232
+ setForgotPasswordState({
233
+ resetTokenValidationStatus: 'valid',
234
+ error: undefined
235
+ });
236
+ }
237
+ return;
238
+ }
239
+ setForgotPasswordState({
240
+ resetTokenValidationStatus: 'pending',
241
+ error: undefined
242
+ });
243
+ try {
244
+ var _payload$signal4;
245
+ await api.auth.validateResetPasswordToken({
246
+ userId: payload.userId,
247
+ token: payload.token
248
+ });
249
+ if ((_payload$signal4 = payload.signal) != null && _payload$signal4.aborted) return;
250
+ setForgotPasswordState({
251
+ resetTokenValidationStatus: 'valid',
252
+ error: undefined
253
+ });
254
+ } catch (e) {
255
+ var _payload$signal5;
256
+ if ((_payload$signal5 = payload.signal) != null && _payload$signal5.aborted) return;
257
+ const handled = errorHandler(e);
258
+ if (isFronteggApiError(handled)) {
259
+ const status = handled.statusCode;
260
+ // Identity: 400 = bad request / missing input; 410 = expired or consumed. Both use the same link-expired screen (invalid).
261
+ // 403/422 included if the API or gateway uses them for invalid tokens.
262
+ const tokenInvalid = status === 400 || status === 403 || status === 410 || status === 422;
263
+ const degradeToLegacyFlow = status === 401 || status === 404 || status >= 500;
264
+ if (tokenInvalid) {
265
+ setForgotPasswordState({
266
+ resetTokenValidationStatus: 'invalid',
267
+ error: undefined
268
+ });
269
+ return;
270
+ }
271
+ if (degradeToLegacyFlow) {
272
+ setForgotPasswordState({
273
+ resetTokenValidationStatus: 'valid',
274
+ error: undefined
275
+ });
276
+ return;
277
+ }
278
+ }
279
+ setForgotPasswordState({
280
+ resetTokenValidationStatus: 'valid',
281
+ error: undefined
282
+ });
283
+ }
284
+ };
221
285
  return {
222
286
  loadPasswordRecoveryStrategies,
223
287
  setForgotPasswordState,
@@ -225,6 +289,7 @@ export default ((store, api, sharedActions) => {
225
289
  forgotPassword,
226
290
  resetPassword,
227
291
  loadPasswordConfig,
292
+ validateResetPasswordToken,
228
293
  determinePasswordRecoveryStrategy,
229
294
  sendPasswordRecoveryEmail,
230
295
  sendPasswordRecoverySms,
@@ -1,5 +1,6 @@
1
1
  import type { EIdentifierType, IForgotPassword, IResetPassword, IPasswordRecoveryStrategy } from '@frontegg/rest-api';
2
2
  import type { WithCallback } from '../../interfaces';
3
+ export type ResetTokenValidationStatus = 'idle' | 'pending' | 'valid' | 'invalid';
3
4
  export declare enum ForgotPasswordStep {
4
5
  'forgotPassword' = "forgotPassword",
5
6
  'resetPasswordViaSms' = "resetPasswordViaSms",
@@ -26,6 +27,7 @@ export interface ForgotPasswordState {
26
27
  token?: string;
27
28
  error?: any;
28
29
  activeStrategies?: IPasswordRecoveryStrategy[];
30
+ resetTokenValidationStatus: ResetTokenValidationStatus;
29
31
  }
30
32
  export interface IForgotPasswordPayload extends WithCallback<IForgotPassword> {
31
33
  recaptchaToken?: string;
@@ -9,6 +9,7 @@ export const initialState = {
9
9
  sessionId: '',
10
10
  userId: '',
11
11
  token: '',
12
- passwordConfig: null
12
+ passwordConfig: null,
13
+ resetTokenValidationStatus: 'idle'
13
14
  };
14
15
  export default (overrideState => createProxy(initialState, overrideState));
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /** @license Frontegg v7.104.0-alpha.0
1
+ /** @license Frontegg v7.104.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.
@@ -6,7 +6,15 @@ declare const _default: (store: FronteggState, api: RestApi, actions: SharedActi
6
6
  resetForgotPasswordState: () => void;
7
7
  forgotPassword: (payload: import("../..").IForgotPasswordPayload) => Promise<void>;
8
8
  resetPassword: (payload: import("../..").IResetPasswordPayload) => Promise<void>;
9
- loadPasswordConfig: (payload?: IGetUserPasswordConfig) => Promise<void>;
9
+ loadPasswordConfig: (payload?: IGetUserPasswordConfig & {
10
+ signal?: AbortSignal;
11
+ }) => Promise<void>;
12
+ validateResetPasswordToken: (payload: {
13
+ userId: string;
14
+ token: string;
15
+ skipValidation?: boolean;
16
+ signal?: AbortSignal;
17
+ }) => Promise<void>;
10
18
  determinePasswordRecoveryStrategy: (payload: import("../..").IDeterminePasswordRecoveryStrategyPayload) => Promise<void>;
11
19
  sendPasswordRecoveryEmail: () => Promise<void>;
12
20
  sendPasswordRecoverySms: () => Promise<void>;
@@ -26,5 +26,19 @@ export default ((store, api, actions) => {
26
26
  });
27
27
  }
28
28
  };
29
+ mockedActions.validateResetPasswordToken = async payload => {
30
+ if (payload.skipValidation) {
31
+ mockedActions.setForgotPasswordState({
32
+ resetTokenValidationStatus: 'valid'
33
+ });
34
+ return;
35
+ }
36
+ mockedActions.setForgotPasswordState({
37
+ resetTokenValidationStatus: 'pending'
38
+ });
39
+ mockedActions.setForgotPasswordState({
40
+ resetTokenValidationStatus: 'valid'
41
+ });
42
+ };
29
43
  return mockedActions;
30
44
  });
@@ -136,7 +136,8 @@ var _default = (store, api, sharedActions) => {
136
136
  error: undefined,
137
137
  userId: response.userId,
138
138
  token: response.token,
139
- step: _interfaces.ForgotPasswordStep.resetPasswordPage
139
+ step: _interfaces.ForgotPasswordStep.resetPasswordPage,
140
+ resetTokenValidationStatus: 'valid'
140
141
  });
141
142
  } catch (e) {
142
143
  setForgotPasswordState({
@@ -213,18 +214,81 @@ var _default = (store, api, sharedActions) => {
213
214
  loading: true
214
215
  });
215
216
  try {
216
- const passwordConfig = await api.auth.loadPasswordConfig(payload);
217
+ var _payload$signal;
218
+ const passwordConfig = await api.auth.loadPasswordConfig(payload ? {
219
+ userId: payload.userId
220
+ } : undefined);
221
+ if (payload != null && (_payload$signal = payload.signal) != null && _payload$signal.aborted) return;
217
222
  setForgotPasswordState({
218
223
  loading: false,
219
224
  passwordConfig
220
225
  });
221
226
  } catch (e) {
227
+ var _payload$signal2;
228
+ if (payload != null && (_payload$signal2 = payload.signal) != null && _payload$signal2.aborted) return;
222
229
  setForgotPasswordState({
223
230
  loading: false,
224
231
  error: (0, _helpers.errorHandler)(e)
225
232
  });
226
233
  }
227
234
  };
235
+ const validateResetPasswordToken = async payload => {
236
+ if (payload.skipValidation || store.auth.forgotPasswordState.resetTokenValidationStatus === 'valid') {
237
+ var _payload$signal3;
238
+ if (!((_payload$signal3 = payload.signal) != null && _payload$signal3.aborted)) {
239
+ setForgotPasswordState({
240
+ resetTokenValidationStatus: 'valid',
241
+ error: undefined
242
+ });
243
+ }
244
+ return;
245
+ }
246
+ setForgotPasswordState({
247
+ resetTokenValidationStatus: 'pending',
248
+ error: undefined
249
+ });
250
+ try {
251
+ var _payload$signal4;
252
+ await api.auth.validateResetPasswordToken({
253
+ userId: payload.userId,
254
+ token: payload.token
255
+ });
256
+ if ((_payload$signal4 = payload.signal) != null && _payload$signal4.aborted) return;
257
+ setForgotPasswordState({
258
+ resetTokenValidationStatus: 'valid',
259
+ error: undefined
260
+ });
261
+ } catch (e) {
262
+ var _payload$signal5;
263
+ if ((_payload$signal5 = payload.signal) != null && _payload$signal5.aborted) return;
264
+ const handled = (0, _helpers.errorHandler)(e);
265
+ if ((0, _helpers.isFronteggApiError)(handled)) {
266
+ const status = handled.statusCode;
267
+ // Identity: 400 = bad request / missing input; 410 = expired or consumed. Both use the same link-expired screen (invalid).
268
+ // 403/422 included if the API or gateway uses them for invalid tokens.
269
+ const tokenInvalid = status === 400 || status === 403 || status === 410 || status === 422;
270
+ const degradeToLegacyFlow = status === 401 || status === 404 || status >= 500;
271
+ if (tokenInvalid) {
272
+ setForgotPasswordState({
273
+ resetTokenValidationStatus: 'invalid',
274
+ error: undefined
275
+ });
276
+ return;
277
+ }
278
+ if (degradeToLegacyFlow) {
279
+ setForgotPasswordState({
280
+ resetTokenValidationStatus: 'valid',
281
+ error: undefined
282
+ });
283
+ return;
284
+ }
285
+ }
286
+ setForgotPasswordState({
287
+ resetTokenValidationStatus: 'valid',
288
+ error: undefined
289
+ });
290
+ }
291
+ };
228
292
  return {
229
293
  loadPasswordRecoveryStrategies,
230
294
  setForgotPasswordState,
@@ -232,6 +296,7 @@ var _default = (store, api, sharedActions) => {
232
296
  forgotPassword,
233
297
  resetPassword,
234
298
  loadPasswordConfig,
299
+ validateResetPasswordToken,
235
300
  determinePasswordRecoveryStrategy,
236
301
  sendPasswordRecoveryEmail,
237
302
  sendPasswordRecoverySms,
@@ -15,7 +15,8 @@ const initialState = {
15
15
  sessionId: '',
16
16
  userId: '',
17
17
  token: '',
18
- passwordConfig: null
18
+ passwordConfig: null,
19
+ resetTokenValidationStatus: 'idle'
19
20
  };
20
21
  exports.initialState = initialState;
21
22
  var _default = overrideState => (0, _proxy.createProxy)(initialState, overrideState);
package/node/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /** @license Frontegg v7.104.0-alpha.0
1
+ /** @license Frontegg v7.104.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.
@@ -32,6 +32,20 @@ var _default = (store, api, actions) => {
32
32
  });
33
33
  }
34
34
  };
35
+ mockedActions.validateResetPasswordToken = async payload => {
36
+ if (payload.skipValidation) {
37
+ mockedActions.setForgotPasswordState({
38
+ resetTokenValidationStatus: 'valid'
39
+ });
40
+ return;
41
+ }
42
+ mockedActions.setForgotPasswordState({
43
+ resetTokenValidationStatus: 'pending'
44
+ });
45
+ mockedActions.setForgotPasswordState({
46
+ resetTokenValidationStatus: 'valid'
47
+ });
48
+ };
35
49
  return mockedActions;
36
50
  };
37
51
  exports.default = _default;
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@frontegg/redux-store",
3
- "version": "7.104.0-alpha.0",
3
+ "version": "7.104.0",
4
4
  "main": "./node/index.js",
5
5
  "license": "MIT",
6
6
  "author": "Frontegg LTD",
7
7
  "dependencies": {
8
8
  "@babel/runtime": "^7.18.6",
9
9
  "@frontegg/entitlements-javascript-commons": "1.1.2",
10
- "@frontegg/rest-api": "7.104.0-alpha.0",
10
+ "@frontegg/rest-api": "7.104.0",
11
11
  "fast-deep-equal": "3.1.3",
12
12
  "get-value": "^3.0.1",
13
13
  "proxy-compare": "^3.0.0",