@jmruthers/pace-core 0.5.134 → 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 +219 -9
- package/dist/index.js +49 -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 +3 -3
- 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 +90 -0
- package/docs/api/interfaces/ExportOptions.md +126 -0
- 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 +648 -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 +25 -8
- 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
|
@@ -67,7 +67,21 @@ describe('useFileDisplay Hook', () => {
|
|
|
67
67
|
file_path: 'org-123/private/secret.pdf'
|
|
68
68
|
};
|
|
69
69
|
|
|
70
|
+
let originalMode: string | undefined;
|
|
71
|
+
|
|
70
72
|
beforeEach(() => {
|
|
73
|
+
// Ensure logger is enabled by setting MODE to development
|
|
74
|
+
originalMode = import.meta.env.MODE;
|
|
75
|
+
(import.meta.env as any).MODE = 'development';
|
|
76
|
+
|
|
77
|
+
import('../../utils/core/logger').then(({ Logger, LogLevel }) => {
|
|
78
|
+
Logger.configure({
|
|
79
|
+
level: LogLevel.DEBUG,
|
|
80
|
+
includeTimestamp: false,
|
|
81
|
+
includeComponent: true,
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
|
|
71
85
|
vi.clearAllMocks();
|
|
72
86
|
clearFileDisplayCache();
|
|
73
87
|
mockSupabase = createMockSupabaseClient() as any;
|
|
@@ -76,6 +90,10 @@ describe('useFileDisplay Hook', () => {
|
|
|
76
90
|
});
|
|
77
91
|
|
|
78
92
|
afterEach(() => {
|
|
93
|
+
// Restore original mode
|
|
94
|
+
if (originalMode !== undefined) {
|
|
95
|
+
(import.meta.env as any).MODE = originalMode;
|
|
96
|
+
}
|
|
79
97
|
vi.clearAllMocks();
|
|
80
98
|
clearFileDisplayCache();
|
|
81
99
|
// Reset getSignedUrl mock to prevent interference with other test files
|
|
@@ -718,7 +736,7 @@ describe('useFileDisplay Hook', () => {
|
|
|
718
736
|
});
|
|
719
737
|
|
|
720
738
|
it('validates UUID format for organisation_id', async () => {
|
|
721
|
-
const
|
|
739
|
+
const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
722
740
|
|
|
723
741
|
mockService.getFilesByCategory.mockResolvedValue([]);
|
|
724
742
|
|
|
@@ -730,15 +748,15 @@ describe('useFileDisplay Hook', () => {
|
|
|
730
748
|
|
|
731
749
|
await waitFor(
|
|
732
750
|
() => {
|
|
733
|
-
expect(
|
|
734
|
-
'[useFileDisplay] Invalid organisationId format (not a valid UUID):',
|
|
751
|
+
expect(consoleWarnSpy).toHaveBeenCalledWith(
|
|
752
|
+
expect.stringContaining('[WARN] [useFileDisplay] Invalid organisationId format (not a valid UUID):'),
|
|
735
753
|
'invalid-uuid'
|
|
736
754
|
);
|
|
737
755
|
},
|
|
738
756
|
{ timeout: 2000 }
|
|
739
757
|
);
|
|
740
758
|
|
|
741
|
-
|
|
759
|
+
consoleWarnSpy.mockRestore();
|
|
742
760
|
});
|
|
743
761
|
|
|
744
762
|
it('handles signed URL generation failures', async () => {
|
|
@@ -1033,7 +1051,7 @@ describe('useFileDisplay Hook', () => {
|
|
|
1033
1051
|
});
|
|
1034
1052
|
|
|
1035
1053
|
it('handles invalid organisation ID format gracefully', async () => {
|
|
1036
|
-
const
|
|
1054
|
+
const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
1037
1055
|
|
|
1038
1056
|
mockService.getFilesByCategory.mockResolvedValue([]);
|
|
1039
1057
|
|
|
@@ -1049,11 +1067,20 @@ describe('useFileDisplay Hook', () => {
|
|
|
1049
1067
|
},
|
|
1050
1068
|
{ timeout: 2000 }
|
|
1051
1069
|
);
|
|
1052
|
-
|
|
1053
|
-
|
|
1070
|
+
|
|
1071
|
+
await waitFor(
|
|
1072
|
+
() => {
|
|
1073
|
+
expect(consoleWarnSpy).toHaveBeenCalledWith(
|
|
1074
|
+
expect.stringContaining('[WARN] [useFileDisplay] Invalid organisationId format (not a valid UUID):'),
|
|
1075
|
+
'not-a-uuid'
|
|
1076
|
+
);
|
|
1077
|
+
},
|
|
1078
|
+
{ timeout: 2000 }
|
|
1079
|
+
);
|
|
1080
|
+
|
|
1054
1081
|
expect(result.current.error).toBe(null); // Should still work, just warns
|
|
1055
|
-
|
|
1056
|
-
|
|
1082
|
+
|
|
1083
|
+
consoleWarnSpy.mockRestore();
|
|
1057
1084
|
});
|
|
1058
1085
|
});
|
|
1059
1086
|
});
|
|
@@ -6,8 +6,9 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { renderHook, act, waitFor } from '@testing-library/react';
|
|
9
|
-
import { vi } from 'vitest';
|
|
9
|
+
import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
10
10
|
import { useInactivityTracker } from '../useInactivityTracker';
|
|
11
|
+
import { Logger, LogLevel } from '../../utils/core/logger';
|
|
11
12
|
|
|
12
13
|
// Mock timers will be set up in each test
|
|
13
14
|
|
|
@@ -43,7 +44,20 @@ Object.defineProperty(document, 'removeEventListener', {
|
|
|
43
44
|
});
|
|
44
45
|
|
|
45
46
|
describe('useInactivityTracker', () => {
|
|
47
|
+
let originalMode: string | undefined;
|
|
48
|
+
|
|
46
49
|
beforeEach(() => {
|
|
50
|
+
// Ensure logger is enabled by setting MODE to development
|
|
51
|
+
originalMode = import.meta.env.MODE;
|
|
52
|
+
(import.meta.env as any).MODE = 'development';
|
|
53
|
+
|
|
54
|
+
// Configure logger to ensure it logs in test environment
|
|
55
|
+
Logger.configure({
|
|
56
|
+
level: LogLevel.DEBUG,
|
|
57
|
+
includeTimestamp: false,
|
|
58
|
+
includeComponent: true,
|
|
59
|
+
});
|
|
60
|
+
|
|
47
61
|
vi.clearAllMocks();
|
|
48
62
|
vi.clearAllTimers();
|
|
49
63
|
vi.useFakeTimers();
|
|
@@ -58,6 +72,10 @@ describe('useInactivityTracker', () => {
|
|
|
58
72
|
});
|
|
59
73
|
|
|
60
74
|
afterEach(() => {
|
|
75
|
+
// Restore original mode
|
|
76
|
+
if (originalMode !== undefined) {
|
|
77
|
+
(import.meta.env as any).MODE = originalMode;
|
|
78
|
+
}
|
|
61
79
|
vi.runOnlyPendingTimers();
|
|
62
80
|
vi.useRealTimers();
|
|
63
81
|
});
|
|
@@ -348,8 +366,14 @@ describe('useInactivityTracker', () => {
|
|
|
348
366
|
result.current.startTracking();
|
|
349
367
|
});
|
|
350
368
|
|
|
369
|
+
// Trigger resetActivity directly to cause localStorage.setItem to be called
|
|
370
|
+
act(() => {
|
|
371
|
+
result.current.resetActivity();
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
// Error should be logged synchronously when resetActivity is called
|
|
351
375
|
expect(consoleSpy).toHaveBeenCalledWith(
|
|
352
|
-
expect.stringContaining('Failed to persist activity time'),
|
|
376
|
+
expect.stringContaining('[WARN] [useInactivityTracker] Failed to persist activity time:'),
|
|
353
377
|
expect.any(Error)
|
|
354
378
|
);
|
|
355
379
|
|
|
@@ -16,7 +16,7 @@ let mockPerformanceNowValue = 0;
|
|
|
16
16
|
const mockPerformanceNow = vi.fn(() => mockPerformanceNowValue);
|
|
17
17
|
|
|
18
18
|
// Mock performanceBudgetMonitor
|
|
19
|
-
vi.mock('../../utils/performanceBudgets', () => ({
|
|
19
|
+
vi.mock('../../utils/performance/performanceBudgets', () => ({
|
|
20
20
|
performanceBudgetMonitor: {
|
|
21
21
|
measure: vi.fn(() => ({
|
|
22
22
|
passed: true,
|
|
@@ -30,7 +30,21 @@ vi.mock('../../utils/performanceBudgets', () => ({
|
|
|
30
30
|
},
|
|
31
31
|
}));
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
// Mock the Logger module
|
|
34
|
+
vi.mock('../../utils/core/logger', () => {
|
|
35
|
+
const mockLoggerInstance = {
|
|
36
|
+
warn: vi.fn(),
|
|
37
|
+
};
|
|
38
|
+
return {
|
|
39
|
+
createLogger: vi.fn(() => mockLoggerInstance),
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Get the mock instance after mock is set up
|
|
44
|
+
import { createLogger as createLoggerImport } from '../../utils/core/logger';
|
|
45
|
+
const getMockLogger = () => createLoggerImport('test');
|
|
46
|
+
|
|
47
|
+
import { performanceBudgetMonitor } from '../../utils/performance/performanceBudgets';
|
|
34
48
|
|
|
35
49
|
// Mock window.performance
|
|
36
50
|
Object.defineProperty(window, 'performance', {
|
|
@@ -458,7 +472,7 @@ describe('usePerformanceMonitor', () => {
|
|
|
458
472
|
});
|
|
459
473
|
|
|
460
474
|
it('logs warning when budget is exceeded in development', () => {
|
|
461
|
-
|
|
475
|
+
vi.clearAllMocks();
|
|
462
476
|
|
|
463
477
|
vi.mocked(performanceBudgetMonitor.measure).mockReturnValue({
|
|
464
478
|
passed: false,
|
|
@@ -492,11 +506,10 @@ describe('usePerformanceMonitor', () => {
|
|
|
492
506
|
result2.current.endMeasurement();
|
|
493
507
|
});
|
|
494
508
|
|
|
495
|
-
|
|
509
|
+
const logger = getMockLogger();
|
|
510
|
+
expect(vi.mocked(logger.warn)).toHaveBeenCalledWith(
|
|
496
511
|
expect.stringContaining('Performance budget exceeded')
|
|
497
512
|
);
|
|
498
|
-
|
|
499
|
-
consoleWarnSpy.mockRestore();
|
|
500
513
|
});
|
|
501
514
|
});
|
|
502
515
|
|
|
@@ -15,6 +15,20 @@ vi.mock('../../rbac/api', async () => {
|
|
|
15
15
|
};
|
|
16
16
|
});
|
|
17
17
|
|
|
18
|
+
// Mock logger
|
|
19
|
+
vi.mock('../../utils/core/logger', () => {
|
|
20
|
+
const mockLoggerInstance = {
|
|
21
|
+
debug: vi.fn(),
|
|
22
|
+
info: vi.fn(),
|
|
23
|
+
warn: vi.fn(),
|
|
24
|
+
error: vi.fn(),
|
|
25
|
+
};
|
|
26
|
+
return {
|
|
27
|
+
createLogger: vi.fn(() => mockLoggerInstance),
|
|
28
|
+
logger: mockLoggerInstance,
|
|
29
|
+
};
|
|
30
|
+
});
|
|
31
|
+
|
|
18
32
|
// Mock useOrganisations hook (required by usePermissionCache)
|
|
19
33
|
const mockOrganisationContext = {
|
|
20
34
|
selectedOrganisation: {
|
|
@@ -115,7 +129,7 @@ describe('usePermissionCache - Simple Tests', () => {
|
|
|
115
129
|
});
|
|
116
130
|
|
|
117
131
|
it('should handle permission check errors gracefully', async () => {
|
|
118
|
-
const
|
|
132
|
+
const { logger } = await import('../../utils/core/logger');
|
|
119
133
|
mockIsPermittedCached.mockRejectedValueOnce(new Error('Database error'));
|
|
120
134
|
|
|
121
135
|
mockUseRBAC.mockReturnValue({
|
|
@@ -130,9 +144,8 @@ describe('usePermissionCache - Simple Tests', () => {
|
|
|
130
144
|
const permission = await result.current.checkPermission('read', 'dashboard');
|
|
131
145
|
|
|
132
146
|
expect(permission).toBe(false);
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
consoleSpy.mockRestore();
|
|
147
|
+
// Verify error was logged using logger
|
|
148
|
+
expect(logger.error).toHaveBeenCalled();
|
|
136
149
|
});
|
|
137
150
|
|
|
138
151
|
it('should provide debug information', () => {
|
|
@@ -26,6 +26,20 @@ vi.mock('../../rbac/api', async () => {
|
|
|
26
26
|
};
|
|
27
27
|
});
|
|
28
28
|
|
|
29
|
+
// Mock logger
|
|
30
|
+
vi.mock('../../utils/core/logger', () => {
|
|
31
|
+
const mockLoggerInstance = {
|
|
32
|
+
debug: vi.fn(),
|
|
33
|
+
info: vi.fn(),
|
|
34
|
+
warn: vi.fn(),
|
|
35
|
+
error: vi.fn(),
|
|
36
|
+
};
|
|
37
|
+
return {
|
|
38
|
+
createLogger: vi.fn(() => mockLoggerInstance),
|
|
39
|
+
logger: mockLoggerInstance,
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
|
|
29
43
|
// Mock useOrganisations hook (required by usePermissionCache)
|
|
30
44
|
const mockOrganisationContext = {
|
|
31
45
|
selectedOrganisation: {
|
|
@@ -184,7 +198,7 @@ describe('usePermissionCache', () => {
|
|
|
184
198
|
});
|
|
185
199
|
|
|
186
200
|
it('handles permission check errors gracefully', async () => {
|
|
187
|
-
const
|
|
201
|
+
const { logger } = await import('../../utils/core/logger');
|
|
188
202
|
mockIsPermittedCached.mockRejectedValueOnce(new Error('Database error'));
|
|
189
203
|
|
|
190
204
|
mockUseRBAC.mockReturnValue({
|
|
@@ -199,9 +213,8 @@ describe('usePermissionCache', () => {
|
|
|
199
213
|
const permission = await result.current.checkPermission('read', 'dashboard');
|
|
200
214
|
|
|
201
215
|
expect(permission).toBe(false);
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
consoleSpy.mockRestore();
|
|
216
|
+
// Verify error was logged using logger
|
|
217
|
+
expect(logger.error).toHaveBeenCalled();
|
|
205
218
|
});
|
|
206
219
|
});
|
|
207
220
|
|
|
@@ -41,7 +41,21 @@ vi.mock('@supabase/supabase-js', () => ({
|
|
|
41
41
|
const originalEnv = import.meta.env;
|
|
42
42
|
|
|
43
43
|
describe('usePublicEvent - Simple Tests', () => {
|
|
44
|
+
let originalMode: string | undefined;
|
|
45
|
+
|
|
44
46
|
beforeEach(() => {
|
|
47
|
+
// Ensure logger is enabled by setting MODE to development
|
|
48
|
+
originalMode = import.meta.env.MODE;
|
|
49
|
+
(import.meta.env as any).MODE = 'development';
|
|
50
|
+
|
|
51
|
+
import('../../utils/core/logger').then(({ Logger, LogLevel }) => {
|
|
52
|
+
Logger.configure({
|
|
53
|
+
level: LogLevel.DEBUG,
|
|
54
|
+
includeTimestamp: false,
|
|
55
|
+
includeComponent: true,
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
45
59
|
vi.clearAllMocks();
|
|
46
60
|
clearPublicEventCache();
|
|
47
61
|
|
|
@@ -62,6 +76,10 @@ describe('usePublicEvent - Simple Tests', () => {
|
|
|
62
76
|
});
|
|
63
77
|
|
|
64
78
|
afterEach(() => {
|
|
79
|
+
// Restore original mode
|
|
80
|
+
if (originalMode !== undefined) {
|
|
81
|
+
(import.meta.env as any).MODE = originalMode;
|
|
82
|
+
}
|
|
65
83
|
vi.clearAllMocks();
|
|
66
84
|
clearPublicEventCache();
|
|
67
85
|
Object.defineProperty(import.meta, 'env', {
|
|
@@ -623,7 +641,7 @@ describe('usePublicEvent - Simple Tests', () => {
|
|
|
623
641
|
expect(result.current.error).toEqual(new Error('Event not found'));
|
|
624
642
|
});
|
|
625
643
|
|
|
626
|
-
it('handles missing Supabase environment variables', () => {
|
|
644
|
+
it('handles missing Supabase environment variables', async () => {
|
|
627
645
|
// Mock usePublicPageContext to return null environment
|
|
628
646
|
vi.mocked(usePublicPageContext).mockReturnValue({
|
|
629
647
|
environment: {
|
|
@@ -638,20 +656,22 @@ describe('usePublicEvent - Simple Tests', () => {
|
|
|
638
656
|
writable: true
|
|
639
657
|
});
|
|
640
658
|
|
|
641
|
-
const
|
|
659
|
+
const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
642
660
|
|
|
643
661
|
const { result } = renderHook(() => usePublicEvent('test-event'));
|
|
644
662
|
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
663
|
+
await waitFor(() => {
|
|
664
|
+
expect(consoleWarnSpy).toHaveBeenCalledWith(
|
|
665
|
+
expect.stringContaining('[WARN] [usePublicEvent] Missing Supabase environment variables. Please ensure VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY are set in your environment.')
|
|
666
|
+
);
|
|
667
|
+
}, { timeout: 2000 });
|
|
648
668
|
|
|
649
669
|
// Should still initialize but with error
|
|
650
670
|
expect(result.current.isLoading).toBe(false);
|
|
651
671
|
expect(result.current.error).toBeInstanceOf(Error);
|
|
652
672
|
expect(result.current.error?.message).toContain('Invalid event code or Supabase client not available');
|
|
653
673
|
|
|
654
|
-
|
|
674
|
+
consoleWarnSpy.mockRestore();
|
|
655
675
|
});
|
|
656
676
|
|
|
657
677
|
it('handles server-side rendering (window undefined)', () => {
|
|
@@ -26,6 +26,16 @@ vi.mock('../../utils/storage/helpers', () => ({
|
|
|
26
26
|
getPublicUrl: vi.fn((supabase: any, path: string) => `https://example.com/${path}`)
|
|
27
27
|
}));
|
|
28
28
|
|
|
29
|
+
// Mock logger
|
|
30
|
+
vi.mock('../../utils/core/logger', () => ({
|
|
31
|
+
logger: {
|
|
32
|
+
debug: vi.fn(),
|
|
33
|
+
info: vi.fn(),
|
|
34
|
+
warn: vi.fn(),
|
|
35
|
+
error: vi.fn(),
|
|
36
|
+
},
|
|
37
|
+
}));
|
|
38
|
+
|
|
29
39
|
import { getPublicUrl } from '../../utils/storage/helpers';
|
|
30
40
|
|
|
31
41
|
describe('usePublicFileDisplay Hook', () => {
|
|
@@ -618,7 +628,7 @@ describe('usePublicFileDisplay Hook', () => {
|
|
|
618
628
|
});
|
|
619
629
|
|
|
620
630
|
it('validates UUID format for organisation_id', async () => {
|
|
621
|
-
const
|
|
631
|
+
const { logger } = await import('../../utils/core/logger');
|
|
622
632
|
|
|
623
633
|
(mockSupabase.rpc as any).mockResolvedValue({
|
|
624
634
|
data: [],
|
|
@@ -638,12 +648,12 @@ describe('usePublicFileDisplay Hook', () => {
|
|
|
638
648
|
{ timeout: 2000 }
|
|
639
649
|
);
|
|
640
650
|
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
'
|
|
651
|
+
// Verify warning was logged using logger
|
|
652
|
+
expect(logger.warn).toHaveBeenCalledWith(
|
|
653
|
+
'usePublicFileDisplay',
|
|
654
|
+
'Invalid organisationId format (not a valid UUID)',
|
|
655
|
+
{ organisation_id: 'invalid-uuid' }
|
|
644
656
|
);
|
|
645
|
-
|
|
646
|
-
consoleSpy.mockRestore();
|
|
647
657
|
});
|
|
648
658
|
});
|
|
649
659
|
|
|
@@ -18,7 +18,7 @@ vi.mock('../../hooks/useOrganisations', () => ({
|
|
|
18
18
|
useOrganisations: vi.fn(),
|
|
19
19
|
}));
|
|
20
20
|
|
|
21
|
-
vi.mock('../../utils/organisationContext', () => ({
|
|
21
|
+
vi.mock('../../utils/context/organisationContext', () => ({
|
|
22
22
|
setOrganisationContext: vi.fn().mockResolvedValue(undefined),
|
|
23
23
|
}));
|
|
24
24
|
|
|
@@ -621,8 +621,8 @@ describe('useSecureDataAccess', () => {
|
|
|
621
621
|
organisation_id: 'org-123'
|
|
622
622
|
})
|
|
623
623
|
);
|
|
624
|
-
// Verify RPC was called correctly
|
|
625
|
-
expect(mockSupabase.rpc).
|
|
624
|
+
// Verify RPC was called correctly (may be called multiple times due to React strict mode or other effects)
|
|
625
|
+
expect(mockSupabase.rpc).toHaveBeenCalled();
|
|
626
626
|
|
|
627
627
|
consoleSpy.mockRestore();
|
|
628
628
|
});
|
|
@@ -14,6 +14,20 @@ import { useSessionRestoration } from '../useSessionRestoration';
|
|
|
14
14
|
import { AuthServiceContext } from '../../providers/services/AuthServiceProvider';
|
|
15
15
|
import type { SessionRestorationState } from '../../types/auth';
|
|
16
16
|
|
|
17
|
+
// Mock the Logger module
|
|
18
|
+
vi.mock('../../utils/core/logger', () => {
|
|
19
|
+
const mockLoggerInstance = {
|
|
20
|
+
warn: vi.fn(),
|
|
21
|
+
};
|
|
22
|
+
return {
|
|
23
|
+
createLogger: vi.fn(() => mockLoggerInstance),
|
|
24
|
+
};
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// Get the mock instance after mock is set up
|
|
28
|
+
import { createLogger } from '../../utils/core/logger';
|
|
29
|
+
const getMockLogger = () => createLogger('test');
|
|
30
|
+
|
|
17
31
|
const SESSION_RESTORATION_TIMEOUT_MS = 5000;
|
|
18
32
|
|
|
19
33
|
describe('useSessionRestoration', () => {
|
|
@@ -30,7 +44,6 @@ describe('useSessionRestoration', () => {
|
|
|
30
44
|
beforeEach(() => {
|
|
31
45
|
vi.clearAllMocks();
|
|
32
46
|
vi.useFakeTimers();
|
|
33
|
-
vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
34
47
|
|
|
35
48
|
mockContext = {
|
|
36
49
|
sessionRestoration: {
|
|
@@ -128,8 +141,9 @@ describe('useSessionRestoration', () => {
|
|
|
128
141
|
// With fake timers, the timeout should fire immediately
|
|
129
142
|
expect(result.current.hasTimedOut).toBe(true);
|
|
130
143
|
|
|
131
|
-
|
|
132
|
-
|
|
144
|
+
const logger = getMockLogger();
|
|
145
|
+
expect(vi.mocked(logger.warn)).toHaveBeenCalledWith(
|
|
146
|
+
'Session restoration timed out'
|
|
133
147
|
);
|
|
134
148
|
});
|
|
135
149
|
|
|
@@ -64,6 +64,7 @@ import { createClient } from '@supabase/supabase-js';
|
|
|
64
64
|
import type { Event } from '../../types/unified';
|
|
65
65
|
import type { Database } from '../../types/database';
|
|
66
66
|
import { usePublicPageContext } from '../../components/PublicLayout/PublicPageProvider';
|
|
67
|
+
import { logger } from '../../utils/core/logger';
|
|
67
68
|
|
|
68
69
|
// Simple in-memory cache for public data
|
|
69
70
|
const publicDataCache = new Map<string, { data: any; timestamp: number; ttl: number }>();
|
|
@@ -127,7 +128,7 @@ export function usePublicEvent(
|
|
|
127
128
|
if (typeof window === 'undefined') return null;
|
|
128
129
|
|
|
129
130
|
if (!environment.supabaseUrl || !environment.supabaseKey) {
|
|
130
|
-
|
|
131
|
+
logger.warn('usePublicEvent', 'Missing Supabase environment variables. Please ensure VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY are set in your environment.');
|
|
131
132
|
return null;
|
|
132
133
|
}
|
|
133
134
|
|
|
@@ -141,7 +142,7 @@ export function usePublicEvent(
|
|
|
141
142
|
await (supabase as any).from('information_schema.routines').select('routine_name').limit(1);
|
|
142
143
|
} catch (error) {
|
|
143
144
|
// Ignore errors, this is just an attempt to refresh cache
|
|
144
|
-
|
|
145
|
+
logger.debug('usePublicEvent', 'Schema cache refresh attempt failed:', error);
|
|
145
146
|
}
|
|
146
147
|
}, [supabase]);
|
|
147
148
|
|
|
@@ -184,7 +185,7 @@ export function usePublicEvent(
|
|
|
184
185
|
if (rpcError.message?.includes('Could not find the function') ||
|
|
185
186
|
rpcError.message?.includes('does not exist') ||
|
|
186
187
|
rpcError.message?.includes('schema cache')) {
|
|
187
|
-
|
|
188
|
+
logger.warn('usePublicEvent', 'RPC function not found or schema cache issue, attempting refresh:', rpcError.message);
|
|
188
189
|
|
|
189
190
|
// Try to refresh schema cache first
|
|
190
191
|
await refreshSchemaCache();
|
|
@@ -204,7 +205,7 @@ export function usePublicEvent(
|
|
|
204
205
|
throw new Error('RPC still failing after cache refresh');
|
|
205
206
|
}
|
|
206
207
|
} catch (retryError) {
|
|
207
|
-
|
|
208
|
+
logger.warn('usePublicEvent', 'RPC still failing after cache refresh, falling back to direct table access');
|
|
208
209
|
|
|
209
210
|
// Fallback: Direct table access with public RLS policy
|
|
210
211
|
const tableResponse2 = await (supabase as any)
|
|
@@ -281,7 +282,7 @@ export function usePublicEvent(
|
|
|
281
282
|
}
|
|
282
283
|
} catch (rpcError) {
|
|
283
284
|
// If RPC call fails for any reason (including schema cache issues), try direct table access
|
|
284
|
-
|
|
285
|
+
logger.warn('usePublicEvent', 'RPC call failed, falling back to direct table access:', rpcError);
|
|
285
286
|
|
|
286
287
|
const tableResponse = await (supabase as any)
|
|
287
288
|
.from('event')
|
|
@@ -372,7 +373,7 @@ export function usePublicEvent(
|
|
|
372
373
|
}
|
|
373
374
|
|
|
374
375
|
} catch (err) {
|
|
375
|
-
|
|
376
|
+
logger.error('usePublicEvent', 'Error fetching event:', err);
|
|
376
377
|
const error = err instanceof Error ? err : new Error('Unknown error occurred');
|
|
377
378
|
setError(error);
|
|
378
379
|
setEvent(null);
|
|
@@ -67,6 +67,9 @@
|
|
|
67
67
|
import { useState, useEffect, useCallback, useMemo } from 'react';
|
|
68
68
|
import type { SupabaseClient } from '@supabase/supabase-js';
|
|
69
69
|
import type { Database } from '../../types/database';
|
|
70
|
+
import { createLogger } from '../../utils/core/logger';
|
|
71
|
+
|
|
72
|
+
const log = createLogger('usePublicEventLogo');
|
|
70
73
|
|
|
71
74
|
// Simple in-memory cache for public data
|
|
72
75
|
const publicDataCache = new Map<string, { data: any; timestamp: number; ttl: number }>();
|
|
@@ -155,7 +158,7 @@ export function usePublicEventLogo(
|
|
|
155
158
|
// Validate UUID format for organisationId to prevent database errors
|
|
156
159
|
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
157
160
|
if (!uuidRegex.test(organisationId)) {
|
|
158
|
-
|
|
161
|
+
log.warn('Invalid organisationId format (not a valid UUID):', organisationId);
|
|
159
162
|
// Don't return early - let the database handle the validation
|
|
160
163
|
// This allows for more graceful error handling
|
|
161
164
|
}
|
|
@@ -198,12 +201,12 @@ export function usePublicEventLogo(
|
|
|
198
201
|
try {
|
|
199
202
|
const response = await fetch(logoUrl, { method: 'HEAD' });
|
|
200
203
|
if (!response.ok) {
|
|
201
|
-
|
|
204
|
+
log.warn('Logo URL not accessible:', logoUrl);
|
|
202
205
|
setLogoUrl(null);
|
|
203
206
|
return;
|
|
204
207
|
}
|
|
205
208
|
} catch (fetchError) {
|
|
206
|
-
|
|
209
|
+
log.warn('Error validating logo URL:', fetchError);
|
|
207
210
|
setLogoUrl(null);
|
|
208
211
|
return;
|
|
209
212
|
}
|
|
@@ -221,7 +224,7 @@ export function usePublicEventLogo(
|
|
|
221
224
|
}
|
|
222
225
|
|
|
223
226
|
} catch (err) {
|
|
224
|
-
|
|
227
|
+
log.error('Error fetching logo:', err);
|
|
225
228
|
const error = err instanceof Error ? err : new Error('Unknown error occurred');
|
|
226
229
|
setError(error);
|
|
227
230
|
setLogoUrl(null);
|