@alore/auth-react-ui 1.0.0-alpha

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 (144) hide show
  1. package/LICENSE +504 -0
  2. package/dist/cjs/Auth.d.ts +18 -0
  3. package/dist/cjs/Auth.js +74 -0
  4. package/dist/cjs/Auth.js.map +1 -0
  5. package/dist/cjs/auth/Login.d.ts +15 -0
  6. package/dist/cjs/auth/Login.js +714 -0
  7. package/dist/cjs/auth/Login.js.map +1 -0
  8. package/dist/cjs/auth/Register.d.ts +16 -0
  9. package/dist/cjs/auth/Register.js +633 -0
  10. package/dist/cjs/auth/Register.js.map +1 -0
  11. package/dist/cjs/components/AuthProvider.d.ts +473 -0
  12. package/dist/cjs/components/AuthProvider.js +36 -0
  13. package/dist/cjs/components/AuthProvider.js.map +1 -0
  14. package/dist/cjs/components/BackButton.d.ts +9 -0
  15. package/dist/cjs/components/BackButton.js +28 -0
  16. package/dist/cjs/components/BackButton.js.map +1 -0
  17. package/dist/cjs/components/CheckboxForm.d.ts +12 -0
  18. package/dist/cjs/components/CheckboxForm.js +29 -0
  19. package/dist/cjs/components/CheckboxForm.js.map +1 -0
  20. package/dist/cjs/components/FormRules/helpers/index.d.ts +13 -0
  21. package/dist/cjs/components/FormRules/helpers/index.js +52 -0
  22. package/dist/cjs/components/FormRules/helpers/index.js.map +1 -0
  23. package/dist/cjs/components/FormRules/index.d.ts +11 -0
  24. package/dist/cjs/components/FormRules/index.js +19 -0
  25. package/dist/cjs/components/FormRules/index.js.map +1 -0
  26. package/dist/cjs/components/InputErrorHelperText.d.ts +7 -0
  27. package/dist/cjs/components/InputErrorHelperText.js +10 -0
  28. package/dist/cjs/components/InputErrorHelperText.js.map +1 -0
  29. package/dist/cjs/components/InputForm.d.ts +14 -0
  30. package/dist/cjs/components/InputForm.js +80 -0
  31. package/dist/cjs/components/InputForm.js.map +1 -0
  32. package/dist/cjs/components/InputOTP.d.ts +12 -0
  33. package/dist/cjs/components/InputOTP.js +118 -0
  34. package/dist/cjs/components/InputOTP.js.map +1 -0
  35. package/dist/cjs/components/TermsModal.d.ts +10 -0
  36. package/dist/cjs/components/TermsModal.js +27 -0
  37. package/dist/cjs/components/TermsModal.js.map +1 -0
  38. package/dist/cjs/components/index.d.ts +6 -0
  39. package/dist/cjs/components/index.js +19 -0
  40. package/dist/cjs/components/index.js.map +1 -0
  41. package/dist/cjs/dictionaries/en.json +116 -0
  42. package/dist/cjs/dictionaries/pt.json +116 -0
  43. package/dist/cjs/get-dictionary.d.ts +356 -0
  44. package/dist/cjs/get-dictionary.js +46 -0
  45. package/dist/cjs/get-dictionary.js.map +1 -0
  46. package/dist/cjs/helpers/index.d.ts +8 -0
  47. package/dist/cjs/helpers/index.js +27 -0
  48. package/dist/cjs/helpers/index.js.map +1 -0
  49. package/dist/cjs/hooks/useAuthService.d.ts +1400 -0
  50. package/dist/cjs/hooks/useAuthService.js +15 -0
  51. package/dist/cjs/hooks/useAuthService.js.map +1 -0
  52. package/dist/cjs/hooks/useAuthServiceInstance.d.ts +469 -0
  53. package/dist/cjs/hooks/useAuthServiceInstance.js +13 -0
  54. package/dist/cjs/hooks/useAuthServiceInstance.js.map +1 -0
  55. package/dist/cjs/hooks/useDictionary.d.ts +118 -0
  56. package/dist/cjs/hooks/useDictionary.js +15 -0
  57. package/dist/cjs/hooks/useDictionary.js.map +1 -0
  58. package/dist/cjs/index.d.ts +7 -0
  59. package/dist/cjs/index.js +13 -0
  60. package/dist/cjs/index.js.map +1 -0
  61. package/dist/cjs/machine/index.d.ts +937 -0
  62. package/dist/cjs/machine/index.js +1208 -0
  63. package/dist/cjs/machine/index.js.map +1 -0
  64. package/dist/cjs/machine/index.typegen.d.ts +164 -0
  65. package/dist/cjs/machine/index.typegen.js +4 -0
  66. package/dist/cjs/machine/index.typegen.js.map +1 -0
  67. package/dist/cjs/machine/types.d.ts +324 -0
  68. package/dist/cjs/machine/types.js +3 -0
  69. package/dist/cjs/machine/types.js.map +1 -0
  70. package/dist/cjs/utils/index.d.ts +7 -0
  71. package/dist/cjs/utils/index.js +19 -0
  72. package/dist/cjs/utils/index.js.map +1 -0
  73. package/dist/mjs/Auth.d.ts +18 -0
  74. package/dist/mjs/Auth.js +46 -0
  75. package/dist/mjs/Auth.js.map +1 -0
  76. package/dist/mjs/auth/Login.d.ts +15 -0
  77. package/dist/mjs/auth/Login.js +688 -0
  78. package/dist/mjs/auth/Login.js.map +1 -0
  79. package/dist/mjs/auth/Register.d.ts +16 -0
  80. package/dist/mjs/auth/Register.js +603 -0
  81. package/dist/mjs/auth/Register.js.map +1 -0
  82. package/dist/mjs/components/AuthProvider.d.ts +473 -0
  83. package/dist/mjs/components/AuthProvider.js +9 -0
  84. package/dist/mjs/components/AuthProvider.js.map +1 -0
  85. package/dist/mjs/components/BackButton.d.ts +9 -0
  86. package/dist/mjs/components/BackButton.js +9 -0
  87. package/dist/mjs/components/BackButton.js.map +1 -0
  88. package/dist/mjs/components/CheckboxForm.d.ts +12 -0
  89. package/dist/mjs/components/CheckboxForm.js +10 -0
  90. package/dist/mjs/components/CheckboxForm.js.map +1 -0
  91. package/dist/mjs/components/FormRules/helpers/index.d.ts +13 -0
  92. package/dist/mjs/components/FormRules/helpers/index.js +48 -0
  93. package/dist/mjs/components/FormRules/helpers/index.js.map +1 -0
  94. package/dist/mjs/components/FormRules/index.d.ts +11 -0
  95. package/dist/mjs/components/FormRules/index.js +14 -0
  96. package/dist/mjs/components/FormRules/index.js.map +1 -0
  97. package/dist/mjs/components/InputErrorHelperText.d.ts +7 -0
  98. package/dist/mjs/components/InputErrorHelperText.js +5 -0
  99. package/dist/mjs/components/InputErrorHelperText.js.map +1 -0
  100. package/dist/mjs/components/InputForm.d.ts +14 -0
  101. package/dist/mjs/components/InputForm.js +58 -0
  102. package/dist/mjs/components/InputForm.js.map +1 -0
  103. package/dist/mjs/components/InputOTP.d.ts +12 -0
  104. package/dist/mjs/components/InputOTP.js +93 -0
  105. package/dist/mjs/components/InputOTP.js.map +1 -0
  106. package/dist/mjs/components/TermsModal.d.ts +10 -0
  107. package/dist/mjs/components/TermsModal.js +21 -0
  108. package/dist/mjs/components/TermsModal.js.map +1 -0
  109. package/dist/mjs/components/index.d.ts +6 -0
  110. package/dist/mjs/components/index.js +7 -0
  111. package/dist/mjs/components/index.js.map +1 -0
  112. package/dist/mjs/dictionaries/en.json +116 -0
  113. package/dist/mjs/dictionaries/pt.json +116 -0
  114. package/dist/mjs/get-dictionary.d.ts +356 -0
  115. package/dist/mjs/get-dictionary.js +10 -0
  116. package/dist/mjs/get-dictionary.js.map +1 -0
  117. package/dist/mjs/helpers/index.d.ts +8 -0
  118. package/dist/mjs/helpers/index.js +23 -0
  119. package/dist/mjs/helpers/index.js.map +1 -0
  120. package/dist/mjs/hooks/useAuthService.d.ts +1400 -0
  121. package/dist/mjs/hooks/useAuthService.js +13 -0
  122. package/dist/mjs/hooks/useAuthService.js.map +1 -0
  123. package/dist/mjs/hooks/useAuthServiceInstance.d.ts +469 -0
  124. package/dist/mjs/hooks/useAuthServiceInstance.js +11 -0
  125. package/dist/mjs/hooks/useAuthServiceInstance.js.map +1 -0
  126. package/dist/mjs/hooks/useDictionary.d.ts +118 -0
  127. package/dist/mjs/hooks/useDictionary.js +13 -0
  128. package/dist/mjs/hooks/useDictionary.js.map +1 -0
  129. package/dist/mjs/index.d.ts +7 -0
  130. package/dist/mjs/index.js +6 -0
  131. package/dist/mjs/index.js.map +1 -0
  132. package/dist/mjs/machine/index.d.ts +937 -0
  133. package/dist/mjs/machine/index.js +1189 -0
  134. package/dist/mjs/machine/index.js.map +1 -0
  135. package/dist/mjs/machine/index.typegen.d.ts +164 -0
  136. package/dist/mjs/machine/index.typegen.js +3 -0
  137. package/dist/mjs/machine/index.typegen.js.map +1 -0
  138. package/dist/mjs/machine/types.d.ts +324 -0
  139. package/dist/mjs/machine/types.js +2 -0
  140. package/dist/mjs/machine/types.js.map +1 -0
  141. package/dist/mjs/utils/index.d.ts +7 -0
  142. package/dist/mjs/utils/index.js +16 -0
  143. package/dist/mjs/utils/index.js.map +1 -0
  144. package/package.json +46 -0
