@digitaldefiance/express-suite-react-components 2.9.7 → 2.9.11

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 +353 -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,307 +0,0 @@
1
- import { Visibility, VisibilityOff } from '@mui/icons-material';
2
- import {
3
- Alert,
4
- Box,
5
- Button,
6
- Container,
7
- IconButton,
8
- InputAdornment,
9
- Link,
10
- TextField,
11
- Typography,
12
- } from '@mui/material';
13
- import { useFormik } from 'formik';
14
- import { FC, useState } from 'react';
15
- import * as Yup from 'yup';
16
- import { SuiteCoreComponentId, SuiteCoreStringKey, Constants } from '@digitaldefiance/suite-core-lib';
17
- import { useI18n } from '../contexts';
18
-
19
- export interface LoginFormValues {
20
- email?: string;
21
- username?: string;
22
- password?: string;
23
- mnemonic?: string;
24
- [key: string]: any;
25
- }
26
-
27
- export interface LoginFormProps {
28
- onSubmit: (values: LoginFormValues) => Promise<void>;
29
- loginType?: 'email' | 'username';
30
- authType?: 'password' | 'mnemonic';
31
- allowLoginTypeToggle?: boolean;
32
- allowAuthTypeToggle?: boolean;
33
- showForgotPassword?: boolean;
34
- showSignUp?: boolean;
35
- forgotPasswordLink?: string;
36
- signUpLink?: string;
37
- emailLabel?: string;
38
- usernameLabel?: string;
39
- passwordLabel?: string;
40
- mnemonicLabel?: string;
41
- signInButtonText?: string;
42
- forgotPasswordText?: string;
43
- signUpText?: string;
44
- useUsernameText?: string;
45
- useEmailText?: string;
46
- useMnemonicText?: string;
47
- usePasswordText?: string;
48
- toggleVisibilityLabel?: string;
49
- titleText?: string;
50
- emailValidation?: Yup.StringSchema;
51
- usernameValidation?: Yup.StringSchema;
52
- passwordValidation?: Yup.StringSchema;
53
- mnemonicValidation?: Yup.StringSchema;
54
- additionalFields?: (formik: ReturnType<typeof useFormik<LoginFormValues>>) => React.ReactNode;
55
- additionalInitialValues?: Record<string, any>;
56
- additionalValidation?: Record<string, Yup.Schema>;
57
- }
58
-
59
- export const LoginForm: FC<LoginFormProps> = ({
60
- onSubmit,
61
- loginType: initialLoginType = 'email',
62
- authType: initialAuthType = 'password',
63
- allowLoginTypeToggle = true,
64
- allowAuthTypeToggle = true,
65
- showForgotPassword = true,
66
- showSignUp = true,
67
- forgotPasswordLink = '/forgot-password',
68
- signUpLink = '/register',
69
- emailLabel,
70
- usernameLabel,
71
- passwordLabel,
72
- mnemonicLabel,
73
- signInButtonText,
74
- forgotPasswordText,
75
- signUpText,
76
- useUsernameText,
77
- useEmailText,
78
- useMnemonicText,
79
- usePasswordText,
80
- toggleVisibilityLabel,
81
- titleText,
82
- emailValidation,
83
- usernameValidation,
84
- passwordValidation,
85
- mnemonicValidation,
86
- additionalFields,
87
- additionalInitialValues = {},
88
- additionalValidation = {},
89
- }) => {
90
- const { tComponent } = useI18n();
91
- const [loginType, setLoginType] = useState<'email' | 'username'>(initialLoginType);
92
- const [authType, setAuthType] = useState<'password' | 'mnemonic'>(initialAuthType);
93
- const [showSecret, setShowSecret] = useState(false);
94
-
95
- // Use translations with fallbacks
96
- const labels = {
97
- title: titleText || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Login_Title),
98
- email: emailLabel || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_Email),
99
- username: usernameLabel || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_Username),
100
- password: passwordLabel || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_Password),
101
- mnemonic: mnemonicLabel || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_Mnemonic),
102
- signIn: signInButtonText || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.SignInButton),
103
- forgotPassword: forgotPasswordText || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Login_ForgotPassword),
104
- signUp: signUpText || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Login_SignUp),
105
- useUsername: useUsernameText || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Login_UseUsername),
106
- useEmail: useEmailText || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Login_UseEmailAddress),
107
- useMnemonic: useMnemonicText || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_UseMnemonic),
108
- usePassword: usePasswordText || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_UsePassword),
109
- toggleVisibility: toggleVisibilityLabel || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.TogglePasswordVisibility),
110
- };
111
-
112
- const validation = {
113
- email: emailValidation || Yup.string()
114
- .email(tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_InvalidEmail))
115
- .required(tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_Required)),
116
- username: usernameValidation || Yup.string()
117
- .matches(Constants.UsernameRegex, tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_UsernameRegexErrorTemplate))
118
- .required(tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_Required)),
119
- password: passwordValidation || Yup.string()
120
- .min(1, tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_Required))
121
- .required(tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_Required)),
122
- mnemonic: mnemonicValidation || Yup.string()
123
- .matches(Constants.MnemonicRegex, tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_InvalidMnemonic))
124
- .required(tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_Required)),
125
- };
126
-
127
- const formik = useFormik<LoginFormValues>({
128
- initialValues: {
129
- email: '',
130
- username: '',
131
- mnemonic: '',
132
- password: '',
133
- ...additionalInitialValues,
134
- },
135
- validationSchema: Yup.object({
136
- [loginType]: loginType === 'email' ? validation.email : validation.username,
137
- ...(authType === 'mnemonic'
138
- ? { mnemonic: validation.mnemonic }
139
- : { password: validation.password }),
140
- ...additionalValidation,
141
- }),
142
- enableReinitialize: true,
143
- onSubmit: async (values, { setStatus }) => {
144
- try {
145
- setStatus(null);
146
- await onSubmit(values);
147
- } catch (error: any) {
148
- setStatus(error.message || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_UnexpectedError));
149
- throw error;
150
- }
151
- },
152
- });
153
-
154
- return (
155
- <Container component="main" maxWidth="xs">
156
- <Box
157
- sx={{
158
- marginTop: 8,
159
- display: 'flex',
160
- flexDirection: 'column',
161
- alignItems: 'center',
162
- }}
163
- >
164
- <Typography component="h1" variant="h5">
165
- {labels.title}
166
- </Typography>
167
- <Box component="form" onSubmit={formik.handleSubmit} sx={{ mt: 1, width: '100%' }}>
168
- {formik.status && (
169
- <Alert severity="error" sx={{ mb: 2 }}>
170
- {formik.status}
171
- </Alert>
172
- )}
173
- <TextField
174
- margin="normal"
175
- fullWidth
176
- id={loginType}
177
- label={loginType === 'email' ? labels.email : labels.username}
178
- name={loginType}
179
- autoComplete={loginType === 'email' ? 'email' : 'username'}
180
- autoFocus
181
- value={loginType === 'email' ? formik.values.email : formik.values.username}
182
- onChange={formik.handleChange}
183
- error={formik.touched[loginType] && Boolean(formik.errors[loginType])}
184
- helperText={formik.touched[loginType] && formik.errors[loginType]}
185
- />
186
- {authType === 'password' ? (
187
- <TextField
188
- margin="normal"
189
- required
190
- fullWidth
191
- name="password"
192
- label={labels.password}
193
- id="password"
194
- type={showSecret ? 'text' : 'password'}
195
- value={formik.values.password}
196
- onChange={formik.handleChange}
197
- error={formik.touched.password && Boolean(formik.errors.password)}
198
- helperText={formik.touched.password && formik.errors.password}
199
- slotProps={{
200
- input: {
201
- endAdornment: (
202
- <InputAdornment position="end">
203
- <IconButton
204
- aria-label={labels.toggleVisibility}
205
- onClick={() => setShowSecret(!showSecret)}
206
- edge="end"
207
- >
208
- {showSecret ? <VisibilityOff /> : <Visibility />}
209
- </IconButton>
210
- </InputAdornment>
211
- ),
212
- },
213
- }}
214
- />
215
- ) : (
216
- <TextField
217
- margin="normal"
218
- required
219
- fullWidth
220
- name="mnemonic"
221
- label={labels.mnemonic}
222
- id="mnemonic"
223
- multiline
224
- rows={3}
225
- value={formik.values.mnemonic}
226
- onChange={formik.handleChange}
227
- error={formik.touched.mnemonic && Boolean(formik.errors.mnemonic)}
228
- helperText={formik.touched.mnemonic && formik.errors.mnemonic}
229
- type={showSecret ? 'text' : 'password'}
230
- slotProps={{
231
- input: {
232
- endAdornment: (
233
- <InputAdornment position="end">
234
- <IconButton
235
- aria-label={labels.toggleVisibility}
236
- onClick={() => setShowSecret(!showSecret)}
237
- edge="end"
238
- >
239
- {showSecret ? <VisibilityOff /> : <Visibility />}
240
- </IconButton>
241
- </InputAdornment>
242
- ),
243
- },
244
- }}
245
- />
246
- )}
247
- {additionalFields && additionalFields(formik)}
248
- <Button
249
- type="submit"
250
- fullWidth
251
- variant="contained"
252
- sx={{ mt: 3, mb: 2 }}
253
- disabled={formik.isSubmitting}
254
- >
255
- {labels.signIn}
256
- </Button>
257
- {(showForgotPassword || showSignUp) && (
258
- <Box sx={{ display: 'flex', justifyContent: 'space-between' }}>
259
- {showForgotPassword && (
260
- <Link href={forgotPasswordLink} variant="body2">
261
- {labels.forgotPassword}
262
- </Link>
263
- )}
264
- {showSignUp && (
265
- <Link href={signUpLink} variant="body2">
266
- {labels.signUp}
267
- </Link>
268
- )}
269
- </Box>
270
- )}
271
- {(allowLoginTypeToggle || allowAuthTypeToggle) && (
272
- <Box sx={{ display: 'flex', gap: 1, mt: 2 }}>
273
- {allowLoginTypeToggle && (
274
- <Button
275
- fullWidth
276
- variant="text"
277
- onClick={() => {
278
- const newType = loginType === 'email' ? 'username' : 'email';
279
- formik.setFieldValue(loginType, '');
280
- setLoginType(newType);
281
- }}
282
- >
283
- {loginType === 'email' ? labels.useUsername : labels.useEmail}
284
- </Button>
285
- )}
286
- {allowAuthTypeToggle && (
287
- <Button
288
- fullWidth
289
- variant="text"
290
- onClick={() => {
291
- const newType = authType === 'password' ? 'mnemonic' : 'password';
292
- formik.setFieldValue(authType, '');
293
- setAuthType(newType);
294
- }}
295
- >
296
- {authType === 'password' ? labels.useMnemonic : labels.usePassword}
297
- </Button>
298
- )}
299
- </Box>
300
- )}
301
- </Box>
302
- </Box>
303
- </Container>
304
- );
305
- };
306
-
307
- export default LoginForm;
@@ -1,21 +0,0 @@
1
- import { useEffect } from 'react';
2
-
3
- export interface LogoutPageProps {
4
- onLogout: () => Promise<void> | void;
5
- onNavigate?: (path: string) => void;
6
- redirectTo?: string;
7
- }
8
-
9
- export const LogoutPage = ({ onLogout, onNavigate, redirectTo = '/login' }: LogoutPageProps) => {
10
- useEffect(() => {
11
- const performLogout = async () => {
12
- await onLogout();
13
- onNavigate?.(redirectTo);
14
- };
15
- performLogout();
16
- }, [onLogout, onNavigate, redirectTo]);
17
-
18
- return null;
19
- };
20
-
21
- export default LogoutPage;
@@ -1,354 +0,0 @@
1
- import {
2
- Alert,
3
- AlertTitle,
4
- Box,
5
- Button,
6
- Checkbox,
7
- Container,
8
- FormControl,
9
- FormControlLabel,
10
- FormHelperText,
11
- InputLabel,
12
- Link,
13
- MenuItem,
14
- Select,
15
- TextField,
16
- Typography,
17
- } from '@mui/material';
18
- import { useFormik } from 'formik';
19
- import { FC, useState } from 'react';
20
- import * as Yup from 'yup';
21
- import { SuiteCoreComponentId, SuiteCoreStringKey, Constants } from '@digitaldefiance/suite-core-lib';
22
- import { useI18n } from '../contexts';
23
-
24
- export interface RegisterFormValues {
25
- username: string;
26
- email: string;
27
- timezone: string;
28
- password?: string;
29
- confirmPassword?: string;
30
- [key: string]: any;
31
- }
32
-
33
- export interface RegisterFormProps {
34
- onSubmit: (values: RegisterFormValues, usePassword: boolean) => Promise<
35
- | { success: boolean; message: string; mnemonic?: string }
36
- | { error: string; errorType?: string; field?: string; errors?: Array<{ path: string; msg: string }> }
37
- >;
38
- timezones: string[];
39
- getInitialTimezone: () => string;
40
- usernameValidation?: Yup.StringSchema;
41
- emailValidation?: Yup.StringSchema;
42
- timezoneValidation?: Yup.StringSchema;
43
- passwordValidation?: Yup.StringSchema;
44
- confirmPasswordValidation?: Yup.StringSchema;
45
- additionalFields?: (formik: any, usePassword: boolean) => React.ReactNode;
46
- additionalInitialValues?: Record<string, any>;
47
- additionalValidation?: Record<string, Yup.Schema>;
48
- labels?: {
49
- title?: string;
50
- username?: string;
51
- email?: string;
52
- timezone?: string;
53
- password?: string;
54
- confirmPassword?: string;
55
- useMnemonic?: string;
56
- usePassword?: string;
57
- registering?: string;
58
- register?: string;
59
- successTitle?: string;
60
- mnemonicSuccess?: string;
61
- proceedToLogin?: string;
62
- loginLink?: string;
63
- };
64
- }
65
-
66
- export const RegisterForm: FC<RegisterFormProps> = ({
67
- onSubmit,
68
- timezones,
69
- getInitialTimezone,
70
- usernameValidation,
71
- emailValidation,
72
- timezoneValidation,
73
- passwordValidation,
74
- confirmPasswordValidation,
75
- additionalFields,
76
- additionalInitialValues = {},
77
- additionalValidation = {},
78
- labels = {},
79
- }) => {
80
- const { t, tComponent } = useI18n();
81
- const [apiErrors, setApiErrors] = useState<Record<string, string>>({});
82
- const [mnemonic, setMnemonic] = useState<string | null>(null);
83
- const [usePassword, setUsePassword] = useState(true);
84
- const [registrationSuccess, setRegistrationSuccess] = useState(false);
85
- const [registering, setRegistering] = useState(false);
86
-
87
- const validation = {
88
- username: usernameValidation || Yup.string()
89
- .min(Constants.UsernameMinLength, tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_UsernameMinLengthTemplate))
90
- .max(Constants.UsernameMaxLength, tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_UsernameMaxLengthTemplate))
91
- .matches(Constants.UsernameRegex, tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_UsernameRegexErrorTemplate))
92
- .required(tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_Required)),
93
- email: emailValidation || Yup.string()
94
- .email(tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_InvalidEmail))
95
- .required(tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_Required)),
96
- timezone: timezoneValidation || Yup.string()
97
- .required(tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_TimezoneRequired))
98
- .oneOf(timezones, tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_TimezoneInvalid)),
99
- password: passwordValidation || Yup.string()
100
- .matches(Constants.PasswordRegex, tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_PasswordRegexErrorTemplate))
101
- .min(8, tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_PasswordMinLengthTemplate))
102
- .required(tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_Required)),
103
- confirmPassword: confirmPasswordValidation || Yup.string()
104
- .oneOf([Yup.ref('password')], tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_PasswordMatch))
105
- .required(tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Validation_Required)),
106
- };
107
-
108
- const formik = useFormik<RegisterFormValues>({
109
- initialValues: {
110
- username: '',
111
- email: '',
112
- timezone: getInitialTimezone(),
113
- password: '',
114
- confirmPassword: '',
115
- directChallenge: false,
116
- ...additionalInitialValues,
117
- },
118
- enableReinitialize: true,
119
- validationSchema: Yup.object({
120
- username: validation.username,
121
- email: validation.email,
122
- timezone: validation.timezone,
123
- ...(usePassword
124
- ? {
125
- password: validation.password,
126
- confirmPassword: validation.confirmPassword,
127
- }
128
- : {}),
129
- ...additionalValidation,
130
- }),
131
- onSubmit: async (values, { setSubmitting, setFieldError, setTouched }) => {
132
- setRegistering(true);
133
- const registerResult = await onSubmit(values, usePassword);
134
-
135
- if ('success' in registerResult && registerResult.success) {
136
- setRegistrationSuccess(true);
137
- if (!usePassword && registerResult?.mnemonic) {
138
- setMnemonic(registerResult.mnemonic);
139
- }
140
- } else {
141
- setRegistrationSuccess(false);
142
- const newApiErrors: Record<string, string> = {};
143
- const fieldsToTouch: Record<string, boolean> = {};
144
-
145
- if ('field' in registerResult && registerResult.field) {
146
- setFieldError(registerResult.field, registerResult.error);
147
- fieldsToTouch[registerResult.field] = true;
148
- }
149
-
150
- if ('errors' in registerResult && registerResult.errors) {
151
- registerResult.errors.forEach((err) => {
152
- if (err.path && err.msg) {
153
- setFieldError(err.path, err.msg);
154
- fieldsToTouch[err.path] = true;
155
- }
156
- });
157
- }
158
-
159
- if ('error' in registerResult && registerResult.error && !Object.keys(newApiErrors).length) {
160
- newApiErrors.general = registerResult.error;
161
- }
162
-
163
- setApiErrors(newApiErrors);
164
- setTouched(fieldsToTouch, false);
165
- }
166
- setSubmitting(false);
167
- setRegistering(false);
168
- setApiErrors({});
169
- },
170
- });
171
-
172
- return (
173
- <Container maxWidth="sm">
174
- <Box sx={{ mt: 8, display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
175
- <Typography variant="h4" component="h1" gutterBottom>
176
- {labels.title || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_Registration)}
177
- </Typography>
178
-
179
- <Box component="form" onSubmit={formik.handleSubmit} sx={{ mt: 1, width: '100%' }}>
180
- <TextField
181
- fullWidth
182
- id="username"
183
- name="username"
184
- label={labels.username || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_Username)}
185
- value={formik.values.username}
186
- onChange={formik.handleChange}
187
- onBlur={formik.handleBlur}
188
- error={Boolean(formik.touched.username && (formik.errors.username || apiErrors.username))}
189
- helperText={formik.touched.username && (formik.errors.username || apiErrors.username)}
190
- margin="normal"
191
- />
192
- <TextField
193
- fullWidth
194
- id="email"
195
- name="email"
196
- label={labels.email || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_Email)}
197
- value={formik.values.email}
198
- onChange={formik.handleChange}
199
- onBlur={formik.handleBlur}
200
- error={Boolean(formik.touched.email && (formik.errors.email || apiErrors.email))}
201
- helperText={formik.touched.email && (formik.errors.email || apiErrors.email)}
202
- margin="normal"
203
- />
204
- <FormControl fullWidth margin="normal">
205
- <InputLabel id="timezone-label">{labels.timezone || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_Timezone)}</InputLabel>
206
- <Select
207
- labelId="timezone-label"
208
- id="timezone"
209
- name="timezone"
210
- value={formik.values.timezone}
211
- onChange={formik.handleChange}
212
- onBlur={formik.handleBlur}
213
- error={formik.touched.timezone && Boolean(formik.errors.timezone)}
214
- label={labels.timezone || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_Timezone)}
215
- >
216
- {timezones.map((tz) => (
217
- <MenuItem key={tz} value={tz}>
218
- {tz}
219
- </MenuItem>
220
- ))}
221
- </Select>
222
- {formik.touched.timezone && (formik.errors.timezone || apiErrors.timezone) && (
223
- <Typography color="error" variant="caption">
224
- {formik.errors.timezone || apiErrors.timezone}
225
- </Typography>
226
- )}
227
- </FormControl>
228
-
229
- <Box sx={{ display: 'flex', alignItems: 'center', mt: 2 }}>
230
- <Button variant="text" onClick={() => setUsePassword(!usePassword)}>
231
- {usePassword
232
- ? labels.useMnemonic || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_UseMnemonic)
233
- : labels.usePassword || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_UsePassword)}
234
- </Button>
235
- </Box>
236
-
237
- {usePassword && (
238
- <>
239
- <TextField
240
- fullWidth
241
- id="password"
242
- name="password"
243
- label={labels.password || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_Password)}
244
- type="password"
245
- value={formik.values.password}
246
- onChange={formik.handleChange}
247
- onBlur={formik.handleBlur}
248
- error={Boolean(formik.touched.password && formik.errors.password)}
249
- helperText={formik.touched.password && formik.errors.password}
250
- margin="normal"
251
- />
252
- <TextField
253
- fullWidth
254
- id="confirmPassword"
255
- name="confirmPassword"
256
- label={labels.confirmPassword || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Common_ConfirmNewPassword)}
257
- type="password"
258
- value={formik.values.confirmPassword}
259
- onChange={formik.handleChange}
260
- onBlur={formik.handleBlur}
261
- error={Boolean(formik.touched.confirmPassword && formik.errors.confirmPassword)}
262
- helperText={formik.touched.confirmPassword && formik.errors.confirmPassword}
263
- margin="normal"
264
- />
265
- </>
266
- )}
267
-
268
- <FormControl fullWidth margin="normal">
269
- <FormControlLabel
270
- control={
271
- <Checkbox
272
- id="directChallenge"
273
- name="directChallenge"
274
- checked={formik.values.directChallenge || false}
275
- onChange={formik.handleChange}
276
- />
277
- }
278
- label={tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Registration_DirectChallengeLabel)}
279
- />
280
- <FormHelperText>
281
- {tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Registration_DirectChallengeHelper)}
282
- </FormHelperText>
283
- </FormControl>
284
-
285
- {additionalFields && additionalFields(formik, usePassword)}
286
-
287
- {apiErrors.general && (
288
- <Alert severity="error" sx={{ mt: 2, mb: 2 }}>
289
- {apiErrors.general}
290
- </Alert>
291
- )}
292
-
293
- <Button
294
- type="submit"
295
- fullWidth
296
- variant="contained"
297
- color="primary"
298
- sx={{ mt: 3, mb: 2 }}
299
- disabled={formik.isSubmitting}
300
- >
301
- {registering
302
- ? labels.registering || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Registration_Registering)
303
- : labels.register || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Registration_RegisterButton)}
304
- </Button>
305
-
306
- {registering && (
307
- <Alert severity="success" sx={{ mt: 2, mb: 2, whiteSpace: 'pre-wrap' }}>
308
- <AlertTitle>{labels.registering || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Registration_Registering)}</AlertTitle>
309
- <Typography variant="body2" component="div">
310
- {tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Registration_RegisteringMessage)}
311
- </Typography>
312
- </Alert>
313
- )}
314
-
315
- {mnemonic && (
316
- <Alert severity="success" sx={{ mt: 2, mb: 2, whiteSpace: 'pre-wrap' }}>
317
- <AlertTitle>{labels.successTitle || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Registration_SuccessTitle)}</AlertTitle>
318
- <Typography variant="body2" component="div">
319
- {labels.mnemonicSuccess || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Registration_MnemonicSuccess)}
320
- <Typography variant="body1" component="div" sx={{ mt: 1, fontFamily: 'monospace' }}>
321
- {mnemonic}
322
- </Typography>
323
- <Box sx={{ textAlign: 'center' }}>
324
- <Link href="/login">{labels.proceedToLogin || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.ProceedToLogin)}</Link>
325
- </Box>
326
- </Typography>
327
- </Alert>
328
- )}
329
-
330
- {registrationSuccess && (
331
- <Alert severity="success" sx={{ mt: 2, mb: 2 }}>
332
- <AlertTitle>{labels.successTitle || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Registration_SuccessTitle)}</AlertTitle>
333
- <Typography variant="body2" component="div">
334
- {tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Registration_Success)}
335
- <Box sx={{ textAlign: 'center' }}>
336
- <Link href="/login">{labels.proceedToLogin || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.ProceedToLogin)}</Link>
337
- </Box>
338
- </Typography>
339
- </Alert>
340
- )}
341
- {!mnemonic && !registrationSuccess && (
342
- <Box sx={{ textAlign: 'center' }}>
343
- <Link href="/login" variant="body2">
344
- {labels.loginLink || tComponent<SuiteCoreStringKey>(SuiteCoreComponentId, SuiteCoreStringKey.Registration_LoginLink)}
345
- </Link>
346
- </Box>
347
- )}
348
- </Box>
349
- </Box>
350
- </Container>
351
- );
352
- };
353
-
354
- export default RegisterForm;