@jmruthers/pace-core 0.5.135 → 0.5.136
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-C7GaRZye.d.ts → DataTable-CWAZZcXC.d.ts} +1 -1
- package/dist/{DataTable-A36PJG6N.js → DataTable-CYOHOX3O.js} +25 -13
- package/dist/{PublicLoadingSpinner-CUAnTvcg.d.ts → EventLogo-801uofbR.d.ts} +51 -135
- package/dist/UnifiedAuthProvider-5E5TUNMS.js +17 -0
- package/dist/{UnifiedAuthProvider-BVKmQd9u.d.ts → UnifiedAuthProvider-DJxGTftH.d.ts} +1 -1
- package/dist/{api-TNIBJWLM.js → api-45XYYO2A.js} +4 -3
- package/dist/{audit-T36HM7IM.js → audit-64X3VJXB.js} +3 -2
- package/dist/{chunk-CTJRBUX2.js → chunk-2TWNJ46Y.js} +2 -2
- package/dist/{chunk-UJI6WSMD.js → chunk-444EZN6N.js} +3 -3
- package/dist/chunk-444EZN6N.js.map +1 -0
- package/dist/{chunk-3CG5L6RN.js → chunk-4MT5BGGL.js} +90 -73
- package/dist/chunk-4MT5BGGL.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-5DPZ5EAT.js +60 -0
- package/dist/chunk-5DPZ5EAT.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-APIBCTL2.js +670 -0
- package/dist/chunk-APIBCTL2.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-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-CQZU6TFE.js → chunk-FHWWBIHA.js} +100 -62
- package/dist/chunk-FHWWBIHA.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-HJGGOMQ6.js} +194 -518
- package/dist/chunk-HJGGOMQ6.js.map +1 -0
- package/dist/{chunk-BDZUMRBD.js → chunk-K2WWTH7O.js} +13 -6
- package/dist/chunk-K2WWTH7O.js.map +1 -0
- package/dist/{chunk-BYXRHAIF.js → chunk-L6PGMCMD.js} +23 -14
- package/dist/chunk-L6PGMCMD.js.map +1 -0
- package/dist/chunk-LMC26NLJ.js +84 -0
- package/dist/chunk-LMC26NLJ.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-ZYZCRSBD.js → chunk-LTV3XIJJ.js} +16 -11
- package/dist/chunk-LTV3XIJJ.js.map +1 -0
- package/dist/{chunk-HMNOSGVA.js → chunk-NOHEVYVX.js} +377 -666
- package/dist/chunk-NOHEVYVX.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-TGIY2AR2.js → chunk-SL2YQDR6.js} +4 -3
- package/dist/{chunk-TGIY2AR2.js.map → chunk-SL2YQDR6.js.map} +1 -1
- package/dist/{chunk-VZ5OR6HD.js → chunk-TVYPTYOY.js} +55 -179
- package/dist/chunk-TVYPTYOY.js.map +1 -0
- package/dist/{chunk-ZV77RZMU.js → chunk-XARJS7CD.js} +2 -2
- package/dist/chunk-XDNLUEXI.js +138 -0
- package/dist/chunk-XDNLUEXI.js.map +1 -0
- package/dist/{chunk-F64FFPOZ.js → chunk-YLKIDTUK.js} +26 -20
- package/dist/chunk-YLKIDTUK.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 +26 -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 +22 -16
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +101 -9
- package/dist/index.js +43 -31
- package/dist/index.js.map +1 -1
- package/dist/providers.d.ts +1 -1
- package/dist/providers.js +5 -4
- package/dist/rbac/index.js +13 -12
- 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 +2 -2
- package/dist/types.js +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 +195 -232
- package/dist/utils.js +173 -331
- package/dist/utils.js.map +1 -1
- package/dist/{validation-DnhrNMju.d.ts → validation-8npbysjg.d.ts} +26 -8
- package/dist/validation.d.ts +261 -10
- package/dist/validation.js +82 -440
- 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/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 +514 -212
- package/docs/api-reference/components.md +106 -26
- package/docs/architecture/README.md +0 -2
- 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/examples/README.md +30 -14
- package/examples/STRUCTURE.md +125 -0
- package/examples/components/DataTable/HierarchicalActionsExample.tsx +421 -0
- package/examples/components/DataTable/HierarchicalExample.tsx +475 -0
- package/examples/components/DataTable/InitialPageSizeExample.tsx +177 -0
- package/examples/components/DataTable/PerformanceExample.tsx +506 -0
- package/examples/components/DataTable/index.ts +13 -0
- package/examples/components/Dialog/BasicHtmlTest.tsx +55 -0
- package/examples/components/Dialog/DebugHtmlExample.tsx +68 -0
- package/examples/components/Dialog/HtmlDialogExample.tsx +202 -0
- package/examples/components/Dialog/ScrollableDialogExample.tsx +290 -0
- package/examples/components/Dialog/SimpleHtmlTest.tsx +61 -0
- package/examples/components/Dialog/SmartDialogExample.tsx +322 -0
- package/examples/components/Dialog/index.ts +15 -0
- package/examples/components/index.ts +11 -0
- package/examples/features/index.ts +12 -0
- package/examples/{public-pages → features/public-pages}/CorrectPublicPageImplementation.tsx +1 -1
- package/examples/{public-pages → features/public-pages}/PublicEventPage.tsx +1 -1
- package/examples/{public-pages → features/public-pages}/PublicPageApp.tsx +1 -1
- package/examples/{public-pages → features/public-pages}/PublicPageUsageExample.tsx +1 -1
- package/examples/index.ts +11 -3
- package/package.json +30 -10
- package/src/components/Alert/Alert.tsx +1 -1
- package/src/components/Avatar/Avatar.tsx +1 -1
- 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__/styles.test.ts +2 -2
- package/src/components/DataTable/components/ActionButtons.tsx +0 -15
- 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/EditableRow.tsx +1 -1
- package/src/components/DataTable/components/ImportModal.tsx +2 -14
- package/src/components/DataTable/components/PaginationControls.tsx +1 -1
- package/src/components/DataTable/components/UnifiedTableBody.tsx +109 -82
- package/src/components/DataTable/components/__tests__/ActionButtons.test.tsx +1 -1
- 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__/ImportModal.test.tsx +1 -1
- 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 +1 -1
- package/src/components/DataTable/types.ts +13 -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/exportUtils.ts +1 -1
- package/src/components/DataTable/utils/flexibleImport.ts +1 -11
- package/src/components/DataTable/utils/index.ts +1 -0
- package/src/components/DataTable/utils/paginationUtils.ts +1 -1
- package/src/components/Dialog/Dialog.tsx +2 -2
- 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.tsx +1 -1
- package/src/components/Form/Form.test.tsx +4 -509
- 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.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.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 +13 -12
- 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/index.ts +4 -2
- package/src/components/Select/Select.tsx +1 -1
- 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/Toast/Toast.tsx +1 -1
- package/src/components/Tooltip/Tooltip.tsx +1 -1
- package/src/components/index.ts +4 -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__/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 +16 -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/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/{appIdResolver.test.ts → app/appIdResolver.test.ts} +28 -30
- package/src/utils/{appIdResolver.ts → app/appIdResolver.ts} +8 -5
- package/src/utils/{appNameResolver.test.ts → app/appNameResolver.test.ts} +1 -1
- package/src/utils/{appNameResolver.ts → app/appNameResolver.ts} +5 -1
- package/src/utils/{organisationContext.ts → context/organisationContext.ts} +6 -3
- package/src/utils/{sessionTracking.ts → context/sessionTracking.ts} +11 -12
- package/src/utils/{logger.ts → core/logger.ts} +4 -2
- package/src/utils/{deviceFingerprint.ts → device/deviceFingerprint.ts} +1 -1
- package/src/utils/{lazyLoad.tsx → dynamic/lazyLoad.tsx} +2 -2
- package/src/utils/{file-reference.test.ts → file-reference/__tests__/file-reference.test.ts} +5 -5
- package/src/utils/{file-reference.ts → file-reference/index.ts} +20 -38
- package/src/utils/index.ts +32 -54
- package/src/utils/{secureErrors.ts → security/secureErrors.ts} +6 -3
- package/src/utils/{security.ts → security/security.ts} +5 -2
- package/src/utils/storage/__tests__/helpers.unit.test.ts +1 -4
- package/src/utils/storage/helpers.ts +15 -8
- package/src/{components/Dialog/utils/__tests__/safeHtml.unit.test.ts → utils/validation/__tests__/htmlSanitization.unit.test.ts} +9 -15
- package/src/{validation → utils/validation}/csrf.ts +1 -1
- package/src/{components/Dialog/utils/safeHtml.ts → utils/validation/htmlSanitization.ts} +9 -10
- package/src/utils/validation/index.ts +79 -0
- package/src/utils/{sanitization.ts → validation/sanitization.ts} +71 -2
- package/src/{validation/schemaUtils.ts → utils/validation/schema.ts} +11 -6
- package/src/{validation → utils/validation}/sqlInjectionProtection.ts +2 -0
- package/src/utils/{validationUtils.ts → validation/validationUtils.ts} +4 -1
- package/src/validation/index.ts +3 -34
- package/dist/UnifiedAuthProvider-CQDZRJIS.js +0 -16
- 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.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/src/components/Dialog/README.md +0 -804
- package/src/components/Form/FormErrorSummary.tsx +0 -113
- package/src/components/Form/FormFieldset.tsx +0 -127
- package/src/components/Form/FormLiveRegion.tsx +0 -198
- package/src/components/PasswordReset/PasswordResetForm.test.tsx +0 -597
- package/src/components/PasswordReset/PasswordResetForm.tsx +0 -201
- package/src/components/PublicLayout/PublicPageDebugger.tsx +0 -104
- package/src/components/PublicLayout/PublicPageDiagnostic.tsx +0 -162
- package/src/components/PublicLayout/__tests__/PublicPageDebugger.test.tsx +0 -185
- package/src/examples/CorrectPublicPageImplementation.tsx +0 -304
- package/src/examples/PublicEventPage.tsx +0 -287
- package/src/examples/PublicPageApp.tsx +0 -321
- package/src/examples/PublicPageUsageExample.tsx +0 -218
- package/src/utils/schemaUtils.ts +0 -37
- 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-CYOHOX3O.js.map} +0 -0
- /package/dist/{UnifiedAuthProvider-CQDZRJIS.js.map → UnifiedAuthProvider-5E5TUNMS.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-2TWNJ46Y.js.map} +0 -0
- /package/dist/{chunk-ZV77RZMU.js.map → chunk-XARJS7CD.js.map} +0 -0
- /package/dist/{useInactivityTracker-MRUU55XI.js.map → useInactivityTracker-TO6ZOF35.js.map} +0 -0
- /package/examples/{public-pages → features/public-pages}/index.ts +0 -0
- /package/examples/{RBAC → features/rbac}/CompleteRBACExample.tsx +0 -0
- /package/examples/{RBAC → features/rbac}/EventBasedApp.tsx +0 -0
- /package/examples/{RBAC → features/rbac}/PermissionExample.tsx +0 -0
- /package/examples/{RBAC → features/rbac}/index.ts +0 -0
- /package/src/utils/{appConfig.ts → app/appConfig.ts} +0 -0
- /package/src/utils/{appNameResolver.simple.test.ts → app/appNameResolver.simple.test.ts} +0 -0
- /package/src/utils/{audit.ts → audit/audit.ts} +0 -0
- /package/src/utils/{organisationContext.test.ts → context/organisationContext.test.ts} +0 -0
- /package/src/utils/{cn.ts → core/cn.ts} +0 -0
- /package/src/utils/{debugLogger.ts → core/debugLogger.ts} +0 -0
- /package/src/utils/{dynamicUtils.ts → dynamic/dynamicUtils.ts} +0 -0
- /package/src/utils/{formatDate.test.ts → formatting/formatDate.test.ts} +0 -0
- /package/src/utils/{formatting.ts → formatting/formatting.ts} +0 -0
- /package/src/utils/{bundleAnalysis.ts → performance/bundleAnalysis.ts} +0 -0
- /package/src/utils/{performanceBenchmark.ts → performance/performanceBenchmark.ts} +0 -0
- /package/src/utils/{performanceBudgets.ts → performance/performanceBudgets.ts} +0 -0
- /package/src/utils/{permissionTypes.ts → permissions/permissionTypes.ts} +0 -0
- /package/src/utils/{permissionUtils.test.ts → permissions/permissionUtils.test.ts} +0 -0
- /package/src/utils/{permissionUtils.ts → permissions/permissionUtils.ts} +0 -0
- /package/src/utils/{auth-utils.ts → security/auth-utils.ts} +0 -0
- /package/src/utils/{secureDataAccess.test.ts → security/secureDataAccess.test.ts} +0 -0
- /package/src/utils/{secureDataAccess.ts → security/secureDataAccess.ts} +0 -0
- /package/src/utils/{secureStorage.ts → security/secureStorage.ts} +0 -0
- /package/src/utils/{securityMonitor.ts → security/securityMonitor.ts} +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
- /package/src/utils/{validation.ts → validation/validation.ts} +0 -0
|
@@ -14,6 +14,7 @@ import { useOrganisations } from './useOrganisations';
|
|
|
14
14
|
// Legacy useRBAC hook removed - use new RBAC system instead
|
|
15
15
|
import type { OrganisationSecurityError, SuperAdminContext } from '../types/organisation';
|
|
16
16
|
import type { Permission } from '../rbac/types';
|
|
17
|
+
import { logger } from '../utils/core/logger';
|
|
17
18
|
|
|
18
19
|
export interface OrganisationSecurityHook {
|
|
19
20
|
// Super admin context
|
|
@@ -66,7 +67,7 @@ export const useOrganisationSecurity = (): OrganisationSecurityHook => {
|
|
|
66
67
|
|
|
67
68
|
setIsSuperAdmin(!error && data && data.length > 0);
|
|
68
69
|
} catch (error) {
|
|
69
|
-
|
|
70
|
+
logger.error('useOrganisationSecurity', 'Error checking super admin status:', error);
|
|
70
71
|
setIsSuperAdmin(false);
|
|
71
72
|
} finally {
|
|
72
73
|
setIsCheckingSuperAdmin(false);
|
|
@@ -107,13 +108,13 @@ export const useOrganisationSecurity = (): OrganisationSecurityHook => {
|
|
|
107
108
|
.single();
|
|
108
109
|
|
|
109
110
|
if (error) {
|
|
110
|
-
|
|
111
|
+
logger.error('useOrganisationSecurity', 'Error validating organisation access:', error);
|
|
111
112
|
return false;
|
|
112
113
|
}
|
|
113
114
|
|
|
114
115
|
return !!data;
|
|
115
116
|
} catch (error) {
|
|
116
|
-
|
|
117
|
+
logger.error('useOrganisationSecurity', 'Exception validating organisation access:', error);
|
|
117
118
|
return false;
|
|
118
119
|
}
|
|
119
120
|
}, [user, session, supabase, superAdminContext.isSuperAdmin]);
|
|
@@ -177,7 +178,7 @@ export const useOrganisationSecurity = (): OrganisationSecurityHook => {
|
|
|
177
178
|
permission: permission as Permission
|
|
178
179
|
});
|
|
179
180
|
} catch (error) {
|
|
180
|
-
|
|
181
|
+
logger.error('useOrganisationSecurity', 'Exception checking permission:', error);
|
|
181
182
|
return false;
|
|
182
183
|
}
|
|
183
184
|
}, [selectedOrganisation, user, superAdminContext.isSuperAdmin]);
|
|
@@ -213,7 +214,7 @@ export const useOrganisationSecurity = (): OrganisationSecurityHook => {
|
|
|
213
214
|
.map(([permission]) => permission);
|
|
214
215
|
return [...new Set(allPermissions)]; // Remove duplicates
|
|
215
216
|
} catch (error) {
|
|
216
|
-
|
|
217
|
+
logger.error('useOrganisationSecurity', 'Exception getting user permissions:', error);
|
|
217
218
|
return [];
|
|
218
219
|
}
|
|
219
220
|
}, [selectedOrganisation, user, getUserRole, superAdminContext.isSuperAdmin]);
|
|
@@ -239,7 +240,7 @@ export const useOrganisationSecurity = (): OrganisationSecurityHook => {
|
|
|
239
240
|
});
|
|
240
241
|
}
|
|
241
242
|
} catch (error) {
|
|
242
|
-
|
|
243
|
+
logger.error('useOrganisationSecurity', 'Error logging organisation access:', error);
|
|
243
244
|
}
|
|
244
245
|
}, [user, selectedOrganisation]);
|
|
245
246
|
|
|
@@ -274,7 +275,7 @@ export const useOrganisationSecurity = (): OrganisationSecurityHook => {
|
|
|
274
275
|
|
|
275
276
|
return await validateOrganisationAccess(orgId);
|
|
276
277
|
} catch (error) {
|
|
277
|
-
|
|
278
|
+
logger.error('useOrganisationSecurity', 'Exception validating user access:', error);
|
|
278
279
|
return false;
|
|
279
280
|
}
|
|
280
281
|
}, [supabase, superAdminContext.isSuperAdmin, user, validateOrganisationAccess]);
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
|
|
2
2
|
import { useEffect, useRef, useCallback } from 'react';
|
|
3
|
-
import { performanceBudgetMonitor, PERFORMANCE_BUDGETS } from '../utils/performanceBudgets';
|
|
3
|
+
import { performanceBudgetMonitor, PERFORMANCE_BUDGETS } from '../utils/performance/performanceBudgets';
|
|
4
|
+
import { createLogger } from '../utils/core/logger';
|
|
5
|
+
|
|
6
|
+
const log = createLogger('usePerformanceMonitor');
|
|
4
7
|
|
|
5
8
|
export interface PerformanceMetrics {
|
|
6
9
|
renderTime: number;
|
|
@@ -54,8 +57,8 @@ export function usePerformanceMonitor(
|
|
|
54
57
|
|
|
55
58
|
// Log slow renders in development
|
|
56
59
|
if (!measurement.passed) {
|
|
57
|
-
|
|
58
|
-
|
|
60
|
+
log.warn(
|
|
61
|
+
`Performance budget exceeded in ${componentName}: ${renderTime.toFixed(2)}ms ` +
|
|
59
62
|
`(budget: ${PERFORMANCE_BUDGETS[budgetName]?.threshold}ms)`
|
|
60
63
|
);
|
|
61
64
|
}
|
|
@@ -59,6 +59,7 @@ import { useUnifiedAuth } from '../providers/UnifiedAuthProvider';
|
|
|
59
59
|
import { useOrganisations } from './useOrganisations';
|
|
60
60
|
import { useEvents } from './useEvents';
|
|
61
61
|
import { isPermittedCached } from '../rbac/api';
|
|
62
|
+
import { logger } from '../utils/core/logger';
|
|
62
63
|
import type { Operation, Permission, Scope, UUID } from '../rbac/types';
|
|
63
64
|
|
|
64
65
|
// Cache entry interface
|
|
@@ -213,12 +214,15 @@ export function usePermissionCache(config: Partial<CacheConfig> = {}) {
|
|
|
213
214
|
): Promise<boolean> => {
|
|
214
215
|
// Validate parameters
|
|
215
216
|
if (!operation || !pageId) {
|
|
216
|
-
|
|
217
|
+
logger.warn('PermissionCache', 'Invalid parameters: operation and pageId are required', { operation, pageId });
|
|
217
218
|
return false;
|
|
218
219
|
}
|
|
219
220
|
|
|
220
221
|
if (!user?.id || !scope.organisationId) {
|
|
221
|
-
|
|
222
|
+
logger.warn('PermissionCache', 'User or organisation context not available - permission check failed', {
|
|
223
|
+
hasUserId: !!user?.id,
|
|
224
|
+
hasOrganisationId: !!scope.organisationId
|
|
225
|
+
});
|
|
222
226
|
return false;
|
|
223
227
|
}
|
|
224
228
|
|
|
@@ -278,7 +282,7 @@ export function usePermissionCache(config: Partial<CacheConfig> = {}) {
|
|
|
278
282
|
logPermissionCheck(operation, pageId, result, false, responseTime);
|
|
279
283
|
return result;
|
|
280
284
|
} catch (error) {
|
|
281
|
-
|
|
285
|
+
logger.error('PermissionCache', `Error checking permission ${operation}:${pageId}`, { operation, pageId, error });
|
|
282
286
|
return false;
|
|
283
287
|
} finally {
|
|
284
288
|
// Remove the promise from cache after completion
|
|
@@ -299,12 +303,15 @@ export function usePermissionCache(config: Partial<CacheConfig> = {}) {
|
|
|
299
303
|
): Promise<PermissionResult[]> => {
|
|
300
304
|
// Validate parameters
|
|
301
305
|
if (!permissions || !Array.isArray(permissions) || permissions.length === 0) {
|
|
302
|
-
|
|
306
|
+
logger.warn('PermissionCache', 'Invalid permissions array', { permissions });
|
|
303
307
|
return [];
|
|
304
308
|
}
|
|
305
309
|
|
|
306
310
|
if (!user?.id || !scope.organisationId) {
|
|
307
|
-
|
|
311
|
+
logger.warn('PermissionCache', 'User or organisation context not available - permission checks failed', {
|
|
312
|
+
hasUserId: !!user?.id,
|
|
313
|
+
hasOrganisationId: !!scope.organisationId
|
|
314
|
+
});
|
|
308
315
|
return permissions.map(([operation, pageId]) => ({
|
|
309
316
|
operation,
|
|
310
317
|
pageId,
|
|
@@ -388,7 +395,7 @@ export function usePermissionCache(config: Partial<CacheConfig> = {}) {
|
|
|
388
395
|
|
|
389
396
|
stats.current.cacheMisses++;
|
|
390
397
|
} catch (error) {
|
|
391
|
-
|
|
398
|
+
logger.error('PermissionCache', `Error checking permission ${operation}:${pageId}`, { operation, pageId, error });
|
|
392
399
|
results[originalIndex] = {
|
|
393
400
|
operation,
|
|
394
401
|
pageId,
|
|
@@ -12,7 +12,7 @@ import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
|
12
12
|
import { useSecureDataAccess } from './useSecureDataAccess';
|
|
13
13
|
import { useUnifiedAuth } from '../providers';
|
|
14
14
|
import { useOrganisations } from './useOrganisations';
|
|
15
|
-
import { setOrganisationContext } from '../utils/organisationContext';
|
|
15
|
+
import { setOrganisationContext } from '../utils/context/organisationContext';
|
|
16
16
|
import { createMockSupabaseClient, createMockQueryBuilderWithData } from '../__tests__/helpers/supabaseMock';
|
|
17
17
|
|
|
18
18
|
// Mock the providers
|
|
@@ -25,7 +25,7 @@ vi.mock('./useOrganisations', () => ({
|
|
|
25
25
|
}));
|
|
26
26
|
|
|
27
27
|
// Mock the organisation context utility
|
|
28
|
-
vi.mock('../utils/organisationContext', () => ({
|
|
28
|
+
vi.mock('../utils/context/organisationContext', () => ({
|
|
29
29
|
setOrganisationContext: vi.fn()
|
|
30
30
|
}));
|
|
31
31
|
|
|
@@ -55,7 +55,8 @@ import { useCallback, useState, useContext } from 'react';
|
|
|
55
55
|
import { useUnifiedAuth } from '../providers';
|
|
56
56
|
import { useOrganisations } from './useOrganisations';
|
|
57
57
|
import { EventServiceContext } from '../providers/services/EventServiceProvider';
|
|
58
|
-
import { setOrganisationContext } from '../utils/organisationContext';
|
|
58
|
+
import { setOrganisationContext } from '../utils/context/organisationContext';
|
|
59
|
+
import { logger } from '../utils/core/logger';
|
|
59
60
|
import type { Permission } from '../rbac/types';
|
|
60
61
|
import type { OrganisationSecurityError } from '../types/organisation';
|
|
61
62
|
|
|
@@ -261,7 +262,7 @@ export function useSecureDataAccess(): SecureDataAccessReturn {
|
|
|
261
262
|
const { data, error } = await query;
|
|
262
263
|
|
|
263
264
|
if (error) {
|
|
264
|
-
|
|
265
|
+
logger.error('useSecureDataAccess', 'Query failed', { table, columns, filters, error });
|
|
265
266
|
// NEW: Phase 1 - Record failed data access attempt
|
|
266
267
|
recordDataAccess(table, 'read', false, `SELECT ${columns} FROM ${table}`, filters);
|
|
267
268
|
throw error;
|
|
@@ -296,7 +297,7 @@ export function useSecureDataAccess(): SecureDataAccessReturn {
|
|
|
296
297
|
.single();
|
|
297
298
|
|
|
298
299
|
if (error) {
|
|
299
|
-
|
|
300
|
+
logger.error('useSecureDataAccess', 'Insert failed', { table, data: secureData, error });
|
|
300
301
|
throw error;
|
|
301
302
|
}
|
|
302
303
|
|
|
@@ -346,7 +347,7 @@ export function useSecureDataAccess(): SecureDataAccessReturn {
|
|
|
346
347
|
const { data: updateData, error } = await query.select();
|
|
347
348
|
|
|
348
349
|
if (error) {
|
|
349
|
-
|
|
350
|
+
logger.error('useSecureDataAccess', 'Update failed', { table, data: secureData, filters, error });
|
|
350
351
|
throw error;
|
|
351
352
|
}
|
|
352
353
|
|
|
@@ -402,7 +403,7 @@ export function useSecureDataAccess(): SecureDataAccessReturn {
|
|
|
402
403
|
const { error } = await query;
|
|
403
404
|
|
|
404
405
|
if (error) {
|
|
405
|
-
|
|
406
|
+
logger.error('useSecureDataAccess', 'Delete failed', { table, filters, error });
|
|
406
407
|
throw error;
|
|
407
408
|
}
|
|
408
409
|
}, [validateContext, getCurrentOrganisationId, setOrganisationContextInSession, supabase]);
|
|
@@ -499,7 +500,7 @@ export function useSecureDataAccess(): SecureDataAccessReturn {
|
|
|
499
500
|
const { data, error } = await supabase!.rpc(functionName, secureParams);
|
|
500
501
|
|
|
501
502
|
if (error) {
|
|
502
|
-
|
|
503
|
+
logger.error('useSecureDataAccess', 'RPC failed', { functionName, params: secureParams, error });
|
|
503
504
|
throw error;
|
|
504
505
|
}
|
|
505
506
|
|
|
@@ -553,7 +554,7 @@ export function useSecureDataAccess(): SecureDataAccessReturn {
|
|
|
553
554
|
try {
|
|
554
555
|
validateContext();
|
|
555
556
|
} catch (error) {
|
|
556
|
-
|
|
557
|
+
logger.error('useSecureDataAccess', 'Organisation context validation failed', { table, operation, error });
|
|
557
558
|
return false;
|
|
558
559
|
}
|
|
559
560
|
|
|
@@ -587,7 +588,7 @@ export function useSecureDataAccess(): SecureDataAccessReturn {
|
|
|
587
588
|
});
|
|
588
589
|
|
|
589
590
|
if (isStrictMode && !allowed) {
|
|
590
|
-
|
|
591
|
+
logger.error('useSecureDataAccess', 'STRICT MODE VIOLATION: User attempted data access without permission', {
|
|
591
592
|
table,
|
|
592
593
|
operation,
|
|
593
594
|
userId: user.id,
|
|
@@ -12,6 +12,9 @@
|
|
|
12
12
|
import { useContext, useMemo, useEffect, useState } from 'react';
|
|
13
13
|
import { AuthServiceContext } from '../providers/services/AuthServiceProvider';
|
|
14
14
|
import type { SessionRestorationState } from '../types/auth';
|
|
15
|
+
import { createLogger } from '../utils/core/logger';
|
|
16
|
+
|
|
17
|
+
const log = createLogger('useSessionRestoration');
|
|
15
18
|
|
|
16
19
|
const SESSION_RESTORATION_TIMEOUT_MS = 5000;
|
|
17
20
|
|
|
@@ -38,7 +41,7 @@ export function useSessionRestoration(): UseSessionRestorationResult {
|
|
|
38
41
|
if (sessionRestoration.isRestoring && !sessionRestoration.restorationComplete && !sessionRestoration.restorationError) {
|
|
39
42
|
setHasTimedOut(false);
|
|
40
43
|
timeoutHandle = setTimeout(() => {
|
|
41
|
-
|
|
44
|
+
log.warn('Session restoration timed out');
|
|
42
45
|
setHasTimedOut(true);
|
|
43
46
|
}, SESSION_RESTORATION_TIMEOUT_MS);
|
|
44
47
|
} else {
|
package/src/hooks/useStorage.ts
CHANGED
|
@@ -17,6 +17,9 @@ import {
|
|
|
17
17
|
listFiles,
|
|
18
18
|
archiveFile
|
|
19
19
|
} from '../utils/storage';
|
|
20
|
+
import { createLogger } from '../utils/core/logger';
|
|
21
|
+
|
|
22
|
+
const log = createLogger('useStorage');
|
|
20
23
|
|
|
21
24
|
export interface UseStorageOptions {
|
|
22
25
|
supabase: SupabaseClient;
|
|
@@ -117,7 +120,7 @@ export function useStorage({ supabase, appName, orgId }: UseStorageOptions): Use
|
|
|
117
120
|
});
|
|
118
121
|
return result?.url || null;
|
|
119
122
|
} catch (error) {
|
|
120
|
-
|
|
123
|
+
log.error('Failed to get signed URL:', error);
|
|
121
124
|
return null;
|
|
122
125
|
}
|
|
123
126
|
}, [supabase, appName, orgId]);
|
package/src/index.ts
CHANGED
|
@@ -21,7 +21,7 @@ export { UnifiedAuthProvider, useUnifiedAuth } from './providers/UnifiedAuthProv
|
|
|
21
21
|
export type { UnifiedAuthProviderProps, UnifiedAuthContextType, UserEventAccess } from './providers/UnifiedAuthProvider';
|
|
22
22
|
|
|
23
23
|
// Session tracking utility (for manual use if needed)
|
|
24
|
-
export { useSessionTracking } from './utils/sessionTracking';
|
|
24
|
+
export { useSessionTracking } from './utils/context/sessionTracking';
|
|
25
25
|
|
|
26
26
|
// Provider components (using service architecture)
|
|
27
27
|
export { EventProvider } from './providers/EventProvider';
|
|
@@ -155,6 +155,15 @@ export {
|
|
|
155
155
|
type ExportColumn
|
|
156
156
|
} from './components/DataTable/utils/exportUtils';
|
|
157
157
|
|
|
158
|
+
// Export DataTable aggregation utilities
|
|
159
|
+
export {
|
|
160
|
+
sum,
|
|
161
|
+
average,
|
|
162
|
+
count,
|
|
163
|
+
min,
|
|
164
|
+
max
|
|
165
|
+
} from './components/DataTable/utils/aggregationUtils';
|
|
166
|
+
|
|
158
167
|
// FORM COMPONENTS
|
|
159
168
|
export { Form } from './components/Form/Form';
|
|
160
169
|
export { LoginForm } from './components/LoginForm/LoginForm';
|
|
@@ -183,7 +192,8 @@ export type { ProtectedRouteProps } from './components/ProtectedRoute/ProtectedR
|
|
|
183
192
|
// UTILITY COMPONENTS
|
|
184
193
|
export { ErrorBoundary } from './components/ErrorBoundary/ErrorBoundary';
|
|
185
194
|
export { LoadingSpinner } from './components/LoadingSpinner/LoadingSpinner';
|
|
186
|
-
export { SessionRestorationLoader } from './components/SessionRestorationLoader';
|
|
195
|
+
export { SessionRestorationLoader } from './components/SessionRestorationLoader/SessionRestorationLoader';
|
|
196
|
+
export type { SessionRestorationLoaderProps } from './components/SessionRestorationLoader/SessionRestorationLoader';
|
|
187
197
|
|
|
188
198
|
// EVENT MANAGEMENT
|
|
189
199
|
export { EventSelector } from './components/EventSelector/EventSelector';
|
|
@@ -192,20 +202,19 @@ export { EventSelector } from './components/EventSelector/EventSelector';
|
|
|
192
202
|
export { OrganisationSelector } from './components/OrganisationSelector/OrganisationSelector';
|
|
193
203
|
export { useOrganisationPermissions } from './hooks/useOrganisationPermissions';
|
|
194
204
|
export { useOrganisationSecurity } from './hooks/useOrganisationSecurity';
|
|
195
|
-
export { createSecureDataAccess } from './utils/secureDataAccess';
|
|
205
|
+
export { createSecureDataAccess } from './utils/security/secureDataAccess';
|
|
196
206
|
|
|
197
207
|
// TYPES
|
|
198
208
|
export type { UserProfile } from './types/organisation';
|
|
199
209
|
|
|
200
210
|
// AUTHENTICATION FORMS
|
|
201
|
-
export { PasswordResetForm } from './components/PasswordReset/PasswordResetForm';
|
|
202
211
|
export { PasswordChangeForm } from './components/PasswordReset/PasswordChangeForm';
|
|
203
212
|
|
|
204
213
|
// UTILS & HOOKS
|
|
205
214
|
export { useAppConfig } from './hooks/useAppConfig';
|
|
206
215
|
export { useEventTheme } from './hooks/useEventTheme';
|
|
207
|
-
export { cn } from './utils/cn';
|
|
208
|
-
export { setAppConfig, getAppConfig, getCurrentAppName, getCurrentAppId } from './utils/appConfig';
|
|
216
|
+
export { cn } from './utils/core/cn';
|
|
217
|
+
export { setAppConfig, getAppConfig, getCurrentAppName, getCurrentAppId } from './utils/app/appConfig';
|
|
209
218
|
|
|
210
219
|
// FORMATTING UTILITIES
|
|
211
220
|
export {
|
|
@@ -215,7 +224,7 @@ export {
|
|
|
215
224
|
formatPercent,
|
|
216
225
|
formatCompactNumber,
|
|
217
226
|
formatFileSize
|
|
218
|
-
} from './utils/formatting';
|
|
227
|
+
} from './utils/formatting/formatting';
|
|
219
228
|
|
|
220
229
|
// STORAGE UTILITIES
|
|
221
230
|
export { FileUpload } from './components/FileUpload';
|
|
@@ -12,6 +12,7 @@ import React, { createContext, useContext, useMemo, useEffect, useState } from '
|
|
|
12
12
|
import { type SupabaseClient } from '@supabase/supabase-js';
|
|
13
13
|
import { AuthService } from '../../services/AuthService';
|
|
14
14
|
import type { SessionRestorationState } from '../../types/auth';
|
|
15
|
+
import { logger } from '../../utils/core/logger';
|
|
15
16
|
|
|
16
17
|
// Context type
|
|
17
18
|
export interface AuthServiceContextType {
|
|
@@ -46,7 +47,7 @@ export function AuthServiceProvider({ children, supabaseClient, appName }: AuthS
|
|
|
46
47
|
|
|
47
48
|
const isDev = typeof import.meta !== 'undefined' && (import.meta.env.DEV || import.meta.env.MODE === 'development');
|
|
48
49
|
if (isDev) {
|
|
49
|
-
|
|
50
|
+
logger.debug('AuthServiceProvider', 'Session restoration state updated', restorationState);
|
|
50
51
|
}
|
|
51
52
|
});
|
|
52
53
|
|
|
@@ -58,7 +59,7 @@ export function AuthServiceProvider({ children, supabaseClient, appName }: AuthS
|
|
|
58
59
|
// Initialize service on mount
|
|
59
60
|
useEffect(() => {
|
|
60
61
|
authService.initialize().catch(error => {
|
|
61
|
-
|
|
62
|
+
logger.error('AuthServiceProvider', 'Failed to initialize auth service:', error);
|
|
62
63
|
});
|
|
63
64
|
|
|
64
65
|
// Cleanup on unmount
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
import React, { createContext, useContext, useMemo, useEffect, useRef } from 'react';
|
|
12
12
|
import { type SupabaseClient, type User, type Session } from '@supabase/supabase-js';
|
|
13
13
|
import { EventService } from '../../services/EventService';
|
|
14
|
+
import { logger } from '../../utils/core/logger';
|
|
14
15
|
|
|
15
16
|
// Context type
|
|
16
17
|
export interface EventServiceContextType {
|
|
@@ -63,7 +64,7 @@ export function EventServiceProvider({
|
|
|
63
64
|
// Re-initialize service when dependencies change
|
|
64
65
|
await eventService.initialize().catch(error => {
|
|
65
66
|
if (isMounted) {
|
|
66
|
-
|
|
67
|
+
logger.error('EventServiceProvider', 'Failed to initialize event service:', error);
|
|
67
68
|
}
|
|
68
69
|
});
|
|
69
70
|
};
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
import React, { createContext, useContext, useMemo, useEffect, useRef } from 'react';
|
|
12
12
|
import { type SupabaseClient, type User, type Session } from '@supabase/supabase-js';
|
|
13
13
|
import { InactivityService } from '../../services/InactivityService';
|
|
14
|
+
import { logger } from '../../utils/core/logger';
|
|
14
15
|
|
|
15
16
|
// Context type
|
|
16
17
|
export interface InactivityServiceContextType {
|
|
@@ -56,7 +57,7 @@ export function InactivityServiceProvider({
|
|
|
56
57
|
|
|
57
58
|
inactivityService.initialize().catch(error => {
|
|
58
59
|
if (isMounted) {
|
|
59
|
-
|
|
60
|
+
logger.error('InactivityServiceProvider', 'Failed to initialize inactivity service:', error);
|
|
60
61
|
}
|
|
61
62
|
});
|
|
62
63
|
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
import React, { createContext, useContext, useMemo, useEffect, useRef } from 'react';
|
|
12
12
|
import { type SupabaseClient, type User, type Session } from '@supabase/supabase-js';
|
|
13
13
|
import { OrganisationService } from '../../services/OrganisationService';
|
|
14
|
+
import { logger } from '../../utils/core/logger';
|
|
14
15
|
|
|
15
16
|
// Context type
|
|
16
17
|
export interface OrganisationServiceContextType {
|
|
@@ -50,7 +51,7 @@ export function OrganisationServiceProvider({
|
|
|
50
51
|
|
|
51
52
|
organisationService.initialize().catch(error => {
|
|
52
53
|
if (isMounted) {
|
|
53
|
-
|
|
54
|
+
logger.error('OrganisationServiceProvider', 'Failed to initialize organisation service:', error);
|
|
54
55
|
}
|
|
55
56
|
});
|
|
56
57
|
|
|
@@ -23,6 +23,7 @@ import type { Organisation, OrganisationMembership } from '../../types/organisat
|
|
|
23
23
|
import type { Event } from '../../types/unified';
|
|
24
24
|
import type { AuthError } from '@supabase/supabase-js';
|
|
25
25
|
import type { SessionRestorationState } from '../../types/auth';
|
|
26
|
+
import { logger } from '../../utils/core/logger';
|
|
26
27
|
|
|
27
28
|
// Re-export UserEventAccess type
|
|
28
29
|
export interface UserEventAccess {
|
|
@@ -116,8 +117,8 @@ const UnifiedAuthContext = createContext<UnifiedAuthContextType | undefined>(und
|
|
|
116
117
|
export const useUnifiedAuth = () => {
|
|
117
118
|
const context = useContext(UnifiedAuthContext);
|
|
118
119
|
if (!context) {
|
|
119
|
-
// Provide a helpful
|
|
120
|
-
|
|
120
|
+
// Provide a helpful error log in addition to throwing for testability and DX
|
|
121
|
+
logger.error('useUnifiedAuth', 'useUnifiedAuth must be used within a UnifiedAuthProvider');
|
|
121
122
|
throw new Error('useUnifiedAuth must be used within a UnifiedAuthProvider');
|
|
122
123
|
}
|
|
123
124
|
return context;
|
|
@@ -265,7 +266,7 @@ function UnifiedAuthContextProvider({
|
|
|
265
266
|
prevState.isAuthenticated !== currentState.isAuthenticated ||
|
|
266
267
|
prevState.userEmail !== currentState.userEmail ||
|
|
267
268
|
prevState.totalLoading !== currentState.totalLoading) {
|
|
268
|
-
|
|
269
|
+
logger.debug('UnifiedAuthContext', 'Auth state changed:', {
|
|
269
270
|
isAuthenticated: isAuth,
|
|
270
271
|
user: currentUser?.email,
|
|
271
272
|
session: currentSession ? 'exists' : 'null',
|
|
@@ -13,6 +13,7 @@ import { render, screen, waitFor } from '@testing-library/react';
|
|
|
13
13
|
import React from 'react';
|
|
14
14
|
import { AuthServiceProvider, useAuthService } from '../AuthServiceProvider';
|
|
15
15
|
import { type SupabaseClient, type User, type Session } from '@supabase/supabase-js';
|
|
16
|
+
import { Logger, LogLevel } from '../../../utils/core/logger';
|
|
16
17
|
|
|
17
18
|
// Mock Supabase client
|
|
18
19
|
const createMockSupabaseClient = (): SupabaseClient => ({
|
|
@@ -76,12 +77,28 @@ function TestComponent() {
|
|
|
76
77
|
|
|
77
78
|
describe('AuthServiceProvider Integration', () => {
|
|
78
79
|
let mockSupabase: SupabaseClient;
|
|
80
|
+
let originalMode: string | undefined;
|
|
79
81
|
|
|
80
82
|
beforeEach(() => {
|
|
83
|
+
// Ensure logger is enabled by setting MODE to development
|
|
84
|
+
originalMode = import.meta.env.MODE;
|
|
85
|
+
(import.meta.env as any).MODE = 'development';
|
|
86
|
+
|
|
87
|
+
// Configure logger to ensure it logs in test environment
|
|
88
|
+
Logger.configure({
|
|
89
|
+
level: LogLevel.DEBUG,
|
|
90
|
+
includeTimestamp: false,
|
|
91
|
+
includeComponent: true,
|
|
92
|
+
});
|
|
93
|
+
|
|
81
94
|
mockSupabase = createMockSupabaseClient();
|
|
82
95
|
});
|
|
83
96
|
|
|
84
97
|
afterEach(() => {
|
|
98
|
+
// Restore original mode
|
|
99
|
+
if (originalMode !== undefined) {
|
|
100
|
+
(import.meta.env as any).MODE = originalMode;
|
|
101
|
+
}
|
|
85
102
|
vi.clearAllMocks();
|
|
86
103
|
});
|
|
87
104
|
|
|
@@ -201,8 +218,11 @@ describe('AuthServiceProvider Integration', () => {
|
|
|
201
218
|
|
|
202
219
|
// Error is logged during initialization
|
|
203
220
|
await waitFor(() => {
|
|
204
|
-
expect(consoleSpy).
|
|
205
|
-
|
|
221
|
+
expect(consoleSpy).toHaveBeenCalledWith(
|
|
222
|
+
expect.stringContaining('[ERROR] [AuthServiceProvider] Failed to initialize auth service'),
|
|
223
|
+
expect.any(Error)
|
|
224
|
+
);
|
|
225
|
+
}, { interval: 10, timeout: 2000 });
|
|
206
226
|
|
|
207
227
|
consoleSpy.mockRestore();
|
|
208
228
|
});
|
|
@@ -12,6 +12,7 @@ import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest';
|
|
|
12
12
|
import { render, screen, waitFor } from '@testing-library/react';
|
|
13
13
|
import { UnifiedAuthProvider, useUnifiedAuth } from '../UnifiedAuthProvider';
|
|
14
14
|
import { type SupabaseClient, type User, type Session } from '@supabase/supabase-js';
|
|
15
|
+
import { Logger, LogLevel } from '../../../utils/core/logger';
|
|
15
16
|
|
|
16
17
|
// Mock Supabase client
|
|
17
18
|
const createMockSupabaseClient = (): SupabaseClient => ({
|
|
@@ -72,12 +73,28 @@ function TestComponent() {
|
|
|
72
73
|
|
|
73
74
|
describe('UnifiedAuthProvider Integration', () => {
|
|
74
75
|
let mockSupabase: SupabaseClient;
|
|
76
|
+
let originalMode: string | undefined;
|
|
75
77
|
|
|
76
78
|
beforeEach(() => {
|
|
79
|
+
// Ensure logger is enabled by setting MODE to development
|
|
80
|
+
originalMode = import.meta.env.MODE;
|
|
81
|
+
(import.meta.env as any).MODE = 'development';
|
|
82
|
+
|
|
83
|
+
// Configure logger to ensure it logs in test environment
|
|
84
|
+
Logger.configure({
|
|
85
|
+
level: LogLevel.DEBUG,
|
|
86
|
+
includeTimestamp: false,
|
|
87
|
+
includeComponent: true,
|
|
88
|
+
});
|
|
89
|
+
|
|
77
90
|
mockSupabase = createMockSupabaseClient();
|
|
78
91
|
});
|
|
79
92
|
|
|
80
93
|
afterEach(() => {
|
|
94
|
+
// Restore original mode
|
|
95
|
+
if (originalMode !== undefined) {
|
|
96
|
+
(import.meta.env as any).MODE = originalMode;
|
|
97
|
+
}
|
|
81
98
|
vi.clearAllMocks();
|
|
82
99
|
});
|
|
83
100
|
|
|
@@ -162,8 +179,13 @@ describe('UnifiedAuthProvider Integration', () => {
|
|
|
162
179
|
);
|
|
163
180
|
|
|
164
181
|
await waitFor(() => {
|
|
165
|
-
|
|
166
|
-
|
|
182
|
+
// Check that logger.error was called (which uses console.error internally)
|
|
183
|
+
// The error could be from any of the service providers (Auth, Organisation, Event, Inactivity)
|
|
184
|
+
expect(consoleSpy).toHaveBeenCalledWith(
|
|
185
|
+
expect.stringMatching(/\[ERROR\] \[(AuthServiceProvider|OrganisationServiceProvider|EventServiceProvider|InactivityServiceProvider)\]/),
|
|
186
|
+
expect.any(Error)
|
|
187
|
+
);
|
|
188
|
+
}, { timeout: 2000 });
|
|
167
189
|
|
|
168
190
|
consoleSpy.mockRestore();
|
|
169
191
|
});
|
|
@@ -20,6 +20,22 @@ import {
|
|
|
20
20
|
import { rbacCache, CACHE_PATTERNS } from '../cache';
|
|
21
21
|
import { emitAuditEvent } from '../audit';
|
|
22
22
|
|
|
23
|
+
// Mock the Logger module
|
|
24
|
+
vi.mock('../../utils/core/logger', () => {
|
|
25
|
+
const mockLoggerInstance = {
|
|
26
|
+
warn: vi.fn(),
|
|
27
|
+
debug: vi.fn(),
|
|
28
|
+
error: vi.fn(),
|
|
29
|
+
};
|
|
30
|
+
return {
|
|
31
|
+
createLogger: vi.fn(() => mockLoggerInstance),
|
|
32
|
+
};
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// Get the mock instance after mock is set up
|
|
36
|
+
import { createLogger } from '../../utils/core/logger';
|
|
37
|
+
const getMockLogger = () => createLogger('test');
|
|
38
|
+
|
|
23
39
|
// Mock the cache module
|
|
24
40
|
vi.mock('../cache', () => ({
|
|
25
41
|
rbacCache: {
|
|
@@ -365,20 +381,18 @@ describe('RBAC Cache Invalidation', () => {
|
|
|
365
381
|
|
|
366
382
|
describe('Error Handling', () => {
|
|
367
383
|
it('handles audit event errors gracefully', async () => {
|
|
384
|
+
vi.clearAllMocks();
|
|
368
385
|
vi.mocked(emitAuditEvent).mockRejectedValue(new Error('Audit error'));
|
|
369
386
|
|
|
370
|
-
const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
371
|
-
|
|
372
387
|
manager.invalidateUser('user-123' as const, 'test');
|
|
373
388
|
|
|
374
389
|
await vi.waitFor(() => {
|
|
375
|
-
|
|
376
|
-
|
|
390
|
+
const logger = getMockLogger();
|
|
391
|
+
expect(vi.mocked(logger.warn)).toHaveBeenCalledWith(
|
|
392
|
+
'Failed to log cache invalidation audit event:',
|
|
377
393
|
expect.any(Error)
|
|
378
394
|
);
|
|
379
395
|
});
|
|
380
|
-
|
|
381
|
-
consoleWarnSpy.mockRestore();
|
|
382
396
|
});
|
|
383
397
|
});
|
|
384
398
|
});
|
package/src/rbac/api.ts
CHANGED
|
@@ -26,6 +26,9 @@ import { createAuditManager, setGlobalAuditManager } from './audit';
|
|
|
26
26
|
import { rbacCache, RBACCache, CACHE_PATTERNS } from './cache';
|
|
27
27
|
import { createRBACConfig, RBACConfig, getRBACLogger } from './config';
|
|
28
28
|
import { SecurityContext } from './security';
|
|
29
|
+
import { createLogger } from '../utils/core/logger';
|
|
30
|
+
|
|
31
|
+
const log = createLogger('RBACAPI');
|
|
29
32
|
|
|
30
33
|
// Global engine instance
|
|
31
34
|
let globalEngine: RBACEngine | null = null;
|
|
@@ -292,7 +295,7 @@ export async function isSuperAdmin(userId: UUID): Promise<boolean> {
|
|
|
292
295
|
export async function getAppConfig(appId: UUID): Promise<{ requires_event: boolean } | null> {
|
|
293
296
|
// This function requires a Supabase client to be provided
|
|
294
297
|
// Callers should pass the client as a parameter
|
|
295
|
-
|
|
298
|
+
log.warn('getAppConfig called without Supabase client - returning null');
|
|
296
299
|
return null;
|
|
297
300
|
}
|
|
298
301
|
|
|
@@ -311,7 +314,7 @@ export async function getAppConfigWithClient(client: SupabaseClient, appId: UUID
|
|
|
311
314
|
|
|
312
315
|
return { requires_event: data.requires_event };
|
|
313
316
|
} catch (err) {
|
|
314
|
-
|
|
317
|
+
log.error('Error fetching app config:', err);
|
|
315
318
|
return null;
|
|
316
319
|
}
|
|
317
320
|
}
|