@rebasepro/firebase 0.0.1-canary.2 → 0.0.1-canary.eb08332

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 (47) hide show
  1. package/README.md +97 -3
  2. package/dist/components/FirebaseLoginView.d.ts +3 -3
  3. package/dist/components/RebaseFirebaseApp.d.ts +2 -1
  4. package/dist/components/RebaseFirebaseAppProps.d.ts +9 -13
  5. package/dist/components/social_icons.d.ts +6 -6
  6. package/dist/hooks/index.d.ts +3 -1
  7. package/dist/hooks/useAppCheck.d.ts +2 -2
  8. package/dist/hooks/useBuildUserManagement.d.ts +78 -0
  9. package/dist/hooks/useFirebaseAccessGate.d.ts +44 -0
  10. package/dist/hooks/useFirebaseAuthController.d.ts +2 -2
  11. package/dist/hooks/useFirebaseRealTimeDBDelegate.d.ts +2 -2
  12. package/dist/hooks/useFirebaseStorageSource.d.ts +1 -1
  13. package/dist/hooks/{useFirestoreDataSource.d.ts → useFirestoreDriver.d.ts} +9 -9
  14. package/dist/index.es.js +2598 -2663
  15. package/dist/index.es.js.map +1 -1
  16. package/dist/index.umd.js +2704 -2702
  17. package/dist/index.umd.js.map +1 -1
  18. package/dist/types/auth.d.ts +2 -2
  19. package/dist/types/text_search.d.ts +3 -3
  20. package/dist/utils/algolia.d.ts +7 -6
  21. package/dist/utils/collections_firestore.d.ts +4 -4
  22. package/package.json +75 -65
  23. package/src/components/FirebaseLoginView.tsx +53 -50
  24. package/src/components/RebaseFirebaseApp.tsx +82 -56
  25. package/src/components/RebaseFirebaseAppProps.tsx +10 -24
  26. package/src/components/social_icons.tsx +8 -8
  27. package/src/hooks/index.ts +3 -1
  28. package/src/hooks/useAppCheck.ts +5 -5
  29. package/src/hooks/useBuildUserManagement.tsx +366 -0
  30. package/src/hooks/useFirebaseAccessGate.tsx +145 -0
  31. package/src/hooks/useFirebaseAuthController.ts +6 -8
  32. package/src/hooks/useFirebaseRealTimeDBDelegate.ts +70 -79
  33. package/src/hooks/useFirebaseStorageSource.ts +23 -25
  34. package/src/hooks/useFirestoreDriver.ts +812 -0
  35. package/src/hooks/useInitialiseFirebase.ts +2 -2
  36. package/src/types/auth.tsx +2 -2
  37. package/src/types/text_search.ts +3 -3
  38. package/src/utils/algolia.ts +6 -9
  39. package/src/utils/collections_firestore.ts +25 -29
  40. package/src/utils/database.ts +2 -2
  41. package/src/utils/local_text_search_controller.ts +12 -12
  42. package/src/utils/pinecone.ts +3 -3
  43. package/src/utils/rebase_search_controller.ts +23 -22
  44. package/src/utils/text_search_controller.ts +2 -2
  45. package/dist/social_icons.d.ts +0 -6
  46. package/src/hooks/useFirestoreDataSource.ts +0 -796
  47. package/src/social_icons.tsx +0 -135
@@ -1,5 +1,5 @@
1
1
  import { ApplicationVerifier, ConfirmationResult, User as FirebaseUser } from "@firebase/auth";
2
- import { AuthController, Role, User } from "@rebasepro/core";
2
+ import type { AuthController, User } from "@rebasepro/types";
3
3
  /**
4
4
  * @group Firebase
5
5
  */
@@ -37,5 +37,5 @@ export type FirebaseAuthController<USER extends User = FirebaseUserWrapper, Extr
37
37
  */
38
38
  skipLogin: () => void;
39
39
  setUser: (user: USER | null) => void;
40
- setUserRoles: (roles: Role[]) => void;
40
+ setUserRoles: (roles: string[]) => void;
41
41
  };
@@ -1,6 +1,6 @@
1
1
  import { User as FirebaseUser } from "@firebase/auth";
2
2
  import { FirebaseApp } from "@firebase/app";
