@jmruthers/pace-core 0.5.135 → 0.5.137
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/{DataTable-A36PJG6N.js → DataTable-6M4L6BI2.js} +26 -13
- package/dist/{DataTable-C7GaRZye.d.ts → DataTable-CWAZZcXC.d.ts} +1 -1
- package/dist/{PublicLoadingSpinner-CUAnTvcg.d.ts → EventLogo-rFL_kRjk.d.ts} +123 -135
- package/dist/{UnifiedAuthProvider-BVKmQd9u.d.ts → UnifiedAuthProvider-DJxGTftH.d.ts} +1 -1
- package/dist/{UnifiedAuthProvider-CQDZRJIS.js → UnifiedAuthProvider-XIQQ7LVU.js} +5 -5
- package/dist/{api-TNIBJWLM.js → api-45XYYO2A.js} +4 -3
- package/dist/{audit-T36HM7IM.js → audit-64X3VJXB.js} +3 -2
- package/dist/{chunk-F64FFPOZ.js → chunk-22WKWKRX.js} +26 -20
- package/dist/chunk-22WKWKRX.js.map +1 -0
- package/dist/{chunk-VZ5OR6HD.js → chunk-4C7EXCAR.js} +62 -150
- package/dist/chunk-4C7EXCAR.js.map +1 -0
- package/dist/{chunk-PYUXFQJ3.js → chunk-56XJ3TU6.js} +2 -2
- package/dist/chunk-56XJ3TU6.js.map +1 -0
- package/dist/{chunk-CTJRBUX2.js → chunk-6LAAY47Q.js} +2 -2
- package/dist/{chunk-UJI6WSMD.js → chunk-7QCC6MCP.js} +90 -3
- package/dist/chunk-7QCC6MCP.js.map +1 -0
- package/dist/{chunk-66C4BSAY.js → chunk-ANBQRTPX.js} +9 -2
- package/dist/chunk-ANBQRTPX.js.map +1 -0
- package/dist/{chunk-CQZU6TFE.js → chunk-BCIBECNB.js} +100 -62
- package/dist/chunk-BCIBECNB.js.map +1 -0
- package/dist/{chunk-GKHF54DI.js → chunk-BESYRHQM.js} +10 -4
- package/dist/chunk-BESYRHQM.js.map +1 -0
- package/dist/chunk-BJPBT3CU.js +21 -0
- package/dist/chunk-BJPBT3CU.js.map +1 -0
- package/dist/{chunk-BYXRHAIF.js → chunk-BLCXZEYF.js} +23 -14
- package/dist/chunk-BLCXZEYF.js.map +1 -0
- package/dist/{chunk-WP5I5GLN.js → chunk-BVYWGZVV.js} +112 -97
- package/dist/chunk-BVYWGZVV.js.map +1 -0
- package/dist/{chunk-GEVIB2UB.js → chunk-ERISIBYU.js} +14 -5
- package/dist/chunk-ERISIBYU.js.map +1 -0
- package/dist/{chunk-O3NWNXDY.js → chunk-FMUCXFII.js} +2 -2
- package/dist/chunk-FMUCXFII.js.map +1 -0
- package/dist/{chunk-GVDR7WNV.js → chunk-HAWZXGR2.js} +334 -614
- package/dist/chunk-HAWZXGR2.js.map +1 -0
- package/dist/{chunk-ZV77RZMU.js → chunk-INQLMHPF.js} +2 -2
- package/dist/chunk-JISYG63F.js +70 -0
- package/dist/chunk-JISYG63F.js.map +1 -0
- package/dist/{chunk-HMNOSGVA.js → chunk-KYRHUBIU.js} +576 -767
- package/dist/chunk-KYRHUBIU.js.map +1 -0
- package/dist/{chunk-M6DDYFUD.js → chunk-LS353YLY.js} +19 -16
- package/dist/chunk-LS353YLY.js.map +1 -0
- package/dist/{chunk-TGIY2AR2.js → chunk-MA6EPSGZ.js} +4 -3
- package/dist/{chunk-TGIY2AR2.js.map → chunk-MA6EPSGZ.js.map} +1 -1
- package/dist/chunk-OWAG3GSU.js +58 -0
- package/dist/chunk-OWAG3GSU.js.map +1 -0
- package/dist/{chunk-JCQZ6LA7.js → chunk-Q5QRDWKI.js} +9 -3
- package/dist/chunk-Q5QRDWKI.js.map +1 -0
- package/dist/chunk-S5OFRT4M.js +94 -0
- package/dist/chunk-S5OFRT4M.js.map +1 -0
- package/dist/{chunk-3DBFLLLU.js → chunk-SBVILCCA.js} +14 -9
- package/dist/chunk-SBVILCCA.js.map +1 -0
- package/dist/{chunk-ZYZCRSBD.js → chunk-T6JN6LH6.js} +16 -11
- package/dist/chunk-T6JN6LH6.js.map +1 -0
- package/dist/chunk-XDNLUEXI.js +138 -0
- package/dist/chunk-XDNLUEXI.js.map +1 -0
- package/dist/{chunk-3CG5L6RN.js → chunk-YCWDTTUK.js} +90 -75
- package/dist/chunk-YCWDTTUK.js.map +1 -0
- package/dist/{chunk-5F3NDPJV.js → chunk-ZZ2SS7NI.js} +10 -5
- package/dist/chunk-ZZ2SS7NI.js.map +1 -0
- package/dist/components.d.ts +7 -287
- package/dist/components.js +27 -157
- package/dist/components.js.map +1 -1
- package/dist/{file-reference-C9isKNPn.d.ts → file-reference-C6Gkn77H.d.ts} +1 -1
- package/dist/{formatting-DFcCxUEk.d.ts → formatting-CvUXy2mF.d.ts} +1 -1
- package/dist/hooks.d.ts +3 -3
- package/dist/hooks.js +21 -16
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +101 -9
- package/dist/index.js +44 -31
- package/dist/index.js.map +1 -1
- package/dist/providers.d.ts +1 -1
- package/dist/providers.js +4 -4
- package/dist/rbac/index.js +12 -12
- package/dist/schema-DTDZQe2u.d.ts +28 -0
- package/dist/styles/index.js +2 -1
- package/dist/theming/runtime.d.ts +2 -19
- package/dist/theming/runtime.js +2 -1
- package/dist/{types-D5rqZQXk.d.ts → types-Dfz9dmVH.d.ts} +12 -1
- package/dist/types.d.ts +153 -4
- package/dist/types.js +51 -16
- package/dist/types.js.map +1 -1
- package/dist/{useInactivityTracker-MRUU55XI.js → useInactivityTracker-TO6ZOF35.js} +3 -2
- package/dist/{usePublicRouteParams-Dyt1tzI9.d.ts → usePublicRouteParams-B7PabvuH.d.ts} +1 -1
- package/dist/utils.d.ts +221 -173
- package/dist/utils.js +185 -225
- package/dist/utils.js.map +1 -1
- package/dist/validation.d.ts +24 -115
- package/dist/validation.js +19 -474
- package/dist/validation.js.map +1 -1
- package/docs/api/classes/ColumnFactory.md +1 -1
- package/docs/api/classes/ErrorBoundary.md +6 -6
- 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 +6 -6
- package/docs/api/classes/RBACCache.md +1 -1
- package/docs/api/classes/RBACEngine.md +7 -7
- 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 +4 -4
- package/docs/api/interfaces/BadgeProps.md +27 -0
- 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 +29 -4
- package/docs/api/interfaces/DataAccessRecord.md +9 -9
- package/docs/api/interfaces/DataRecord.md +1 -1
- package/docs/api/interfaces/DataTableAction.md +18 -18
- package/docs/api/interfaces/DataTableColumn.md +61 -1
- package/docs/api/interfaces/DataTableProps.md +1 -1
- package/docs/api/interfaces/DataTableToolbarButton.md +7 -7
- package/docs/api/interfaces/EmptyStateConfig.md +5 -5
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +14 -14
- package/docs/api/interfaces/EventAppRoleData.md +1 -1
- package/docs/api/interfaces/EventLogoProps.md +152 -0
- package/docs/api/interfaces/ExportColumn.md +1 -1
- package/docs/api/interfaces/ExportOptions.md +8 -8
- package/docs/api/interfaces/FileDisplayProps.md +15 -15
- 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 +10 -10
- package/docs/api/interfaces/NavigationContextType.md +9 -9
- package/docs/api/interfaces/NavigationGuardProps.md +10 -10
- 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 +27 -27
- package/docs/api/interfaces/PaceLoginPageProps.md +4 -4
- package/docs/api/interfaces/PageAccessRecord.md +8 -8
- package/docs/api/interfaces/PagePermissionContextType.md +8 -8
- package/docs/api/interfaces/PagePermissionGuardProps.md +11 -11
- package/docs/api/interfaces/PagePermissionProviderProps.md +7 -7
- package/docs/api/interfaces/PaletteData.md +4 -4
- package/docs/api/interfaces/PermissionEnforcerProps.md +11 -11
- package/docs/api/interfaces/ProtectedRouteProps.md +6 -6
- 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/RevokeEventAppRoleParams.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterContextType.md +8 -8
- package/docs/api/interfaces/RoleBasedRouterProps.md +10 -10
- package/docs/api/interfaces/RoleManagementResult.md +1 -1
- package/docs/api/interfaces/RouteAccessRecord.md +10 -10
- package/docs/api/interfaces/RouteConfig.md +10 -10
- package/docs/api/interfaces/SecureDataContextType.md +9 -9
- package/docs/api/interfaces/SecureDataProviderProps.md +8 -8
- package/docs/api/interfaces/SessionRestorationLoaderProps.md +21 -0
- 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 +53 -53
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +13 -13
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +9 -9
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +8 -8
- package/docs/api/interfaces/UsePublicEventOptions.md +3 -3
- package/docs/api/interfaces/UsePublicEventReturn.md +5 -5
- package/docs/api/interfaces/UsePublicFileDisplayOptions.md +4 -4
- package/docs/api/interfaces/UsePublicFileDisplayReturn.md +9 -9
- package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
- package/docs/api/interfaces/UseResolvedScopeOptions.md +4 -4
- package/docs/api/interfaces/UseResolvedScopeReturn.md +4 -4
- 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 +591 -220
- package/docs/api-reference/components.md +106 -26
- package/docs/architecture/README.md +0 -3
- package/docs/implementation-guides/data-tables.md +277 -13
- package/docs/implementation-guides/forms.md +1 -16
- package/docs/implementation-guides/permission-enforcement.md +8 -2
- package/docs/styles/README.md +0 -2
- package/examples/README.md +30 -14
- package/examples/STRUCTURE.md +125 -0
- package/examples/components 2/DataTable/HierarchicalActionsExample.tsx +421 -0
- package/examples/components 2/DataTable/HierarchicalExample.tsx +475 -0
- package/examples/components 2/DataTable/InitialPageSizeExample.tsx +177 -0
- package/examples/components 2/DataTable/PerformanceExample.tsx +506 -0
- package/examples/components 2/DataTable/index.ts +13 -0
- package/examples/components 2/Dialog/BasicHtmlTest.tsx +55 -0
- package/examples/components 2/Dialog/DebugHtmlExample.tsx +68 -0
- package/examples/components 2/Dialog/HtmlDialogExample.tsx +202 -0
- package/examples/components 2/Dialog/ScrollableDialogExample.tsx +290 -0
- package/examples/components 2/Dialog/SimpleHtmlTest.tsx +61 -0
- package/examples/components 2/Dialog/SmartDialogExample.tsx +322 -0
- package/examples/components 2/Dialog/index.ts +15 -0
- package/examples/components 2/index.ts +11 -0
- package/examples/features/index.ts +12 -0
- package/{src/examples → examples/features/public-pages}/CorrectPublicPageImplementation.tsx +14 -17
- package/{src/examples → examples/features/public-pages}/PublicEventPage.tsx +14 -27
- package/{src/examples → examples/features/public-pages}/PublicPageApp.tsx +15 -28
- package/{src/examples → examples/features/public-pages}/PublicPageUsageExample.tsx +8 -10
- package/examples/features/public-pages/index.ts +14 -0
- package/examples/features/rbac/CompleteRBACExample.tsx +324 -0
- package/examples/features/rbac/EventBasedApp.tsx +239 -0
- package/examples/features/rbac/PermissionExample.tsx +151 -0
- package/examples/features/rbac/index.ts +13 -0
- package/examples/index.ts +11 -3
- package/package.json +30 -19
- package/src/__tests__/TEST_STANDARD.md +92 -0
- package/src/components/Alert/Alert.tsx +1 -1
- package/src/components/Avatar/Avatar.tsx +1 -1
- package/src/components/Badge/Badge.test.tsx +314 -0
- package/src/components/Badge/Badge.tsx +304 -0
- package/src/components/Badge/index.ts +3 -0
- package/src/components/Button/Button.tsx +1 -1
- package/src/components/Card/Card.tsx +1 -1
- package/src/components/Checkbox/Checkbox.tsx +1 -1
- package/src/components/DataTable/DataTable.test.tsx +1 -1
- package/src/components/DataTable/DataTable.tsx +1 -30
- package/src/components/DataTable/__tests__/DataTable.grouping-aggregation.test.tsx +562 -0
- package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +217 -0
- package/src/components/DataTable/__tests__/styles.test.ts +3 -3
- package/src/components/DataTable/components/ActionButtons.tsx +0 -15
- package/src/components/DataTable/components/ColumnFilter.tsx +8 -4
- package/src/components/DataTable/components/DataTableBody.tsx +461 -0
- package/src/components/DataTable/components/DataTableCore.tsx +4 -185
- package/src/components/DataTable/components/DataTableErrorBoundary.tsx +1 -1
- package/src/components/DataTable/components/DataTableModals.tsx +1 -27
- package/src/components/DataTable/components/DraggableColumnHeader.tsx +144 -0
- package/src/components/DataTable/components/EditableRow.tsx +1 -1
- package/src/components/DataTable/components/FilterRow.tsx +9 -3
- package/src/components/DataTable/components/ImportModal.tsx +2 -14
- package/src/components/DataTable/components/PaginationControls.tsx +2 -1
- package/src/components/DataTable/components/UnifiedTableBody.tsx +109 -82
- package/src/components/DataTable/components/VirtualizedDataTable.tsx +513 -0
- package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +14 -68
- package/src/components/DataTable/components/__tests__/ActionButtons.test.tsx +1 -1
- package/src/components/DataTable/components/__tests__/ColumnFilter.test.tsx +62 -0
- package/src/components/DataTable/components/__tests__/DataTableErrorBoundary.test.tsx +1 -1
- package/src/components/DataTable/components/__tests__/DataTableModals.test.tsx +1 -1
- package/src/components/DataTable/components/__tests__/FilterRow.test.tsx +43 -0
- package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +1 -1
- package/src/components/DataTable/core/ActionManager.ts +235 -0
- package/src/components/DataTable/core/ColumnManager.ts +205 -0
- package/src/components/DataTable/core/DataManager.ts +188 -0
- package/src/components/DataTable/core/DataTableContext.tsx +181 -0
- package/src/components/DataTable/core/LocalDataAdapter.ts +273 -0
- package/src/components/DataTable/core/PluginRegistry.ts +229 -0
- package/src/components/DataTable/core/StateManager.ts +311 -0
- package/src/components/DataTable/core/interfaces.ts +338 -0
- package/src/components/DataTable/examples/GroupingAggregationExample.tsx +273 -0
- package/src/components/DataTable/examples/HierarchicalActionsExample.tsx +1 -1
- package/src/components/DataTable/examples/__tests__/HierarchicalActionsExample.test.tsx +1 -1
- package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +1 -1
- package/src/components/DataTable/hooks/useColumnVisibilityPersistence.ts +1 -1
- package/src/components/DataTable/hooks/useDataTablePermissions.ts +2 -23
- package/src/components/DataTable/index.ts +4 -0
- package/src/components/DataTable/styles.ts +28 -7
- package/src/components/DataTable/types.ts +13 -0
- package/src/components/DataTable/utils/__tests__/columnUtils.test.ts +94 -0
- package/src/components/DataTable/utils/__tests__/exportUtils.test.ts +1 -1
- package/src/components/DataTable/utils/aggregationUtils.ts +161 -0
- package/src/components/DataTable/utils/columnUtils.ts +40 -0
- package/src/components/DataTable/utils/debugTools.ts +609 -0
- package/src/components/DataTable/utils/exportUtils.ts +1 -1
- package/src/components/DataTable/utils/flexibleImport.ts +1 -11
- package/src/components/DataTable/utils/index.ts +2 -0
- package/src/components/DataTable/utils/paginationUtils.ts +1 -1
- package/src/components/Dialog/Dialog.tsx +2 -2
- package/src/components/Dialog/utils/__tests__/safeHtml.unit.test.ts +8 -1
- package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +35 -7
- package/src/components/ErrorBoundary/ErrorBoundary.tsx +5 -4
- package/src/components/EventSelector/EventSelector.tsx +3 -2
- package/src/components/FileDisplay/FileDisplay.tsx +2 -36
- package/src/components/FileUpload/FileUpload.test.tsx +2 -2
- package/src/components/FileUpload/FileUpload.tsx +2 -2
- package/src/components/Footer/Footer.test.tsx +1 -1
- package/src/components/Footer/Footer.tsx +1 -1
- package/src/components/Form/Form.test.tsx +5 -510
- package/src/components/Form/Form.tsx +1 -1
- package/src/components/Form/FormField.tsx +1 -1
- package/src/components/Form/index.ts +0 -12
- package/src/components/Header/Header.tsx +1 -1
- package/src/components/Input/Input.tsx +1 -1
- package/src/components/Label/Label.tsx +1 -1
- package/src/components/LoginForm/LoginForm.test.tsx +1 -1
- package/src/components/LoginForm/LoginForm.tsx +1 -1
- package/src/components/NavigationMenu/NavigationMenu.test.tsx +19 -3
- package/src/components/NavigationMenu/NavigationMenu.tsx +9 -8
- package/src/components/OrganisationSelector/OrganisationSelector.tsx +4 -3
- package/src/components/PaceAppLayout/PaceAppLayout.tsx +14 -12
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.integration.test.tsx +0 -16
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.performance.test.tsx +76 -10
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.security.test.tsx +0 -1
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.unit.test.tsx +0 -9
- package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +35 -3
- package/src/components/PaceLoginPage/PaceLoginPage.tsx +14 -13
- package/src/components/PasswordReset/PasswordChangeForm.tsx +1 -1
- package/src/components/PasswordReset/index.ts +0 -2
- package/src/components/Progress/Progress.tsx +1 -1
- package/src/components/ProtectedRoute/ProtectedRoute.test.tsx +35 -8
- package/src/components/ProtectedRoute/ProtectedRoute.tsx +3 -2
- package/src/components/PublicLayout/PublicErrorBoundary.tsx +1 -1
- package/src/components/PublicLayout/PublicLoadingSpinner.tsx +1 -1
- package/src/components/PublicLayout/PublicPageContextChecker.tsx +44 -43
- package/src/components/PublicLayout/PublicPageFooter.tsx +1 -1
- package/src/components/PublicLayout/PublicPageHeader.tsx +1 -15
- package/src/components/PublicLayout/PublicPageProvider.tsx +3 -2
- package/src/components/PublicLayout/__tests__/PublicPageContextChecker.test.tsx +2 -0
- package/src/components/PublicLayout/__tests__/PublicPageFooter.test.tsx +1 -1
- package/src/components/PublicLayout/index.ts +4 -2
- package/src/components/Select/Select.test.tsx +1 -1
- package/src/components/Select/Select.tsx +21 -9
- package/src/components/{SessionRestorationLoader.tsx → SessionRestorationLoader/SessionRestorationLoader.tsx} +3 -2
- package/src/components/SessionRestorationLoader/index.ts +3 -0
- package/src/components/Switch/Switch.tsx +1 -1
- package/src/components/Table/Table.tsx +1 -1
- package/src/components/Table/__tests__/Table.test.tsx +1 -1
- package/src/components/Toast/Toast.tsx +1 -1
- package/src/components/Tooltip/Tooltip.tsx +1 -1
- package/src/components/index.ts +7 -10
- package/src/hooks/__tests__/hooks.integration.test.tsx +37 -22
- package/src/hooks/__tests__/useComponentPerformance.unit.test.tsx +33 -17
- package/src/hooks/__tests__/useDataTablePerformance.unit.test.ts +28 -3
- package/src/hooks/__tests__/useFileDisplay.unit.test.ts +36 -9
- package/src/hooks/__tests__/useFileUrl.unit.test.ts +83 -85
- package/src/hooks/__tests__/useInactivityTracker.unit.test.ts +26 -2
- package/src/hooks/__tests__/usePerformanceMonitor.unit.test.ts +19 -6
- package/src/hooks/__tests__/usePermissionCache.simple.test.ts +17 -4
- package/src/hooks/__tests__/usePermissionCache.unit.test.ts +17 -4
- package/src/hooks/__tests__/usePublicEvent.simple.test.ts +26 -6
- package/src/hooks/__tests__/usePublicFileDisplay.test.ts +16 -6
- package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +3 -3
- package/src/hooks/__tests__/useSessionRestoration.unit.test.tsx +17 -3
- package/src/hooks/public/usePublicEvent.ts +7 -6
- package/src/hooks/public/usePublicEventLogo.ts +7 -4
- package/src/hooks/public/usePublicFileDisplay.ts +6 -150
- package/src/hooks/useComponentPerformance.ts +4 -1
- package/src/hooks/useDataTablePerformance.ts +4 -3
- package/src/hooks/useEventTheme.test.ts +18 -5
- package/src/hooks/useEventTheme.ts +4 -1
- package/src/hooks/useEvents.ts +2 -0
- package/src/hooks/useFileDisplay.ts +9 -8
- package/src/hooks/useFileReference.ts +4 -1
- package/src/hooks/useFileUrl.ts +4 -1
- package/src/hooks/useInactivityTracker.ts +5 -4
- package/src/hooks/useOrganisationSecurity.test.ts +33 -12
- package/src/hooks/useOrganisationSecurity.ts +8 -7
- package/src/hooks/usePerformanceMonitor.ts +6 -3
- package/src/hooks/usePermissionCache.ts +13 -6
- package/src/hooks/useSecureDataAccess.test.ts +2 -2
- package/src/hooks/useSecureDataAccess.ts +9 -8
- package/src/hooks/useSessionRestoration.ts +4 -1
- package/src/hooks/useStorage.ts +4 -1
- package/src/index.ts +20 -7
- package/src/providers/services/AuthServiceProvider.tsx +3 -2
- package/src/providers/services/EventServiceProvider.tsx +2 -1
- package/src/providers/services/InactivityServiceProvider.tsx +2 -1
- package/src/providers/services/OrganisationServiceProvider.tsx +2 -1
- package/src/providers/services/UnifiedAuthProvider.tsx +4 -3
- package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +22 -2
- package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +24 -2
- package/src/rbac/__tests__/cache-invalidation.test.ts +20 -6
- package/src/rbac/api.ts +5 -2
- package/src/rbac/audit-enhanced.ts +6 -6
- package/src/rbac/audit.test.ts +60 -38
- package/src/rbac/audit.ts +8 -8
- package/src/rbac/cache-invalidation.ts +7 -4
- package/src/rbac/components/EnhancedNavigationMenu.tsx +11 -5
- package/src/rbac/components/NavigationGuard.tsx +7 -3
- package/src/rbac/components/NavigationProvider.tsx +6 -3
- package/src/rbac/components/PagePermissionGuard.tsx +28 -16
- package/src/rbac/components/PagePermissionProvider.tsx +4 -1
- package/src/rbac/components/PermissionEnforcer.tsx +9 -3
- package/src/rbac/components/RoleBasedRouter.tsx +3 -1
- package/src/rbac/components/SecureDataProvider.tsx +7 -3
- package/src/rbac/components/__tests__/EnhancedNavigationMenu.test.tsx +87 -61
- package/src/rbac/components/__tests__/NavigationGuard.test.tsx +83 -33
- package/src/rbac/components/__tests__/NavigationProvider.test.tsx +36 -13
- package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +2 -2
- package/src/rbac/components/__tests__/PagePermissionProvider.test.tsx +22 -8
- package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +19 -6
- package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +43 -17
- package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +42 -17
- package/src/rbac/engine.ts +15 -7
- package/src/rbac/hooks/usePermissions.ts +7 -3
- package/src/rbac/hooks/useResolvedScope.test.ts +2 -2
- package/src/rbac/hooks/useResolvedScope.ts +10 -7
- package/src/rbac/permissions.ts +5 -2
- package/src/rbac/security.test.ts +27 -16
- package/src/rbac/security.ts +5 -4
- package/src/services/AuthService.ts +22 -21
- package/src/services/EventService.ts +12 -12
- package/src/services/InactivityService.ts +5 -4
- package/src/services/OrganisationService.ts +26 -25
- package/src/services/__tests__/AuthService.test.ts +51 -19
- package/src/services/__tests__/EventService.test.ts +37 -5
- package/src/services/__tests__/InactivityService.test.ts +38 -4
- package/src/services/__tests__/OrganisationService.test.ts +3 -8
- package/src/services/base/BaseService.ts +3 -1
- package/src/styles/core.css +3 -0
- package/src/theming/__tests__/runtime.test.ts +21 -12
- package/src/theming/parseEventColours.ts +5 -19
- package/src/theming/runtime.ts +8 -4
- package/src/types/validation.ts +2 -29
- package/src/utils/__tests__/appConfig.unit.test.ts +1 -1
- package/src/utils/__tests__/audit.unit.test.ts +1 -1
- package/src/utils/__tests__/auth-utils.unit.test.ts +1 -1
- package/src/utils/__tests__/bundleAnalysis.unit.test.ts +19 -19
- package/src/utils/__tests__/cn.unit.test.ts +1 -1
- package/src/utils/__tests__/debugLogger.test.ts +1 -1
- package/src/utils/__tests__/deviceFingerprint.unit.test.ts +1 -1
- package/src/utils/__tests__/dynamicUtils.unit.test.ts +1 -1
- package/src/utils/__tests__/formatting.unit.test.ts +1 -1
- package/src/utils/__tests__/lazyLoad.unit.test.tsx +1 -1
- package/src/utils/__tests__/logger.unit.test.ts +1 -1
- package/src/utils/__tests__/organisationContext.unit.test.ts +1 -1
- package/src/utils/__tests__/performanceBenchmark.test.ts +1 -1
- package/src/utils/__tests__/performanceBudgets.unit.test.ts +1 -1
- package/src/utils/__tests__/permissionTypes.unit.test.ts +1 -1
- package/src/utils/__tests__/permissionUtils.unit.test.ts +1 -1
- package/src/utils/__tests__/sanitization.unit.test.ts +1 -1
- package/src/utils/__tests__/schemaUtils.unit.test.ts +1 -1
- package/src/utils/__tests__/secureDataAccess.unit.test.ts +1 -1
- package/src/utils/__tests__/secureErrors.unit.test.ts +33 -15
- package/src/utils/__tests__/secureStorage.unit.test.ts +1 -1
- package/src/utils/__tests__/security.unit.test.ts +40 -18
- package/src/utils/__tests__/securityMonitor.unit.test.ts +1 -1
- package/src/utils/__tests__/sessionTracking.unit.test.ts +40 -29
- package/src/utils/__tests__/validationUtils.unit.test.ts +19 -6
- package/src/utils/app/appConfig.ts +47 -0
- package/src/utils/app/appIdResolver.test.ts +497 -0
- package/src/utils/app/appIdResolver.ts +133 -0
- package/src/utils/app/appNameResolver.simple.test.ts +212 -0
- package/src/utils/app/appNameResolver.test.ts +121 -0
- package/src/utils/app/appNameResolver.ts +195 -0
- package/src/utils/audit/audit.ts +127 -0
- package/src/utils/context/organisationContext.test.ts +322 -0
- package/src/utils/context/organisationContext.ts +156 -0
- package/src/utils/context/sessionTracking.ts +125 -0
- package/src/utils/core/cn.ts +7 -0
- package/src/utils/core/debugLogger.ts +67 -0
- package/src/utils/core/logger.ts +181 -0
- package/src/utils/device/deviceFingerprint.ts +215 -0
- package/src/utils/dynamic/dynamicUtils.ts +105 -0
- package/src/utils/dynamic/lazyLoad.tsx +44 -0
- package/src/utils/file-reference/__tests__/file-reference.test.ts +788 -0
- package/src/utils/file-reference/index.ts +501 -0
- package/src/utils/formatting/formatDate.test.ts +237 -0
- package/src/utils/formatting/formatting.ts +133 -0
- package/src/utils/index.ts +39 -54
- package/src/utils/performance/bundleAnalysis.ts +129 -0
- package/src/utils/performance/performanceBenchmark.ts +64 -0
- package/src/utils/performance/performanceBudgets.ts +110 -0
- package/src/utils/permissions/permissionTypes.ts +37 -0
- package/src/utils/permissions/permissionUtils.test.ts +393 -0
- package/src/utils/permissions/permissionUtils.ts +34 -0
- package/src/utils/security/auth-utils.ts +96 -0
- package/src/utils/security/secureDataAccess.test.ts +711 -0
- package/src/utils/security/secureDataAccess.ts +377 -0
- package/src/utils/security/secureErrors.ts +82 -0
- package/src/utils/security/secureStorage.ts +244 -0
- package/src/utils/security/security.ts +159 -0
- package/src/utils/security/securityMonitor.ts +45 -0
- package/src/utils/storage/__tests__/helpers.unit.test.ts +1 -4
- package/src/utils/storage/helpers.ts +15 -8
- package/src/utils/validation/__tests__/htmlSanitization.unit.test.ts +598 -0
- package/src/{validation → utils/validation}/csrf.ts +1 -1
- package/src/utils/validation/htmlSanitization.ts +184 -0
- package/src/utils/validation/index.ts +79 -0
- package/src/utils/validation/sanitization.ts +333 -0
- package/src/{validation/schemaUtils.ts → utils/validation/schema.ts} +11 -6
- package/src/{validation → utils/validation}/sqlInjectionProtection.ts +2 -0
- package/src/utils/validation/validation.ts +111 -0
- package/src/utils/validation/validationUtils.ts +123 -0
- package/src/validation/index.ts +3 -34
- package/dist/chunk-24MKLB7U.js +0 -81
- package/dist/chunk-24MKLB7U.js.map +0 -1
- package/dist/chunk-3CG5L6RN.js.map +0 -1
- package/dist/chunk-3DBFLLLU.js.map +0 -1
- package/dist/chunk-5F3NDPJV.js.map +0 -1
- package/dist/chunk-66C4BSAY.js.map +0 -1
- package/dist/chunk-BDZUMRBD.js +0 -87
- package/dist/chunk-BDZUMRBD.js.map +0 -1
- package/dist/chunk-BYXRHAIF.js.map +0 -1
- package/dist/chunk-CDQ3PX7L.js +0 -18
- package/dist/chunk-CDQ3PX7L.js.map +0 -1
- package/dist/chunk-CQZU6TFE.js.map +0 -1
- package/dist/chunk-F64FFPOZ.js.map +0 -1
- package/dist/chunk-GEVIB2UB.js.map +0 -1
- package/dist/chunk-GKHF54DI.js.map +0 -1
- package/dist/chunk-GVDR7WNV.js.map +0 -1
- package/dist/chunk-HMNOSGVA.js.map +0 -1
- package/dist/chunk-JCQZ6LA7.js.map +0 -1
- package/dist/chunk-M6DDYFUD.js.map +0 -1
- package/dist/chunk-O3NWNXDY.js.map +0 -1
- package/dist/chunk-PYUXFQJ3.js.map +0 -1
- package/dist/chunk-UJI6WSMD.js.map +0 -1
- package/dist/chunk-VZ5OR6HD.js.map +0 -1
- package/dist/chunk-WP5I5GLN.js.map +0 -1
- package/dist/chunk-ZYZCRSBD.js.map +0 -1
- package/dist/validation-DnhrNMju.d.ts +0 -159
- package/src/components/PublicLayout/__tests__/PublicPageDebugger.test.tsx +0 -185
- package/src/validation/__tests__/common.unit.test.ts +0 -101
- package/src/validation/__tests__/csrf.unit.test.ts +0 -365
- package/src/validation/__tests__/passwordSchema.unit.test.ts +0 -203
- package/src/validation/__tests__/sanitization.unit.test.ts +0 -250
- package/src/validation/__tests__/schemaUtils.unit.test.ts +0 -451
- package/src/validation/__tests__/sqlInjectionProtection.unit.test.ts +0 -462
- package/src/validation/__tests__/user.unit.test.ts +0 -440
- package/src/validation/sanitization.ts +0 -96
- /package/dist/{DataTable-A36PJG6N.js.map → DataTable-6M4L6BI2.js.map} +0 -0
- /package/dist/{UnifiedAuthProvider-CQDZRJIS.js.map → UnifiedAuthProvider-XIQQ7LVU.js.map} +0 -0
- /package/dist/{api-TNIBJWLM.js.map → api-45XYYO2A.js.map} +0 -0
- /package/dist/{audit-T36HM7IM.js.map → audit-64X3VJXB.js.map} +0 -0
- /package/dist/{chunk-CTJRBUX2.js.map → chunk-6LAAY47Q.js.map} +0 -0
- /package/dist/{chunk-ZV77RZMU.js.map → chunk-INQLMHPF.js.map} +0 -0
- /package/dist/{useInactivityTracker-MRUU55XI.js.map → useInactivityTracker-TO6ZOF35.js.map} +0 -0
- /package/src/{validation → utils/validation}/common.ts +0 -0
- /package/src/{validation → utils/validation}/passwordSchema.ts +0 -0
- /package/src/{validation → utils/validation}/user.ts +0 -0
|
@@ -15,6 +15,29 @@ import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
|
15
15
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
16
16
|
import { renderWithProviders } from '../../../__tests__/helpers';
|
|
17
17
|
|
|
18
|
+
// Mock the RBAC logger - define inside factory to avoid hoisting issues
|
|
19
|
+
const mockLogger = {
|
|
20
|
+
debug: vi.fn(),
|
|
21
|
+
error: vi.fn(),
|
|
22
|
+
warn: vi.fn(),
|
|
23
|
+
info: vi.fn(),
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
vi.mock('../../config', () => ({
|
|
27
|
+
getRBACLogger: vi.fn(() => mockLogger),
|
|
28
|
+
getRBACConfig: vi.fn(() => ({
|
|
29
|
+
debug: true,
|
|
30
|
+
logLevel: 'debug',
|
|
31
|
+
developmentMode: true,
|
|
32
|
+
audit: {
|
|
33
|
+
enabled: true,
|
|
34
|
+
logLevel: 'debug'
|
|
35
|
+
}
|
|
36
|
+
})),
|
|
37
|
+
isDebugMode: vi.fn(() => true),
|
|
38
|
+
isDevelopmentMode: vi.fn(() => true),
|
|
39
|
+
}));
|
|
40
|
+
|
|
18
41
|
import {
|
|
19
42
|
SecureDataProvider,
|
|
20
43
|
SecureDataProviderProps,
|
|
@@ -97,18 +120,14 @@ const TestWrapper: React.FC<{
|
|
|
97
120
|
};
|
|
98
121
|
|
|
99
122
|
describe('SecureDataProvider', () => {
|
|
100
|
-
let consoleSpy: any;
|
|
101
|
-
|
|
102
123
|
beforeEach(() => {
|
|
103
|
-
|
|
104
|
-
vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
124
|
+
vi.clearAllMocks();
|
|
105
125
|
|
|
106
126
|
mockUseUnifiedAuth.mockReturnValue(mockUser);
|
|
107
127
|
mockValidateContext.mockImplementation(() => {});
|
|
108
128
|
});
|
|
109
129
|
|
|
110
130
|
afterEach(() => {
|
|
111
|
-
consoleSpy.mockRestore();
|
|
112
131
|
vi.clearAllMocks();
|
|
113
132
|
});
|
|
114
133
|
|
|
@@ -284,40 +303,47 @@ describe('SecureDataProvider', () => {
|
|
|
284
303
|
});
|
|
285
304
|
|
|
286
305
|
describe('Audit Logging', () => {
|
|
287
|
-
it('should log strict mode status when enabled', () => {
|
|
306
|
+
it('should log strict mode status when enabled', async () => {
|
|
288
307
|
renderWithProviders(
|
|
289
308
|
<TestWrapper providerProps={{ strictMode: true, auditLog: true }}>
|
|
290
309
|
<TestComponent />
|
|
291
310
|
</TestWrapper>
|
|
292
311
|
);
|
|
293
312
|
|
|
294
|
-
|
|
295
|
-
expect.
|
|
296
|
-
|
|
313
|
+
await waitFor(() => {
|
|
314
|
+
expect(mockLogger.debug).toHaveBeenCalledWith(
|
|
315
|
+
'Strict mode enabled - all data access attempts will be logged and enforced'
|
|
316
|
+
);
|
|
317
|
+
});
|
|
297
318
|
});
|
|
298
319
|
|
|
299
|
-
it('should log RLS enforcement when enabled', () => {
|
|
320
|
+
it('should log RLS enforcement when enabled', async () => {
|
|
300
321
|
renderWithProviders(
|
|
301
322
|
<TestWrapper providerProps={{ enforceRLS: true, auditLog: true }}>
|
|
302
323
|
<TestComponent />
|
|
303
324
|
</TestWrapper>
|
|
304
325
|
);
|
|
305
326
|
|
|
306
|
-
|
|
307
|
-
expect.
|
|
308
|
-
|
|
327
|
+
await waitFor(() => {
|
|
328
|
+
expect(mockLogger.debug).toHaveBeenCalledWith(
|
|
329
|
+
'RLS enforcement enabled - all queries will include organisation context'
|
|
330
|
+
);
|
|
331
|
+
});
|
|
309
332
|
});
|
|
310
333
|
|
|
311
|
-
it('should not log when audit logging is disabled', () => {
|
|
334
|
+
it('should not log when audit logging is disabled', async () => {
|
|
312
335
|
renderWithProviders(
|
|
313
336
|
<TestWrapper providerProps={{ strictMode: true, auditLog: false }}>
|
|
314
337
|
<TestComponent />
|
|
315
338
|
</TestWrapper>
|
|
316
339
|
);
|
|
317
340
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
341
|
+
// Wait a bit to ensure useEffect has run
|
|
342
|
+
await waitFor(() => {
|
|
343
|
+
expect(mockLogger.debug).not.toHaveBeenCalledWith(
|
|
344
|
+
'Strict mode enabled - all data access attempts will be logged and enforced'
|
|
345
|
+
);
|
|
346
|
+
}, { timeout: 100 });
|
|
321
347
|
});
|
|
322
348
|
});
|
|
323
349
|
|
|
@@ -15,6 +15,29 @@ import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
|
15
15
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
16
16
|
import { renderWithProviders } from '../../../__tests__/helpers';
|
|
17
17
|
|
|
18
|
+
// Mock the RBAC logger - define inside factory to avoid hoisting issues
|
|
19
|
+
const mockLogger = {
|
|
20
|
+
debug: vi.fn(),
|
|
21
|
+
error: vi.fn(),
|
|
22
|
+
warn: vi.fn(),
|
|
23
|
+
info: vi.fn(),
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
vi.mock('../../config', () => ({
|
|
27
|
+
getRBACLogger: vi.fn(() => mockLogger),
|
|
28
|
+
getRBACConfig: vi.fn(() => ({
|
|
29
|
+
debug: true,
|
|
30
|
+
logLevel: 'debug',
|
|
31
|
+
developmentMode: true,
|
|
32
|
+
audit: {
|
|
33
|
+
enabled: true,
|
|
34
|
+
logLevel: 'debug'
|
|
35
|
+
}
|
|
36
|
+
})),
|
|
37
|
+
isDebugMode: vi.fn(() => true),
|
|
38
|
+
isDevelopmentMode: vi.fn(() => true),
|
|
39
|
+
}));
|
|
40
|
+
|
|
18
41
|
import {
|
|
19
42
|
SecureDataProvider,
|
|
20
43
|
SecureDataProviderProps,
|
|
@@ -97,18 +120,14 @@ const TestWrapper: React.FC<{
|
|
|
97
120
|
};
|
|
98
121
|
|
|
99
122
|
describe('SecureDataProvider', () => {
|
|
100
|
-
let consoleSpy: any;
|
|
101
|
-
|
|
102
123
|
beforeEach(() => {
|
|
103
|
-
|
|
104
|
-
vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
124
|
+
vi.clearAllMocks();
|
|
105
125
|
|
|
106
126
|
mockUseUnifiedAuth.mockReturnValue(mockUser);
|
|
107
127
|
mockValidateContext.mockImplementation(() => {});
|
|
108
128
|
});
|
|
109
129
|
|
|
110
130
|
afterEach(() => {
|
|
111
|
-
consoleSpy.mockRestore();
|
|
112
131
|
vi.clearAllMocks();
|
|
113
132
|
});
|
|
114
133
|
|
|
@@ -284,40 +303,46 @@ describe('SecureDataProvider', () => {
|
|
|
284
303
|
});
|
|
285
304
|
|
|
286
305
|
describe('Audit Logging', () => {
|
|
287
|
-
it('should log strict mode status when enabled', () => {
|
|
306
|
+
it('should log strict mode status when enabled', async () => {
|
|
288
307
|
renderWithProviders(
|
|
289
308
|
<TestWrapper providerProps={{ strictMode: true, auditLog: true }}>
|
|
290
309
|
<TestComponent />
|
|
291
310
|
</TestWrapper>
|
|
292
311
|
);
|
|
293
312
|
|
|
294
|
-
|
|
295
|
-
expect.
|
|
296
|
-
|
|
313
|
+
await waitFor(() => {
|
|
314
|
+
expect(mockLogger.debug).toHaveBeenCalledWith(
|
|
315
|
+
'Strict mode enabled - all data access attempts will be logged and enforced'
|
|
316
|
+
);
|
|
317
|
+
});
|
|
297
318
|
});
|
|
298
319
|
|
|
299
|
-
it('should log RLS enforcement when enabled', () => {
|
|
320
|
+
it('should log RLS enforcement when enabled', async () => {
|
|
300
321
|
renderWithProviders(
|
|
301
322
|
<TestWrapper providerProps={{ enforceRLS: true, auditLog: true }}>
|
|
302
323
|
<TestComponent />
|
|
303
324
|
</TestWrapper>
|
|
304
325
|
);
|
|
305
326
|
|
|
306
|
-
|
|
307
|
-
expect.
|
|
308
|
-
|
|
327
|
+
await waitFor(() => {
|
|
328
|
+
expect(mockLogger.debug).toHaveBeenCalledWith(
|
|
329
|
+
'RLS enforcement enabled - all queries will include organisation context'
|
|
330
|
+
);
|
|
331
|
+
});
|
|
309
332
|
});
|
|
310
333
|
|
|
311
|
-
it('should not log when audit logging is disabled', () => {
|
|
334
|
+
it('should not log when audit logging is disabled', async () => {
|
|
312
335
|
renderWithProviders(
|
|
313
336
|
<TestWrapper providerProps={{ strictMode: true, auditLog: false }}>
|
|
314
337
|
<TestComponent />
|
|
315
338
|
</TestWrapper>
|
|
316
339
|
);
|
|
317
340
|
|
|
318
|
-
|
|
319
|
-
expect.
|
|
320
|
-
|
|
341
|
+
await waitFor(() => {
|
|
342
|
+
expect(mockLogger.debug).not.toHaveBeenCalledWith(
|
|
343
|
+
'Strict mode enabled - all data access attempts will be logged and enforced'
|
|
344
|
+
);
|
|
345
|
+
});
|
|
321
346
|
});
|
|
322
347
|
});
|
|
323
348
|
|
package/src/rbac/engine.ts
CHANGED
|
@@ -39,6 +39,7 @@ import {
|
|
|
39
39
|
DEFAULT_SECURITY_CONFIG,
|
|
40
40
|
RBACSecurityConfig
|
|
41
41
|
} from './security';
|
|
42
|
+
import { getRBACLogger } from './config';
|
|
42
43
|
|
|
43
44
|
/**
|
|
44
45
|
* Simplified RBAC Engine
|
|
@@ -199,7 +200,8 @@ export class RBACEngine {
|
|
|
199
200
|
});
|
|
200
201
|
|
|
201
202
|
if (error) {
|
|
202
|
-
|
|
203
|
+
const logger = getRBACLogger();
|
|
204
|
+
logger.error('RPC error:', error);
|
|
203
205
|
|
|
204
206
|
const category = categorizeError(error);
|
|
205
207
|
const eventType = mapErrorCategoryToSecurityEventType(category);
|
|
@@ -272,7 +274,8 @@ export class RBACEngine {
|
|
|
272
274
|
});
|
|
273
275
|
|
|
274
276
|
// Fail securely - deny access on error
|
|
275
|
-
|
|
277
|
+
const logger = getRBACLogger();
|
|
278
|
+
logger.error('Permission check failed:', error);
|
|
276
279
|
return false;
|
|
277
280
|
}
|
|
278
281
|
}
|
|
@@ -460,7 +463,8 @@ export class RBACEngine {
|
|
|
460
463
|
});
|
|
461
464
|
|
|
462
465
|
if (error) {
|
|
463
|
-
|
|
466
|
+
const logger = getRBACLogger();
|
|
467
|
+
logger.error('Failed to resolve app context:', error);
|
|
464
468
|
return null;
|
|
465
469
|
}
|
|
466
470
|
|
|
@@ -478,7 +482,8 @@ export class RBACEngine {
|
|
|
478
482
|
hasAccess: appData.has_access !== false,
|
|
479
483
|
};
|
|
480
484
|
} catch (error) {
|
|
481
|
-
|
|
485
|
+
const logger = getRBACLogger();
|
|
486
|
+
logger.error('Unexpected error resolving app context:', error);
|
|
482
487
|
return null;
|
|
483
488
|
}
|
|
484
489
|
}
|
|
@@ -502,7 +507,8 @@ export class RBACEngine {
|
|
|
502
507
|
});
|
|
503
508
|
|
|
504
509
|
if (error) {
|
|
505
|
-
|
|
510
|
+
const logger = getRBACLogger();
|
|
511
|
+
logger.error('Failed to load role context:', error);
|
|
506
512
|
return result;
|
|
507
513
|
}
|
|
508
514
|
|
|
@@ -526,7 +532,8 @@ export class RBACEngine {
|
|
|
526
532
|
|
|
527
533
|
return result;
|
|
528
534
|
} catch (error) {
|
|
529
|
-
|
|
535
|
+
const logger = getRBACLogger();
|
|
536
|
+
logger.error('Unexpected error loading role context:', error);
|
|
530
537
|
return result;
|
|
531
538
|
}
|
|
532
539
|
}
|
|
@@ -597,7 +604,8 @@ export class RBACEngine {
|
|
|
597
604
|
|
|
598
605
|
return page?.id || pageId;
|
|
599
606
|
} catch (error) {
|
|
600
|
-
|
|
607
|
+
const logger = getRBACLogger();
|
|
608
|
+
logger.warn('Failed to resolve page name to UUID:', { pageId, appId, error });
|
|
601
609
|
return pageId;
|
|
602
610
|
}
|
|
603
611
|
}
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
isPermitted,
|
|
22
22
|
isPermittedCached
|
|
23
23
|
} from '../api';
|
|
24
|
+
import { getRBACLogger } from '../config';
|
|
24
25
|
|
|
25
26
|
/**
|
|
26
27
|
* Hook to get user's permissions in a scope
|
|
@@ -104,7 +105,8 @@ export function usePermissions(userId: UUID, scope: Scope) {
|
|
|
104
105
|
} catch (err) {
|
|
105
106
|
// On error, keep existing permissions but set error state
|
|
106
107
|
// This prevents the UI from losing all items when there's a transient error
|
|
107
|
-
|
|
108
|
+
const logger = getRBACLogger();
|
|
109
|
+
logger.error('Failed to fetch permissions:', err);
|
|
108
110
|
setError(err instanceof Error ? err : new Error('Failed to fetch permissions'));
|
|
109
111
|
// Don't clear permissions on error - keep what we had
|
|
110
112
|
} finally {
|
|
@@ -171,7 +173,8 @@ export function usePermissions(userId: UUID, scope: Scope) {
|
|
|
171
173
|
} catch (err) {
|
|
172
174
|
// On error, keep existing permissions but set error state
|
|
173
175
|
// This prevents the UI from losing all items when there's a transient error
|
|
174
|
-
|
|
176
|
+
const logger = getRBACLogger();
|
|
177
|
+
logger.error('Failed to refetch permissions:', err);
|
|
175
178
|
setError(err instanceof Error ? err : new Error('Failed to fetch permissions'));
|
|
176
179
|
// Don't clear permissions on error - keep what we had
|
|
177
180
|
} finally {
|
|
@@ -295,7 +298,8 @@ export function useCan(
|
|
|
295
298
|
|
|
296
299
|
setCan(result);
|
|
297
300
|
} catch (err) {
|
|
298
|
-
|
|
301
|
+
const logger = getRBACLogger();
|
|
302
|
+
logger.error('Permission check error:', { permission, error: err });
|
|
299
303
|
setError(err instanceof Error ? err : new Error('Failed to check permission'));
|
|
300
304
|
setCan(false);
|
|
301
305
|
} finally {
|
|
@@ -19,12 +19,12 @@ vi.mock('../utils/eventContext', () => ({
|
|
|
19
19
|
createScopeFromEvent: vi.fn(),
|
|
20
20
|
}));
|
|
21
21
|
|
|
22
|
-
vi.mock('../../utils/appNameResolver', () => ({
|
|
22
|
+
vi.mock('../../utils/app/appNameResolver', () => ({
|
|
23
23
|
getCurrentAppName: vi.fn(),
|
|
24
24
|
}));
|
|
25
25
|
|
|
26
26
|
import { createScopeFromEvent } from '../utils/eventContext';
|
|
27
|
-
import { getCurrentAppName } from '../../utils/appNameResolver';
|
|
27
|
+
import { getCurrentAppName } from '../../utils/app/appNameResolver';
|
|
28
28
|
import { createMockSupabaseClient } from '../../__tests__/helpers/supabaseMock';
|
|
29
29
|
|
|
30
30
|
describe('useResolvedScope Hook', () => {
|
|
@@ -14,7 +14,10 @@ import { SupabaseClient } from '@supabase/supabase-js';
|
|
|
14
14
|
import type { Database } from '../../types/database';
|
|
15
15
|
import type { Scope } from '../types';
|
|
16
16
|
import { createScopeFromEvent } from '../utils/eventContext';
|
|
17
|
-
import { getCurrentAppName } from '../../utils/appNameResolver';
|
|
17
|
+
import { getCurrentAppName } from '../../utils/app/appNameResolver';
|
|
18
|
+
import { createLogger } from '../../utils/core/logger';
|
|
19
|
+
|
|
20
|
+
const log = createLogger('useResolvedScope');
|
|
18
21
|
|
|
19
22
|
export interface UseResolvedScopeOptions {
|
|
20
23
|
/** Supabase client instance */
|
|
@@ -133,15 +136,15 @@ export function useResolvedScope({
|
|
|
133
136
|
.single() as { data: { id: string; name: string; is_active: boolean } | null };
|
|
134
137
|
|
|
135
138
|
if (inactiveApp) {
|
|
136
|
-
|
|
139
|
+
log.error(`App "${appName}" exists but is inactive (is_active: ${inactiveApp.is_active})`);
|
|
137
140
|
} else {
|
|
138
|
-
|
|
141
|
+
log.error(`App "${appName}" not found in rbac_apps table`);
|
|
139
142
|
}
|
|
140
143
|
} else if (app) {
|
|
141
144
|
appId = app.id;
|
|
142
145
|
}
|
|
143
146
|
} catch (error) {
|
|
144
|
-
|
|
147
|
+
log.error('Unexpected error resolving app ID:', error);
|
|
145
148
|
}
|
|
146
149
|
}
|
|
147
150
|
}
|
|
@@ -179,7 +182,7 @@ export function useResolvedScope({
|
|
|
179
182
|
try {
|
|
180
183
|
const eventScope = await createScopeFromEvent(supabase, selectedEventId, appId);
|
|
181
184
|
if (!eventScope) {
|
|
182
|
-
|
|
185
|
+
log.error('Could not resolve organization from event context');
|
|
183
186
|
if (!cancelled) {
|
|
184
187
|
setResolvedScope(null);
|
|
185
188
|
setError(new Error('Could not resolve organisation from event context'));
|
|
@@ -196,7 +199,7 @@ export function useResolvedScope({
|
|
|
196
199
|
setIsLoading(false);
|
|
197
200
|
}
|
|
198
201
|
} catch (err) {
|
|
199
|
-
|
|
202
|
+
log.error('Error resolving scope from event:', err);
|
|
200
203
|
if (!cancelled) {
|
|
201
204
|
setResolvedScope(null);
|
|
202
205
|
setError(err as Error);
|
|
@@ -207,7 +210,7 @@ export function useResolvedScope({
|
|
|
207
210
|
}
|
|
208
211
|
|
|
209
212
|
// No context available
|
|
210
|
-
|
|
213
|
+
log.error('No organisation or event context available');
|
|
211
214
|
if (!cancelled) {
|
|
212
215
|
setResolvedScope(null);
|
|
213
216
|
setError(new Error('No organisation or event context available'));
|
package/src/rbac/permissions.ts
CHANGED
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { Permission } from './types';
|
|
12
|
+
import { createLogger } from '../utils/core/logger';
|
|
13
|
+
|
|
14
|
+
const log = createLogger('RBACPermissions');
|
|
12
15
|
|
|
13
16
|
// ============================================================================
|
|
14
17
|
// GLOBAL PERMISSIONS
|
|
@@ -186,8 +189,8 @@ export function isValidPermission(permission: string): permission is Permission
|
|
|
186
189
|
* @returns Empty array (function deprecated)
|
|
187
190
|
*/
|
|
188
191
|
export function getPermissionsForRole(role: string): Permission[] {
|
|
189
|
-
|
|
190
|
-
'
|
|
192
|
+
log.warn(
|
|
193
|
+
'getPermissionsForRole() is deprecated. ' +
|
|
191
194
|
'Permissions must be queried from rbac_page_permissions table. ' +
|
|
192
195
|
`Called with role: ${role}`
|
|
193
196
|
);
|
|
@@ -15,6 +15,20 @@ import {
|
|
|
15
15
|
} from './security';
|
|
16
16
|
import { UUID, Scope, Permission } from './types';
|
|
17
17
|
|
|
18
|
+
// Mock the Logger module
|
|
19
|
+
vi.mock('../utils/core/logger', () => {
|
|
20
|
+
const mockLoggerInstance = {
|
|
21
|
+
warn: vi.fn(),
|
|
22
|
+
};
|
|
23
|
+
return {
|
|
24
|
+
createLogger: vi.fn(() => mockLoggerInstance),
|
|
25
|
+
};
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// Get the mock instance after mock is set up
|
|
29
|
+
import { createLogger } from '../utils/core/logger';
|
|
30
|
+
const getMockLogger = () => createLogger('test');
|
|
31
|
+
|
|
18
32
|
describe('RBACSecurityValidator', () => {
|
|
19
33
|
describe('Permission Validation', () => {
|
|
20
34
|
it('validates correct permission format', () => {
|
|
@@ -177,7 +191,7 @@ describe('RBACSecurityValidator', () => {
|
|
|
177
191
|
// Mock import.meta.env.MODE for development using vi.stubEnv
|
|
178
192
|
vi.stubEnv('MODE', 'development');
|
|
179
193
|
|
|
180
|
-
|
|
194
|
+
vi.clearAllMocks();
|
|
181
195
|
|
|
182
196
|
RBACSecurityValidator.logSecurityEvent({
|
|
183
197
|
type: 'invalid_input',
|
|
@@ -185,8 +199,9 @@ describe('RBACSecurityValidator', () => {
|
|
|
185
199
|
details: { reason: 'Invalid permission format' }
|
|
186
200
|
});
|
|
187
201
|
|
|
188
|
-
|
|
189
|
-
|
|
202
|
+
const logger = getMockLogger();
|
|
203
|
+
expect(vi.mocked(logger.warn)).toHaveBeenCalledWith(
|
|
204
|
+
'Security event:',
|
|
190
205
|
expect.objectContaining({
|
|
191
206
|
type: 'invalid_input',
|
|
192
207
|
userId: 'user-123',
|
|
@@ -194,23 +209,21 @@ describe('RBACSecurityValidator', () => {
|
|
|
194
209
|
})
|
|
195
210
|
);
|
|
196
211
|
|
|
197
|
-
consoleSpy.mockRestore();
|
|
198
212
|
vi.unstubAllEnvs();
|
|
199
213
|
});
|
|
200
214
|
|
|
201
215
|
it('handles missing details gracefully', () => {
|
|
202
216
|
// Mock import.meta.env.MODE for development using vi.stubEnv
|
|
203
217
|
vi.stubEnv('MODE', 'development');
|
|
204
|
-
|
|
205
|
-
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
218
|
+
vi.clearAllMocks();
|
|
206
219
|
|
|
207
220
|
RBACSecurityValidator.logSecurityEvent({
|
|
208
221
|
type: 'suspicious_activity',
|
|
209
222
|
userId: 'user-123' as UUID
|
|
210
223
|
});
|
|
211
224
|
|
|
212
|
-
|
|
213
|
-
|
|
225
|
+
const logger = getMockLogger();
|
|
226
|
+
expect(vi.mocked(logger.warn)).toHaveBeenCalled();
|
|
214
227
|
vi.unstubAllEnvs();
|
|
215
228
|
});
|
|
216
229
|
});
|
|
@@ -334,7 +347,7 @@ describe('RBACSecurityMiddleware', () => {
|
|
|
334
347
|
timestamp: new Date()
|
|
335
348
|
};
|
|
336
349
|
|
|
337
|
-
|
|
350
|
+
vi.clearAllMocks();
|
|
338
351
|
|
|
339
352
|
// Make many rapid requests
|
|
340
353
|
for (let i = 0; i < 50; i++) {
|
|
@@ -343,9 +356,8 @@ describe('RBACSecurityMiddleware', () => {
|
|
|
343
356
|
|
|
344
357
|
// Note: Suspicious activity detection is not implemented yet
|
|
345
358
|
// The middleware only validates input, it doesn't detect patterns
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
consoleSpy.mockRestore();
|
|
359
|
+
const logger = getMockLogger();
|
|
360
|
+
expect(vi.mocked(logger.warn)).not.toHaveBeenCalled();
|
|
349
361
|
});
|
|
350
362
|
|
|
351
363
|
it('detects unusual permission patterns', async () => {
|
|
@@ -363,7 +375,7 @@ describe('RBACSecurityMiddleware', () => {
|
|
|
363
375
|
timestamp: new Date()
|
|
364
376
|
};
|
|
365
377
|
|
|
366
|
-
|
|
378
|
+
vi.clearAllMocks();
|
|
367
379
|
|
|
368
380
|
// Make requests with high-privilege permissions
|
|
369
381
|
for (let i = 0; i < 20; i++) {
|
|
@@ -372,9 +384,8 @@ describe('RBACSecurityMiddleware', () => {
|
|
|
372
384
|
|
|
373
385
|
// Note: Suspicious activity detection is not implemented yet
|
|
374
386
|
// The middleware only validates input, it doesn't detect patterns
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
consoleSpy.mockRestore();
|
|
387
|
+
const logger = getMockLogger();
|
|
388
|
+
expect(vi.mocked(logger.warn)).not.toHaveBeenCalled();
|
|
378
389
|
});
|
|
379
390
|
});
|
|
380
391
|
});
|
package/src/rbac/security.ts
CHANGED
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { UUID, Permission, Scope } from './types';
|
|
11
|
+
import { createLogger } from '../utils/core/logger';
|
|
12
|
+
|
|
13
|
+
const log = createLogger('RBACSecurity');
|
|
11
14
|
|
|
12
15
|
/**
|
|
13
16
|
* Security validation utilities for RBAC operations
|
|
@@ -206,10 +209,8 @@ export class RBACSecurityValidator {
|
|
|
206
209
|
severity: this.getEventSeverity(event.type),
|
|
207
210
|
};
|
|
208
211
|
|
|
209
|
-
// Log
|
|
210
|
-
|
|
211
|
-
console.warn('[RBAC Security]', securityEvent);
|
|
212
|
-
}
|
|
212
|
+
// Log security event - could be sent to security monitoring service in production
|
|
213
|
+
log.warn('Security event:', securityEvent);
|
|
213
214
|
|
|
214
215
|
// TODO: Send to security monitoring service
|
|
215
216
|
}
|