@jmruthers/pace-core 0.5.109 → 0.5.110
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/CHANGELOG.md +22 -0
- package/dist/{DataTable-5HITILXS.js → DataTable-D3BK2FCN.js} +4 -4
- package/dist/{api-5I3E47G2.js → api-PIE4JRFS.js} +2 -2
- package/dist/{chunk-P72NKAT5.js → chunk-3J5N2T2N.js} +51 -11
- package/dist/chunk-3J5N2T2N.js.map +1 -0
- package/dist/{chunk-3TKTL5AZ.js → chunk-7GBEBJLR.js} +26 -34
- package/dist/chunk-7GBEBJLR.js.map +1 -0
- package/dist/{chunk-S4D3Z723.js → chunk-AWK2FAUN.js} +3 -3
- package/dist/{chunk-WWNOVFDC.js → chunk-HADXAZT3.js} +2 -2
- package/dist/{chunk-UW2DE6JX.js → chunk-HGZSO43Y.js} +2 -2
- package/dist/{chunk-F6TSYCKP.js → chunk-XRSP3H52.js} +12 -7
- package/dist/chunk-XRSP3H52.js.map +1 -0
- package/dist/components.js +4 -4
- package/dist/hooks.js +1 -1
- package/dist/index.js +6 -6
- package/dist/rbac/index.d.ts +34 -22
- package/dist/rbac/index.js +3 -3
- package/dist/utils.js +1 -1
- package/docs/api/classes/ColumnFactory.md +1 -1
- package/docs/api/classes/ErrorBoundary.md +1 -1
- package/docs/api/classes/InvalidScopeError.md +1 -1
- package/docs/api/classes/MissingUserContextError.md +1 -1
- package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
- package/docs/api/classes/PermissionDeniedError.md +1 -1
- package/docs/api/classes/PublicErrorBoundary.md +1 -1
- package/docs/api/classes/RBACAuditManager.md +1 -1
- package/docs/api/classes/RBACCache.md +1 -1
- package/docs/api/classes/RBACEngine.md +9 -8
- package/docs/api/classes/RBACError.md +1 -1
- package/docs/api/classes/RBACNotInitializedError.md +1 -1
- package/docs/api/classes/SecureSupabaseClient.md +1 -1
- package/docs/api/classes/StorageUtils.md +1 -1
- package/docs/api/enums/FileCategory.md +1 -1
- package/docs/api/interfaces/AggregateConfig.md +1 -1
- package/docs/api/interfaces/ButtonProps.md +1 -1
- package/docs/api/interfaces/CardProps.md +1 -1
- package/docs/api/interfaces/ColorPalette.md +1 -1
- package/docs/api/interfaces/ColorShade.md +1 -1
- package/docs/api/interfaces/DataAccessRecord.md +1 -1
- package/docs/api/interfaces/DataRecord.md +1 -1
- package/docs/api/interfaces/DataTableAction.md +1 -1
- package/docs/api/interfaces/DataTableColumn.md +1 -1
- package/docs/api/interfaces/DataTableProps.md +1 -1
- package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
- package/docs/api/interfaces/EmptyStateConfig.md +1 -1
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
- package/docs/api/interfaces/FileDisplayProps.md +1 -1
- package/docs/api/interfaces/FileMetadata.md +1 -1
- package/docs/api/interfaces/FileReference.md +1 -1
- package/docs/api/interfaces/FileSizeLimits.md +1 -1
- package/docs/api/interfaces/FileUploadOptions.md +1 -1
- package/docs/api/interfaces/FileUploadProps.md +1 -1
- package/docs/api/interfaces/FooterProps.md +1 -1
- package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
- package/docs/api/interfaces/InputProps.md +1 -1
- package/docs/api/interfaces/LabelProps.md +1 -1
- package/docs/api/interfaces/LoginFormProps.md +1 -1
- package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
- package/docs/api/interfaces/NavigationContextType.md +1 -1
- package/docs/api/interfaces/NavigationGuardProps.md +1 -1
- package/docs/api/interfaces/NavigationItem.md +1 -1
- package/docs/api/interfaces/NavigationMenuProps.md +1 -1
- package/docs/api/interfaces/NavigationProviderProps.md +1 -1
- package/docs/api/interfaces/Organisation.md +1 -1
- package/docs/api/interfaces/OrganisationContextType.md +1 -1
- package/docs/api/interfaces/OrganisationMembership.md +1 -1
- package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
- package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
- package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
- package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
- package/docs/api/interfaces/PageAccessRecord.md +1 -1
- package/docs/api/interfaces/PagePermissionContextType.md +1 -1
- package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
- package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
- package/docs/api/interfaces/PaletteData.md +1 -1
- package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
- package/docs/api/interfaces/ProtectedRouteProps.md +1 -1
- package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
- package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
- package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
- package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
- package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
- package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
- package/docs/api/interfaces/RBACConfig.md +19 -8
- package/docs/api/interfaces/RBACLogger.md +5 -5
- package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
- package/docs/api/interfaces/RouteAccessRecord.md +1 -1
- package/docs/api/interfaces/RouteConfig.md +1 -1
- package/docs/api/interfaces/SecureDataContextType.md +1 -1
- package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
- package/docs/api/interfaces/StorageConfig.md +1 -1
- package/docs/api/interfaces/StorageFileInfo.md +1 -1
- package/docs/api/interfaces/StorageFileMetadata.md +1 -1
- package/docs/api/interfaces/StorageListOptions.md +1 -1
- package/docs/api/interfaces/StorageListResult.md +1 -1
- package/docs/api/interfaces/StorageUploadOptions.md +1 -1
- package/docs/api/interfaces/StorageUploadResult.md +1 -1
- package/docs/api/interfaces/StorageUrlOptions.md +1 -1
- package/docs/api/interfaces/StyleImport.md +1 -1
- package/docs/api/interfaces/SwitchProps.md +1 -1
- package/docs/api/interfaces/ToastActionElement.md +1 -1
- package/docs/api/interfaces/ToastProps.md +1 -1
- package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
- package/docs/api/interfaces/UsePublicFileDisplayOptions.md +1 -1
- package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
- package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
- package/docs/api/interfaces/UseResolvedScopeOptions.md +1 -1
- package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
- package/docs/api/interfaces/UserEventAccess.md +1 -1
- package/docs/api/interfaces/UserMenuProps.md +1 -1
- package/docs/api/interfaces/UserProfile.md +1 -1
- package/docs/api/modules.md +21 -20
- package/docs/documentation-index.md +0 -2
- package/docs/rbac/README.md +114 -38
- package/docs/rbac/api-reference.md +63 -16
- package/docs/rbac/getting-started.md +16 -16
- package/docs/rbac/quick-start.md +110 -35
- package/docs/rbac/troubleshooting.md +125 -2
- package/package.json +1 -1
- package/src/components/NavigationMenu/NavigationMenu.test.tsx +38 -4
- package/src/components/NavigationMenu/NavigationMenu.tsx +71 -6
- package/src/rbac/api.test.ts +2 -2
- package/src/rbac/api.ts +2 -1
- package/src/rbac/components/PagePermissionGuard.tsx +21 -38
- package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +1 -1
- package/src/rbac/config.ts +2 -0
- package/src/rbac/engine.ts +15 -5
- package/src/rbac/security.ts +1 -1
- package/dist/chunk-3TKTL5AZ.js.map +0 -1
- package/dist/chunk-F6TSYCKP.js.map +0 -1
- package/dist/chunk-P72NKAT5.js.map +0 -1
- package/docs/rbac/breaking-changes-v3.md +0 -222
- package/docs/rbac/migration-guide.md +0 -260
- /package/dist/{DataTable-5HITILXS.js.map → DataTable-D3BK2FCN.js.map} +0 -0
- /package/dist/{api-5I3E47G2.js.map → api-PIE4JRFS.js.map} +0 -0
- /package/dist/{chunk-S4D3Z723.js.map → chunk-AWK2FAUN.js.map} +0 -0
- /package/dist/{chunk-WWNOVFDC.js.map → chunk-HADXAZT3.js.map} +0 -0
- /package/dist/{chunk-UW2DE6JX.js.map → chunk-HGZSO43Y.js.map} +0 -0
package/docs/api/modules.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
[@jmruthers/pace-core - v0.5.
|
|
1
|
+
[@jmruthers/pace-core - v0.5.110](README.md) / Exports
|
|
2
2
|
|
|
3
|
-
# @jmruthers/pace-core - v0.5.
|
|
3
|
+
# @jmruthers/pace-core - v0.5.110
|
|
4
4
|
|
|
5
5
|
**`File`**
|
|
6
6
|
|
|
@@ -499,7 +499,7 @@ ___
|
|
|
499
499
|
|
|
500
500
|
#### Defined in
|
|
501
501
|
|
|
502
|
-
[packages/core/src/rbac/config.ts:
|
|
502
|
+
[packages/core/src/rbac/config.ts:14](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/config.ts#L14)
|
|
503
503
|
|
|
504
504
|
___
|
|
505
505
|
|
|
@@ -5027,7 +5027,7 @@ const accessLevel = await getAccessLevel({
|
|
|
5027
5027
|
|
|
5028
5028
|
#### Defined in
|
|
5029
5029
|
|
|
5030
|
-
[packages/core/src/rbac/api.ts:
|
|
5030
|
+
[packages/core/src/rbac/api.ts:89](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/api.ts#L89)
|
|
5031
5031
|
|
|
5032
5032
|
___
|
|
5033
5033
|
|
|
@@ -5066,7 +5066,7 @@ const permissions = await getPermissionMap({
|
|
|
5066
5066
|
|
|
5067
5067
|
#### Defined in
|
|
5068
5068
|
|
|
5069
|
-
[packages/core/src/rbac/api.ts:
|
|
5069
|
+
[packages/core/src/rbac/api.ts:115](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/api.ts#L115)
|
|
5070
5070
|
|
|
5071
5071
|
___
|
|
5072
5072
|
|
|
@@ -5088,7 +5088,7 @@ ___
|
|
|
5088
5088
|
|
|
5089
5089
|
#### Defined in
|
|
5090
5090
|
|
|
5091
|
-
[packages/core/src/rbac/api.ts:
|
|
5091
|
+
[packages/core/src/rbac/api.ts:123](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/api.ts#L123)
|
|
5092
5092
|
|
|
5093
5093
|
___
|
|
5094
5094
|
|
|
@@ -5110,7 +5110,7 @@ ___
|
|
|
5110
5110
|
|
|
5111
5111
|
#### Defined in
|
|
5112
5112
|
|
|
5113
|
-
[packages/core/src/rbac/api.ts:
|
|
5113
|
+
[packages/core/src/rbac/api.ts:131](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/api.ts#L131)
|
|
5114
5114
|
|
|
5115
5115
|
___
|
|
5116
5116
|
|
|
@@ -5145,7 +5145,7 @@ const canManage = await isPermitted({
|
|
|
5145
5145
|
|
|
5146
5146
|
#### Defined in
|
|
5147
5147
|
|
|
5148
|
-
[packages/core/src/rbac/api.ts:
|
|
5148
|
+
[packages/core/src/rbac/api.ts:155](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/api.ts#L155)
|
|
5149
5149
|
|
|
5150
5150
|
___
|
|
5151
5151
|
|
|
@@ -5169,7 +5169,7 @@ Promise resolving to permission result
|
|
|
5169
5169
|
|
|
5170
5170
|
#### Defined in
|
|
5171
5171
|
|
|
5172
|
-
[packages/core/src/rbac/api.ts:
|
|
5172
|
+
[packages/core/src/rbac/api.ts:176](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/api.ts#L176)
|
|
5173
5173
|
|
|
5174
5174
|
___
|
|
5175
5175
|
|
|
@@ -5193,7 +5193,7 @@ Promise<boolean> - True if user has permission
|
|
|
5193
5193
|
|
|
5194
5194
|
#### Defined in
|
|
5195
5195
|
|
|
5196
|
-
[packages/core/src/rbac/api.ts:
|
|
5196
|
+
[packages/core/src/rbac/api.ts:209](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/api.ts#L209)
|
|
5197
5197
|
|
|
5198
5198
|
___
|
|
5199
5199
|
|
|
@@ -5221,7 +5221,7 @@ Promise resolving to true if user has any permission
|
|
|
5221
5221
|
|
|
5222
5222
|
#### Defined in
|
|
5223
5223
|
|
|
5224
|
-
[packages/core/src/rbac/api.ts:
|
|
5224
|
+
[packages/core/src/rbac/api.ts:219](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/api.ts#L219)
|
|
5225
5225
|
|
|
5226
5226
|
___
|
|
5227
5227
|
|
|
@@ -5249,7 +5249,7 @@ Promise resolving to true if user has all permissions
|
|
|
5249
5249
|
|
|
5250
5250
|
#### Defined in
|
|
5251
5251
|
|
|
5252
|
-
[packages/core/src/rbac/api.ts:
|
|
5252
|
+
[packages/core/src/rbac/api.ts:247](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/api.ts#L247)
|
|
5253
5253
|
|
|
5254
5254
|
___
|
|
5255
5255
|
|
|
@@ -5467,7 +5467,7 @@ React element with permission enforcement
|
|
|
5467
5467
|
|
|
5468
5468
|
#### Defined in
|
|
5469
5469
|
|
|
5470
|
-
[packages/core/src/rbac/components/PagePermissionGuard.tsx:
|
|
5470
|
+
[packages/core/src/rbac/components/PagePermissionGuard.tsx:533](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/components/PagePermissionGuard.tsx#L533)
|
|
5471
5471
|
|
|
5472
5472
|
___
|
|
5473
5473
|
|
|
@@ -5662,7 +5662,7 @@ ___
|
|
|
5662
5662
|
|
|
5663
5663
|
#### Defined in
|
|
5664
5664
|
|
|
5665
|
-
[packages/core/src/rbac/config.ts:
|
|
5665
|
+
[packages/core/src/rbac/config.ts:112](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/config.ts#L112)
|
|
5666
5666
|
|
|
5667
5667
|
___
|
|
5668
5668
|
|
|
@@ -5676,7 +5676,7 @@ ___
|
|
|
5676
5676
|
|
|
5677
5677
|
#### Defined in
|
|
5678
5678
|
|
|
5679
|
-
[packages/core/src/rbac/config.ts:
|
|
5679
|
+
[packages/core/src/rbac/config.ts:117](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/config.ts#L117)
|
|
5680
5680
|
|
|
5681
5681
|
___
|
|
5682
5682
|
|
|
@@ -5690,7 +5690,7 @@ ___
|
|
|
5690
5690
|
|
|
5691
5691
|
#### Defined in
|
|
5692
5692
|
|
|
5693
|
-
[packages/core/src/rbac/config.ts:
|
|
5693
|
+
[packages/core/src/rbac/config.ts:121](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/config.ts#L121)
|
|
5694
5694
|
|
|
5695
5695
|
___
|
|
5696
5696
|
|
|
@@ -5704,7 +5704,7 @@ ___
|
|
|
5704
5704
|
|
|
5705
5705
|
#### Defined in
|
|
5706
5706
|
|
|
5707
|
-
[packages/core/src/rbac/config.ts:
|
|
5707
|
+
[packages/core/src/rbac/config.ts:125](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/config.ts#L125)
|
|
5708
5708
|
|
|
5709
5709
|
___
|
|
5710
5710
|
|
|
@@ -5718,13 +5718,13 @@ ___
|
|
|
5718
5718
|
|
|
5719
5719
|
#### Defined in
|
|
5720
5720
|
|
|
5721
|
-
[packages/core/src/rbac/config.ts:
|
|
5721
|
+
[packages/core/src/rbac/config.ts:129](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/config.ts#L129)
|
|
5722
5722
|
|
|
5723
5723
|
___
|
|
5724
5724
|
|
|
5725
5725
|
### createRBACEngine
|
|
5726
5726
|
|
|
5727
|
-
▸ **createRBACEngine**(`supabase`): [`RBACEngine`](classes/RBACEngine.md)
|
|
5727
|
+
▸ **createRBACEngine**(`supabase`, `securityConfig?`): [`RBACEngine`](classes/RBACEngine.md)
|
|
5728
5728
|
|
|
5729
5729
|
Create an RBAC engine instance
|
|
5730
5730
|
|
|
@@ -5733,6 +5733,7 @@ Create an RBAC engine instance
|
|
|
5733
5733
|
| Name | Type | Description |
|
|
5734
5734
|
| :------ | :------ | :------ |
|
|
5735
5735
|
| `supabase` | `default`\<`Database`, ``"public"``, ``"public"``, `never`, {}\> | Supabase client |
|
|
5736
|
+
| `securityConfig?` | `Partial`\<`RBACSecurityConfig`\> | Optional security configuration |
|
|
5736
5737
|
|
|
5737
5738
|
#### Returns
|
|
5738
5739
|
|
|
@@ -5742,7 +5743,7 @@ RBACEngine instance
|
|
|
5742
5743
|
|
|
5743
5744
|
#### Defined in
|
|
5744
5745
|
|
|
5745
|
-
[packages/core/src/rbac/engine.ts:
|
|
5746
|
+
[packages/core/src/rbac/engine.ts:601](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/engine.ts#L601)
|
|
5746
5747
|
|
|
5747
5748
|
___
|
|
5748
5749
|
|
|
@@ -54,8 +54,6 @@ This index mirrors the folder layout in `packages/core/docs/` so teams can quick
|
|
|
54
54
|
- [Advanced patterns](./rbac/advanced-patterns.md)
|
|
55
55
|
- [Super admin guide](./rbac/super-admin-guide.md)
|
|
56
56
|
- [RLS integration](./rbac/rbac-rls-integration.md)
|
|
57
|
-
- [Migration guide](./rbac/migration-guide.md)
|
|
58
|
-
- [Breaking changes v3](./rbac/breaking-changes-v3.md)
|
|
59
57
|
- [Troubleshooting](./rbac/troubleshooting.md)
|
|
60
58
|
- [Legacy RLS README](./rbac/README-rbac-rls-integration.md)
|
|
61
59
|
|
package/docs/rbac/README.md
CHANGED
|
@@ -12,10 +12,35 @@ The PACE Core RBAC (Role-Based Access Control) system provides comprehensive per
|
|
|
12
12
|
|
|
13
13
|
## 🚨 Critical Rules (Follow These or It Won't Work)
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
**MANDATORY Setup Steps (in order):**
|
|
16
|
+
|
|
17
|
+
1. **Call `setupRBAC(supabase)` FIRST** - Must be called before any RBAC components or hooks
|
|
18
|
+
```typescript
|
|
19
|
+
// In main.tsx or App.tsx
|
|
20
|
+
import { setupRBAC } from '@jmruthers/pace-core/rbac';
|
|
21
|
+
setupRBAC(supabase); // Must be BEFORE rendering App
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
2. **Wrap app with providers** in exact order:
|
|
25
|
+
```tsx
|
|
26
|
+
<UnifiedAuthProvider supabaseClient={supabase} appName={APP_NAME}>
|
|
27
|
+
<OrganisationProvider>
|
|
28
|
+
<YourApp />
|
|
29
|
+
</OrganisationProvider>
|
|
30
|
+
</UnifiedAuthProvider>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
3. **Use `PagePermissionGuard` for ALL pages** - This is the ONLY correct way to protect pages
|
|
34
|
+
```tsx
|
|
35
|
+
<PagePermissionGuard pageName="dashboard" operation="read">
|
|
36
|
+
<DashboardContent />
|
|
37
|
+
</PagePermissionGuard>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
4. **Database must be configured** - App, pages, and permissions must exist in database
|
|
41
|
+
5. **User must have organisation role** - Users need roles in `rbac_organisation_roles` table
|
|
42
|
+
6. **App name must match exactly** - Environment variable must match `rbac_apps.name` (case-sensitive)
|
|
43
|
+
7. **Never query RBAC tables directly** - Always use `PagePermissionGuard` or RBAC API functions
|
|
19
44
|
|
|
20
45
|
## 🚀 Quick Start
|
|
21
46
|
|
|
@@ -179,34 +204,58 @@ function App() {
|
|
|
179
204
|
}
|
|
180
205
|
```
|
|
181
206
|
|
|
182
|
-
### 2.
|
|
207
|
+
### 2. Protect Pages with PagePermissionGuard
|
|
208
|
+
|
|
209
|
+
**⚠️ CRITICAL: Always use `PagePermissionGuard` for page-level access. This is the ONLY way to ensure permissions are checked correctly.**
|
|
183
210
|
|
|
184
211
|
```tsx
|
|
185
212
|
import { PagePermissionGuard } from '@jmruthers/pace-core/rbac';
|
|
186
213
|
|
|
187
|
-
function
|
|
214
|
+
function UsersPage() {
|
|
188
215
|
return (
|
|
189
|
-
<
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
>
|
|
195
|
-
<
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
216
|
+
<PagePermissionGuard
|
|
217
|
+
pageName="users"
|
|
218
|
+
operation="read"
|
|
219
|
+
fallback={<div>You don't have permission to view this page</div>}
|
|
220
|
+
>
|
|
221
|
+
<div>
|
|
222
|
+
<h1>User Management</h1>
|
|
223
|
+
|
|
224
|
+
{/* Multiple operations on same page */}
|
|
225
|
+
<PagePermissionGuard
|
|
226
|
+
pageName="users"
|
|
227
|
+
operation="create"
|
|
228
|
+
fallback={null}
|
|
229
|
+
>
|
|
230
|
+
<AddUserButton />
|
|
231
|
+
</PagePermissionGuard>
|
|
232
|
+
|
|
233
|
+
<PagePermissionGuard
|
|
234
|
+
pageName="users"
|
|
235
|
+
operation="update"
|
|
236
|
+
fallback={null}
|
|
237
|
+
>
|
|
238
|
+
<EditUserButtons />
|
|
239
|
+
</PagePermissionGuard>
|
|
240
|
+
|
|
241
|
+
<PagePermissionGuard
|
|
242
|
+
pageName="users"
|
|
243
|
+
operation="delete"
|
|
244
|
+
fallback={null}
|
|
245
|
+
>
|
|
246
|
+
<DeleteUserButtons />
|
|
247
|
+
</PagePermissionGuard>
|
|
248
|
+
</div>
|
|
249
|
+
</PagePermissionGuard>
|
|
206
250
|
);
|
|
207
251
|
}
|
|
208
252
|
```
|
|
209
253
|
|
|
254
|
+
**Important**:
|
|
255
|
+
- `pageName` must match the `page_name` in `rbac_app_pages` table
|
|
256
|
+
- `operation` can be: `read`, `create`, `update`, or `delete`
|
|
257
|
+
- Permission checked in database is: `{operation}:page.{pageName}` (e.g., `read:page.users`)
|
|
258
|
+
|
|
210
259
|
### 3. Protect Components
|
|
211
260
|
|
|
212
261
|
```tsx
|
|
@@ -230,24 +279,51 @@ function AdminPanel() {
|
|
|
230
279
|
The RBAC system uses **page-level permissions** with the format: `{operation}:page.{pageName}`
|
|
231
280
|
|
|
232
281
|
### Operations
|
|
233
|
-
- `read` - View page content
|
|
282
|
+
- `read` - View page content (required for `PagePermissionGuard` with `operation="read"`)
|
|
234
283
|
- `create` - Create new content on page
|
|
235
284
|
- `update` - Modify existing content on page
|
|
236
285
|
- `delete` - Remove content from page
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
- `
|
|
286
|
+
|
|
287
|
+
### Page-Level Permission Format
|
|
288
|
+
|
|
289
|
+
When you use `PagePermissionGuard` with:
|
|
290
|
+
```tsx
|
|
291
|
+
<PagePermissionGuard pageName="dashboard" operation="read">
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
The system checks for permission: `read:page.dashboard` in the database.
|
|
295
|
+
|
|
296
|
+
### Database Structure
|
|
297
|
+
|
|
298
|
+
Permissions are stored in `rbac_page_permissions` table with:
|
|
299
|
+
- `app_page_id` - Links to `rbac_app_pages` table
|
|
300
|
+
- `operation` - One of: `read`, `create`, `update`, `delete`
|
|
301
|
+
- `role_name` - User's role (e.g., `org_admin`, `leader`, `member`)
|
|
302
|
+
- `allowed` - Boolean (`true` if user has permission, `false` otherwise)
|
|
303
|
+
- `organisation_id` - Organisation context (must match user's organisation)
|
|
304
|
+
|
|
305
|
+
### Examples
|
|
306
|
+
|
|
307
|
+
If you have a page named `"users"` and check `operation="read"`:
|
|
308
|
+
- System checks: `read:page.users` permission
|
|
309
|
+
- Database query looks in `rbac_page_permissions` for matching `operation='read'` and `page_name='users'`
|
|
310
|
+
- Permission is granted if user's role has `allowed=true` for that page, operation, and organisation
|
|
311
|
+
|
|
312
|
+
### Complete Example
|
|
313
|
+
|
|
314
|
+
```sql
|
|
315
|
+
-- Database setup for a "users" page with read permission for org_admin role
|
|
316
|
+
INSERT INTO rbac_page_permissions (app_page_id, operation, role_name, allowed, organisation_id)
|
|
317
|
+
VALUES (
|
|
318
|
+
(SELECT id FROM rbac_app_pages WHERE page_name = 'users'),
|
|
319
|
+
'read',
|
|
320
|
+
'org_admin',
|
|
321
|
+
true,
|
|
322
|
+
'your-organisation-id'::uuid
|
|
323
|
+
);
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
This allows users with `org_admin` role to access `<PagePermissionGuard pageName="users" operation="read">`.
|
|
251
327
|
|
|
252
328
|
## 🔒 Security Features
|
|
253
329
|
|