@jmruthers/pace-core 0.5.181 → 0.5.183
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1 -1
- package/README.md +16 -2
- package/dist/{AuthService-DYuQPJj6.d.ts → AuthService-B-cd2MA4.d.ts} +9 -11
- package/dist/{DataTable-CWAZZcXC.d.ts → DataTable-Bz8ffqyA.d.ts} +1 -1
- package/dist/{DataTable-UA6CL4JI.js → DataTable-QAB34V6K.js} +14 -15
- package/dist/UnifiedAuthProvider-7F6T4B6K.js +13 -0
- package/dist/{UnifiedAuthProvider-DJxGTftH.d.ts → UnifiedAuthProvider-F86d7dSi.d.ts} +5 -6
- package/dist/{api-45XYYO2A.js → api-ROMBCNKU.js} +5 -5
- package/dist/{audit-64X3VJXB.js → audit-WRS3KJKI.js} +4 -4
- package/dist/auth-BZOJqrdd.d.ts +49 -0
- package/dist/{chunk-CX5M4ZAG.js → chunk-5DRSZLL2.js} +1 -1
- package/dist/chunk-5DRSZLL2.js.map +1 -0
- package/dist/{chunk-BESYRHQM.js → chunk-6C4YBBJM.js} +10 -7
- package/dist/chunk-6C4YBBJM.js.map +1 -0
- package/dist/{chunk-PLDDJCW6.js → chunk-7D4SUZUM.js} +2 -13
- package/dist/{chunk-HRO5HWN2.js → chunk-CSOFYHAG.js} +55 -162
- package/dist/chunk-CSOFYHAG.js.map +1 -0
- package/dist/{chunk-ANBQRTPX.js → chunk-E66EQZE6.js} +3 -5
- package/dist/{chunk-ANBQRTPX.js.map → chunk-E66EQZE6.js.map} +1 -1
- package/dist/{chunk-Q5QRDWKI.js → chunk-F2IMUDXZ.js} +4 -6
- package/dist/chunk-F2IMUDXZ.js.map +1 -0
- package/dist/{chunk-SBVILCCA.js → chunk-FSFQFJCU.js} +28 -6
- package/dist/chunk-FSFQFJCU.js.map +1 -0
- package/dist/chunk-FUEYYMX5.js +2296 -0
- package/dist/chunk-FUEYYMX5.js.map +1 -0
- package/dist/{chunk-FFKNH6U5.js → chunk-HKIT6O7W.js} +3 -5
- package/dist/{chunk-FFKNH6U5.js.map → chunk-HKIT6O7W.js.map} +1 -1
- package/dist/chunk-KQCRWDSA.js +1 -0
- package/dist/{chunk-S5OFRT4M.js → chunk-KUEN3HFB.js} +6 -6
- package/dist/chunk-KUEN3HFB.js.map +1 -0
- package/dist/chunk-LMC26NLJ.js +84 -0
- package/dist/chunk-LMC26NLJ.js.map +1 -0
- package/dist/{chunk-BVYWGZVV.js → chunk-M7W4CP3M.js} +52 -19
- package/dist/chunk-M7W4CP3M.js.map +1 -0
- package/dist/{chunk-HZLDFOE4.js → chunk-MI7HBHN3.js} +164 -243
- package/dist/chunk-MI7HBHN3.js.map +1 -0
- package/dist/{chunk-PPMP5J6T.js → chunk-PWAHJW4G.js} +180 -29
- package/dist/chunk-PWAHJW4G.js.map +1 -0
- package/dist/chunk-PWLANIRT.js +127 -0
- package/dist/{chunk-XDNLUEXI.js.map → chunk-PWLANIRT.js.map} +1 -1
- package/dist/chunk-QCDXODCA.js +75 -0
- package/dist/chunk-QCDXODCA.js.map +1 -0
- package/dist/{chunk-D7LCGMVS.js → chunk-QETLRQI6.js} +526 -887
- package/dist/chunk-QETLRQI6.js.map +1 -0
- package/dist/{chunk-5MT24GKJ.js → chunk-QUVSNGIP.js} +264 -262
- package/dist/chunk-QUVSNGIP.js.map +1 -0
- package/dist/chunk-QXHPKYJV.js +113 -0
- package/dist/chunk-QXHPKYJV.js.map +1 -0
- package/dist/{chunk-OWAG3GSU.js → chunk-R77UEZ4E.js} +11 -1
- package/dist/chunk-R77UEZ4E.js.map +1 -0
- package/dist/{chunk-ZYTYSTO5.js → chunk-RA3JUFMW.js} +314 -161
- package/dist/chunk-RA3JUFMW.js.map +1 -0
- package/dist/{chunk-ERISIBYU.js → chunk-SQGMNID3.js} +3 -8
- package/dist/chunk-SQGMNID3.js.map +1 -0
- package/dist/{chunk-XJ2HZOBU.js → chunk-UHNYIBXL.js} +1 -1
- package/dist/chunk-UHNYIBXL.js.map +1 -0
- package/{src/utils/secureStorage.ts → dist/chunk-VBXEHIUJ.js} +113 -88
- package/dist/{chunk-7QCC6MCP.js.map → chunk-VBXEHIUJ.js.map} +1 -1
- package/dist/{chunk-VZ4VDGTB.js → chunk-W22JP75J.js} +5 -13
- package/dist/{chunk-VZ4VDGTB.js.map → chunk-W22JP75J.js.map} +1 -1
- package/dist/components.d.ts +12 -93
- package/dist/components.js +23 -106
- package/dist/components.js.map +1 -1
- package/dist/core-CUElvH_C.d.ts +164 -0
- package/dist/database.generated-CBmg2950.d.ts +8284 -0
- package/dist/event-CW5YB_2p.d.ts +239 -0
- package/dist/{file-reference-C6Gkn77H.d.ts → file-reference-D06mEEWW.d.ts} +7 -5
- package/dist/functions-D_kgHktt.d.ts +208 -0
- package/dist/hooks.d.ts +54 -7
- package/dist/hooks.js +204 -17
- package/dist/hooks.js.map +1 -1
- package/dist/{EventLogo-B3V3otev.d.ts → index-Bl--n7-T.d.ts} +387 -397
- package/dist/index.d.ts +94 -261
- package/dist/index.js +314 -126
- package/dist/index.js.map +1 -1
- package/dist/providers.d.ts +7 -8
- package/dist/providers.js +6 -13
- package/dist/rbac/index.d.ts +171 -101
- package/dist/rbac/index.js +23 -17
- package/dist/styles/index.d.ts +1 -3
- package/dist/styles/index.js +2 -17
- package/dist/theming/runtime.js +3 -3
- package/dist/types-UU913iLA.d.ts +102 -0
- package/dist/{types-Dfz9dmVH.d.ts → types-_x1f4QBF.d.ts} +6 -6
- package/dist/types.d.ts +88 -227
- package/dist/types.js +64 -112
- package/dist/types.js.map +1 -1
- package/dist/{usePublicRouteParams-B7PabvuH.d.ts → usePublicRouteParams-JJczomYq.d.ts} +203 -6
- package/dist/utils.d.ts +299 -13
- package/dist/utils.js +481 -55
- package/dist/utils.js.map +1 -1
- package/dist/validation-643vUDZW.d.ts +177 -0
- package/docs/DOCUMENTATION_REVIEW_TRACKER.md +511 -0
- package/docs/README.md +9 -8
- package/docs/api/README.md +16 -2
- package/docs/api/classes/ColumnFactory.md +1 -1
- package/docs/api/classes/ErrorBoundary.md +1 -1
- package/docs/api/classes/InvalidScopeError.md +4 -4
- package/docs/api/classes/MissingUserContextError.md +4 -4
- package/docs/api/classes/OrganisationContextRequiredError.md +4 -4
- package/docs/api/classes/PermissionDeniedError.md +4 -4
- package/docs/api/classes/RBACAuditManager.md +14 -14
- package/docs/api/classes/RBACCache.md +1 -1
- package/docs/api/classes/RBACEngine.md +2 -2
- package/docs/api/classes/RBACError.md +4 -4
- package/docs/api/classes/RBACNotInitializedError.md +4 -4
- package/docs/api/classes/SecureSupabaseClient.md +29 -9
- package/docs/api/classes/StorageUtils.md +1 -1
- package/docs/api/enums/FileCategory.md +17 -17
- package/docs/api/enums/RBACErrorCode.md +228 -0
- package/docs/api/enums/RPCFunction.md +118 -0
- package/docs/api/interfaces/AggregateConfig.md +1 -1
- package/docs/api/interfaces/BadgeProps.md +1 -1
- package/docs/api/interfaces/ButtonProps.md +2 -2
- package/docs/api/interfaces/CalendarProps.md +1 -1
- package/docs/api/interfaces/CardProps.md +29 -3
- package/docs/api/interfaces/ColorPalette.md +1 -1
- package/docs/api/interfaces/ColorShade.md +1 -1
- package/docs/api/interfaces/DataAccessRecord.md +1 -1
- package/docs/api/interfaces/DataRecord.md +1 -1
- package/docs/api/interfaces/DataTableAction.md +2 -2
- package/docs/api/interfaces/DataTableColumn.md +6 -6
- package/docs/api/interfaces/DataTableProps.md +1 -1
- package/docs/api/interfaces/DataTableToolbarButton.md +2 -2
- package/docs/api/interfaces/EmptyStateConfig.md +1 -1
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
- package/docs/api/interfaces/EventAppRoleData.md +1 -1
- package/docs/api/interfaces/ExportColumn.md +5 -5
- package/docs/api/interfaces/ExportOptions.md +4 -4
- package/docs/api/interfaces/FileDisplayProps.md +1 -1
- package/docs/api/interfaces/FileMetadata.md +13 -13
- package/docs/api/interfaces/FileReference.md +12 -12
- package/docs/api/interfaces/FileSizeLimits.md +1 -1
- package/docs/api/interfaces/FileUploadOptions.md +10 -10
- package/docs/api/interfaces/FileUploadProps.md +19 -19
- package/docs/api/interfaces/FooterProps.md +1 -1
- package/docs/api/interfaces/FormFieldProps.md +166 -0
- package/docs/api/interfaces/FormProps.md +113 -0
- package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
- package/docs/api/interfaces/InactivityWarningModalProps.md +8 -8
- package/docs/api/interfaces/InputProps.md +2 -2
- package/docs/api/interfaces/LabelProps.md +8 -8
- package/docs/api/interfaces/LoginFormProps.md +1 -1
- package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
- package/docs/api/interfaces/NavigationContextType.md +1 -1
- package/docs/api/interfaces/NavigationGuardProps.md +1 -1
- package/docs/api/interfaces/NavigationItem.md +17 -73
- package/docs/api/interfaces/NavigationMenuProps.md +38 -53
- package/docs/api/interfaces/NavigationProviderProps.md +1 -1
- package/docs/api/interfaces/Organisation.md +13 -13
- package/docs/api/interfaces/OrganisationContextType.md +21 -21
- package/docs/api/interfaces/OrganisationMembership.md +15 -15
- package/docs/api/interfaces/OrganisationProviderProps.md +59 -2
- package/docs/api/interfaces/OrganisationSecurityError.md +5 -5
- package/docs/api/interfaces/PaceAppLayoutProps.md +26 -39
- package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
- package/docs/api/interfaces/PageAccessRecord.md +1 -1
- package/docs/api/interfaces/PagePermissionContextType.md +1 -1
- package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
- package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
- package/docs/api/interfaces/PaletteData.md +1 -1
- package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
- package/docs/api/interfaces/ProgressProps.md +50 -0
- package/docs/api/interfaces/ProtectedRouteProps.md +1 -1
- package/docs/api/interfaces/PublicPageFooterProps.md +9 -9
- package/docs/api/interfaces/PublicPageHeaderProps.md +10 -10
- package/docs/api/interfaces/PublicPageLayoutProps.md +15 -15
- package/docs/api/interfaces/RBACAccessValidateParams.md +52 -0
- package/docs/api/interfaces/RBACAccessValidateResult.md +41 -0
- package/docs/api/interfaces/RBACAuditLogParams.md +85 -0
- package/docs/api/interfaces/RBACAuditLogResult.md +52 -0
- package/docs/api/interfaces/RBACConfig.md +2 -2
- package/docs/api/interfaces/RBACContext.md +52 -0
- package/docs/api/interfaces/RBACLogger.md +1 -1
- package/docs/api/interfaces/RBACPageAccessCheckParams.md +74 -0
- package/docs/api/interfaces/RBACPermissionCheckParams.md +74 -0
- package/docs/api/interfaces/RBACPermissionCheckResult.md +52 -0
- package/docs/api/interfaces/RBACPermissionsGetParams.md +63 -0
- package/docs/api/interfaces/RBACPermissionsGetResult.md +63 -0
- package/docs/api/interfaces/RBACResult.md +58 -0
- package/docs/api/interfaces/RBACRoleGrantParams.md +63 -0
- package/docs/api/interfaces/RBACRoleGrantResult.md +52 -0
- package/docs/api/interfaces/RBACRoleRevokeParams.md +63 -0
- package/docs/api/interfaces/RBACRoleRevokeResult.md +52 -0
- package/docs/api/interfaces/RBACRoleValidateParams.md +52 -0
- package/docs/api/interfaces/RBACRoleValidateResult.md +63 -0
- package/docs/api/interfaces/RBACRolesListParams.md +52 -0
- package/docs/api/interfaces/RBACRolesListResult.md +74 -0
- package/docs/api/interfaces/RBACSessionTrackParams.md +74 -0
- package/docs/api/interfaces/RBACSessionTrackResult.md +52 -0
- package/docs/api/interfaces/ResourcePermissions.md +1 -1
- package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
- package/docs/api/interfaces/RoleManagementResult.md +1 -1
- package/docs/api/interfaces/RouteAccessRecord.md +1 -1
- package/docs/api/interfaces/RouteConfig.md +1 -1
- package/docs/api/interfaces/SecureDataContextType.md +1 -1
- package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
- package/docs/api/interfaces/SessionRestorationLoaderProps.md +15 -2
- 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/TabsContentProps.md +1 -1
- package/docs/api/interfaces/TabsListProps.md +1 -1
- package/docs/api/interfaces/TabsProps.md +1 -1
- package/docs/api/interfaces/TabsTriggerProps.md +43 -2
- package/docs/api/interfaces/TextareaProps.md +2 -2
- package/docs/api/interfaces/ToastActionElement.md +1 -1
- package/docs/api/interfaces/ToastProps.md +1 -1
- package/docs/api/interfaces/UnifiedAuthContextType.md +61 -61
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +13 -13
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoOptions.md +87 -0
- package/docs/api/interfaces/UsePublicEventLogoReturn.md +81 -0
- package/docs/api/interfaces/UsePublicEventOptions.md +3 -3
- package/docs/api/interfaces/UsePublicEventReturn.md +5 -5
- package/docs/api/interfaces/UsePublicFileDisplayOptions.md +2 -2
- package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
- package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
- package/docs/api/interfaces/UseResolvedScopeOptions.md +2 -2
- package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
- package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
- package/docs/api/interfaces/UserEventAccess.md +1 -1
- package/docs/api/interfaces/UserMenuProps.md +4 -4
- package/docs/api/interfaces/UserProfile.md +7 -7
- package/docs/api/modules.md +484 -462
- package/docs/api-reference/components.md +186 -15
- package/docs/api-reference/deprecated.md +376 -0
- package/docs/api-reference/hooks.md +149 -19
- package/docs/api-reference/providers.md +61 -6
- package/docs/api-reference/rpc-functions.md +397 -0
- package/docs/api-reference/types.md +135 -78
- package/docs/api-reference/utilities.md +51 -380
- package/docs/architecture/README.md +49 -3
- package/docs/architecture/database-schema-requirements.md +40 -3
- package/docs/architecture/rbac-security-architecture.md +41 -4
- package/docs/architecture/services.md +127 -42
- package/docs/best-practices/README.md +51 -5
- package/docs/best-practices/accessibility.md +32 -3
- package/docs/best-practices/common-patterns.md +50 -3
- package/docs/best-practices/deployment.md +50 -4
- package/docs/best-practices/performance.md +50 -3
- package/docs/best-practices/security.md +94 -41
- package/docs/best-practices/testing.md +33 -4
- package/docs/core-concepts/authentication.md +5 -5
- package/docs/core-concepts/events.md +3 -3
- package/docs/core-concepts/organisations.md +3 -3
- package/docs/core-concepts/permissions.md +3 -3
- package/docs/core-concepts/rbac-system.md +5 -5
- package/docs/documentation-index.md +30 -8
- package/docs/getting-started/documentation-index.md +1 -1
- package/docs/getting-started/examples/README.md +7 -5
- package/docs/getting-started/examples/basic-auth-app.md +3 -0
- package/docs/getting-started/examples/full-featured-app.md +5 -3
- package/docs/getting-started/faq.md +6 -6
- package/docs/getting-started/installation-guide.md +192 -13
- package/docs/getting-started/local-development.md +303 -0
- package/docs/getting-started/quick-reference.md +3 -3
- package/docs/getting-started/quick-start.md +517 -0
- package/docs/implementation-guides/app-layout.md +45 -3
- package/docs/implementation-guides/authentication.md +66 -7
- package/docs/implementation-guides/component-styling.md +53 -3
- package/docs/implementation-guides/data-tables.md +76 -7
- package/docs/implementation-guides/datatable-filtering.md +1 -2
- package/docs/implementation-guides/datatable-rbac-usage.md +0 -1
- package/docs/implementation-guides/dynamic-colors.md +155 -4
- package/docs/implementation-guides/file-reference-system.md +72 -3
- package/docs/implementation-guides/file-upload-storage.md +72 -3
- package/docs/implementation-guides/forms.md +53 -3
- package/docs/implementation-guides/inactivity-tracking.md +53 -3
- package/docs/implementation-guides/large-datasets.md +1 -1
- package/docs/implementation-guides/navigation.md +55 -5
- package/docs/implementation-guides/organisation-security.md +72 -3
- package/docs/implementation-guides/performance.md +57 -1
- package/docs/implementation-guides/permission-enforcement.md +81 -8
- package/docs/implementation-guides/public-pages.md +560 -14
- package/docs/migration/MIGRATION_GUIDE.md +409 -50
- package/docs/migration/README.md +37 -3
- package/docs/migration/organisation-context-timing-fix.md +39 -4
- package/docs/migration/quick-migration-guide.md +41 -5
- package/docs/migration/rbac-migration.md +59 -3
- package/docs/migration/service-architecture.md +77 -14
- package/docs/rbac/README.md +79 -3
- package/docs/rbac/advanced-patterns.md +47 -3
- package/docs/rbac/api-reference.md +77 -8
- package/docs/rbac/event-based-apps.md +50 -5
- package/docs/rbac/examples/rbac-rls-integration-example.md +3 -3
- package/docs/rbac/examples.md +39 -3
- package/docs/rbac/getting-started.md +63 -4
- package/docs/rbac/quick-start.md +57 -5
- package/docs/rbac/rbac-rls-integration.md +68 -6
- package/docs/rbac/super-admin-guide.md +47 -3
- package/docs/rbac/troubleshooting.md +3 -3
- package/docs/security/README.md +68 -3
- package/docs/security/checklist.md +50 -3
- package/docs/standards/01-architecture-standard.md +39 -0
- package/docs/standards/02-api-and-rpc-standard.md +39 -0
- package/docs/standards/03-component-standard.md +32 -0
- package/docs/standards/04-code-style-standard.md +32 -0
- package/docs/standards/05-security-standard.md +30 -0
- package/docs/standards/06-testing-and-docs-standard.md +29 -0
- package/docs/standards/README.md +35 -0
- package/docs/styles/README.md +89 -8
- package/docs/testing/README.md +175 -24
- package/docs/troubleshooting/README.md +50 -3
- package/docs/troubleshooting/common-issues.md +271 -5
- package/docs/troubleshooting/debugging.md +54 -1
- package/docs/troubleshooting/migration.md +54 -1
- package/docs/troubleshooting/organisation-context-setup.md +29 -3
- package/docs/troubleshooting/styling-issues.md +246 -4
- package/{src/components/DataTable/examples → examples/DataTable}/GroupingAggregationExample.tsx +1 -1
- package/examples/{components 2/DataTable/HierarchicalActionsExample.tsx → DataTable/HierarchicalActionsExample.tsx} +7 -6
- package/{src/components/DataTable/examples → examples/DataTable}/HierarchicalExample.tsx +8 -6
- package/examples/{components 2/DataTable/PerformanceExample.tsx → DataTable/PerformanceExample.tsx} +2 -2
- package/examples/{components 2/DataTable/index.ts → DataTable/index.ts} +1 -0
- package/{src/components/Dialog/examples → examples/Dialog}/HtmlDialogExample.tsx +3 -3
- package/examples/{components 2/Dialog/ScrollableDialogExample.tsx → Dialog/ScrollableDialogExample.tsx} +1 -1
- package/{src/components/Dialog/examples → examples/Dialog}/SmartDialogExample.tsx +1 -1
- package/examples/{components 2/Dialog/index.ts → Dialog/index.ts} +0 -3
- package/examples/{features/public-pages → PublicPages}/CorrectPublicPageImplementation.tsx +52 -17
- package/examples/{features/public-pages → PublicPages}/PublicEventPage.tsx +65 -35
- package/examples/{features/public-pages → PublicPages}/PublicPageApp.tsx +52 -18
- package/examples/{features/public-pages → PublicPages}/PublicPageUsageExample.tsx +28 -15
- package/examples/README.md +81 -33
- package/examples/index.ts +14 -12
- package/examples/{RBAC → rbac}/CompleteRBACExample.tsx +1 -1
- package/examples/{features/rbac → rbac}/EventBasedApp.tsx +4 -4
- package/examples/{features/rbac → rbac}/PermissionExample.tsx +5 -3
- package/package.json +21 -27
- package/src/__tests__/helpers/test-utils.tsx +29 -3
- package/src/__tests__/rbac/PagePermissionGuard.test.tsx +7 -5
- package/src/components/Alert/Alert.test.tsx +2 -2
- package/src/components/Alert/Alert.tsx +4 -4
- package/src/components/Avatar/Avatar.test.tsx +17 -6
- package/src/components/Badge/Badge.test.tsx +1 -1
- package/src/components/Badge/Badge.tsx +2 -2
- package/src/components/Button/Button.test.tsx +2 -2
- package/src/components/Button/Button.tsx +11 -7
- package/src/components/Calendar/Calendar.test.tsx +41 -8
- package/src/components/Calendar/Calendar.tsx +39 -36
- package/src/components/Card/Card.tsx +51 -13
- package/src/components/Checkbox/Checkbox.test.tsx +36 -12
- package/src/components/DataTable/DataTable.test.tsx +1 -1
- package/src/components/DataTable/__tests__/DataTable.comprehensive.test.tsx +13 -7
- package/src/components/DataTable/__tests__/DataTable.default-state.test.tsx +14 -42
- package/src/components/DataTable/__tests__/DataTable.export.test.tsx +13 -10
- package/src/components/DataTable/__tests__/DataTable.grouping-aggregation.test.tsx +14 -11
- package/src/components/DataTable/__tests__/DataTable.hooks.test.tsx +4 -2
- package/src/components/DataTable/__tests__/DataTable.test.tsx +13 -7
- package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +13 -10
- package/src/components/DataTable/__tests__/DataTableCore.test.tsx +15 -11
- package/src/components/DataTable/__tests__/a11y.basic.test.tsx +12 -6
- package/src/components/DataTable/__tests__/keyboard.test.tsx +12 -6
- package/src/components/DataTable/__tests__/pagination.modes.test.tsx +10 -6
- package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +1 -1
- package/src/components/DataTable/components/DataTableBody.tsx +10 -25
- package/src/components/DataTable/components/DataTableCore.tsx +1 -1
- package/src/components/DataTable/components/FilterRow.tsx +3 -1
- package/src/components/DataTable/components/ImportModal.tsx +1 -1
- package/src/components/DataTable/components/VirtualizedDataTable.tsx +9 -9
- package/src/components/DataTable/core/ColumnFactory.ts +6 -6
- package/src/components/DataTable/core/DataTableContext.tsx +14 -10
- package/src/components/DataTable/core/LocalDataAdapter.ts +2 -1
- package/src/components/DataTable/core/PluginRegistry.ts +3 -3
- package/src/components/DataTable/core/StateManager.ts +12 -11
- package/src/components/DataTable/core/__tests__/ActionManager.test.ts +104 -0
- package/src/components/DataTable/core/__tests__/DataManager.test.ts +101 -0
- package/src/components/DataTable/core/__tests__/LocalDataAdapter.test.ts +84 -0
- package/src/components/DataTable/core/__tests__/PluginRegistry.test.ts +102 -0
- package/src/components/DataTable/core/__tests__/StateManager.test.ts +104 -0
- package/src/components/DataTable/core/interfaces.ts +17 -17
- package/src/components/DataTable/hooks/__tests__/useDataTableConfiguration.test.ts +124 -0
- package/src/components/DataTable/hooks/__tests__/useDataTableDataPipeline.test.ts +117 -0
- package/src/components/DataTable/hooks/__tests__/useDataTablePermissions.test.ts +102 -0
- package/src/components/DataTable/hooks/__tests__/useEffectiveColumnOrder.test.ts +53 -0
- package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +0 -2
- package/src/components/DataTable/hooks/useDataTablePermissions.ts +9 -8
- package/src/components/DataTable/types.ts +5 -5
- package/src/components/DataTable/utils/aggregationUtils.ts +4 -4
- package/src/components/DataTable/utils/columnUtils.ts +3 -2
- package/src/components/DataTable/utils/debugTools.ts +1 -1
- package/src/components/DataTable/utils/exportUtils.ts +6 -6
- package/src/components/DataTable/utils/hierarchicalSorting.ts +6 -6
- package/src/components/DataTable/utils/hierarchicalUtils.ts +0 -8
- package/src/components/DataTable/utils/index.ts +0 -1
- package/src/components/DataTable/utils/performanceUtils.ts +9 -4
- package/src/components/Dialog/Dialog.test.tsx +49 -27
- package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +13 -8
- package/src/components/EventSelector/EventSelector.test.tsx +60 -12
- package/src/components/EventSelector/EventSelector.tsx +38 -15
- package/src/components/EventSelector/index.ts +2 -2
- package/src/components/FileDisplay/FileDisplay.test.tsx +143 -85
- package/src/components/FileDisplay/FileDisplay.tsx +1 -0
- package/src/components/FileUpload/FileUpload.test.tsx +532 -152
- package/src/components/FileUpload/FileUpload.tsx +43 -8
- package/src/components/Footer/Footer.test.tsx +19 -14
- package/src/components/Form/Form.test.tsx +96 -14
- package/src/components/Form/Form.tsx +210 -1
- package/src/components/Form/index.ts +3 -7
- package/src/components/Header/Header.test.tsx +24 -17
- package/src/components/Header/Header.tsx +3 -1
- package/src/components/InactivityWarningModal/InactivityWarningModal.tsx +2 -4
- package/src/components/Input/Input.test.tsx +61 -36
- package/src/components/Label/{__tests__/Label.test.tsx → Label.test.tsx} +2 -2
- package/src/components/Label/Label.tsx +2 -3
- package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +6 -5
- package/src/components/LoadingSpinner/LoadingSpinner.tsx +6 -2
- package/src/components/LoginForm/LoginForm.test.tsx +14 -13
- package/src/components/LoginForm/LoginForm.tsx +1 -1
- package/src/components/LoginForm/index.ts +7 -0
- package/src/components/NavigationMenu/NavigationMenu.test.tsx +233 -20
- package/src/components/NavigationMenu/NavigationMenu.tsx +191 -55
- package/src/components/NavigationMenu/index.ts +1 -1
- package/src/components/OrganisationSelector/OrganisationSelector.test.tsx +20 -11
- package/src/components/OrganisationSelector/OrganisationSelector.tsx +1 -1
- package/src/components/PaceAppLayout/{__tests__/PaceAppLayout.integration.test.tsx → PaceAppLayout.integration.test.tsx} +272 -79
- package/src/components/PaceAppLayout/{__tests__/PaceAppLayout.performance.test.tsx → PaceAppLayout.performance.test.tsx} +155 -32
- package/src/components/PaceAppLayout/{__tests__/PaceAppLayout.security.test.tsx → PaceAppLayout.security.test.tsx} +211 -65
- package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +498 -210
- package/src/components/PaceAppLayout/PaceAppLayout.tsx +63 -64
- package/src/components/PaceAppLayout/test-setup.tsx +192 -0
- package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +193 -39
- package/src/components/{PasswordReset → PasswordChange}/PasswordChangeForm.test.tsx +2 -2
- package/src/components/{PasswordReset → PasswordChange}/PasswordChangeForm.tsx +10 -4
- package/src/components/PasswordChange/index.ts +2 -0
- package/src/components/Progress/Progress.test.tsx +11 -0
- package/src/components/Progress/Progress.tsx +1 -1
- package/src/components/Progress/index.ts +10 -0
- package/src/components/ProtectedRoute/ProtectedRoute.test.tsx +2 -1
- package/src/components/PublicLayout/PublicLayout.test.tsx +1210 -0
- package/src/components/PublicLayout/PublicPageLayout.tsx +190 -36
- package/src/components/PublicLayout/PublicPageProvider.tsx +8 -7
- package/src/components/PublicLayout/index.ts +10 -28
- package/src/components/Select/Select.test.tsx +7 -7
- package/src/components/Select/Select.tsx +277 -11
- package/src/components/Select/index.ts +1 -2
- package/src/components/SessionRestorationLoader/SessionRestorationLoader.test.tsx +232 -0
- package/src/components/SessionRestorationLoader/SessionRestorationLoader.tsx +40 -19
- package/src/components/Table/{__tests__/Table.test.tsx → Table.test.tsx} +94 -41
- package/src/components/Tabs/Tabs.test.tsx +10 -9
- package/src/components/Tabs/Tabs.tsx +61 -33
- package/src/components/Textarea/Textarea.test.tsx +31 -18
- package/src/components/Toast/Toast.tsx +2 -2
- package/src/components/Tooltip/Tooltip.test.tsx +1 -1
- package/src/components/UserMenu/UserMenu.test.tsx +7 -6
- package/src/components/UserMenu/UserMenu.tsx +2 -2
- package/src/components/index.ts +5 -4
- package/src/constants/performance.ts +19 -8
- package/src/hooks/__tests__/useAppConfig.unit.test.ts +21 -22
- package/src/hooks/__tests__/useEvents.unit.test.ts +5 -4
- package/src/hooks/__tests__/useOrganisationPermissions.unit.test.tsx +2 -2
- package/src/hooks/__tests__/usePermissionCache.simple.test.ts +17 -0
- package/src/hooks/__tests__/usePermissionCache.unit.test.ts +16 -11
- package/src/hooks/__tests__/usePublicEvent.simple.test.ts +1 -3
- package/src/hooks/__tests__/usePublicEvent.unit.test.ts +1 -3
- package/src/hooks/__tests__/useRBAC.unit.test.ts +24 -2
- package/src/hooks/index.ts +4 -0
- package/src/hooks/public/index.ts +2 -0
- package/src/hooks/public/usePublicEvent.ts +4 -6
- package/src/hooks/public/usePublicEventLogo.test.ts +147 -0
- package/src/hooks/public/usePublicRouteParams.ts +1 -1
- package/src/hooks/services/useAuth.ts +2 -4
- package/src/hooks/services/useCurrentEvent.ts +1 -1
- package/src/hooks/useAppConfig.ts +1 -1
- package/src/hooks/useDataTablePerformance.ts +2 -2
- package/src/hooks/useEventTheme.ts +1 -1
- package/src/hooks/useEvents.ts +51 -10
- package/src/hooks/useOrganisationPermissions.test.ts +3 -3
- package/src/hooks/useOrganisationPermissions.ts +1 -1
- package/src/hooks/useOrganisationSecurity.ts +2 -2
- package/src/hooks/usePermissionCache.test.ts +9 -9
- package/src/hooks/usePermissionCache.ts +2 -2
- package/src/index.ts +19 -12
- package/src/providers/OrganisationProvider.tsx +73 -9
- package/src/providers/UnifiedAuthProvider.smoke.test.tsx +113 -13
- package/src/providers/__tests__/AuthProvider.test.tsx +2 -1
- package/src/providers/__tests__/EventProvider.test.tsx +24 -15
- package/src/providers/__tests__/OrganisationProvider.test.tsx +87 -36
- package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +80 -24
- package/src/providers/index.ts +0 -3
- package/src/providers/services/AuthServiceProvider.tsx +2 -17
- package/src/providers/services/EventServiceProvider.tsx +11 -16
- package/src/providers/services/InactivityServiceProvider.tsx +9 -12
- package/src/providers/services/OrganisationServiceProvider.tsx +9 -12
- package/src/providers/services/UnifiedAuthProvider.tsx +85 -18
- package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +11 -4
- package/src/rbac/__tests__/scenarios.user-role.test.tsx +105 -21
- package/src/rbac/adapters.tsx +1 -1
- package/src/rbac/api.ts +20 -4
- package/src/rbac/audit-enhanced.ts +47 -2
- package/src/rbac/audit.ts +47 -2
- package/src/rbac/components/NavigationGuard.tsx +1 -1
- package/src/rbac/components/NavigationProvider.test.tsx +7 -6
- package/src/rbac/components/NavigationProvider.tsx +1 -1
- package/src/rbac/components/PagePermissionGuard.tsx +1 -1
- package/src/rbac/components/PagePermissionProvider.test.tsx +7 -6
- package/src/rbac/components/PagePermissionProvider.tsx +1 -1
- package/src/rbac/components/PermissionEnforcer.tsx +1 -1
- package/src/rbac/components/RoleBasedRouter.tsx +1 -1
- package/src/rbac/components/SecureDataProvider.test.tsx +7 -6
- package/src/rbac/components/SecureDataProvider.tsx +1 -1
- package/src/rbac/components/__tests__/EnhancedNavigationMenu.test.tsx +6 -6
- package/src/rbac/components/__tests__/NavigationGuard.test.tsx +11 -10
- package/src/rbac/components/__tests__/NavigationProvider.test.tsx +10 -11
- package/src/rbac/components/__tests__/PagePermissionGuard.race-condition.test.tsx +19 -15
- package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +13 -12
- package/src/rbac/components/__tests__/PagePermissionGuard.verification.test.tsx +19 -15
- package/src/rbac/components/__tests__/PagePermissionProvider.test.tsx +18 -18
- package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +11 -10
- package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +8 -7
- package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +10 -11
- package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +48 -19
- package/src/rbac/hooks/__tests__/useSecureSupabase.test.ts +476 -0
- package/src/rbac/hooks/index.ts +3 -0
- package/src/rbac/hooks/usePermissions.ts +31 -85
- package/src/rbac/hooks/useRBAC.test.ts +13 -1
- package/src/rbac/hooks/useRBAC.ts +13 -67
- package/src/rbac/hooks/useResolvedScope.ts +11 -0
- package/src/rbac/hooks/useSecureSupabase.ts +308 -0
- package/src/rbac/index.ts +3 -0
- package/src/rbac/secureClient.ts +53 -6
- package/src/rbac/security.ts +37 -1
- package/src/{types/rbac-functions.ts → rbac/types/functions.ts} +30 -30
- package/src/rbac/types.ts +3 -2
- package/src/services/AuthService.ts +33 -25
- package/src/services/EventService.ts +56 -44
- package/src/services/InactivityService.ts +33 -53
- package/src/services/OrganisationService.ts +36 -40
- package/src/services/__tests__/AuthService.restoreSession.test.ts +6 -2
- package/src/services/__tests__/EventService.test.ts +67 -33
- package/src/services/interfaces/IEventService.ts +1 -1
- package/src/styles/core.css +2 -2
- package/src/styles/index.test.ts +21 -0
- package/src/styles/index.ts +1 -5
- package/src/types/__tests__/guards.test.ts +1 -1
- package/src/types/__tests__/organisation.roles.test.ts +55 -0
- package/src/types/__tests__/type-validation.test.ts +0 -1
- package/src/types/auth.ts +42 -2
- package/src/types/core.ts +251 -0
- package/src/types/database.ts +11 -496
- package/src/types/event.ts +102 -0
- package/src/types/file-reference.ts +6 -4
- package/src/types/guards.ts +2 -1
- package/src/types/index.ts +48 -14
- package/src/types/lodash.debounce.d.ts +15 -0
- package/src/types/organisation.ts +14 -10
- package/src/types/supabase.ts +15 -17
- package/src/utils/__tests__/secureErrors.unit.test.ts +1 -1
- package/src/utils/__tests__/validationUtils.unit.test.ts +0 -29
- package/src/utils/app/appNameResolver.ts +1 -1
- package/src/utils/audit/audit.test.ts +65 -0
- package/src/utils/device/deviceFingerprint.test.ts +171 -0
- package/src/utils/dynamic/dynamicUtils.ts +3 -2
- package/src/utils/file-reference/index.ts +25 -6
- package/src/utils/security/secureErrors.ts +1 -1
- package/src/utils/validation/__tests__/validationUtils.test.ts +72 -0
- package/src/utils/validation/index.ts +6 -12
- package/src/utils/validation/validationUtils.ts +0 -13
- package/dist/UnifiedAuthProvider-B37ATQHE.js +0 -16
- package/dist/auth-DReDSLq9.d.ts +0 -16
- package/dist/chunk-3JI76CYK.js +0 -2444
- package/dist/chunk-3JI76CYK.js.map +0 -1
- package/dist/chunk-56XJ3TU6.js +0 -11
- package/dist/chunk-56XJ3TU6.js.map +0 -1
- package/dist/chunk-5MT24GKJ.js.map +0 -1
- package/dist/chunk-7QCC6MCP.js +0 -288
- package/dist/chunk-BESYRHQM.js.map +0 -1
- package/dist/chunk-BJPBT3CU.js +0 -21
- package/dist/chunk-BJPBT3CU.js.map +0 -1
- package/dist/chunk-BVYWGZVV.js.map +0 -1
- package/dist/chunk-CX5M4ZAG.js.map +0 -1
- package/dist/chunk-D7LCGMVS.js.map +0 -1
- package/dist/chunk-EGI6MUL6.js +0 -27
- package/dist/chunk-EGI6MUL6.js.map +0 -1
- package/dist/chunk-ERISIBYU.js.map +0 -1
- package/dist/chunk-HRO5HWN2.js.map +0 -1
- package/dist/chunk-HZLDFOE4.js.map +0 -1
- package/dist/chunk-JISYG63F.js +0 -70
- package/dist/chunk-JISYG63F.js.map +0 -1
- package/dist/chunk-LIMSTKYD.js +0 -61
- package/dist/chunk-LIMSTKYD.js.map +0 -1
- package/dist/chunk-OWAG3GSU.js.map +0 -1
- package/dist/chunk-PPMP5J6T.js.map +0 -1
- package/dist/chunk-Q5QRDWKI.js.map +0 -1
- package/dist/chunk-S5OFRT4M.js.map +0 -1
- package/dist/chunk-SBVILCCA.js.map +0 -1
- package/dist/chunk-TUMEWN34.js +0 -15
- package/dist/chunk-TUMEWN34.js.map +0 -1
- package/dist/chunk-XDNLUEXI.js +0 -138
- package/dist/chunk-XJ2HZOBU.js.map +0 -1
- package/dist/chunk-ZYTYSTO5.js.map +0 -1
- package/dist/chunk-ZZ2SS7NI.js +0 -237
- package/dist/chunk-ZZ2SS7NI.js.map +0 -1
- package/dist/database-C6jy7EOu.d.ts +0 -500
- package/dist/organisation-D6qRDtbF.d.ts +0 -93
- package/dist/schema-DTDZQe2u.d.ts +0 -28
- package/dist/unified-DQ4VcT7H.d.ts +0 -198
- package/dist/useInactivityTracker-TO6ZOF35.js +0 -11
- package/dist/validation.d.ts +0 -47
- package/dist/validation.js +0 -24
- package/dist/validation.js.map +0 -1
- package/docs/DOCUMENTATION_AUDIT.md +0 -172
- package/docs/DOCUMENTATION_STANDARD.md +0 -137
- package/docs/api/classes/PublicErrorBoundary.md +0 -132
- package/docs/api/interfaces/EventLogoProps.md +0 -152
- package/docs/api/interfaces/PublicErrorBoundaryProps.md +0 -94
- package/docs/api/interfaces/PublicErrorBoundaryState.md +0 -68
- package/docs/api/interfaces/PublicLoadingSpinnerProps.md +0 -86
- package/docs/architecture/rpc-function-standards.md +0 -1106
- package/docs/getting-started/consuming-app-vite-config.md +0 -239
- package/docs/implementation-guides/event-theming-summary.md +0 -226
- package/docs/implementation-guides/public-pages-advanced.md +0 -1038
- package/docs/migration/v0.4.15-tailwind-scanning.md +0 -278
- package/docs/migration/v0.4.16-css-first-approach.md +0 -312
- package/docs/migration/v0.4.17-source-path-fix.md +0 -235
- package/docs/rbac/RBAC_EVENT_CONTEXT_LOADING.md +0 -222
- package/docs/rbac/RBAC_LOGIN_SAFETY_FIX.md +0 -95
- package/docs/rbac/RBAC_V0.5.147_FIX.md +0 -117
- package/docs/rbac/README-rbac-rls-integration.md +0 -374
- package/docs/styles/usage.md +0 -227
- package/docs/testing/visual-testing.md +0 -120
- package/docs/troubleshooting/DEBUG_NETWORK_ERROR.md +0 -152
- package/docs/troubleshooting/FIX_SUPABASE_CORS.md +0 -184
- package/docs/troubleshooting/cake-page-permission-guard-issue-summary.md +0 -193
- package/docs/troubleshooting/database-view-compatibility.md +0 -125
- package/docs/troubleshooting/react-hooks-issue-analysis.md +0 -172
- package/docs/troubleshooting/tailwind-content-scanning.md +0 -219
- package/examples/RBAC/EventBasedApp.tsx +0 -239
- package/examples/RBAC/PermissionExample.tsx +0 -151
- package/examples/STRUCTURE.md +0 -125
- package/examples/components 2/DataTable/HierarchicalExample.tsx +0 -475
- package/examples/components 2/Dialog/BasicHtmlTest.tsx +0 -55
- package/examples/components 2/Dialog/DebugHtmlExample.tsx +0 -68
- package/examples/components 2/Dialog/HtmlDialogExample.tsx +0 -202
- package/examples/components 2/Dialog/SimpleHtmlTest.tsx +0 -61
- package/examples/components 2/Dialog/SmartDialogExample.tsx +0 -322
- package/examples/components 2/index.ts +0 -11
- package/examples/features/index.ts +0 -12
- package/examples/features/rbac/CompleteRBACExample.tsx +0 -324
- package/examples/features/rbac/index.ts +0 -13
- package/examples/public-pages/CorrectPublicPageImplementation.tsx +0 -301
- package/examples/public-pages/PublicEventPage.tsx +0 -274
- package/examples/public-pages/PublicPageApp.tsx +0 -308
- package/examples/public-pages/PublicPageUsageExample.tsx +0 -216
- package/examples/public-pages/index.ts +0 -14
- package/src/__tests__/TEST_STANDARD.md +0 -1008
- package/src/components/Checkbox/__mocks__/Checkbox.tsx +0 -2
- package/src/components/DataTable/examples/HierarchicalActionsExample.tsx +0 -421
- package/src/components/DataTable/examples/InitialPageSizeExample.tsx +0 -177
- package/src/components/DataTable/examples/PerformanceExample.tsx +0 -506
- package/src/components/DataTable/examples/__tests__/HierarchicalActionsExample.test.tsx +0 -316
- package/src/components/DataTable/examples/__tests__/HierarchicalExample.test.tsx +0 -45
- package/src/components/DataTable/examples/__tests__/InitialPageSizeExample.test.tsx +0 -211
- package/src/components/DataTable/examples/__tests__/PerformanceExample.test.tsx +0 -126
- package/src/components/Dialog/README.md +0 -804
- package/src/components/Dialog/examples/BasicHtmlTest.tsx +0 -55
- package/src/components/Dialog/examples/DebugHtmlExample.tsx +0 -68
- package/src/components/Dialog/examples/ScrollableDialogExample.tsx +0 -290
- package/src/components/Dialog/examples/SimpleHtmlTest.tsx +0 -61
- package/src/components/Dialog/examples/__tests__/HtmlDialogExample.test.tsx +0 -71
- package/src/components/Dialog/examples/__tests__/SimpleHtmlTest.test.tsx +0 -122
- package/src/components/Dialog/examples/__tests__/SmartDialogExample.unit.test.tsx +0 -147
- package/src/components/Dialog/utils/__tests__/safeHtml.unit.test.ts +0 -611
- package/src/components/Dialog/utils/safeHtml.ts +0 -185
- package/src/components/EventSelector/types.ts +0 -79
- package/src/components/Form/FormErrorSummary.tsx +0 -113
- package/src/components/Form/FormField.tsx +0 -249
- package/src/components/Form/FormFieldset.tsx +0 -127
- package/src/components/Form/FormLiveRegion.tsx +0 -198
- package/src/components/Input/__mocks__/Input.tsx +0 -2
- package/src/components/NavigationMenu/types.ts +0 -85
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.accessibility.test.tsx +0 -326
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.unit.test.tsx +0 -1078
- package/src/components/PasswordReset/PasswordResetForm.test.tsx +0 -597
- package/src/components/PasswordReset/PasswordResetForm.tsx +0 -201
- package/src/components/PasswordReset/index.ts +0 -2
- package/src/components/ProtectedRoute/README.md +0 -164
- package/src/components/PublicLayout/EventLogo.tsx +0 -175
- package/src/components/PublicLayout/PublicErrorBoundary.tsx +0 -282
- package/src/components/PublicLayout/PublicLoadingSpinner.tsx +0 -216
- package/src/components/PublicLayout/PublicPageContextChecker.tsx +0 -131
- package/src/components/PublicLayout/PublicPageDebugger.tsx +0 -104
- package/src/components/PublicLayout/PublicPageDiagnostic.tsx +0 -162
- package/src/components/PublicLayout/PublicPageFooter.tsx +0 -124
- package/src/components/PublicLayout/PublicPageHeader.tsx +0 -209
- package/src/components/PublicLayout/__tests__/PublicErrorBoundary.test.tsx +0 -449
- package/src/components/PublicLayout/__tests__/PublicLoadingSpinner.test.tsx +0 -393
- package/src/components/PublicLayout/__tests__/PublicPageContextChecker.test.tsx +0 -192
- package/src/components/PublicLayout/__tests__/PublicPageFooter.test.tsx +0 -351
- package/src/components/PublicLayout/__tests__/PublicPageHeader.test.tsx +0 -402
- package/src/components/PublicLayout/__tests__/PublicPageLayout.test.tsx +0 -460
- package/src/components/PublicLayout/__tests__/PublicPageProvider.test.tsx +0 -313
- package/src/components/Select/hooks.ts +0 -289
- package/src/hooks/useCounter.test.ts +0 -131
- package/src/hooks/useDebounce.test.ts +0 -375
- package/src/providers/AuthProvider.tsx +0 -15
- package/src/providers/EventProvider.tsx +0 -16
- package/src/providers/InactivityProvider.tsx +0 -15
- package/src/providers/OrganisationProvider.context.test.tsx +0 -169
- package/src/providers/UnifiedAuthProvider.tsx +0 -15
- package/src/types/theme.ts +0 -6
- package/src/types/unified.ts +0 -265
- package/src/utils/appConfig.ts +0 -47
- package/src/utils/appIdResolver.test.ts +0 -499
- package/src/utils/appIdResolver.ts +0 -130
- package/src/utils/appNameResolver.simple.test.ts +0 -212
- package/src/utils/appNameResolver.test.ts +0 -121
- package/src/utils/appNameResolver.ts +0 -191
- package/src/utils/audit.ts +0 -127
- package/src/utils/auth-utils.ts +0 -96
- package/src/utils/bundleAnalysis.ts +0 -129
- package/src/utils/debugLogger.ts +0 -67
- package/src/utils/deviceFingerprint.ts +0 -215
- package/src/utils/dynamicUtils.ts +0 -105
- package/src/utils/file-reference.test.ts +0 -788
- package/src/utils/file-reference.ts +0 -519
- package/src/utils/formatDate.test.ts +0 -237
- package/src/utils/formatting.ts +0 -170
- package/src/utils/lazyLoad.tsx +0 -44
- package/src/utils/logger.ts +0 -179
- package/src/utils/organisationContext.test.ts +0 -322
- package/src/utils/organisationContext.ts +0 -153
- package/src/utils/performanceBenchmark.ts +0 -64
- package/src/utils/performanceBudgets.ts +0 -110
- package/src/utils/permissionTypes.ts +0 -37
- package/src/utils/permissionUtils.test.ts +0 -393
- package/src/utils/permissionUtils.ts +0 -34
- package/src/utils/sanitization.ts +0 -264
- package/src/utils/schemaUtils.ts +0 -37
- package/src/utils/secureDataAccess.test.ts +0 -711
- package/src/utils/secureDataAccess.ts +0 -377
- package/src/utils/secureErrors.ts +0 -79
- package/src/utils/security.ts +0 -156
- package/src/utils/securityMonitor.ts +0 -45
- package/src/utils/sessionTracking.ts +0 -126
- package/src/utils/validation.ts +0 -111
- package/src/utils/validationUtils.ts +0 -120
- package/src/validation/index.ts +0 -12
- /package/dist/{DataTable-UA6CL4JI.js.map → DataTable-QAB34V6K.js.map} +0 -0
- /package/dist/{UnifiedAuthProvider-B37ATQHE.js.map → UnifiedAuthProvider-7F6T4B6K.js.map} +0 -0
- /package/dist/{api-45XYYO2A.js.map → api-ROMBCNKU.js.map} +0 -0
- /package/dist/{audit-64X3VJXB.js.map → audit-WRS3KJKI.js.map} +0 -0
- /package/dist/{chunk-PLDDJCW6.js.map → chunk-7D4SUZUM.js.map} +0 -0
- /package/dist/{useInactivityTracker-TO6ZOF35.js.map → chunk-KQCRWDSA.js.map} +0 -0
- /package/examples/{components 2/DataTable → DataTable}/InitialPageSizeExample.tsx +0 -0
- /package/examples/{features/public-pages → PublicPages}/index.ts +0 -0
- /package/examples/{RBAC → rbac}/index.ts +0 -0
|
@@ -1,611 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file Safe HTML Utilities Unit Tests
|
|
3
|
-
* @package @jmruthers/pace-core
|
|
4
|
-
* @module Components/Dialog/Utils/Tests
|
|
5
|
-
* @since 0.4.36
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
9
|
-
import { sanitizeHtml, validateHtml, renderSafeHtml } from '../safeHtml';
|
|
10
|
-
|
|
11
|
-
// Mock console methods to avoid noise in test output
|
|
12
|
-
const originalConsoleLog = console.log;
|
|
13
|
-
const originalConsoleWarn = console.warn;
|
|
14
|
-
|
|
15
|
-
describe('Safe HTML Utilities', () => {
|
|
16
|
-
beforeEach(() => {
|
|
17
|
-
vi.clearAllMocks();
|
|
18
|
-
// Mock console methods
|
|
19
|
-
console.log = vi.fn();
|
|
20
|
-
console.warn = vi.fn();
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
afterEach(() => {
|
|
24
|
-
// Restore console methods
|
|
25
|
-
console.log = originalConsoleLog;
|
|
26
|
-
console.warn = originalConsoleWarn;
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
describe('sanitizeHtml', () => {
|
|
30
|
-
describe('Input validation', () => {
|
|
31
|
-
it('should return empty string for null input', () => {
|
|
32
|
-
const result = sanitizeHtml(null as any);
|
|
33
|
-
expect(result).toBe('');
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it('should return empty string for undefined input', () => {
|
|
37
|
-
const result = sanitizeHtml(undefined as any);
|
|
38
|
-
expect(result).toBe('');
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it('should return empty string for non-string input', () => {
|
|
42
|
-
const result = sanitizeHtml(123 as any);
|
|
43
|
-
expect(result).toBe('');
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it('should return empty string for empty string', () => {
|
|
47
|
-
const result = sanitizeHtml('');
|
|
48
|
-
expect(result).toBe('');
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
it('should handle whitespace-only strings', () => {
|
|
52
|
-
const result = sanitizeHtml(' \n\t ');
|
|
53
|
-
expect(result).toBe(' \n\t ');
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
describe('Basic HTML sanitization', () => {
|
|
58
|
-
it('should preserve safe HTML tags', () => {
|
|
59
|
-
const html = '<p>Hello <strong>world</strong>!</p>';
|
|
60
|
-
const result = sanitizeHtml(html);
|
|
61
|
-
expect(result).toBe(html);
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it('should preserve safe HTML with attributes', () => {
|
|
65
|
-
const html = '<div class="container" id="main">Content</div>';
|
|
66
|
-
const result = sanitizeHtml(html);
|
|
67
|
-
expect(result).toBe(html);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it('should preserve complex safe HTML structures', () => {
|
|
71
|
-
const html = `
|
|
72
|
-
<section>
|
|
73
|
-
<h1>Title</h1>
|
|
74
|
-
<p>Paragraph with <em>emphasis</em> and <a href="/link">link</a></p>
|
|
75
|
-
<ul>
|
|
76
|
-
<li>Item 1</li>
|
|
77
|
-
<li>Item 2</li>
|
|
78
|
-
</ul>
|
|
79
|
-
</section>
|
|
80
|
-
`;
|
|
81
|
-
const result = sanitizeHtml(html);
|
|
82
|
-
expect(result).toBe(html);
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
it('should preserve table structures', () => {
|
|
86
|
-
const html = `
|
|
87
|
-
<table>
|
|
88
|
-
<thead>
|
|
89
|
-
<tr>
|
|
90
|
-
<th>Header 1</th>
|
|
91
|
-
<th>Header 2</th>
|
|
92
|
-
</tr>
|
|
93
|
-
</thead>
|
|
94
|
-
<tbody>
|
|
95
|
-
<tr>
|
|
96
|
-
<td>Data 1</td>
|
|
97
|
-
<td>Data 2</td>
|
|
98
|
-
</tr>
|
|
99
|
-
</tbody>
|
|
100
|
-
</table>
|
|
101
|
-
`;
|
|
102
|
-
const result = sanitizeHtml(html);
|
|
103
|
-
expect(result).toBe(html);
|
|
104
|
-
});
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
describe('Dangerous content removal', () => {
|
|
108
|
-
it('should remove script tags', () => {
|
|
109
|
-
const html = '<p>Safe content</p><script>alert("xss")</script><p>More content</p>';
|
|
110
|
-
const result = sanitizeHtml(html);
|
|
111
|
-
expect(result).toBe('<p>Safe content</p><p>More content</p>');
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it('should remove script tags with attributes', () => {
|
|
115
|
-
const html = '<p>Safe</p><script type="text/javascript" src="malicious.js">alert("xss")</script><p>Content</p>';
|
|
116
|
-
const result = sanitizeHtml(html);
|
|
117
|
-
expect(result).toBe('<p>Safe</p><p>Content</p>');
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
it('should remove iframe tags', () => {
|
|
121
|
-
const html = '<p>Safe content</p><iframe src="malicious.com"></iframe><p>More content</p>';
|
|
122
|
-
const result = sanitizeHtml(html);
|
|
123
|
-
expect(result).toBe('<p>Safe content</p><p>More content</p>');
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
it('should remove iframe tags with attributes', () => {
|
|
127
|
-
const html = '<p>Safe</p><iframe width="100" height="100" src="evil.com"></iframe><p>Content</p>';
|
|
128
|
-
const result = sanitizeHtml(html);
|
|
129
|
-
expect(result).toBe('<p>Safe</p><p>Content</p>');
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
it('should partially remove event handlers (basic implementation)', () => {
|
|
133
|
-
const html = '<p onclick="alert(\'xss\')">Click me</p>';
|
|
134
|
-
const result = sanitizeHtml(html);
|
|
135
|
-
// The basic implementation may not fully remove event handlers with nested quotes
|
|
136
|
-
expect(result).toContain('<p');
|
|
137
|
-
expect(result).toContain('Click me</p>');
|
|
138
|
-
expect(result).not.toContain('<script>');
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
it('should partially remove multiple event handlers (basic implementation)', () => {
|
|
142
|
-
const html = '<div onmouseover="evil()" onload="bad()" onclick="alert(\'xss\')">Content</div>';
|
|
143
|
-
const result = sanitizeHtml(html);
|
|
144
|
-
// The basic implementation may not fully remove event handlers with nested quotes
|
|
145
|
-
expect(result).toContain('<div');
|
|
146
|
-
expect(result).toContain('Content</div>');
|
|
147
|
-
expect(result).not.toContain('<script>');
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
it('should partially remove javascript: protocols (basic implementation)', () => {
|
|
151
|
-
const html = '<a href="javascript:alert(\'xss\')">Link</a>';
|
|
152
|
-
const result = sanitizeHtml(html);
|
|
153
|
-
// The basic implementation may not fully remove protocols with nested quotes
|
|
154
|
-
expect(result).toContain('<a href=');
|
|
155
|
-
expect(result).toContain('Link</a>');
|
|
156
|
-
expect(result).not.toContain('<script>');
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
it('should partially remove data: protocols (basic implementation)', () => {
|
|
160
|
-
const html = '<img src="data:text/html,<script>alert(\'xss\')</script>">';
|
|
161
|
-
const result = sanitizeHtml(html);
|
|
162
|
-
// The basic implementation may not fully remove protocols with nested quotes
|
|
163
|
-
expect(result).toContain('<img src=');
|
|
164
|
-
expect(result).not.toContain('<script>');
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
it('should handle case-insensitive dangerous content', () => {
|
|
168
|
-
const html = '<SCRIPT>alert("xss")</SCRIPT><IFRAME src="evil.com"></IFRAME>';
|
|
169
|
-
const result = sanitizeHtml(html);
|
|
170
|
-
expect(result).toBe('');
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
it('should partially handle mixed case event handlers (basic implementation)', () => {
|
|
174
|
-
const html = '<div OnClick="alert(\'xss\')" ONMOUSEOVER="evil()">Content</div>';
|
|
175
|
-
const result = sanitizeHtml(html);
|
|
176
|
-
// The basic implementation may not fully remove event handlers with nested quotes
|
|
177
|
-
expect(result).toContain('<div');
|
|
178
|
-
expect(result).toContain('Content</div>');
|
|
179
|
-
expect(result).not.toContain('<script>');
|
|
180
|
-
});
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
describe('Edge cases and complex scenarios', () => {
|
|
184
|
-
it('should handle nested dangerous content', () => {
|
|
185
|
-
const html = '<div><script>alert("outer")</script><p>Safe</p><script>alert("inner")</script></div>';
|
|
186
|
-
const result = sanitizeHtml(html);
|
|
187
|
-
expect(result).toBe('<div><p>Safe</p></div>');
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
it('should handle malformed script tags', () => {
|
|
191
|
-
const html = '<p>Safe</p><script>alert("xss")<script>alert("more")</script><p>Content</p>';
|
|
192
|
-
const result = sanitizeHtml(html);
|
|
193
|
-
expect(result).toBe('<p>Safe</p><p>Content</p>');
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
it('should handle script tags with no content', () => {
|
|
197
|
-
const html = '<p>Safe</p><script></script><p>Content</p>';
|
|
198
|
-
const result = sanitizeHtml(html);
|
|
199
|
-
expect(result).toBe('<p>Safe</p><p>Content</p>');
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
it('should handle self-closing script tags', () => {
|
|
203
|
-
const html = '<p>Safe</p><script src="evil.js" /><p>Content</p>';
|
|
204
|
-
const result = sanitizeHtml(html);
|
|
205
|
-
expect(result).toBe('<p>Safe</p><p>Content</p>');
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
it('should preserve safe content while partially removing dangerous content (basic implementation)', () => {
|
|
209
|
-
const html = `
|
|
210
|
-
<div>
|
|
211
|
-
<h1>Title</h1>
|
|
212
|
-
<script>alert("xss")</script>
|
|
213
|
-
<p>This is <strong>safe</strong> content</p>
|
|
214
|
-
<iframe src="evil.com"></iframe>
|
|
215
|
-
<ul>
|
|
216
|
-
<li>Safe item</li>
|
|
217
|
-
<li onclick="alert('xss')">Dangerous item</li>
|
|
218
|
-
</ul>
|
|
219
|
-
</div>
|
|
220
|
-
`;
|
|
221
|
-
const result = sanitizeHtml(html);
|
|
222
|
-
expect(result).toContain('<h1>Title</h1>');
|
|
223
|
-
expect(result).toContain('<p>This is <strong>safe</strong> content</p>');
|
|
224
|
-
expect(result).toContain('<li>Safe item</li>');
|
|
225
|
-
expect(result).toContain('<li'); // May have partial event handler removal
|
|
226
|
-
expect(result).not.toContain('<script>');
|
|
227
|
-
expect(result).not.toContain('<iframe>');
|
|
228
|
-
});
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
describe('Console logging', () => {
|
|
232
|
-
it('should log input and output for debugging', () => {
|
|
233
|
-
const html = '<p>Test content</p>';
|
|
234
|
-
sanitizeHtml(html);
|
|
235
|
-
|
|
236
|
-
expect(console.log).toHaveBeenCalledWith('🔍 sanitizeHtml input:', html);
|
|
237
|
-
expect(console.log).toHaveBeenCalledWith('🔍 sanitizeHtml output:', html);
|
|
238
|
-
});
|
|
239
|
-
});
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
describe('validateHtml', () => {
|
|
243
|
-
describe('Input validation', () => {
|
|
244
|
-
it('should return invalid for null input', () => {
|
|
245
|
-
const result = validateHtml(null as any);
|
|
246
|
-
expect(result.isValid).toBe(false);
|
|
247
|
-
expect(result.warnings).toContain('HTML content must be a non-empty string');
|
|
248
|
-
});
|
|
249
|
-
|
|
250
|
-
it('should return invalid for undefined input', () => {
|
|
251
|
-
const result = validateHtml(undefined as any);
|
|
252
|
-
expect(result.isValid).toBe(false);
|
|
253
|
-
expect(result.warnings).toContain('HTML content must be a non-empty string');
|
|
254
|
-
});
|
|
255
|
-
|
|
256
|
-
it('should return invalid for non-string input', () => {
|
|
257
|
-
const result = validateHtml(123 as any);
|
|
258
|
-
expect(result.isValid).toBe(false);
|
|
259
|
-
expect(result.warnings).toContain('HTML content must be a non-empty string');
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
it('should return invalid for empty string', () => {
|
|
263
|
-
const result = validateHtml('');
|
|
264
|
-
expect(result.isValid).toBe(false);
|
|
265
|
-
expect(result.warnings).toContain('HTML content must be a non-empty string');
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
it('should return valid for whitespace-only strings', () => {
|
|
269
|
-
const result = validateHtml(' \n\t ');
|
|
270
|
-
expect(result.isValid).toBe(true);
|
|
271
|
-
expect(result.warnings).toEqual([]);
|
|
272
|
-
});
|
|
273
|
-
});
|
|
274
|
-
|
|
275
|
-
describe('Safe content validation', () => {
|
|
276
|
-
it('should validate safe HTML content', () => {
|
|
277
|
-
const html = '<p>Hello <strong>world</strong>!</p>';
|
|
278
|
-
const result = validateHtml(html);
|
|
279
|
-
expect(result.isValid).toBe(true);
|
|
280
|
-
expect(result.warnings).toEqual([]);
|
|
281
|
-
});
|
|
282
|
-
|
|
283
|
-
it('should validate complex safe HTML structures', () => {
|
|
284
|
-
const html = `
|
|
285
|
-
<section>
|
|
286
|
-
<h1>Title</h1>
|
|
287
|
-
<p>Paragraph with <em>emphasis</em> and <a href="/link">link</a></p>
|
|
288
|
-
<ul>
|
|
289
|
-
<li>Item 1</li>
|
|
290
|
-
<li>Item 2</li>
|
|
291
|
-
</ul>
|
|
292
|
-
</section>
|
|
293
|
-
`;
|
|
294
|
-
const result = validateHtml(html);
|
|
295
|
-
expect(result.isValid).toBe(true);
|
|
296
|
-
expect(result.warnings).toEqual([]);
|
|
297
|
-
});
|
|
298
|
-
|
|
299
|
-
it('should validate table structures', () => {
|
|
300
|
-
const html = `
|
|
301
|
-
<table>
|
|
302
|
-
<thead>
|
|
303
|
-
<tr>
|
|
304
|
-
<th>Header 1</th>
|
|
305
|
-
<th>Header 2</th>
|
|
306
|
-
</tr>
|
|
307
|
-
</thead>
|
|
308
|
-
<tbody>
|
|
309
|
-
<tr>
|
|
310
|
-
<td>Data 1</td>
|
|
311
|
-
<td>Data 2</td>
|
|
312
|
-
</tr>
|
|
313
|
-
</tbody>
|
|
314
|
-
</table>
|
|
315
|
-
`;
|
|
316
|
-
const result = validateHtml(html);
|
|
317
|
-
expect(result.isValid).toBe(true);
|
|
318
|
-
expect(result.warnings).toEqual([]);
|
|
319
|
-
});
|
|
320
|
-
});
|
|
321
|
-
|
|
322
|
-
describe('Dangerous content detection', () => {
|
|
323
|
-
it('should detect script tags', () => {
|
|
324
|
-
const html = '<p>Safe content</p><script>alert("xss")</script>';
|
|
325
|
-
const result = validateHtml(html);
|
|
326
|
-
expect(result.isValid).toBe(false);
|
|
327
|
-
expect(result.warnings).toContain('Script tags are not allowed');
|
|
328
|
-
});
|
|
329
|
-
|
|
330
|
-
it('should detect iframe tags', () => {
|
|
331
|
-
const html = '<p>Safe content</p><iframe src="malicious.com"></iframe>';
|
|
332
|
-
const result = validateHtml(html);
|
|
333
|
-
expect(result.isValid).toBe(false);
|
|
334
|
-
expect(result.warnings).toContain('Iframe tags are not allowed');
|
|
335
|
-
});
|
|
336
|
-
|
|
337
|
-
it('should detect object tags', () => {
|
|
338
|
-
const html = '<p>Safe content</p><object data="malicious.swf"></object>';
|
|
339
|
-
const result = validateHtml(html);
|
|
340
|
-
expect(result.isValid).toBe(false);
|
|
341
|
-
expect(result.warnings).toContain('Object tags are not allowed');
|
|
342
|
-
});
|
|
343
|
-
|
|
344
|
-
it('should detect embed tags', () => {
|
|
345
|
-
const html = '<p>Safe content</p><embed src="malicious.swf">';
|
|
346
|
-
const result = validateHtml(html);
|
|
347
|
-
expect(result.isValid).toBe(false);
|
|
348
|
-
expect(result.warnings).toContain('Embed tags are not allowed');
|
|
349
|
-
});
|
|
350
|
-
|
|
351
|
-
it('should detect form tags', () => {
|
|
352
|
-
const html = '<p>Safe content</p><form action="/submit"><input type="text"></form>';
|
|
353
|
-
const result = validateHtml(html);
|
|
354
|
-
expect(result.isValid).toBe(false);
|
|
355
|
-
expect(result.warnings).toContain('Form tags are not allowed');
|
|
356
|
-
});
|
|
357
|
-
|
|
358
|
-
it('should detect input tags', () => {
|
|
359
|
-
const html = '<p>Safe content</p><input type="text" value="test">';
|
|
360
|
-
const result = validateHtml(html);
|
|
361
|
-
expect(result.isValid).toBe(false);
|
|
362
|
-
expect(result.warnings).toContain('Input tags are not allowed');
|
|
363
|
-
});
|
|
364
|
-
|
|
365
|
-
it('should detect button tags', () => {
|
|
366
|
-
const html = '<p>Safe content</p><button onclick="alert(\'xss\')">Click me</button>';
|
|
367
|
-
const result = validateHtml(html);
|
|
368
|
-
expect(result.isValid).toBe(false);
|
|
369
|
-
expect(result.warnings).toContain('Button tags are not allowed');
|
|
370
|
-
});
|
|
371
|
-
|
|
372
|
-
it('should detect event handlers', () => {
|
|
373
|
-
const html = '<p onclick="alert(\'xss\')">Click me</p>';
|
|
374
|
-
const result = validateHtml(html);
|
|
375
|
-
expect(result.isValid).toBe(false);
|
|
376
|
-
expect(result.warnings).toContain('Event handlers are not allowed');
|
|
377
|
-
});
|
|
378
|
-
|
|
379
|
-
it('should detect javascript protocols', () => {
|
|
380
|
-
const html = '<a href="javascript:alert(\'xss\')">Link</a>';
|
|
381
|
-
const result = validateHtml(html);
|
|
382
|
-
expect(result.isValid).toBe(false);
|
|
383
|
-
expect(result.warnings).toContain('JavaScript protocols are not allowed');
|
|
384
|
-
});
|
|
385
|
-
|
|
386
|
-
it('should detect data protocols', () => {
|
|
387
|
-
const html = '<img src="data:text/html,<script>alert(\'xss\')</script>">';
|
|
388
|
-
const result = validateHtml(html);
|
|
389
|
-
expect(result.isValid).toBe(false);
|
|
390
|
-
expect(result.warnings).toContain('Data protocols are not allowed');
|
|
391
|
-
});
|
|
392
|
-
});
|
|
393
|
-
|
|
394
|
-
describe('Multiple warnings', () => {
|
|
395
|
-
it('should collect multiple warnings', () => {
|
|
396
|
-
const html = '<script>alert("xss")</script><iframe src="evil.com"></iframe><p onclick="alert(\'xss\')">Click</p>';
|
|
397
|
-
const result = validateHtml(html);
|
|
398
|
-
expect(result.isValid).toBe(false);
|
|
399
|
-
expect(result.warnings).toHaveLength(3);
|
|
400
|
-
expect(result.warnings).toContain('Script tags are not allowed');
|
|
401
|
-
expect(result.warnings).toContain('Iframe tags are not allowed');
|
|
402
|
-
expect(result.warnings).toContain('Event handlers are not allowed');
|
|
403
|
-
});
|
|
404
|
-
|
|
405
|
-
it('should handle case-insensitive detection', () => {
|
|
406
|
-
const html = '<SCRIPT>alert("xss")</SCRIPT><IFRAME src="evil.com"></IFRAME><P ONCLICK="alert(\'xss\')">Click</P>';
|
|
407
|
-
const result = validateHtml(html);
|
|
408
|
-
expect(result.isValid).toBe(false);
|
|
409
|
-
expect(result.warnings).toHaveLength(3);
|
|
410
|
-
expect(result.warnings).toContain('Script tags are not allowed');
|
|
411
|
-
expect(result.warnings).toContain('Iframe tags are not allowed');
|
|
412
|
-
expect(result.warnings).toContain('Event handlers are not allowed');
|
|
413
|
-
});
|
|
414
|
-
});
|
|
415
|
-
|
|
416
|
-
describe('Edge cases', () => {
|
|
417
|
-
it('should handle malformed dangerous tags', () => {
|
|
418
|
-
const html = '<script>alert("xss")<script>alert("more")</script>';
|
|
419
|
-
const result = validateHtml(html);
|
|
420
|
-
expect(result.isValid).toBe(false);
|
|
421
|
-
expect(result.warnings).toContain('Script tags are not allowed');
|
|
422
|
-
});
|
|
423
|
-
|
|
424
|
-
it('should handle self-closing dangerous tags', () => {
|
|
425
|
-
const html = '<script src="evil.js" /><iframe src="evil.com" />';
|
|
426
|
-
const result = validateHtml(html);
|
|
427
|
-
expect(result.isValid).toBe(false);
|
|
428
|
-
expect(result.warnings).toContain('Script tags are not allowed');
|
|
429
|
-
expect(result.warnings).toContain('Iframe tags are not allowed');
|
|
430
|
-
});
|
|
431
|
-
|
|
432
|
-
it('should handle dangerous content in attributes', () => {
|
|
433
|
-
const html = '<p title="javascript:alert(\'xss\')">Content</p>';
|
|
434
|
-
const result = validateHtml(html);
|
|
435
|
-
expect(result.isValid).toBe(false);
|
|
436
|
-
expect(result.warnings).toContain('JavaScript protocols are not allowed');
|
|
437
|
-
});
|
|
438
|
-
});
|
|
439
|
-
});
|
|
440
|
-
|
|
441
|
-
describe('renderSafeHtml', () => {
|
|
442
|
-
describe('Basic functionality', () => {
|
|
443
|
-
it('should return sanitized HTML and validation info', () => {
|
|
444
|
-
const html = '<p>Hello <strong>world</strong>!</p>';
|
|
445
|
-
const result = renderSafeHtml(html);
|
|
446
|
-
|
|
447
|
-
expect(result.html).toBe(html);
|
|
448
|
-
expect(result.isValid).toBe(true);
|
|
449
|
-
expect(result.warnings).toEqual([]);
|
|
450
|
-
});
|
|
451
|
-
|
|
452
|
-
it('should handle dangerous content', () => {
|
|
453
|
-
const html = '<p>Safe content</p><script>alert("xss")</script><p>More content</p>';
|
|
454
|
-
const result = renderSafeHtml(html);
|
|
455
|
-
|
|
456
|
-
expect(result.html).toBe('<p>Safe content</p><p>More content</p>');
|
|
457
|
-
expect(result.isValid).toBe(false);
|
|
458
|
-
expect(result.warnings).toContain('Script tags are not allowed');
|
|
459
|
-
});
|
|
460
|
-
});
|
|
461
|
-
|
|
462
|
-
describe('Options handling', () => {
|
|
463
|
-
it('should use default options when none provided', () => {
|
|
464
|
-
const html = '<p>Safe content</p><script>alert("xss")</script>';
|
|
465
|
-
const result = renderSafeHtml(html);
|
|
466
|
-
|
|
467
|
-
expect(result.html).toBe('<p>Safe content</p>');
|
|
468
|
-
expect(result.isValid).toBe(false);
|
|
469
|
-
expect(result.warnings).toContain('Script tags are not allowed');
|
|
470
|
-
});
|
|
471
|
-
|
|
472
|
-
it('should respect strict option (default true)', () => {
|
|
473
|
-
const html = '<p>Safe content</p><script>alert("xss")</script>';
|
|
474
|
-
const result = renderSafeHtml(html, { strict: true });
|
|
475
|
-
|
|
476
|
-
expect(result.isValid).toBe(false);
|
|
477
|
-
expect(result.warnings).toContain('Script tags are not allowed');
|
|
478
|
-
});
|
|
479
|
-
|
|
480
|
-
it('should respect logWarnings option (default false)', () => {
|
|
481
|
-
const html = '<p>Safe content</p><script>alert("xss")</script>';
|
|
482
|
-
renderSafeHtml(html, { logWarnings: false });
|
|
483
|
-
|
|
484
|
-
expect(console.warn).not.toHaveBeenCalled();
|
|
485
|
-
});
|
|
486
|
-
|
|
487
|
-
it('should log warnings when logWarnings is true', () => {
|
|
488
|
-
const html = '<p>Safe content</p><script>alert("xss")</script>';
|
|
489
|
-
renderSafeHtml(html, { logWarnings: true });
|
|
490
|
-
|
|
491
|
-
expect(console.warn).toHaveBeenCalledWith('Dialog HTML content warnings:', ['Script tags are not allowed']);
|
|
492
|
-
});
|
|
493
|
-
|
|
494
|
-
it('should handle both options together', () => {
|
|
495
|
-
const html = '<p>Safe content</p><script>alert("xss")</script><iframe src="evil.com"></iframe>';
|
|
496
|
-
const result = renderSafeHtml(html, { strict: true, logWarnings: true });
|
|
497
|
-
|
|
498
|
-
expect(result.isValid).toBe(false);
|
|
499
|
-
expect(result.warnings).toHaveLength(2);
|
|
500
|
-
expect(console.warn).toHaveBeenCalledWith('Dialog HTML content warnings:', expect.arrayContaining(['Script tags are not allowed', 'Iframe tags are not allowed']));
|
|
501
|
-
});
|
|
502
|
-
});
|
|
503
|
-
|
|
504
|
-
describe('Edge cases', () => {
|
|
505
|
-
it('should handle null input', () => {
|
|
506
|
-
const result = renderSafeHtml(null as any);
|
|
507
|
-
|
|
508
|
-
expect(result.html).toBe('');
|
|
509
|
-
expect(result.isValid).toBe(false);
|
|
510
|
-
expect(result.warnings).toContain('HTML content must be a non-empty string');
|
|
511
|
-
});
|
|
512
|
-
|
|
513
|
-
it('should handle undefined input', () => {
|
|
514
|
-
const result = renderSafeHtml(undefined as any);
|
|
515
|
-
|
|
516
|
-
expect(result.html).toBe('');
|
|
517
|
-
expect(result.isValid).toBe(false);
|
|
518
|
-
expect(result.warnings).toContain('HTML content must be a non-empty string');
|
|
519
|
-
});
|
|
520
|
-
|
|
521
|
-
it('should handle empty string', () => {
|
|
522
|
-
const result = renderSafeHtml('');
|
|
523
|
-
|
|
524
|
-
expect(result.html).toBe('');
|
|
525
|
-
expect(result.isValid).toBe(false);
|
|
526
|
-
expect(result.warnings).toContain('HTML content must be a non-empty string');
|
|
527
|
-
});
|
|
528
|
-
|
|
529
|
-
it('should handle non-string input', () => {
|
|
530
|
-
const result = renderSafeHtml(123 as any);
|
|
531
|
-
|
|
532
|
-
expect(result.html).toBe('');
|
|
533
|
-
expect(result.isValid).toBe(false);
|
|
534
|
-
expect(result.warnings).toContain('HTML content must be a non-empty string');
|
|
535
|
-
});
|
|
536
|
-
|
|
537
|
-
it('should handle whitespace-only input', () => {
|
|
538
|
-
const result = renderSafeHtml(' \n\t ');
|
|
539
|
-
|
|
540
|
-
expect(result.html).toBe(' \n\t ');
|
|
541
|
-
expect(result.isValid).toBe(true);
|
|
542
|
-
expect(result.warnings).toEqual([]);
|
|
543
|
-
});
|
|
544
|
-
});
|
|
545
|
-
|
|
546
|
-
describe('Integration scenarios', () => {
|
|
547
|
-
it('should handle complex mixed content (basic implementation)', () => {
|
|
548
|
-
const html = `
|
|
549
|
-
<div>
|
|
550
|
-
<h1>Title</h1>
|
|
551
|
-
<script>alert("xss")</script>
|
|
552
|
-
<p>This is <strong>safe</strong> content</p>
|
|
553
|
-
<iframe src="evil.com"></iframe>
|
|
554
|
-
<ul>
|
|
555
|
-
<li>Safe item</li>
|
|
556
|
-
<li onclick="alert('xss')">Dangerous item</li>
|
|
557
|
-
</ul>
|
|
558
|
-
<a href="javascript:alert('xss')">Dangerous link</a>
|
|
559
|
-
</div>
|
|
560
|
-
`;
|
|
561
|
-
const result = renderSafeHtml(html, { logWarnings: true });
|
|
562
|
-
|
|
563
|
-
expect(result.html).toContain('<h1>Title</h1>');
|
|
564
|
-
expect(result.html).toContain('<p>This is <strong>safe</strong> content</p>');
|
|
565
|
-
expect(result.html).toContain('<li>Safe item</li>');
|
|
566
|
-
expect(result.html).toContain('<li'); // May have partial event handler removal
|
|
567
|
-
expect(result.html).not.toContain('<script>');
|
|
568
|
-
expect(result.html).not.toContain('<iframe>');
|
|
569
|
-
expect(result.html).toContain('<a href='); // May have partial protocol removal
|
|
570
|
-
|
|
571
|
-
expect(result.isValid).toBe(false);
|
|
572
|
-
expect(result.warnings.length).toBeGreaterThan(0);
|
|
573
|
-
expect(console.warn).toHaveBeenCalled();
|
|
574
|
-
});
|
|
575
|
-
|
|
576
|
-
it('should preserve safe content while removing all dangerous elements', () => {
|
|
577
|
-
const html = `
|
|
578
|
-
<article>
|
|
579
|
-
<header>
|
|
580
|
-
<h1>Article Title</h1>
|
|
581
|
-
<p class="meta">Published on <time datetime="2023-01-01">January 1, 2023</time></p>
|
|
582
|
-
</header>
|
|
583
|
-
<main>
|
|
584
|
-
<p>This is a <em>safe</em> article with <a href="/safe-link">safe links</a>.</p>
|
|
585
|
-
<blockquote>
|
|
586
|
-
<p>This is a <strong>safe</strong> quote.</p>
|
|
587
|
-
</blockquote>
|
|
588
|
-
<script>alert("xss")</script>
|
|
589
|
-
<pre><code>console.log("safe code");</code></pre>
|
|
590
|
-
</main>
|
|
591
|
-
<footer>
|
|
592
|
-
<p>Safe footer content</p>
|
|
593
|
-
</footer>
|
|
594
|
-
</article>
|
|
595
|
-
`;
|
|
596
|
-
const result = renderSafeHtml(html);
|
|
597
|
-
|
|
598
|
-
expect(result.html).toContain('<h1>Article Title</h1>');
|
|
599
|
-
expect(result.html).toContain('<p class="meta">Published on <time datetime="2023-01-01">January 1, 2023</time></p>');
|
|
600
|
-
expect(result.html).toContain('<p>This is a <em>safe</em> article with <a href="/safe-link">safe links</a>.</p>');
|
|
601
|
-
expect(result.html).toContain('<blockquote>');
|
|
602
|
-
expect(result.html).toContain('<pre><code>console.log("safe code");</code></pre>');
|
|
603
|
-
expect(result.html).toContain('<p>Safe footer content</p>');
|
|
604
|
-
expect(result.html).not.toContain('<script>');
|
|
605
|
-
|
|
606
|
-
expect(result.isValid).toBe(false);
|
|
607
|
-
expect(result.warnings).toContain('Script tags are not allowed');
|
|
608
|
-
});
|
|
609
|
-
});
|
|
610
|
-
});
|
|
611
|
-
});
|