@digitaldefiance/express-suite-react-components 2.9.6 → 2.9.9

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 (257) hide show
  1. package/package.json +6 -5
  2. package/src/auth/Private.d.ts +6 -0
  3. package/src/auth/Private.d.ts.map +1 -0
  4. package/src/auth/Private.js +14 -0
  5. package/src/auth/PrivateRoute.d.ts +8 -0
  6. package/src/auth/PrivateRoute.d.ts.map +1 -0
  7. package/src/auth/PrivateRoute.js +23 -0
  8. package/src/auth/UnAuth.d.ts +6 -0
  9. package/src/auth/UnAuth.d.ts.map +1 -0
  10. package/src/auth/UnAuth.js +14 -0
  11. package/src/auth/UnAuthRoute.d.ts +8 -0
  12. package/src/auth/UnAuthRoute.d.ts.map +1 -0
  13. package/src/auth/UnAuthRoute.js +22 -0
  14. package/src/auth/{index.ts → index.d.ts} +2 -1
  15. package/src/auth/index.d.ts.map +1 -0
  16. package/src/auth/index.js +10 -0
  17. package/src/components/ApiAccess.d.ts +16 -0
  18. package/src/components/ApiAccess.d.ts.map +1 -0
  19. package/src/components/ApiAccess.js +70 -0
  20. package/src/components/BackupCodeLoginForm.d.ts +43 -0
  21. package/src/components/BackupCodeLoginForm.d.ts.map +1 -0
  22. package/src/components/BackupCodeLoginForm.js +106 -0
  23. package/src/components/BackupCodesForm.d.ts +26 -0
  24. package/src/components/BackupCodesForm.d.ts.map +1 -0
  25. package/src/components/BackupCodesForm.js +108 -0
  26. package/src/components/ChangePasswordForm.d.ts +26 -0
  27. package/src/components/ChangePasswordForm.d.ts.map +1 -0
  28. package/src/components/ChangePasswordForm.js +66 -0
  29. package/src/components/ConfirmationDialog.d.ts +13 -0
  30. package/src/components/ConfirmationDialog.d.ts.map +1 -0
  31. package/src/components/ConfirmationDialog.js +10 -0
  32. package/src/components/CurrencyCodeSelector.d.ts +9 -0
  33. package/src/components/CurrencyCodeSelector.d.ts.map +1 -0
  34. package/src/components/CurrencyCodeSelector.js +31 -0
  35. package/src/components/CurrencyInput.d.ts +13 -0
  36. package/src/components/CurrencyInput.d.ts.map +1 -0
  37. package/src/components/CurrencyInput.js +22 -0
  38. package/src/components/DashboardPage.d.ts +8 -0
  39. package/src/components/DashboardPage.d.ts.map +1 -0
  40. package/src/components/DashboardPage.js +10 -0
  41. package/src/components/DropdownMenu.d.ts +9 -0
  42. package/src/components/DropdownMenu.d.ts.map +1 -0
  43. package/src/components/DropdownMenu.js +56 -0
  44. package/src/components/ExpirationSecondsSelector.d.ts +13 -0
  45. package/src/components/ExpirationSecondsSelector.d.ts.map +1 -0
  46. package/src/components/ExpirationSecondsSelector.js +32 -0
  47. package/src/components/Flag.d.ts +20 -0
  48. package/src/components/Flag.d.ts.map +1 -0
  49. package/src/components/Flag.js +43 -0
  50. package/src/components/ForgotPasswordForm.d.ts +18 -0
  51. package/src/components/ForgotPasswordForm.d.ts.map +1 -0
  52. package/src/components/ForgotPasswordForm.js +54 -0
  53. package/src/components/LoginForm.d.ts +44 -0
  54. package/src/components/LoginForm.d.ts.map +1 -0
  55. package/src/components/LoginForm.js +99 -0
  56. package/src/components/LogoutPage.d.ts +8 -0
  57. package/src/components/LogoutPage.d.ts.map +1 -0
  58. package/src/components/LogoutPage.js +16 -0
  59. package/src/components/RegisterForm.d.ts +54 -0
  60. package/src/components/RegisterForm.d.ts.map +1 -0
  61. package/src/components/RegisterForm.js +105 -0
  62. package/src/components/ResetPasswordForm.d.ts +23 -0
  63. package/src/components/ResetPasswordForm.d.ts.map +1 -0
  64. package/src/components/ResetPasswordForm.js +68 -0
  65. package/src/components/SideMenu.d.ts +8 -0
  66. package/src/components/SideMenu.d.ts.map +1 -0
  67. package/src/components/SideMenu.js +25 -0
  68. package/src/components/SideMenuListItem.d.ts +13 -0
  69. package/src/components/SideMenuListItem.d.ts.map +1 -0
  70. package/src/components/SideMenuListItem.js +44 -0
  71. package/src/components/TopMenu.d.ts +24 -0
  72. package/src/components/TopMenu.d.ts.map +1 -0
  73. package/src/components/TopMenu.js +42 -0
  74. package/src/components/TranslatedTitle.d.ts +7 -0
  75. package/src/components/TranslatedTitle.d.ts.map +1 -0
  76. package/src/components/TranslatedTitle.js +15 -0
  77. package/src/components/UserLanguageSelector.d.ts +4 -0
  78. package/src/components/UserLanguageSelector.d.ts.map +1 -0
  79. package/src/components/UserLanguageSelector.js +31 -0
  80. package/src/components/UserMenu.d.ts +4 -0
  81. package/src/components/UserMenu.d.ts.map +1 -0
  82. package/src/components/UserMenu.js +12 -0
  83. package/src/components/UserSettingsForm.d.ts +56 -0
  84. package/src/components/UserSettingsForm.d.ts.map +1 -0
  85. package/src/components/UserSettingsForm.js +93 -0
  86. package/src/components/VerifyEmailPage.d.ts +23 -0
  87. package/src/components/VerifyEmailPage.d.ts.map +1 -0
  88. package/src/components/VerifyEmailPage.js +61 -0
  89. package/src/components/{index.ts → index.d.ts} +1 -1
  90. package/src/components/index.d.ts.map +1 -0
  91. package/src/components/index.js +28 -0
  92. package/src/contexts/AuthProvider.d.ts +152 -0
  93. package/src/contexts/AuthProvider.d.ts.map +1 -0
  94. package/src/contexts/AuthProvider.js +446 -0
  95. package/src/contexts/I18nProvider.d.ts +16 -0
  96. package/src/contexts/I18nProvider.d.ts.map +1 -0
  97. package/src/contexts/I18nProvider.js +46 -0
  98. package/src/contexts/MenuContext.d.ts +20 -0
  99. package/src/contexts/MenuContext.d.ts.map +1 -0
  100. package/src/contexts/MenuContext.js +244 -0
  101. package/src/contexts/SuiteConfigProvider.d.ts +44 -0
  102. package/src/contexts/SuiteConfigProvider.d.ts.map +1 -0
  103. package/src/contexts/SuiteConfigProvider.js +43 -0
  104. package/src/contexts/ThemeProvider.d.ts +15 -0
  105. package/src/contexts/ThemeProvider.d.ts.map +1 -0
  106. package/src/contexts/ThemeProvider.js +36 -0
  107. package/src/contexts/{index.ts → index.d.ts} +1 -0
  108. package/src/contexts/index.d.ts.map +1 -0
  109. package/src/contexts/index.js +8 -0
  110. package/src/hooks/{index.ts → index.d.ts} +1 -0
  111. package/src/hooks/index.d.ts.map +1 -0
  112. package/src/hooks/index.js +8 -0
  113. package/src/hooks/useBackupCodes.d.ts +15 -0
  114. package/src/hooks/useBackupCodes.d.ts.map +1 -0
  115. package/src/hooks/useBackupCodes.js +70 -0
  116. package/src/hooks/useEmailVerification.d.ts +10 -0
  117. package/src/hooks/useEmailVerification.d.ts.map +1 -0
  118. package/src/hooks/useEmailVerification.js +36 -0
  119. package/src/hooks/useExpiringValue.d.ts +14 -0
  120. package/src/hooks/useExpiringValue.d.ts.map +1 -0
  121. package/src/hooks/useExpiringValue.js +53 -0
  122. package/src/hooks/useLocalStorage.d.ts +2 -0
  123. package/src/hooks/useLocalStorage.d.ts.map +1 -0
  124. package/src/hooks/useLocalStorage.js +15 -0
  125. package/src/hooks/useUserSettings.d.ts +46 -0
  126. package/src/hooks/useUserSettings.d.ts.map +1 -0
  127. package/src/hooks/useUserSettings.js +152 -0
  128. package/src/{index.ts → index.d.ts} +1 -1
  129. package/src/index.d.ts.map +1 -0
  130. package/src/index.js +12 -0
  131. package/src/interfaces/IAppConfig.d.ts +6 -0
  132. package/src/interfaces/IAppConfig.d.ts.map +1 -0
  133. package/src/interfaces/IAppConfig.js +2 -0
  134. package/src/interfaces/IMenuConfig.d.ts +11 -0
  135. package/src/interfaces/IMenuConfig.d.ts.map +1 -0
  136. package/src/interfaces/IMenuConfig.js +2 -0
  137. package/src/interfaces/IMenuOption.d.ts +58 -0
  138. package/src/interfaces/IMenuOption.d.ts.map +1 -0
  139. package/src/interfaces/IMenuOption.js +2 -0
  140. package/src/interfaces/index.d.ts +4 -0
  141. package/src/interfaces/index.d.ts.map +1 -0
  142. package/src/interfaces/index.js +6 -0
  143. package/src/services/__mocks__/authService.d.ts +21 -0
  144. package/src/services/__mocks__/authService.d.ts.map +1 -0
  145. package/src/services/__mocks__/authService.js +15 -0
  146. package/src/services/api.d.ts +3 -0
  147. package/src/services/api.d.ts.map +1 -0
  148. package/src/services/api.js +14 -0
  149. package/src/services/authService.d.ts +72 -0
  150. package/src/services/authService.d.ts.map +1 -0
  151. package/src/services/authService.js +347 -0
  152. package/src/services/authenticatedApi.d.ts +3 -0
  153. package/src/services/authenticatedApi.d.ts.map +1 -0
  154. package/src/services/authenticatedApi.js +18 -0
  155. package/src/services/index.d.ts +4 -0
  156. package/src/services/index.d.ts.map +1 -0
  157. package/src/services/index.js +6 -0
  158. package/src/types/MenuType.d.ts +11 -0
  159. package/src/types/MenuType.d.ts.map +1 -0
  160. package/src/types/MenuType.js +12 -0
  161. package/src/types/expirationSeconds.d.ts +3 -0
  162. package/src/types/expirationSeconds.d.ts.map +1 -0
  163. package/src/types/expirationSeconds.js +17 -0
  164. package/src/types/index.d.ts +2 -0
  165. package/src/types/index.d.ts.map +1 -0
  166. package/src/types/index.js +4 -0
  167. package/src/types/translation.d.ts +10 -0
  168. package/src/types/translation.d.ts.map +1 -0
  169. package/src/types/translation.js +9 -0
  170. package/src/wrappers/BackupCodeLoginWrapper.d.ts +8 -0
  171. package/src/wrappers/BackupCodeLoginWrapper.d.ts.map +1 -0
  172. package/src/wrappers/BackupCodeLoginWrapper.js +21 -0
  173. package/src/wrappers/BackupCodesWrapper.d.ts +7 -0
  174. package/src/wrappers/BackupCodesWrapper.d.ts.map +1 -0
  175. package/src/wrappers/BackupCodesWrapper.js +17 -0
  176. package/src/wrappers/ChangePasswordFormWrapper.d.ts +8 -0
  177. package/src/wrappers/ChangePasswordFormWrapper.d.ts.map +1 -0
  178. package/src/wrappers/ChangePasswordFormWrapper.js +21 -0
  179. package/src/wrappers/LoginFormWrapper.d.ts +9 -0
  180. package/src/wrappers/LoginFormWrapper.d.ts.map +1 -0
  181. package/src/wrappers/LoginFormWrapper.js +43 -0
  182. package/src/wrappers/LogoutPageWrapper.d.ts +9 -0
  183. package/src/wrappers/LogoutPageWrapper.d.ts.map +1 -0
  184. package/src/wrappers/LogoutPageWrapper.js +21 -0
  185. package/src/wrappers/RegisterFormWrapper.d.ts +9 -0
  186. package/src/wrappers/RegisterFormWrapper.d.ts.map +1 -0
  187. package/src/wrappers/RegisterFormWrapper.js +26 -0
  188. package/src/wrappers/UserSettingsFormWrapper.d.ts +8 -0
  189. package/src/wrappers/UserSettingsFormWrapper.d.ts.map +1 -0
  190. package/src/wrappers/UserSettingsFormWrapper.js +24 -0
  191. package/src/wrappers/VerifyEmailPageWrapper.d.ts +8 -0
  192. package/src/wrappers/VerifyEmailPageWrapper.d.ts.map +1 -0
  193. package/src/wrappers/VerifyEmailPageWrapper.js +20 -0
  194. package/src/wrappers/{index.tsx → index.d.ts} +1 -8
  195. package/src/wrappers/index.d.ts.map +1 -0
  196. package/src/wrappers/index.js +20 -0
  197. package/LICENSE +0 -21
  198. package/src/auth/Private.tsx +0 -17
  199. package/src/auth/PrivateRoute.tsx +0 -28
  200. package/src/auth/UnAuth.tsx +0 -16
  201. package/src/auth/UnAuthRoute.tsx +0 -30
  202. package/src/components/ApiAccess.tsx +0 -134
  203. package/src/components/BackupCodeLoginForm.tsx +0 -314
  204. package/src/components/BackupCodesForm.tsx +0 -198
  205. package/src/components/ChangePasswordForm.tsx +0 -182
  206. package/src/components/ConfirmationDialog.tsx +0 -48
  207. package/src/components/CurrencyCodeSelector.tsx +0 -60
  208. package/src/components/CurrencyInput.tsx +0 -80
  209. package/src/components/DashboardPage.tsx +0 -24
  210. package/src/components/DropdownMenu.tsx +0 -92
  211. package/src/components/ExpirationSecondsSelector.tsx +0 -65
  212. package/src/components/Flag.tsx +0 -53
  213. package/src/components/ForgotPasswordForm.tsx +0 -120
  214. package/src/components/LoginForm.tsx +0 -307
  215. package/src/components/LogoutPage.tsx +0 -21
  216. package/src/components/RegisterForm.tsx +0 -354
  217. package/src/components/ResetPasswordForm.tsx +0 -164
  218. package/src/components/SideMenu.tsx +0 -46
  219. package/src/components/SideMenuListItem.tsx +0 -74
  220. package/src/components/TopMenu.tsx +0 -149
  221. package/src/components/TranslatedTitle.tsx +0 -22
  222. package/src/components/UserLanguageSelector.tsx +0 -45
  223. package/src/components/UserMenu.tsx +0 -15
  224. package/src/components/UserSettingsForm.tsx +0 -328
  225. package/src/components/VerifyEmailPage.tsx +0 -133
  226. package/src/contexts/AuthProvider.spec.tsx +0 -1060
  227. package/src/contexts/AuthProvider.tsx +0 -741
  228. package/src/contexts/I18nProvider.tsx +0 -85
  229. package/src/contexts/MenuContext.tsx +0 -310
  230. package/src/contexts/SuiteConfigProvider.tsx +0 -93
  231. package/src/contexts/ThemeProvider.tsx +0 -67
  232. package/src/hooks/useBackupCodes.ts +0 -85
  233. package/src/hooks/useEmailVerification.ts +0 -39
  234. package/src/hooks/useExpiringValue.ts +0 -78
  235. package/src/hooks/useLocalStorage.ts +0 -18
  236. package/src/hooks/useUserSettings.ts +0 -216
  237. package/src/interfaces/IAppConfig.ts +0 -5
  238. package/src/interfaces/IMenuConfig.ts +0 -11
  239. package/src/interfaces/IMenuOption.ts +0 -55
  240. package/src/interfaces/index.ts +0 -3
  241. package/src/services/__mocks__/authService.ts +0 -14
  242. package/src/services/api.ts +0 -13
  243. package/src/services/authService.ts +0 -422
  244. package/src/services/authenticatedApi.ts +0 -17
  245. package/src/services/index.ts +0 -3
  246. package/src/types/MenuType.ts +0 -15
  247. package/src/types/expirationSeconds.ts +0 -18
  248. package/src/types/index.ts +0 -1
  249. package/src/types/translation.ts +0 -20
  250. package/src/wrappers/BackupCodeLoginWrapper.tsx +0 -35
  251. package/src/wrappers/BackupCodesWrapper.tsx +0 -28
  252. package/src/wrappers/ChangePasswordFormWrapper.tsx +0 -31
  253. package/src/wrappers/LoginFormWrapper.tsx +0 -59
  254. package/src/wrappers/LogoutPageWrapper.tsx +0 -30
  255. package/src/wrappers/RegisterFormWrapper.tsx +0 -48
  256. package/src/wrappers/UserSettingsFormWrapper.tsx +0 -39
  257. package/src/wrappers/VerifyEmailPageWrapper.tsx +0 -27
