@rebasepro/client-firebase 0.2.3 → 0.2.5

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.
@@ -16,4 +16,4 @@ import { RebaseFirebaseAppProps } from "./RebaseFirebaseAppProps";
16
16
 
17
17
  * @category Firebase
18
18
  */
19
- export declare function RebaseFirebaseApp({ name, logo, logoDark, authenticator, collections, views, adminViews, textSearchControllerBuilder, allowSkipLogin, signInOptions, firebaseConfig, onFirebaseInit, appCheckOptions, dateTimeFormat, locale, basePath, baseCollectionPath, onAnalyticsEvent, propertyConfigs: propertyConfigsProp, plugins, autoOpenDrawer, firestoreIndexesBuilder, components, localTextSearchEnabled, userManagement }: RebaseFirebaseAppProps): import("react/jsx-runtime").JSX.Element;
19
+ export declare function RebaseFirebaseApp({ name, logo, logoDark, accessGate, collections, views, adminViews, textSearchControllerBuilder, allowSkipLogin, signInOptions, firebaseConfig, onFirebaseInit, appCheckOptions, dateTimeFormat, locale, basePath, baseCollectionPath, onAnalyticsEvent, propertyConfigs: propertyConfigsProp, plugins, autoOpenDrawer, firestoreIndexesBuilder, components, localTextSearchEnabled, userManagement }: RebaseFirebaseAppProps): import("react/jsx-runtime").JSX.Element;
@@ -1,5 +1,6 @@
1
1
  import React from "react";
2
- import { Authenticator, AnalyticsEvent, AppView, AppViewsBuilder, EntityCollection, EntityCollectionsBuilder, RebasePlugin, Locale, PropertyConfig } from "@rebasepro/types";
2
+ import { AnalyticsEvent, AppView, AppViewsBuilder, EntityCollection, EntityCollectionsBuilder, RebasePlugin, Locale, PropertyConfig } from "@rebasepro/types";
3
+ import { FirebaseAccessGate } from "../hooks/useFirebaseAccessGate";
3
4
  import { UserManagementDelegate } from "@rebasepro/types";
4
5
  import { FirebaseApp } from "@firebase/app";
5
6
  import { FirebaseLoginViewProps } from "./FirebaseLoginView";
@@ -48,12 +49,12 @@ export type RebaseFirebaseAppProps = {
48
49
  propertyConfigs?: PropertyConfig[];
49
50
  /**
50
51
  * Do the users need to log in to access the CMS.
51
- * You can specify an Authenticator function to discriminate which users can
52
- * access the CMS or not.
52
+ * You can specify a {@link FirebaseAccessGate} function to discriminate
53
+ * which users can access the CMS or not.
53
54
  * If not specified, authentication is enabled but no user restrictions
54
55
  * apply
55
56
  */
56
- authenticator?: boolean | Authenticator<FirebaseUserWrapper>;
57
+ accessGate?: boolean | FirebaseAccessGate<FirebaseUserWrapper>;
57
58
  /**
58
59
  * List of sign in options that will be displayed in the login
59
60
  * view if `authentication` is enabled. You can pass Firebase providers strings,
@@ -6,3 +6,4 @@ export * from "./useFirestoreDriver";
6
6
  export * from "./useFirebaseRealTimeDBDelegate";
7
7
  export * from "./useRecaptcha";
8
8
  export * from "./useBuildUserManagement";
9
+ export * from "./useFirebaseAccessGate";
@@ -10,7 +10,7 @@ export interface InitializeAppCheckProps {
10
10
  export interface InitializeAppCheckResult {
11
11
  loading: boolean;
12
12
  appCheckVerified?: boolean;
13
- error?: any;
13
+ error?: unknown;
14
14
  }
15
15
  /**
16
16
  * Function used to initialise Firebase App Check.
@@ -1,5 +1,10 @@
1
- import { AuthController, DataDriver, Role, User, UserManagementDelegate } from "@rebasepro/types";
2
- export interface UserManagementDelegateParams<CONTROLLER extends AuthController<any> = AuthController<any>> {
1
+ import { AuthController, DataDriver, User, UserManagementDelegate } from "@rebasepro/types";
2
+ export interface Role {
3
+ id: string;
4
+ name: string;
5
+ isAdmin?: boolean;
6
+ }
7
+ export interface UserManagementDelegateParams<CONTROLLER extends AuthController<User> = AuthController<User>> {
3
8
  authController: CONTROLLER;
4
9
  /**
5
10
  * The delegate in charge of persisting the data.
@@ -27,10 +32,6 @@ export interface UserManagementDelegateParams<CONTROLLER extends AuthController<
27
32
  * If there are no roles in the database, provide a button to create the default roles.
28
33
  */
29
34
  allowDefaultRolesCreation?: boolean;
30
- /**
31
- * Include the collection config permissions in the user management system.
32
- */
33
- includeCollectionConfigPermissions?: boolean;
34
35
  }
