rbac-shield 0.2.0 → 0.2.2

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.
package/README.md CHANGED
@@ -5,11 +5,12 @@
5
5
  [![Status](https://img.shields.io/badge/Status-Beta-orange.svg)]()
6
6
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue.svg)](https://www.typescriptlang.org/)
7
7
 
8
- > [!WARNING] > **Public Beta**: ensuring strict type safety and performance. API is stable but minor breaking changes might occur before v1.0.
8
+ > [!WARNING]
9
+ > **Public Beta**: Ensuring strict type safety and performance. API is stable but minor breaking changes might occur before v1.0.
9
10
 
10
11
  **The production-ready, type-safe Role-Based Access Control (RBAC) system for Next.js applications.**
11
12
 
12
- Built for modern web development with **React 19**, **TypeScript 5**, and **Next.js App Router** compatibility. RBAC Shield provides a seamless, multi-tenant permission system that just works.
13
+ Built for modern web development with **React 19**, **TypeScript 5**, and **Next.js App Router** compatibility. RBAC Shield provides a seamless, multi-tenant permission system that supports both **Role-based** and **Permission-based** strategies.
13
14
 
14
15
  ---
15
16
 
@@ -19,10 +20,10 @@ Built for modern web development with **React 19**, **TypeScript 5**, and **Next
19
20
  - [Quick Setup (CLI)](#-quick-setup-recommended)
20
21
  - [Manual Installation](#-manual-installation)
21
22
  - [Quick Start](#-quick-start)
23
+ - [Role Management (New)](#-role-management)
22
24
  - [Guides & Patterns](#-guides--patterns)
23
- - [Roles as Permissions](#roles-as-permissions)
25
+ - [Roles vs Permissions](#roles-vs-permissions)
24
26
  - [Complex Logic (AND/OR)](#complex-logic-andor)
25
- - [Customizing UX](#customizing-ux-loading--redirects)
26
27
  - [SSR & Hydration](#ssr--hydration-eliminate-loading-states)
27
28
  - [Logic Switching (Dynamic APIs)](#logic-switching-dynamic-apis)
28
29
  - [Server Action Guards](#server-action-guards)
@@ -35,6 +36,7 @@ Built for modern web development with **React 19**, **TypeScript 5**, and **Next
35
36
  ## ✨ Features
36
37
 
37
38
  - 🎯 **Type-Safe Permissions**: Typescript "Prettify" helpers ensure tooltips show exact prop shapes, amazing IntelliSense.
39
+ - 👑 **First-Class Role Support**: Check for Roles (`admin`), Permissions (`edit:post`), or both simultaneously.
38
40
  - 🚀 **High Performance**: Optimized with React Context and memoization. Permission checks are < 1ms.
39
41
  - 🏢 **Multi-Tenant Native**: Switch between multiple organizations/roles instantly without page reloads.
40
42
  - ⚡ **Zero Loading States**: Support for `initialData` prop allows instant hydration from server-side data.
@@ -100,7 +102,8 @@ export type Actions = "view" | "create" | "edit" | "delete" | "export";
100
102
  // 3. Create your instances
101
103
  export const {
102
104
  RBACProvider,
103
- useRBAC, // Renamed from useRBAC (alias available)
105
+ useRBAC,
106
+ useHasRole, // New!
104
107
  useHasPermission,
105
108
  useMatch,
106
109
  Can,
@@ -111,7 +114,7 @@ export const {
111
114
 
112
115
  ### 2. Wrap Your App
113
116
 
114
- Add the provider to your root layout to enable state management.
117
+ Add the provider to your root layout.
115
118
 
116
119
  ```tsx
117
120
  // app/layout.tsx
@@ -134,36 +137,30 @@ export default function RootLayout({
134
137
 
135
138
  ### 3. Load Permissions
136
139
 
137
- Initialize the system with data from your backend (e.g., after login).
140
+ Initialize the system with data from your backend. You can now pass just permissions (strings) or roles and permissions.
138
141
 
139
142
  ```tsx
140
143
  // components/AuthProvider.tsx
141
144
  "use client";
142
145
  import { useEffect } from "react";
143
- import { useRBAC, useMatch } from "@/lib/rbac"; // Use the hook directly
146
+ import { useRBAC } from "@/lib/rbac";
144
147
 
145
- export function AuthProvider({
146
- user,
147
- children,
148
- }: {
149
- user: any;
150
- children: React.ReactNode;
151
- }) {
152
- const { setAuth, switchTenant } = useRBAC();
148
+ export function AuthProvider({ user, children }) {
149
+ const { setAuth } = useRBAC();
153
150
 
154
151
  useEffect(() => {
155
152
  if (user) {
156
- // Load permissions into RBAC Shield
157
- setAuth([
158
- {
159
- tenantId: "team-123",
160
- permissions: ["projects:view", "projects:edit"],
161
- },
162
- ]);
163
- // Activate the context
164
- switchTenant("team-123");
153
+ // Option A: Simple Permissions (Auto-assigned to 'default' tenant)
154
+ setAuth(["projects:view"]);
155
+
156
+ // Option B: Roles + Permissions
157
+ // setAuth([{
158
+ // tenantId: "default",
159
+ // roles: ["admin"],
160
+ // permissions: ["projects:view"]
161
+ // }]);
165
162
  }
166
- }, [user, setAuth, switchTenant]);
163
+ }, [user, setAuth]);
167
164
 
168
165
  return <>{children}</>;
169
166
  }
@@ -171,26 +168,28 @@ export function AuthProvider({
171
168
 
172
169
  ### 4. Secure Your App
173
170
 
174
- Use the generated hooks and components anywhere.
171
+ Use the components to guard access.
175
172
 
176
173
  ```tsx
177
- import { ProtectedRoute, Can, useHasPermission } from "@/lib/rbac";
174
+ import { ProtectedRoute, Can, useHasRole } from "@/lib/rbac";
178
175
 
179
- export default function ProjectSettings() {
180
- const canDelete = useHasPermission("projects:delete");
176
+ export default function AdminPanel() {
177
+ const isAdmin = useHasRole("admin");
181
178
 
182
179
  return (
183
- // 1. Protect Example: Redirects to / if missing permission
184
- <ProtectedRoute requiredPermission="projects:edit" fallbackPath="/">
185
- <h1>Project Settings</h1>
180
+ // 1. Role-Based Route Protection
181
+ <ProtectedRoute role="admin" fallbackPath="/login">
182
+ <h1>Admin Dashboard</h1>
186
183
 
187
- {/* 2. Conditional Render Example */}
188
- <Can permission="billing:view" fallback={<p>Upgrade to see billing</p>}>
184
+ {/* 2. Permission Check */}
185
+ <Can permission="billing:view">
189
186
  <BillingWidget />
190
187
  </Can>
191
188
 
192
- {/* 3. Hook Logic Example */}
193
- <button disabled={!canDelete}>Delete Project</button>
189
+ {/* 3. Combined Logic (Role AND Permission) */}
190
+ <Can role="manager" permission="users:delete">
191
+ <DeleteUserButton />
192
+ </Can>
194
193
  </ProtectedRoute>
195
194
  );
196
195
  }
@@ -198,28 +197,49 @@ export default function ProjectSettings() {
198
197
 
199
198
  ---
200
199
 
201
- ## 📖 Guides & Patterns
200
+ ## 👑 Role Management
202
201
 
203
- ### Roles as Permissions
202
+ RBAC Shield now supports **Dynamic Logic** for access control. You can check for Roles, Permissions, or Both.
204
203
 
205
- Avoid hardcoding role checks like `if (role === 'admin')`. Instead, treat roles as permissions!
206
- Assign a "identity permission" to your roles, e.g., `role:admin`, `role:manager`.
204
+ ### Logic Matrix
207
205
 
208
- ```tsx
209
- // Bad: Brittle
210
- if (user.role === 'admin') <AdminText />
206
+ | Props Provided | Logic Applied | Example |
207
+ | :------------------ | :--------------------------------------------------- | :------------------------------------- |
208
+ | **Role Only** | User has `role` | `<Can role="admin">` |
209
+ | **Permission Only** | User has `permission` | `<Can permission="edit">` |
210
+ | **Both** | **STRICT AND**: User has `role` **AND** `permission` | `<Can role="admin" permission="edit">` |
211
+ | **Neither** | Deny Access | `<Can />` (Renders nothing) |
212
+
213
+ ### Wildcards
214
+
215
+ - **Roles**: If the user has the role `*`, they pass ALL role checks.
216
+ - **Permissions**: If the user has permission `*`, they pass ALL permission checks.
211
217
 
212
- // Good: Flexible
213
- // User permissions: ['post:read', 'role:admin']
214
- <Can permission="role:admin" fallback="Welcome User">
215
- Welcome Admin
218
+ ### Array Inputs (OR Logic)
219
+
220
+ If you provide an array to `role` or `permission`, by default it checks if the user has **ANY** of them (OR logic).
221
+
222
+ ```tsx
223
+ // User is EITHER 'admin' OR 'manager'
224
+ <Can role={["admin", "manager"]}>
225
+ <ManagementPanel />
216
226
  </Can>
217
227
  ```
218
228
 
229
+ ---
230
+
231
+ ## 📖 Guides & Patterns
232
+
233
+ ### Roles vs Permissions
234
+
235
+ - **Roles**: Use for high-level identity or persona checks (e.g., "Is this an Admin?").
236
+ - **Permissions**: Use for granular capability checks (e.g., "Can they delete this post?").
237
+
238
+ **Best Practice**: Combine them! Use `<ProtectedRoute role="admin">` for the page layout, and `<Can permission="settings:edit">` for specific buttons.
239
+
219
240
  ### Complex Logic (AND/OR)
220
241
 
221
- Sometimes you need a user to have a specific permission **AND** a specific role.
222
- Use the array format with `requireAll`.
242
+ Use `requireAll` to enforce strict requirements on arrays.
223
243
 
224
244
  ```tsx
225
245
  // User must be 'admin' AND have 'post:delete' permission
@@ -228,27 +248,6 @@ Use the array format with `requireAll`.
228
248
  </Can>
229
249
  ```
230
250
 
231
- ### Customizing UX (Loading & Redirects)
232
-
233
- You have full control over the loading and fallback states. Pass `null` to hide them completely.
234
-
235
- ```tsx
236
- // 1. Silent Loading (No Spinner)
237
- <ProtectedRoute permission="admin:view" loadingComponent={null} >
238
- <Dashboard />
239
- </ProtectedRoute>
240
-
241
- // 2. Instant Redirect (No "Access Denied" screen)
242
- <ProtectedRoute permission="admin:view" fallback={null} fallbackPath="/login" >
243
- <Dashboard />
244
- </ProtectedRoute>
245
-
246
- // 3. No Redirect (Show Custom 403 Page)
247
- <ProtectedRoute permission="admin:view" redirect={false} fallback={<AccessDeniedPage />} >
248
- <Dashboard />
249
- </ProtectedRoute>
250
- ```
251
-
252
251
  ### SSR & Hydration (Eliminate Loading States)
253
252
 
254
253
  Prevent the "flicker" of loading states by passing server-side permissions directly to the provider.
@@ -256,24 +255,18 @@ Prevent the "flicker" of loading states by passing server-side permissions direc
256
255
  ```tsx
257
256
  // app/layout.tsx (Server Component)
258
257
  import { RBACProvider } from "@/lib/rbac";
259
- import { getSession } from "@/lib/auth"; // Your auth logic
258
+ import { getSession } from "@/lib/auth";
260
259
 
261
260
  export default async function RootLayout({ children }) {
262
261
  const session = await getSession();
263
262
 
264
- // Prepare valid initial data matches TenantAuthInput[]
265
- const initialData = session
266
- ? [
267
- {
268
- tenantId: session.orgId,
269
- permissions: session.permissions, // string[] from DB is fine!
270
- },
271
- ]
272
- : [];
263
+ // server-side: just pass the string array of permissions!
264
+ const initialData = session?.permissions || [];
273
265
 
274
266
  return (
275
267
  <html>
276
268
  <body>
269
+ {/* Hydrates instantly! */}
277
270
  <RBACProvider initialData={initialData}>{children}</RBACProvider>
278
271
  </body>
279
272
  </html>
@@ -283,51 +276,19 @@ export default async function RootLayout({ children }) {
283
276
 
284
277
  ### Logic Switching (Dynamic APIs)
285
278
 
286
- Need to call different APIs or execute different logic based on permissions? You have two options:
287
-
288
- #### Option 1: Top-Level Hook (Recommended)
289
-
290
- Use this when you want to resolve the handler _during render_ but call it later (e.g., on click).
279
+ Use `useMatch` to execute different logic based on permissions or roles.
291
280
 
292
281
  ```tsx
293
- import { useRBAC, useMatch } from "@/lib/rbac";
282
+ import { useMatch } from "@/lib/rbac";
294
283
 
295
284
  export default function Dashboard() {
296
- // 1. Resolve the handler at the top level
297
- // Note: We return a FUNCTION () => ... so it doesn't run immediately!
298
285
  const getData = useMatch({
299
- "admin:view": () => () => api.getAdminStats(),
300
- "manager:view": () => () => api.getManagerStats(),
301
- default: () => () => api.getUserStats(),
286
+ "admin:view": () => api.getAdminStats(),
287
+ "manager:view": () => api.getManagerStats(),
288
+ default: () => api.getUserStats(),
302
289
  });
303
290
 
304
- const handleRefresh = () => {
305
- // 2. Call the resolved function
306
- if (getData) getData();
307
- };
308
-
309
- return <button onClick={handleRefresh}>Refresh Data</button>;
310
- }
311
- ```
312
-
313
- #### Option 2: Event Handler Utility
314
-
315
- Use the `match` utility (not the hook) if you want to keep all logic inside the event handler.
316
-
317
- ```tsx
318
- import { usePermissions, match } from "@/lib/rbac";
319
-
320
- export default function Dashboard() {
321
- const permissions = usePermissions(); // Hooks must be top-level
322
-
323
- const handleRefresh = () => {
324
- // 'match' is a plain function, safe to use here!
325
- match(permissions, {
326
- "admin:view": () => api.getAdminStats(),
327
- "manager:view": () => api.getManagerStats(),
328
- default: () => api.getUserStats(),
329
- });
330
- };
291
+ return <button onClick={getData}>Refresh Data</button>;
331
292
  }
332
293
  ```
333
294
 
@@ -343,17 +304,16 @@ import { getSession } from "@/lib/auth";
343
304
  export async function deleteProject(id: string) {
344
305
  const session = await getSession();
345
306
 
346
- // Wrap your delicate logic
347
307
  const safeAction = guard(
348
308
  session.permissions, // User's permissions
349
309
  "project:delete", // Required permission
350
310
  async () => {
351
311
  await db.project.delete(id);
352
312
  return "Deleted!";
353
- }
313
+ },
354
314
  );
355
315
 
356
- return safeAction(); // Throws Error if unauthorized
316
+ return safeAction();
357
317
  }
358
318
  ```
359
319
 
@@ -363,119 +323,56 @@ export async function deleteProject(id: string) {
363
323
 
364
324
  ### Components
365
325
 
366
- #### `<RBACProvider>`
367
-
368
- Top-level provider component.
369
-
370
- - **initialData**: (Optional) `TenantAuthInput[]`. Hydrate state immediately.
371
- - **debug**: (Optional) `boolean`. Log permission checks to console.
372
-
373
326
  #### `<ProtectedRoute>`
374
327
 
375
328
  A wrapper component that guards an entire route or section.
376
329
 
377
- - **permission**: Single permission string OR array (`[]`).
378
- - **requireAll**: `boolean` (Default: `false`).
379
- - **redirect**: `boolean` (Default: `true`).
380
- - **fallbackPath**: URL to redirect to if unauthorized.
381
- - **fallback**: UI to show while redirecting.
382
- - **loadingComponent**: Custom UI to show during initial check.
330
+ - **permission**: string | string[] (Optional)
331
+ - **role**: string | string[] (Optional)
332
+ - **requireAll**: boolean (Default: `false`)
333
+ - **redirect**: boolean (Default: `true`)
334
+ - **fallbackPath**: string (Default: `/`)
335
+ - **fallback**: ReactNode (UI while redirecting/denied)
383
336
 
384
337
  #### `<Can>`
385
338
 
386
339
  Structural component for conditional rendering.
387
340
 
388
- - **permission**: Single string OR array.
389
- - **requireAll**: `boolean`.
390
- - **fallback**: UI to show when permission is denied.
341
+ - **permission**: string | string[] (Optional)
342
+ - **role**: string | string[] (Optional)
343
+ - **requireAll**: boolean
344
+ - **fallback**: ReactNode
391
345
 
392
346
  ### Hooks
393
347
 
394
- #### `useRBAC()`
395
-
396
- Access raw state and actions.
397
-
398
- - `setAuth(authData)`: Accepts simple `string[]`.
399
- - `switchTenant(id)`: Change active context.
400
- - `isLoading`: `boolean`.
401
- - `activeTenantId`: `string | null`.
402
-
403
- #### `useMatch(handlers)`
348
+ #### `useHasRole(role: string)`
404
349
 
405
- Executes logic based on the first matching permission.
350
+ Returns `boolean`. Checks if user has the specific role (or `*`).
406
351
 
407
- - **handlers**: Object `{ [permission]: () => T }`.
408
- - **default**: Fallback function.
409
-
410
- #### `useHasPermission(permission)`
352
+ #### `useHasPermission(permission: string)`
411
353
 
412
354
  Returns `boolean`. Checks for exact permission match or wildcard `*`.
413
355
 
414
- #### `useHasAnyPermission(permissions[])`
415
-
416
- Returns `boolean`. True if user has **at least one** permission.
417
-
418
- #### `useHasAllPermissions(permissions[])`
419
-
420
- Returns `boolean`. True only if user has **every single** permission.
421
-
422
- ### Utilities
423
-
424
- #### `guard(userPerms, requiredPerm, function)`
425
-
426
- Higher-order function that wraps and protects a function execution.
356
+ #### `useRBAC()`
427
357
 
428
- #### `checkPermission(userPerms, requiredPerm)`
358
+ Access raw state.
429
359
 
430
- Universal helper for checking permissions (works on Server/Client/Edge).
360
+ - `setAuth(authData)`: Valid inputs:
361
+ - `string[]` (Permissions only)
362
+ - `TenantAuthInput[]` (Full Multi-tenant data)
363
+ - `switchTenant(id)`: Change active context.
431
364
 
432
365
  ---
433
366
 
434
367
  ## 🛡️ Security & Best Practices
435
368
 
436
- > [!IMPORTANT] > **Client-side checks are for User Experience (UX) only.**
369
+ > [!IMPORTANT]
370
+ > **Client-side checks are for User Experience (UX) only.**
437
371
 
438
- RBAC Shield controls what the user _sees_ in the browser, but it cannot stop a determined attacker from crafting API requests manually.
439
-
440
- ### 1. Server-Side Verification (Universal)
441
-
442
- Use the universal `checkPermission` helper in Middleware, Server Actions, or API Routes:
443
-
444
- ```tsx
445
- import { checkPermission } from "rbac-shield";
446
- // 1. Middleware Example
447
- export function middleware(req) {
448
- const permissions = getPermissionsFromCookie(req);
449
- if (!checkPermission(permissions, "admin:access")) {
450
- return NextResponse.redirect(new URL("/403", req.url));
451
- }
452
- }
453
- ```
454
-
455
- ### 2. Debug Mode
456
-
457
- Enable debug mode to see permission logs in the console:
458
-
459
- ```tsx
460
- <RBACProvider debug={true}>{children}</RBACProvider>
461
- ```
462
-
463
- ---
464
-
465
- ## 🐛 Troubleshooting
466
-
467
- | Issue | Solution |
468
- | ---------------------- | -------------------------------------------------------------------------------------------------------------- |
469
- | **Infinite Loading** | Ensure `RBACProvider` wraps your app and `setAuth` is called with valid data. |
470
- | **Type Errors** | Verify your `Resources` and `Actions` types in `lib/rbac.ts` are exported. |
471
- | **Hydration Mismatch** | `ProtectedRoute` and `Can` are client components; ensure they are used in client contexts or wrapped properly. |
372
+ Always verify permissions on the server (API Routes, Server Actions, Middleware) using `checkPermission` or `guard`.
472
373
 
473
374
  ---
474
375
 
475
- ## 🤝 Contributing
476
-
477
- We welcome contributions! Please open an issue or submit a PR on our [GitHub repository](https://github.com/your-repo/rbac-shield).
478
-
479
376
  ## 📄 License
480
377
 
481
378
  MIT © [Arif Hossain Roman](https://github.com/devnuckles)
@@ -5,7 +5,9 @@ type Prettify<T> = {
5
5
  } & {};
6
6
  export interface CanProps<R extends string, A extends string> {
7
7
  /** Single permission or array of permissions to check */
8
- permission: PermissionString<R, A> | PermissionString<R, A>[];
8
+ permission?: PermissionString<R, A> | PermissionString<R, A>[];
9
+ /** Single role or array of roles to check */
10
+ role?: string | string[];
9
11
  children: React.ReactNode;
10
12
  /** Content to render if permission is denied */
11
13
  fallback?: React.ReactNode;
@@ -15,7 +17,9 @@ export interface CanProps<R extends string, A extends string> {
15
17
  export interface ProtectedRouteProps<R extends string, A extends string> {
16
18
  children: React.ReactNode;
17
19
  /** Single permission or array of permissions to check */
18
- permission: PermissionString<R, A> | PermissionString<R, A>[];
20
+ permission?: PermissionString<R, A> | PermissionString<R, A>[];
21
+ /** Single role or array of roles to check */
22
+ role?: string | string[];
19
23
  /** Path to redirect to if access denied (if redirect is true) */
20
24
  fallbackPath?: string;
21
25
  /** Content to render if access denied (or while redirecting) */
@@ -30,16 +34,17 @@ export interface ProtectedRouteProps<R extends string, A extends string> {
30
34
  export interface RBACProviderProps {
31
35
  children: React.ReactNode;
32
36
  debug?: boolean;
33
- initialData?: TenantAuthInput[];
37
+ initialData?: TenantAuthInput[] | string[];
34
38
  }
35
39
  export interface RBACFactory<R extends string, A extends string> {
36
40
  RBACProvider: (props: RBACProviderProps) => React.JSX.Element;
37
41
  /** Access raw state and actions */
38
42
  useRBAC: () => RBACState<R, A> & {
39
- setAuth: (authArray: TenantAuthInput[]) => void;
43
+ setAuth: (auth: TenantAuthInput[] | string[]) => void;
40
44
  switchTenant: (tenantId: string) => void;
41
45
  reset: () => void;
42
46
  };
47
+ useHasRole: (role: string) => boolean;
43
48
  useHasPermission: (permission: PermissionString<R, A>) => boolean;
44
49
  useHasAnyPermission: (permissions: PermissionString<R, A>[]) => boolean;
45
50
  useHasAllPermissions: (permissions: PermissionString<R, A>[]) => boolean;
package/dist/factory.d.ts CHANGED
@@ -5,7 +5,9 @@ type Prettify<T> = {
5
5
  } & {};
6
6
  export interface CanProps<R extends string, A extends string> {
7
7
  /** Single permission or array of permissions to check */
8
- permission: PermissionString<R, A> | PermissionString<R, A>[];
8
+ permission?: PermissionString<R, A> | PermissionString<R, A>[];
9
+ /** Single role or array of roles to check */
10
+ role?: string | string[];
9
11
  children: React.ReactNode;
10
12
  /** Content to render if permission is denied */
11
13
  fallback?: React.ReactNode;
@@ -15,7 +17,9 @@ export interface CanProps<R extends string, A extends string> {
15
17
  export interface ProtectedRouteProps<R extends string, A extends string> {
16
18
  children: React.ReactNode;
17
19
  /** Single permission or array of permissions to check */
18
- permission: PermissionString<R, A> | PermissionString<R, A>[];
20
+ permission?: PermissionString<R, A> | PermissionString<R, A>[];
21
+ /** Single role or array of roles to check */
22
+ role?: string | string[];
19
23
  /** Path to redirect to if access denied (if redirect is true) */
20
24
  fallbackPath?: string;
21
25
  /** Content to render if access denied (or while redirecting) */
@@ -30,16 +34,17 @@ export interface ProtectedRouteProps<R extends string, A extends string> {
30
34
  export interface RBACProviderProps {
31
35
  children: React.ReactNode;
32
36
  debug?: boolean;
33
- initialData?: TenantAuthInput[];
37
+ initialData?: TenantAuthInput[] | string[];
34
38
  }
35
39
  export interface RBACFactory<R extends string, A extends string> {
36
40
  RBACProvider: (props: RBACProviderProps) => React.JSX.Element;
37
41
  /** Access raw state and actions */
38
42
  useRBAC: () => RBACState<R, A> & {
39
- setAuth: (authArray: TenantAuthInput[]) => void;
43
+ setAuth: (auth: TenantAuthInput[] | string[]) => void;
40
44
  switchTenant: (tenantId: string) => void;
41
45
  reset: () => void;
42
46
  };
47
+ useHasRole: (role: string) => boolean;
43
48
  useHasPermission: (permission: PermissionString<R, A>) => boolean;
44
49
  useHasAnyPermission: (permissions: PermissionString<R, A>[]) => boolean;
45
50
  useHasAllPermissions: (permissions: PermissionString<R, A>[]) => boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.tsx"],"names":[],"mappings":"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"}