@rebasepro/auth 0.2.4 → 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.
@@ -1,5 +1,5 @@
1
1
  import { useCallback, useEffect, useRef, useState } from "react";
2
- import { Role, User } from "@rebasepro/types";
2
+ import type { User } from "@rebasepro/types";
3
3
 
4
4
  /**
5
5
  * UserManagement interface - compatible with @rebasepro/user_management
@@ -23,13 +23,9 @@ export interface UserManagement<USER extends User = User> {
23
23
  }>;
24
24
  deleteUser: (user: USER) => Promise<void>;
25
25
 
26
- roles: Role[];
27
- saveRole: (role: Role) => Promise<void>;
28
- deleteRole: (role: Role) => Promise<void>;
29
-
30
26
  isAdmin?: boolean;
31
27
  allowDefaultRolesCreation?: boolean;
32
- defineRolesFor: (user: User) => Promise<Role[] | undefined> | Role[] | undefined;
28
+ defineRolesFor: (user: User) => Promise<string[] | undefined> | string[] | undefined;
33
29
  getUser: (uid: string) => User | null;
34
30
 
35
31
  /**
@@ -47,7 +43,6 @@ export interface UserManagement<USER extends User = User> {
47
43
  }) => Promise<{ users: USER[]; total: number }>;
48
44
 
49
45
  usersError?: Error;
50
- rolesError?: Error;
51
46
  bootstrapAdmin?: () => Promise<void>;
52
47
  }
53
48
 
@@ -83,17 +78,9 @@ interface ApiUser {
83
78
  updatedAt?: string;
84
79
  }
85
80
 
86
- interface ApiRole {
87
- id: string;
88
- name: string;
89
- isAdmin?: boolean;
90
- }
91
-
92
81
  /** Response shapes from the admin API */
93
- interface ApiRolesResponse { roles: ApiRole[] }
94
82
  interface ApiUsersResponse { users: ApiUser[]; total: number }
95
83
  interface ApiUserResponse { user: ApiUser; invitationSent?: boolean; temporaryPassword?: string }
96
- interface ApiRoleResponse { role: ApiRole }
97
84
 
98
85
  /**
99
86
  * Convert API user to Rebase User
@@ -112,17 +99,6 @@ function convertUser(apiUser: ApiUser): User {
112
99
  } as User;
113
100
  }
114
101
 
115
- /**
116
- * Convert API role to Rebase Role
117
- */
118
- function convertRole(apiRole: ApiRole): Role {
119
- return {
120
- id: apiRole.id,
121
- name: apiRole.name,
122
- isAdmin: apiRole.isAdmin ?? false
123
- };
124
- }
125
-
126
102
  /**
127
103
  * Hook to manage users and roles via backend API
128
104
  * Compatible with Rebase UserManagement interface
@@ -134,7 +110,6 @@ export function useBackendUserManagement(config: BackendUserManagementConfig): U
134
110
  // individual API lookups. We never load ALL users into memory.
135
111
  const [userCache, setUserCache] = useState<Map<string, User>>(new Map());
136
112
  const [hasAdminUsers, setHasAdminUsers] = useState(false);
137
- const [roles, setRoles] = useState<Role[]>([]);
138
113
  const userRoles = currentUser?.roles ?? [];
139
114
  const isUserAdmin = userRoles.some(r => r === "admin" || r === "schema-admin");
140
115
 
@@ -144,7 +119,6 @@ export function useBackendUserManagement(config: BackendUserManagementConfig): U
144
119
  return true;
145
120
  });
146
121
  const [usersError, setUsersError] = useState<Error | undefined>();
147
- const [rolesError, setRolesError] = useState<Error | undefined>();
148
122
 
149
123
  // Tracks the UID for which roles+users were last successfully loaded.
150
124
  // Prevents redundant refetches on React StrictMode double-mounts.
@@ -261,20 +235,7 @@ export function useBackendUserManagement(config: BackendUserManagementConfig): U
261
235
  // Keep the ref in sync after every render.
262
236
  apiRequestRef.current = apiRequest;
263
237
 
264
- /**
265
- * Load roles from API
266
- */
267
- const loadRoles = useCallback(async (signal?: AbortSignal) => {
268
- try {
269
- const data = await apiRequest<ApiRolesResponse>("/roles", "GET", undefined, 6, signal);
270
- setRoles(data.roles.map(convertRole));
271
- setRolesError(undefined);
272
- } catch (error: unknown) {
273
- if (error instanceof Error && error.name === "AbortError") return;
274
- console.error("Failed to load roles:", error);
275
- setRolesError(error instanceof Error ? error : new Error(String(error)));
276
- }
277
- }, [apiRequest]);
238
+
278
239
 