35
36
  /**
36
37
  * This hook is used to build a user management object that can be used to
@@ -41,6 +42,5 @@ export interface UserManagementDelegateParams<CONTROLLER extends AuthController<
41
42
  * @param rolesPath
42
43
  * @param roles
43
44
  * @param allowDefaultRolesCreation
44
- * @param includeCollectionConfigPermissions
45
45
  */
46
- export declare function useBuildUserManagement<CONTROLLER extends AuthController<any> = AuthController<any>, USER extends User = CONTROLLER extends AuthController<infer U> ? U : any>({ authController, dataSourceDelegate, roles: rolesProp, usersPath, rolesPath, allowDefaultRolesCreation, includeCollectionConfigPermissions }: UserManagementDelegateParams<CONTROLLER>): UserManagementDelegate<USER> & CONTROLLER;
46
+ export declare function useBuildUserManagement<CONTROLLER extends AuthController<User> = AuthController<User>, USER extends User = CONTROLLER extends AuthController<infer U> ? U : User>({ authController, dataSourceDelegate, roles: rolesProp, usersPath, rolesPath, allowDefaultRolesCreation }: UserManagementDelegateParams<CONTROLLER>): UserManagementDelegate<USER> & CONTROLLER;
@@ -0,0 +1,44 @@
1
+ import { AuthController, RebaseData, StorageSource, User } from "@rebasepro/types";
2
+ /**
3
+ * Client-side gate that decides whether a Firebase-authenticated user
4
+ * is allowed to access the CMS UI.
5
+ *
6
+ * Return `true` to allow access or `false` / throw to deny.
7
+ * @group Firebase
8
+ */
9
+ export type FirebaseAccessGate<USER extends User = User> = (props: {
10
+ /**
11
+ * Logged-in user or null
12
+ */
13
+ user: USER | null;
14
+ /**
15
+ * AuthController
16
+ */
17
+ authController: AuthController<USER>;
18
+ /**
19
+ * Unified data access API
20
+ */
21
+ data: RebaseData;
22
+ /**
23
+ * Used storage implementation
24
+ */
25
+ storageSource: StorageSource;
26
+ }) => boolean | Promise<boolean>;
27
+ /**
28
+ * Hook that evaluates a {@link FirebaseAccessGate} callback after
29
+ * the user logs in and gates access to the main CMS view.
30
+ *
31
+ * @group Firebase
32
+ */
33
+ export declare function useFirebaseAccessGate<USER extends User = User>({ disabled, authController, accessGate, storageSource, data }: {
34
+ disabled?: boolean;
35
+ authController: AuthController<USER>;
36
+ accessGate?: boolean | FirebaseAccessGate<USER>;
37
+ data: RebaseData;
38
+ storageSource: StorageSource;
39
+ }): {
40
+ canAccessMainView: boolean;
41
+ authLoading: boolean;
42
+ notAllowedError: unknown;
43
+ authVerified: boolean;
44
+ };
@@ -1,12 +1,12 @@
1
1
  import { FirebaseApp } from "@firebase/app";
2
2
  import { FirebaseAuthController, FirebaseSignInOption, FirebaseSignInProvider, FirebaseUserWrapper } from "../types";
