@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.
- package/auth/ForgotPasswordState/actions.d.ts +9 -1
- package/auth/ForgotPasswordState/actions.js +68 -3
- package/auth/ForgotPasswordState/interfaces.d.ts +2 -0
- package/auth/ForgotPasswordState/state.js +2 -1
- package/index.js +1 -1
- package/mocks/auth-mocks/forgotPasswordActions.mocks.d.ts +9 -1
- package/mocks/auth-mocks/forgotPasswordActions.mocks.js +14 -0
- package/node/auth/ForgotPasswordState/actions.js +67 -2
- package/node/auth/ForgotPasswordState/state.js +2 -1
- package/node/index.js +1 -1
- package/node/mocks/auth-mocks/forgotPasswordActions.mocks.js +14 -0
- package/package.json +2 -2
|
@@ -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
|
|
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
|
-
|
|
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;
|
package/index.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
@@ -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
|
|
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
|
|
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",
|