@jmruthers/pace-core 0.5.76 → 0.5.78
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 +8 -0
- package/dist/{RBACService-C4udt_Zp.d.ts → AuthService-Df3IozMG.d.ts} +10 -118
- package/dist/{DataTable-ntgmhO2W.d.ts → DataTable-BE0OXZKQ.d.ts} +9 -2
- package/dist/{DataTable-4GAVPIEG.js → DataTable-ETGVF4Y5.js} +50 -13
- package/dist/{PublicLoadingSpinner-BiNER8F5.d.ts → PublicLoadingSpinner-CnUaz0vG.d.ts} +5 -2
- package/dist/{UnifiedAuthProvider-Bj6YCf7c.d.ts → UnifiedAuthProvider-B391Aqum.d.ts} +42 -45
- package/dist/{UnifiedAuthProvider-3NKDOSOK.js → UnifiedAuthProvider-P5SOJAQ6.js} +4 -5
- package/dist/{api-DDMUKIUD.js → api-KG4A2X7P.js} +9 -3
- package/dist/{audit-6TOCAMKO.js → audit-65VNHEV2.js} +2 -2
- package/dist/{chunk-K34IM5CT.js → chunk-2OGV6IRV.js} +196 -626
- package/dist/chunk-2OGV6IRV.js.map +1 -0
- package/dist/{chunk-NTNILOBC.js → chunk-5BO3MI5Y.js} +4 -4
- package/dist/{chunk-XLZ7U46Z.js → chunk-CVMVPYAL.js} +9 -60
- package/dist/chunk-CVMVPYAL.js.map +1 -0
- package/dist/{chunk-URUTVZ7N.js → chunk-FL4ZCQLD.js} +2 -2
- package/dist/{chunk-LW7MMEAQ.js → chunk-FT2M4R4F.js} +2 -2
- package/dist/{chunk-5BSLGBYI.js → chunk-JCQZ6LA7.js} +2 -8
- package/dist/{chunk-5BSLGBYI.js.map → chunk-JCQZ6LA7.js.map} +1 -1
- package/dist/{chunk-KHJS6VIA.js → chunk-LRQ6RBJC.js} +157 -112
- package/dist/chunk-LRQ6RBJC.js.map +1 -0
- package/dist/{chunk-WN6XJWOS.js → chunk-MNJXXD6C.js} +274 -743
- package/dist/chunk-MNJXXD6C.js.map +1 -0
- package/dist/{chunk-KK73ZB4E.js → chunk-PTR5PMPE.js} +153 -132
- package/dist/chunk-PTR5PMPE.js.map +1 -0
- package/dist/{chunk-B2WTCLCV.js → chunk-Q7APDV6H.js} +18 -8
- package/dist/chunk-Q7APDV6H.js.map +1 -0
- package/dist/{chunk-A4FUBC7B.js → chunk-QGVSOUJ2.js} +2 -4
- package/dist/{chunk-A4FUBC7B.js.map → chunk-QGVSOUJ2.js.map} +1 -1
- package/dist/{chunk-FGMFQSHX.js → chunk-S63MFSY6.js} +500 -551
- package/dist/chunk-S63MFSY6.js.map +1 -0
- package/dist/{chunk-AFGTSUAD.js → chunk-VSOKOFRF.js} +4 -4
- package/dist/chunk-WUXCWRL6.js +20 -0
- package/dist/chunk-WUXCWRL6.js.map +1 -0
- package/dist/{chunk-Y6TXWPJO.js → chunk-YVVGHRGI.js} +105 -31
- package/dist/chunk-YVVGHRGI.js.map +1 -0
- package/dist/{chunk-M5IWZRBT.js → chunk-ZMNXIJP4.js} +2187 -981
- package/dist/chunk-ZMNXIJP4.js.map +1 -0
- package/dist/components.d.ts +6 -6
- package/dist/components.js +14 -18
- package/dist/components.js.map +1 -1
- package/dist/{database-C3Szpi5J.d.ts → database-BXAfr2Y_.d.ts} +18 -0
- package/dist/hooks.d.ts +5 -5
- package/dist/hooks.js +8 -9
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +19 -27
- package/dist/index.js +21 -29
- package/dist/index.js.map +1 -1
- package/dist/{organisation-BtshODVF.d.ts → organisation-D6qRDtbF.d.ts} +1 -1
- package/dist/providers.d.ts +7 -21
- package/dist/providers.js +3 -10
- package/dist/rbac/index.d.ts +71 -221
- package/dist/rbac/index.js +15 -16
- package/dist/{types-CGX9Vyf5.d.ts → types-BDg1mAGG.d.ts} +36 -6
- package/dist/types.d.ts +3 -3
- package/dist/types.js +61 -18
- package/dist/types.js.map +1 -1
- package/dist/{unified-CM7T0aTK.d.ts → unified-DQ4VcT7H.d.ts} +1 -1
- package/dist/{usePublicRouteParams-B-CumWRc.d.ts → usePublicRouteParams-BlgwXweB.d.ts} +3 -3
- package/dist/utils.d.ts +2 -2
- package/dist/utils.js +52 -9
- package/dist/utils.js.map +1 -1
- package/docs/CONTENT_AUDIT_REPORT.md +253 -0
- package/docs/DOCUMENTATION_AUDIT.md +172 -0
- package/docs/README.md +142 -147
- package/docs/STYLE_GUIDE.md +37 -0
- package/docs/api/classes/ColumnFactory.md +17 -17
- package/docs/api/classes/ErrorBoundary.md +1 -1
- package/docs/api/classes/InvalidScopeError.md +4 -4
- package/docs/api/classes/MissingUserContextError.md +4 -4
- package/docs/api/classes/OrganisationContextRequiredError.md +4 -4
- package/docs/api/classes/PermissionDeniedError.md +5 -5
- package/docs/api/classes/PublicErrorBoundary.md +1 -1
- package/docs/api/classes/RBACAuditManager.md +8 -8
- package/docs/api/classes/RBACCache.md +35 -5
- package/docs/api/classes/RBACEngine.md +49 -20
- package/docs/api/classes/RBACError.md +4 -4
- package/docs/api/classes/RBACNotInitializedError.md +4 -4
- 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 +4 -4
- 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 +11 -0
- package/docs/api/interfaces/DataTableAction.md +65 -29
- package/docs/api/interfaces/DataTableColumn.md +36 -23
- package/docs/api/interfaces/DataTableProps.md +80 -38
- package/docs/api/interfaces/DataTableToolbarButton.md +7 -7
- package/docs/api/interfaces/EmptyStateConfig.md +5 -5
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
- package/docs/api/interfaces/EventLogoProps.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 +11 -11
- package/docs/api/interfaces/NavigationContextType.md +9 -9
- 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 +7 -7
- 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 +16 -3
- package/docs/api/interfaces/PageAccessRecord.md +1 -1
- package/docs/api/interfaces/PagePermissionContextType.md +1 -1
- package/docs/api/interfaces/PagePermissionGuardProps.md +2 -2
- package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
- package/docs/api/interfaces/PaletteData.md +1 -1
- package/docs/api/interfaces/PermissionEnforcerProps.md +4 -4
- 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/RoleBasedRouterContextType.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
- package/docs/api/interfaces/RouteAccessRecord.md +2 -2
- package/docs/api/interfaces/RouteConfig.md +2 -2
- 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 +94 -521
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +16 -16
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventReturn.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 +11 -11
- package/docs/api/interfaces/UserMenuProps.md +1 -1
- package/docs/api/interfaces/UserProfile.md +1 -1
- package/docs/api/modules.md +251 -269
- package/docs/api-reference/components.md +193 -0
- package/docs/api-reference/hooks.md +265 -0
- package/docs/api-reference/providers.md +6 -0
- package/docs/api-reference/types.md +6 -0
- package/docs/api-reference/utilities.md +207 -0
- package/docs/architecture/README.md +6 -0
- package/docs/{database-schema-requirements.md → architecture/database-schema-requirements.md} +6 -0
- package/docs/architecture/rbac-security-architecture.md +258 -0
- package/docs/architecture/services.md +9 -1
- package/docs/best-practices/README.md +6 -0
- package/docs/best-practices/accessibility.md +6 -0
- package/docs/{common-patterns.md → best-practices/common-patterns.md} +6 -0
- package/docs/best-practices/deployment.md +6 -0
- package/docs/best-practices/performance.md +475 -2
- package/docs/best-practices/security.md +6 -0
- package/docs/best-practices/testing.md +6 -0
- package/docs/core-concepts/authentication.md +6 -0
- package/docs/core-concepts/events.md +6 -0
- package/docs/core-concepts/organisations.md +6 -0
- package/docs/core-concepts/permissions.md +6 -0
- package/docs/core-concepts/rbac-system.md +8 -0
- package/docs/documentation-index.md +121 -182
- package/docs/{consuming-app-vite-config.md → getting-started/consuming-app-vite-config.md} +6 -0
- package/docs/getting-started/documentation-index.md +40 -0
- package/docs/getting-started/examples/README.md +878 -35
- package/docs/{faq.md → getting-started/faq.md} +7 -1
- package/docs/getting-started/installation-guide.md +6 -0
- package/docs/{quick-reference.md → getting-started/quick-reference.md} +6 -0
- package/docs/implementation-guides/app-layout.md +6 -0
- package/docs/implementation-guides/authentication.md +1021 -0
- package/docs/implementation-guides/component-styling.md +6 -0
- package/docs/implementation-guides/data-tables.md +1264 -2076
- package/docs/implementation-guides/dynamic-colors.md +6 -0
- package/docs/implementation-guides/event-theming-summary.md +6 -0
- package/docs/{file-reference-system.md → implementation-guides/file-reference-system.md} +6 -0
- package/docs/implementation-guides/file-upload-storage.md +6 -0
- package/docs/implementation-guides/forms.md +6 -0
- package/docs/implementation-guides/inactivity-tracking.md +6 -0
- package/docs/implementation-guides/navigation.md +6 -0
- package/docs/implementation-guides/organisation-security.md +6 -0
- package/docs/implementation-guides/permission-enforcement.md +6 -0
- package/docs/implementation-guides/public-pages-advanced.md +6 -0
- package/docs/implementation-guides/public-pages.md +6 -0
- package/docs/migration/MIGRATION_GUIDE.md +827 -351
- package/docs/migration/README.md +7 -1
- package/docs/migration/organisation-context-timing-fix.md +6 -0
- package/docs/migration/rbac-migration.md +44 -1
- package/docs/migration/service-architecture.md +6 -0
- package/docs/migration/v0.4.15-tailwind-scanning.md +6 -0
- package/docs/migration/v0.4.16-css-first-approach.md +6 -0
- package/docs/migration/v0.4.17-source-path-fix.md +6 -0
- package/docs/rbac/README-rbac-rls-integration.md +6 -0
- package/docs/rbac/README.md +6 -0
- package/docs/rbac/advanced-patterns.md +6 -0
- package/docs/rbac/api-reference.md +7 -1
- package/docs/rbac/breaking-changes-v3.md +222 -0
- package/docs/rbac/examples/rbac-rls-integration-example.md +6 -0
- package/docs/rbac/examples.md +6 -0
- package/docs/rbac/getting-started.md +6 -0
- package/docs/rbac/migration-guide.md +260 -0
- package/docs/rbac/quick-start.md +70 -13
- package/docs/rbac/rbac-rls-integration.md +6 -0
- package/docs/rbac/super-admin-guide.md +6 -0
- package/docs/rbac/troubleshooting.md +6 -0
- package/docs/security/README.md +6 -0
- package/docs/security/checklist.md +6 -0
- package/docs/styles/README.md +7 -1
- package/docs/{usage.md → styles/usage.md} +6 -0
- package/docs/testing/README.md +6 -0
- package/docs/{visual-testing.md → testing/visual-testing.md} +6 -0
- package/docs/troubleshooting/README.md +387 -5
- package/docs/troubleshooting/cake-page-permission-guard-issue-summary.md +6 -0
- package/docs/troubleshooting/common-issues.md +6 -0
- package/docs/troubleshooting/database-view-compatibility.md +6 -0
- package/docs/troubleshooting/organisation-context-setup.md +6 -0
- package/docs/troubleshooting/react-hooks-issue-analysis.md +6 -0
- package/docs/troubleshooting/styling-issues.md +6 -0
- package/docs/troubleshooting/tailwind-content-scanning.md +6 -0
- package/package.json +1 -1
- package/src/__tests__/helpers/__tests__/test-providers.test.tsx +2 -1
- package/src/__tests__/helpers/test-providers.tsx +3 -53
- package/src/components/DataTable/DataTable.test.tsx +319 -0
- package/src/components/DataTable/DataTable.tsx +32 -11
- package/src/components/DataTable/__tests__/{DataTable.comprehensive.test.tsx → DataTable.comprehensive.test.tsx.skip} +6 -4
- package/src/components/DataTable/__tests__/{DataTable.test.tsx → DataTable.test.tsx.skip} +6 -4
- package/src/components/DataTable/__tests__/DataTableCore.test.tsx +31 -9
- package/src/components/DataTable/__tests__/a11y.basic.test.tsx +601 -0
- package/src/components/DataTable/__tests__/keyboard.test.tsx +615 -0
- package/src/components/DataTable/__tests__/pagination.modes.test.tsx +639 -0
- package/src/components/DataTable/__tests__/ssr.strict-mode.test.tsx.skip +330 -0
- package/src/components/DataTable/components/AccessDeniedPage.tsx +2 -2
- package/src/components/DataTable/components/ActionButtons.tsx +88 -104
- package/src/components/DataTable/components/DataTableCore.tsx +309 -337
- package/src/components/DataTable/components/DataTableErrorBoundary.tsx +4 -2
- package/src/components/DataTable/components/DataTableModals.tsx +22 -1
- package/src/components/DataTable/components/EditableRow.tsx +69 -84
- package/src/components/DataTable/components/EmptyState.tsx +5 -1
- package/src/components/DataTable/components/ImportModal.tsx +65 -36
- package/src/components/DataTable/components/PaginationControls.tsx +40 -100
- package/src/components/DataTable/components/UnifiedTableBody.tsx +125 -148
- package/src/components/DataTable/context/DataTableContext.tsx +1 -1
- package/src/components/DataTable/core/ColumnFactory.ts +5 -0
- package/src/components/DataTable/examples/HierarchicalActionsExample.tsx +12 -10
- package/src/components/DataTable/examples/HierarchicalExample.tsx +1 -1
- package/src/components/DataTable/examples/InitialPageSizeExample.tsx +1 -0
- package/src/components/DataTable/examples/PerformanceExample.tsx +1 -0
- package/src/components/DataTable/hooks/__tests__/useColumnOrderPersistence.test.ts +1 -5
- package/src/components/DataTable/hooks/__tests__/useColumnVisibilityPersistence.test.ts +167 -0
- package/src/components/DataTable/hooks/index.ts +7 -0
- package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +32 -15
- package/src/components/DataTable/hooks/useColumnVisibilityPersistence.ts +102 -0
- package/src/components/DataTable/hooks/useDataTableConfiguration.ts +89 -0
- package/src/components/DataTable/hooks/useDataTableDataPipeline.ts +117 -0
- package/src/components/DataTable/hooks/useDataTablePermissions.ts +71 -27
- package/src/components/DataTable/hooks/useDataTableState.ts +39 -11
- package/src/components/DataTable/hooks/useEffectiveColumnOrder.ts +33 -0
- package/src/components/DataTable/hooks/useHierarchicalState.ts +15 -1
- package/src/components/DataTable/hooks/useKeyboardNavigation.ts +447 -0
- package/src/components/DataTable/hooks/useServerSideDataEffect.ts +94 -0
- package/src/components/DataTable/hooks/useTableColumns.ts +10 -7
- package/src/components/DataTable/hooks/useTableHandlers.ts +174 -0
- package/src/components/DataTable/index.ts +12 -3
- package/src/components/DataTable/types.ts +129 -9
- package/src/components/DataTable/utils/__tests__/exportUtils.test.ts +159 -22
- package/src/components/DataTable/utils/__tests__/flexibleImport.test.ts +111 -0
- package/src/components/DataTable/utils/__tests__/rowUtils.test.ts +15 -29
- package/src/components/DataTable/utils/a11yUtils.ts +244 -0
- package/src/components/DataTable/utils/debugTools.ts +609 -0
- package/src/components/DataTable/utils/exportUtils.ts +114 -16
- package/src/components/DataTable/utils/flexibleImport.ts +202 -32
- package/src/components/DataTable/utils/hierarchicalUtils.ts +1 -1
- package/src/components/DataTable/utils/index.ts +2 -0
- package/src/components/DataTable/utils/paginationUtils.ts +350 -0
- package/src/components/DataTable/utils/rowUtils.ts +6 -5
- package/src/components/NavigationMenu/NavigationMenu.test.tsx +19 -24
- package/src/components/NavigationMenu/NavigationMenu.tsx +19 -8
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.security.test.tsx +1 -23
- package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +56 -6
- package/src/components/PaceLoginPage/PaceLoginPage.tsx +137 -13
- package/src/components/PublicLayout/__tests__/PublicPageHeader.test.tsx +1 -1
- package/src/components/Select/Select.tsx +1 -0
- package/src/components/examples/PermissionExample.tsx +173 -0
- package/src/examples/CorrectPublicPageImplementation.tsx +301 -0
- package/src/examples/PublicEventPage.tsx +274 -0
- package/src/examples/PublicPageApp.tsx +308 -0
- package/src/examples/PublicPageUsageExample.tsx +216 -0
- package/src/hooks/__tests__/useOrganisationPermissions.unit.test.tsx +12 -1
- package/src/hooks/__tests__/useOrganisationSecurity.unit.test.tsx +129 -17
- package/src/hooks/__tests__/useRBAC.unit.test.ts +151 -846
- package/src/hooks/useOrganisationPermissions.test.ts +42 -18
- package/src/hooks/useOrganisationPermissions.ts +12 -6
- package/src/hooks/useOrganisationSecurity.test.ts +138 -85
- package/src/hooks/useOrganisationSecurity.ts +41 -10
- package/src/index.ts +0 -1
- package/src/providers/AuthProvider.simplified.tsx +880 -0
- package/src/providers/UnifiedAuthProvider.test.simple.tsx +8 -8
- package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +29 -19
- package/src/providers/index.ts +0 -1
- package/src/providers/services/EventServiceProvider.tsx +19 -15
- package/src/providers/services/InactivityServiceProvider.tsx +19 -15
- package/src/providers/services/OrganisationServiceProvider.tsx +19 -15
- package/src/providers/services/UnifiedAuthProvider.tsx +156 -127
- package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +1 -1
- package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +3 -3
- package/src/rbac/README.md +1 -1
- package/src/rbac/__tests__/adapters.comprehensive.test.tsx +25 -27
- package/src/rbac/__tests__/auth-rbac-security.integration.test.tsx +313 -0
- package/src/rbac/__tests__/engine.comprehensive.test.ts +114 -348
- package/src/rbac/__tests__/rbac-engine-core-logic.test.ts +28 -110
- package/src/rbac/__tests__/rbac-engine-simplified.test.ts +33 -85
- package/src/rbac/__tests__/scenarios.user-role.test.tsx +2 -2
- package/src/rbac/adapters.tsx +26 -69
- package/src/rbac/api.test.ts +90 -27
- package/src/rbac/api.ts +61 -10
- package/src/rbac/audit.test.ts +33 -38
- package/src/rbac/audit.ts +21 -6
- package/src/rbac/cache.ts +33 -1
- package/src/rbac/components/NavigationGuard.tsx +11 -11
- package/src/rbac/components/NavigationProvider.test.tsx +11 -5
- package/src/rbac/components/NavigationProvider.tsx +37 -13
- package/src/rbac/components/PagePermissionGuard.tsx +111 -50
- package/src/rbac/components/PagePermissionProvider.tsx +5 -5
- package/src/rbac/components/PermissionEnforcer.tsx +11 -11
- package/src/rbac/components/RoleBasedRouter.tsx +5 -5
- package/src/rbac/components/SecureDataProvider.tsx +5 -5
- package/src/rbac/components/__tests__/NavigationGuard.test.tsx +8 -8
- package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +14 -14
- package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +12 -12
- package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +6 -6
- package/src/rbac/engine.test.simple.ts +19 -13
- package/src/rbac/engine.test.ts +1 -0
- package/src/rbac/engine.ts +330 -766
- package/src/rbac/errors.ts +156 -0
- package/src/rbac/hooks/usePermissions.ts +32 -10
- package/src/rbac/hooks/useRBAC.test.ts +126 -512
- package/src/rbac/hooks/useRBAC.ts +147 -193
- package/src/rbac/hooks/useResolvedScope.ts +12 -0
- package/src/rbac/index.ts +7 -4
- package/src/rbac/security.ts +109 -18
- package/src/rbac/types.ts +12 -1
- package/src/services/AuthService.ts +2 -15
- package/src/services/EventService.ts +43 -46
- package/src/services/OrganisationService.ts +51 -31
- package/src/services/__tests__/AuthService.test.ts +1 -1
- package/src/services/__tests__/EventService.test.ts +1 -1
- package/src/services/__tests__/OrganisationService.test.ts +1 -1
- package/src/services/base/BaseService.ts +8 -0
- package/src/styles/base.css +208 -0
- package/src/styles/semantic.css +24 -0
- package/src/types/database.generated.ts +7347 -0
- package/src/types/database.ts +20 -0
- package/src/utils/logger.ts +179 -0
- package/src/utils/organisationContext.ts +11 -4
- package/src/utils/storage/__tests__/helpers.unit.test.ts +6 -2
- package/dist/appNameResolver-UURKN7NF.js +0 -22
- package/dist/audit-6TOCAMKO.js.map +0 -1
- package/dist/chunk-B2WTCLCV.js.map +0 -1
- package/dist/chunk-FGMFQSHX.js.map +0 -1
- package/dist/chunk-K34IM5CT.js.map +0 -1
- package/dist/chunk-KHJS6VIA.js.map +0 -1
- package/dist/chunk-KK73ZB4E.js.map +0 -1
- package/dist/chunk-M5IWZRBT.js.map +0 -1
- package/dist/chunk-ULBI5JGB.js +0 -109
- package/dist/chunk-ULBI5JGB.js.map +0 -1
- package/dist/chunk-WN6XJWOS.js.map +0 -1
- package/dist/chunk-XLZ7U46Z.js.map +0 -1
- package/dist/chunk-Y6TXWPJO.js.map +0 -1
- package/docs/DOCUMENTATION_CHECKLIST.md +0 -281
- package/docs/TERMINOLOGY.md +0 -231
- package/docs/api/interfaces/RBACContextType.md +0 -468
- package/docs/api/interfaces/RBACProviderProps.md +0 -107
- package/docs/best-practices/performance-expansion.md +0 -473
- package/docs/breaking-changes.md +0 -179
- package/docs/consuming-app-example.md +0 -290
- package/docs/documentation-templates.md +0 -539
- package/docs/examples/navigation-menu-auth-fix.md +0 -344
- package/docs/getting-started/examples/basic-auth-app.md +0 -520
- package/docs/getting-started/examples/full-featured-app.md +0 -616
- package/docs/getting-started/quick-start.md +0 -376
- package/docs/implementation-guides/datatable-filtering.md +0 -313
- package/docs/implementation-guides/datatable-rbac-usage.md +0 -317
- package/docs/implementation-guides/hierarchical-datatable.md +0 -850
- package/docs/implementation-guides/large-datasets.md +0 -281
- package/docs/implementation-guides/performance.md +0 -403
- package/docs/migration/quick-migration-guide.md +0 -320
- package/docs/migration-guide.md +0 -193
- package/docs/migration-guides/unified-auth-provider-mandatory-timeouts.md +0 -226
- package/docs/performance/README.md +0 -551
- package/docs/style-guide.md +0 -964
- package/docs/troubleshooting/authentication-issues.md +0 -334
- package/docs/troubleshooting/debugging.md +0 -1117
- package/docs/troubleshooting/migration.md +0 -918
- package/src/__tests__/hooks/usePermissions.test.ts +0 -261
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.rbac.test.tsx +0 -574
- package/src/hooks/__tests__/ServiceHooks.test.tsx +0 -613
- package/src/hooks/services/__tests__/useServiceHooks.test.tsx +0 -137
- package/src/hooks/services/usePermissions.ts +0 -70
- package/src/hooks/services/useRBACService.ts +0 -30
- package/src/hooks/usePermissionCheck.ts +0 -150
- package/src/providers/__tests__/ServiceProviders.test.tsx +0 -477
- package/src/providers/services/RBACServiceProvider.tsx +0 -79
- package/src/rbac/__tests__/integration.authflow.test.tsx +0 -119
- package/src/rbac/__tests__/integration.navigation.test.tsx +0 -69
- package/src/rbac/__tests__/integration.securedata.test.tsx +0 -92
- package/src/rbac/__tests__/integration.smoke.test.tsx +0 -73
- package/src/rbac/providers/RBACProvider.tsx +0 -645
- package/src/rbac/providers/__tests__/RBACProvider.integration.test.tsx +0 -688
- package/src/rbac/providers/__tests__/RBACProvider.test.tsx +0 -1186
- package/src/rbac/providers/index.ts +0 -11
- package/src/services/RBACService.ts +0 -522
- package/src/services/__tests__/RBACService.test.ts +0 -492
- package/src/services/interfaces/IRBACService.ts +0 -62
- package/src/utils/appNameResolver.test 2.ts +0 -494
- /package/dist/{DataTable-4GAVPIEG.js.map → DataTable-ETGVF4Y5.js.map} +0 -0
- /package/dist/{UnifiedAuthProvider-3NKDOSOK.js.map → UnifiedAuthProvider-P5SOJAQ6.js.map} +0 -0
- /package/dist/{api-DDMUKIUD.js.map → api-KG4A2X7P.js.map} +0 -0
- /package/dist/{appNameResolver-UURKN7NF.js.map → audit-65VNHEV2.js.map} +0 -0
- /package/dist/{chunk-NTNILOBC.js.map → chunk-5BO3MI5Y.js.map} +0 -0
- /package/dist/{chunk-URUTVZ7N.js.map → chunk-FL4ZCQLD.js.map} +0 -0
- /package/dist/{chunk-LW7MMEAQ.js.map → chunk-FT2M4R4F.js.map} +0 -0
- /package/dist/{chunk-AFGTSUAD.js.map → chunk-VSOKOFRF.js.map} +0 -0
- /package/docs/{app.css.example → styles/app.css.example} +0 -0
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Public Page Usage Example
|
|
3
|
+
* @package @jmruthers/pace-core
|
|
4
|
+
* @module Examples/PublicPages
|
|
5
|
+
* @since 1.0.0
|
|
6
|
+
*
|
|
7
|
+
* A complete example showing the correct usage pattern for public pages.
|
|
8
|
+
* This example demonstrates how to properly implement public pages without
|
|
9
|
+
* authentication context conflicts.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```tsx
|
|
13
|
+
* import { PublicPageUsageExample } from '@jmruthers/pace-core/examples';
|
|
14
|
+
*
|
|
15
|
+
* function App() {
|
|
16
|
+
* return (
|
|
17
|
+
* <BrowserRouter>
|
|
18
|
+
* <Routes>
|
|
19
|
+
* <Route path="/events/:eventCode/recipe-grid-report" element={<PublicPageUsageExample />} />
|
|
20
|
+
* </Routes>
|
|
21
|
+
* </BrowserRouter>
|
|
22
|
+
* );
|
|
23
|
+
* }
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import React from 'react';
|
|
28
|
+
import {
|
|
29
|
+
PublicPageLayout,
|
|
30
|
+
PublicPageHeader,
|
|
31
|
+
PublicPageFooter,
|
|
32
|
+
EventLogo,
|
|
33
|
+
usePublicEvent,
|
|
34
|
+
usePublicRouteParams,
|
|
35
|
+
PublicLoadingSpinner,
|
|
36
|
+
PublicErrorBoundary
|
|
37
|
+
} from '../index';
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Correct usage pattern for public pages
|
|
41
|
+
*
|
|
42
|
+
* This component demonstrates the proper way to implement public pages:
|
|
43
|
+
* 1. Use usePublicRouteParams to get the eventCode from URL
|
|
44
|
+
* 2. Use usePublicEvent to fetch event data
|
|
45
|
+
* 3. Pass event data to PublicPageLayout
|
|
46
|
+
* 4. No authentication context is triggered
|
|
47
|
+
*/
|
|
48
|
+
export function PublicPageUsageExample() {
|
|
49
|
+
// Step 1: Extract event code from URL parameters
|
|
50
|
+
const { eventCode } = usePublicRouteParams({ fetchEventData: false });
|
|
51
|
+
|
|
52
|
+
// Step 2: Fetch event data using the event code
|
|
53
|
+
const { event, isLoading, error, refetch } = usePublicEvent(eventCode || '');
|
|
54
|
+
|
|
55
|
+
// Step 3: Handle loading state
|
|
56
|
+
if (isLoading) {
|
|
57
|
+
return (
|
|
58
|
+
<PublicLoadingSpinner
|
|
59
|
+
message="Loading event details..."
|
|
60
|
+
/>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Step 4: Handle error state
|
|
65
|
+
if (error) {
|
|
66
|
+
return (
|
|
67
|
+
<div className="min-h-screen bg-white flex items-center justify-center">
|
|
68
|
+
<div className="max-w-md mx-auto text-center px-4">
|
|
69
|
+
<div className="mb-6">
|
|
70
|
+
<div className="mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-red-100 mb-4">
|
|
71
|
+
<svg className="h-6 w-6 text-red-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
72
|
+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z" />
|
|
73
|
+
</svg>
|
|
74
|
+
</div>
|
|
75
|
+
<h1 className="text-2xl font-bold text-gray-900 mb-2">
|
|
76
|
+
Event Not Found
|
|
77
|
+
</h1>
|
|
78
|
+
<p className="text-gray-600 mb-6">
|
|
79
|
+
The event code "{eventCode}" is invalid or the event is not available for public viewing.
|
|
80
|
+
</p>
|
|
81
|
+
<button
|
|
82
|
+
onClick={refetch}
|
|
83
|
+
className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors"
|
|
84
|
+
>
|
|
85
|
+
Try Again
|
|
86
|
+
</button>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
</div>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Step 5: Handle missing event
|
|
94
|
+
if (!event) {
|
|
95
|
+
return (
|
|
96
|
+
<div className="min-h-screen bg-white flex items-center justify-center">
|
|
97
|
+
<div className="max-w-md mx-auto text-center px-4">
|
|
98
|
+
<h1 className="text-2xl font-bold text-gray-900 mb-4">
|
|
99
|
+
Event Not Available
|
|
100
|
+
</h1>
|
|
101
|
+
<p className="text-gray-600 mb-6">
|
|
102
|
+
This event is not available for public viewing.
|
|
103
|
+
</p>
|
|
104
|
+
<button
|
|
105
|
+
onClick={refetch}
|
|
106
|
+
className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors"
|
|
107
|
+
>
|
|
108
|
+
Try Again
|
|
109
|
+
</button>
|
|
110
|
+
</div>
|
|
111
|
+
</div>
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Step 6: Render the public page with event data
|
|
116
|
+
return (
|
|
117
|
+
<PublicErrorBoundary>
|
|
118
|
+
<PublicPageLayout eventCode={eventCode || ''} event={event}>
|
|
119
|
+
<PublicPageHeader
|
|
120
|
+
event={event}
|
|
121
|
+
eventCode={eventCode || ''}
|
|
122
|
+
title="Recipe Grid Report"
|
|
123
|
+
description="Public recipe grid report for this event"
|
|
124
|
+
/>
|
|
125
|
+
|
|
126
|
+
<main className="max-w-6xl mx-auto px-4 py-8">
|
|
127
|
+
{/* Event Overview */}
|
|
128
|
+
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8 mb-12">
|
|
129
|
+
{/* Event Information */}
|
|
130
|
+
<div className="lg:col-span-2 space-y-6">
|
|
131
|
+
<div>
|
|
132
|
+
<h2 className="text-2xl font-bold text-gray-900 mb-4">Event Information</h2>
|
|
133
|
+
<div className="bg-gray-50 rounded-lg p-6 space-y-4">
|
|
134
|
+
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
135
|
+
<div>
|
|
136
|
+
<h3 className="font-semibold text-gray-700">Date</h3>
|
|
137
|
+
<p className="text-gray-900">
|
|
138
|
+
{event.event_date ? new Date(event.event_date).toLocaleDateString('en-AU', {
|
|
139
|
+
weekday: 'long',
|
|
140
|
+
year: 'numeric',
|
|
141
|
+
month: 'long',
|
|
142
|
+
day: 'numeric'
|
|
143
|
+
}) : 'TBA'}
|
|
144
|
+
</p>
|
|
145
|
+
</div>
|
|
146
|
+
<div>
|
|
147
|
+
<h3 className="font-semibold text-gray-700">Venue</h3>
|
|
148
|
+
<p className="text-gray-900">{event.event_venue || 'TBA'}</p>
|
|
149
|
+
</div>
|
|
150
|
+
<div>
|
|
151
|
+
<h3 className="font-semibold text-gray-700">Participants</h3>
|
|
152
|
+
<p className="text-gray-900">{event.event_participants || 'TBA'}</p>
|
|
153
|
+
</div>
|
|
154
|
+
<div>
|
|
155
|
+
<h3 className="font-semibold text-gray-700">Event Code</h3>
|
|
156
|
+
<p className="text-gray-900 font-mono">{event.event_code}</p>
|
|
157
|
+
</div>
|
|
158
|
+
</div>
|
|
159
|
+
|
|
160
|
+
{event.event_news && (
|
|
161
|
+
<div>
|
|
162
|
+
<h3 className="font-semibold text-gray-700 mb-2">Event News</h3>
|
|
163
|
+
<p className="text-gray-900">{event.event_news}</p>
|
|
164
|
+
</div>
|
|
165
|
+
)}
|
|
166
|
+
</div>
|
|
167
|
+
</div>
|
|
168
|
+
</div>
|
|
169
|
+
|
|
170
|
+
{/* Event Logo */}
|
|
171
|
+
<div className="flex justify-center lg:justify-start">
|
|
172
|
+
<div className="text-center">
|
|
173
|
+
<EventLogo
|
|
174
|
+
eventId={event.event_id}
|
|
175
|
+
eventName={event.event_name}
|
|
176
|
+
organisationId={event.organisation_id}
|
|
177
|
+
size="2xl"
|
|
178
|
+
className="rounded-lg shadow-lg"
|
|
179
|
+
/>
|
|
180
|
+
<p className="mt-4 text-sm text-gray-600">Event Logo</p>
|
|
181
|
+
</div>
|
|
182
|
+
</div>
|
|
183
|
+
</div>
|
|
184
|
+
|
|
185
|
+
{/* Recipe Grid Report Content */}
|
|
186
|
+
<div className="mb-12">
|
|
187
|
+
<div className="bg-green-50 border border-green-200 rounded-lg p-6">
|
|
188
|
+
<h3 className="font-semibold text-green-900 mb-2">Recipe Grid Report</h3>
|
|
189
|
+
<p className="text-green-800">
|
|
190
|
+
This is where your recipe grid report content would go.
|
|
191
|
+
The public page is now working correctly without authentication context conflicts.
|
|
192
|
+
</p>
|
|
193
|
+
<div className="mt-4 text-sm text-green-700">
|
|
194
|
+
<p><strong>Event Code:</strong> {eventCode}</p>
|
|
195
|
+
<p><strong>Event ID:</strong> {event.event_id}</p>
|
|
196
|
+
<p><strong>Event Name:</strong> {event.event_name}</p>
|
|
197
|
+
</div>
|
|
198
|
+
</div>
|
|
199
|
+
</div>
|
|
200
|
+
|
|
201
|
+
{/* Event Footer Information */}
|
|
202
|
+
{event.event_footer && (
|
|
203
|
+
<div className="bg-gray-50 rounded-lg p-6">
|
|
204
|
+
<h3 className="font-semibold text-gray-900 mb-2">Additional Information</h3>
|
|
205
|
+
<p className="text-gray-700">{event.event_footer}</p>
|
|
206
|
+
</div>
|
|
207
|
+
)}
|
|
208
|
+
</main>
|
|
209
|
+
|
|
210
|
+
<PublicPageFooter event={event} />
|
|
211
|
+
</PublicPageLayout>
|
|
212
|
+
</PublicErrorBoundary>
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export default PublicPageUsageExample;
|
|
@@ -15,6 +15,17 @@ vi.mock('../../providers/OrganisationProvider', () => ({
|
|
|
15
15
|
useOrganisations: vi.fn(() => mockUseOrganisations)
|
|
16
16
|
}));
|
|
17
17
|
|
|
18
|
+
// Mock useOrganisationSecurity to avoid provider dependencies
|
|
19
|
+
vi.mock('../useOrganisationSecurity', () => ({
|
|
20
|
+
useOrganisationSecurity: vi.fn(() => ({
|
|
21
|
+
superAdminContext: {
|
|
22
|
+
isSuperAdmin: false,
|
|
23
|
+
hasGlobalAccess: false,
|
|
24
|
+
canManageAllOrganisations: false
|
|
25
|
+
}
|
|
26
|
+
}))
|
|
27
|
+
}));
|
|
28
|
+
|
|
18
29
|
describe('useOrganisationPermissions', () => {
|
|
19
30
|
describe('Basic functionality', () => {
|
|
20
31
|
it('should return default values when no organisation context', () => {
|
|
@@ -108,7 +119,7 @@ describe('useOrganisationPermissions', () => {
|
|
|
108
119
|
const { result } = renderHook(() => useOrganisationPermissions());
|
|
109
120
|
|
|
110
121
|
expect(result.current.isOrgAdmin).toBe(true);
|
|
111
|
-
expect(result.current.isSuperAdmin).toBe(
|
|
122
|
+
expect(result.current.isSuperAdmin).toBe(false); // Super admin requires database query, not role-based
|
|
112
123
|
expect(result.current.canModerate).toBe(true);
|
|
113
124
|
expect(result.current.canManageMembers).toBe(true);
|
|
114
125
|
expect(result.current.canManageSettings).toBe(true);
|
|
@@ -40,6 +40,20 @@ const mockUseOrganisations = {
|
|
|
40
40
|
validateOrganisationAccess: vi.fn()
|
|
41
41
|
};
|
|
42
42
|
|
|
43
|
+
// Mock Supabase client for database queries
|
|
44
|
+
const mockSupabaseQuery = {
|
|
45
|
+
select: vi.fn().mockReturnThis(),
|
|
46
|
+
eq: vi.fn().mockReturnThis(),
|
|
47
|
+
lte: vi.fn().mockReturnThis(),
|
|
48
|
+
or: vi.fn().mockReturnThis(),
|
|
49
|
+
single: vi.fn(),
|
|
50
|
+
limit: vi.fn()
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const mockSupabase = {
|
|
54
|
+
from: vi.fn().mockReturnValue(mockSupabaseQuery)
|
|
55
|
+
};
|
|
56
|
+
|
|
43
57
|
// Legacy useRBAC mock removed - global role now derived from user metadata
|
|
44
58
|
|
|
45
59
|
describe('useOrganisationSecurity', () => {
|
|
@@ -47,24 +61,49 @@ describe('useOrganisationSecurity', () => {
|
|
|
47
61
|
vi.clearAllMocks();
|
|
48
62
|
vi.mocked(useUnifiedAuth).mockReturnValue(mockUseUnifiedAuth as any);
|
|
49
63
|
vi.mocked(useOrganisations).mockReturnValue(mockUseOrganisations as any);
|
|
50
|
-
|
|
64
|
+
|
|
65
|
+
// Reset Supabase mock chain
|
|
66
|
+
mockSupabaseQuery.select.mockClear().mockReturnThis();
|
|
67
|
+
mockSupabaseQuery.eq.mockClear().mockReturnThis();
|
|
68
|
+
mockSupabaseQuery.lte.mockClear().mockReturnThis();
|
|
69
|
+
mockSupabaseQuery.or.mockClear().mockReturnThis();
|
|
70
|
+
mockSupabaseQuery.single.mockClear();
|
|
71
|
+
mockSupabaseQuery.limit.mockClear();
|
|
72
|
+
mockSupabase.from.mockClear().mockReturnValue(mockSupabaseQuery);
|
|
73
|
+
|
|
74
|
+
// Default: not a super admin
|
|
75
|
+
mockSupabaseQuery.limit.mockResolvedValue({ data: [], error: null });
|
|
76
|
+
mockSupabaseQuery.single.mockResolvedValue({ data: null, error: { message: 'No rows found' } });
|
|
51
77
|
});
|
|
52
78
|
|
|
53
79
|
describe('Super admin context', () => {
|
|
54
|
-
it('should detect super admin from user metadata', () => {
|
|
80
|
+
it('should detect super admin from user metadata', async () => {
|
|
55
81
|
const mockUser = {
|
|
56
82
|
id: 'user-123',
|
|
57
83
|
user_metadata: { globalRole: 'super_admin' },
|
|
58
84
|
app_metadata: { globalRole: 'super_admin' }
|
|
59
85
|
};
|
|
86
|
+
|
|
87
|
+
// Mock database query to return super admin role
|
|
88
|
+
mockSupabaseQuery.limit.mockResolvedValue({
|
|
89
|
+
data: [{ role: 'super_admin' }],
|
|
90
|
+
error: null
|
|
91
|
+
});
|
|
92
|
+
|
|
60
93
|
vi.mocked(useUnifiedAuth).mockReturnValue({
|
|
61
94
|
...mockUseUnifiedAuth,
|
|
62
|
-
user: mockUser
|
|
95
|
+
user: mockUser,
|
|
96
|
+
session: { access_token: 'token' },
|
|
97
|
+
supabase: mockSupabase
|
|
63
98
|
} as any);
|
|
64
99
|
|
|
65
100
|
const { result } = renderHook(() => useOrganisationSecurity());
|
|
66
101
|
|
|
67
|
-
|
|
102
|
+
// Wait for async super admin check to complete
|
|
103
|
+
await act(async () => {
|
|
104
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
105
|
+
});
|
|
106
|
+
|
|
68
107
|
expect(result.current.superAdminContext.isSuperAdmin).toBe(true);
|
|
69
108
|
expect(result.current.superAdminContext.hasGlobalAccess).toBe(true);
|
|
70
109
|
expect(result.current.superAdminContext.canManageAllOrganisations).toBe(true);
|
|
@@ -111,17 +150,26 @@ describe('useOrganisationSecurity', () => {
|
|
|
111
150
|
user_metadata: { globalRole: 'super_admin' },
|
|
112
151
|
app_metadata: { globalRole: 'super_admin' }
|
|
113
152
|
};
|
|
114
|
-
|
|
115
|
-
|
|
153
|
+
|
|
154
|
+
// Mock database query to return super admin role
|
|
155
|
+
mockSupabaseQuery.limit.mockResolvedValue({
|
|
156
|
+
data: [{ role: 'super_admin' }],
|
|
157
|
+
error: null
|
|
158
|
+
});
|
|
116
159
|
|
|
117
160
|
vi.mocked(useUnifiedAuth).mockReturnValue({
|
|
118
161
|
...mockUseUnifiedAuth,
|
|
119
162
|
user: mockUser,
|
|
120
|
-
session:
|
|
163
|
+
session: { access_token: 'token' },
|
|
121
164
|
supabase: mockSupabase
|
|
122
165
|
} as any);
|
|
123
166
|
|
|
124
167
|
const { result } = renderHook(() => useOrganisationSecurity());
|
|
168
|
+
|
|
169
|
+
// Wait for async super admin check to complete
|
|
170
|
+
await act(async () => {
|
|
171
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
172
|
+
});
|
|
125
173
|
|
|
126
174
|
const hasAccess = await result.current.validateOrganisationAccess('org-123');
|
|
127
175
|
|
|
@@ -220,18 +268,32 @@ describe('useOrganisationSecurity', () => {
|
|
|
220
268
|
});
|
|
221
269
|
|
|
222
270
|
describe('hasMinimumRole', () => {
|
|
223
|
-
it('should return true for super admin regardless of role', () => {
|
|
271
|
+
it('should return true for super admin regardless of role', async () => {
|
|
224
272
|
const mockUser = {
|
|
225
273
|
id: 'user-123',
|
|
226
274
|
user_metadata: { globalRole: 'super_admin' },
|
|
227
275
|
app_metadata: { globalRole: 'super_admin' }
|
|
228
276
|
};
|
|
277
|
+
|
|
278
|
+
// Mock database query to return super admin role
|
|
279
|
+
mockSupabaseQuery.limit.mockResolvedValue({
|
|
280
|
+
data: [{ role: 'super_admin' }],
|
|
281
|
+
error: null
|
|
282
|
+
});
|
|
283
|
+
|
|
229
284
|
vi.mocked(useUnifiedAuth).mockReturnValue({
|
|
230
285
|
...mockUseUnifiedAuth,
|
|
231
|
-
user: mockUser
|
|
286
|
+
user: mockUser,
|
|
287
|
+
session: { access_token: 'token' },
|
|
288
|
+
supabase: mockSupabase
|
|
232
289
|
} as any);
|
|
233
290
|
|
|
234
291
|
const { result } = renderHook(() => useOrganisationSecurity());
|
|
292
|
+
|
|
293
|
+
// Wait for async super admin check to complete
|
|
294
|
+
await act(async () => {
|
|
295
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
296
|
+
});
|
|
235
297
|
|
|
236
298
|
expect(result.current.hasMinimumRole('org_admin')).toBe(true);
|
|
237
299
|
expect(result.current.hasMinimumRole('member')).toBe(true);
|
|
@@ -280,18 +342,32 @@ describe('useOrganisationSecurity', () => {
|
|
|
280
342
|
});
|
|
281
343
|
|
|
282
344
|
describe('canAccessChildOrganisations', () => {
|
|
283
|
-
it('should return true for super admin', () => {
|
|
345
|
+
it('should return true for super admin', async () => {
|
|
284
346
|
const mockUser = {
|
|
285
347
|
id: 'user-123',
|
|
286
348
|
user_metadata: { globalRole: 'super_admin' },
|
|
287
349
|
app_metadata: { globalRole: 'super_admin' }
|
|
288
350
|
};
|
|
351
|
+
|
|
352
|
+
// Mock database query to return super admin role
|
|
353
|
+
mockSupabaseQuery.limit.mockResolvedValue({
|
|
354
|
+
data: [{ role: 'super_admin' }],
|
|
355
|
+
error: null
|
|
356
|
+
});
|
|
357
|
+
|
|
289
358
|
vi.mocked(useUnifiedAuth).mockReturnValue({
|
|
290
359
|
...mockUseUnifiedAuth,
|
|
291
|
-
user: mockUser
|
|
360
|
+
user: mockUser,
|
|
361
|
+
session: { access_token: 'token' },
|
|
362
|
+
supabase: mockSupabase
|
|
292
363
|
} as any);
|
|
293
364
|
|
|
294
365
|
const { result } = renderHook(() => useOrganisationSecurity());
|
|
366
|
+
|
|
367
|
+
// Wait for async super admin check to complete
|
|
368
|
+
await act(async () => {
|
|
369
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
370
|
+
});
|
|
295
371
|
|
|
296
372
|
expect(result.current.canAccessChildOrganisations()).toBe(true);
|
|
297
373
|
});
|
|
@@ -344,15 +420,26 @@ describe('useOrganisationSecurity', () => {
|
|
|
344
420
|
user_metadata: { globalRole: 'super_admin' },
|
|
345
421
|
app_metadata: { globalRole: 'super_admin' }
|
|
346
422
|
};
|
|
347
|
-
|
|
423
|
+
|
|
424
|
+
// Mock database query to return super admin role
|
|
425
|
+
mockSupabaseQuery.limit.mockResolvedValue({
|
|
426
|
+
data: [{ role: 'super_admin' }],
|
|
427
|
+
error: null
|
|
428
|
+
});
|
|
348
429
|
|
|
349
430
|
vi.mocked(useUnifiedAuth).mockReturnValue({
|
|
350
431
|
...mockUseUnifiedAuth,
|
|
351
432
|
user: mockUser,
|
|
433
|
+
session: { access_token: 'token' },
|
|
352
434
|
supabase: mockSupabase
|
|
353
435
|
} as any);
|
|
354
436
|
|
|
355
437
|
const { result } = renderHook(() => useOrganisationSecurity());
|
|
438
|
+
|
|
439
|
+
// Wait for async super admin check to complete
|
|
440
|
+
await act(async () => {
|
|
441
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
442
|
+
});
|
|
356
443
|
|
|
357
444
|
const hasPermission = await result.current.hasPermission('view_basic');
|
|
358
445
|
|
|
@@ -489,15 +576,26 @@ describe('useOrganisationSecurity', () => {
|
|
|
489
576
|
user_metadata: { globalRole: 'super_admin' },
|
|
490
577
|
app_metadata: { globalRole: 'super_admin' }
|
|
491
578
|
};
|
|
492
|
-
|
|
579
|
+
|
|
580
|
+
// Mock database query to return super admin role
|
|
581
|
+
mockSupabaseQuery.limit.mockResolvedValue({
|
|
582
|
+
data: [{ role: 'super_admin' }],
|
|
583
|
+
error: null
|
|
584
|
+
});
|
|
493
585
|
|
|
494
586
|
vi.mocked(useUnifiedAuth).mockReturnValue({
|
|
495
587
|
...mockUseUnifiedAuth,
|
|
496
588
|
user: mockUser,
|
|
589
|
+
session: { access_token: 'token' },
|
|
497
590
|
supabase: mockSupabase
|
|
498
591
|
} as any);
|
|
499
592
|
|
|
500
593
|
const { result } = renderHook(() => useOrganisationSecurity());
|
|
594
|
+
|
|
595
|
+
// Wait for async super admin check to complete
|
|
596
|
+
await act(async () => {
|
|
597
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
598
|
+
});
|
|
501
599
|
|
|
502
600
|
const permissions = await result.current.getUserPermissions();
|
|
503
601
|
|
|
@@ -511,9 +609,12 @@ describe('useOrganisationSecurity', () => {
|
|
|
511
609
|
// Mock the RBAC API
|
|
512
610
|
const { getPermissionMap } = await import('../../rbac/api');
|
|
513
611
|
const mockPermissions = {
|
|
514
|
-
'
|
|
515
|
-
'
|
|
516
|
-
'
|
|
612
|
+
'view_basic': true,
|
|
613
|
+
'view_details': true,
|
|
614
|
+
'moderate_content': true,
|
|
615
|
+
'manage_events': true,
|
|
616
|
+
'manage_members': true,
|
|
617
|
+
'manage_settings': true
|
|
517
618
|
};
|
|
518
619
|
vi.mocked(getPermissionMap).mockResolvedValue(mockPermissions);
|
|
519
620
|
|
|
@@ -757,15 +858,26 @@ describe('useOrganisationSecurity', () => {
|
|
|
757
858
|
user_metadata: { globalRole: 'super_admin' },
|
|
758
859
|
app_metadata: { globalRole: 'super_admin' }
|
|
759
860
|
};
|
|
760
|
-
|
|
861
|
+
|
|
862
|
+
// Mock database query to return super admin role
|
|
863
|
+
mockSupabaseQuery.limit.mockResolvedValue({
|
|
864
|
+
data: [{ role: 'super_admin' }],
|
|
865
|
+
error: null
|
|
866
|
+
});
|
|
761
867
|
|
|
762
868
|
vi.mocked(useUnifiedAuth).mockReturnValue({
|
|
763
869
|
...mockUseUnifiedAuth,
|
|
764
870
|
user: mockUser,
|
|
871
|
+
session: { access_token: 'token' },
|
|
765
872
|
supabase: mockSupabase
|
|
766
873
|
} as any);
|
|
767
874
|
|
|
768
875
|
const { result } = renderHook(() => useOrganisationSecurity());
|
|
876
|
+
|
|
877
|
+
// Wait for async super admin check to complete
|
|
878
|
+
await act(async () => {
|
|
879
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
880
|
+
});
|
|
769
881
|
|
|
770
882
|
const hasAccess = await result.current.validateUserAccess('other-user', 'org-123');
|
|
771
883
|
|