3
- import { Role, User } from "@rebasepro/types";
3
+ import type { User } from "@rebasepro/types";
4
4
  export interface FirebaseAuthControllerProps {
5
5
  loading?: boolean;
6
6
  firebaseApp?: FirebaseApp;
7
7
  signInOptions?: Array<FirebaseSignInProvider | FirebaseSignInOption>;
8
8
  onSignOut?: () => void;
9
- defineRolesFor?: (user: User) => Promise<Role[] | undefined> | Role[] | undefined;
9
+ defineRolesFor?: (user: User) => Promise<string[] | undefined> | string[] | undefined;
10
10
  }
11
11
  /**
12
12
  * Use this hook to build an {@link AuthController} based on Firebase Auth
@@ -52,5 +52,5 @@ export declare function useFirestoreDriver({ firebaseApp, textSearchControllerBu
52
52
  * @param data
53
53
  * @group Firestore
54
54
  */
55
- export declare function firestoreToCMSModel(data: any): any;
56
- export declare function cmsToFirestoreModel(data: any, firestore: Firestore, inArray?: boolean): any;
55
+ export declare function firestoreToCMSModel(data: unknown): unknown;
56
+ export declare function cmsToFirestoreModel(data: unknown, firestore: Firestore, inArray?: boolean): unknown;
package/dist/index.es.js CHANGED
@@ -13,7 +13,7 @@ import { c } from "react-compiler-runtime";
13
13
  import { getDatabase, query as query$1, ref as ref$1, orderByKey, startAt, limitToFirst, get, onValue, push, set, remove, orderByChild } from "@firebase/database";
14
14
  import { removeUndefined } from "@rebasepro/utils";
15
15
  import { jsx, Fragment, jsxs } from "react/jsx-runtime";
16
- import { useModeController, ErrorView, useSnackbarController, RebaseLogo, useBrowserTitleAndIcon, useBuildModeController, useBuildAdminModeController, useBuildLocalConfigurationPersistence, useValidateAuthenticator, RebaseRoutes, Rebase, AdminModeControllerProvider, SnackbarProvider, ModeControllerProvider } from "@rebasepro/core";
16
+ import { useModeController, ErrorView, useSnackbarController, RebaseLogo, useBrowserTitleAndIcon, useBuildModeController, useBuildAdminModeController, useBuildLocalConfigurationPersistence, RebaseRoutes, Rebase, AdminModeControllerProvider, SnackbarProvider, ModeControllerProvider } from "@rebasepro/core";
17
17
  import { useBuildCollectionRegistryController, useBuildUrlController, useBuildNavigationStateController, NavigationStateContext, UrlContext, CollectionRegistryContext, SideEntityProvider, RebaseRoute, Scaffold, AppBar, Drawer, SideDialogs } from "@rebasepro/admin";
18
18
  import { MailIcon, iconSize, PhoneIcon, UserIcon, Button, cls, IconButton, ArrowLeftIcon, Typography, TextField, CircularProgress, LoadingButton, CircularProgressCenter, CenteredView } from "@rebasepro/ui";
19
19
  import { Navigate, Route, Outlet } from "react-router-dom";
