@oneblink/apps-react 10.3.1 → 11.0.0-beta.1

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 (49) hide show
  1. package/dist/apps/auth-service.d.ts +3 -2
  2. package/dist/apps/auth-service.js +2 -2
  3. package/dist/apps/auth-service.js.map +1 -1
  4. package/dist/apps/services/AWSCognitoClient.d.ts +39 -4
  5. package/dist/apps/services/AWSCognitoClient.js +238 -23
  6. package/dist/apps/services/AWSCognitoClient.js.map +1 -1
  7. package/dist/apps/services/cognito.d.ts +50 -41
  8. package/dist/apps/services/cognito.js +85 -48
  9. package/dist/apps/services/cognito.js.map +1 -1
  10. package/dist/components/mfa/MfaAuthenticatorAppDialog.d.ts +12 -0
  11. package/dist/components/mfa/MfaAuthenticatorAppDialog.js +64 -0
  12. package/dist/components/mfa/MfaAuthenticatorAppDialog.js.map +1 -0
  13. package/dist/components/mfa/MfaDisableDialog.d.ts +10 -0
  14. package/dist/components/mfa/MfaDisableDialog.js +31 -0
  15. package/dist/components/mfa/MfaDisableDialog.js.map +1 -0
  16. package/dist/components/mfa/MfaErrorSnackbar.d.ts +10 -0
  17. package/dist/components/mfa/MfaErrorSnackbar.js +17 -0
  18. package/dist/components/mfa/MfaErrorSnackbar.js.map +1 -0
  19. package/dist/components/mfa/MfaMethodRow.d.ts +19 -0
  20. package/dist/components/mfa/MfaMethodRow.js +10 -0
  21. package/dist/components/mfa/MfaMethodRow.js.map +1 -0
  22. package/dist/components/mfa/MfaPhoneNumberDialog.d.ts +11 -0
  23. package/dist/components/mfa/MfaPhoneNumberDialog.js +120 -0
  24. package/dist/components/mfa/MfaPhoneNumberDialog.js.map +1 -0
  25. package/dist/components/mfa/MfaRemovePhoneNumberDialog.d.ts +10 -0
  26. package/dist/components/mfa/MfaRemovePhoneNumberDialog.js +24 -0
  27. package/dist/components/mfa/MfaRemovePhoneNumberDialog.js.map +1 -0
  28. package/dist/components/mfa/MfaStatusChip.d.ts +10 -0
  29. package/dist/components/mfa/MfaStatusChip.js +29 -0
  30. package/dist/components/mfa/MfaStatusChip.js.map +1 -0
  31. package/dist/components/mfa/MfaSuccessSnackbar.d.ts +10 -0
  32. package/dist/components/mfa/MfaSuccessSnackbar.js +17 -0
  33. package/dist/components/mfa/MfaSuccessSnackbar.js.map +1 -0
  34. package/dist/components/mfa/MultiFactorAuthentication.d.ts +1 -2
  35. package/dist/components/mfa/MultiFactorAuthentication.js +30 -30
  36. package/dist/components/mfa/MultiFactorAuthentication.js.map +1 -1
  37. package/dist/hooks/useLogin.d.ts +14 -8
  38. package/dist/hooks/useLogin.js +16 -6
  39. package/dist/hooks/useLogin.js.map +1 -1
  40. package/dist/hooks/useMfa.d.ts +46 -14
  41. package/dist/hooks/useMfa.js +388 -43
  42. package/dist/hooks/useMfa.js.map +1 -1
  43. package/dist/index.d.ts +7 -0
  44. package/dist/index.js +7 -0
  45. package/dist/index.js.map +1 -1
  46. package/package.json +2 -2
  47. package/dist/components/mfa/MfaDialog.d.ts +0 -9
  48. package/dist/components/mfa/MfaDialog.js +0 -47
  49. package/dist/components/mfa/MfaDialog.js.map +0 -1
