@jmruthers/pace-core 0.5.142 → 0.5.143
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/dist/{chunk-TUJSIWX6.js → chunk-VP44VQJ6.js} +18 -7
- package/dist/chunk-VP44VQJ6.js.map +1 -0
- package/dist/components.js +1 -1
- package/dist/index.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 +1 -1
- 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/BadgeProps.md +1 -1
- package/docs/api/interfaces/ButtonProps.md +1 -1
- package/docs/api/interfaces/CalendarProps.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/EventAppRoleData.md +1 -1
- package/docs/api/interfaces/EventLogoProps.md +1 -1
- package/docs/api/interfaces/ExportColumn.md +1 -1
- package/docs/api/interfaces/ExportOptions.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/GrantEventAppRoleParams.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 +1 -1
- package/docs/api/interfaces/RBACLogger.md +1 -1
- package/docs/api/interfaces/ResourcePermissions.md +1 -1
- package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
- package/docs/api/interfaces/RoleManagementResult.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/SessionRestorationLoaderProps.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/TabsContentProps.md +1 -1
- package/docs/api/interfaces/TabsListProps.md +1 -1
- package/docs/api/interfaces/TabsProps.md +1 -1
- package/docs/api/interfaces/TabsTriggerProps.md +1 -1
- package/docs/api/interfaces/TextareaProps.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/UseResourcePermissionsOptions.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 +2 -2
- package/docs/rbac/README.md +9 -4
- package/package.json +1 -1
- package/src/components/NavigationMenu/NavigationMenu.tsx +32 -7
- package/dist/chunk-TUJSIWX6.js.map +0 -1
package/docs/api/modules.md
CHANGED
package/docs/rbac/README.md
CHANGED
|
@@ -188,15 +188,18 @@ if (appConfig?.requires_event) {
|
|
|
188
188
|
|
|
189
189
|
```tsx
|
|
190
190
|
import { UnifiedAuthProvider, OrganisationProvider } from '@jmruthers/pace-core';
|
|
191
|
-
import { setRBACAppName } from '@jmruthers/pace-core/utils';
|
|
192
191
|
|
|
193
|
-
// CRITICAL:
|
|
192
|
+
// CRITICAL: App name is automatically resolved from environment variable
|
|
193
|
+
// Make sure VITE_APP_NAME (or NEXT_PUBLIC_APP_NAME) is set in your .env file
|
|
194
|
+
// Optionally, you can also call setRBACAppName() to override:
|
|
195
|
+
// import { setRBACAppName } from '@jmruthers/pace-core/utils';
|
|
196
|
+
// setRBACAppName('your-app-name');
|
|
197
|
+
|
|
194
198
|
const APP_NAME = import.meta.env.VITE_APP_NAME;
|
|
195
|
-
setRBACAppName(APP_NAME);
|
|
196
199
|
|
|
197
200
|
function App() {
|
|
198
201
|
return (
|
|
199
|
-
<UnifiedAuthProvider supabaseClient={supabase}>
|
|
202
|
+
<UnifiedAuthProvider supabaseClient={supabase} appName={APP_NAME}>
|
|
200
203
|
<OrganisationProvider>
|
|
201
204
|
<YourApp />
|
|
202
205
|
</OrganisationProvider>
|
|
@@ -205,6 +208,8 @@ function App() {
|
|
|
205
208
|
}
|
|
206
209
|
```
|
|
207
210
|
|
|
211
|
+
**Note**: The `appName` prop on `UnifiedAuthProvider` is used for other features. RBAC resolution automatically uses the environment variable (`VITE_APP_NAME` or `NEXT_PUBLIC_APP_NAME`). You can optionally call `setRBACAppName()` if you need to override the environment variable.
|
|
212
|
+
|
|
208
213
|
### 2. Protect Pages with PagePermissionGuard
|
|
209
214
|
|
|
210
215
|
**⚠️ CRITICAL: Always use `PagePermissionGuard` for page-level access. This is the ONLY way to ensure permissions are checked correctly.**
|
package/package.json
CHANGED
|
@@ -437,14 +437,24 @@ export const NavigationMenu = React.forwardRef<
|
|
|
437
437
|
logger.warn('NavigationMenu', 'useRBAC not available, permission filtering disabled');
|
|
438
438
|
}
|
|
439
439
|
|
|
440
|
+
// Get event context state for checking readiness
|
|
441
|
+
// Store the raw value to check if it's undefined (tests without event provider)
|
|
442
|
+
const eventLoadingRaw = authContext?.eventLoading;
|
|
443
|
+
const eventLoading = eventLoadingRaw ?? false;
|
|
444
|
+
const selectedEvent = authContext?.selectedEvent || null;
|
|
445
|
+
// Check org context readiness: use isContextReady if available, otherwise fall back to checking selectedOrganisation
|
|
446
|
+
// This handles both production (with isContextReady) and test scenarios (without it)
|
|
447
|
+
const orgContextReady = authContext?.isContextReady ?? (authContext?.selectedOrganisation?.id ? true : false);
|
|
448
|
+
|
|
440
449
|
// Get resolved scope for permission checks
|
|
450
|
+
// Note: Always call useResolvedScope (hooks must be called unconditionally)
|
|
451
|
+
// When filterByPermissions is false, we'll simply ignore the resolved scope
|
|
441
452
|
const { supabase } = authContext || {};
|
|
442
453
|
const { selectedOrganisation } = authContext || {};
|
|
443
|
-
const selectedEvent = authContext?.selectedEvent || null;
|
|
444
454
|
const { resolvedScope, isLoading: scopeLoading } = useResolvedScope({
|
|
445
|
-
supabase: supabase || null,
|
|
446
|
-
selectedOrganisationId: selectedOrganisation?.id || null,
|
|
447
|
-
selectedEventId: selectedEvent?.event_id || null
|
|
455
|
+
supabase: filterByPermissions ? (supabase || null) : null,
|
|
456
|
+
selectedOrganisationId: filterByPermissions ? (selectedOrganisation?.id || null) : null,
|
|
457
|
+
selectedEventId: filterByPermissions ? (selectedEvent?.event_id || null) : null
|
|
448
458
|
});
|
|
449
459
|
|
|
450
460
|
// Stabilize scope object to prevent unnecessary permission refetches
|
|
@@ -504,9 +514,18 @@ export const NavigationMenu = React.forwardRef<
|
|
|
504
514
|
// Security: If filtering is enabled but we're missing required context or still loading, show NO items
|
|
505
515
|
// This prevents security risk of showing items before permissions are verified
|
|
506
516
|
if (filterByPermissions) {
|
|
507
|
-
//
|
|
508
|
-
|
|
517
|
+
// CRITICAL: Wait for BOTH organisation AND event context to be ready before checking permissions
|
|
518
|
+
// This prevents the error "No organisation or event context available" when event context is still loading
|
|
519
|
+
const isOrgContextReady = orgContextReady && selectedOrganisation?.id;
|
|
520
|
+
// Event context is ready when not loading
|
|
521
|
+
// If eventLoadingRaw is undefined (tests without event provider), consider it ready
|
|
522
|
+
// Only wait for event context if we're actually loading events
|
|
523
|
+
const isEventContextReady = eventLoadingRaw === undefined ? true : !eventLoading;
|
|
524
|
+
|
|
525
|
+
// During initial load or when scope/context is loading, show nothing
|
|
526
|
+
if (!authContext || !rbacContext || scopeLoading || !isOrgContextReady || !isEventContextReady) {
|
|
509
527
|
// Still loading - show nothing to prevent security risk
|
|
528
|
+
// Note: We check both org and event context readiness to prevent premature permission checks
|
|
510
529
|
return [];
|
|
511
530
|
}
|
|
512
531
|
|
|
@@ -711,7 +730,13 @@ export const NavigationMenu = React.forwardRef<
|
|
|
711
730
|
scopeLoading,
|
|
712
731
|
permissionsLoading,
|
|
713
732
|
resolvedScope,
|
|
714
|
-
auditLog
|
|
733
|
+
auditLog,
|
|
734
|
+
// Add event context state to dependencies so we re-check permissions when event context becomes available
|
|
735
|
+
eventLoadingRaw,
|
|
736
|
+
eventLoading,
|
|
737
|
+
selectedEvent,
|
|
738
|
+
orgContextReady,
|
|
739
|
+
selectedOrganisation?.id
|
|
715
740
|
]);
|
|
716
741
|
|
|
717
742
|
// Log navigation access attempts for debugging
|