@@ -34,9 +34,7 @@ const useFirebaseAuthController = ({
34
34
  const [userRoles, _setUserRoles] = useState();
35
35
  const [extra, setExtra] = useState();
36
36
  const setUserRoles = useCallback((roles) => {
37
- const currentRoleIds = userRoles?.map((r) => r.id);
38
- const newRoleIds = roles?.map((r_0) => r_0.id);
39
- if (!deepEqual(currentRoleIds, newRoleIds)) {
37
+ if (!deepEqual(userRoles, roles)) {
40
38
  _setUserRoles(roles);
41
39
  }
42
40
  }, [userRoles]);
@@ -224,8 +222,7 @@ const useFirebaseAuthController = ({
224
222
  }, []);
225
223
  const firebaseUserWrapper = loggedUser ? {
226
224
  ...loggedUser,
227
- roles: userRoles?.map((r_1) => r_1.id),
228
- // User.roles is string[], keep Role[] internally only
225
+ roles: userRoles,
229
226
  firebaseUser: loggedUser
230
227
  } : null;
231
228
  return {
@@ -351,7 +348,7 @@ function useFirebaseStorageSource({
351
348
  const blob = await response.blob();
352
349
  return new File([blob], path);
353
350
  } catch (e) {
354
- if (e?.code === "storage/object-not-found") return null;
351
+ if (typeof e === "object" && e !== null && "code" in e && e.code === "storage/object-not-found") return null;
355
352
  throw e;
356
353
  }
357
354
  },
@@ -383,7 +380,7 @@ function useFirebaseStorageSource({
383
380
  urlsCache[storagePathOrUrl] = result;
384
381
  return result;
385
382
  } catch (e) {
386
- if (e?.code === "storage/object-not-found") return {
383
+ if (typeof e === "object" && e !== null && "code" in e && e.code === "storage/object-not-found") return {
387
384
  url: null,
388
385
  fileNotFound: true
389
386
  };
@@ -442,7 +439,7 @@ function useInitialiseFirebase({
442
439
  setFirebaseApp(initialisedFirebaseApp);
443
440
  } catch (e) {
444
441
  console.error("Error initialising Firebase", e);
445
- setConfigError(hostingError + "\n" + (e.message ?? JSON.stringify(e)));
442
+ setConfigError(hostingError + "\n" + (e instanceof Error ? e.message : JSON.stringify(e)));
446
443
  }
447
444
  }, [name]);
448
445
  useEffect(() => {
@@ -511,7 +508,7 @@ function useAppCheck({
511
508
  }
512
509
  } catch (e) {
513
510
  console.error("App Check error:", e);
514
- setError(e.message);
511
+ setError(e instanceof Error ? e.message : String(e));
515
512
  }
516
513
  }, [options?.forceRefresh]);
517
514
  useEffect(() => {
@@ -867,7 +864,7 @@ function buildRebaseSearchController(options) {
867
864
  }
868
865
  } catch (error) {
869
866
  console.error("Failed to get search config from extension:", error);
870
- throw new Error(`Failed to initialize Rebase Search. Make sure the rebase-search extension is installed and configured. Error: ${error.message || error}`);
867
+ throw new Error(`Failed to initialize Rebase Search. Make sure the rebase-search extension is installed and configured. Error: ${error instanceof Error ? error.message : String(error)}`);
871
868
  }
872
869
  }
873
870
  if (!searchConfig) {
@@ -948,7 +945,7 @@ function buildRebaseSearchController(options) {
948
945
  schemaCache.set(collectionName, stringFields);
949
946
  return stringFields;
950
947
  } catch (error) {
951
- if (error.httpStatus === 404) {
948
+ if (error instanceof Error && "httpStatus" in error && error.httpStatus === 404) {
952
949
  throw new Error(`Collection "${collectionName}" not found in Typesense. Make sure the collection has been indexed. Try running the backfill function.`);
953
950
  }
954
951
  throw error;
@@ -988,7 +985,7 @@ function buildRebaseSearchController(options) {
988
985
  const ids = result.hits?.map((hit) => hit.document.id) ?? [];
989
986
  return ids;
990
987
  } catch (error) {
991
- const message = error.message || error.toString();
988
+ const message = error instanceof Error ? error.message : String(error);
992
989
  throw new Error(`Search failed: ${message}`);
993
990
  }
994
991
  };
@@ -1413,13 +1410,13 @@ const createEntityFromDocument = (docSnap, databaseId) => {
1413
1410
  };
1414
1411
  function firestoreToCMSModel(data) {
1415
1412
  if (data === null || data === void 0) return null;
1416
- if (deleteField().isEqual(data)) {
1413
+ if (typeof data === "object" && data !== null && "isEqual" in data && typeof data.isEqual === "function" && deleteField().isEqual(data)) {
1417
1414
  return void 0;
1418
1415
  }
1419
- if (serverTimestamp().isEqual(data)) {
1416
+ if (typeof data === "object" && data !== null && "isEqual" in data && typeof data.isEqual === "function" && serverTimestamp().isEqual(data)) {
1420
1417
  return null;
1421
1418
  }
1422
- if (data instanceof Timestamp || typeof data.toDate === "function" && data.toDate() instanceof Date) {
1419
+ if (data instanceof Timestamp || typeof data === "object" && data !== null && "toDate" in data && typeof data.toDate === "function" && data.toDate() instanceof Date) {
1423
1420
  return data.toDate();
1424
1421
  }
1425
1422
  if (data instanceof Date) {
@@ -1428,7 +1425,7 @@ function firestoreToCMSModel(data) {
1428
1425
  if (typeof data === "object" && "__type__" in data && data.__type__ === "__vector__") {
1429
1426
  return data;
1430
1427
  }
1431
- if (data instanceof VectorValue || typeof data === "object" && data !== null && typeof data.toArray === "function" && data.constructor?.name === "VectorValue") {
1428
+ if (data instanceof VectorValue || typeof data === "object" && data !== null && "toArray" in data && typeof data.toArray === "function" && data.constructor?.name === "VectorValue") {
1432
1429
  return {
1433
1430
  __type__: "__vector__",
1434
1431
  value: data.toArray()
@@ -1470,11 +1467,13 @@ function cmsToFirestoreModel(data, firestore, inArray = false) {
1470
1467
  return null;
1471
1468
  } else if (Array.isArray(data)) {
1472
1469
  return data.filter((v) => v !== void 0).map((v) => cmsToFirestoreModel(v, firestore, true));
1473
- } else if (data.isEntityReference && data.isEntityReference()) {
1474
- const targetFirestore = data.databaseId ? getFirestore(firestore.app, data.databaseId) : firestore;
1475
- return doc(targetFirestore, data.path, data.id);
1476
- } else if (data && typeof data === "object" && data.__type === "relation" && data.path && data.id) {
1477
- return doc(firestore, data.path, String(data.id));
1470
+ } else if (typeof data === "object" && data !== null && "isEntityReference" in data && typeof data.isEntityReference === "function" && data.isEntityReference()) {
1471
+ const entityRef = data;
1472
+ const targetFirestore = entityRef.databaseId ? getFirestore(firestore.app, entityRef.databaseId) : firestore;
1473
+ return doc(targetFirestore, entityRef.path, entityRef.id);
1474
+ } else if (data && typeof data === "object" && "__type" in data && data.__type === "relation" && "path" in data && "id" in data) {
1475
+ const rel = data;
1476
+ return doc(firestore, rel.path, String(rel.id));
1478
1477
  } else if (data instanceof GeoPoint) {
1479
1478
  return new GeoPoint$1(data.latitude, data.longitude);
1480
1479
  } else if (data instanceof Date) {
@@ -1805,8 +1804,9 @@ function cmsToRTDBModel(data, database) {
1805
1804
  return null;
1806
1805
  } else if (Array.isArray(data)) {
1807
1806
  return data.filter((v) => v !== void 0).map((v) => cmsToRTDBModel(v, database));
1808
- } else if (data.isEntityReference && data.isEntityReference()) {
1809
- return ref$1(database, `${data.slug}/${data.id}`);
1807
+ } else if (typeof data === "object" && data !== null && "isEntityReference" in data && typeof data.isEntityReference === "function" && data.isEntityReference()) {
1808
+ const entityRef = data;
1809
+ return ref$1(database, `${entityRef.slug}/${entityRef.id}`);
1810
1810
  } else if (data instanceof Date) {
1811
1811
  return data.toISOString();
1812
1812
  } else if (data && typeof data === "object") {
@@ -1851,8 +1851,7 @@ function useBuildUserManagement({
1851
1851
  roles: rolesProp,
1852
1852
  usersPath = "__FIRECMS/config/users",
1853
1853
  rolesPath = "__FIRECMS/config/roles",
1854
- allowDefaultRolesCreation,
1855
- includeCollectionConfigPermissions
1854
+ allowDefaultRolesCreation
1856
1855
  }) {
1857
1856
  if (!authController) {
1858
1857
  throw Error("useBuildUserManagement: You need to provide an authController since version 3.0.0-beta.11. Check https://firecms.co/docs/pro/migrating_from_v3_beta");
@@ -1896,7 +1895,7 @@ function useBuildUserManagement({
1896
1895
  onError(e_0) {
1897
1896
  setRoles([]);
1898
1897
  console.error("Error loading roles", e_0);
1899
- setRolesError(e_0);
1898
+ setRolesError(e_0 instanceof Error ? e_0 : new Error(String(e_0)));
1900
1899
  setRolesLoading(false);
1901
1900
  }
1902
1901
  });
@@ -1928,7 +1927,7 @@ function useBuildUserManagement({
1928
1927
  onError(e_2) {
1929
1928
  console.error("Error loading users", e_2);
1930
1929
  setUsersWithRoleIds([]);
1931
- setUsersError(e_2);
1930
+ setUsersError(e_2 instanceof Error ? e_2 : new Error(String(e_2)));
1932
1931
  setUsersLoading(false);
1933
1932
  }
1934
1933
  });
@@ -2022,9 +2021,9 @@ function useBuildUserManagement({
2022
2021
  if (!usersWithRoleIds) throw Error("Users not loaded");
2023
2022
  const mgmtUser = usersWithRoleIds.find((u_1) => u_1.email?.toLowerCase() === user_1?.email?.toLowerCase());
2024
2023
  if (!mgmtUser || !mgmtUser.roles) return void 0;
2025
- return roles.filter((r) => mgmtUser.roles.includes(r.id));
2026
- }, [roles, usersWithRoleIds]);
2027
- const authenticator = useCallback(({
2024
+ return mgmtUser.roles;
2025
+ }, [usersWithRoleIds]);
2026
+ const accessGate = useCallback(({
2028
2027
  user: user_2
2029
2028
  }) => {
2030
2029
  if (loading) {
@@ -2063,8 +2062,8 @@ function useBuildUserManagement({
2063
2062
  throw Error("Could not find a user with the provided email in the user management system.");
2064
2063
  }, [loading, users]);
2065
2064
  const userRoles = authController.user ? defineRolesFor(authController.user) : void 0;
2066
- const isAdmin = (userRoles ?? []).some((r_0) => r_0.id === "admin");
2067
- const userRoleIds = userRoles?.map((r_1) => r_1.id);
2065
+ const isAdmin = (userRoles ?? []).some((r) => r === "admin");
2066
+ const userRoleIds = userRoles;
2068
2067
  useEffect(() => {
2069
2068
  console.debug("Setting user roles", {
2070
2069
  userRoles,
@@ -2089,9 +2088,8 @@ function useBuildUserManagement({
2089
2088
  usersError,
2090
2089
  isAdmin,
2091
2090
  allowDefaultRolesCreation: allowDefaultRolesCreation === void 0 ? true : allowDefaultRolesCreation,
2092
- includeCollectionConfigPermissions: Boolean(includeCollectionConfigPermissions),
2093
2091
  defineRolesFor,
2094
- authenticator,
2092
+ accessGate,
2095
2093
  ...authController,
2096
2094
  initialLoading: authController.initialLoading || loading,
2097
2095
  userRoles,
@@ -2107,8 +2105,8 @@ const entitiesToUsers = (docs) => {
2107
2105
  const data = doc2.values;
2108
2106
  const record = data;
2109
2107
  const newVar = {
2110
- uid: doc2.id,
2111
2108
  ...data,
2109
+ uid: doc2.id,
2112
2110
  created_on: record.created_on,
2113
2111
  updated_on: record.updated_on
2114
2112
  };
@@ -2121,6 +2119,128 @@ const entityToRoles = (entities) => {
2121
2119
  ...doc2.values
2122
2120
  }));
2123
2121
  };
2122
+ function useFirebaseAccessGate(t0) {
2123
+ const $ = c(17);
2124
+ const {
2125
+ disabled,
2126
+ authController,
2127
+ accessGate,
2128
+ storageSource,
2129
+ data
2130
+ } = t0;
2131
+ const gateEnabled = Boolean(accessGate);
2132
+ const [authLoading, setAuthLoading] = useState(gateEnabled);
2133
+ const [notAllowedError, setNotAllowedError] = useState(false);
2134
+ const [authVerified, setAuthVerified] = useState(!gateEnabled || Boolean(authController.loginSkipped));
2135
+ const canAccessMainView = authVerified && (!gateEnabled || Boolean(authController.user) || Boolean(authController.loginSkipped)) && !notAllowedError;
2136
+ let t1;
2137
+ let t2;
2138
+ if ($[0] !== authController.loginSkipped) {
2139
+ t1 = () => {
2140
+ if (authController.loginSkipped) {
2141
+ setAuthVerified(true);
2142
+ }
2143
+ };
2144
+ t2 = [authController.loginSkipped];
2145
+ $[0] = authController.loginSkipped;
2146
+ $[1] = t1;
2147
+ $[2] = t2;
2148
+ } else {
2149
+ t1 = $[1];
2150
+ t2 = $[2];
2151
+ }
2152
+ useEffect(t1, t2);
2153
+ const checkedUserRef = useRef(void 0);
2154
+ let t3;
2155
+ if ($[3] !== accessGate || $[4] !== authController || $[5] !== data || $[6] !== disabled || $[7] !== storageSource) {
2156
+ t3 = async () => {
2157
+ if (disabled) {
2158
+ return;
2159
+ }
2160
+ if (authController.initialLoading) {
2161
+ return;
2162
+ }
2163
+ if (!authController.user && !authController.loginSkipped) {
2164
+ checkedUserRef.current = void 0;
2165
+ setAuthLoading(false);
2166
+ setAuthVerified(false);
2167
+ return;
2168
+ }
2169
+ const delegateUser = authController.user;
2170
+ if (accessGate instanceof Function && delegateUser && !deepEqual(checkedUserRef.current?.uid, delegateUser.uid)) {
2171
+ setAuthLoading(true);
2172
+ try {
2173
+ const allowed = await accessGate({
2174
+ user: delegateUser,
2175
+ authController,
2176
+ data,
2177
+ storageSource
2178
+ });
2179
+ if (!allowed) {
2180
+ authController.signOut();
2181
+ setNotAllowedError(true);
2182
+ }
2183
+ } catch (t42) {
2184
+ const e = t42;
2185
+ setNotAllowedError(e);
2186
+ authController.signOut();
2187
+ }
2188
+ setAuthLoading(false);
2189
+ setAuthVerified(true);
2190
+ checkedUserRef.current = delegateUser;
2191
+ } else {
2192
+ setAuthLoading(false);
2193
+ }
2194
+ if (!authController.initialLoading && !delegateUser) {
2195
+ setAuthVerified(true);
2196
+ }
2197
+ };
2198
+ $[3] = accessGate;
2199
+ $[4] = authController;
2200
+ $[5] = data;
2201
+ $[6] = disabled;
2202
+ $[7] = storageSource;
2203
+ $[8] = t3;
2204
+ } else {
2205
+ t3 = $[8];
2206
+ }
2207
+ const checkAccess = t3;
2208
+ let t4;
2209
+ let t5;
2210
+ if ($[9] !== checkAccess) {
2211
+ t4 = () => {
2212
+ checkAccess();
2213
+ };
2214
+ t5 = [checkAccess];
2215
+ $[9] = checkAccess;
2216
+ $[10] = t4;
2217
+ $[11] = t5;
2218
+ } else {
2219
+ t4 = $[10];
2220
+ t5 = $[11];
2221
+ }
2222
+ useEffect(t4, t5);
2223
+ let t6;
2224
+ const t7 = gateEnabled && authLoading;
2225
+ let t8;
2226
+ if ($[12] !== authVerified || $[13] !== canAccessMainView || $[14] !== notAllowedError || $[15] !== t7) {
2227
+ t8 = {
2228
+ canAccessMainView,
2229
+ authLoading: t7,
2230
+ notAllowedError,
2231
+ authVerified
2232
+ };
2233
+ $[12] = authVerified;
2234
+ $[13] = canAccessMainView;
2235
+ $[14] = notAllowedError;
2236
+ $[15] = t7;
2237
+ $[16] = t8;
2238
+ } else {
2239
+ t8 = $[16];
2240
+ }
2241
+ t6 = t8;
2242
+ return t6;
2243
+ }
2124
2244
  const googleIcon = (mode) => /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 64 64", width: 24, height: 24, children: [
2125
2245
  /* @__PURE__ */ jsxs("linearGradient", { id: "95yY7w43Oj6n2vH63j6HJb", x1: "29.401", x2: "29.401", y1: "4.064", y2: "106.734", gradientTransform: "matrix(1 0 0 -1 0 66)", gradientUnits: "userSpaceOnUse", children: [
2126
2246
  /* @__PURE__ */ jsx("stop", { offset: "0", stopColor: "#ff5840" }),
@@ -2252,7 +2372,7 @@ function FirebaseLoginView({
2252
2372
  } else if (notAllowedError instanceof Error) {
2253
2373
  notAllowedMessage = notAllowedError.message;
2254
2374
  } else {
2255
- notAllowedMessage = "It looks like you don't have access to the CMS, based on the specified Authenticator configuration";
2375
+ notAllowedMessage = "It looks like you don't have access to the CMS, based on the specified access gate configuration";
2256
2376
  }
2257
2377
  }
2258
2378
  const fadeStyle = {
@@ -2639,7 +2759,7 @@ function RebaseFirebaseApp(t0) {
2639
2759
  name,
2640
2760
  logo,
2641
2761
  logoDark,
2642
- authenticator,
2762
+ accessGate,
2643
2763
  collections,
2644
2764
  views,
2645
2765
  adminViews,
@@ -2767,15 +2887,15 @@ function RebaseFirebaseApp(t0) {
2767
2887
  t10 = $[21];
2768
2888
  }
2769
2889
  let t11;
2770
- if ($[22] !== authController || $[23] !== authenticator || $[24] !== storageSource || $[25] !== t10) {
2890
+ if ($[22] !== accessGate || $[23] !== authController || $[24] !== storageSource || $[25] !== t10) {
2771
2891
  t11 = {
2772
2892
  authController,
2773
- authenticator,
2893
+ accessGate,
2774
2894
  data: t10,
2775
2895
  storageSource
2776
2896
  };
2777
- $[22] = authController;
2778
- $[23] = authenticator;
2897
+ $[22] = accessGate;
2898
+ $[23] = authController;
2779
2899
  $[24] = storageSource;
2780
2900
  $[25] = t10;
2781
2901
  $[26] = t11;
@@ -2786,7 +2906,7 @@ function RebaseFirebaseApp(t0) {
2786
2906
  authLoading,
2787
2907
  canAccessMainView,
2788
2908
  notAllowedError
2789
- } = useValidateAuthenticator(t11);
2909
+ } = useFirebaseAccessGate(t11);
2790
2910
  let t12;
2791
2911
  if ($[27] !== userConfigPersistence) {
2792
2912
  t12 = {
@@ -2914,7 +3034,7 @@ function RebaseFirebaseApp(t0) {
2914
3034
  const usedLogo = modeController.mode === "dark" && logoDark ? logoDark : logo;
2915
3035
  if (!canAccessMainView) {
2916
3036
  const LoginViewUsed = components?.LoginView ?? FirebaseLoginView;
2917
- component = /* @__PURE__ */ jsx(LoginViewUsed, { logo: usedLogo, allowSkipLogin, signInOptions: signInOptions ?? DEFAULT_SIGN_IN_OPTIONS, firebaseApp, authController, notAllowedError });
3037
+ component = /* @__PURE__ */ jsx(LoginViewUsed, { logo: usedLogo, allowSkipLogin, signInOptions: signInOptions ?? DEFAULT_SIGN_IN_OPTIONS, firebaseApp, authController, notAllowedError: notAllowedError instanceof Error ? notAllowedError : typeof notAllowedError === "string" ? notAllowedError : void 0 });
2918
3038
  } else {
2919
3039
  const firstCollectionEntry = navigationStateController.topLevelNavigation?.navigationEntries.find(_temp3);
2920
3040
  const fallbackRoute = firstCollectionEntry ? /* @__PURE__ */ jsx(Navigate, { to: urlController.buildUrlCollectionPath(firstCollectionEntry.id), replace: true }) : /* @__PURE__ */ jsx(CenteredView, { children: "No home page or collections provided." });
@@ -3049,6 +3169,7 @@ export {
3049
3169
  performPineconeTextSearch,
3050
3170
  useAppCheck,
3051
3171
  useBuildUserManagement,
3172
+ useFirebaseAccessGate,
3052
3173
  useFirebaseAuthController,
3053
3174
  useFirebaseRTDBDelegate,
3054
3175
  useFirebaseStorageSource,