@@ -1,314 +0,0 @@
1
- import {
2
- Box,
3
- Button,
4
- Checkbox,
5
- Container,
6
- FormControlLabel,
7
- TextField,
8
- Typography,
9
- } from '@mui/material';
10
- import { useFormik } from 'formik';
11
- import { FC, useState } from 'react';
12
- import * as Yup from 'yup';
13
- import { Constants, SuiteCoreComponentId, SuiteCoreStringKey } from '@digitaldefiance/suite-core-lib';
14
- import { useI18n } from '../contexts';
15
-
16
- export interface BackupCodeLoginFormValues {
17
- email: string;
18
- username: string;
19
- code: string;
20
- newPassword?: string;
21
- confirmNewPassword?: string;
22
- recoverMnemonic: boolean;
23
- }
24
-
25
- export interface BackupCodeLoginFormProps {
26
- onSubmit: (
27
- identifier: string,
28
- code: string,
29
- isEmail: boolean,
30
- recoverMnemonic: boolean,
31
- newPassword?: string
32
- ) => Promise<
33
- | { token: string; codeCount: number; mnemonic?: string; message?: string }
34
- | { error: string; status?: number }
35
- >;
36
- onNavigate?: (path: string, state?: any) => void;
37
- isAuthenticated?: boolean;
38
- validationSchema?: Yup.ObjectSchema<any>;
39
- labels?: {
40
- title?: string;
41
- email?: string;
42
- username?: string;
43
- code?: string;
44
- newPassword?: string;
45
- confirmPassword?: string;
46
- recoverMnemonic?: string;
47
- login?: string;
48
- useUsername?: string;
49
- useEmail?: string;
50
- dashboard?: string;
51
- generateNewCodes?: string;
52
- mnemonicLabel?: string;
53
- codesRemaining?: string;
54
- };
55
- }
56
-
57
- export const BackupCodeLoginForm: FC<BackupCodeLoginFormProps> = ({
58
- onSubmit,
59
- onNavigate,
60
- isAuthenticated = false,
61
- validationSchema,
62
- labels = {},
63
- }) => {
64
- const { tComponent } = useI18n();
65
- const [loginType, setLoginType] = useState<'email' | 'username'>('email');
66
- const [loginError, setLoginError] = useState<string | null>(null);
67
- const [recoveredMnemonic, setRecoveredMnemonic] = useState<string | null>(null);
68
- const [successMessage, setSuccessMessage] = useState<string | null>(null);
69
- const [codesRemaining, setCodesRemaining] = useState<number | null>(null);
70
-
71
- const translatedLabels = {
72
- title: labels.title || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.BackupCodeRecovery_Title),
73
- email: labels.email || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_Email),
74
- username: labels.username || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_Username),
75
- code: labels.code || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_BackupCode),
76
- newPassword: labels.newPassword || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_NewPassword),
77
- confirmPassword: labels.confirmPassword || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_ConfirmNewPassword),
78
- recoverMnemonic: labels.recoverMnemonic || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.BackupCodeRecovery_RecoverMnemonic),
79
- login: labels.login || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.BackupCodeRecovery_Login),
80
- useUsername: labels.useUsername || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Login_UseUsername),
81
- useEmail: labels.useEmail || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Login_UseEmailAddress),
82
- dashboard: labels.dashboard || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_Dashboard),
83
- generateNewCodes: labels.generateNewCodes || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.BackupCodeRecovery_GenerateNewCodes),
84
- mnemonicLabel: labels.mnemonicLabel || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_Mnemonic),
85
- codesRemaining: labels.codesRemaining || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.BackupCodeRecovery_CodesRemainingTemplate),
86
- unexpectedError: tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_UnexpectedError),
87
- };
88
-
89
- const yupFieldValidation = {
90
- email: Yup.string()
91
- .email(tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_InvalidEmail))
92
- .required(tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_Required)),
93
- username: Yup.string()
94
- .matches(Constants.UsernameRegex, tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_UsernameRegexErrorTemplate))
95
- .required(tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_Required)),
96
- code: Yup.string()
97
- .required(tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_Required))
98
- .matches(Constants.BACKUP_CODES.DisplayRegex, tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_InvalidBackupCode)),
99
- password: Yup.string()
100
- .matches(Constants.PasswordRegex, tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_PasswordRegexErrorTemplate)),
101
- confirmPassword: Yup.string()
102
- .oneOf([Yup.ref('newPassword')], tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_PasswordMatch)),
103
- };
104
-
105
- const formik = useFormik<BackupCodeLoginFormValues>({
106
- initialValues: {
107
- email: '',
108
- username: '',
109
- code: '',
110
- newPassword: '',
111
- confirmNewPassword: '',
112
- recoverMnemonic: false,
113
- },
114
- validationSchema: validationSchema ?? Yup.object({
115
- [loginType]: loginType === 'email' ? yupFieldValidation.email : yupFieldValidation.username,
116
- code: yupFieldValidation.code,
117
- newPassword: yupFieldValidation.password,
118
- confirmNewPassword: yupFieldValidation.confirmPassword,
119
- }),
120
- enableReinitialize: true,
121
- onSubmit: async (values, { setSubmitting }) => {
122
- try {
123
- const loginResult = await onSubmit(
124
- loginType === 'email' ? values.email : values.username,
125
- values.code,
126
- loginType === 'email',
127
- values.recoverMnemonic,
128
- values.newPassword && values.newPassword.length > 0 ? values.newPassword : undefined
129
- );
130
- if ('error' in loginResult) {
131
- setLoginError(loginResult.error);
132
- setCodesRemaining(null);
133
- setRecoveredMnemonic(null);
134
- return;
135
- }
136
- setLoginError(null);
137
- if (loginResult.codeCount) {
138
- setCodesRemaining(loginResult.codeCount);
139
- }
140
- if (loginResult.mnemonic) {
141
- setRecoveredMnemonic(loginResult.mnemonic);
142
- }
143
- if (loginResult.message) {
144
- setSuccessMessage(loginResult.message);
145
- }
146
- } catch {
147
- setLoginError(translatedLabels.unexpectedError);
148
- } finally {
149
- setSubmitting(false);
150
- }
151
- },
152
- });
153
-
154
- if (isAuthenticated && recoveredMnemonic === null && codesRemaining === null) {
155
- onNavigate?.('/dashboard');
156
- return null;
157
- }
158
-
159
- return (
160
- <Container component="main" maxWidth="xs">
161
- <Box sx={{ marginTop: 8, display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
162
- <Typography component="h1" variant="h5">
163
- {translatedLabels.title}
164
- </Typography>
165
- <Box component="form" onSubmit={formik.handleSubmit} sx={{ mt: 1, width: '100%' }}>
166
- {!isAuthenticated && (
167
- <>
168
- <TextField
169
- margin="normal"
170
- fullWidth
171
- id={loginType}
172
- label={loginType === 'email' ? translatedLabels.email : translatedLabels.username}
173
- name={loginType}
174
- autoComplete={loginType === 'email' ? 'email' : 'username'}
175
- autoFocus
176
- value={loginType === 'email' ? formik.values.email : formik.values.username}
177
- onChange={formik.handleChange}
178
- onBlur={formik.handleBlur}
179
- error={formik.touched[loginType] && Boolean(formik.errors[loginType])}
180
- helperText={formik.touched[loginType] && formik.errors[loginType]}
181
- disabled={isAuthenticated}
182
- />
183
- <TextField
184
- margin="normal"
185
- required
186
- fullWidth
187
- name="code"
188
- label={translatedLabels.code}
189
- id="code"
190
- value={formik.values.code}
191
- onChange={formik.handleChange}
192
- onBlur={formik.handleBlur}
193
- error={formik.touched.code && Boolean(formik.errors.code)}
194
- helperText={formik.touched.code && formik.errors.code}
195
- disabled={isAuthenticated}
196
- />
197
- <TextField
198
- margin="normal"
199
- fullWidth
200
- name="newPassword"
201
- label={translatedLabels.newPassword}
202
- type="password"
203
- id="newPassword"
204
- value={formik.values.newPassword}
205
- onChange={formik.handleChange}
206
- onBlur={formik.handleBlur}
207
- error={formik.touched.newPassword && Boolean(formik.errors.newPassword)}
208
- helperText={formik.touched.newPassword && formik.errors.newPassword}
209
- disabled={isAuthenticated}
210
- />
211
- <TextField
212
- margin="normal"
213
- fullWidth
214
- name="confirmNewPassword"
215
- label={translatedLabels.confirmPassword}
216
- type="password"
217
- id="confirmNewPassword"
218
- value={formik.values.confirmNewPassword}
219
- onChange={formik.handleChange}
220
- onBlur={formik.handleBlur}
221
- error={formik.touched.confirmNewPassword && Boolean(formik.errors.confirmNewPassword)}
222
- helperText={formik.touched.confirmNewPassword && formik.errors.confirmNewPassword}
223
- disabled={isAuthenticated}
224
- />
225
- <FormControlLabel
226
- control={
227
- <Checkbox
228
- checked={formik.values.recoverMnemonic}
229
- onChange={formik.handleChange}
230
- onBlur={formik.handleBlur}
231
- name="recoverMnemonic"
232
- />
233
- }
234
- label={translatedLabels.recoverMnemonic}
235
- disabled={isAuthenticated}
236
- />
237
- </>
238
- )}
239
- {successMessage && (
240
- <Typography color="success.main" variant="body2" sx={{ mt: 1 }}>
241
- {successMessage}
242
- </Typography>
243
- )}
244
- {recoveredMnemonic && (
245
- <Box sx={{ mt: 2, p: 2, bgcolor: 'grey.100', borderRadius: 1 }}>
246
- <Typography variant="subtitle2" gutterBottom>
247
- {translatedLabels.mnemonicLabel}:
248
- </Typography>
249
- <Typography variant="body2" sx={{ fontFamily: 'monospace' }}>
250
- {recoveredMnemonic}
251
- </Typography>
252
- <Button
253
- fullWidth
254
- variant="contained"
255
- sx={{ mt: 2 }}
256
- onClick={() => onNavigate?.('/dashboard')}
257
- >
258
- {translatedLabels.dashboard}
259
- </Button>
260
- </Box>
261
- )}
262
- {codesRemaining !== null && (
263
- <Box sx={{ mt: 2 }}>
264
- <Typography variant="body2">
265
- {translatedLabels.codesRemaining.replace('{count}', String(codesRemaining))}
266
- </Typography>
267
- <Button
268
- fullWidth
269
- variant="contained"
270
- sx={{ mt: 2 }}
271
- onClick={() => onNavigate?.('/backup-codes', { codeCount: codesRemaining })}
272
- >
273
- {translatedLabels.generateNewCodes}
274
- </Button>
275
- </Box>
276
- )}
277
- {loginError && (
278
- <Typography color="error" variant="body2" sx={{ mt: 1 }}>
279
- {loginError}
280
- </Typography>
281
- )}
282
- {!isAuthenticated && (
283
- <>
284
- <Button
285
- type="submit"
286
- fullWidth
287
- variant="contained"
288
- sx={{ mt: 3, mb: 2 }}
289
- disabled={formik.isSubmitting}
290
- >
291
- {translatedLabels.login}
292
- </Button>
293
- <Box sx={{ display: 'flex', justifyContent: 'center' }}>
294
- <Button
295
- fullWidth
296
- variant="text"
297
- onClick={() => {
298
- const newType = loginType === 'email' ? 'username' : 'email';
299
- formik.setFieldValue(loginType, '');
300
- setLoginType(newType);
301
- }}
302
- >
303
- {loginType === 'email' ? translatedLabels.useUsername : translatedLabels.useEmail}
304
- </Button>
305
- </Box>
306
- </>
307
- )}
308
- </Box>
309
- </Box>
310
- </Container>
311
- );
312
- };
313
-
314
- export default BackupCodeLoginForm;
@@ -1,198 +0,0 @@
1
- import { Alert, Box, Button, Container, TextField, Typography } from '@mui/material';
2
- import { useFormik } from 'formik';
3
- import { FC, useState } from 'react';
4
- import * as Yup from 'yup';
5
- import { Constants, SuiteCoreComponentId, SuiteCoreStringKey } from '@digitaldefiance/suite-core-lib';
6
- import { useI18n } from '../contexts';
7
-
8
- export interface BackupCodesFormValues {
9
- password?: string;
10
- mnemonic?: string;
11
- }
12
-
13
- export interface BackupCodesFormProps {
14
- onSubmit: (values: BackupCodesFormValues) => Promise<{
15
- message: string;
16
- backupCodes: string[];
17
- }>;
18
- backupCodesRemaining?: number | null;
19
- mnemonicValidation?: Yup.StringSchema;
20
- passwordValidation?: Yup.StringSchema;
21
- labels?: {
22
- title?: string;
23
- codesRemaining?: string;
24
- mnemonic?: string;
25
- password?: string;
26
- generateButton?: string;
27
- successTitle?: string;
28
- };
29
- }
30
-
31
- export const BackupCodesForm: FC<BackupCodesFormProps> = ({
32
- onSubmit,
33
- backupCodesRemaining = null,
34
- mnemonicValidation,
35
- passwordValidation,
36
- labels = {},
37
- }) => {
38
- const { t, tComponent } = useI18n();
39
- const [apiError, setApiError] = useState<string | null>(null);
40
- const [apiSuccess, setApiSuccess] = useState<string | null>(null);
41
- const [backupCodes, setBackupCodes] = useState<string[] | null>(null);
42
-
43
- const validation = {
44
- mnemonic: mnemonicValidation || Yup.string()
45
- .trim()
46
- .matches(Constants.MnemonicRegex, tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_MnemonicRegex))
47
- .optional(),
48
- password: passwordValidation || Yup.string()
49
- .trim()
50
- .matches(Constants.PasswordRegex, tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_PasswordRegexErrorTemplate))
51
- .optional(),
52
- };
53
-
54
- const translatedLabels = {
55
- codesRemaining: labels.codesRemaining || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.BackupCodeRecovery_CodesRemainingTemplate),
56
- mnemonic: labels.mnemonic || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_Mnemonic),
57
- password: labels.password || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_Password),
58
- generateButton: labels.generateButton || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.BackupCodeRecovery_GenerateNewCodes),
59
- successTitle: labels.successTitle || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.BackupCodeRecovery_YourNewCodes),
60
- xorError: tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_MnemonicOrPasswordRequired),
61
- unexpectedError: tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_UnexpectedError),
62
- };
63
-
64
- const validationSchema = Yup.object({
65
- mnemonic: validation.mnemonic,
66
- password: validation.password,
67
- })
68
- .test('xor-mnemonic-password-mnemonic', translatedLabels.xorError, function (value) {
69
- const mnemonic = value?.mnemonic?.trim() ?? '';
70
- const password = value?.password?.trim() ?? '';
71
- const hasMnemonic = mnemonic.length > 0;
72
- const hasPassword = password.length > 0;
73
-
74
- if (!hasMnemonic && !hasPassword) {
75
- return this.createError({
76
- path: 'mnemonic',
77
- message: translatedLabels.xorError,
78
- });
79
- }
80
- if (hasMnemonic && hasPassword) {
81
- return this.createError({
82
- path: 'mnemonic',
83
- message: translatedLabels.xorError,
84
- });
85
- }
86
- return true;
87
- })
88
- .test('xor-mnemonic-password-password', translatedLabels.xorError, function (value) {
89
- const mnemonic = value?.mnemonic?.trim() ?? '';
90
- const password = value?.password?.trim() ?? '';
91
- const hasMnemonic = mnemonic.length > 0;
92
- const hasPassword = password.length > 0;
93
-
94
- if (!hasMnemonic && !hasPassword) {
95
- return this.createError({
96
- path: 'password',
97
- message: translatedLabels.xorError,
98
- });
99
- }
100
- if (hasMnemonic && hasPassword) {
101
- return this.createError({
102
- path: 'password',
103
- message: translatedLabels.xorError,
104
- });
105
- }
106
- return true;
107
- });
108
-
109
- const formik = useFormik<BackupCodesFormValues>({
110
- initialValues: {
111
- password: '',
112
- mnemonic: '',
113
- },
114
- validationSchema,
115
- onSubmit: async (values, { setSubmitting }) => {
116
- try {
117
- const result = await onSubmit(values);
118
- if (result && result.backupCodes) {
119
- setApiSuccess(translatedLabels.successTitle);
120
- setBackupCodes(result.backupCodes);
121
- }
122
- if (result && result.message) {
123
- setApiSuccess(result.message);
124
- }
125
- setApiError(null);
126
- } catch (e: any) {
127
- setApiSuccess(null);
128
- setApiError(e.response?.data?.message ?? translatedLabels.unexpectedError);
129
- } finally {
130
- setSubmitting(false);
131
- }
132
- },
133
- });
134
-
135
- return (
136
- <Container component="main" maxWidth="xs">
137
- <Box>
138
- <Typography component="h1" variant="h5">
139
- {translatedLabels.codesRemaining.replace('{count}', String(backupCodesRemaining ?? 0))}
140
- </Typography>
141
- </Box>
142
- <Box component="form" onSubmit={formik.handleSubmit} sx={{ mt: 1, width: '100%' }}>
143
- <TextField
144
- margin="normal"
145
- fullWidth
146
- id="mnemonic"
147
- label={translatedLabels.mnemonic}
148
- type="password"
149
- name="mnemonic"
150
- autoComplete="mnemonic"
151
- autoFocus
152
- value={formik.values.mnemonic}
153
- onChange={formik.handleChange}
154
- onBlur={formik.handleBlur}
155
- error={(formik.touched.mnemonic || formik.submitCount > 0) && Boolean(formik.errors.mnemonic)}
156
- helperText={(formik.touched.mnemonic || formik.submitCount > 0) && formik.errors.mnemonic}
157
- />
158
- <TextField
159
- margin="normal"
160
- fullWidth
161
- name="password"
162
- label={translatedLabels.password}
163
- type="password"
164
- id="password"
165
- value={formik.values.password}
166
- onChange={formik.handleChange}
167
- onBlur={formik.handleBlur}
168
- error={(formik.touched.password || formik.submitCount > 0) && Boolean(formik.errors.password)}
169
- helperText={(formik.touched.password || formik.submitCount > 0) && formik.errors.password}
170
- />
171
- <Button type="submit" fullWidth variant="contained" sx={{ mt: 2 }}>
172
- {translatedLabels.generateButton}
173
- </Button>
174
- </Box>
175
- {apiError && (
176
- <Alert severity="error" sx={{ mt: 2, mb: 2 }}>
177
- {apiError}
178
- </Alert>
179
- )}
180
- {backupCodes && apiSuccess && (
181
- <Box sx={{ mt: 2, mb: 2 }}>
182
- <Typography component="h2" variant="h6">
183
- {apiSuccess}
184
- </Typography>
185
- <ul>
186
- {backupCodes.map((code, index) => (
187
- <li key={index}>
188
- <pre>{code}</pre>
189
- </li>
190
- ))}
191
- </ul>
192
- </Box>
193
- )}
194
- </Container>
195
- );
196
- };
197
-
198
- export default BackupCodesForm;
@@ -1,182 +0,0 @@
1
- import {
2
- Alert,
3
- Box,
4
- Button,
5
- Container,
6
- TextField,
7
- Typography,
8
- } from '@mui/material';
9
- import { useFormik } from 'formik';
10
- import { FC, useState } from 'react';
11
- import * as Yup from 'yup';
12
- import { Constants, SuiteCoreComponentId, SuiteCoreStringKey } from '@digitaldefiance/suite-core-lib';
13
- import { useI18n } from '../contexts';
14
-
15
- export interface ChangePasswordFormValues {
16
- currentPassword: string;
17
- newPassword: string;
18
- confirmPassword: string;
19
- }
20
-
21
- export interface ChangePasswordFormProps {
22
- onSubmit: (values: ChangePasswordFormValues) => Promise<{ success?: boolean; error?: string }>;
23
- titleText?: string;
24
- currentPasswordLabel?: string;
25
- newPasswordLabel?: string;
26
- confirmPasswordLabel?: string;
27
- submitButtonText?: string;
28
- submittingButtonText?: string;
29
- successMessage?: string;
30
- currentPasswordValidation?: Yup.StringSchema;
31
- newPasswordValidation?: Yup.StringSchema;
32
- confirmPasswordValidation?: Yup.StringSchema;
33
- }
34
-
35
- export const ChangePasswordForm: FC<ChangePasswordFormProps> = ({
36
- onSubmit,
37
- titleText,
38
- currentPasswordLabel,
39
- newPasswordLabel,
40
- confirmPasswordLabel,
41
- submitButtonText,
42
- submittingButtonText,
43
- successMessage,
44
- currentPasswordValidation,
45
- newPasswordValidation,
46
- confirmPasswordValidation,
47
- }) => {
48
- const { t, tComponent } = useI18n();
49
- const [success, setSuccess] = useState(false);
50
- const [apiError, setApiError] = useState<string>('');
51
-
52
- const validation = {
53
- currentPassword: currentPasswordValidation || Yup.string().required(tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_Required)),
54
- newPassword: newPasswordValidation || Yup.string()
55
- .min(Constants.PasswordMinLength, tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_PasswordMinLengthTemplate))
56
- .required(tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_Required)),
57
- confirmPassword: confirmPasswordValidation || Yup.string()
58
- .oneOf([Yup.ref('newPassword')], tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_PasswordMatch))
59
- .required(tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_Required)),
60
- };
61
-
62
- const labels = {
63
- title: titleText || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_ChangePassword),
64
- currentPassword: currentPasswordLabel || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_CurrentPassword),
65
- newPassword: newPasswordLabel || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_NewPassword),
66
- confirmPassword: confirmPasswordLabel || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_ConfirmNewPassword),
67
- submitButton: submitButtonText || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_ChangePassword),
68
- submittingButton: submittingButtonText || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_ChangingPassword),
69
- success: successMessage || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.PasswordChange_Success),
70
- };
71
-
72
- const formik = useFormik<ChangePasswordFormValues>({
73
- initialValues: {
74
- currentPassword: '',
75
- newPassword: '',
76
- confirmPassword: '',
77
- },
78
- validationSchema: Yup.object({
79
- currentPassword: validation.currentPassword,
80
- newPassword: validation.newPassword,
81
- confirmPassword: validation.confirmPassword,
82
- }),
83
- onSubmit: async (values, { resetForm }) => {
84
- const result = await onSubmit(values);
85
-
86
- if ('success' in result) {
87
- setSuccess(true);
88
- setApiError('');
89
- resetForm();
90
- } else if ('error' in result && result.error) {
91
- setApiError(result.error);
92
- setSuccess(false);
93
- }
94
- },
95
- });
96
-
97
- return (
98
- <Container maxWidth="sm">
99
- <Box
100
- sx={{
101
- mt: 8,
102
- display: 'flex',
103
- flexDirection: 'column',
104
- alignItems: 'center',
105
- }}
106
- >
107
- <Typography variant="h4" component="h1" gutterBottom>
108
- {labels.title}
109
- </Typography>
110
-
111
- <Box component="form" onSubmit={formik.handleSubmit} sx={{ mt: 1, width: '100%' }}>
112
- <TextField
113
- fullWidth
114
- id="currentPassword"
115
- name="currentPassword"
116
- label={labels.currentPassword}
117
- type="password"
118
- value={formik.values.currentPassword}
119
- onChange={formik.handleChange}
120
- onBlur={formik.handleBlur}
121
- error={Boolean(formik.touched.currentPassword && formik.errors.currentPassword)}
122
- helperText={formik.touched.currentPassword && formik.errors.currentPassword}
123
- margin="normal"
124
- />
125
-
126
- <TextField
127
- fullWidth
128
- id="newPassword"
129
- name="newPassword"
130
- label={labels.newPassword}
131
- type="password"
132
- value={formik.values.newPassword}
133
- onChange={formik.handleChange}
134
- onBlur={formik.handleBlur}
135
- error={Boolean(formik.touched.newPassword && formik.errors.newPassword)}
136
- helperText={formik.touched.newPassword && formik.errors.newPassword}
137
- margin="normal"
138
- />
139
-
140
- <TextField
141
- fullWidth
142
- id="confirmPassword"
143
- name="confirmPassword"
144
- label={labels.confirmPassword}
145
- type="password"
146
- value={formik.values.confirmPassword}
147
- onChange={formik.handleChange}
148
- onBlur={formik.handleBlur}
149
- error={Boolean(formik.touched.confirmPassword && formik.errors.confirmPassword)}
150
- helperText={formik.touched.confirmPassword && formik.errors.confirmPassword}
151
- margin="normal"
152
- />
153
-
154
- {apiError && (
155
- <Alert severity="error" sx={{ mt: 2, mb: 2 }}>
156
- {apiError}
157
- </Alert>
158
- )}
159
-
160
- {success && (
161
- <Alert severity="success" sx={{ mt: 2, mb: 2 }}>
162
- {labels.success}
163
- </Alert>
164
- )}
165
-
166
- <Button
167
- type="submit"
168
- fullWidth
169
- variant="contained"
170
- color="primary"
171
- sx={{ mt: 3, mb: 2 }}
172
- disabled={formik.isSubmitting}
173
- >
174
- {formik.isSubmitting ? labels.submittingButton : labels.submitButton}
175
- </Button>
176
- </Box>
177
- </Box>
178
- </Container>
179
- );
180
- };
181
-
182
- export default ChangePasswordForm;