279
240
  /**
280
241
  * Lightweight admin-existence check: fetch a single admin user.
@@ -334,27 +295,6 @@ export function useBackendUserManagement(config: BackendUserManagementConfig): U
334
295
  setLoading(true);
335
296
  const request = apiRequestRef.current!;
336
297
 
337
- // Load roles first
338
- try {
339
- const data = await request<ApiRolesResponse>("/roles", "GET", undefined, 6, abortController.signal);
340
- setRoles(data.roles.map(convertRole));
341
- setRolesError(undefined);
342
- } catch (error: unknown) {
343
- if (error instanceof Error && error.name === "AbortError") return;
344
- console.error("Failed to load roles:", error);
345
- setRolesError(error instanceof Error ? error : new Error(String(error)));
346
-
347
- // If the error is a permission issue (e.g. 403), skip the
348
- // admin check — it will fail with the same error and we'd
349
- // show a duplicate snackbar / error message.
350
- const status = (error as { status?: number }).status;
351
- if (status === 403 || status === 401) {
352
- setUsersError(error instanceof Error ? error : new Error(String(error)));
353
- setLoading(false);
354
- return;
355
- }
356
- }
357
-
358
298
  // Lightweight admin-existence check (NOT loading all users)
359
299
  if (!abortController.signal.aborted) {
360
300
  try {
@@ -488,40 +428,7 @@ export function useBackendUserManagement(config: BackendUserManagementConfig): U
488
428
  });
489
429
  }, [apiRequest]);
490
430
 
491
- /**
492
- * Save role (create or update)
493
- */
494
- const saveRole = useCallback(async (role: Role): Promise<void> => {
495
- // Check if role exists
496
- const existingRole = roles.find(r => r.id === role.id);
497
-
498
- if (existingRole) {
499
- // Update
500
- const data = await apiRequest<ApiRoleResponse>(`/roles/${role.id}`, "PUT", {
501
- name: role.name,
502
- isAdmin: role.isAdmin
503
- });
504
- const updated = convertRole(data.role);
505
- setRoles(prev => prev.map(r => r.id === updated.id ? updated : r));
506
- } else {
507
- // Create
508
- const data = await apiRequest<ApiRoleResponse>("/roles", "POST", {
509
- id: role.id,
510
- name: role.name,
511
- isAdmin: role.isAdmin ?? false
512
- });
513
- const created = convertRole(data.role);
514
- setRoles(prev => [...prev, created]);
515
- }
516
- }, [apiRequest, roles]);
517
431
 
518
- /**
519
- * Delete role
520
- */
521
- const deleteRole = useCallback(async (role: Role): Promise<void> => {
522
- await apiRequest(`/roles/${role.id}`, "DELETE");
523
- setRoles(prev => prev.filter(r => r.id !== role.id));
524
- }, [apiRequest]);
525
432
 
526
433
  /**
527
434
  * Get user by uid
@@ -533,7 +440,7 @@ export function useBackendUserManagement(config: BackendUserManagementConfig): U
533
440
  /**
534
441
  * Define roles for a given user (for authController)
535
442
  */