@@ -0,0 +1,688 @@
1
+ 'use client';
2
+ import { ArrowRightIcon, EnvelopeIcon } from '@heroicons/react/20/solid';
3
+ import { KeyIcon, LockOpenIcon } from '@heroicons/react/24/outline';
4
+ import { yupResolver } from '@hookform/resolvers/yup';
5
+ import { useGoogleLogin } from '@react-oauth/google';
6
+ import { useActor } from '@xstate/react';
7
+ import { Button, Card, Spinner } from 'flowbite-react';
8
+ import React, { useEffect, useMemo, useRef, useState } from 'react';
9
+ import { useForm, useWatch } from 'react-hook-form';
10
+ import { twMerge } from 'tailwind-merge';
11
+ import * as yup from 'yup';
12
+ import { verifyEmptyValues } from '../helpers';
13
+ import useDictionary from '../hooks/useDictionary';
14
+ import { aloreLogoBlack, authErrorImage, fingerprint, fingerprintError, google, metamaskLogo, walletConnectLogo, } from '../utils';
15
+ const InputForm = React.lazy(() => import('../components/InputForm'));
16
+ const InputOTP = React.lazy(() => import('../components/InputOTP'));
17
+ const BackButton = React.lazy(() => import('../components/BackButton'));
18
+ const envelopIcon = () => React.createElement(EnvelopeIcon, { className: "size-4 text-gray-500" });
19
+ const HARDWARE = 1;
20
+ const SOFTWARE = 2;
21
+ const ABORT_CONDITIONAL_UI = 'abort-conditional-ui';
22
+ export const Login = ({ locale = 'pt', authServiceInstance, forgeId, logoImage, keyshareWorker, cryptoUtils, }) => {
23
+ const { hashUserInfo, generateSecureHash } = cryptoUtils;
24
+ const dictionary = useDictionary(locale);
25
+ const loginDictionary = dictionary?.auth.login;
26
+ const [secureCode2FA, setSecure2FACode] = useState('');
27
+ const [secureCodeEmail, setSecureCodeEmail] = useState('');
28
+ const [authState, sendAuth] = useActor(authServiceInstance);
29
+ const { salt, error: authError, active2fa, registerUser, googleOtpCode, googleUser, sessionUser, RCRPublicKey, } = authState.context;
30
+ const [currentDevice, setCurrentDevice] = useState('');
31
+ const [loading, setLoading] = useState(false);
32
+ const [sendEmailCooldown, setSendEmailCooldown] = useState(0);
33
+ const [cooldownMultiplier, setCooldownMultiplier] = useState(1);
34
+ const [newDeviceInfo] = useState();
35
+ const [loginMethod, setLoginMethod] = useState('password');
36
+ const [isConditionalMediationAvailable, setIsConditionalMediationAvailable] = useState(false);
37
+ const [authAbortController, setAuthAbortController] = useState(undefined);
38
+ const intervalRef = useRef();
39
+ const googleLogin = useGoogleLogin({
40
+ onSuccess: (tokenResponse) => {
41
+ resetEmail();
42
+ sendAuth({
43
+ type: 'GOOGLE_LOGIN',
44
+ googleToken: tokenResponse.access_token,
45
+ });
46
+ },
47
+ });
48
+ const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
49
+ const handleGoogleLogin = () => googleLogin();
50
+ const hasPasskeySupportWithPRFOrLargeBlob = () => {
51
+ if (window.PublicKeyCredential &&
52
+ // eslint-disable-next-line no-undef
53
+ PublicKeyCredential.isConditionalMediationAvailable) {
54
+ Promise.all([
55
+ // eslint-disable-next-line no-undef
56
+ PublicKeyCredential.isConditionalMediationAvailable(),
57
+ ]).then(([isConditionalMediationAvailableCheck]) => {
58
+ setIsConditionalMediationAvailable(isConditionalMediationAvailableCheck);
59
+ });
60
+ }
61
+ };
62
+ const selectLoginMethod = () => {
63
+ if (loginMethod === 'password') {
64
+ sendAuth('SELECT_PASSWORD');
65
+ }
66
+ else {
67
+ const { username: email } = getValuesEmail();
68
+ sendAuth({
69
+ type: 'START_PASSKEY_LOGIN',
70
+ payload: {
71
+ email,
72
+ },
73
+ });
74
+ }
75
+ };
76
+ const cancelConditionalCredentialRequest = () => {
77
+ authAbortController?.abort(ABORT_CONDITIONAL_UI);
78
+ setAuthAbortController(undefined);
79
+ };
80
+ // eslint-disable-next-line no-undef
81
+ const sendSignedCredential = async (credential) => {
82
+ const extensionResults = credential.getClientExtensionResults();
83
+ let secretFromCredential;
84
+ // @ts-ignore
85
+ const hasPrf = !!extensionResults?.prf?.results?.first;
86
+ // @ts-ignore
87
+ const hasLargeBlob = !!extensionResults?.largeBlob?.blob;
88
+ if (hasPrf) {
89
+ // @ts-ignore
90
+ secretFromCredential = extensionResults?.prf?.results?.first;
91
+ }
92
+ else if (hasLargeBlob) {
93
+ // @ts-ignore
94
+ secretFromCredential = extensionResults?.largeBlob?.blob;
95
+ }
96
+ if (hasLargeBlob && isSafari) {
97
+ // @ts-ignore
98
+ secretFromCredential = extensionResults?.largeBlob?.blob;
99
+ }
100
+ if (!secretFromCredential) {
101
+ sendAuth({
102
+ type: 'PASSKEY_NOT_SUPPORTED',
103
+ payload: { error: loginDictionary?.passkeyNotSupported },
104
+ });
105
+ return;
106
+ }
107
+ sendAuth({
108
+ type: 'FINISH_PASSKEY_LOGIN',
109
+ payload: {
110
+ passkeyAuth: {
111
+ id: credential.id,
112
+ rawId: Buffer.from(credential.rawId).toString('base64'),
113
+ response: {
114
+ authenticatorData: Buffer.from(
115
+ // eslint-disable-next-line no-undef
116
+ credential.response.authenticatorData).toString('base64'),
117
+ clientDataJSON: Buffer.from(credential.response.clientDataJSON).toString('base64'),
118
+ signature: Buffer.from(
119
+ // eslint-disable-next-line no-undef
120
+ credential.response.signature).toString('base64'),
121
+ userHandle: Buffer.from(
122
+ // @ts-ignore
123
+ credential.response.userHandle || [0]).toString('base64'),
124
+ },
125
+ type: 'public-key',
126
+ },
127
+ },
128
+ });
129
+ if (keyshareWorker) {
130
+ keyshareWorker.postMessage({
131
+ method: 'derive-password',
132
+ payload: {
133
+ password: new TextDecoder().decode(secretFromCredential),
134
+ email: credential.id,
135
+ },
136
+ });
137
+ }
138
+ };
139
+ const finishPasskeyAuth = async () => {
140
+ if (!RCRPublicKey || !navigator?.credentials) {
141
+ sendAuth('BACK');
142
+ return;
143
+ }
144
+ cancelConditionalCredentialRequest();
145
+ const { publicKey } = RCRPublicKey;
146
+ const extensions = {
147
+ prf: { eval: { first: new TextEncoder().encode('Alore') } },
148
+ largeBlob: {
149
+ read: true,
150
+ },
151
+ };
152
+ // eslint-disable-next-line no-undef
153
+ const credentialOptions = {
154
+ publicKey: {
155
+ ...publicKey,
156
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
157
+ allowCredentials: publicKey.allowCredentials?.map((cred) => ({
158
+ ...cred,
159
+ id: Buffer.from(cred.id, 'base64'),
160
+ })),
161
+ timeout: 10000,
162
+ // @ts-ignore
163
+ challenge: Buffer.from(publicKey.challenge, 'base64'),
164
+ rpId: publicKey.rpId,
165
+ extensions: {
166
+ ...publicKey.extensions,
167
+ // @ts-ignore
168
+ ...extensions,
169
+ },
170
+ },
171
+ };
172
+ try {
173
+ if (authState.matches('active.login.signingCredentialRCR') ||
174
+ authState.matches('active.login.idle.signWithPasskey') ||
175
+ authState.matches('active.login.idle.authScreen')) {
176
+ const cred = await navigator.credentials.get(credentialOptions);
177
+ // eslint-disable-next-line no-undef
178
+ const credential = cred;
179
+ sendSignedCredential(credential);
180
+ }
181
+ if (isConditionalMediationAvailable &&
182
+ authState.matches('active.login.idle.localPasskeySign')) {
183
+ const abortController = new AbortController();
184
+ setAuthAbortController(abortController);
185
+ const cred = await navigator.credentials.get({
186
+ ...credentialOptions,
187
+ mediation: 'conditional',
188
+ signal: abortController.signal,
189
+ });
190
+ // eslint-disable-next-line no-undef
191
+ const credential = cred;
192
+ sendSignedCredential(credential);
193
+ abortController?.abort();
194
+ setAuthAbortController(undefined);
195
+ }
196
+ }
197
+ catch (error) {
198
+ if (error !== ABORT_CONDITIONAL_UI) {
199
+ authAbortController?.abort();
200
+ setAuthAbortController(undefined);
201
+ sendAuth('BACK');
202
+ }
203
+ }
204
+ };
205
+ useEffect(() => {
206
+ cancelConditionalCredentialRequest();
207
+ }, [authState.matches('active.login.loginMethodSelection')]);
208
+ useEffect(() => {
209
+ if (authState.matches('active.login.idle.localPasskeySign') ||
210
+ authState.matches('active.login.idle.signWithPasskey') ||
211
+ authState.matches('active.login.signingCredentialRCR')) {
212
+ finishPasskeyAuth();
213
+ }
214
+ }, [
215
+ authState.matches('active.login.idle.localPasskeySign'),
216
+ authState.matches('active.login.idle.signWithPasskey'),
217
+ authState.matches('active.login.signingCredentialRCR'),
218
+ ]);
219
+ useEffect(() => {
220
+ if (authState.matches('active.login.idle.authScreen') && !isSafari) {
221
+ sendAuth('SET_CONDITIONAL_UI_PASSKEY');
222
+ }
223
+ }, [authState.matches('active.login.idle.authScreen')]);
224
+ const handlePasskeyButton = () => {
225
+ sendAuth('SIGN_IN_WITH_PASSKEY');
226
+ };
227
+ const isLoading = useMemo(() => loading ||
228
+ authState.matches('active.login.retrievingSalt') ||
229
+ authState.matches('active.login.verifyingLogin') ||
230
+ authState.matches('active.login.verifyingHwAuth') ||
231
+ authState.matches('active.login.verifying2faCode') ||
232
+ authState.matches('active.login.verifyingCode') ||
233
+ authState.matches('active.login.verifyingEmail2fa') ||
234
+ authState.matches('active.login.resendingEmailCode') ||
235
+ authState.matches('active.login.googleLogin') ||
236
+ authState.matches('active.login.verifyingGoogleLogin') ||
237
+ authState.matches('active.login.retrievingRCR') ||
238
+ authState.matches('active.login.verifyingRegisterPublicKeyCredential') ||
239
+ authState.matches('active.login.retrievingCredentialRCR') ||
240
+ authState.matches('active.login.signingCredentialRCR') ||
241
+ authState.matches('active.login.resendingConfirmationEmail') ||
242
+ authState.matches('active.web3Connector.verifyingClaimNftEmail2fa') ||
243
+ authState.matches('active.web3Connector.verifyingEmailEligibility'), [authState.value]);
244
+ useEffect(() => {
245
+ if (typeof window !== 'undefined') {
246
+ hasPasskeySupportWithPRFOrLargeBlob();
247
+ }
248
+ return () => {
249
+ cancelConditionalCredentialRequest();
250
+ };
251
+ }, []);
252
+ const emailFormSchema = yup
253
+ .object({
254
+ username: yup
255
+ .string()
256
+ .required(dictionary?.formValidation.required)
257
+ .email(dictionary?.formValidation.invalidEmail),
258
+ })
259
+ .required();
260
+ const passwordFormSchema = yup
261
+ .object({
262
+ password: yup
263
+ .string()
264
+ .required(dictionary?.formValidation.required)
265
+ .min(8, dictionary?.formValidation.passwordMinimum),
266
+ })
267
+ .required();
268
+ const activeHw2fa = useMemo(() => active2fa?.filter((item) => item.twoFaTypeId === HARDWARE) || [], [active2fa]);
269
+ const activeSw2fa = useMemo(() => active2fa?.find((item) => item.twoFaTypeId === SOFTWARE), [active2fa]);
270
+ const emailDefaultValues = {
271
+ username: '',
272
+ };
273
+ const { control: emailControl, formState: { errors: emailErrors, dirtyFields: emailDirtyFields }, handleSubmit: handleSubmitEmail, getValues: getValuesEmail, reset: resetEmail, } = useForm({
274
+ resolver: yupResolver(emailFormSchema),
275
+ defaultValues: emailDefaultValues,
276
+ });
277
+ useWatch({ control: emailControl, name: ['username'] });
278
+ const passwordDefaultValues = {
279
+ password: '',
280
+ };
281
+ const { control: passwordControl, formState: { errors: passwordErrors, dirtyFields: passwordDirtyFields }, handleSubmit: handleSubmitPassword, getValues: getValuesPassword, } = useForm({
282
+ resolver: yupResolver(passwordFormSchema),
283
+ defaultValues: passwordDefaultValues,
284
+ });
285
+ useWatch({ control: passwordControl, name: ['password'] });
286
+ useEffect(() => {
287
+ if (registerUser) {
288
+ if (forgeId) {
289
+ sendAuth(['RESET', { type: 'INITIALIZE', forgeId }]);
290
+ }
291
+ else {
292
+ sendAuth(['RESET', { type: 'INITIALIZE', forgeId }, 'LOGIN']);
293
+ }
294
+ }
295
+ }, [registerUser]);
296
+ useEffect(() => {
297
+ if (secureCode2FA.length === 6) {
298
+ if (authState.matches('active.login.email2fa')) {
299
+ onClickSecureCodeSubmit();
300
+ }
301
+ else {
302
+ onSubmitSecureCode2FA();
303
+ }
304
+ }
305
+ }, [secureCode2FA]);
306
+ useEffect(() => {
307
+ if (secureCodeEmail.length === 6) {
308
+ onSubmitSecureCodeEmail();
309
+ }
310
+ }, [secureCodeEmail]);
311
+ useEffect(() => {
312
+ if (sendEmailCooldown <= 0) {
313
+ clearInterval(intervalRef.current);
314
+ }
315
+ }, [sendEmailCooldown]);
316
+ useEffect(() => {
317
+ if (authState.matches('active.login.newDevice')) {
318
+ // getNewDeviceInfo(); // TODO
319
+ }
320
+ if (authState.matches('active.login.hardware2fa') &&
321
+ authState.history?.matches('active.login.verifyingLogin')) {
322
+ startHwAuth(0);
323
+ }
324
+ }, [authState.value]);
325
+ const startHwAuth = async (index) => {
326
+ setLoading(true);
327
+ const { username: email } = getValuesEmail();
328
+ const { password } = getValuesPassword();
329
+ if (salt && active2fa) {
330
+ const secureHashArgon2d = await generateSecureHash(password, salt, 'argon2d');
331
+ const hardwares2fa = active2fa.filter((item) => item.twoFaTypeId === HARDWARE);
332
+ sendAuth({
333
+ type: 'VERIFY_HW_AUTH',
334
+ payload: {
335
+ email,
336
+ device: currentDevice,
337
+ passwordHash: secureHashArgon2d,
338
+ authId: hardwares2fa[index].id,
339
+ },
340
+ });
341
+ }
342
+ setLoading(false);
343
+ };
344
+ const onSubmitEmail = async (data) => {
345
+ setLoading(true);
346
+ const { username: email } = data;
347
+ // await signOut({ redirect: false });
348
+ sendAuth({ type: 'NEXT', payload: { email } });
349
+ setLoading(false);
350
+ };
351
+ const derivePasswordAndGetKeyshares = async (password, email) => {
352
+ if (keyshareWorker) {
353
+ keyshareWorker.postMessage({
354
+ method: 'derive-password',
355
+ payload: { password, email },
356
+ });
357
+ }
358
+ };
359
+ const onSubmitLogin = async (data) => {
360
+ setLoading(true);
361
+ const { password } = data;
362
+ const email = getValuesEmail('username') || googleUser?.email;
363
+ if (salt && email) {
364
+ derivePasswordAndGetKeyshares(password, email);
365
+ const secureHashArgon2d = await generateSecureHash(password, salt, 'argon2d');
366
+ if (typeof window !== 'undefined') {
367
+ let device = window.localStorage.getItem('currentDeviceSecret');
368
+ if (!device) {
369
+ const { userAgent } = window.navigator;
370
+ device = hashUserInfo(userAgent);
371
+ }
372
+ setCurrentDevice(device);
373
+ if (googleOtpCode) {
374
+ sendAuth({
375
+ type: 'COMPLETE_GOOGLE_SIGN_IN',
376
+ payload: {
377
+ email,
378
+ passwordHash: secureHashArgon2d,
379
+ otp: googleOtpCode,
380
+ },
381
+ });
382
+ }
383
+ else {
384
+ sendAuth({
385
+ type: 'VERIFY_LOGIN',
386
+ payload: {
387
+ email,
388
+ device,
389
+ passwordHash: secureHashArgon2d,
390
+ isForgeClaim: !!forgeId,
391
+ locale,
392
+ },
393
+ });
394
+ }
395
+ }
396
+ }
397
+ setLoading(false);
398
+ };
399
+ const onSubmitSecureCode2FA = async () => {
400
+ setLoading(true);
401
+ const { username: email } = getValuesEmail();
402
+ const { password } = getValuesPassword();
403
+ if (salt) {
404
+ derivePasswordAndGetKeyshares(password, email);
405
+ const secureHashArgon2d = await generateSecureHash(password, salt, 'argon2d');
406
+ sendAuth({
407
+ type: 'CONFIRM_SW_CODE',
408
+ payload: {
409
+ email,
410
+ device: currentDevice,
411
+ passwordHash: secureHashArgon2d,
412
+ otp: secureCode2FA,
413
+ },
414
+ });
415
+ setSecure2FACode('');
416
+ }
417
+ setLoading(false);
418
+ };
419
+ const onClickSecureCodeSubmit = async () => {
420
+ setLoading(true);
421
+ const { password } = getValuesPassword();
422
+ const { username: email } = getValuesEmail();
423
+ if (salt) {
424
+ derivePasswordAndGetKeyshares(password, email);
425
+ const secureHashArgon2d = await generateSecureHash(password, salt, 'argon2d');
426
+ if (typeof window !== 'undefined') {
427
+ let device = window.localStorage.getItem('currentDeviceSecret');
428
+ if (!device) {
429
+ const { userAgent } = window.navigator;
430
+ device = hashUserInfo(userAgent);
431
+ }
432
+ setCurrentDevice(device);
433
+ sendAuth({
434
+ type: 'VERIFY_EMAIL_2FA',
435
+ payload: {
436
+ email: getValuesEmail('username'),
437
+ secureCode: secureCode2FA,
438
+ passwordHash: secureHashArgon2d,
439
+ },
440
+ });
441
+ }
442
+ }
443
+ setLoading(false);
444
+ setSecure2FACode('');
445
+ };
446
+ const resendSecureCode = async () => {
447
+ setLoading(true);
448
+ const { username: email } = getValuesEmail();
449
+ const { password } = getValuesPassword();
450
+ if (salt) {
451
+ derivePasswordAndGetKeyshares(password, email);
452
+ const secureHashArgon2d = await generateSecureHash(password, salt, 'argon2d');
453
+ sendAuth({
454
+ type: 'RESEND_CODE',
455
+ payload: {
456
+ email,
457
+ passwordHash: secureHashArgon2d,
458
+ device: currentDevice,
459
+ nickname: email,
460
+ isForgeClaim: !!forgeId,
461
+ locale,
462
+ },
463
+ });
464
+ setSecureCodeEmail('');
465
+ }
466
+ setLoading(false);
467
+ setSendEmailCooldown(15 * cooldownMultiplier);
468
+ intervalRef.current = setInterval(() => setSendEmailCooldown((state) => state - 1), 1000);
469
+ setCooldownMultiplier((state) => state + 1);
470
+ };
471
+ const onSubmitSecureCodeEmail = async () => {
472
+ setLoading(true);
473
+ const { username: email } = getValuesEmail();
474
+ const { password } = getValuesPassword();
475
+ if (salt) {
476
+ derivePasswordAndGetKeyshares(password, email);
477
+ const secureHashArgon2d = await generateSecureHash(password, salt, 'argon2d');
478
+ sendAuth({
479
+ type: 'CONFIRM_DEVICE_CODE',
480
+ payload: {
481
+ email,
482
+ passwordHash: secureHashArgon2d,
483
+ device: currentDevice,
484
+ secureCode: secureCodeEmail,
485
+ },
486
+ });
487
+ setSecureCodeEmail('');
488
+ }
489
+ setLoading(false);
490
+ };
491
+ const isLoginSubmitDisabled = useMemo(() => verifyEmptyValues({ ...getValuesEmail(), ...getValuesPassword() }), [
492
+ { ...getValuesEmail(), ...getValuesPassword() },
493
+ { ...emailDirtyFields, ...passwordDirtyFields },
494
+ ]);
495
+ const getAuthError = () => {
496
+ let authErrorTitle = loginDictionary?.somethingWrong;
497
+ let authErrorDescription = loginDictionary?.defaultError;
498
+ if (authError?.includes('Invalid credentials')) {
499
+ authErrorTitle = loginDictionary?.invalidEmailPassword;
500
+ authErrorDescription = loginDictionary?.invalidEmailPasswordDescription;
501
+ }
502
+ else if (authError?.includes('Passkey')) {
503
+ authErrorTitle = loginDictionary?.passkeyNotSupported;
504
+ authErrorDescription = loginDictionary?.passkeyNotSupportedDescription;
505
+ }
506
+ return { authErrorTitle, authErrorDescription };
507
+ };
508
+ const EmailInputStep = useMemo(() => {
509
+ const { authErrorTitle, authErrorDescription } = getAuthError();
510
+ return (React.createElement(React.Fragment, null,
511
+ authError ? (React.createElement("div", { className: "flex flex-col items-center justify-center gap-5" },
512
+ React.createElement("img", { src: authErrorImage, alt: "alore logo", width: 70 }),
513
+ authError?.includes('beta') ? (React.createElement("span", { className: "font-poppins text-alr-red text-center text-xl font-bold" }, authError)) : (React.createElement(React.Fragment, null,
514
+ React.createElement("span", { className: "font-poppins text-alr-red text-center text-xl font-bold" }, authErrorTitle),
515
+ React.createElement("span", { className: "text-alr-grey text-center font-medium" }, authErrorDescription))))) : (React.createElement("h1", { className: "font-inter text-center text-lg font-bold text-gray-700" }, forgeId ? loginDictionary?.forgeLogin : loginDictionary?.loginAccount)),
516
+ React.createElement("form", { className: "flex flex-col gap-y-5", onSubmit: handleSubmitEmail((data) => onSubmitEmail(data)) },
517
+ React.createElement(InputForm, { className: "my-1", control: emailControl, errors: emailErrors, name: "username", type: "text", placeholder: loginDictionary?.enterEmail, "data-test": "login-email", icon: envelopIcon, autoComplete: authAbortController && isConditionalMediationAvailable
518
+ ? 'username webauthn'
519
+ : undefined, autoFocus: true }),
520
+ React.createElement(Button, { type: "submit", "data-test": "login-button", disabled: verifyEmptyValues(getValuesEmail('username')), className: "bg-alr-red hover:bg-alr-dark-red group relative flex items-center justify-center rounded-lg border border-transparent p-0.5 text-center font-medium text-white duration-300 focus:z-10 focus:outline-none focus:ring-2 focus:ring-red-300 enabled:hover:bg-red-700 disabled:hover:bg-red-900 dark:bg-red-600 dark:hover:bg-red-700 dark:focus:ring-red-900 dark:enabled:hover:bg-red-700 dark:disabled:hover:bg-red-600" },
521
+ isLoading && React.createElement(Spinner, { className: "mr-3 !h-5 w-full !fill-gray-300" }),
522
+ loginDictionary?.login),
523
+ React.createElement("div", { className: "h-[0.5px] w-full bg-gray-300" }),
524
+ typeof window.PublicKeyCredential !== 'undefined' && (React.createElement(Button, { color: "light", onClick: handlePasskeyButton, outline: true }, dictionary?.auth.signWithPasskey)),
525
+ React.createElement(Button, { color: "light", onClick: handleGoogleLogin, outline: true },
526
+ React.createElement("div", { className: "flex flex-row items-center justify-center gap-2" },
527
+ React.createElement("img", { src: google, alt: "google logo", width: 16 }),
528
+ dictionary?.auth.continueGoogle)),
529
+ forgeId && (React.createElement(Button, { color: "light", onClick: () => sendAuth('LOGIN_WITH_WEB3CONNECTOR'), outline: true },
530
+ React.createElement("div", { className: "flex flex-row items-center justify-center gap-2" },
531
+ React.createElement("div", { className: "relative flex flex-row" },
532
+ React.createElement("img", { src: metamaskLogo, alt: "metamask logo", width: 20, className: "absolute right-3" }),
533
+ React.createElement("img", { src: walletConnectLogo, alt: "walletconnect logo", width: 20 })),
534
+ "Metamask/WalletConnect"))),
535
+ React.createElement("span", { className: "text-center text-sm font-medium" },
536
+ loginDictionary?.dontHaveAccount,
537
+ React.createElement("div", { className: "text-alr-red cursor-pointer", onClick: () => {
538
+ sendAuth(['RESET', { type: 'INITIALIZE', forgeId }, 'SIGN_UP']);
539
+ } }, loginDictionary?.signUp)))));
540
+ }, [getValuesEmail(), isLoginSubmitDisabled, emailErrors, emailControl, isLoading]);
541
+ const SelectLoginMethod = useMemo(() => {
542
+ const { authErrorTitle, authErrorDescription } = getAuthError();
543
+ return (React.createElement("div", null,
544
+ React.createElement(BackButton, { disabled: isLoading, onClick: () => sendAuth('BACK') }),
545
+ authError ? (React.createElement("div", { className: "my-4 flex flex-col items-center justify-center gap-2" },
546
+ React.createElement("span", { className: "font-poppins text-alr-red text-center text-xl font-bold" }, authErrorTitle),
547
+ React.createElement("span", { className: "text-alr-grey text-center font-medium" }, authErrorDescription))) : undefined,
548
+ React.createElement("div", { className: "mt-2 flex w-full flex-col items-center", "data-test": "login-method-selection-step" },
549
+ isLoading && React.createElement(Spinner, { className: "mr-3 !h-5 w-full !fill-gray-300" }),
550
+ React.createElement("span", { className: "font-poppins text-alr-grey mb-6 text-center text-2xl font-bold md:text-[1.75rem]" }, loginDictionary?.selectMethodTitle),
551
+ React.createElement("span", { className: "text-alr-grey mb-6 w-full text-center font-medium" }, loginDictionary?.selectMethodDescription),
552
+ React.createElement("div", { className: "flex flex-col gap-5" },
553
+ React.createElement("div", { className: "flex w-full gap-2" },
554
+ React.createElement(Button, { "data-test": "login-method-selection-password", onClick: () => setLoginMethod('password'), color: "light", className: `${loginMethod === 'password' ? '!border-alr-red' : '!border-gray-500'} child:h-full w-full cursor-pointer items-start border focus:ring-0` },
555
+ React.createElement("div", { className: "flex flex-col items-start justify-center gap-2" },
556
+ React.createElement(LockOpenIcon, { className: `${loginMethod === 'password' ? 'text-alr-red' : 'text-gray-500'} size-7` }),
557
+ React.createElement("span", { className: "font-semibold text-gray-900" }, loginDictionary?.password),
558
+ React.createElement("span", { className: "text-start text-xs font-normal text-gray-600" }, loginDictionary?.selectMethodPassword))),
559
+ React.createElement(Button, { "data-test": "login-method-selection-passkey", onClick: () => setLoginMethod('passkey'), color: "light", className: `${loginMethod === 'passkey' ? '!border-alr-red' : '!border-gray-500'} child:h-full w-full cursor-pointer items-start border focus:ring-0` },
560
+ React.createElement("div", { className: "flex flex-col items-start justify-center gap-2" },
561
+ React.createElement(KeyIcon, { className: `${loginMethod === 'passkey' ? 'text-alr-red' : 'text-gray-500'} size-7` }),
562
+ React.createElement("span", { className: "font-semibold text-gray-900" }, loginDictionary?.passkey),
563
+ React.createElement("span", { className: "text-start text-xs font-normal text-gray-600" }, loginDictionary?.selectMethodPasskey)))),
564
+ React.createElement(Button, { "data-test": "login-method-selection-submit", onClick: () => selectLoginMethod(), className: "bg-alr-red text-alr-white mb-6 flex w-full cursor-pointer items-center" }, loginDictionary?.continue)))));
565
+ }, [isLoading, loginMethod]);
566
+ const PasswordInputStep = useMemo(() => (React.createElement(React.Fragment, null,
567
+ React.createElement(BackButton, { className: "mb-2.5", onClick: () => sendAuth('BACK') }, getValuesEmail('username') || googleUser?.email),
568
+ authError && (React.createElement("div", { className: "flex flex-col items-center justify-center gap-5" },
569
+ React.createElement("img", { src: authErrorImage, alt: "alore logo", width: 70 }),
570
+ React.createElement("span", { className: "font-poppins text-alr-red text-center text-xl font-bold" }, authError?.includes('Invalid credentials')
571
+ ? loginDictionary?.invalidEmailPassword
572
+ : loginDictionary?.somethingWrong),
573
+ React.createElement("span", { className: "text-alr-grey text-center font-medium" }, authError?.includes('Invalid credentials')
574
+ ? loginDictionary?.invalidEmailPasswordDescription
575
+ : loginDictionary?.defaultError))),
576
+ React.createElement("form", { onSubmit: handleSubmitPassword((data) => onSubmitLogin(data)), className: "flex flex-col gap-y-5", "data-test": "login-password-step" },
577
+ React.createElement(InputForm, { control: passwordControl, errors: passwordErrors, name: "password", placeholder: loginDictionary?.enterPassword, type: "password", label: dictionary?.password, "data-test": "login-password" }),
578
+ React.createElement(Button, { type: "submit", "data-test": "login-submit", disabled: verifyEmptyValues(getValuesPassword('password')), className: "bg-alr-red hover:bg-alr-dark-red group relative flex items-center justify-center rounded-lg border border-transparent p-0.5 text-center font-medium text-white duration-300 focus:z-10 focus:outline-none focus:ring-2 focus:ring-red-300 enabled:hover:bg-red-700 disabled:hover:bg-red-900 dark:bg-red-600 dark:hover:bg-red-700 dark:focus:ring-red-900 dark:enabled:hover:bg-red-700 dark:disabled:hover:bg-red-600" },
579
+ isLoading && React.createElement(Spinner, { className: "mr-3 !h-5 w-full !fill-gray-300" }),
580
+ loginDictionary?.login),
581
+ React.createElement("span", { className: "text-sm font-medium" },
582
+ loginDictionary?.dontHaveAccount,
583
+ React.createElement("div", { className: "text-alr-red cursor-pointer", onClick: () => {
584
+ sendAuth(['RESET', { type: 'INITIALIZE', forgeId }, 'SIGN_UP']);
585
+ } }, loginDictionary?.signUp))))), [getValuesPassword(), isLoginSubmitDisabled, passwordErrors, passwordControl, isLoading]);
586
+ const VerifyEmail = useMemo(() => (React.createElement("div", { className: "pb-10 pt-4" },
587
+ React.createElement(BackButton, { disabled: isLoading, onClick: () => sendAuth('BACK') }),
588
+ React.createElement("div", { className: "flex w-full flex-col items-center", "data-test": "login-verify-email-step" },
589
+ React.createElement("span", { className: "font-poppins text-alr-grey mb-10 mt-[4.5rem] text-[1.75rem] font-bold" }, loginDictionary?.verifyEmail),
590
+ React.createElement("span", { className: "text-alr-grey mb-12 w-[23.75rem] text-center font-medium" }, loginDictionary?.verifyEmailDescription),
591
+ React.createElement("div", { className: "mb-6 flex" },
592
+ React.createElement(InputOTP, { className: "child:gap-x-3 md:child:gap-x-5 [&>div>input]:!h-9 [&>div>input]:!w-9", value: secureCode2FA, onChange: (value) => setSecure2FACode(value), inputLength: 6, "data-test": "secure-code", errorMessage: authError?.includes('wrong') ? loginDictionary?.wrongCode : undefined, disabled: isLoading })),
593
+ React.createElement(Button, { "data-test": "secure-code-submit", onClick: () => onClickSecureCodeSubmit(), className: "bg-alr-red hover:bg-alr-dark-red group relative mb-6 flex w-full items-center justify-center rounded-lg border border-transparent p-0.5 text-center font-medium text-white duration-300 focus:z-10 focus:outline-none focus:ring-2 focus:ring-red-300 enabled:hover:bg-red-700 disabled:hover:bg-red-900 dark:bg-red-600 dark:hover:bg-red-700 dark:focus:ring-red-900 dark:enabled:hover:bg-red-700 dark:disabled:hover:bg-red-600", disabled: secureCode2FA.length !== 6 || isLoading },
594
+ isLoading && React.createElement(Spinner, { className: "mr-3 !h-5 w-full !fill-gray-300" }),
595
+ loginDictionary?.confirmCode),
596
+ React.createElement("span", { onClick: () => resendSecureCode(), className: twMerge(`text-base font-medium duration-300`, sendEmailCooldown > 0
597
+ ? 'pointer-events-none opacity-50'
598
+ : 'hover:text-alr-red cursor-pointer opacity-100') }, `${loginDictionary?.resendCode}${sendEmailCooldown ? ` (${sendEmailCooldown}s)` : ''}`)))), [secureCode2FA, sendEmailCooldown, isLoading, authState]);
599
+ const VerifyHw2FAStep = useMemo(() => (React.createElement("div", null,
600
+ React.createElement(BackButton, { onClick: () => sendAuth('BACK') }),
601
+ authError?.includes('Failed authenticating with hardware key') ? (React.createElement("div", { className: "mt-6 flex w-full flex-col items-center gap-6" },
602
+ React.createElement("img", { alt: "fingerprint error", src: fingerprintError }),
603
+ React.createElement("span", { className: "font-poppins text-alr-red text-center text-[1.3rem] font-bold" }, loginDictionary?.cantVerify2fa),
604
+ React.createElement(Button, { className: "bg-alr-red hover:bg-alr-dark-red group relative flex w-full items-center justify-center rounded-lg border border-transparent p-0.5 text-center font-medium text-white duration-300 focus:z-10 focus:outline-none focus:ring-2 focus:ring-red-300 enabled:hover:bg-red-700 disabled:hover:bg-red-900 dark:bg-red-600 dark:hover:bg-red-700 dark:focus:ring-red-900 dark:enabled:hover:bg-red-700 dark:disabled:hover:bg-red-600", onClick: () => startHwAuth(0) }, loginDictionary?.tryAgain),
605
+ activeHw2fa?.length > 1 && (React.createElement(React.Fragment, null,
606
+ React.createElement("span", null, loginDictionary?.tryHardware),
607
+ React.createElement("div", { className: "text-alr-red flex cursor-pointer items-center gap-x-1 text-base font-semibold", onClick: () => startHwAuth(1) },
608
+ loginDictionary?.useAnotherHardware,
609
+ React.createElement(ArrowRightIcon, { className: "size-5" })))),
610
+ activeSw2fa && (React.createElement("div", { className: "text-alr-red flex cursor-pointer items-center gap-x-1 text-base font-semibold", onClick: () => sendAuth('USE_SOFTWARE_2FA') },
611
+ loginDictionary?.useSw2fa,
612
+ React.createElement(ArrowRightIcon, { className: "size-5" }))))) : (React.createElement("div", { className: "flex w-full flex-col items-center" },
613
+ React.createElement("span", { className: "font-poppins text-alr-grey mb-10 mt-12 text-center text-[1.3rem] font-bold" }, loginDictionary?.touchHardware),
614
+ React.createElement("span", { className: "text-alr-grey mb-10 w-60 text-sm font-normal" }, loginDictionary?.touchHardwareDescription),
615
+ React.createElement("img", { alt: "usb indicator", src: fingerprint }),
616
+ activeSw2fa && (React.createElement("div", { className: "text-alr-red mt-9 flex cursor-pointer items-center gap-x-1 text-base font-semibold", onClick: () => sendAuth('USE_SOFTWARE_2FA') },
617
+ loginDictionary?.useSw2fa,
618
+ React.createElement(ArrowRightIcon, { className: "size-5" }))))))), [isLoading, active2fa]);
619
+ const VerifySw2FAStep = useMemo(() => (React.createElement("div", null,
620
+ React.createElement(BackButton, { onClick: () => sendAuth('BACK') }),
621
+ React.createElement("div", { className: "flex w-full flex-col items-center" },
622
+ React.createElement("span", { className: "font-poppins text-alr-grey mb-10 mt-12 text-center text-[1.3rem] font-bold" }, loginDictionary?.inform2FACode),
623
+ React.createElement("div", { className: "mb-6 flex" },
624
+ React.createElement(InputOTP, { className: "child:gap-x-3 md:child:gap-x-5 [&>div>input]:!h-9 [&>div>input]:!w-9", value: secureCode2FA, onChange: (value) => setSecure2FACode(value), "data-test": "secure-code-2FA", inputLength: 6, errorMessage: authError?.includes('Invalid 2FA code') ? loginDictionary?.wrongCode : undefined })),
625
+ React.createElement(Button, { "data-test": "secure-code-2FA-submit", onClick: () => onSubmitSecureCode2FA(), className: "bg-alr-red hover:bg-alr-dark-red group relative mb-6 flex w-full items-center justify-center rounded-lg border border-transparent p-0.5 text-center font-medium text-white duration-300 focus:z-10 focus:outline-none focus:ring-2 focus:ring-red-300 enabled:hover:bg-red-700 disabled:hover:bg-red-900 dark:bg-red-600 dark:hover:bg-red-700 dark:focus:ring-red-900 dark:enabled:hover:bg-red-700 dark:disabled:hover:bg-red-600", disabled: secureCode2FA.length !== 6 },
626
+ isLoading && React.createElement(Spinner, { className: "mr-3 !h-5 w-full !fill-gray-300" }),
627
+ loginDictionary?.confirmCode),
628
+ active2fa?.find((item) => item.twoFaTypeId === HARDWARE) && (React.createElement("div", { className: "text-alr-red mt-9 flex cursor-pointer items-center gap-x-1 text-base font-semibold", onClick: () => sendAuth('USE_HARDWARE_2FA') },
629
+ loginDictionary?.useHw2fa,
630
+ React.createElement(ArrowRightIcon, { className: "size-5" })))))), [secureCode2FA, isLoading, active2fa]);
631
+ const NewDeviceStep = useMemo(() => (React.createElement("div", null,
632
+ React.createElement("div", { className: "flex w-full flex-col items-center" },
633
+ React.createElement("span", { className: "font-poppins text-alr-grey mb-5 mt-14 text-[1.75rem] font-bold" }, loginDictionary?.newDevice),
634
+ React.createElement("span", { className: "text-alr-grey mb-3 w-[23.75rem] text-center font-medium" }, loginDictionary?.verifyEmailDescription),
635
+ React.createElement("span", { className: "mb-5 font-bold" }, getValuesEmail('username')),
636
+ React.createElement("div", { className: "mb-5 h-44 w-full" }),
637
+ React.createElement("div", { className: "mb-6 flex" },
638
+ React.createElement(InputOTP, { className: "child:gap-x-3 md:child:gap-x-5 [&>div>input]:!h-9 [&>div>input]:!w-9", value: secureCodeEmail, onChange: (value) => setSecureCodeEmail(value), "data-test": "secure-code-email", inputLength: 6, errorMessage: authError?.includes('Wrong code') ? loginDictionary?.wrongCode : undefined })),
639
+ React.createElement(Button, { "data-test": "secure-code-email-submit", onClick: () => onSubmitSecureCodeEmail(), className: "bg-alr-red hover:bg-alr-dark-red group relative mb-6 flex w-full items-center justify-center rounded-lg border border-transparent p-0.5 text-center font-medium text-white duration-300 focus:z-10 focus:outline-none focus:ring-2 focus:ring-red-300 enabled:hover:bg-red-700 disabled:hover:bg-red-900 dark:bg-red-600 dark:hover:bg-red-700 dark:focus:ring-red-900 dark:enabled:hover:bg-red-700 dark:disabled:hover:bg-red-600", disabled: secureCodeEmail.length !== 6 },
640
+ isLoading && React.createElement(Spinner, { className: "mr-3 !h-5 w-full !fill-gray-300" }),
641
+ loginDictionary?.confirmCode),
642
+ React.createElement("span", { onClick: () => resendSecureCode(), className: twMerge(`text-base font-medium duration-300`, sendEmailCooldown > 0
643
+ ? 'pointer-events-none opacity-50'
644
+ : 'hover:text-alr-red cursor-pointer opacity-100') }, `${loginDictionary?.resendCode}${sendEmailCooldown ? ` (${sendEmailCooldown}s)` : ''}`)))), [secureCodeEmail, sendEmailCooldown, isLoading, newDeviceInfo]);
645
+ return (React.createElement("div", { className: "flex size-full min-h-screen flex-col items-center justify-center gap-y-2 sm:gap-y-7", "data-test": "login-page" },
646
+ forgeId ? (React.createElement("div", { className: "flex flex-col" },
647
+ React.createElement("span", { className: "font-poppins text-alr-grey text-center text-2xl font-black" }, "Tardezinha com Thiaguinho"),
648
+ React.createElement("div", { className: "flex w-full flex-row items-center justify-center gap-2" },
649
+ React.createElement("span", { className: "font-inter text-sm font-medium text-gray-900" }, dictionary?.auth.poweredBy),
650
+ React.createElement("img", { src: aloreLogoBlack, alt: "alore logo", width: "60" })))) : (logoImage || (React.createElement("img", { src: aloreLogoBlack, alt: "alore logo", width: authState.matches('active.login.newDevice') ? 153 : 201 }))),
651
+ React.createElement(Card, { className: twMerge(`md:child:!px-9 mx-5 flex min-w-[20rem] py-2 md:mx-7 md:w-96`, isLoading ? 'pointer-events-none opacity-50' : '') },
652
+ forgeId && authState.matches('active.web3Connector') && 'TODO',
653
+ (authState.matches('active.login.passkeyGuard') ||
654
+ authState.matches('active.login.idle') ||
655
+ authState.matches('active.login.googleLogin') ||
656
+ authState.matches('active.login.retrievingSalt') ||
657
+ authState.matches('active.login.verifyingRegisterPublicKeyCredential') ||
658
+ authState.matches('active.login.retrievingRCR')) &&
659
+ EmailInputStep,
660
+ (authState.matches('active.login.loginMethodSelection') ||
661
+ authState.matches('active.login.signingCredentialRCR') ||
662
+ authState.matches('active.login.retrievingCredentialRCR')) &&
663
+ SelectLoginMethod,
664
+ (authState.matches('active.login.inputPassword') ||
665
+ authState.matches('active.login.verifyingGoogleLogin') ||
666
+ authState.matches('active.login.verifyingLogin')) &&
667
+ PasswordInputStep,
668
+ (authState.matches('active.login.email2fa') ||
669
+ authState.matches('active.login.resendingEmailCode') ||
670
+ authState.matches('active.login.verifyingEmail2fa')) &&
671
+ VerifyEmail,
672
+ (authState.matches('active.login.hardware2fa') ||
673
+ authState.matches('active.login.verifyingHwAuth')) &&
674
+ VerifyHw2FAStep,
675
+ (authState.matches('active.login.software2fa') ||
676
+ authState.matches('active.login.verifying2faCode')) &&
677
+ VerifySw2FAStep,
678
+ (authState.matches('active.login.newDevice') ||
679
+ authState.matches('active.login.verifyingCode') ||
680
+ authState.matches('active.login.resendingConfirmationEmail')) &&
681
+ NewDeviceStep,
682
+ authState.matches('active.login.successfulLogin') && (React.createElement("div", { className: "flex flex-col items-center justify-center gap-4" },
683
+ React.createElement("div", { className: "flex flex-row items-center justify-center gap-2" },
684
+ React.createElement("span", null, "Login complete for"),
685
+ React.createElement("span", { className: "font-semibold" }, sessionUser?.nickname)),
686
+ React.createElement(Button, { className: "bg-alr-red hover:bg-alr-dark-red group relative flex items-center justify-center rounded-lg border border-transparent p-0.5 text-center font-medium text-white duration-300 focus:z-10 focus:outline-none focus:ring-2 focus:ring-red-300 enabled:hover:bg-red-700 disabled:hover:bg-red-900 dark:bg-red-600 dark:hover:bg-red-700 dark:focus:ring-red-900 dark:enabled:hover:bg-red-700 dark:disabled:hover:bg-red-600", onClick: () => sendAuth(['RESET_CONTEXT', 'INITIALIZE']) }, "LOGOUT"))))));
687
+ };
688
+ //# sourceMappingURL=Login.js.map