3
- import { EntityCollection } from "@rebasepro/core";
3
+ import { CollectionConfig } from "@rebasepro/types";
4
4
  export type FirestoreTextSearchControllerBuilder = (props: {
5
5
  firebaseApp: FirebaseApp;
6
6
  }) => FirestoreTextSearchController;
@@ -23,7 +23,7 @@ export type FirestoreTextSearchController = {
23
23
  init: (props: {
24
24
  path: string;
25
25
  databaseId?: string;
26
- collection?: EntityCollection;
26
+ collection?: CollectionConfig;
27
27
  }) => Promise<boolean>;
28
28
  /**
29
29
  * Do the search and return a list of ids.
@@ -34,6 +34,6 @@ export type FirestoreTextSearchController = {
34
34
  path: string;
35
35
  currentUser?: FirebaseUser;
36
36
  databaseId?: string;
37
- collection?: EntityCollection;
37
+ collection?: CollectionConfig;
38
38
  }) => (Promise<readonly string[] | undefined>);
39
39
  };
@@ -1,4 +1,3 @@
1
- import { buildExternalSearchController } from "./text_search_controller";
2
1
  /**
3
2
  * Utility function to perform a text search in an algolia index,
4
3
  * returning the ids of the entities.
@@ -7,8 +6,10 @@ import { buildExternalSearchController } from "./text_search_controller";
7
6
  * @param query
8
7
  * @group Firebase
9
8
  */
10
- export declare function performAlgoliaTextSearch(client: any, indexName: string, query: string): Promise<readonly string[]>;
11
- /**
12
- * @deprecated Use `buildExternalSearchController` instead
13
- */
14
- export declare const buildAlgoliaSearchController: typeof buildExternalSearchController;
9
+ export declare function performAlgoliaTextSearch(client: {
10
+ searchSingleIndex: (params: Record<string, unknown>) => Promise<{
11
+ hits: Array<{
12
+ objectID: string;
13
+ }>;
14
+ }>;
15
+ }, indexName: string, query: string): Promise<readonly string[]>;
@@ -1,5 +1,5 @@
1
1
  import { DocumentSnapshot } from "@firebase/firestore";
2
- import { PersistedCollection } from "@rebasepro/studio";
3
- export declare function buildCollectionId(idOrPath: string, parentCollectionIds?: string[]): string;
4
- export declare const docsToCollectionTree: (docs: DocumentSnapshot[]) => PersistedCollection[];
5
- export declare const docToCollection: (doc: DocumentSnapshot) => PersistedCollection;
2
+ import { CollectionConfig } from "@rebasepro/types";
3
+ export declare function buildCollectionId(idOrPath: string, parentCollectionSlugs?: string[], parentEntityIds?: string[]): string;
4
+ export declare const docsToCollectionTree: (docs: DocumentSnapshot[]) => CollectionConfig[];
5
+ export declare const docToCollection: (doc: DocumentSnapshot) => CollectionConfig;
package/package.json CHANGED
@@ -1,67 +1,77 @@
1
1
  {
2
- "name": "@rebasepro/firebase",
3
- "type": "module",
4
- "version": "0.0.1-canary.2",
5
- "publishConfig": {
6
- "access": "public"
2
+ "name": "@rebasepro/firebase",
3
+ "type": "module",
4
+ "version": "0.0.1-canary.eb08332",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "main": "./dist/index.umd.js",
9
+ "module": "./dist/index.es.js",
10
+ "types": "./dist/index.d.ts",
11
+ "source": "src/index.ts",
12
+ "dependencies": {
13
+ "fast-equals": "6.0.0",
14
+ "fuse.js": "^7.4.2",
15
+ "react-router-dom": "^7.17.0",
16
+ "@rebasepro/admin": "0.0.1-canary.eb08332",
17
+ "@rebasepro/app": "0.0.1-canary.eb08332",
18
+ "@rebasepro/ui": "0.0.1-canary.eb08332",
19
+ "@rebasepro/types": "0.0.1-canary.eb08332",
20
+ "@rebasepro/common": "0.0.1-canary.eb08332",
21
+ "@rebasepro/utils": "0.0.1-canary.eb08332"
22
+ },
23
+ "peerDependencies": {
24
+ "firebase": "^10.12.2 || ^11.0.0 || ^12.0.0",
25
+ "react": ">=19.0.0",
26
+ "react-dom": ">=19.0.0",
27
+ "typesense": "^1.8.0"
28
+ },
29
+ "peerDependenciesMeta": {
30
+ "typesense": {
31
+ "optional": true
32
+ }
33
+ },
34
+ "exports": {
35
+ ".": {
36
+ "types": "./dist/index.d.ts",
37
+ "development": "./dist/index.es.js",
38
+ "import": "./dist/index.es.js",
39
+ "require": "./dist/index.umd.js"
7
40
  },
8
- "main": "./dist/index.umd.js",
9
- "module": "./dist/index.es.js",
10
- "types": "./dist/index.d.ts",
11
- "source": "src/index.ts",
12
- "dependencies": {
13
- "@firebase/auth": "*",
14
- "@rebasepro/common": "^0.0.1-canary.2",
15
- "@rebasepro/core": "^0.0.1-canary.2",
16
- "@rebasepro/data_enhancement": "^0.0.1-canary.2",
17
- "@rebasepro/data_export": "^0.0.1-canary.2",
18
- "@rebasepro/data_import": "^0.0.1-canary.2",
19
- "@rebasepro/data_import_export": "^0.0.1-canary.2",
20
- "@rebasepro/schema_inference": "^0.0.1-canary.2",
21
- "@rebasepro/studio": "4.0.0",
22
- "@rebasepro/types": "^0.0.1-canary.2",
23
- "@rebasepro/ui": "^0.0.1-canary.2",
24
- "react-router": "^7.13.1",
25
- "react-router-dom": "^7.13.1"
26
- },
27
- "peerDependencies": {
28
- "firebase": "^10.12.2 || ^11.0.0 || ^12.0.0",
29
- "react": ">=19.0.0",
30
- "react-dom": ">=19.0.0",
31
- "typesense": "^1.8.0"
32
- },
33
- "peerDependenciesMeta": {
34
- "typesense": {
35
- "optional": true
36
- }
37
- },
38
- "exports": {
39
- ".": {
40
- "development": "./src/index.ts",
41
- "import": "./dist/index.es.js",
42
- "require": "./dist/index.umd.js",
43
- "types": "./dist/index.d.ts"
44
- },
45
- "./package.json": "./package.json"
46
- },
47
- "devDependencies": {
48
- "@types/node": "^20.19.17",
49
- "@types/react": "^19.0.8",
50
- "@types/react-dom": "^19.0.3",
51
- "babel-plugin-react-compiler": "^19.0.0-beta-af1b7da-20250417",
52
- "eslint-plugin-react-compiler": "^19.1.0-rc.2",
53
- "typescript": "^5.9.3",
54
- "typesense": "^2.1.0",
55
- "vite": "^7.2.4"
56
- },
57
- "scripts": {
58
- "dev": "vite",
59
- "build": "vite build && tsc --emitDeclarationOnly -p tsconfig.prod.json",
60
- "clean": "rm -rf dist && find ./src -name '*.js' -type f | xargs rm -f"
61
- },
62
- "files": [
63
- "dist",
64
- "src"
65
- ],
66
- "gitHead": "d935eefa5aa8d1009a2398cfac2c1e4ee9aeb6b6"
67
- }
41
+ "./package.json": "./package.json"
42
+ },
43
+ "devDependencies": {
44
+ "@firebase/app": "^0.15.0",
45
+ "@firebase/app-check": "^0.12.0",
46
+ "@firebase/auth": "^1.13.3",
47
+ "@firebase/database": "^1.1.3",
48
+ "@firebase/firestore": "^4.16.0",
49
+ "@firebase/functions": "^0.13.5",
50
+ "@firebase/storage": "^0.14.3",
51
+ "@types/jest": "^30.0.0",
52
+ "@types/node": "^25.9.3",
53
+ "@types/react": "^19.2.17",
54
+ "@types/react-dom": "^19.2.3",
55
+ "@vitejs/plugin-react": "^6.0.2",
56
+ "babel-plugin-react-compiler": "19.0.0-beta-ebf51a3-20250411",
57
+ "firebase": "^12.15.0",
58
+ "typescript": "^6.0.3",
59
+ "typesense": "^3.0.6",
60
+ "vite": "^8.0.16"
61
+ },
62
+ "files": [
63
+ "dist",
64
+ "src"
65
+ ],
66
+ "gitHead": "d935eefa5aa8d1009a2398cfac2c1e4ee9aeb6b6",
67
+ "repository": {
68
+ "type": "git",
69
+ "url": "https://github.com/rebasepro/rebase.git",
70
+ "directory": "packages/firebase"
71
+ },
72
+ "scripts": {
73
+ "dev": "vite",
74
+ "build": "vite build && tsc --emitDeclarationOnly -p tsconfig.prod.json",
75
+ "clean": "rm -rf dist && find ./src -name '*.js' -type f | xargs rm -f"
76
+ }
77
+ }
@@ -1,24 +1,27 @@
1
+
1
2
  import React, { ReactNode, useCallback, useEffect, useRef, useState } from "react";
2
3
 
3
4
  import { FirebaseApp, FirebaseError } from "@firebase/app";
4
- import { ErrorView, RebaseLogo, useModeController, useSnackbarController, } from "@rebasepro/core";
5
+ import { ErrorView, RebaseLogo, useModeController, useSnackbarController } from "@rebasepro/app";
5
6
  import {
6
- ArrowBackIcon,
7
+ ArrowLeftIcon,
7
8
  Button,
8
- CallIcon,
9
9
  CircularProgress,
10
10
  cls,
11
11
  IconButton,
12
+ iconSize,
12
13
  LoadingButton,
13
14
  MailIcon,
14
- PersonIcon,
15
+ PhoneIcon,
15
16
  TextField,
16
17
  Typography,
18
+ UserIcon
17
19
  } from "@rebasepro/ui";
18
20
  import { appleIcon, facebookIcon, githubIcon, googleIcon, microsoftIcon, twitterIcon } from "./social_icons";
19
21
  import {
20
22
  getAuth,
21
23
  getMultiFactorResolver,
24
+ MultiFactorError,
22
25
  PhoneAuthProvider,
23
26
  PhoneMultiFactorGenerator,
24
27
  RecaptchaVerifier
@@ -96,7 +99,7 @@ export interface FirebaseLoginViewProps {
96
99
  */
97
100
  additionalComponent?: ReactNode;
98
101
 
99
- notAllowedError?: any;
102
+ notAllowedError?: string | Error;
100
103
 
101
104
  className?: string;
102
105
 
@@ -151,7 +154,7 @@ export function FirebaseLoginView({
151
154
  const auth = getAuth(firebaseApp);
152
155
  const recaptchaVerifier = new RecaptchaVerifier(auth, "recaptcha", { size: "invisible" });
153
156
 
154
- const resolver = getMultiFactorResolver(auth, authController.authProviderError as any);
157
+ const resolver = getMultiFactorResolver(auth, authController.authProviderError as MultiFactorError);
155
158
 
156
159
  if (resolver.hints[0].factorId === PhoneMultiFactorGenerator.FACTOR_ID) {
157
160
 
@@ -181,11 +184,11 @@ export function FirebaseLoginView({
181
184
  }, [authController.authProviderError]);
182
185
 
183
186
  function buildErrorView() {
184
- let errorView: any;
187
+ let errorView: React.ReactNode;
185
188
  if (authController.user != null) return errorView; // if the user is logged in via MFA
186
189
  const ignoredCodes = ["auth/popup-closed-by-user", "auth/cancelled-popup-request"];
187
190
  if (authController.authProviderError) {
188
- const authError = authController.authProviderError as any;
191
+ const authError = authController.authProviderError as FirebaseError;
189
192
  if (authError.code === "auth/operation-not-allowed" ||
190
193
  authError.code === "auth/configuration-not-found") {
191
194
  errorView =
@@ -193,7 +196,7 @@ export function FirebaseLoginView({
193
196
  <div className="p-4">
194
197
  <ErrorView
195
198
  title={"Firebase Auth not enabled"}
196
- error={"You need to enable Firebase Auth and the corresponding login provider in your Firebase project"} />
199
+ error={"You need to enable Firebase Auth and the corresponding login provider in your Firebase project"}/>
197
200
  </div>
198
201
  {firebaseApp &&
199
202
  <div className="p-4">
@@ -211,19 +214,19 @@ export function FirebaseLoginView({
211
214
  errorView = <div className="p-4">
212
215
  <ErrorView
213
216
  title={"Invalid API key"}
214
- error={"auth/invalid-api-key: Check that your Firebase config is set correctly in your `firebase_config.ts` file"} />
217
+ error={"auth/invalid-api-key: Check that your Firebase config is set correctly in your `firebase_config.ts` file"}/>
215
218
  </div>;
216
219
  } else if (authError.code === "auth/email-already-in-use") {
217
220
  errorView = <div className="p-4">
218
221
  <ErrorView
219
222
  title={"Email already in use"}
220
- error={"The selected email is already in use by another account"} />
223
+ error={"The selected email is already in use by another account"}/>
221
224
  </div>;
222
225
  } else if (authError.code === "auth/invalid-credential") {
223
226
  errorView = <div className="p-4">
224
227
  <ErrorView
225
228
  title={"Invalid credential"}
226
- error={"The provided credential is not correct"} />
229
+ error={"The provided credential is not correct"}/>
227
230
  </div>;
228
231
  } else if (!ignoredCodes.includes(authError.code)) {
229
232
  if (authError.code === "auth/multi-factor-auth-required") {
@@ -231,7 +234,7 @@ export function FirebaseLoginView({
231
234
  }
232
235
  errorView =
233
236
  <div className="p-4">
234
- <ErrorView error={authController.authProviderError as Error} />
237
+ <ErrorView error={authController.authProviderError as Error}/>
235
238
  </div>;
236
239
  }
237
240
  }
@@ -246,9 +249,9 @@ export function FirebaseLoginView({
246
249
  width: "100%",
247
250
  objectFit: "contain"
248
251
  }}
249
- alt={"Logo"} />;
252
+ alt={"Logo"}/>;
250
253
  } else {
251
- logoComponent = <RebaseLogo />;
254
+ logoComponent = <RebaseLogo/>;
252
255
  }
253
256
 
254
257
  let notAllowedMessage: string | undefined;
@@ -258,7 +261,7 @@ export function FirebaseLoginView({
258
261
  } else if (notAllowedError instanceof Error) {
259
262
  notAllowedMessage = notAllowedError.message;
260
263
  } else {
261
- notAllowedMessage = "It looks like you don't have access to the CMS, based on the specified Authenticator configuration";
264
+ notAllowedMessage = "It looks like you don't have access to the CMS, based on the specified access gate configuration";
262
265
  }
263
266
  }
264
267
 
@@ -284,36 +287,36 @@ export function FirebaseLoginView({
284
287
 
285
288
  {notAllowedMessage &&
286
289
  <div className="p-8">
287
- <ErrorView error={notAllowedMessage} />
290
+ <ErrorView error={notAllowedMessage}/>
288
291
  </div>}
289
292
 
290
293
  {buildErrorView()}
291
294
 
292
295
  {(!passwordLoginSelected && !phoneLoginSelected) && <div className={"my-4 w-full"}>
293
296
 
294
- {buildOauthLoginButtons(authController, resolvedSignInOptions, modeState.mode, disabled)}
297
+ {buildOauthLoginButtons(authController, resolvedSignInOptions, modeState.mode as "light" | "dark", disabled)}
295
298
 
296
299
  {resolvedSignInOptions.includes("password") &&
297
300
  <LoginButton
298
301
  disabled={disabled}
299
302
  text={"Email/password"}
300
- icon={<MailIcon size={28} />}
301
- onClick={() => setPasswordLoginSelected(true)} />}
303
+ icon={<MailIcon size={iconSize.medium}/>}
304
+ onClick={() => setPasswordLoginSelected(true)}/>}
302
305
 
303
306
  {resolvedSignInOptions.includes("phone") &&
304
307
  <LoginButton
305
308
  disabled={disabled}
306
- text={"Phone number"}
307
- icon={<CallIcon size={28} />}
308
- onClick={() => setPhoneLoginSelected(true)} />}
309
+ text={"PhoneIcon number"}
310
+ icon={<PhoneIcon size={iconSize.medium}/>}
311
+ onClick={() => setPhoneLoginSelected(true)}/>}
309
312
 
310
313
  {resolvedSignInOptions.includes("anonymous") &&
311
314
  <LoginButton
312
315
  disabled={disabled}
313
316
  text={"Log in anonymously"}
314
- icon={<PersonIcon
315
- size={28} />}
316
- onClick={authController.anonymousLogin} />}
317
+ icon={<UserIcon
318
+ size={"medium"}/>}
319
+ onClick={authController.anonymousLogin}/>}
317
320
 
318
321
  {allowSkipLogin &&
319
322
  <Button
@@ -330,7 +333,7 @@ export function FirebaseLoginView({
330
333
  {passwordLoginSelected && <LoginForm
331
334
  authController={authController}
332
335
  onClose={() => setPasswordLoginSelected(false)}
333
- mode={modeState.mode}
336
+ mode={modeState.mode as "light" | "dark"}
334
337
  noUserComponent={noUserComponent}
335
338
  disableSignupScreen={disableSignupScreen}
336
339
  disableResetPassword={disableResetPassword}
@@ -362,7 +365,7 @@ export function LoginButton({
362
365
  return (
363
366
  <div className="my-1 w-full">
364
367
  <Button
365
- className={cls("w-full bg-white dark:bg-surface-800 text-surface-900 dark:text-surface-100", disabled ? "" : "hover:text-surface-800 hover:dark:text-white")}
368
+ className={cls("w-full bg-white dark:bg-surface-950 text-surface-900 dark:text-surface-100", disabled ? "" : "hover:text-surface-950 hover:dark:text-white")}
366
369
  style={{
367
370
  height: "40px",
368
371
  borderRadius: "4px",
@@ -397,7 +400,7 @@ function PhoneLoginForm({
397
400
  const [code, setCode] = useState<string>();
398
401
  const [isInvalidCode, setIsInvalidCode] = useState(false);
399
402
 
400
- const handleSubmit = async (event: any) => {
403
+ const handleSubmit = async (event: React.FormEvent) => {
401
404
  event.preventDefault();
402
405
 
403
406
  if (code && authController.confirmationResult) {
@@ -419,15 +422,15 @@ function PhoneLoginForm({
419
422
  <form onSubmit={handleSubmit}>
420
423
  {isInvalidCode &&
421
424
  <div className="p-8">
422
- <ErrorView error={"Invalid confirmation code"} />
425
+ <ErrorView error={"Invalid confirmation code"}/>
423
426
  </div>}
424
427
 
425
- <div id={RECAPTCHA_CONTAINER_ID} />
428
+ <div id={RECAPTCHA_CONTAINER_ID}/>
426
429
 
427
430
  <div className={"flex flex-col gap-1"}>
428
431
  <IconButton
429
432
  onClick={onClose}>
430
- <ArrowBackIcon className="w-5 h-5" />
433
+ <ArrowLeftIcon className="w-5 h-5"/>
431
434
  </IconButton>
432
435
  <div className="p-1 flex">
433
436
  <Typography align={"center"}
@@ -437,7 +440,7 @@ function PhoneLoginForm({
437
440
  value={phone ?? ""}
438
441
  disabled={Boolean(phone && (authController.authLoading || authController.confirmationResult))}
439
442
  type="phone"
440
- onChange={(event) => setPhone(event.target.value)} />
443
+ onChange={(event) => setPhone(event.target.value)}/>
441
444
  {Boolean(phone && authController.confirmationResult) &&
442
445
  <>
443
446
  <div className="mt-2 p-1 flex">
@@ -447,14 +450,14 @@ function PhoneLoginForm({
447
450
  <TextField placeholder=""
448
451
  value={code ?? ""}
449
452
  type="text"
450
- onChange={(event) => setCode(event.target.value)} />
453
+ onChange={(event) => setCode(event.target.value)}/>
451
454
  </>
452
455
  }
453
456
 
454
457
  <div className="flex justify-end items-center w-full">
455
458
 
456
459
  {authController.authLoading &&
457
- <CircularProgress className="p-1" size={"small"} />
460
+ <CircularProgress className="p-1" size={"small"}/>
458
461
  }
459
462
 
460
463
  <Button type="submit">
@@ -503,8 +506,8 @@ function LoginForm({
503
506
 
504
507
  useEffect(() => {
505
508
  if (!document) return;
506
- const escFunction = (event: any) => {
507
- if (event.keyCode === 27) {
509
+ const escFunction = (event: KeyboardEvent) => {
510
+ if (event.key === "Escape") {
508
511
  onClose();
509
512
  }
510
513
  };
@@ -545,7 +548,7 @@ function LoginForm({
545
548
  }
546
549
  }
547
550
 
548
- const handleSubmit = (event: any) => {
551
+ const handleSubmit = (event: React.FormEvent) => {
549
552
  event.preventDefault();
550
553
  if (loginState === "email") {
551
554
  handleEnterEmail();
@@ -568,7 +571,7 @@ function LoginForm({
568
571
  <div className={"max-w-[480px] w-full flex flex-col gap-4"}>
569
572
  <IconButton
570
573
  onClick={onBackPressed}>
571
- <ArrowBackIcon className="w-5 h-5" />
574
+ <ArrowLeftIcon className="w-5 h-5"/>
572
575
  </IconButton>
573
576
 
574
577
  <div>
@@ -583,7 +586,7 @@ function LoginForm({
583
586
  value={email ?? ""}
584
587
  disabled={authController.authLoading}
585
588
  type="email"
586
- onChange={(event) => setEmail(event.target.value)} />}
589
+ onChange={(event) => setEmail(event.target.value)}/>}
587
590
 
588
591
  <div
589
592
  className={`${loginState === "password" || (loginState === "registration" && !disableSignupScreen) ? "block" : "hidden"}`}>
@@ -592,14 +595,14 @@ function LoginForm({
592
595
  disabled={authController.authLoading}
593
596
  inputRef={passwordRef}
594
597
  type="password"
595
- onChange={(event) => setPassword(event.target.value)} />
598
+ onChange={(event) => setPassword(event.target.value)}/>
596
599
  </div>
597
600
 
598
601
  <div
599
602
  className={`${loginState === "registration" && disableSignupScreen ? "hidden" : "flex"} justify-end items-center w-full flex gap-2`}>
600
603
 
601
604
  {authController.authLoading &&
602
- <CircularProgress className="p-1" size={"small"} />
605
+ <CircularProgress className="p-1" size={"small"}/>
603
606
  }
604
607
 
605
608
  {!disableResetPassword && <LoadingButton variant="text"
@@ -614,9 +617,9 @@ function LoginForm({
614
617
  message: "Password reset email sent",
615
618
  type: "success"
616
619
  });
617
- } catch (e: any) {
620
+ } catch (e: unknown) {
618
621
  snackbarController.open({
619
- message: e.message,
622
+ message: e instanceof Error ? e.message : String(e),
620
623
  type: "error"
621
624
  });
622
625
  }
@@ -667,36 +670,36 @@ function buildOauthLoginButtons(authController: FirebaseAuthController, provider
667
670
  disabled={disabled}
668
671
  text={"Sign in with Google"}
669
672
  icon={googleIcon(mode)}
670
- onClick={authController.googleLogin} />}
673
+ onClick={authController.googleLogin}/>}
671
674
 
672
675
  {providers.includes("microsoft.com") && <LoginButton
673
676
  disabled={disabled}
674
677
  text={"Sign in with Microsoft"}
675
678
  icon={microsoftIcon(mode)}
676
- onClick={authController.microsoftLogin} />}
679
+ onClick={authController.microsoftLogin}/>}
677
680
 
678
681
  {providers.includes("apple.com") && <LoginButton
679
682
  disabled={disabled}
680
683
  text={"Sign in with Apple"}
681
684
  icon={appleIcon(mode)}
682
- onClick={authController.appleLogin} />}
685
+ onClick={authController.appleLogin}/>}
683
686
 
684
687
  {providers.includes("github.com") && <LoginButton
685
688
  disabled={disabled}
686
689
  text={"Sign in with Github"}
687
690
  icon={githubIcon(mode)}
688
- onClick={authController.githubLogin} />}
691
+ onClick={authController.githubLogin}/>}
689
692
 
690
693
  {providers.includes("facebook.com") && <LoginButton
691
694
  disabled={disabled}
692
695
  text={"Sign in with Facebook"}
693
696
  icon={facebookIcon(mode)}
694
- onClick={authController.facebookLogin} />}
697
+ onClick={authController.facebookLogin}/>}
695
698
 
696
699
  {providers.includes("twitter.com") && <LoginButton
697
700
  disabled={disabled}
698
701
  text={"Sign in with Twitter"}
699
702
  icon={twitterIcon(mode)}
700
- onClick={authController.twitterLogin} />}
703
+ onClick={authController.twitterLogin}/>}
701
704
  </>
702
705
  }