@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
package/dist/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/debugLogger.ts","../src/utils/validation.ts","../src/utils/validationUtils.ts","../src/utils/sanitization.ts","../src/utils/security.ts","../src/constants/performance.ts","../src/utils/performanceBenchmark.ts","../src/utils/bundleAnalysis.ts","../src/utils/dynamicUtils.ts","../src/utils/lazyLoad.tsx","../src/utils/permissionUtils.ts","../src/utils/permissionTypes.ts","../src/utils/schemaUtils.ts","../src/utils/securityMonitor.ts","../src/utils/audit.ts","../src/utils/deviceFingerprint.ts","../src/utils/index.ts"],"sourcesContent":["/**\n * @file Debug Logger Utility\n * @package @jmruthers/pace-core\n * @module Utils/DebugLogger\n * @since 0.4.76\n */\n\n/**\n * Debug logger that respects environment settings\n * Only logs in development mode to prevent production console spam\n */\nexport class DebugLogger {\n /**\n * Check if we're in development mode\n */\n private static get isDevelopment(): boolean {\n return import.meta.env.MODE === 'development';\n }\n\n /**\n * Log debug information only in development mode\n */\n static log(component: string, message: string, ...args: any[]): void {\n if (this.isDevelopment) {\n try {\n console.log(`[${component}] ${message}`, ...args);\n } catch (e) {\n // Gracefully handle console method errors\n }\n }\n }\n\n /**\n * Log error information (always logged)\n */\n static error(component: string, message: string, ...args: any[]): void {\n try {\n console.error(`[${component}] ${message}`, ...args);\n } catch (e) {\n // Gracefully handle console method errors\n }\n }\n\n /**\n * Log warning information (always logged)\n */\n static warn(component: string, message: string, ...args: any[]): void {\n try {\n console.warn(`[${component}] ${message}`, ...args);\n } catch (e) {\n // Gracefully handle console method errors\n }\n }\n\n /**\n * Log info information only in development mode\n */\n static info(component: string, message: string, ...args: any[]): void {\n if (this.isDevelopment) {\n try {\n console.info(`[${component}] ${message}`, ...args);\n } catch (e) {\n // Gracefully handle console method errors\n }\n }\n }\n}\n","/**\n * @file Internal utilities for validation module\n * @internal This file contains implementation details that should not be used directly\n */\n\n/**\n * Utility functions for validating data in the application\n */\n\n/**\n * Check if a string is a valid email\n */\nexport function isValidEmail(email: string): boolean {\n const emailPattern = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return emailPattern.test(email);\n}\n\n/**\n * Check if a string is empty (either null, undefined, or just whitespace)\n */\nexport function isEmpty(value: string | null | undefined): boolean {\n return value === null || value === undefined || value.trim() === '';\n}\n\n/**\n * Check if a password meets minimum requirements\n */\nexport function isStrongPassword(password: string): boolean {\n // Minimum 8 characters, at least one uppercase, one lowercase, one number\n const passwordPattern = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d).{8,}$/;\n return passwordPattern.test(password);\n}\n\n/**\n * Check if a URL is valid\n */\nexport function isValidUrl(url: string): boolean {\n try {\n new URL(url);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Check if a date string is valid\n */\nexport function isValidDate(dateStr: string): boolean {\n const date = new Date(dateStr);\n return !isNaN(date.getTime());\n}\n\n/**\n * Check if a value is within a range\n */\nexport function isWithinRange(value: number, min: number, max: number): boolean {\n return value >= min && value <= max;\n}\n\n/**\n * Check if a value matches a specific pattern\n */\nexport function matchesPattern(value: string, pattern: RegExp): boolean {\n return pattern.test(value);\n}\n\n/**\n * Utility function to deep merge objects for schema combination\n * @internal\n */\nexport function deepMerge<T extends Record<string, unknown>>(\n target: T, \n source: Record<string, unknown>\n): T {\n const output = { ...target };\n \n if (isObject(target) && isObject(source)) {\n Object.keys(source).forEach(key => {\n if (isObject(source[key])) {\n if (!(key in target)) {\n Object.assign(output, { [key]: source[key] });\n } else {\n // Use a type assertion to safely handle the indexing\n const targetKey = key as keyof typeof target;\n const targetValue = target[targetKey];\n \n if (isObject(targetValue)) {\n // Safe cast using type assertion\n output[targetKey] = deepMerge(\n targetValue as Record<string, unknown>,\n source[key] as Record<string, unknown>\n ) as unknown as T[keyof T];\n }\n }\n } else {\n Object.assign(output, { [key]: source[key] });\n }\n });\n }\n \n return output as T;\n}\n\n/**\n * Type guard to check if a value is a plain object\n * @internal\n */\nexport function isObject(item: unknown): item is Record<string, unknown> {\n return item !== null && typeof item === 'object' && !Array.isArray(item);\n}\n","\n/**\n * @file Validation utilities\n * \n * Shared validation utilities with enhanced security\n */\n\nimport { z } from 'zod';\nimport { sanitizeUserInput, sanitizeFormData, type SanitizationOptions } from './sanitization';\n\n/**\n * Validates user input against a schema with automatic sanitization\n */\nexport function validateUserInput<T>(\n schema: z.ZodSchema<T>, \n data: unknown,\n sanitizationRules?: Record<string, SanitizationOptions>\n): { success: boolean; data?: T; error?: string } {\n return sanitizeFormData(data, schema, sanitizationRules);\n}\n\n/**\n * Sanitizes user input by removing potentially dangerous characters\n * @deprecated Use sanitizeUserInput from lib/sanitization instead\n */\nexport function sanitizeUserInput_deprecated(input: string): string {\n // Log deprecation warning\n console.warn('sanitizeUserInput is deprecated. Use sanitizeUserInput from lib/sanitization instead.');\n return sanitizeUserInput(input);\n}\n\n/**\n * Enhanced email validation with sanitization\n */\nexport const emailSchema = z.string()\n .transform(email => email.toLowerCase().trim())\n .pipe(z.string().min(1, 'Email is required').email('Invalid email format').max(254, 'Email too long'));\n\n/**\n * Enhanced password validation\n */\nexport const passwordSchema = z.string()\n .min(8, 'Password must be at least 8 characters')\n .max(128, 'Password too long')\n .regex(/[A-Z]/, 'Password must contain at least one uppercase letter')\n .regex(/[a-z]/, 'Password must contain at least one lowercase letter')\n .regex(/[0-9]/, 'Password must contain at least one number')\n .regex(/[^A-Za-z0-9]/, 'Password must contain at least one special character');\n\n/**\n * Username validation with sanitization\n */\nexport const usernameSchema = z.string()\n .transform(username => username.toLowerCase().trim())\n .pipe(z.string().min(3, 'Username must be at least 3 characters').max(30, 'Username too long').regex(/^[a-zA-Z0-9_-]+$/, 'Username can only contain letters, numbers, hyphens, and underscores'));\n\n/**\n * Name validation with sanitization\n */\nexport const nameSchema = z.string()\n .min(1, 'Name is required')\n .max(100, 'Name too long')\n .refine(name => {\n // Check for XSS attempts and other invalid patterns\n const dangerousPatterns = [\n /<script/i,\n /<img/i,\n /on\\w+\\s*=/i,\n /javascript:/i,\n /data:/i,\n /vbscript:/i\n ];\n \n return !dangerousPatterns.some(pattern => pattern.test(name));\n }, 'Name contains invalid characters')\n .transform(name => sanitizeUserInput(name, { \n allowHtml: false, \n maxLength: 100, \n trim: true \n }));\n\n/**\n * Phone number validation with sanitization\n */\nexport const phoneSchema = z.string()\n .min(10, 'Phone number must be at least 10 digits')\n .max(20, 'Phone number too long')\n .regex(/^[\\+]?[0-9\\s\\-\\(\\)\\.]+$/, 'Invalid phone number format')\n .refine(phone => {\n // Remove all non-digit characters and check length\n const digitsOnly = phone.replace(/\\D/g, '');\n return digitsOnly.length >= 10 && digitsOnly.length <= 15;\n }, 'Phone number must be between 10 and 15 digits');\n\n/**\n * URL validation with sanitization\n */\nexport const urlSchema = z.string()\n .min(1, 'URL is required')\n .max(2048, 'URL too long')\n .refine(url => {\n try {\n const parsed = new URL(url);\n return ['http:', 'https:'].includes(parsed.protocol);\n } catch {\n return false;\n }\n }, 'Invalid URL format')\n .refine(url => {\n // Additional security checks\n const dangerousPatterns = [\n /javascript:/i,\n /data:/i,\n /vbscript:/i,\n /file:/i,\n /mailto:/i\n ];\n \n return !dangerousPatterns.some(pattern => pattern.test(url));\n }, 'URL contains invalid protocol');\n","\n/**\n * @file Input Sanitization Layer\n * @package @jmruthers/pace-core\n * @module Security\n * @since 0.1.0\n * \n * Comprehensive input sanitization utilities to prevent XSS, injection attacks,\n * and other security vulnerabilities.\n */\n\nimport { z } from 'zod';\n\n/**\n * Sanitization options for different contexts\n */\nexport interface SanitizationOptions {\n allowHtml?: boolean;\n allowedTags?: string[];\n maxLength?: number;\n trim?: boolean;\n removeScripts?: boolean;\n removeEvents?: boolean;\n}\n\n/**\n * Default sanitization options\n */\nconst DEFAULT_OPTIONS: SanitizationOptions = {\n allowHtml: false,\n allowedTags: [],\n maxLength: 1000,\n trim: true,\n removeScripts: true,\n removeEvents: true\n};\n\n/**\n * Sanitizes user input by removing potentially dangerous characters and patterns\n */\nexport function sanitizeUserInput(input: string, options: SanitizationOptions = {}): string {\n if (typeof input !== 'string') {\n return '';\n }\n\n const opts = { ...DEFAULT_OPTIONS, ...options };\n let sanitized = input;\n\n // Trim whitespace if requested\n if (opts.trim) {\n sanitized = sanitized.trim();\n }\n\n // Enforce maximum length\n if (opts.maxLength && sanitized.length > opts.maxLength) {\n sanitized = sanitized.substring(0, opts.maxLength);\n }\n\n // Remove or escape HTML if not allowed\n if (!opts.allowHtml) {\n sanitized = sanitized\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\n } else if (opts.allowedTags && opts.allowedTags.length > 0) {\n // If HTML is allowed, only permit specific tags\n const allowedTagsRegex = new RegExp(`<(?!\\/?(?:${opts.allowedTags.join('|')})\\s*\\/?>)[^>]+>`, 'gi');\n sanitized = sanitized.replace(allowedTagsRegex, '');\n }\n\n // Remove script tags and javascript: protocols\n if (opts.removeScripts) {\n sanitized = sanitized\n .replace(/<script[^>]*>.*?<\\/script>/gi, '')\n .replace(/javascript:/gi, '')\n .replace(/vbscript:/gi, '')\n .replace(/data:/gi, '');\n }\n\n // Remove event handlers\n if (opts.removeEvents) {\n sanitized = sanitized.replace(/on\\w+\\s*=/gi, '');\n }\n\n return sanitized;\n}\n\n/**\n * Sanitizes email addresses\n */\nexport function sanitizeEmail(email: string): string {\n if (typeof email !== 'string') {\n return '';\n }\n\n return email\n .trim()\n .toLowerCase()\n .replace(/[^\\w@.-]/g, ''); // Only allow word characters, @, ., and -\n}\n\n/**\n * Sanitizes phone numbers\n */\nexport function sanitizePhoneNumber(phone: string): string {\n if (typeof phone !== 'string') {\n return '';\n }\n\n return phone.replace(/[^\\d+\\-\\s()]/g, '').trim();\n}\n\n/**\n * Sanitizes URLs\n */\nexport function sanitizeUrl(url: string): string {\n if (typeof url !== 'string') {\n return '';\n }\n\n const sanitized = url.trim();\n \n // Only allow http(s) and ftp protocols\n if (!/^https?:\\/\\/|^ftp:\\/\\//i.test(sanitized)) {\n return '';\n }\n\n // Remove javascript: and other dangerous protocols\n if (/javascript:|data:|vbscript:/i.test(sanitized)) {\n return '';\n }\n\n return sanitized;\n}\n\n/**\n * Sanitizes file names\n */\nexport function sanitizeFileName(fileName: string): string {\n if (typeof fileName !== 'string') {\n return '';\n }\n\n return fileName\n .trim()\n .replace(/[<>:\"/\\\\|?*]/g, '') // Remove invalid file name characters\n .replace(/\\.\\./g, '') // Remove directory traversal attempts\n .substring(0, 255); // Limit length\n}\n\n/**\n * Sanitizes SQL input to prevent injection\n */\nexport function sanitizeSqlInput(input: string): string {\n if (typeof input !== 'string') {\n return '';\n }\n\n return input\n .replace(/['\";\\\\]/g, '') // Remove SQL special characters\n .replace(/--.*$/gm, '') // Remove SQL comments\n .replace(/\\/\\*.*?\\*\\//g, '') // Remove SQL block comments\n .trim();\n}\n\n/**\n * Validates and sanitizes form data using Zod schemas\n */\nexport function sanitizeFormData<T>(\n data: unknown,\n schema: z.ZodSchema<T>,\n sanitizationRules?: Record<string, SanitizationOptions>\n): { success: boolean; data?: T; error?: string } {\n try {\n // First, sanitize string fields if rules are provided\n if (sanitizationRules && typeof data === 'object' && data !== null) {\n const sanitizedData = { ...data } as Record<string, unknown>;\n \n Object.entries(sanitizationRules).forEach(([field, options]) => {\n if (typeof sanitizedData[field] === 'string') {\n sanitizedData[field] = sanitizeUserInput(sanitizedData[field] as string, options);\n }\n });\n \n data = sanitizedData;\n }\n\n // Then validate with Zod schema\n const result = schema.parse(data);\n return { success: true, data: result };\n } catch (error) {\n if (error instanceof z.ZodError) {\n return { \n success: false, \n error: error.errors.map(e => e.message).join(', ') \n };\n }\n return { \n success: false, \n error: 'Validation failed' \n };\n }\n}\n\n/**\n * Content Security Policy (CSP) utilities\n */\nexport const CSP_DIRECTIVES = {\n default: \"default-src 'self'\",\n script: \"script-src 'self' 'unsafe-inline'\",\n style: \"style-src 'self' 'unsafe-inline'\",\n img: \"img-src 'self' data: https:\",\n font: \"font-src 'self'\",\n connect: \"connect-src 'self'\",\n frame: \"frame-src 'none'\"\n};\n\nexport function generateCSPHeader(customDirectives?: Partial<typeof CSP_DIRECTIVES>): string {\n const directives = { ...CSP_DIRECTIVES, ...customDirectives };\n return Object.values(directives).join('; ');\n}\n\n/**\n * Rate limiting utilities\n */\nexport class RateLimiter {\n private attempts: Map<string, { count: number; resetTime: number }> = new Map();\n\n constructor(\n private maxAttempts: number = 5,\n private windowMs: number = 15 * 60 * 1000 // 15 minutes\n ) {}\n\n isAllowed(identifier: string): boolean {\n const now = Date.now();\n const record = this.attempts.get(identifier);\n\n if (!record || now > record.resetTime) {\n this.attempts.set(identifier, { count: 1, resetTime: now + this.windowMs });\n return true;\n }\n\n if (record.count >= this.maxAttempts) {\n return false;\n }\n\n record.count++;\n return true;\n }\n\n getRemainingAttempts(identifier: string): number {\n const record = this.attempts.get(identifier);\n if (!record || Date.now() > record.resetTime) {\n return this.maxAttempts;\n }\n return Math.max(0, this.maxAttempts - record.count);\n }\n\n reset(identifier: string): void {\n this.attempts.delete(identifier);\n }\n}\n","\nimport type { SupabaseClient } from '@supabase/supabase-js';\n\nexport interface SecurityEvent {\n type: string;\n timestamp: Date;\n userId?: string;\n details: Record<string, unknown>;\n}\n\nexport function logSecurityEvent(event: SecurityEvent): void {\n // In production, this should log to your security monitoring system\n // For now, we'll log to console.warn for testing purposes\n console.warn('[SECURITY EVENT]', {\n ...event,\n timestamp: event.timestamp.toISOString()\n });\n}\n\nexport function validateUserSession(userId: string, sessionToken?: string): Promise<boolean> {\n // Mock implementation - replace with actual session validation\n if (!userId || typeof userId !== 'string') {\n logSecurityEvent({\n type: 'invalid_session_validation',\n timestamp: new Date(),\n details: { reason: 'Invalid userId provided' }\n });\n return Promise.resolve(false);\n }\n \n if (sessionToken && sessionToken.length < 10) {\n logSecurityEvent({\n type: 'suspicious_session_token',\n timestamp: new Date(),\n userId,\n details: { reason: 'Session token too short' }\n });\n return Promise.resolve(false);\n }\n \n return Promise.resolve(true);\n}\n\nexport function createSecureSession(\n _supabaseClient: SupabaseClient,\n sessionData: { userId: string; deviceFingerprint?: string }\n): Promise<string> {\n // Mock implementation - in production, create actual secure session\n const sessionId = `sess_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n \n logSecurityEvent({\n type: 'session_created',\n timestamp: new Date(),\n userId: sessionData.userId,\n details: { \n sessionId,\n hasDeviceFingerprint: !!sessionData.deviceFingerprint\n }\n });\n \n return Promise.resolve(sessionId);\n}\n\nexport function invalidateSession(\n _supabaseClient: SupabaseClient,\n sessionId: string\n): Promise<void> {\n // Mock implementation - in production, invalidate actual session\n logSecurityEvent({\n type: 'session_invalidated',\n timestamp: new Date(),\n details: { sessionId }\n });\n \n return Promise.resolve();\n}\n\nexport function getSecurityHeaders(): Record<string, string> {\n return {\n 'X-Content-Type-Options': 'nosniff',\n 'X-Frame-Options': 'DENY',\n 'X-XSS-Protection': '1; mode=block',\n 'Referrer-Policy': 'strict-origin-when-cross-origin',\n 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains'\n };\n}\n\nexport function validateSecurityHeaders(headers: Record<string, string>): boolean {\n const requiredHeaders = ['X-Content-Type-Options', 'X-Frame-Options'];\n const missingHeaders = requiredHeaders.filter(header => !headers[header]);\n \n if (missingHeaders.length > 0) {\n logSecurityEvent({\n type: 'missing_security_headers',\n timestamp: new Date(),\n details: { missingHeaders }\n });\n return false;\n }\n \n return true;\n}\n\nexport function generateDeviceFingerprint(): string {\n // Basic device fingerprinting - in production, use more sophisticated methods\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n if (ctx) {\n ctx.textBaseline = 'top';\n ctx.font = '14px Arial';\n ctx.fillText('Device fingerprint', 2, 2);\n }\n \n const fingerprint = [\n navigator.userAgent,\n navigator.language,\n screen.width + 'x' + screen.height,\n new Date().getTimezoneOffset(),\n canvas.toDataURL()\n ].join('|');\n \n // Simple hash function for demonstration\n let hash = 0;\n for (let i = 0; i < fingerprint.length; i++) {\n const char = fingerprint.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n \n return Math.abs(hash).toString(16);\n}\n\nexport function validateDeviceFingerprint(fingerprint: string, expectedFingerprint?: string): boolean {\n if (!fingerprint || typeof fingerprint !== 'string') {\n logSecurityEvent({\n type: 'invalid_device_fingerprint',\n timestamp: new Date(),\n details: { reason: 'Invalid fingerprint format' }\n });\n return false;\n }\n \n if (expectedFingerprint && fingerprint !== expectedFingerprint) {\n logSecurityEvent({\n type: 'device_fingerprint_mismatch',\n timestamp: new Date(),\n details: { \n provided: fingerprint,\n expected: expectedFingerprint\n }\n });\n return false;\n }\n \n return true;\n}\n","/**\n * Performance thresholds and constants\n */\n\nexport const PERFORMANCE_THRESHOLDS = {\n RENDER_TIME: 16, // 60fps target\n INTERACTION_TIME: 100, // 100ms for interactions\n ANIMATION_TIME: 300, // 300ms for animations\n LOAD_TIME: 1000, // 1 second for initial load\n MEMORY_USAGE: 50 * 1024 * 1024, // 50MB memory limit\n BUNDLE_SIZE: 250 * 1024, // 250KB bundle size limit\n} as const;\n\nexport type PerformanceThreshold = keyof typeof PERFORMANCE_THRESHOLDS; ","/**\n * Performance benchmarking utilities\n */\n\nexport interface PerformanceMetrics {\n renderTime: number;\n interactionTime: number;\n memoryUsage: number;\n bundleSize: number;\n}\n\nexport function createPerformanceBenchmark(name: string) {\n const startTime = performance.now();\n const startMemory = (performance as any).memory?.usedJSHeapSize || 0;\n\n return {\n end: () => {\n const endTime = performance.now();\n const endMemory = (performance as any).memory?.usedJSHeapSize || 0;\n \n const metrics: PerformanceMetrics = {\n renderTime: endTime - startTime,\n interactionTime: 0, // Would be measured separately\n memoryUsage: endMemory - startMemory,\n bundleSize: 0, // Would be measured at build time\n };\n\n // TODO: Replace with proper logging service integration\n // For now, we'll use a no-op to prevent console pollution\n const _unused = { \n benchmark: `Performance Benchmark [${name}]`, \n metrics \n };\n \n return metrics;\n }\n };\n}\n\nexport function measureRenderPerformance(componentName: string, renderFn: () => void): PerformanceMetrics {\n const startTime = performance.now();\n const startMemory = (performance as any).memory?.usedJSHeapSize || 0;\n \n renderFn();\n \n const endTime = performance.now();\n const endMemory = (performance as any).memory?.usedJSHeapSize || 0;\n \n const metrics: PerformanceMetrics = {\n renderTime: endTime - startTime,\n interactionTime: 0,\n memoryUsage: endMemory - startMemory,\n bundleSize: 0,\n };\n \n // TODO: Replace with proper logging service integration\n // For now, we'll use a no-op to prevent console pollution\n const _unused = { \n benchmark: `Render Performance [${componentName}]`, \n metrics \n };\n \n return metrics;\n} ","\ninterface BundleStats {\n totalSize: number;\n gzippedSize: number;\n chunks: ChunkInfo[];\n treeshakingEffectiveness: number;\n}\n\ninterface ChunkInfo {\n name: string;\n size: number;\n modules: string[];\n dynamicallyImported: boolean;\n}\n\nclass BundleAnalyzer {\n private enabled = import.meta.env.MODE === 'development';\n\n analyzeBundle(): BundleStats | null {\n if (!this.enabled) return null;\n\n // In a real implementation, this would integrate with webpack-bundle-analyzer\n // or similar tools. For now, we'll simulate analysis\n \n // TODO: Replace with proper logging service integration\n // For now, we'll log to console for testing purposes\n console.log('Bundle analysis would run here in development');\n console.log('To enable real bundle analysis:');\n console.log('1. Install webpack-bundle-analyzer');\n console.log('2. Add bundle analysis to build scripts');\n console.log('3. Integrate with performance budgets');\n\n return {\n totalSize: 0,\n gzippedSize: 0,\n chunks: [],\n treeshakingEffectiveness: 0\n };\n }\n\n checkTreeshaking(): void {\n if (!this.enabled) return;\n\n const potentialIssues = [\n 'Check for unused exports in index files',\n 'Verify side-effect free modules in package.json',\n 'Ensure proper ES module syntax',\n 'Check for circular dependencies'\n ];\n\n // TODO: Replace with proper logging service integration\n // For now, we'll log to console for testing purposes\n console.group('Tree-shaking Analysis');\n potentialIssues.forEach(issue => console.log('- ' + issue));\n console.groupEnd();\n }\n\n validateExports(): void {\n if (!this.enabled) return;\n\n // TODO: Replace with proper logging service integration\n // For now, we'll log to console for testing purposes\n console.group('Export Validation');\n console.log('Checking for optimal export patterns...');\n console.log('- Prefer named exports over default exports');\n console.log('- Avoid barrel exports for large modules');\n console.log('- Use dynamic imports for large dependencies');\n console.groupEnd();\n }\n\n generateReport(): string {\n const report = `\n# Bundle Analysis Report\n\n## Recommendations for @jmruthers/pace-core\n\n### 1. Code Splitting Opportunities\n- ✅ DataTable virtualization is lazy-loaded\n- ⚠️ Consider splitting auth providers by use case\n- ⚠️ Lazy load heavy UI components (charts, complex forms)\n\n### 2. Tree-shaking Optimization\n- ✅ Using ES modules throughout\n- ✅ Proper sideEffects configuration\n- ⚠️ Check for unused utility functions\n\n### 3. Bundle Size Targets\n- Core components: < 50KB gzipped\n- Auth module: < 30KB gzipped \n- Utilities: < 20KB gzipped\n- Total package: < 150KB gzipped\n\n### 4. Performance Monitoring\n- Monitor component render times\n- Track bundle size changes\n- Validate tree-shaking effectiveness\n `;\n\n return report.trim();\n }\n}\n\nexport const bundleAnalyzer = new BundleAnalyzer();\n\n// Helper to check if imports are optimized\nexport function validateImportPattern(moduleId: string, importedItems: string[]): void {\n if (import.meta.env.MODE !== 'development') return;\n\n const largeModules = ['lodash', 'moment', 'rxjs'];\n const isLargeModule = largeModules.some(mod => moduleId.includes(mod));\n \n if (isLargeModule && importedItems.length > 5) {\n // TODO: Replace with proper logging service integration\n // For now, we'll log to console for testing purposes\n console.warn(\n 'Large import detected: importing ' + importedItems.length + ' items from ' + moduleId + '. ' +\n 'Consider splitting imports or using more specific imports.'\n );\n }\n}\n\n// Monitor dynamic imports\nexport function trackDynamicImport(moduleName: string): void {\n if (import.meta.env.MODE !== 'development') return;\n \n // TODO: Replace with proper logging service integration\n // For now, we'll log to console for testing purposes\n console.log('Dynamic import: ' + moduleName + ' - Good for code splitting!');\n}\n","\n/**\n * Dynamic utility loader to reduce initial bundle size\n * Heavy utilities are loaded on-demand\n */\n\n// Type definitions for dynamic imports\ntype DebounceFunction = <T extends (...args: unknown[]) => unknown>(\n func: T,\n wait?: number,\n options?: { leading?: boolean; maxWait?: number; trailing?: boolean }\n) => T & { cancel(): void; flush(): void };\n\ntype ThrottleFunction = <T extends (...args: unknown[]) => unknown>(\n func: T,\n wait?: number,\n options?: { leading?: boolean; trailing?: boolean }\n) => T & { cancel(): void; flush(): void };\n\n// Dynamic lodash utilities\nexport const loadLodash = async (): Promise<{\n debounce: DebounceFunction;\n throttle: ThrottleFunction;\n}> => {\n const [debounceModule, throttleModule] = await Promise.all([\n import('lodash.debounce' as any),\n import('lodash.throttle' as any)\n ]);\n \n return {\n debounce: (debounceModule.default || debounceModule) as DebounceFunction,\n throttle: (throttleModule.default || throttleModule) as ThrottleFunction\n };\n};\n\n// Dynamic date utilities\nexport const loadDateUtils = async (): Promise<typeof import('date-fns')> => {\n const dateFns = await import('date-fns');\n return dateFns;\n};\n\n// Dynamic chart utilities - using unknown type to avoid Recharts type issues\nexport const loadChartUtils = async (): Promise<unknown> => {\n const recharts = await import('recharts');\n return recharts;\n};\n\n// Dynamic form utilities\nexport const loadFormUtils = async (): Promise<{\n useForm: unknown;\n useController: unknown;\n Controller: unknown;\n FormProvider: unknown;\n useFormContext: unknown;\n useWatch: unknown;\n useFormState: unknown;\n useFieldArray: unknown;\n zodResolver: unknown;\n}> => {\n const [reactHookForm, zodResolvers] = await Promise.all([\n import('react-hook-form'),\n import('@hookform/resolvers/zod')\n ]);\n \n return {\n ...reactHookForm,\n zodResolver: zodResolvers.zodResolver\n };\n};\n\n// Dynamic CSV utilities\nexport const loadCSVUtils = async (): Promise<unknown> => {\n const papaparse = await import('papaparse');\n return papaparse.default;\n};\n\n// Utility function to create lazy utility hooks\nexport function createLazyUtility<T>(loader: () => Promise<T>) {\n let cached: T | null = null;\n let loading: Promise<T> | null = null;\n\n return {\n load: async (): Promise<T> => {\n if (cached) return cached;\n if (loading) return loading;\n\n loading = loader().then(result => {\n cached = result;\n loading = null;\n return result;\n });\n\n return loading;\n },\n getCached: (): T | null => cached,\n isLoaded: (): boolean => cached !== null\n };\n}\n\n// Pre-configured lazy utilities with explicit types\nexport const lazyLodash: ReturnType<typeof createLazyUtility<Awaited<ReturnType<typeof loadLodash>>>> = createLazyUtility(loadLodash);\nexport const lazyDateUtils: ReturnType<typeof createLazyUtility<Awaited<ReturnType<typeof loadDateUtils>>>> = createLazyUtility(loadDateUtils);\nexport const lazyChartUtils: ReturnType<typeof createLazyUtility<unknown>> = createLazyUtility(loadChartUtils);\nexport const lazyFormUtils: ReturnType<typeof createLazyUtility<Awaited<ReturnType<typeof loadFormUtils>>>> = createLazyUtility(loadFormUtils);\nexport const lazyCSVUtils: ReturnType<typeof createLazyUtility<unknown>> = createLazyUtility(loadCSVUtils);\n","import React, { Suspense, ComponentType, lazy } from 'react';\nimport { LoadingSpinner } from '../components/LoadingSpinner/LoadingSpinner';\n\ninterface LazyLoadOptions {\n fallback?: React.ReactNode;\n errorBoundary?: ComponentType<{ children: React.ReactNode }>;\n}\n\n/**\n * Create a lazy-loaded component with error boundary and loading fallback\n */\nexport function createLazyComponent<T extends ComponentType<any>>(\n importFn: () => Promise<{ default: T }>,\n componentName: string,\n options: LazyLoadOptions = {}\n): T {\n const LazyComponent = lazy(importFn);\n \n const WrappedComponent = (props: any) => {\n const content = (\n <Suspense fallback={options.fallback || <LoadingSpinner />}>\n <LazyComponent {...props} />\n </Suspense>\n );\n\n if (options.errorBoundary) {\n const ErrorBoundary = options.errorBoundary;\n return <ErrorBoundary>{content}</ErrorBoundary>;\n }\n\n return content;\n };\n \n WrappedComponent.displayName = `Lazy${componentName}`;\n return WrappedComponent as T;\n}\n\n/**\n * Lazy-loaded DataTable component\n */\nexport const LazyDataTable = createLazyComponent(\n () => import('../components/DataTable').then(module => ({ default: module.DataTable })),\n 'DataTable'\n);\n","\n/**\n * Permission utilities for transforming and managing permissions\n */\n\nexport function transformPermissionMapToBoolean(permissions: Record<string, unknown>): Record<string, boolean> {\n const result: Record<string, boolean> = {};\n \n Object.entries(permissions).forEach(([key, value]) => {\n if (typeof value === 'string') {\n // Handle string values - 'false' should be false, empty strings are false, other non-empty strings are true\n result[key] = value !== '' && value.toLowerCase() !== 'false';\n } else {\n result[key] = Boolean(value);\n }\n });\n \n return result;\n}\n\nexport function hasPermission(permissions: Record<string, boolean>, permission: string): boolean {\n return Boolean(permissions[permission]);\n}\n\nexport function hasAnyPermission(permissions: Record<string, boolean>, permissionList: string[] | null | undefined): boolean {\n if (!permissionList || permissionList.length === 0) return false;\n return permissionList.some(permission => hasPermission(permissions, permission));\n}\n\nexport function hasAllPermissions(permissions: Record<string, boolean>, permissionList: string[] | null | undefined): boolean {\n if (!permissionList) return false;\n if (permissionList.length === 0) return true;\n return permissionList.every(permission => hasPermission(permissions, permission));\n}\n","\n/**\n * @file Permission type definitions and utilities\n */\n\nexport enum PermissionType {\n READ = 'read',\n WRITE = 'write',\n DELETE = 'delete',\n ADMIN = 'admin'\n}\n\n/**\n * Parse a permission string into components\n */\nexport function parsePermission(permission: string): { resource: string; action: string } | null {\n if (!permission || typeof permission !== 'string') {\n return null;\n }\n \n const parts = permission.split(':');\n if (parts.length !== 2) {\n return null;\n }\n \n const [action, resource] = parts;\n \n // Check that both action and resource exist and are not empty\n if (action === undefined || resource === undefined || action === '' || resource === '') {\n return null;\n }\n \n return {\n resource,\n action\n };\n}\n","import { z } from 'zod';\n\n/**\n * Creates a subset schema from a larger schema\n * \n * @param schema - Original Zod schema\n * @param keys - Array of keys to pick from the schema\n * @returns New schema with only the selected fields\n */\nexport function pickSchema<T extends z.ZodObject<any, any, any>, K extends keyof z.infer<T>>(\n schema: T,\n keys: K[]\n): z.ZodObject<any> {\n const shape = Object.entries(schema.shape)\n .filter(([key]) => keys.includes(key as K))\n .reduce((acc, [key, value]) => {\n acc[key] = value as z.ZodTypeAny;\n return acc;\n }, {} as Record<string, z.ZodTypeAny>);\n\n return z.object(shape);\n}\n\n/**\n * Combines multiple Zod schemas into one\n * \n * @param schemas - Array of Zod schemas to combine\n * @returns Combined schema\n */\nexport function combineSchemas<T extends z.ZodObject<any, any, any>[]>(\n schemas: T\n): z.ZodObject<any> {\n return schemas.reduce(\n (merged, schema) => merged.merge(schema),\n z.object({})\n );\n} ","\ninterface SecurityEvent {\n id?: string;\n action: string;\n details: Record<string, any>;\n timestamp?: number;\n}\n\ninterface SecurityAlert {\n id: string;\n type: string;\n message: string;\n timestamp: Date;\n}\n\nclass SecurityMonitor {\n private events: SecurityEvent[] = [];\n\n logEvent(event: SecurityEvent) {\n const eventWithId = {\n ...event,\n id: Math.random().toString(36).substr(2, 9),\n timestamp: Date.now()\n };\n this.events.push(eventWithId);\n }\n\n getEvents(): SecurityEvent[] {\n return [...this.events];\n }\n\n clearEvents() {\n this.events = [];\n }\n\n createAlert(alert: Omit<SecurityAlert, 'id' | 'timestamp'>): SecurityAlert {\n return {\n ...alert,\n id: Math.random().toString(36).substr(2, 9),\n timestamp: new Date()\n };\n }\n}\n\nexport const securityMonitor = new SecurityMonitor();\n","\n/**\n * @file Audit Logger - General Utility\n * \n * Moved from shared/auditLogger to lib for better organization\n */\n\nexport interface AuditEvent {\n type: 'auth' | 'permission' | 'security';\n action?: string;\n event?: string;\n user?: string;\n userId?: string;\n details?: Record<string, unknown>;\n data?: Record<string, unknown>;\n timestamp?: number;\n severity?: 'low' | 'medium' | 'high' | 'critical';\n source?: string;\n}\n\nclass AuditLogger {\n private events: AuditEvent[] = [];\n\n log(event: AuditEvent): void {\n const eventWithTimestamp = {\n ...event,\n timestamp: Date.now(),\n };\n \n this.events.push(eventWithTimestamp);\n // TODO: In production, this should send to a proper logging service\n // Console logging removed for production\n }\n\n async logPermissionEvent(event: {\n event: string;\n userId: string;\n data?: Record<string, unknown>;\n }): Promise<void> {\n this.log({\n type: 'permission',\n event: event.event,\n userId: event.userId,\n data: event.data,\n });\n }\n\n async logSecurityEvent(event: {\n event: string;\n data?: Record<string, unknown>;\n }): Promise<void> {\n this.log({\n type: 'security',\n event: event.event,\n data: event.data,\n });\n }\n\n async logAuthEvent(event: {\n event: string;\n userId?: string;\n data?: Record<string, unknown>;\n }): Promise<void> {\n this.log({\n type: 'auth',\n event: event.event,\n userId: event.userId,\n data: event.data,\n });\n }\n\n async getSecurityEvents(): Promise<AuditEvent[]> {\n return this.events.filter(event => event.type === 'security');\n }\n\n getEvents(): AuditEvent[] {\n return [...this.events];\n }\n\n clearEvents(): void {\n this.events = [];\n }\n}\n\nexport const auditLogger = new AuditLogger();\n\n// Alias for backward compatibility\nexport const auditLog = auditLogger;\n\nexport function logAuthEvent(action: string, user?: string, details?: Record<string, unknown>): void {\n auditLogger.log({\n type: 'auth',\n action,\n user,\n details,\n });\n // Console logging removed for production\n}\n\nexport function logPermissionEvent(action: string, user?: string, details?: Record<string, unknown>): void {\n auditLogger.log({\n type: 'permission',\n action,\n user,\n details,\n });\n // Console logging removed for production\n}\n\nexport function logSecurityEvent(action: string, user?: string, details?: Record<string, unknown>): void {\n auditLogger.log({\n type: 'security',\n action,\n user,\n details,\n });\n // Console logging removed for production\n}\n\nexport function logAuditEvent(action: string, user?: string, details?: Record<string, unknown>): void {\n auditLogger.log({\n type: 'auth', // Default to auth type for general audit events\n action,\n user,\n details,\n });\n}\n","/**\n * @file Secure Device Fingerprinting\n * @description Enhanced device fingerprinting with encryption and security measures\n */\n\nimport { secureStorage } from './secureStorage';\n\nexport interface DeviceFingerprint {\n hash: string;\n timestamp: number;\n components: {\n userAgent: string;\n language: string;\n platform: string;\n screen: string;\n timezone: string;\n canvas?: string;\n webgl?: string;\n };\n entropy: number;\n}\n\n/**\n * Generate a secure device fingerprint (synchronous)\n */\nexport function generateDeviceFingerprint(): DeviceFingerprint {\n try {\n const components = {\n userAgent: getHashedUserAgent(),\n language: navigator.language || 'unknown',\n platform: navigator.platform || 'unknown',\n screen: `${screen.width}x${screen.height}x${screen.colorDepth}`,\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone || 'unknown',\n canvas: getCanvasFingerprint(),\n webgl: getWebGLFingerprint(),\n };\n\n // Calculate entropy (uniqueness score)\n const entropy = calculateEntropy(components);\n \n // Create a hash from all components\n const fingerprintData = JSON.stringify(components);\n const hash = hashStringSync(fingerprintData);\n\n const fingerprint: DeviceFingerprint = {\n hash,\n timestamp: Date.now(),\n components,\n entropy,\n };\n\n // Store fingerprint asynchronously\n secureStorage.setItem('device_fingerprint', JSON.stringify(fingerprint));\n \n return fingerprint;\n } catch (error) {\n return generateFallbackFingerprint();\n }\n}\n\n/**\n * Validate device fingerprint with security checks\n */\nexport function validateDeviceFingerprint(\n storedFingerprint: DeviceFingerprint,\n currentFingerprint: DeviceFingerprint\n): {\n isValid: boolean;\n confidence: number;\n reasons: string[];\n} {\n const reasons: string[] = [];\n let matchingComponents = 0;\n const totalComponents = Object.keys(storedFingerprint.components).length;\n\n // Check each component\n Object.entries(storedFingerprint.components).forEach(([key, value]) => {\n if (currentFingerprint.components[key as keyof typeof currentFingerprint.components] === value) {\n matchingComponents++;\n } else {\n reasons.push(`Component mismatch: ${key}`);\n }\n });\n\n // Calculate confidence score\n const confidence = (matchingComponents / totalComponents) * 100;\n\n // Security thresholds\n const isValid = confidence >= 80; // Require 80% match\n \n // Additional security checks\n const timeDiff = currentFingerprint.timestamp - storedFingerprint.timestamp;\n const maxAge = 30 * 24 * 60 * 60 * 1000; // 30 days\n \n if (timeDiff > maxAge) {\n reasons.push('Fingerprint too old');\n return { isValid: false, confidence, reasons };\n }\n\n if (confidence < 60) {\n reasons.push('Device signature changed significantly');\n }\n\n return { isValid, confidence, reasons };\n}\n\n/**\n * Generate canvas fingerprint for enhanced uniqueness\n */\nfunction getCanvasFingerprint(): string {\n try {\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n \n if (!ctx) return 'canvas-unavailable';\n\n // Draw complex pattern for fingerprinting\n ctx.textBaseline = 'top';\n ctx.font = '14px Arial';\n ctx.fillStyle = '#f60';\n ctx.fillRect(125, 1, 62, 20);\n ctx.fillStyle = '#069';\n ctx.fillText('Device fingerprint 🔒', 2, 15);\n ctx.fillStyle = 'rgba(102, 204, 0, 0.2)';\n ctx.fillText('Device fingerprint 🔒', 4, 17);\n\n const dataURL = canvas.toDataURL();\n return hashStringSync(dataURL);\n } catch (error) {\n return 'canvas-error';\n }\n}\n\n/**\n * Get WebGL fingerprint\n */\nfunction getWebGLFingerprint(): string {\n try {\n const canvas = document.createElement('canvas');\n const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl') as WebGLRenderingContext | null;\n \n if (!gl) return 'webgl-unavailable';\n\n const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');\n if (!debugInfo) return 'webgl-no-debug';\n\n const vendor = gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL);\n const renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);\n \n return `${vendor}|${renderer}`;\n } catch (error) {\n return 'webgl-error';\n }\n}\n\n/**\n * Hash user agent to prevent direct exposure\n */\nfunction getHashedUserAgent(): string {\n const ua = navigator.userAgent;\n return hashStringSync(ua).substring(0, 16); // Shorter hash for storage\n}\n\n/**\n * Calculate entropy of fingerprint components\n */\nfunction calculateEntropy(components: Record<string, string>): number {\n const values = Object.values(components).join('');\n const charCounts = new Map<string, number>();\n \n for (const char of values) {\n charCounts.set(char, (charCounts.get(char) || 0) + 1);\n }\n \n let entropy = 0;\n for (const count of charCounts.values()) {\n const probability = count / values.length;\n entropy -= probability * Math.log2(probability);\n }\n \n return entropy;\n}\n\n/**\n * Synchronous hash function for device fingerprinting\n */\nfunction hashStringSync(str: string): string {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash;\n }\n return Math.abs(hash).toString(36);\n}\n\n/**\n * Generate fallback fingerprint for error cases\n */\nfunction generateFallbackFingerprint(): DeviceFingerprint {\n const components = {\n userAgent: 'fallback',\n language: 'unknown',\n platform: 'unknown',\n screen: 'unknown',\n timezone: 'unknown',\n };\n\n return {\n hash: `fallback_${Date.now()}_${Math.random().toString(36)}`,\n timestamp: Date.now(),\n components,\n entropy: 1, // Low entropy for fallback\n };\n}\n","/**\n * @file Utility functions exports\n * @package @jmruthers/pace-core\n * @module Utils\n * @since 0.1.0\n */\n\n// Core utilities\nexport { cn } from './cn';\nexport { DebugLogger } from './debugLogger';\n\n// App configuration utilities\nexport * from './appNameResolver';\nexport * from './appConfig';\n\n// Validation and sanitization\nexport * from './validation';\nexport * from './validationUtils';\nexport * from './sanitization';\n\n// Security utilities\nexport { \n getSecurityHeaders, \n validateSecurityHeaders\n} from './security';\n\n// Note: Accessibility testing utilities are only available in test environments\n// They are not exported in production builds to avoid including test dependencies\n\n// Performance utilities\nexport { useComponentPerformance } from '../hooks/useComponentPerformance';\nexport { PERFORMANCE_THRESHOLDS } from '../constants/performance';\nexport { createPerformanceBenchmark, measureRenderPerformance } from './performanceBenchmark';\nexport type { PerformanceMetrics } from './performanceBenchmark';\n\n// Bundle analysis utilities\nexport { \n bundleAnalyzer, \n validateImportPattern, \n trackDynamicImport \n} from './bundleAnalysis';\n\n// Dynamic utility loaders\nexport { \n loadLodash, \n loadDateUtils, \n loadChartUtils,\n loadFormUtils,\n loadCSVUtils,\n createLazyUtility,\n lazyLodash,\n lazyDateUtils,\n lazyChartUtils,\n lazyFormUtils,\n lazyCSVUtils\n} from './dynamicUtils';\n\n// Performance budget utilities\nexport { \n performanceBudgetMonitor, \n PERFORMANCE_BUDGETS \n} from './performanceBudgets';\n\n// Lazy loading utilities\nexport { createLazyComponent, LazyDataTable } from './lazyLoad';\n\n// App configuration utilities\nexport { \n setAppConfig, \n getAppConfig, \n getCurrentAppName, \n getCurrentAppId \n} from './appConfig';\nexport type { AppConfig } from './appConfig';\n\n// Permission utilities\nexport { \n transformPermissionMapToBoolean, \n hasPermission, \n hasAnyPermission, \n hasAllPermissions \n} from './permissionUtils';\n\n// Permission types\nexport { \n PermissionType, \n parsePermission \n} from './permissionTypes';\n\n// Schema utilities\nexport { \n pickSchema, \n combineSchemas \n} from './schemaUtils';\n\n// Security monitoring utilities\nexport { \n securityMonitor \n} from './securityMonitor';\nexport type { SecureDataAccess } from './secureDataAccess';\n\n// Session tracking utilities\nexport { \n useSessionTracking \n} from './sessionTracking';\n\n// Audit utilities\nexport { \n auditLogger, \n auditLog,\n logAuthEvent,\n logPermissionEvent,\n logSecurityEvent,\n logAuditEvent\n} from './audit';\n\n// Device fingerprinting utilities\nexport { \n generateDeviceFingerprint, \n validateDeviceFingerprint \n} from './deviceFingerprint';\n\n\n// Formatting utilities\nexport { \n formatDate, \n formatCurrency, \n formatNumber,\n formatPercent,\n formatCompactNumber,\n formatFileSize\n} from './formatting';\n\n// Organisation context utilities\nexport { \n setOrganisationContext, \n clearOrganisationContext, \n getOrganisationContext, \n isOrganisationContextAvailable \n} from './organisationContext';\n\n// Re-export types for convenience\nexport type { \n SecurityEvent\n} from './security';\n"],"mappings":"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","names":["z","z","PermissionType","z","logSecurityEvent"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils/core/debugLogger.ts","../src/utils/index.ts","../src/utils/security/security.ts","../src/utils/security/securityMonitor.ts","../src/constants/performance.ts","../src/utils/performance/performanceBenchmark.ts","../src/utils/performance/bundleAnalysis.ts","../src/utils/dynamic/dynamicUtils.ts","../src/utils/dynamic/lazyLoad.tsx","../src/utils/permissions/permissionUtils.ts","../src/utils/permissions/permissionTypes.ts","../src/utils/audit/audit.ts","../src/utils/device/deviceFingerprint.ts"],"sourcesContent":["/**\n * @file Debug Logger Utility\n * @package @jmruthers/pace-core\n * @module Utils/DebugLogger\n * @since 0.4.76\n */\n\n/**\n * Debug logger that respects environment settings\n * Only logs in development mode to prevent production console spam\n */\nexport class DebugLogger {\n /**\n * Check if we're in development mode\n */\n private static get isDevelopment(): boolean {\n return import.meta.env.MODE === 'development';\n }\n\n /**\n * Log debug information only in development mode\n */\n static log(component: string, message: string, ...args: any[]): void {\n if (this.isDevelopment) {\n try {\n console.log(`[${component}] ${message}`, ...args);\n } catch (e) {\n // Gracefully handle console method errors\n }\n }\n }\n\n /**\n * Log error information (always logged)\n */\n static error(component: string, message: string, ...args: any[]): void {\n try {\n console.error(`[${component}] ${message}`, ...args);\n } catch (e) {\n // Gracefully handle console method errors\n }\n }\n\n /**\n * Log warning information (always logged)\n */\n static warn(component: string, message: string, ...args: any[]): void {\n try {\n console.warn(`[${component}] ${message}`, ...args);\n } catch (e) {\n // Gracefully handle console method errors\n }\n }\n\n /**\n * Log info information only in development mode\n */\n static info(component: string, message: string, ...args: any[]): void {\n if (this.isDevelopment) {\n try {\n console.info(`[${component}] ${message}`, ...args);\n } catch (e) {\n // Gracefully handle console method errors\n }\n }\n }\n}\n","/**\n * @file Utility functions exports\n * @package @jmruthers/pace-core\n * @module Utils\n * @since 0.1.0\n */\n\n// Core utilities\nexport { cn } from './core/cn';\nexport { DebugLogger } from './core/debugLogger';\nexport { Logger, logger, createLogger, LogLevel } from './core/logger';\nexport type { LoggerConfig } from './core/logger';\n\n// App configuration utilities\nexport * from './app/appNameResolver';\nexport { setAppConfig, getAppConfig, getCurrentAppId } from './app/appConfig';\nexport * from './app/appIdResolver';\n\n// Validation and sanitization\nexport * from './validation';\n\n// Security utilities\nexport { \n getSecurityHeaders, \n validateSecurityHeaders\n} from './security/security';\nexport type { SecurityEvent } from './security/security';\n\n// Security monitoring utilities\nexport { \n securityMonitor \n} from './security/securityMonitor';\nexport type { SecureDataAccess } from './security/secureDataAccess';\n\n// Performance utilities\nexport { useComponentPerformance } from '../hooks/useComponentPerformance';\nexport { PERFORMANCE_THRESHOLDS } from '../constants/performance';\nexport { createPerformanceBenchmark, measureRenderPerformance } from './performance/performanceBenchmark';\nexport type { PerformanceMetrics } from './performance/performanceBenchmark';\n\n// Bundle analysis utilities\nexport { \n bundleAnalyzer, \n validateImportPattern, \n trackDynamicImport \n} from './performance/bundleAnalysis';\n\n// Performance budget utilities\nexport { \n performanceBudgetMonitor, \n PERFORMANCE_BUDGETS \n} from './performance/performanceBudgets';\n\n// Dynamic utility loaders\nexport { \n loadLodash, \n loadDateUtils, \n loadChartUtils,\n loadFormUtils,\n loadCSVUtils,\n createLazyUtility,\n lazyLodash,\n lazyDateUtils,\n lazyChartUtils,\n lazyFormUtils,\n lazyCSVUtils\n} from './dynamic/dynamicUtils';\n\n// Lazy loading utilities\nexport { createLazyComponent, LazyDataTable } from './dynamic/lazyLoad';\n\n// Permission utilities\nexport { \n transformPermissionMapToBoolean, \n hasPermission, \n hasAnyPermission, \n hasAllPermissions \n} from './permissions/permissionUtils';\n\n// Permission types\nexport { \n PermissionType, \n parsePermission \n} from './permissions/permissionTypes';\n\n// Session tracking utilities\nexport { \n useSessionTracking \n} from './context/sessionTracking';\n\n// Audit utilities\nexport { \n auditLogger, \n auditLog,\n logAuthEvent,\n logPermissionEvent,\n logSecurityEvent,\n logAuditEvent\n} from './audit/audit';\n\n// Device fingerprinting utilities\nexport { \n generateDeviceFingerprint, \n validateDeviceFingerprint \n} from './device/deviceFingerprint';\n\n// Formatting utilities\nexport { \n formatDate, \n formatCurrency, \n formatNumber,\n formatPercent,\n formatCompactNumber,\n formatFileSize\n} from './formatting/formatting';\n\n// Organisation context utilities\nexport { \n setOrganisationContext, \n clearOrganisationContext, \n getOrganisationContext, \n isOrganisationContextAvailable \n} from './context/organisationContext';\n","\nimport type { SupabaseClient } from '@supabase/supabase-js';\nimport { createLogger } from '../core/logger';\n\nconst log = createLogger('Security');\n\nexport interface SecurityEvent {\n type: string;\n timestamp: Date;\n userId?: string;\n details: Record<string, unknown>;\n}\n\nexport function logSecurityEvent(event: SecurityEvent): void {\n // In production, this should log to your security monitoring system\n // Using Logger.warn for now - can be upgraded to audit system later\n log.warn('Security event:', {\n ...event,\n timestamp: event.timestamp.toISOString()\n });\n}\n\nexport function validateUserSession(userId: string, sessionToken?: string): Promise<boolean> {\n // Mock implementation - replace with actual session validation\n if (!userId || typeof userId !== 'string') {\n logSecurityEvent({\n type: 'invalid_session_validation',\n timestamp: new Date(),\n details: { reason: 'Invalid userId provided' }\n });\n return Promise.resolve(false);\n }\n \n if (sessionToken && sessionToken.length < 10) {\n logSecurityEvent({\n type: 'suspicious_session_token',\n timestamp: new Date(),\n userId,\n details: { reason: 'Session token too short' }\n });\n return Promise.resolve(false);\n }\n \n return Promise.resolve(true);\n}\n\nexport function createSecureSession(\n _supabaseClient: SupabaseClient,\n sessionData: { userId: string; deviceFingerprint?: string }\n): Promise<string> {\n // Mock implementation - in production, create actual secure session\n const sessionId = `sess_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n \n logSecurityEvent({\n type: 'session_created',\n timestamp: new Date(),\n userId: sessionData.userId,\n details: { \n sessionId,\n hasDeviceFingerprint: !!sessionData.deviceFingerprint\n }\n });\n \n return Promise.resolve(sessionId);\n}\n\nexport function invalidateSession(\n _supabaseClient: SupabaseClient,\n sessionId: string\n): Promise<void> {\n // Mock implementation - in production, invalidate actual session\n logSecurityEvent({\n type: 'session_invalidated',\n timestamp: new Date(),\n details: { sessionId }\n });\n \n return Promise.resolve();\n}\n\nexport function getSecurityHeaders(): Record<string, string> {\n return {\n 'X-Content-Type-Options': 'nosniff',\n 'X-Frame-Options': 'DENY',\n 'X-XSS-Protection': '1; mode=block',\n 'Referrer-Policy': 'strict-origin-when-cross-origin',\n 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains'\n };\n}\n\nexport function validateSecurityHeaders(headers: Record<string, string>): boolean {\n const requiredHeaders = ['X-Content-Type-Options', 'X-Frame-Options'];\n const missingHeaders = requiredHeaders.filter(header => !headers[header]);\n \n if (missingHeaders.length > 0) {\n logSecurityEvent({\n type: 'missing_security_headers',\n timestamp: new Date(),\n details: { missingHeaders }\n });\n return false;\n }\n \n return true;\n}\n\nexport function generateDeviceFingerprint(): string {\n // Basic device fingerprinting - in production, use more sophisticated methods\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n if (ctx) {\n ctx.textBaseline = 'top';\n ctx.font = '14px Arial';\n ctx.fillText('Device fingerprint', 2, 2);\n }\n \n const fingerprint = [\n navigator.userAgent,\n navigator.language,\n screen.width + 'x' + screen.height,\n new Date().getTimezoneOffset(),\n canvas.toDataURL()\n ].join('|');\n \n // Simple hash function for demonstration\n let hash = 0;\n for (let i = 0; i < fingerprint.length; i++) {\n const char = fingerprint.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n \n return Math.abs(hash).toString(16);\n}\n\nexport function validateDeviceFingerprint(fingerprint: string, expectedFingerprint?: string): boolean {\n if (!fingerprint || typeof fingerprint !== 'string') {\n logSecurityEvent({\n type: 'invalid_device_fingerprint',\n timestamp: new Date(),\n details: { reason: 'Invalid fingerprint format' }\n });\n return false;\n }\n \n if (expectedFingerprint && fingerprint !== expectedFingerprint) {\n logSecurityEvent({\n type: 'device_fingerprint_mismatch',\n timestamp: new Date(),\n details: { \n provided: fingerprint,\n expected: expectedFingerprint\n }\n });\n return false;\n }\n \n return true;\n}\n","\ninterface SecurityEvent {\n id?: string;\n action: string;\n details: Record<string, any>;\n timestamp?: number;\n}\n\ninterface SecurityAlert {\n id: string;\n type: string;\n message: string;\n timestamp: Date;\n}\n\nclass SecurityMonitor {\n private events: SecurityEvent[] = [];\n\n logEvent(event: SecurityEvent) {\n const eventWithId = {\n ...event,\n id: Math.random().toString(36).substr(2, 9),\n timestamp: Date.now()\n };\n this.events.push(eventWithId);\n }\n\n getEvents(): SecurityEvent[] {\n return [...this.events];\n }\n\n clearEvents() {\n this.events = [];\n }\n\n createAlert(alert: Omit<SecurityAlert, 'id' | 'timestamp'>): SecurityAlert {\n return {\n ...alert,\n id: Math.random().toString(36).substr(2, 9),\n timestamp: new Date()\n };\n }\n}\n\nexport const securityMonitor = new SecurityMonitor();\n","/**\n * Performance thresholds and constants\n */\n\nexport const PERFORMANCE_THRESHOLDS = {\n RENDER_TIME: 16, // 60fps target\n INTERACTION_TIME: 100, // 100ms for interactions\n ANIMATION_TIME: 300, // 300ms for animations\n LOAD_TIME: 1000, // 1 second for initial load\n MEMORY_USAGE: 50 * 1024 * 1024, // 50MB memory limit\n BUNDLE_SIZE: 250 * 1024, // 250KB bundle size limit\n} as const;\n\nexport type PerformanceThreshold = keyof typeof PERFORMANCE_THRESHOLDS; ","/**\n * Performance benchmarking utilities\n */\n\nexport interface PerformanceMetrics {\n renderTime: number;\n interactionTime: number;\n memoryUsage: number;\n bundleSize: number;\n}\n\nexport function createPerformanceBenchmark(name: string) {\n const startTime = performance.now();\n const startMemory = (performance as any).memory?.usedJSHeapSize || 0;\n\n return {\n end: () => {\n const endTime = performance.now();\n const endMemory = (performance as any).memory?.usedJSHeapSize || 0;\n \n const metrics: PerformanceMetrics = {\n renderTime: endTime - startTime,\n interactionTime: 0, // Would be measured separately\n memoryUsage: endMemory - startMemory,\n bundleSize: 0, // Would be measured at build time\n };\n\n // TODO: Replace with proper logging service integration\n // For now, we'll use a no-op to prevent console pollution\n const _unused = { \n benchmark: `Performance Benchmark [${name}]`, \n metrics \n };\n \n return metrics;\n }\n };\n}\n\nexport function measureRenderPerformance(componentName: string, renderFn: () => void): PerformanceMetrics {\n const startTime = performance.now();\n const startMemory = (performance as any).memory?.usedJSHeapSize || 0;\n \n renderFn();\n \n const endTime = performance.now();\n const endMemory = (performance as any).memory?.usedJSHeapSize || 0;\n \n const metrics: PerformanceMetrics = {\n renderTime: endTime - startTime,\n interactionTime: 0,\n memoryUsage: endMemory - startMemory,\n bundleSize: 0,\n };\n \n // TODO: Replace with proper logging service integration\n // For now, we'll use a no-op to prevent console pollution\n const _unused = { \n benchmark: `Render Performance [${componentName}]`, \n metrics \n };\n \n return metrics;\n} ","\ninterface BundleStats {\n totalSize: number;\n gzippedSize: number;\n chunks: ChunkInfo[];\n treeshakingEffectiveness: number;\n}\n\ninterface ChunkInfo {\n name: string;\n size: number;\n modules: string[];\n dynamicallyImported: boolean;\n}\n\nclass BundleAnalyzer {\n private enabled = import.meta.env.MODE === 'development';\n\n analyzeBundle(): BundleStats | null {\n if (!this.enabled) return null;\n\n // In a real implementation, this would integrate with webpack-bundle-analyzer\n // or similar tools. For now, we'll simulate analysis\n \n // TODO: Replace with proper logging service integration\n // For now, we'll log to console for testing purposes\n console.log('Bundle analysis would run here in development');\n console.log('To enable real bundle analysis:');\n console.log('1. Install webpack-bundle-analyzer');\n console.log('2. Add bundle analysis to build scripts');\n console.log('3. Integrate with performance budgets');\n\n return {\n totalSize: 0,\n gzippedSize: 0,\n chunks: [],\n treeshakingEffectiveness: 0\n };\n }\n\n checkTreeshaking(): void {\n if (!this.enabled) return;\n\n const potentialIssues = [\n 'Check for unused exports in index files',\n 'Verify side-effect free modules in package.json',\n 'Ensure proper ES module syntax',\n 'Check for circular dependencies'\n ];\n\n // TODO: Replace with proper logging service integration\n // For now, we'll log to console for testing purposes\n console.group('Tree-shaking Analysis');\n potentialIssues.forEach(issue => console.log('- ' + issue));\n console.groupEnd();\n }\n\n validateExports(): void {\n if (!this.enabled) return;\n\n // TODO: Replace with proper logging service integration\n // For now, we'll log to console for testing purposes\n console.group('Export Validation');\n console.log('Checking for optimal export patterns...');\n console.log('- Prefer named exports over default exports');\n console.log('- Avoid barrel exports for large modules');\n console.log('- Use dynamic imports for large dependencies');\n console.groupEnd();\n }\n\n generateReport(): string {\n const report = `\n# Bundle Analysis Report\n\n## Recommendations for @jmruthers/pace-core\n\n### 1. Code Splitting Opportunities\n- ✅ DataTable virtualization is lazy-loaded\n- ⚠️ Consider splitting auth providers by use case\n- ⚠️ Lazy load heavy UI components (charts, complex forms)\n\n### 2. Tree-shaking Optimization\n- ✅ Using ES modules throughout\n- ✅ Proper sideEffects configuration\n- ⚠️ Check for unused utility functions\n\n### 3. Bundle Size Targets\n- Core components: < 50KB gzipped\n- Auth module: < 30KB gzipped \n- Utilities: < 20KB gzipped\n- Total package: < 150KB gzipped\n\n### 4. Performance Monitoring\n- Monitor component render times\n- Track bundle size changes\n- Validate tree-shaking effectiveness\n `;\n\n return report.trim();\n }\n}\n\nexport const bundleAnalyzer = new BundleAnalyzer();\n\n// Helper to check if imports are optimized\nexport function validateImportPattern(moduleId: string, importedItems: string[]): void {\n if (import.meta.env.MODE !== 'development') return;\n\n const largeModules = ['lodash', 'moment', 'rxjs'];\n const isLargeModule = largeModules.some(mod => moduleId.includes(mod));\n \n if (isLargeModule && importedItems.length > 5) {\n // TODO: Replace with proper logging service integration\n // For now, we'll log to console for testing purposes\n console.warn(\n 'Large import detected: importing ' + importedItems.length + ' items from ' + moduleId + '. ' +\n 'Consider splitting imports or using more specific imports.'\n );\n }\n}\n\n// Monitor dynamic imports\nexport function trackDynamicImport(moduleName: string): void {\n if (import.meta.env.MODE !== 'development') return;\n \n // TODO: Replace with proper logging service integration\n // For now, we'll log to console for testing purposes\n console.log('Dynamic import: ' + moduleName + ' - Good for code splitting!');\n}\n","\n/**\n * Dynamic utility loader to reduce initial bundle size\n * Heavy utilities are loaded on-demand\n */\n\n// Type definitions for dynamic imports\ntype DebounceFunction = <T extends (...args: unknown[]) => unknown>(\n func: T,\n wait?: number,\n options?: { leading?: boolean; maxWait?: number; trailing?: boolean }\n) => T & { cancel(): void; flush(): void };\n\ntype ThrottleFunction = <T extends (...args: unknown[]) => unknown>(\n func: T,\n wait?: number,\n options?: { leading?: boolean; trailing?: boolean }\n) => T & { cancel(): void; flush(): void };\n\n// Dynamic lodash utilities\nexport const loadLodash = async (): Promise<{\n debounce: DebounceFunction;\n throttle: ThrottleFunction;\n}> => {\n const [debounceModule, throttleModule] = await Promise.all([\n import('lodash.debounce' as any),\n import('lodash.throttle' as any)\n ]);\n \n return {\n debounce: (debounceModule.default || debounceModule) as DebounceFunction,\n throttle: (throttleModule.default || throttleModule) as ThrottleFunction\n };\n};\n\n// Dynamic date utilities\nexport const loadDateUtils = async (): Promise<typeof import('date-fns')> => {\n const dateFns = await import('date-fns');\n return dateFns;\n};\n\n// Dynamic chart utilities - using unknown type to avoid Recharts type issues\nexport const loadChartUtils = async (): Promise<unknown> => {\n const recharts = await import('recharts');\n return recharts;\n};\n\n// Dynamic form utilities\nexport const loadFormUtils = async (): Promise<{\n useForm: unknown;\n useController: unknown;\n Controller: unknown;\n FormProvider: unknown;\n useFormContext: unknown;\n useWatch: unknown;\n useFormState: unknown;\n useFieldArray: unknown;\n zodResolver: unknown;\n}> => {\n const [reactHookForm, zodResolvers] = await Promise.all([\n import('react-hook-form'),\n import('@hookform/resolvers/zod')\n ]);\n \n return {\n ...reactHookForm,\n zodResolver: zodResolvers.zodResolver\n };\n};\n\n// Dynamic CSV utilities\nexport const loadCSVUtils = async (): Promise<unknown> => {\n const papaparse = await import('papaparse');\n return papaparse.default;\n};\n\n// Utility function to create lazy utility hooks\nexport function createLazyUtility<T>(loader: () => Promise<T>) {\n let cached: T | null = null;\n let loading: Promise<T> | null = null;\n\n return {\n load: async (): Promise<T> => {\n if (cached) return cached;\n if (loading) return loading;\n\n loading = loader().then(result => {\n cached = result;\n loading = null;\n return result;\n });\n\n return loading;\n },\n getCached: (): T | null => cached,\n isLoaded: (): boolean => cached !== null\n };\n}\n\n// Pre-configured lazy utilities with explicit types\nexport const lazyLodash: ReturnType<typeof createLazyUtility<Awaited<ReturnType<typeof loadLodash>>>> = createLazyUtility(loadLodash);\nexport const lazyDateUtils: ReturnType<typeof createLazyUtility<Awaited<ReturnType<typeof loadDateUtils>>>> = createLazyUtility(loadDateUtils);\nexport const lazyChartUtils: ReturnType<typeof createLazyUtility<unknown>> = createLazyUtility(loadChartUtils);\nexport const lazyFormUtils: ReturnType<typeof createLazyUtility<Awaited<ReturnType<typeof loadFormUtils>>>> = createLazyUtility(loadFormUtils);\nexport const lazyCSVUtils: ReturnType<typeof createLazyUtility<unknown>> = createLazyUtility(loadCSVUtils);\n","import React, { Suspense, ComponentType, lazy } from 'react';\nimport { LoadingSpinner } from '../../components/LoadingSpinner/LoadingSpinner';\n\ninterface LazyLoadOptions {\n fallback?: React.ReactNode;\n errorBoundary?: ComponentType<{ children: React.ReactNode }>;\n}\n\n/**\n * Create a lazy-loaded component with error boundary and loading fallback\n */\nexport function createLazyComponent<T extends ComponentType<any>>(\n importFn: () => Promise<{ default: T }>,\n componentName: string,\n options: LazyLoadOptions = {}\n): T {\n const LazyComponent = lazy(importFn);\n \n const WrappedComponent = (props: any) => {\n const content = (\n <Suspense fallback={options.fallback || <LoadingSpinner />}>\n <LazyComponent {...props} />\n </Suspense>\n );\n\n if (options.errorBoundary) {\n const ErrorBoundary = options.errorBoundary;\n return <ErrorBoundary>{content}</ErrorBoundary>;\n }\n\n return content;\n };\n \n WrappedComponent.displayName = `Lazy${componentName}`;\n return WrappedComponent as T;\n}\n\n/**\n * Lazy-loaded DataTable component\n */\nexport const LazyDataTable = createLazyComponent(\n () => import('../../components/DataTable').then(module => ({ default: module.DataTable })),\n 'DataTable'\n);\n","\n/**\n * Permission utilities for transforming and managing permissions\n */\n\nexport function transformPermissionMapToBoolean(permissions: Record<string, unknown>): Record<string, boolean> {\n const result: Record<string, boolean> = {};\n \n Object.entries(permissions).forEach(([key, value]) => {\n if (typeof value === 'string') {\n // Handle string values - 'false' should be false, empty strings are false, other non-empty strings are true\n result[key] = value !== '' && value.toLowerCase() !== 'false';\n } else {\n result[key] = Boolean(value);\n }\n });\n \n return result;\n}\n\nexport function hasPermission(permissions: Record<string, boolean>, permission: string): boolean {\n return Boolean(permissions[permission]);\n}\n\nexport function hasAnyPermission(permissions: Record<string, boolean>, permissionList: string[] | null | undefined): boolean {\n if (!permissionList || permissionList.length === 0) return false;\n return permissionList.some(permission => hasPermission(permissions, permission));\n}\n\nexport function hasAllPermissions(permissions: Record<string, boolean>, permissionList: string[] | null | undefined): boolean {\n if (!permissionList) return false;\n if (permissionList.length === 0) return true;\n return permissionList.every(permission => hasPermission(permissions, permission));\n}\n","\n/**\n * @file Permission type definitions and utilities\n */\n\nexport enum PermissionType {\n READ = 'read',\n WRITE = 'write',\n DELETE = 'delete',\n ADMIN = 'admin'\n}\n\n/**\n * Parse a permission string into components\n */\nexport function parsePermission(permission: string): { resource: string; action: string } | null {\n if (!permission || typeof permission !== 'string') {\n return null;\n }\n \n const parts = permission.split(':');\n if (parts.length !== 2) {\n return null;\n }\n \n const [action, resource] = parts;\n \n // Check that both action and resource exist and are not empty\n if (action === undefined || resource === undefined || action === '' || resource === '') {\n return null;\n }\n \n return {\n resource,\n action\n };\n}\n","\n/**\n * @file Audit Logger - General Utility\n * \n * Moved from shared/auditLogger to lib for better organization\n */\n\nexport interface AuditEvent {\n type: 'auth' | 'permission' | 'security';\n action?: string;\n event?: string;\n user?: string;\n userId?: string;\n details?: Record<string, unknown>;\n data?: Record<string, unknown>;\n timestamp?: number;\n severity?: 'low' | 'medium' | 'high' | 'critical';\n source?: string;\n}\n\nclass AuditLogger {\n private events: AuditEvent[] = [];\n\n log(event: AuditEvent): void {\n const eventWithTimestamp = {\n ...event,\n timestamp: Date.now(),\n };\n \n this.events.push(eventWithTimestamp);\n // TODO: In production, this should send to a proper logging service\n // Console logging removed for production\n }\n\n async logPermissionEvent(event: {\n event: string;\n userId: string;\n data?: Record<string, unknown>;\n }): Promise<void> {\n this.log({\n type: 'permission',\n event: event.event,\n userId: event.userId,\n data: event.data,\n });\n }\n\n async logSecurityEvent(event: {\n event: string;\n data?: Record<string, unknown>;\n }): Promise<void> {\n this.log({\n type: 'security',\n event: event.event,\n data: event.data,\n });\n }\n\n async logAuthEvent(event: {\n event: string;\n userId?: string;\n data?: Record<string, unknown>;\n }): Promise<void> {\n this.log({\n type: 'auth',\n event: event.event,\n userId: event.userId,\n data: event.data,\n });\n }\n\n async getSecurityEvents(): Promise<AuditEvent[]> {\n return this.events.filter(event => event.type === 'security');\n }\n\n getEvents(): AuditEvent[] {\n return [...this.events];\n }\n\n clearEvents(): void {\n this.events = [];\n }\n}\n\nexport const auditLogger = new AuditLogger();\n\n// Alias for backward compatibility\nexport const auditLog = auditLogger;\n\nexport function logAuthEvent(action: string, user?: string, details?: Record<string, unknown>): void {\n auditLogger.log({\n type: 'auth',\n action,\n user,\n details,\n });\n // Console logging removed for production\n}\n\nexport function logPermissionEvent(action: string, user?: string, details?: Record<string, unknown>): void {\n auditLogger.log({\n type: 'permission',\n action,\n user,\n details,\n });\n // Console logging removed for production\n}\n\nexport function logSecurityEvent(action: string, user?: string, details?: Record<string, unknown>): void {\n auditLogger.log({\n type: 'security',\n action,\n user,\n details,\n });\n // Console logging removed for production\n}\n\nexport function logAuditEvent(action: string, user?: string, details?: Record<string, unknown>): void {\n auditLogger.log({\n type: 'auth', // Default to auth type for general audit events\n action,\n user,\n details,\n });\n}\n","/**\n * @file Secure Device Fingerprinting\n * @description Enhanced device fingerprinting with encryption and security measures\n */\n\nimport { secureStorage } from '../security/secureStorage';\n\nexport interface DeviceFingerprint {\n hash: string;\n timestamp: number;\n components: {\n userAgent: string;\n language: string;\n platform: string;\n screen: string;\n timezone: string;\n canvas?: string;\n webgl?: string;\n };\n entropy: number;\n}\n\n/**\n * Generate a secure device fingerprint (synchronous)\n */\nexport function generateDeviceFingerprint(): DeviceFingerprint {\n try {\n const components = {\n userAgent: getHashedUserAgent(),\n language: navigator.language || 'unknown',\n platform: navigator.platform || 'unknown',\n screen: `${screen.width}x${screen.height}x${screen.colorDepth}`,\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone || 'unknown',\n canvas: getCanvasFingerprint(),\n webgl: getWebGLFingerprint(),\n };\n\n // Calculate entropy (uniqueness score)\n const entropy = calculateEntropy(components);\n \n // Create a hash from all components\n const fingerprintData = JSON.stringify(components);\n const hash = hashStringSync(fingerprintData);\n\n const fingerprint: DeviceFingerprint = {\n hash,\n timestamp: Date.now(),\n components,\n entropy,\n };\n\n // Store fingerprint asynchronously\n secureStorage.setItem('device_fingerprint', JSON.stringify(fingerprint));\n \n return fingerprint;\n } catch (error) {\n return generateFallbackFingerprint();\n }\n}\n\n/**\n * Validate device fingerprint with security checks\n */\nexport function validateDeviceFingerprint(\n storedFingerprint: DeviceFingerprint,\n currentFingerprint: DeviceFingerprint\n): {\n isValid: boolean;\n confidence: number;\n reasons: string[];\n} {\n const reasons: string[] = [];\n let matchingComponents = 0;\n const totalComponents = Object.keys(storedFingerprint.components).length;\n\n // Check each component\n Object.entries(storedFingerprint.components).forEach(([key, value]) => {\n if (currentFingerprint.components[key as keyof typeof currentFingerprint.components] === value) {\n matchingComponents++;\n } else {\n reasons.push(`Component mismatch: ${key}`);\n }\n });\n\n // Calculate confidence score\n const confidence = (matchingComponents / totalComponents) * 100;\n\n // Security thresholds\n const isValid = confidence >= 80; // Require 80% match\n \n // Additional security checks\n const timeDiff = currentFingerprint.timestamp - storedFingerprint.timestamp;\n const maxAge = 30 * 24 * 60 * 60 * 1000; // 30 days\n \n if (timeDiff > maxAge) {\n reasons.push('Fingerprint too old');\n return { isValid: false, confidence, reasons };\n }\n\n if (confidence < 60) {\n reasons.push('Device signature changed significantly');\n }\n\n return { isValid, confidence, reasons };\n}\n\n/**\n * Generate canvas fingerprint for enhanced uniqueness\n */\nfunction getCanvasFingerprint(): string {\n try {\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n \n if (!ctx) return 'canvas-unavailable';\n\n // Draw complex pattern for fingerprinting\n ctx.textBaseline = 'top';\n ctx.font = '14px Arial';\n ctx.fillStyle = '#f60';\n ctx.fillRect(125, 1, 62, 20);\n ctx.fillStyle = '#069';\n ctx.fillText('Device fingerprint 🔒', 2, 15);\n ctx.fillStyle = 'rgba(102, 204, 0, 0.2)';\n ctx.fillText('Device fingerprint 🔒', 4, 17);\n\n const dataURL = canvas.toDataURL();\n return hashStringSync(dataURL);\n } catch (error) {\n return 'canvas-error';\n }\n}\n\n/**\n * Get WebGL fingerprint\n */\nfunction getWebGLFingerprint(): string {\n try {\n const canvas = document.createElement('canvas');\n const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl') as WebGLRenderingContext | null;\n \n if (!gl) return 'webgl-unavailable';\n\n const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');\n if (!debugInfo) return 'webgl-no-debug';\n\n const vendor = gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL);\n const renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);\n \n return `${vendor}|${renderer}`;\n } catch (error) {\n return 'webgl-error';\n }\n}\n\n/**\n * Hash user agent to prevent direct exposure\n */\nfunction getHashedUserAgent(): string {\n const ua = navigator.userAgent;\n return hashStringSync(ua).substring(0, 16); // Shorter hash for storage\n}\n\n/**\n * Calculate entropy of fingerprint components\n */\nfunction calculateEntropy(components: Record<string, string>): number {\n const values = Object.values(components).join('');\n const charCounts = new Map<string, number>();\n \n for (const char of values) {\n charCounts.set(char, (charCounts.get(char) || 0) + 1);\n }\n \n let entropy = 0;\n for (const count of charCounts.values()) {\n const probability = count / values.length;\n entropy -= probability * Math.log2(probability);\n }\n \n return entropy;\n}\n\n/**\n * Synchronous hash function for device fingerprinting\n */\nfunction hashStringSync(str: string): string {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash;\n }\n return Math.abs(hash).toString(36);\n}\n\n/**\n * Generate fallback fingerprint for error cases\n */\nfunction generateFallbackFingerprint(): DeviceFingerprint {\n const components = {\n userAgent: 'fallback',\n language: 'unknown',\n platform: 'unknown',\n screen: 'unknown',\n timezone: 'unknown',\n };\n\n return {\n hash: `fallback_${Date.now()}_${Math.random().toString(36)}`,\n timestamp: Date.now(),\n components,\n entropy: 1, // Low entropy for fallback\n };\n}\n"],"mappings":"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","names":["PermissionType","logSecurityEvent"]}
|
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* @file Schema utility functions
|
|
5
|
+
* @package @jmruthers/pace-core
|
|
6
|
+
* @module Utils/Validation/Schema
|
|
7
|
+
* @since 0.1.0
|
|
8
|
+
*
|
|
9
|
+
* Utility functions for working with Zod schemas.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Creates a subset schema from a larger schema
|
|
14
|
+
*
|
|
15
|
+
* @param schema - Original Zod schema
|
|
16
|
+
* @param keys - Array of keys to pick from the schema
|
|
17
|
+
* @returns New schema with only the selected fields
|
|
18
|
+
*/
|
|
19
|
+
declare function pickSchema<T extends z.ZodObject<any, any, any>, K extends keyof z.infer<T>>(schema: T, keys: K[]): z.ZodObject<Pick<z.infer<T>, K>>;
|
|
20
|
+
/**
|
|
21
|
+
* Combines multiple Zod schemas into one
|
|
22
|
+
*
|
|
23
|
+
* @param schemas - Array of Zod schemas to combine
|
|
24
|
+
* @returns Combined schema
|
|
25
|
+
*/
|
|
26
|
+
declare function combineSchemas<T extends z.ZodObject<any, any, any>[]>(schemas: T): z.ZodObject<any, any, any>;
|
|
27
|
+
|
|
3
28
|
/**
|
|
4
29
|
* @file Validation Types
|
|
5
30
|
* @package @jmruthers/pace-core
|
|
@@ -130,7 +155,6 @@ declare const contactFormSchema: z.ZodObject<{
|
|
|
130
155
|
}>;
|
|
131
156
|
type LoginFormValues = z.infer<typeof loginSchema>;
|
|
132
157
|
type RegistrationFormValues = z.infer<typeof registrationSchema>;
|
|
133
|
-
type PasswordResetFormValues = z.infer<typeof passwordResetSchema>;
|
|
134
158
|
type ChangePasswordFormValues = z.infer<typeof changePasswordSchema>;
|
|
135
159
|
type UserProfileFormValues = z.infer<typeof userProfileSchema>;
|
|
136
160
|
type SecureLoginFormValues = {
|
|
@@ -144,16 +168,10 @@ type SecureRegistrationFormValues = {
|
|
|
144
168
|
confirmPassword: string;
|
|
145
169
|
csrfToken?: string;
|
|
146
170
|
};
|
|
147
|
-
type SecurePasswordResetFormValues = {
|
|
148
|
-
email: string;
|
|
149
|
-
csrfToken?: string;
|
|
150
|
-
};
|
|
151
171
|
type FormData = LoginFormData | RegistrationFormData | ProfileFormData | ContactFormData;
|
|
152
172
|
type LoginFormData = z.infer<typeof loginSchema>;
|
|
153
173
|
type RegistrationFormData = z.infer<typeof registrationSchema>;
|
|
154
174
|
type ProfileFormData = z.infer<typeof userProfileSchema>;
|
|
155
175
|
type ContactFormData = z.infer<typeof contactFormSchema>;
|
|
156
|
-
declare function pickSchema<T extends z.ZodObject<any, any, any>, K extends keyof z.infer<T>>(schema: T, keys: K[]): z.ZodObject<Pick<z.infer<T>, K>>;
|
|
157
|
-
declare function combineSchemas<T extends z.ZodObject<any, any, any>[]>(schemas: T): z.ZodObject<any, any, any>;
|
|
158
176
|
|
|
159
|
-
export { type ChangePasswordFormValues as C, type FormData as F, type LoginFormValues as L, type
|
|
177
|
+
export { type ChangePasswordFormValues as C, type FormData as F, type LoginFormValues as L, type ProfileFormData as P, type RegistrationFormValues as R, type SecureLoginFormValues as S, type UserProfileFormValues as U, type ValidationError as V, type ValidationResult as a, passwordSchema as b, secureLoginSchema as c, dateSchema as d, emailSchema as e, passwordResetSchema as f, changePasswordSchema as g, userProfileSchema as h, contactFormSchema as i, type SecureRegistrationFormValues as j, type LoginFormData as k, loginSchema as l, type RegistrationFormData as m, nameSchema as n, type ContactFormData as o, phoneSchema as p, pickSchema as q, registrationSchema as r, securePasswordSchema as s, combineSchemas as t, urlSchema as u };
|
package/dist/validation.d.ts
CHANGED
|
@@ -1,23 +1,222 @@
|
|
|
1
|
+
export { g as changePasswordSchema, t as combineSchemas, i as contactFormSchema, l as loginSchema, f as passwordResetSchema, q as pickSchema, r as registrationSchema, c as secureLoginSchema, s as securePasswordSchema, h as userProfileSchema } from './validation-8npbysjg.js';
|
|
1
2
|
import { z } from 'zod';
|
|
2
|
-
export { g as changePasswordSchema, w as combineSchemas, i as contactFormSchema, d as dateSchema, e as emailSchema, l as loginSchema, n as nameSchema, f as passwordResetSchema, b as passwordSchema, p as phoneSchema, v as pickSchema, r as registrationSchema, c as secureLoginSchema, s as securePasswordSchema, u as urlSchema, h as userProfileSchema } from './validation-DnhrNMju.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* @file
|
|
6
|
-
* @
|
|
5
|
+
* @file Internal utilities for validation module
|
|
6
|
+
* @internal This file contains implementation details that should not be used directly
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Utility functions for validating data in the application
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Check if a string is a valid email
|
|
13
|
+
*/
|
|
14
|
+
declare function isValidEmail(email: string): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Check if a string is empty (either null, undefined, or just whitespace)
|
|
17
|
+
*/
|
|
18
|
+
declare function isEmpty(value: string | null | undefined): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Check if a password meets minimum requirements
|
|
21
|
+
*/
|
|
22
|
+
declare function isStrongPassword(password: string): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Check if a URL is valid
|
|
25
|
+
*/
|
|
26
|
+
declare function isValidUrl(url: string): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Check if a date string is valid
|
|
29
|
+
*/
|
|
30
|
+
declare function isValidDate(dateStr: string): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Check if a value is within a range
|
|
33
|
+
*/
|
|
34
|
+
declare function isWithinRange(value: number, min: number, max: number): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Check if a value matches a specific pattern
|
|
37
|
+
*/
|
|
38
|
+
declare function matchesPattern(value: string, pattern: RegExp): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Utility function to deep merge objects for schema combination
|
|
41
|
+
* @internal
|
|
42
|
+
*/
|
|
43
|
+
declare function deepMerge<T extends Record<string, unknown>>(target: T, source: Record<string, unknown>): T;
|
|
44
|
+
/**
|
|
45
|
+
* Type guard to check if a value is a plain object
|
|
46
|
+
* @internal
|
|
47
|
+
*/
|
|
48
|
+
declare function isObject(item: unknown): item is Record<string, unknown>;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @file HTML Sanitization Utilities
|
|
52
|
+
* @package @jmruthers/pace-core
|
|
53
|
+
* @module Utils/Validation/HTMLSanitization
|
|
54
|
+
* @since 0.4.36
|
|
55
|
+
*
|
|
56
|
+
* Utilities for safely rendering HTML content.
|
|
57
|
+
* Provides sanitization and validation for basic HTML elements.
|
|
58
|
+
*/
|
|
59
|
+
/**
|
|
60
|
+
* Basic HTML sanitization function using regex-based approach
|
|
61
|
+
* Removes potentially dangerous elements and attributes while preserving basic formatting
|
|
62
|
+
* This approach is more reliable in SSR environments and doesn't require DOM manipulation
|
|
63
|
+
*
|
|
64
|
+
* @param html - The HTML string to sanitize
|
|
65
|
+
* @returns Sanitized HTML string safe for rendering
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```tsx
|
|
69
|
+
* const safeHtml = sanitizeHtml('<p>Hello <strong>world</strong>!</p>');
|
|
70
|
+
* // Returns: '<p>Hello <strong>world</strong>!</p>'
|
|
71
|
+
*
|
|
72
|
+
* const dangerousHtml = sanitizeHtml('<script>alert("xss")</script><p>Safe content</p>');
|
|
73
|
+
* // Returns: '<p>Safe content</p>'
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
declare function sanitizeHtml(html: string): string;
|
|
77
|
+
/**
|
|
78
|
+
* Validates if HTML content is safe for rendering
|
|
79
|
+
*
|
|
80
|
+
* @param html - The HTML string to validate
|
|
81
|
+
* @returns Object with validation result and any warnings
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```tsx
|
|
85
|
+
* const validation = validateHtml('<p>Safe content</p>');
|
|
86
|
+
* console.log(validation.isValid); // true
|
|
87
|
+
* console.log(validation.warnings); // []
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
declare function validateHtml(html: string): {
|
|
91
|
+
isValid: boolean;
|
|
92
|
+
warnings: string[];
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Safely renders HTML content with sanitization
|
|
96
|
+
*
|
|
97
|
+
* @param html - The HTML string to render
|
|
98
|
+
* @param options - Rendering options
|
|
99
|
+
* @returns Object with sanitized HTML and validation info
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* ```tsx
|
|
103
|
+
* const result = renderSafeHtml('<p>Hello <strong>world</strong>!</p>');
|
|
104
|
+
* console.log(result.html); // Sanitized HTML
|
|
105
|
+
* console.log(result.isValid); // true
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
declare function renderSafeHtml(html: string, options?: {
|
|
109
|
+
strict?: boolean;
|
|
110
|
+
logWarnings?: boolean;
|
|
111
|
+
}): {
|
|
112
|
+
html: string;
|
|
113
|
+
isValid: boolean;
|
|
114
|
+
warnings: string[];
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* @file Input Sanitization Layer
|
|
119
|
+
* @package @jmruthers/pace-core
|
|
120
|
+
* @module Utils/Validation/Sanitization
|
|
121
|
+
* @since 0.1.0
|
|
122
|
+
*
|
|
123
|
+
* Comprehensive input sanitization utilities to prevent XSS, injection attacks,
|
|
124
|
+
* and other security vulnerabilities.
|
|
125
|
+
*/
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Sanitization options for different contexts
|
|
129
|
+
*/
|
|
130
|
+
interface SanitizationOptions {
|
|
131
|
+
allowHtml?: boolean;
|
|
132
|
+
allowedTags?: string[];
|
|
133
|
+
maxLength?: number;
|
|
134
|
+
trim?: boolean;
|
|
135
|
+
removeScripts?: boolean;
|
|
136
|
+
removeEvents?: boolean;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Sanitizes user input by removing potentially dangerous characters and patterns
|
|
140
|
+
*/
|
|
141
|
+
declare function sanitizeUserInput(input: string, options?: SanitizationOptions): string;
|
|
142
|
+
/**
|
|
143
|
+
* Validates and sanitizes form data using Zod schemas
|
|
144
|
+
*/
|
|
145
|
+
declare function sanitizeFormData<T>(data: unknown, schema: z.ZodSchema<T>, sanitizationRules?: Record<string, SanitizationOptions>): {
|
|
146
|
+
success: boolean;
|
|
147
|
+
data?: T;
|
|
148
|
+
error?: string;
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* @file Validation utilities
|
|
153
|
+
*
|
|
154
|
+
* Shared validation utilities with enhanced security
|
|
7
155
|
*/
|
|
8
156
|
|
|
9
157
|
/**
|
|
10
|
-
*
|
|
158
|
+
* Validates user input against a schema with automatic sanitization
|
|
159
|
+
*/
|
|
160
|
+
declare function validateUserInput<T>(schema: z.ZodSchema<T>, data: unknown, sanitizationRules?: Record<string, SanitizationOptions>): {
|
|
161
|
+
success: boolean;
|
|
162
|
+
data?: T;
|
|
163
|
+
error?: string;
|
|
164
|
+
};
|
|
165
|
+
/**
|
|
166
|
+
* Sanitizes user input by removing potentially dangerous characters
|
|
167
|
+
* @deprecated Use sanitizeUserInput from lib/sanitization instead
|
|
11
168
|
*/
|
|
12
|
-
declare
|
|
169
|
+
declare function sanitizeUserInput_deprecated(input: string): string;
|
|
13
170
|
/**
|
|
14
|
-
*
|
|
171
|
+
* Enhanced email validation with sanitization
|
|
15
172
|
*/
|
|
16
|
-
declare
|
|
173
|
+
declare const emailSchema$1: z.ZodPipeline<z.ZodEffects<z.ZodString, string, string>, z.ZodString>;
|
|
17
174
|
/**
|
|
18
|
-
*
|
|
175
|
+
* Enhanced password validation
|
|
19
176
|
*/
|
|
20
|
-
declare
|
|
177
|
+
declare const passwordSchema$1: z.ZodString;
|
|
178
|
+
/**
|
|
179
|
+
* Username validation with sanitization
|
|
180
|
+
*/
|
|
181
|
+
declare const usernameSchema: z.ZodPipeline<z.ZodEffects<z.ZodString, string, string>, z.ZodString>;
|
|
182
|
+
/**
|
|
183
|
+
* Name validation with sanitization
|
|
184
|
+
*/
|
|
185
|
+
declare const nameSchema$1: z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
|
|
186
|
+
/**
|
|
187
|
+
* Phone number validation with sanitization
|
|
188
|
+
*/
|
|
189
|
+
declare const phoneSchema$1: z.ZodEffects<z.ZodString, string, string>;
|
|
190
|
+
/**
|
|
191
|
+
* URL validation with sanitization
|
|
192
|
+
*/
|
|
193
|
+
declare const urlSchema$1: z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* @file Common validation schemas
|
|
197
|
+
* @description Reusable validation schemas for common data types
|
|
198
|
+
*/
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Email validation schema
|
|
202
|
+
*/
|
|
203
|
+
declare const emailSchema: z.ZodString;
|
|
204
|
+
/**
|
|
205
|
+
* Name validation schema
|
|
206
|
+
*/
|
|
207
|
+
declare const nameSchema: z.ZodString;
|
|
208
|
+
/**
|
|
209
|
+
* Phone number validation schema
|
|
210
|
+
*/
|
|
211
|
+
declare const phoneSchema: z.ZodString;
|
|
212
|
+
/**
|
|
213
|
+
* URL validation schema
|
|
214
|
+
*/
|
|
215
|
+
declare const urlSchema: z.ZodString;
|
|
216
|
+
/**
|
|
217
|
+
* Date validation schema
|
|
218
|
+
*/
|
|
219
|
+
declare const dateSchema: z.ZodEffects<z.ZodString, string, string>;
|
|
21
220
|
|
|
22
221
|
/**
|
|
23
222
|
* @file CSRF Protection Implementation
|
|
@@ -126,6 +325,10 @@ declare function detectSQLInjection(input: string): {
|
|
|
126
325
|
* @description Comprehensive password validation with security checks
|
|
127
326
|
*/
|
|
128
327
|
|
|
328
|
+
/**
|
|
329
|
+
* Basic password schema for less strict requirements
|
|
330
|
+
*/
|
|
331
|
+
declare const passwordSchema: z.ZodString;
|
|
129
332
|
/**
|
|
130
333
|
* Password strength calculator
|
|
131
334
|
*/
|
|
@@ -135,4 +338,52 @@ declare function calculatePasswordStrength(password: string): {
|
|
|
135
338
|
level: 'very-weak' | 'weak' | 'fair' | 'good' | 'strong';
|
|
136
339
|
};
|
|
137
340
|
|
|
138
|
-
|
|
341
|
+
/**
|
|
342
|
+
* Schema for user settings
|
|
343
|
+
*/
|
|
344
|
+
declare const userSettingsSchema: z.ZodObject<{
|
|
345
|
+
notifications: z.ZodObject<{
|
|
346
|
+
email: z.ZodBoolean;
|
|
347
|
+
push: z.ZodBoolean;
|
|
348
|
+
}, "strip", z.ZodTypeAny, {
|
|
349
|
+
push: boolean;
|
|
350
|
+
email: boolean;
|
|
351
|
+
}, {
|
|
352
|
+
push: boolean;
|
|
353
|
+
email: boolean;
|
|
354
|
+
}>;
|
|
355
|
+
language: z.ZodString;
|
|
356
|
+
}, "strip", z.ZodTypeAny, {
|
|
357
|
+
notifications: {
|
|
358
|
+
push: boolean;
|
|
359
|
+
email: boolean;
|
|
360
|
+
};
|
|
361
|
+
language: string;
|
|
362
|
+
}, {
|
|
363
|
+
notifications: {
|
|
364
|
+
push: boolean;
|
|
365
|
+
email: boolean;
|
|
366
|
+
};
|
|
367
|
+
language: string;
|
|
368
|
+
}>;
|
|
369
|
+
/**
|
|
370
|
+
* Schema for user preferences
|
|
371
|
+
*/
|
|
372
|
+
declare const userPreferencesSchema: z.ZodObject<{
|
|
373
|
+
displayName: z.ZodString;
|
|
374
|
+
timezone: z.ZodString;
|
|
375
|
+
dateFormat: z.ZodString;
|
|
376
|
+
currency: z.ZodString;
|
|
377
|
+
}, "strip", z.ZodTypeAny, {
|
|
378
|
+
displayName: string;
|
|
379
|
+
timezone: string;
|
|
380
|
+
dateFormat: string;
|
|
381
|
+
currency: string;
|
|
382
|
+
}, {
|
|
383
|
+
displayName: string;
|
|
384
|
+
timezone: string;
|
|
385
|
+
dateFormat: string;
|
|
386
|
+
currency: string;
|
|
387
|
+
}>;
|
|
388
|
+
|
|
389
|
+
export { type CSRFTokenData, type SafeQueryParams, type SanitizationOptions, buildSafeQueryParams, calculatePasswordStrength, csrfManager, dateSchema, deepMerge, detectSQLInjection, emailSchema, emailSchema$1 as enhancedEmailSchema, nameSchema$1 as enhancedNameSchema, passwordSchema$1 as enhancedPasswordSchema, phoneSchema$1 as enhancedPhoneSchema, urlSchema$1 as enhancedUrlSchema, escapeLikeQuery, generateCSRFToken, getCSRFToken, isEmpty, isObject, isStrongPassword, isValidDate, isValidEmail, isValidUrl, isWithinRange, limitOffsetSchema, matchesPattern, nameSchema, orderBySchema, passwordSchema, phoneSchema, renderSafeHtml, sanitizeFilters, sanitizeFormData, sanitizeHtml, sanitizeHtml as sanitizeHtmlAdvanced, sanitizeSearchQuery, sanitizeUserInput, sanitizeUserInput_deprecated, searchQuerySchema, sqlIdentifierSchema, urlSchema, userPreferencesSchema, userSettingsSchema, usernameSchema, validateCSRFToken, validateHtml, validateUserInput };
|