536
- const defineRolesFor = useCallback(async (user: User): Promise<Role[] | undefined> => {
443
+ const defineRolesFor = useCallback(async (user: User): Promise<string[] | undefined> => {
537
444
  // Check cache first
538
445
  let existingUser = userCache.get(user.uid)
539
446
  ?? Array.from(userCache.values()).find(u => u.email === user.email);
@@ -549,10 +456,10 @@ export function useBackendUserManagement(config: BackendUserManagementConfig): U
549
456
  }
550
457
  }
551
458
 
552
- // Return roles from our cached role data (string IDs full Role objects)
459
+ // Return role IDs as simple strings
553
460
  const userRoleIds = existingUser.roles ?? [];
554
- return roles.filter(r => userRoleIds.includes(r.id));
555
- }, [userCache, roles, apiRequest, mergeIntoCache]);
461
+ return userRoleIds;
462
+ }, [userCache, apiRequest, mergeIntoCache]);
556
463
 
557
464
  /**
558
465
  * Check if current user is admin
@@ -566,10 +473,7 @@ export function useBackendUserManagement(config: BackendUserManagementConfig): U
566
473
  const bootstrapAdmin = useCallback(async (): Promise<void> => {
567
474
  try {
568
475
  await apiRequest("/bootstrap", "POST");
569
- // Reload roles and re-check admin existence after successful bootstrap
570
- const data = await apiRequest<ApiRolesResponse>("/roles");
571
- const loadedRoles = data.roles.map(convertRole);
572
- setRoles(loadedRoles);
476
+ // Re-check admin existence after successful bootstrap
573
477
  await checkAdminExists();
574
478
  } catch (error) {
575
479
  console.error("Failed to bootstrap admin:", error);
@@ -589,16 +493,12 @@ export function useBackendUserManagement(config: BackendUserManagementConfig): U
589
493
  createUser,
590
494
  resetPassword,
591
495
  deleteUser,
592
- roles,
593
- saveRole,
594
- deleteRole,
595
496
  isAdmin,
596
497
  allowDefaultRolesCreation: isAdmin,
597
498
  defineRolesFor,
598
499
  getUser,
599
500
  searchUsers,
600
501
  usersError,
601
- rolesError,
602
502
  bootstrapAdmin
603
503
  };
604
504
  }
@@ -313,7 +313,7 @@ export function useRebaseAuthController(
313
313
  if (defineRolesFor) {
314
314
  const customRoles = await defineRolesFor(convertedUser);
315
315
  if (customRoles) {
316
- convertedUser = { ...convertedUser, roles: customRoles.map(r => r.id) };
316
+ convertedUser = { ...convertedUser, roles: customRoles };
317
317
  }
318
318
  }
319
319
 
@@ -479,7 +479,7 @@ export function useRebaseAuthController(
479
479
  const customRoles = await defineRolesFor(convertedUser);
480
480
  if (customRoles) {
481
481
  convertedUser = { ...convertedUser,
482
- roles: customRoles.map(r => r.id) };
482
+ roles: customRoles };
483
483
  }
484
484
  }
485
485
 
@@ -575,7 +575,7 @@ roles: customRoles.map(r => r.id) };
575
575
  const customRoles = await defineRolesFor(userToSet);
576
576
  if (customRoles) {
577
577
  userToSet = { ...userToSet,
578
- roles: customRoles.map(r => r.id) };
578
+ roles: customRoles };
579
579
  }
580
580
  }
581
581
 
@@ -619,7 +619,7 @@ roles: customRoles.map(r => r.id) };
619
619
  if (!isMountedRef.current) return;
620
620
  if (customRoles) {
621
621
  userToSet = { ...userToSet,
622
- roles: customRoles.map(r => r.id) };
622
+ roles: customRoles };
623
623
  }
624
624
  }
625
625
  } catch (meError: unknown) {
package/src/types.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { AuthController, Role, User } from "@rebasepro/types";
1
+ import { AuthController, User } from "@rebasepro/types";
2
2
 
3
3
  /**
4
4
  * Auth controller that extends the base AuthController
@@ -64,7 +64,7 @@ export interface RebaseAuthControllerProps {
64
64
  /** Callback when user signs out */
65
65
  onSignOut?: () => void;
66
66
  /** Define roles for a user after login */
67
- defineRolesFor?: (user: User) => Promise<Role[] | undefined> | Role[] | undefined;
67
+ defineRolesFor?: (user: User) => Promise<string[] | undefined> | string[] | undefined;
68
68
  }
69
69
 
70
70
  /**