@@ -4,19 +4,39 @@ type MfaState = {
4
4
  isExternalIdentityProviderUser: boolean;
5
5
  isLoading: boolean;
6
6
  isMfaEnabled: boolean;
7
+ mfaSettings: authService.MfaSettings;
8
+ isSetupSuccessOpen: boolean;
7
9
  loadingError?: Error;
8
10
  isSettingUpMfa: boolean;
9
- isDisablingMfa: boolean;
11
+ settingUpMfaMethod?: authService.MfaMethod;
12
+ isSetupMethodDialogOpen: boolean;
13
+ disablingMfaMethod?: authService.MfaMethod;
14
+ isSettingPreferredMfaMethod: boolean;
10
15
  setupError?: Error;
11
- mfaSetup?: Awaited<ReturnType<typeof authService.setupMfa>>;
16
+ mfaAuthenticatorAppSetup?: Awaited<ReturnType<typeof authService.setupMfaAuthenticatorApp>>;
17
+ isPhoneNumberDialogOpen: boolean;
18
+ phoneVerificationCodeSentAt?: number;
19
+ isRemovePhoneNumberDialogOpen: boolean;
12
20
  };
13
21
  export declare const MfaContext: React.Context<MfaState & {
14
- beginMfaSetup: () => void;
15
- cancelMfaSetup: () => void;
16
- completeMfaSetup: () => void;
17
- beginDisablingMfa: () => void;
22
+ beginMfaSetup: (mfaMethod: authService.MfaMethod) => Promise<void>;
23
+ openMfaSetupMethodDialog: () => void;
24
+ closeMfaSetupMethodDialog: () => void;
25
+ beginDisablingMfaMethod: (mfaMethod: authService.MfaMethod) => void;
26
+ setPreferredMfaMethod: (mfaMethod: authService.MfaMethod) => Promise<void>;
27
+ openPhoneNumberDialog: () => void;
28
+ closePhoneNumberDialog: () => void;
29
+ savePhoneNumber: (phoneNumber: string) => Promise<void>;
30
+ verifyPhoneNumber: (code: string) => Promise<void>;
31
+ resendPhoneNumberVerificationCode: () => Promise<void>;
32
+ beginRemovingPhoneNumber: () => void;
33
+ cancelRemovingPhoneNumber: () => void;
34
+ completeRemovingPhoneNumber: () => Promise<void>;
35
+ hideSetupSuccess: () => void;
36
+ cancelMfaAuthenticatorAppSetup: () => void;
37
+ completeMfaAuthenticatorAppSetup: () => Promise<void>;
18
38
  cancelDisablingMfa: () => void;
19
- completeDisablingMfa: () => void;
39
+ completeDisablingMfa: () => Promise<void>;
20
40
  clearMfaSetupError: () => void;
21
41
  loadMfa: () => void;
22
42
  }>;
@@ -65,19 +85,31 @@ export declare function MfaProvider({ children, isExternalIdentityProviderUser,
65
85
  isExternalIdentityProviderUser: boolean;
66
86
  }): import("react/jsx-runtime").JSX.Element;
67
87
  export default function useMfa(): MfaState & {
68
- beginMfaSetup: () => void;
69
- cancelMfaSetup: () => void;
70
- completeMfaSetup: () => void;
71
- beginDisablingMfa: () => void;
88
+ beginMfaSetup: (mfaMethod: authService.MfaMethod) => Promise<void>;
89
+ openMfaSetupMethodDialog: () => void;
90
+ closeMfaSetupMethodDialog: () => void;
91
+ beginDisablingMfaMethod: (mfaMethod: authService.MfaMethod) => void;
92
+ setPreferredMfaMethod: (mfaMethod: authService.MfaMethod) => Promise<void>;
93
+ openPhoneNumberDialog: () => void;
94
+ closePhoneNumberDialog: () => void;
95
+ savePhoneNumber: (phoneNumber: string) => Promise<void>;
96
+ verifyPhoneNumber: (code: string) => Promise<void>;
97
+ resendPhoneNumberVerificationCode: () => Promise<void>;
98
+ beginRemovingPhoneNumber: () => void;
99
+ cancelRemovingPhoneNumber: () => void;
100
+ completeRemovingPhoneNumber: () => Promise<void>;
101
+ hideSetupSuccess: () => void;
102
+ cancelMfaAuthenticatorAppSetup: () => void;
103
+ completeMfaAuthenticatorAppSetup: () => Promise<void>;
72
104
  cancelDisablingMfa: () => void;
73
- completeDisablingMfa: () => void;
105
+ completeDisablingMfa: () => Promise<void>;
74
106
  clearMfaSetupError: () => void;
75
107
  loadMfa: () => void;
76
108
  };
