rbac-shield 0.2.2 → 0.2.4
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 +95 -218
- package/bin/templates.js +8 -4
- package/dist/factory.d.mts +5 -1
- package/dist/factory.d.ts +5 -1
- package/dist/factory.d.ts.map +1 -1
- package/dist/factory.js +100 -108
- package/dist/factory.mjs +101 -109
- package/dist/guards.d.mts +1 -1
- package/dist/guards.d.ts +1 -1
- package/dist/guards.d.ts.map +1 -1
- package/dist/guards.js +2 -2
- package/dist/guards.mjs +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.mjs +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,129 +2,82 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/rbac-shield)
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
|
-
[]()
|
|
6
5
|
[](https://www.typescriptlang.org/)
|
|
7
6
|
|
|
8
|
-
> [!WARNING]
|
|
9
|
-
> **Public Beta**: Ensuring strict type safety and performance. API is stable but minor breaking changes might occur before v1.0.
|
|
10
|
-
|
|
11
7
|
**The production-ready, type-safe Role-Based Access Control (RBAC) system for Next.js applications.**
|
|
12
8
|
|
|
13
9
|
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.
|
|
14
10
|
|
|
15
11
|
---
|
|
16
12
|
|
|
17
|
-
## 📑 Table of Contents
|
|
18
|
-
|
|
19
|
-
- [Features](#-features)
|
|
20
|
-
- [Quick Setup (CLI)](#-quick-setup-recommended)
|
|
21
|
-
- [Manual Installation](#-manual-installation)
|
|
22
|
-
- [Quick Start](#-quick-start)
|
|
23
|
-
- [Role Management (New)](#-role-management)
|
|
24
|
-
- [Guides & Patterns](#-guides--patterns)
|
|
25
|
-
- [Roles vs Permissions](#roles-vs-permissions)
|
|
26
|
-
- [Complex Logic (AND/OR)](#complex-logic-andor)
|
|
27
|
-
- [SSR & Hydration](#ssr--hydration-eliminate-loading-states)
|
|
28
|
-
- [Logic Switching (Dynamic APIs)](#logic-switching-dynamic-apis)
|
|
29
|
-
- [Server Action Guards](#server-action-guards)
|
|
30
|
-
- [API Reference](#-api-reference)
|
|
31
|
-
- [Security & Best Practices](#-security--best-practices)
|
|
32
|
-
- [Troubleshooting](#-troubleshooting)
|
|
33
|
-
|
|
34
|
-
---
|
|
35
|
-
|
|
36
13
|
## ✨ Features
|
|
37
14
|
|
|
38
|
-
- 🎯 **Type-Safe Permissions**: Typescript "Prettify" helpers ensure tooltips show exact prop shapes
|
|
39
|
-
- 👑 **First-Class Role Support**: Check for Roles
|
|
40
|
-
- 🚀 **High Performance**: Optimized with React Context and memoization.
|
|
41
|
-
- 🏢 **Multi-Tenant Native**: Switch between
|
|
42
|
-
- ⚡ **Zero Loading States**:
|
|
43
|
-
- 🛡️ **Route Protection**: Declarative
|
|
44
|
-
- 🌍 **Universal
|
|
45
|
-
- 📦 **Zero Dependencies**: Lightweight (~35KB) and built entirely on standard React APIs.
|
|
15
|
+
- 🎯 **Type-Safe Permissions**: Typescript "Prettify" helpers ensure tooltips show exact prop shapes.
|
|
16
|
+
- 👑 **First-Class Role Support**: Check for **Roles**, **Permissions**, or **Both**.
|
|
17
|
+
- 🚀 **High Performance**: Optimized with React Context and memoization.
|
|
18
|
+
- 🏢 **Multi-Tenant Native**: Switch between organizations/roles instantly.
|
|
19
|
+
- ⚡ **Zero Loading States**: Instant hydration via server-side data injection.
|
|
20
|
+
- 🛡️ **Route Protection**: Declarative guards with auto-redirects.
|
|
21
|
+
- 🌍 **Universal**: Works in Client Components, Server Components, and Middleware.
|
|
46
22
|
|
|
47
23
|
---
|
|
48
24
|
|
|
49
|
-
##
|
|
25
|
+
## 📦 Installation
|
|
26
|
+
|
|
27
|
+
### Option 1: Interactive CLI (Recommended)
|
|
50
28
|
|
|
51
|
-
|
|
29
|
+
This will set up your types and configuration file automatically.
|
|
52
30
|
|
|
53
31
|
```bash
|
|
54
32
|
npx rbac-shield init
|
|
55
33
|
```
|
|
56
34
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
1. Detect your project type (Next.js/React, TS/JS)
|
|
60
|
-
2. Help you define your resources (e.g., `projects`) and actions (e.g., `create`)
|
|
61
|
-
3. Generate a clean, type-safe `lib/rbac.ts` file configured for your app
|
|
62
|
-
|
|
63
|
-
---
|
|
64
|
-
|
|
65
|
-
## 📦 Manual Installation
|
|
66
|
-
|
|
67
|
-
If you prefer to set things up yourself:
|
|
35
|
+
### Option 2: Manual Install
|
|
68
36
|
|
|
69
37
|
```bash
|
|
70
38
|
npm install rbac-shield
|
|
71
39
|
# or
|
|
72
40
|
yarn add rbac-shield
|
|
73
|
-
# or
|
|
74
|
-
pnpm add rbac-shield
|
|
75
|
-
# or
|
|
76
|
-
bun add rbac-shield
|
|
77
41
|
```
|
|
78
42
|
|
|
79
|
-
**Peer Dependencies:**
|
|
80
|
-
Ensure you have peer dependencies installed (standard in Next.js apps):
|
|
81
|
-
`react >= 18.0.0`, `react-dom >= 18.0.0`, `next >= 13.0.0`
|
|
82
|
-
|
|
83
43
|
---
|
|
84
44
|
|
|
85
45
|
## 🚀 Quick Start
|
|
86
46
|
|
|
87
|
-
### 1. Define
|
|
47
|
+
### 1. Define Schema
|
|
88
48
|
|
|
89
|
-
Create
|
|
49
|
+
Create `lib/rbac.ts` to define your types and export your instances.
|
|
90
50
|
|
|
91
51
|
```typescript
|
|
92
52
|
// lib/rbac.ts
|
|
93
53
|
"use client";
|
|
94
54
|
import { createRBAC } from "rbac-shield";
|
|
95
55
|
|
|
96
|
-
|
|
97
|
-
export type
|
|
56
|
+
export type Resources = "projects" | "billing" | "users";
|
|
57
|
+
export type Actions = "view" | "create" | "edit" | "delete";
|
|
98
58
|
|
|
99
|
-
// 2. Define actions (what users can do)
|
|
100
|
-
export type Actions = "view" | "create" | "edit" | "delete" | "export";
|
|
101
|
-
|
|
102
|
-
// 3. Create your instances
|
|
103
59
|
export const {
|
|
104
60
|
RBACProvider,
|
|
105
61
|
useRBAC,
|
|
106
|
-
useHasRole,
|
|
62
|
+
useHasRole,
|
|
107
63
|
useHasPermission,
|
|
108
|
-
|
|
64
|
+
useAccess, // Hook returning check function
|
|
65
|
+
usePermissionMatch, // Logic switcher
|
|
109
66
|
Can,
|
|
110
67
|
ProtectedRoute,
|
|
111
68
|
guard,
|
|
112
69
|
} = createRBAC<Resources, Actions>();
|
|
113
70
|
```
|
|
114
71
|
|
|
115
|
-
### 2. Wrap
|
|
72
|
+
### 2. Wrap App
|
|
116
73
|
|
|
117
|
-
|
|
74
|
+
Wrap your root layout with the provider.
|
|
118
75
|
|
|
119
76
|
```tsx
|
|
120
77
|
// app/layout.tsx
|
|
121
78
|
import { RBACProvider } from "@/lib/rbac";
|
|
122
79
|
|
|
123
|
-
export default function RootLayout({
|
|
124
|
-
children,
|
|
125
|
-
}: {
|
|
126
|
-
children: React.ReactNode;
|
|
127
|
-
}) {
|
|
80
|
+
export default function RootLayout({ children }) {
|
|
128
81
|
return (
|
|
129
82
|
<html lang="en">
|
|
130
83
|
<body>
|
|
@@ -137,59 +90,65 @@ export default function RootLayout({
|
|
|
137
90
|
|
|
138
91
|
### 3. Load Permissions
|
|
139
92
|
|
|
140
|
-
Initialize
|
|
93
|
+
Initialize permissions. For async user data, **wait for the user to load** before setting auth.
|
|
141
94
|
|
|
142
95
|
```tsx
|
|
143
|
-
// components/
|
|
96
|
+
// components/PermissionLoader.tsx
|
|
144
97
|
"use client";
|
|
145
98
|
import { useEffect } from "react";
|
|
146
99
|
import { useRBAC } from "@/lib/rbac";
|
|
100
|
+
import { useUser } from "@/hooks/useUser";
|
|
147
101
|
|
|
148
|
-
export function
|
|
149
|
-
const { setAuth } = useRBAC();
|
|
102
|
+
export function PermissionLoader({ children }) {
|
|
103
|
+
const { setAuth, switchTenant } = useRBAC();
|
|
104
|
+
const { user, isLoading } = useUser();
|
|
150
105
|
|
|
151
106
|
useEffect(() => {
|
|
152
|
-
if (user)
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
163
|
-
}, [user, setAuth]);
|
|
107
|
+
if (isLoading || !user) return;
|
|
108
|
+
|
|
109
|
+
// Load Roles + Permissions
|
|
110
|
+
setAuth([
|
|
111
|
+
{
|
|
112
|
+
tenantId: user.id || "default",
|
|
113
|
+
roles: [user.role], // e.g. ["admin"]
|
|
114
|
+
permissions: user.permissions, // e.g. ["projects:view"]
|
|
115
|
+
},
|
|
116
|
+
]);
|
|
164
117
|
|
|
118
|
+
switchTenant(user.id || "default");
|
|
119
|
+
}, [user, isLoading]);
|
|
120
|
+
|
|
121
|
+
if (isLoading || !user) return null; // Prevent render until authed
|
|
165
122
|
return <>{children}</>;
|
|
166
123
|
}
|
|
167
124
|
```
|
|
168
125
|
|
|
169
|
-
### 4.
|
|
126
|
+
### 4. Protect Routes
|
|
170
127
|
|
|
171
128
|
Use the components to guard access.
|
|
172
129
|
|
|
173
130
|
```tsx
|
|
174
|
-
import { ProtectedRoute, Can, useHasRole } from "@/lib/rbac";
|
|
131
|
+
import { ProtectedRoute, Can, useHasRole, useAccess } from "@/lib/rbac";
|
|
132
|
+
|
|
133
|
+
export default function AdminDashboard() {
|
|
134
|
+
const isSuperAdmin = useHasRole("super_admin");
|
|
175
135
|
|
|
176
|
-
|
|
177
|
-
const
|
|
136
|
+
// Advanced: Get access checker function
|
|
137
|
+
const hasAccess = useAccess();
|
|
138
|
+
|
|
139
|
+
const canManage = hasAccess({
|
|
140
|
+
roles: ["admin"],
|
|
141
|
+
permissions: ["system:manage"],
|
|
142
|
+
});
|
|
178
143
|
|
|
179
144
|
return (
|
|
180
|
-
|
|
181
|
-
<ProtectedRoute role="admin" fallbackPath="/login">
|
|
145
|
+
<ProtectedRoute role={["admin", "super_admin"]} fallbackPath="/login">
|
|
182
146
|
<h1>Admin Dashboard</h1>
|
|
183
147
|
|
|
184
|
-
{/*
|
|
148
|
+
{/* Conditional Rendering */}
|
|
185
149
|
<Can permission="billing:view">
|
|
186
150
|
<BillingWidget />
|
|
187
151
|
</Can>
|
|
188
|
-
|
|
189
|
-
{/* 3. Combined Logic (Role AND Permission) */}
|
|
190
|
-
<Can role="manager" permission="users:delete">
|
|
191
|
-
<DeleteUserButton />
|
|
192
|
-
</Can>
|
|
193
152
|
</ProtectedRoute>
|
|
194
153
|
);
|
|
195
154
|
}
|
|
@@ -197,9 +156,9 @@ export default function AdminPanel() {
|
|
|
197
156
|
|
|
198
157
|
---
|
|
199
158
|
|
|
200
|
-
## 👑 Role Management
|
|
159
|
+
## 👑 Role Management & Logic
|
|
201
160
|
|
|
202
|
-
RBAC Shield
|
|
161
|
+
RBAC Shield uses a **Unified Access Logic** across all components.
|
|
203
162
|
|
|
204
163
|
### Logic Matrix
|
|
205
164
|
|
|
@@ -208,81 +167,67 @@ RBAC Shield now supports **Dynamic Logic** for access control. You can check for
|
|
|
208
167
|
| **Role Only** | User has `role` | `<Can role="admin">` |
|
|
209
168
|
| **Permission Only** | User has `permission` | `<Can permission="edit">` |
|
|
210
169
|
| **Both** | **STRICT AND**: User has `role` **AND** `permission` | `<Can role="admin" permission="edit">` |
|
|
211
|
-
| **Neither** | Deny Access | `<Can />` (Renders nothing) |
|
|
212
170
|
|
|
213
|
-
### Wildcards
|
|
171
|
+
### Wildcards (`*`)
|
|
214
172
|
|
|
215
|
-
- **Roles**: If
|
|
216
|
-
- **Permissions**: If
|
|
173
|
+
- **Roles**: If user has role `*`, they pass ALL role checks.
|
|
174
|
+
- **Permissions**: If user has permission `*`, they pass ALL permission checks.
|
|
217
175
|
|
|
218
|
-
###
|
|
176
|
+
### Arrays (OR Logic)
|
|
219
177
|
|
|
220
|
-
|
|
178
|
+
Providing an array means "User must match **ANY** of these".
|
|
221
179
|
|
|
222
180
|
```tsx
|
|
223
|
-
//
|
|
224
|
-
<
|
|
225
|
-
<ManagementPanel />
|
|
226
|
-
</Can>
|
|
181
|
+
// Allow if user is 'admin' OR 'manager'
|
|
182
|
+
<ProtectedRoute role={["admin", "manager"]}>
|
|
227
183
|
```
|
|
228
184
|
|
|
229
185
|
---
|
|
230
186
|
|
|
231
|
-
##
|
|
187
|
+
## � API Reference
|
|
232
188
|
|
|
233
|
-
###
|
|
189
|
+
### Components
|
|
234
190
|
|
|
235
|
-
|
|
236
|
-
- **Permissions**: Use for granular capability checks (e.g., "Can they delete this post?").
|
|
191
|
+
#### `<ProtectedRoute>`
|
|
237
192
|
|
|
238
|
-
|
|
193
|
+
Guards an entire route. Redirects if access denied.
|
|
239
194
|
|
|
240
|
-
|
|
195
|
+
- **role**: `string | string[]`
|
|
196
|
+
- **permission**: `string | string[]`
|
|
197
|
+
- **requireAll**: `boolean` (Default: `false` - generally used for checking multiple permissions)
|
|
198
|
+
- **redirect**: `boolean` (Default: `true`)
|
|
199
|
+
- **fallbackPath**: `string` (Default: `/`)
|
|
200
|
+
- **fallback**: `ReactNode` (Shown while redirecting)
|
|
241
201
|
|
|
242
|
-
|
|
202
|
+
#### `<Can>`
|
|
243
203
|
|
|
244
|
-
|
|
245
|
-
// User must be 'admin' AND have 'post:delete' permission
|
|
246
|
-
<Can permission={["role:admin", "post:delete"]} requireAll>
|
|
247
|
-
<DeleteEverythingButton />
|
|
248
|
-
</Can>
|
|
249
|
-
```
|
|
204
|
+
Conditionally renders children.
|
|
250
205
|
|
|
251
|
-
|
|
206
|
+
- **role**: `string | string[]`
|
|
207
|
+
- **permission**: `string | string[]`
|
|
208
|
+
- **fallback**: `ReactNode` (Shown if denied)
|
|
252
209
|
|
|
253
|
-
|
|
210
|
+
### Hooks
|
|
254
211
|
|
|
255
|
-
|
|
256
|
-
// app/layout.tsx (Server Component)
|
|
257
|
-
import { RBACProvider } from "@/lib/rbac";
|
|
258
|
-
import { getSession } from "@/lib/auth";
|
|
212
|
+
#### `useAccess({ roles?, permissions? })`
|
|
259
213
|
|
|
260
|
-
|
|
261
|
-
const session = await getSession();
|
|
214
|
+
Returns `boolean`. Checks if user matches ANY of the roles OR ANY of the permissions.
|
|
262
215
|
|
|
263
|
-
|
|
264
|
-
const initialData = session?.permissions || [];
|
|
216
|
+
#### `useHasRole(role)`
|
|
265
217
|
|
|
266
|
-
|
|
267
|
-
<html>
|
|
268
|
-
<body>
|
|
269
|
-
{/* Hydrates instantly! */}
|
|
270
|
-
<RBACProvider initialData={initialData}>{children}</RBACProvider>
|
|
271
|
-
</body>
|
|
272
|
-
</html>
|
|
273
|
-
);
|
|
274
|
-
}
|
|
275
|
-
```
|
|
218
|
+
Returns `boolean`. Checks for specific role (or wildcard).
|
|
276
219
|
|
|
277
|
-
|
|
220
|
+
#### `usePermissionMatch(handlers)`
|
|
278
221
|
|
|
279
|
-
|
|
222
|
+
Executes logic based on the### Logic Switching (Dynamic APIs)
|
|
223
|
+
|
|
224
|
+
Use `usePermissionMatch` to execute different logic based on permissions.
|
|
280
225
|
|
|
281
226
|
```tsx
|
|
282
|
-
import {
|
|
227
|
+
import { usePermissionMatch } from "@/lib/rbac";
|
|
283
228
|
|
|
284
229
|
export default function Dashboard() {
|
|
285
|
-
const getData =
|
|
230
|
+
const getData = usePermissionMatch({
|
|
286
231
|
"admin:view": () => api.getAdminStats(),
|
|
287
232
|
"manager:view": () => api.getManagerStats(),
|
|
288
233
|
default: () => api.getUserStats(),
|
|
@@ -292,84 +237,16 @@ export default function Dashboard() {
|
|
|
292
237
|
}
|
|
293
238
|
```
|
|
294
239
|
|
|
295
|
-
### Server Action Guards
|
|
296
|
-
|
|
297
|
-
Protect arbitrary functions (like Server Actions) using the `guard` wrapper.
|
|
298
|
-
|
|
299
|
-
```typescript
|
|
300
|
-
// actions/project.ts (Server Action)
|
|
301
|
-
import { guard } from "rbac-shield";
|
|
302
|
-
import { getSession } from "@/lib/auth";
|
|
303
|
-
|
|
304
|
-
export async function deleteProject(id: string) {
|
|
305
|
-
const session = await getSession();
|
|
306
|
-
|
|
307
|
-
const safeAction = guard(
|
|
308
|
-
session.permissions, // User's permissions
|
|
309
|
-
"project:delete", // Required permission
|
|
310
|
-
async () => {
|
|
311
|
-
await db.project.delete(id);
|
|
312
|
-
return "Deleted!";
|
|
313
|
-
},
|
|
314
|
-
);
|
|
315
|
-
|
|
316
|
-
return safeAction();
|
|
317
|
-
}
|
|
318
|
-
```
|
|
319
|
-
|
|
320
|
-
---
|
|
321
|
-
|
|
322
|
-
## 📚 API Reference
|
|
323
|
-
|
|
324
|
-
### Components
|
|
325
|
-
|
|
326
|
-
#### `<ProtectedRoute>`
|
|
327
|
-
|
|
328
|
-
A wrapper component that guards an entire route or section.
|
|
329
|
-
|
|
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)
|
|
336
|
-
|
|
337
|
-
#### `<Can>`
|
|
338
|
-
|
|
339
|
-
Structural component for conditional rendering.
|
|
340
|
-
|
|
341
|
-
- **permission**: string | string[] (Optional)
|
|
342
|
-
- **role**: string | string[] (Optional)
|
|
343
|
-
- **requireAll**: boolean
|
|
344
|
-
- **fallback**: ReactNode
|
|
345
|
-
|
|
346
|
-
### Hooks
|
|
347
|
-
|
|
348
|
-
#### `useHasRole(role: string)`
|
|
349
|
-
|
|
350
|
-
Returns `boolean`. Checks if user has the specific role (or `*`).
|
|
351
|
-
|
|
352
|
-
#### `useHasPermission(permission: string)`
|
|
353
|
-
|
|
354
|
-
Returns `boolean`. Checks for exact permission match or wildcard `*`.
|
|
355
|
-
|
|
356
240
|
#### `useRBAC()`
|
|
357
241
|
|
|
358
|
-
Access raw state.
|
|
359
|
-
|
|
360
|
-
- `setAuth(authData)`: Valid inputs:
|
|
361
|
-
- `string[]` (Permissions only)
|
|
362
|
-
- `TenantAuthInput[]` (Full Multi-tenant data)
|
|
363
|
-
- `switchTenant(id)`: Change active context.
|
|
242
|
+
Access raw state (`isLoading`, `activeTenantId`, etc.) and actions (`setAuth`).
|
|
364
243
|
|
|
365
244
|
---
|
|
366
245
|
|
|
367
|
-
## 🛡️
|
|
368
|
-
|
|
369
|
-
> [!IMPORTANT]
|
|
370
|
-
> **Client-side checks are for User Experience (UX) only.**
|
|
246
|
+
## 🛡️ Best Practices
|
|
371
247
|
|
|
372
|
-
Always verify permissions on the server (API Routes, Server Actions
|
|
248
|
+
1. **Server-Side Verification**: Always verify permissions on the server (API Routes, Server Actions) using the `checkPermission` utility or `guard` wrapper. Client-side checks are for UX only.
|
|
249
|
+
2. **Combine Checks**: Use Roles for high-level page access, and Permissions for specific button visibility.
|
|
373
250
|
|
|
374
251
|
---
|
|
375
252
|
|
package/bin/templates.js
CHANGED
|
@@ -33,11 +33,13 @@ export type Actions = ${actionsType};
|
|
|
33
33
|
export const {
|
|
34
34
|
RBACProvider,
|
|
35
35
|
useRBAC,
|
|
36
|
-
|
|
36
|
+
useHasRole,
|
|
37
|
+
useHasPermission,
|
|
38
|
+
useAccess,
|
|
37
39
|
useHasAnyPermission,
|
|
38
40
|
useHasAllPermissions,
|
|
39
41
|
usePermissions,
|
|
40
|
-
|
|
42
|
+
usePermissionMatch,
|
|
41
43
|
Can,
|
|
42
44
|
RBACErrorBoundary,
|
|
43
45
|
ProtectedRoute,
|
|
@@ -53,11 +55,13 @@ import { createRBAC } from 'rbac-shield';
|
|
|
53
55
|
export const {
|
|
54
56
|
RBACProvider,
|
|
55
57
|
useRBAC,
|
|
56
|
-
|
|
58
|
+
useHasRole,
|
|
59
|
+
useHasPermission,
|
|
60
|
+
useAccess,
|
|
57
61
|
useHasAnyPermission,
|
|
58
62
|
useHasAllPermissions,
|
|
59
63
|
usePermissions,
|
|
60
|
-
|
|
64
|
+
usePermissionMatch,
|
|
61
65
|
Can,
|
|
62
66
|
RBACErrorBoundary,
|
|
63
67
|
ProtectedRoute,
|
package/dist/factory.d.mts
CHANGED
|
@@ -46,6 +46,10 @@ export interface RBACFactory<R extends string, A extends string> {
|
|
|
46
46
|
};
|
|
47
47
|
useHasRole: (role: string) => boolean;
|
|
48
48
|
useHasPermission: (permission: PermissionString<R, A>) => boolean;
|
|
49
|
+
useAccess: () => (requirements: {
|
|
50
|
+
roles?: string[];
|
|
51
|
+
permissions?: string[];
|
|
52
|
+
}) => boolean;
|
|
49
53
|
useHasAnyPermission: (permissions: PermissionString<R, A>[]) => boolean;
|
|
50
54
|
useHasAllPermissions: (permissions: PermissionString<R, A>[]) => boolean;
|
|
51
55
|
usePermissions: () => PermissionString<R, A>[];
|
|
@@ -53,7 +57,7 @@ export interface RBACFactory<R extends string, A extends string> {
|
|
|
53
57
|
* Execute logic based on the first matching permission.
|
|
54
58
|
* Useful for switching APIs or components based on role.
|
|
55
59
|
*/
|
|
56
|
-
|
|
60
|
+
usePermissionMatch: <T>(handlers: Partial<Record<PermissionString<R, A>, () => T>> & {
|
|
57
61
|
default?: () => T;
|
|
58
62
|
}) => T | undefined;
|
|
59
63
|
Can: (props: Prettify<CanProps<R, A>>) => React.JSX.Element;
|
package/dist/factory.d.ts
CHANGED
|
@@ -46,6 +46,10 @@ export interface RBACFactory<R extends string, A extends string> {
|
|
|
46
46
|
};
|
|
47
47
|
useHasRole: (role: string) => boolean;
|
|
48
48
|
useHasPermission: (permission: PermissionString<R, A>) => boolean;
|
|
49
|
+
useAccess: () => (requirements: {
|
|
50
|
+
roles?: string[];
|
|
51
|
+
permissions?: string[];
|
|
52
|
+
}) => boolean;
|
|
49
53
|
useHasAnyPermission: (permissions: PermissionString<R, A>[]) => boolean;
|
|
50
54
|
useHasAllPermissions: (permissions: PermissionString<R, A>[]) => boolean;
|
|
51
55
|
usePermissions: () => PermissionString<R, A>[];
|
|
@@ -53,7 +57,7 @@ export interface RBACFactory<R extends string, A extends string> {
|
|
|
53
57
|
* Execute logic based on the first matching permission.
|
|
54
58
|
* Useful for switching APIs or components based on role.
|
|
55
59
|
*/
|
|
56
|
-
|
|
60
|
+
usePermissionMatch: <T>(handlers: Partial<Record<PermissionString<R, A>, () => T>> & {
|
|
57
61
|
default?: () => T;
|
|
58
62
|
}) => T | undefined;
|
|
59
63
|
Can: (props: Prettify<CanProps<R, A>>) => React.JSX.Element;
|
package/dist/factory.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.tsx"],"names":[],"mappings":"AAEA,OAAO,KAON,MAAM,OAAO,CAAC;AAEf,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAavE,KAAK,QAAQ,CAAC,CAAC,IAAI;KAChB,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CACrB,GAAG,EAAE,CAAC;AAEP,MAAM,WAAW,QAAQ,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM;IAC1D,yDAAyD;IACzD,UAAU,CAAC,EAAE,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;IAC/D,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,gDAAgD;IAChD,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,2EAA2E;IAC3E,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM;IACrE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,yDAAyD;IACzD,UAAU,CAAC,EAAE,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;IAC/D,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzB,iEAAiE;IACjE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,2EAA2E;IAC3E,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,yDAAyD;IACzD,gBAAgB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACnC,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,eAAe,EAAE,GAAG,MAAM,EAAE,CAAC;CAC5C;AAED,MAAM,WAAW,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM;IAC7D,YAAY,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC;IAC9D,mCAAmC;IACnC,OAAO,EAAE,MAAM,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;QAC/B,OAAO,EAAE,CAAC,IAAI,EAAE,eAAe,EAAE,GAAG,MAAM,EAAE,KAAK,IAAI,CAAC;QACtD,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;QACzC,KAAK,EAAE,MAAM,IAAI,CAAC;KACnB,CAAC;IACF,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IACtC,gBAAgB,EAAE,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,OAAO,CAAC;IAClE,mBAAmB,EAAE,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC;IACxE,oBAAoB,EAAE,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC;IACzE,cAAc,EAAE,MAAM,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;IAC/C;;;OAGG;IACH,
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.tsx"],"names":[],"mappings":"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"}
|