77
109
  /**
78
110
  * React hook to check if the logged in user meets the MFA requirement of your
79
- * application. Will throw an Error if used outside of the `<MfaProvider />`
80
- * component.
111
+ * application. Will throw an Error if used outside of the
112
+ * `<MfaProvider />` component.
81
113
  *
82
114
  * Example
83
115
  *
@@ -1,21 +1,83 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import * as React from 'react';
3
3
  import { authService } from '../apps';
4
+ import useLoadDataEffect from './useLoadDataEffect';
4
5
  export const MfaContext = React.createContext({
5
6
  isExternalIdentityProviderUser: false,
6
7
  isLoading: true,
7
8
  isMfaEnabled: false,
9
+ mfaSettings: authService.DEFAULT_MFA_SETTINGS,
10
+ isSetupSuccessOpen: false,
8
11
  isSettingUpMfa: false,
9
- isDisablingMfa: false,
10
- beginMfaSetup: () => { },
11
- cancelMfaSetup: () => { },
12
- completeMfaSetup: () => { },
13
- beginDisablingMfa: () => { },
12
+ isSetupMethodDialogOpen: false,
13
+ isSettingPreferredMfaMethod: false,
14
+ isPhoneNumberDialogOpen: false,
15
+ isRemovePhoneNumberDialogOpen: false,
16
+ beginMfaSetup: async () => { },
17
+ openMfaSetupMethodDialog: () => { },
18
+ closeMfaSetupMethodDialog: () => { },
19
+ beginDisablingMfaMethod: () => { },
20
+ setPreferredMfaMethod: async () => { },
21
+ openPhoneNumberDialog: () => { },
22
+ closePhoneNumberDialog: () => { },
23
+ savePhoneNumber: async () => { },
24
+ verifyPhoneNumber: async () => { },
25
+ resendPhoneNumberVerificationCode: async () => { },
26
+ beginRemovingPhoneNumber: () => { },
27
+ cancelRemovingPhoneNumber: () => { },
28
+ completeRemovingPhoneNumber: async () => { },
29
+ hideSetupSuccess: () => { },
30
+ cancelMfaAuthenticatorAppSetup: () => { },
31
+ completeMfaAuthenticatorAppSetup: async () => { },
14
32
  cancelDisablingMfa: () => { },
15
- completeDisablingMfa: () => { },
33
+ completeDisablingMfa: async () => { },
16
34
  clearMfaSetupError: () => { },
17
35
  loadMfa: () => { },
18
36
  });
37
+ function getIsMfaEnabled(mfaSettings) {
38
+ return mfaSettings.authenticator.enabled || mfaSettings.sms.enabled;
39
+ }
40
+ function hasPreferredMfaMethod(mfaSettings) {
41
+ return ((mfaSettings.authenticator.enabled &&
42
+ mfaSettings.authenticator.preferred) ||
43
+ (mfaSettings.sms.enabled && mfaSettings.sms.preferred));
44
+ }
45
+ function enableSmsMfaInSettings(mfaSettings, smsPreferred) {
46
+ return {
47
+ ...mfaSettings,
48
+ sms: {
49
+ ...mfaSettings.sms,
50
+ enabled: true,
51
+ preferred: smsPreferred,
52
+ },
53
+ };
54
+ }
55
+ function enableAuthenticatorMfaInSettings(mfaSettings, authenticatorPreferred) {
56
+ return {
57
+ ...mfaSettings,
58
+ authenticator: {
59
+ enabled: true,
60
+ preferred: authenticatorPreferred,
61
+ },
62
+ sms: {
63
+ ...mfaSettings.sms,
64
+ preferred: authenticatorPreferred ? false : mfaSettings.sms.preferred,
65
+ },
66
+ };
67
+ }
68
+ function setPreferredMfaMethodInSettings(mfaSettings, mfaMethod) {
69
+ return {
70
+ ...mfaSettings,
71
+ authenticator: {
72
+ ...mfaSettings.authenticator,
73
+ preferred: mfaMethod === 'authenticator',
74
+ },
75
+ sms: {
76
+ ...mfaSettings.sms,
77
+ preferred: mfaMethod === 'sms',
78
+ },
79
+ };
80
+ }
19
81
  /**
20
82
  * React Component that provides the context for the
21
83
  * `useUserMeetsMfaRequirement()` hook and `<MultiFactorAuthentication />`
@@ -61,112 +123,383 @@ export function MfaProvider({ children, isExternalIdentityProviderUser, }) {
61
123
  isExternalIdentityProviderUser,
62
124
  isLoading: !isExternalIdentityProviderUser,
63
125
  isMfaEnabled: false,
126
+ mfaSettings: authService.DEFAULT_MFA_SETTINGS,
127
+ isSetupSuccessOpen: false,
64
128
  isSettingUpMfa: false,
65
- isDisablingMfa: false,
129
+ isSetupMethodDialogOpen: false,
130
+ isSettingPreferredMfaMethod: false,
131
+ isPhoneNumberDialogOpen: false,
132
+ isRemovePhoneNumberDialogOpen: false,
66
133
  });
67
- const loadMfa = React.useCallback(async (abortSignal) => {
134
+ const handleLoadMfa = React.useCallback(async (abortSignal) => {
135
+ if (isExternalIdentityProviderUser) {
136
+ return;
137
+ }
68
138
  setState((currentState) => ({
69
139
  ...currentState,
70
140
  isLoading: true,
71
141
  isMfaEnabled: false,
142
+ mfaSettings: authService.DEFAULT_MFA_SETTINGS,
72
143
  loadingError: undefined,
73
144
  }));
74
145
  try {
75
- const newIsMfaEnabled = await authService.checkIsMfaEnabled();
76
- if (!(abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.aborted)) {
146
+ const mfaSettings = await authService.getMfaSettings(abortSignal);
147
+ if (!abortSignal.aborted) {
77
148
  setState((currentState) => ({
78
149
  ...currentState,
79
150
  isLoading: false,
80
- isMfaEnabled: newIsMfaEnabled,
151
+ mfaSettings,
152
+ isMfaEnabled: getIsMfaEnabled(mfaSettings),
81
153
  }));
82
154
  }
83
155
  }
84
156
  catch (error) {
157
+ if (abortSignal.aborted) {
158
+ return;
159
+ }
85
160
  setState((currentState) => ({
86
161
  ...currentState,
87
162
  isLoading: false,
88
163
  loadingError: error,
89
164
  }));
90
165
  }
91
- }, []);
166
+ }, [isExternalIdentityProviderUser]);
167
+ const loadMfa = useLoadDataEffect(handleLoadMfa);
92
168
  const clearMfaSetupError = React.useCallback(() => {
93
169
  setState((currentState) => ({
94
170
  ...currentState,
95
171
  setupError: undefined,
96
172
  }));
97
173
  }, []);
98
- const cancelMfaSetup = React.useCallback(() => {
174
+ const openMfaSetupMethodDialog = React.useCallback(() => {
175
+ setState((currentState) => ({
176
+ ...currentState,
177
+ isSetupMethodDialogOpen: true,
178
+ }));
179
+ }, []);
180
+ const closeMfaSetupMethodDialog = React.useCallback(() => {
99
181
  setState((currentState) => ({
100
182
  ...currentState,
101
- mfaSetup: undefined,
183
+ isSetupMethodDialogOpen: false,
102
184
  }));
103
185
  }, []);
104
- const completeMfaSetup = React.useCallback(() => {
186
+ const hideSetupSuccess = React.useCallback(() => {
105
187
  setState((currentState) => ({
106
188
  ...currentState,
107
- isMfaEnabled: true,
108
- mfaSetup: undefined,
189
+ isSetupSuccessOpen: false,
109
190
  }));
110
191
  }, []);
111
- const beginMfaSetup = React.useCallback(async () => {
192
+ const cancelMfaAuthenticatorAppSetup = React.useCallback(() => {
193
+ setState((currentState) => ({
194
+ ...currentState,
195
+ mfaAuthenticatorAppSetup: undefined,
196
+ settingUpMfaMethod: undefined,
197
+ }));
198
+ }, []);
199
+ const completeMfaAuthenticatorAppSetup = React.useCallback(async () => {
200
+ setState((currentState) => {
201
+ const authenticatorPreferred = !hasPreferredMfaMethod(currentState.mfaSettings);
202
+ const mfaSettings = enableAuthenticatorMfaInSettings(currentState.mfaSettings, authenticatorPreferred);
203
+ return {
204
+ ...currentState,
205
+ isSetupSuccessOpen: true,
206
+ isMfaEnabled: getIsMfaEnabled(mfaSettings),
207
+ mfaSettings,
208
+ mfaAuthenticatorAppSetup: undefined,
209
+ settingUpMfaMethod: undefined,
210
+ };
211
+ });
212
+ }, []);
213
+ const openPhoneNumberDialog = React.useCallback(() => {
214
+ setState((currentState) => ({
215
+ ...currentState,
216
+ isPhoneNumberDialogOpen: true,
217
+ phoneVerificationCodeSentAt: undefined,
218
+ setupError: undefined,
219
+ }));
220
+ }, []);
221
+ const closePhoneNumberDialog = React.useCallback(() => {
222
+ setState((currentState) => ({
223
+ ...currentState,
224
+ isPhoneNumberDialogOpen: false,
225
+ phoneVerificationCodeSentAt: undefined,
226
+ }));
227
+ }, []);
228
+ const setupSmsMfaMethod = React.useCallback(async () => {
229
+ let smsPreferred = false;
230
+ setState((currentState) => {
231
+ smsPreferred = !hasPreferredMfaMethod(currentState.mfaSettings);
232
+ return currentState;
233
+ });
234
+ await authService.setupSmsMfa({
235
+ preferred: smsPreferred,
236
+ });
237
+ setState((currentState) => {
238
+ const mfaSettings = enableSmsMfaInSettings(currentState.mfaSettings, smsPreferred);
239
+ return {
240
+ ...currentState,
241
+ isSetupSuccessOpen: true,
242
+ isSettingUpMfa: false,
243
+ settingUpMfaMethod: undefined,
244
+ isMfaEnabled: getIsMfaEnabled(mfaSettings),
245
+ mfaSettings,
246
+ };
247
+ });
248
+ }, []);
249
+ const savePhoneNumber = React.useCallback(async (phoneNumber) => {
250
+ setState((currentState) => ({
251
+ ...currentState,
252
+ setupError: undefined,
253
+ }));
254
+ try {
255
+ const { isPhoneNumberVerified } = await authService.updateUserPhoneNumber(phoneNumber);
256
+ if (!isPhoneNumberVerified) {
257
+ setState((currentState) => ({
258
+ ...currentState,
259
+ phoneVerificationCodeSentAt: Date.now(),
260
+ mfaSettings: {
261
+ ...currentState.mfaSettings,
262
+ sms: {
263
+ ...currentState.mfaSettings.sms,
264
+ phoneNumber,
265
+ isPhoneNumberVerified: false,
266
+ },
267
+ },
268
+ }));
269
+ return;
270
+ }
271
+ setState((currentState) => ({
272
+ ...currentState,
273
+ mfaSettings: {
274
+ ...currentState.mfaSettings,
275
+ sms: {
276
+ ...currentState.mfaSettings.sms,
277
+ phoneNumber,
278
+ isPhoneNumberVerified,
279
+ },
280
+ },
281
+ isPhoneNumberDialogOpen: false,
282
+ phoneVerificationCodeSentAt: undefined,
283
+ }));
284
+ await setupSmsMfaMethod();
285
+ }
286
+ catch (error) {
287
+ setState((currentState) => ({
288
+ ...currentState,
289
+ setupError: error,
290
+ }));
291
+ }
292
+ }, [setupSmsMfaMethod]);
293
+ const verifyPhoneNumber = React.useCallback(async (code) => {
294
+ setState((currentState) => ({
295
+ ...currentState,
296
+ setupError: undefined,
297
+ }));
298
+ try {
299
+ await authService.verifyUserPhoneNumber(code);
300
+ setState((currentState) => ({
301
+ ...currentState,
302
+ mfaSettings: {
303
+ ...currentState.mfaSettings,
304
+ sms: {
305
+ ...currentState.mfaSettings.sms,
306
+ isPhoneNumberVerified: true,
307
+ },
308
+ },
309
+ isPhoneNumberDialogOpen: false,
310
+ phoneVerificationCodeSentAt: undefined,
311
+ }));
312
+ await setupSmsMfaMethod();
313
+ }
314
+ catch (error) {
315
+ setState((currentState) => ({
316
+ ...currentState,
317
+ setupError: error,
318
+ }));
319
+ }
320
+ }, [setupSmsMfaMethod]);
321
+ const resendPhoneNumberVerificationCode = React.useCallback(async () => {
322
+ setState((currentState) => ({
323
+ ...currentState,
324
+ setupError: undefined,
325
+ phoneVerificationCodeSentAt: Date.now(),
326
+ }));
327
+ try {
328
+ await authService.sendPhoneNumberVerificationCode();
329
+ }
330
+ catch (error) {
331
+ setState((currentState) => ({
332
+ ...currentState,
333
+ setupError: error,
334
+ }));
335
+ }
336
+ }, []);
337
+ const beginRemovingPhoneNumber = React.useCallback(() => {
338
+ setState((currentState) => ({
339
+ ...currentState,
340
+ isRemovePhoneNumberDialogOpen: true,
341
+ setupError: undefined,
342
+ }));
343
+ }, []);
344
+ const cancelRemovingPhoneNumber = React.useCallback(() => {
345
+ setState((currentState) => ({
346
+ ...currentState,
347
+ isRemovePhoneNumberDialogOpen: false,
348
+ }));
349
+ }, []);
350
+ const completeRemovingPhoneNumber = React.useCallback(async () => {
351
+ setState((currentState) => ({
352
+ ...currentState,
353
+ setupError: undefined,
354
+ }));
355
+ try {
356
+ await authService.removeUserPhoneNumber();
357
+ setState((currentState) => ({
358
+ ...currentState,
359
+ isRemovePhoneNumberDialogOpen: false,
360
+ mfaSettings: {
361
+ ...currentState.mfaSettings,
362
+ sms: {
363
+ ...currentState.mfaSettings.sms,
364
+ phoneNumber: undefined,
365
+ isPhoneNumberVerified: false,
366
+ },
367
+ },
368
+ }));
369
+ }
370
+ catch (error) {
371
+ setState((currentState) => ({
372
+ ...currentState,
373
+ setupError: error,
374
+ }));
375
+ }
376
+ }, []);
377
+ const beginMfaSetup = React.useCallback(async (mfaMethod) => {
112
378
  setState((currentState) => ({
113
379
  ...currentState,
114
380
  isSettingUpMfa: true,
115
- mfaSetup: undefined,
381
+ settingUpMfaMethod: mfaMethod,
382
+ mfaAuthenticatorAppSetup: undefined,
116
383
  setupError: undefined,
117
384
  }));
118
385
  try {
119
- const newMfaSetup = await authService.setupMfa();
386
+ let mfaSettings = authService.DEFAULT_MFA_SETTINGS;
387
+ setState((currentState) => {
388
+ mfaSettings = currentState.mfaSettings;
389
+ return currentState;
390
+ });
391
+ if (mfaMethod === 'sms') {
392
+ if (!mfaSettings.sms.phoneNumber ||
393
+ !mfaSettings.sms.isPhoneNumberVerified) {
394
+ setState((currentState) => ({
395
+ ...currentState,
396
+ isSettingUpMfa: false,
397
+ settingUpMfaMethod: undefined,
398
+ isSetupMethodDialogOpen: false,
399
+ isPhoneNumberDialogOpen: true,
400
+ }));
401
+ return;
402
+ }
403
+ await setupSmsMfaMethod();
404
+ setState((currentState) => ({
405
+ ...currentState,
406
+ isSetupMethodDialogOpen: false,
407
+ }));
408
+ return;
409
+ }
410
+ const hasPreferredMethod = hasPreferredMfaMethod(mfaSettings);
411
+ const newMfaAuthenticatorAppSetup = await authService.setupMfaAuthenticatorApp({
412
+ preferred: !hasPreferredMethod,
413
+ });
120
414
  setState((currentState) => ({
121
415
  ...currentState,
122
416
  isSettingUpMfa: false,
123
- mfaSetup: newMfaSetup,
417
+ isSetupMethodDialogOpen: false,
418
+ mfaAuthenticatorAppSetup: newMfaAuthenticatorAppSetup,
124
419
  }));
125
420
  }
126
421
  catch (error) {
127
422
  setState((currentState) => ({
128
423
  ...currentState,
129
424
  isSettingUpMfa: false,
425
+ settingUpMfaMethod: undefined,
130
426
  setupError: error,
131
427
  }));
132
428
  }
133
- }, []);
134
- const beginDisablingMfa = React.useCallback(() => {
429
+ }, [setupSmsMfaMethod]);
430
+ const disablingMfaMethodRef = React.useRef(undefined);
431
+ const beginDisablingMfaMethod = React.useCallback((mfaMethod) => {
432
+ disablingMfaMethodRef.current = mfaMethod;
135
433
  setState((currentState) => ({
136
434
  ...currentState,
137
- isDisablingMfa: true,
435
+ disablingMfaMethod: mfaMethod,
138
436
  }));
139
437
  }, []);
140
438
  const cancelDisablingMfa = React.useCallback(() => {
439
+ disablingMfaMethodRef.current = undefined;
141
440
  setState((currentState) => ({
142
441
  ...currentState,
143
- isDisablingMfa: false,
442
+ disablingMfaMethod: undefined,
144
443
  }));
145
444
  }, []);
146
445
  const completeDisablingMfa = React.useCallback(async () => {
147
- await authService.disableMfa();
446
+ const disablingMfaMethod = disablingMfaMethodRef.current;
447
+ if (!disablingMfaMethod) {
448
+ return;
449
+ }
450
+ await authService.disableMfaMethod(disablingMfaMethod);
451
+ const mfaSettings = await authService.getMfaSettings();
452
+ disablingMfaMethodRef.current = undefined;
148
453
  setState((currentState) => ({
149
454
  ...currentState,
150
- isDisablingMfa: false,
151
- isMfaEnabled: false,
455
+ disablingMfaMethod: undefined,
456
+ mfaSettings,
457
+ isMfaEnabled: getIsMfaEnabled(mfaSettings),
152
458
  }));
153
459
  }, []);
154
- React.useEffect(() => {
155
- if (isExternalIdentityProviderUser) {
156
- return;
460
+ const setPreferredMfaMethod = React.useCallback(async (mfaMethod) => {
461
+ setState((currentState) => ({
462
+ ...currentState,
463
+ isSettingPreferredMfaMethod: true,
464
+ setupError: undefined,
465
+ }));
466
+ try {
467
+ await authService.setPreferredMfaMethod(mfaMethod);
468
+ setState((currentState) => ({
469
+ ...currentState,
470
+ isSettingPreferredMfaMethod: false,
471
+ mfaSettings: setPreferredMfaMethodInSettings(currentState.mfaSettings, mfaMethod),
472
+ }));
473
+ }
474
+ catch (error) {
475
+ setState((currentState) => ({
476
+ ...currentState,
477
+ isSettingPreferredMfaMethod: false,
478
+ setupError: error,
479
+ }));
157
480
  }
158
- loadMfa();
159
- return () => { };
160
- }, [isExternalIdentityProviderUser, loadMfa]);
481
+ }, []);
161
482
  const value = React.useMemo(() => {
162
483
  return {
163
484
  ...state,
164
485
  clearMfaSetupError,
165
486
  loadMfa,
166
487
  beginMfaSetup,
167
- cancelMfaSetup,
168
- completeMfaSetup,
169
- beginDisablingMfa,
488
+ openMfaSetupMethodDialog,
489
+ closeMfaSetupMethodDialog,
490
+ beginDisablingMfaMethod,
491
+ setPreferredMfaMethod,
492
+ openPhoneNumberDialog,
493
+ closePhoneNumberDialog,
494
+ savePhoneNumber,
495
+ verifyPhoneNumber,
496
+ resendPhoneNumberVerificationCode,
497
+ beginRemovingPhoneNumber,
498
+ cancelRemovingPhoneNumber,
499
+ completeRemovingPhoneNumber,
500
+ hideSetupSuccess,
501
+ cancelMfaAuthenticatorAppSetup,
502
+ completeMfaAuthenticatorAppSetup,
170
503
  cancelDisablingMfa,
171
504
  completeDisablingMfa,
172
505
  };
@@ -175,21 +508,33 @@ export function MfaProvider({ children, isExternalIdentityProviderUser, }) {
175
508
  clearMfaSetupError,
176
509
  loadMfa,
177
510
  beginMfaSetup,
178
- cancelMfaSetup,
179
- completeMfaSetup,
180
- beginDisablingMfa,
511
+ openMfaSetupMethodDialog,
512
+ closeMfaSetupMethodDialog,
513
+ beginDisablingMfaMethod,
514
+ setPreferredMfaMethod,
515
+ openPhoneNumberDialog,
516
+ closePhoneNumberDialog,
517
+ savePhoneNumber,
518
+ verifyPhoneNumber,
519
+ resendPhoneNumberVerificationCode,
520
+ beginRemovingPhoneNumber,
521
+ cancelRemovingPhoneNumber,
522
+ completeRemovingPhoneNumber,
523
+ hideSetupSuccess,
524
+ cancelMfaAuthenticatorAppSetup,
525
+ completeMfaAuthenticatorAppSetup,
181
526
  cancelDisablingMfa,
182
527
  completeDisablingMfa,
183
528
  ]);
184
- return _jsx(MfaContext.Provider, { value: value, children: children });
529
+ return (_jsx(MfaContext.Provider, { value: value, children: children }));
185
530
  }
186
531
  export default function useMfa() {
187
532
  return React.useContext(MfaContext);
188
533
  }
189
534
  /**
190
535
  * React hook to check if the logged in user meets the MFA requirement of your
191
- * application. Will throw an Error if used outside of the `<MfaProvider />`
192
- * component.
536
+ * application. Will throw an Error if used outside of the
537
+ * `<MfaProvider />` component.
193
538
  *
194
539
  * Example
195
540
  *