@jmruthers/pace-core 0.5.181 → 0.5.182
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/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.ts +1 -5
- package/src/types/__tests__/guards.test.ts +1 -1
- 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/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/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
|
@@ -69,28 +69,7 @@ export function useRBAC(pageId?: string): UserRBACContext {
|
|
|
69
69
|
// This prevents premature loading when appConfig hasn't loaded yet
|
|
70
70
|
const requiresEvent = appConfig?.requires_event ?? (appConfig === null ? true : false);
|
|
71
71
|
|
|
72
|
-
//
|
|
73
|
-
// Log hook initialization for debugging (use warn level so it's always visible)
|
|
74
|
-
// Also use direct console.log as fallback to ensure visibility
|
|
75
|
-
if (user && session) {
|
|
76
|
-
const hookInitLog = {
|
|
77
|
-
appName,
|
|
78
|
-
requiresEvent,
|
|
79
|
-
appConfig: appConfig ? JSON.stringify(appConfig) : 'null',
|
|
80
|
-
hasUser: !!user,
|
|
81
|
-
hasSession: !!session,
|
|
82
|
-
hasSelectedEvent: !!selectedEvent,
|
|
83
|
-
eventLoading,
|
|
84
|
-
selectedEventId: selectedEvent?.event_id,
|
|
85
|
-
hasSelectedOrganisation: !!selectedOrganisation,
|
|
86
|
-
organisationId: selectedOrganisation?.id,
|
|
87
|
-
orgContextReady,
|
|
88
|
-
orgLoading
|
|
89
|
-
};
|
|
90
|
-
logger.warn('[useRBAC] Hook initialized', hookInitLog);
|
|
91
|
-
// Direct console.log as fallback to ensure we can see if hook is called
|
|
92
|
-
console.warn('[useRBAC] Hook initialized (direct log)', hookInitLog);
|
|
93
|
-
}
|
|
72
|
+
// Removed excessive logging - hook initialization logged only on first mount or significant changes
|
|
94
73
|
|
|
95
74
|
const [globalRole, setGlobalRole] = useState<GlobalRole | null>(null);
|
|
96
75
|
const [organisationRole, setOrganisationRole] = useState<OrganisationRole | null>(null);
|
|
@@ -120,13 +99,6 @@ export function useRBAC(pageId?: string): UserRBACContext {
|
|
|
120
99
|
// This is critical - without organisation ID, RPC calls can't resolve permissions
|
|
121
100
|
if (orgLoading || !orgContextReady || !selectedOrganisation?.id) {
|
|
122
101
|
setIsLoading(true);
|
|
123
|
-
logger.warn('[useRBAC] Waiting for organisation context before loading RBAC context', {
|
|
124
|
-
orgLoading,
|
|
125
|
-
orgContextReady,
|
|
126
|
-
hasSelectedOrganisation: !!selectedOrganisation,
|
|
127
|
-
organisationId: selectedOrganisation?.id,
|
|
128
|
-
appName
|
|
129
|
-
});
|
|
130
102
|
return;
|
|
131
103
|
}
|
|
132
104
|
|
|
@@ -138,13 +110,6 @@ export function useRBAC(pageId?: string): UserRBACContext {
|
|
|
138
110
|
// This prevents premature RPC calls that can cause NetworkError
|
|
139
111
|
// Set loading state so React knows we're waiting
|
|
140
112
|
setIsLoading(true);
|
|
141
|
-
logger.warn('[useRBAC] Waiting for event context before loading RBAC context', {
|
|
142
|
-
eventLoading,
|
|
143
|
-
hasSelectedEvent: !!selectedEvent,
|
|
144
|
-
appName,
|
|
145
|
-
selectedEventId: selectedEvent?.event_id,
|
|
146
|
-
organisationId: selectedOrganisation?.id
|
|
147
|
-
});
|
|
148
113
|
return;
|
|
149
114
|
}
|
|
150
115
|
}
|
|
@@ -152,7 +117,9 @@ export function useRBAC(pageId?: string): UserRBACContext {
|
|
|
152
117
|
setIsLoading(true);
|
|
153
118
|
setError(null);
|
|
154
119
|
|
|
155
|
-
|
|
120
|
+
// Only log at debug level - loading RBAC context is normal operation
|
|
121
|
+
// Changed from warn to debug to reduce console noise
|
|
122
|
+
logger.debug('[useRBAC] Loading RBAC context', {
|
|
156
123
|
appName,
|
|
157
124
|
requiresEvent,
|
|
158
125
|
hasSelectedEvent: !!selectedEvent,
|
|
@@ -195,15 +162,6 @@ export function useRBAC(pageId?: string): UserRBACContext {
|
|
|
195
162
|
appId,
|
|
196
163
|
};
|
|
197
164
|
|
|
198
|
-
// Log scope to verify it's built correctly
|
|
199
|
-
logger.warn('[useRBAC] Building scope for RBAC context', {
|
|
200
|
-
organisationId: scope.organisationId,
|
|
201
|
-
eventId: scope.eventId,
|
|
202
|
-
appId: scope.appId,
|
|
203
|
-
hasOrganisationId: !!scope.organisationId,
|
|
204
|
-
hasEventId: !!scope.eventId
|
|
205
|
-
});
|
|
206
|
-
|
|
207
165
|
setCurrentScope(scope);
|
|
208
166
|
|
|
209
167
|
const [map, roleContext, accessLevel] = await Promise.all([
|
|
@@ -217,13 +175,15 @@ export function useRBAC(pageId?: string): UserRBACContext {
|
|
|
217
175
|
setOrganisationRole(roleContext.organisationRole);
|
|
218
176
|
setEventAppRole(roleContext.eventAppRole || mapAccessLevelToEventRole(accessLevel));
|
|
219
177
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
178
|
+
// Only log on first successful load or if there's an issue
|
|
179
|
+
const permissionCount = Object.keys(map).length;
|
|
180
|
+
if (permissionCount === 0) {
|
|
181
|
+
logger.warn('[useRBAC] RBAC context loaded but returned 0 permissions', {
|
|
182
|
+
appName,
|
|
183
|
+
organisationId: selectedOrganisation.id,
|
|
184
|
+
eventId: selectedEvent?.event_id
|
|
185
|
+
});
|
|
186
|
+
}
|
|
227
187
|
} catch (err) {
|
|
228
188
|
const handledError = err instanceof Error ? err : new Error('Failed to load RBAC context');
|
|
229
189
|
logger.error('[useRBAC] Error loading RBAC context:', handledError);
|
|
@@ -260,20 +220,6 @@ export function useRBAC(pageId?: string): UserRBACContext {
|
|
|
260
220
|
const canManageEvent = useMemo(() => isSuperAdmin || eventAppRole === 'event_admin', [isSuperAdmin, eventAppRole]);
|
|
261
221
|
|
|
262
222
|
useEffect(() => {
|
|
263
|
-
// Log when effect runs to help debug
|
|
264
|
-
logger.warn('[useRBAC] useEffect triggered - calling loadRBACContext', {
|
|
265
|
-
appName,
|
|
266
|
-
requiresEvent,
|
|
267
|
-
eventLoading,
|
|
268
|
-
hasSelectedEvent: !!selectedEvent,
|
|
269
|
-
selectedEventId: selectedEvent?.event_id,
|
|
270
|
-
hasUser: !!user,
|
|
271
|
-
hasSession: !!session,
|
|
272
|
-
hasSelectedOrganisation: !!selectedOrganisation,
|
|
273
|
-
organisationId: selectedOrganisation?.id,
|
|
274
|
-
orgContextReady,
|
|
275
|
-
orgLoading
|
|
276
|
-
});
|
|
277
223
|
loadRBACContext();
|
|
278
224
|
}, [loadRBACContext, appName, requiresEvent, eventLoading, selectedEvent?.event_id, user, session, selectedOrganisation?.id, orgContextReady, orgLoading]);
|
|
279
225
|
|
|
@@ -108,6 +108,17 @@ export function useResolvedScope({
|
|
|
108
108
|
let cancelled = false;
|
|
109
109
|
|
|
110
110
|
const resolveScope = async () => {
|
|
111
|
+
// OPTIMIZATION: If all inputs are null/undefined, immediately return empty scope
|
|
112
|
+
// This indicates pre-filtered mode where we don't need to resolve scope
|
|
113
|
+
if (!supabase && !selectedOrganisationId && !selectedEventId) {
|
|
114
|
+
if (!cancelled) {
|
|
115
|
+
setResolvedScope(null);
|
|
116
|
+
setIsLoading(false);
|
|
117
|
+
setError(null);
|
|
118
|
+
}
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
111
122
|
setIsLoading(true);
|
|
112
123
|
setError(null);
|
|
113
124
|
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Secure Supabase Client Hook
|
|
3
|
+
* @package @jmruthers/pace-core
|
|
4
|
+
* @module RBAC/Hooks
|
|
5
|
+
* @since 1.0.0
|
|
6
|
+
*
|
|
7
|
+
* React hook for getting a secure Supabase client with automatic context injection
|
|
8
|
+
* and caching to prevent multiple client instances.
|
|
9
|
+
*
|
|
10
|
+
* ## Overview
|
|
11
|
+
*
|
|
12
|
+
* This hook provides a secure Supabase client that automatically injects
|
|
13
|
+
* organisation and event context for all database operations, while preventing
|
|
14
|
+
* the creation of multiple Supabase client instances (which causes the
|
|
15
|
+
* "Multiple GoTrueClient instances" warning).
|
|
16
|
+
*
|
|
17
|
+
* ## Features
|
|
18
|
+
*
|
|
19
|
+
* - **Automatic Context Injection**: Organisation, event, and app context are
|
|
20
|
+
* automatically injected into all database queries
|
|
21
|
+
* - **Client Instance Caching**: Prevents creating duplicate Supabase clients
|
|
22
|
+
* for the same context, eliminating the "Multiple GoTrueClient instances" warning
|
|
23
|
+
* - **Automatic Fallback**: Falls back to base client when context is unavailable
|
|
24
|
+
* - **Type-Safe**: Full TypeScript support with proper type inference
|
|
25
|
+
*
|
|
26
|
+
* ## Usage
|
|
27
|
+
*
|
|
28
|
+
* ### Basic Usage
|
|
29
|
+
*
|
|
30
|
+
* ```tsx
|
|
31
|
+
* import { useSecureSupabase } from '@jmruthers/pace-core/rbac';
|
|
32
|
+
*
|
|
33
|
+
* function MyComponent() {
|
|
34
|
+
* const supabase = useSecureSupabase();
|
|
35
|
+
*
|
|
36
|
+
* if (!supabase) {
|
|
37
|
+
* return <div>Loading context...</div>;
|
|
38
|
+
* }
|
|
39
|
+
*
|
|
40
|
+
* const fetchData = async () => {
|
|
41
|
+
* const { data, error } = await supabase
|
|
42
|
+
* .from('users')
|
|
43
|
+
* .select('*');
|
|
44
|
+
* // Organisation context is automatically injected
|
|
45
|
+
* };
|
|
46
|
+
*
|
|
47
|
+
* return <div>...</div>;
|
|
48
|
+
* }
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* ### With Base Client Fallback
|
|
52
|
+
*
|
|
53
|
+
* ```tsx
|
|
54
|
+
* import { useSecureSupabase } from '@jmruthers/pace-core/rbac';
|
|
55
|
+
* import { supabase } from './lib/supabase';
|
|
56
|
+
*
|
|
57
|
+
* function MyComponent() {
|
|
58
|
+
* // Provide base client as fallback
|
|
59
|
+
* const secureSupabase = useSecureSupabase(supabase);
|
|
60
|
+
*
|
|
61
|
+
* // secureSupabase will be the secure client when context is available,
|
|
62
|
+
* // or the base client when context is unavailable
|
|
63
|
+
* }
|
|
64
|
+
* ```
|
|
65
|
+
*
|
|
66
|
+
* ## How It Works
|
|
67
|
+
*
|
|
68
|
+
* 1. **Context Resolution**: The hook uses `useResolvedScope` to get the current
|
|
69
|
+
* organisation, event, and app context
|
|
70
|
+
* 2. **Client Caching**: Clients are cached by context key (organisationId-eventId-appId)
|
|
71
|
+
* to prevent duplicate instances
|
|
72
|
+
* 3. **Automatic Injection**: The secure client automatically injects context headers
|
|
73
|
+
* into all database operations
|
|
74
|
+
* 4. **Fallback Behavior**: When context is unavailable or event is loading, the hook
|
|
75
|
+
* returns the base client (or null if no base client provided)
|
|
76
|
+
*
|
|
77
|
+
* ## Security
|
|
78
|
+
*
|
|
79
|
+
* - **Organisation Context Enforcement**: All queries automatically include organisation
|
|
80
|
+
* context, preventing cross-organisation data access
|
|
81
|
+
* - **Event Context Injection**: Event context is automatically included when available
|
|
82
|
+
* - **App Context Support**: App context is included when resolved from scope
|
|
83
|
+
*
|
|
84
|
+
* ## Performance
|
|
85
|
+
*
|
|
86
|
+
* - **Client Instance Caching**: Prevents creating multiple Supabase clients for the
|
|
87
|
+
* same context, reducing memory usage and eliminating the "Multiple GoTrueClient
|
|
88
|
+
* instances" warning
|
|
89
|
+
* - **Cache Management**: Automatically cleans up old cache entries (keeps last 5)
|
|
90
|
+
* to prevent memory leaks
|
|
91
|
+
* - **Stable References**: Returns stable client references to prevent unnecessary
|
|
92
|
+
* re-renders in consuming components
|
|
93
|
+
*
|
|
94
|
+
* ## Requirements
|
|
95
|
+
*
|
|
96
|
+
* - Must be used within `UnifiedAuthProvider` context
|
|
97
|
+
* - Requires `useOrganisations` and `useEvents` hooks to be available
|
|
98
|
+
* - Environment variables `VITE_SUPABASE_URL` and `VITE_SUPABASE_ANON_KEY` must be set
|
|
99
|
+
* (or `NEXT_PUBLIC_SUPABASE_URL` and `NEXT_PUBLIC_SUPABASE_ANON_KEY` for Next.js)
|
|
100
|
+
*
|
|
101
|
+
* ## See Also
|
|
102
|
+
*
|
|
103
|
+
* - {@link SecureSupabaseClient} - The underlying secure client class
|
|
104
|
+
* - {@link createSecureClient} - Function to create secure clients manually
|
|
105
|
+
* - {@link useResolvedScope} - Hook for resolving RBAC scope
|
|
106
|
+
*
|
|
107
|
+
* @security
|
|
108
|
+
* - Enforces organisation context on all queries
|
|
109
|
+
* - Prevents cross-organisation data access
|
|
110
|
+
* - Automatic context injection
|
|
111
|
+
*
|
|
112
|
+
* @performance
|
|
113
|
+
* - Client instance caching prevents duplicate creation
|
|
114
|
+
* - Reuses cached clients for same context
|
|
115
|
+
* - Automatic cache cleanup
|
|
116
|
+
*/
|
|
117
|
+
|
|
118
|
+
import { useMemo, useRef } from 'react';
|
|
119
|
+
import { useUnifiedAuth } from '../../providers/services/UnifiedAuthProvider';
|
|
120
|
+
import { useOrganisations } from '../../hooks/useOrganisations';
|
|
121
|
+
import { useEvents } from '../../hooks/useEvents';
|
|
122
|
+
import { useResolvedScope } from './useResolvedScope';
|
|
123
|
+
import { createSecureClient, SecureSupabaseClient } from '../secureClient';
|
|
124
|
+
import type { Database } from '../../types/database';
|
|
125
|
+
import type { SupabaseClient } from '@supabase/supabase-js';
|
|
126
|
+
import { logger } from '../../utils/core/logger';
|
|
127
|
+
|
|
128
|
+
// Cache secure clients by context to prevent creating multiple instances
|
|
129
|
+
// This prevents the "Multiple GoTrueClient instances" warning
|
|
130
|
+
const secureClientCache = new Map<string, SecureSupabaseClient>();
|
|
131
|
+
|
|
132
|
+
// Maximum cache size to prevent memory leaks
|
|
133
|
+
const MAX_CACHE_SIZE = 5;
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Get cache key for secure client based on context
|
|
137
|
+
*/
|
|
138
|
+
function getCacheKey(
|
|
139
|
+
organisationId: string,
|
|
140
|
+
eventId: string | undefined,
|
|
141
|
+
appId: string | undefined
|
|
142
|
+
): string {
|
|
143
|
+
return `${organisationId}-${eventId || 'no-event'}-${appId || 'no-app'}`;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Get Supabase URL and key from environment
|
|
148
|
+
*/
|
|
149
|
+
function getSupabaseConfig(): { url: string; key: string } | null {
|
|
150
|
+
// Try to get from environment variables
|
|
151
|
+
const getEnvVar = (key: string): string | undefined => {
|
|
152
|
+
if (typeof import.meta !== 'undefined' && (import.meta as any).env) {
|
|
153
|
+
return (import.meta as any).env[key];
|
|
154
|
+
}
|
|
155
|
+
if (typeof process !== 'undefined' && process.env) {
|
|
156
|
+
return process.env[key];
|
|
157
|
+
}
|
|
158
|
+
return undefined;
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
const supabaseUrl = getEnvVar('VITE_SUPABASE_URL') ||
|
|
162
|
+
getEnvVar('NEXT_PUBLIC_SUPABASE_URL') ||
|
|
163
|
+
null;
|
|
164
|
+
|
|
165
|
+
const supabaseKey = getEnvVar('VITE_SUPABASE_ANON_KEY') ||
|
|
166
|
+
getEnvVar('NEXT_PUBLIC_SUPABASE_ANON_KEY') ||
|
|
167
|
+
null;
|
|
168
|
+
|
|
169
|
+
if (!supabaseUrl || !supabaseKey) {
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return { url: supabaseUrl, key: supabaseKey };
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Hook to get a secure Supabase client with automatic context injection
|
|
178
|
+
*
|
|
179
|
+
* Returns a secure client when organisation context is available,
|
|
180
|
+
* otherwise returns null. The client automatically injects organisation
|
|
181
|
+
* and event context into all database operations.
|
|
182
|
+
*
|
|
183
|
+
* Uses caching to prevent creating multiple Supabase client instances,
|
|
184
|
+
* which causes the "Multiple GoTrueClient instances" warning.
|
|
185
|
+
*
|
|
186
|
+
* @param baseClient - Optional base Supabase client to use as fallback
|
|
187
|
+
* @returns Secure Supabase client or null if context is not available
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* ```tsx
|
|
191
|
+
* import { useSecureSupabase } from '@jmruthers/pace-core/rbac';
|
|
192
|
+
*
|
|
193
|
+
* function MyComponent() {
|
|
194
|
+
* const supabase = useSecureSupabase();
|
|
195
|
+
*
|
|
196
|
+
* if (!supabase) {
|
|
197
|
+
* return <div>Loading context...</div>;
|
|
198
|
+
* }
|
|
199
|
+
*
|
|
200
|
+
* // Use supabase client - organisation context is automatically injected
|
|
201
|
+
* const { data } = await supabase.from('users').select('*');
|
|
202
|
+
* }
|
|
203
|
+
* ```
|
|
204
|
+
*/
|
|
205
|
+
export function useSecureSupabase(
|
|
206
|
+
baseClient?: SupabaseClient<Database> | null
|
|
207
|
+
): SupabaseClient<Database> | null {
|
|
208
|
+
const { user, supabase: authSupabase } = useUnifiedAuth();
|
|
209
|
+
const { selectedOrganisation } = useOrganisations();
|
|
210
|
+
const eventsContext = useEvents();
|
|
211
|
+
const { selectedEvent } = eventsContext;
|
|
212
|
+
const eventLoading = 'eventLoading' in eventsContext ? eventsContext.eventLoading : false;
|
|
213
|
+
|
|
214
|
+
// Resolve scope to get appId
|
|
215
|
+
const { resolvedScope } = useResolvedScope({
|
|
216
|
+
supabase: authSupabase || null,
|
|
217
|
+
selectedOrganisationId: selectedOrganisation?.id || null,
|
|
218
|
+
selectedEventId: selectedEvent?.event_id || null
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
// Track previous context to detect changes
|
|
222
|
+
const prevContextRef = useRef<{
|
|
223
|
+
organisationId: string | undefined;
|
|
224
|
+
eventId: string | undefined;
|
|
225
|
+
appId: string | undefined;
|
|
226
|
+
}>({
|
|
227
|
+
organisationId: undefined,
|
|
228
|
+
eventId: undefined,
|
|
229
|
+
appId: undefined
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
return useMemo(() => {
|
|
233
|
+
// If event is loading, return base client or null to avoid recreating client unnecessarily
|
|
234
|
+
if (eventLoading) {
|
|
235
|
+
return baseClient || authSupabase || null;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// If we have organisation context, create or reuse a secure client
|
|
239
|
+
if (selectedOrganisation?.id && user?.id) {
|
|
240
|
+
const organisationId = selectedOrganisation.id;
|
|
241
|
+
const eventId = selectedEvent?.event_id;
|
|
242
|
+
|
|
243
|
+
// Get appId from resolved scope if available
|
|
244
|
+
const appId = resolvedScope?.appId;
|
|
245
|
+
|
|
246
|
+
// Update previous context
|
|
247
|
+
prevContextRef.current = { organisationId, eventId, appId };
|
|
248
|
+
|
|
249
|
+
// Check cache first
|
|
250
|
+
const cacheKey = getCacheKey(organisationId, eventId, appId);
|
|
251
|
+
const cachedClient = secureClientCache.get(cacheKey);
|
|
252
|
+
|
|
253
|
+
if (cachedClient) {
|
|
254
|
+
// Reuse cached client - prevents creating multiple instances
|
|
255
|
+
return cachedClient.getClient();
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Get Supabase configuration
|
|
259
|
+
const config = getSupabaseConfig();
|
|
260
|
+
if (!config || !config.url || !config.key) {
|
|
261
|
+
logger.warn('useSecureSupabase', 'Missing Supabase environment variables. Falling back to base client.', {
|
|
262
|
+
note: 'Ensure VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY are set in your environment.'
|
|
263
|
+
});
|
|
264
|
+
return baseClient || authSupabase || null;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
try {
|
|
268
|
+
const secureClient = createSecureClient(
|
|
269
|
+
config.url,
|
|
270
|
+
config.key,
|
|
271
|
+
organisationId as any, // organisationId is string, UUID is string alias
|
|
272
|
+
eventId,
|
|
273
|
+
appId as any // appId is string | undefined, UUID is string alias
|
|
274
|
+
);
|
|
275
|
+
|
|
276
|
+
// Cache the client for reuse
|
|
277
|
+
secureClientCache.set(cacheKey, secureClient);
|
|
278
|
+
|
|
279
|
+
// Clean up old cache entries to prevent memory leaks
|
|
280
|
+
if (secureClientCache.size > MAX_CACHE_SIZE) {
|
|
281
|
+
const firstKey = secureClientCache.keys().next().value;
|
|
282
|
+
if (firstKey) {
|
|
283
|
+
secureClientCache.delete(firstKey);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Return the underlying client for compatibility
|
|
288
|
+
return secureClient.getClient();
|
|
289
|
+
} catch (error) {
|
|
290
|
+
logger.error('useSecureSupabase', 'Failed to create secure client', error);
|
|
291
|
+
// Fallback to base client
|
|
292
|
+
return baseClient || authSupabase || null;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// Fallback to base client when context is not available
|
|
297
|
+
return baseClient || authSupabase || null;
|
|
298
|
+
}, [
|
|
299
|
+
selectedOrganisation?.id,
|
|
300
|
+
selectedEvent?.event_id,
|
|
301
|
+
user?.id,
|
|
302
|
+
eventLoading,
|
|
303
|
+
resolvedScope?.appId,
|
|
304
|
+
baseClient,
|
|
305
|
+
authSupabase
|
|
306
|
+
]);
|
|
307
|
+
}
|
|
308
|
+
|
package/src/rbac/index.ts
CHANGED
package/src/rbac/secureClient.ts
CHANGED
|
@@ -21,6 +21,7 @@ import { OrganisationContextRequiredError } from './types';
|
|
|
21
21
|
*/
|
|
22
22
|
export class SecureSupabaseClient {
|
|
23
23
|
private supabase: SupabaseClient<Database>;
|
|
24
|
+
private edgeFunctionClient: SupabaseClient<Database> | null = null;
|
|
24
25
|
private supabaseUrl: string;
|
|
25
26
|
private supabaseKey: string;
|
|
26
27
|
private organisationId: UUID;
|
|
@@ -40,7 +41,9 @@ export class SecureSupabaseClient {
|
|
|
40
41
|
this.eventId = eventId;
|
|
41
42
|
this.appId = appId;
|
|
42
43
|
|
|
43
|
-
// Create the base Supabase client
|
|
44
|
+
// Create the base Supabase client with context headers
|
|
45
|
+
// Note: We'll override functions.invoke to exclude headers for Edge Functions
|
|
46
|
+
// as they may not have CORS configured to accept custom headers
|
|
44
47
|
this.supabase = createClient<Database>(supabaseUrl, supabaseKey, {
|
|
45
48
|
global: {
|
|
46
49
|
headers: {
|
|
@@ -53,6 +56,10 @@ export class SecureSupabaseClient {
|
|
|
53
56
|
|
|
54
57
|
// Override the auth methods to inject context
|
|
55
58
|
this.setupContextInjection();
|
|
59
|
+
|
|
60
|
+
// Override functions.invoke to exclude custom headers for Edge Functions
|
|
61
|
+
// Edge Functions may not have CORS configured to accept custom headers
|
|
62
|
+
this.setupEdgeFunctionHandling();
|
|
56
63
|
}
|
|
57
64
|
|
|
58
65
|
/**
|
|
@@ -61,11 +68,12 @@ export class SecureSupabaseClient {
|
|
|
61
68
|
private setupContextInjection() {
|
|
62
69
|
const originalFrom = this.supabase.from.bind(this.supabase);
|
|
63
70
|
|
|
64
|
-
this.supabase.from = (table: string) => {
|
|
71
|
+
(this.supabase as any).from = (table: string): any => {
|
|
65
72
|
// Validate context before allowing any database operations
|
|
66
73
|
this.validateContext();
|
|
67
74
|
|
|
68
|
-
|
|
75
|
+
// Type assertion needed because table is a string but Supabase expects specific table names
|
|
76
|
+
const query = originalFrom(table as any);
|
|
69
77
|
|
|
70
78
|
// Inject organisation context into all queries
|
|
71
79
|
return this.injectContext(query);
|
|
@@ -75,7 +83,8 @@ export class SecureSupabaseClient {
|
|
|
75
83
|
|
|
76
84
|
// Override rpc method to inject context
|
|
77
85
|
// Type assertion needed because we're wrapping the generic rpc method
|
|
78
|
-
|
|
86
|
+
// The fn parameter is typed as string to match Supabase's rpc signature
|
|
87
|
+
(this.supabase as any).rpc = (fn: string, args?: any, options?: any): any => {
|
|
79
88
|
// Validate context before allowing any RPC calls
|
|
80
89
|
this.validateContext();
|
|
81
90
|
|
|
@@ -87,10 +96,36 @@ export class SecureSupabaseClient {
|
|
|
87
96
|
p_app_id: this.appId,
|
|
88
97
|
};
|
|
89
98
|
|
|
90
|
-
return originalRpc(fn, contextArgs, options);
|
|
99
|
+
return originalRpc(fn as any, contextArgs, options);
|
|
91
100
|
};
|
|
92
101
|
}
|
|
93
102
|
|
|
103
|
+
/**
|
|
104
|
+
* Setup Edge Function handling to bypass custom headers
|
|
105
|
+
* Edge Functions may not have CORS configured to accept custom headers,
|
|
106
|
+
* so we create a separate client without custom headers for Edge Function calls
|
|
107
|
+
*
|
|
108
|
+
* NOTE: We store the edge function client but don't override functions here.
|
|
109
|
+
* Instead, we provide a method to get the edge function client for direct use.
|
|
110
|
+
* This avoids interfering with the main client's operations.
|
|
111
|
+
*/
|
|
112
|
+
private setupEdgeFunctionHandling() {
|
|
113
|
+
// Create a separate client without custom headers for Edge Functions
|
|
114
|
+
// This prevents CORS errors when Edge Functions don't accept custom headers
|
|
115
|
+
// Store it as an instance variable to avoid creating multiple clients
|
|
116
|
+
// We'll use this client directly for Edge Function calls instead of overriding
|
|
117
|
+
this.edgeFunctionClient = createClient<Database>(this.supabaseUrl, this.supabaseKey);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Get a client for Edge Function calls without custom headers
|
|
122
|
+
* Edge Functions may not have CORS configured to accept custom headers
|
|
123
|
+
* @returns Supabase client without custom headers for Edge Function calls
|
|
124
|
+
*/
|
|
125
|
+
getEdgeFunctionClient(): SupabaseClient<Database> {
|
|
126
|
+
return this.edgeFunctionClient || this.supabase;
|
|
127
|
+
}
|
|
128
|
+
|
|
94
129
|
/**
|
|
95
130
|
* Inject organisation context into a query
|
|
96
131
|
*/
|
|
@@ -190,7 +225,19 @@ export class SecureSupabaseClient {
|
|
|
190
225
|
* @internal
|
|
191
226
|
*/
|
|
192
227
|
getClient(): SupabaseClient<Database> {
|
|
193
|
-
|
|
228
|
+
// Return a proxy that intercepts functions.invoke calls to use edge function client
|
|
229
|
+
// This avoids CORS issues with Edge Functions while keeping the main client intact
|
|
230
|
+
return new Proxy(this.supabase, {
|
|
231
|
+
get: (target, prop) => {
|
|
232
|
+
if (prop === 'functions' && this.edgeFunctionClient) {
|
|
233
|
+
// Return the edge function client's functions for invoke calls
|
|
234
|
+
// This bypasses custom headers that cause CORS errors
|
|
235
|
+
return this.edgeFunctionClient.functions;
|
|
236
|
+
}
|
|
237
|
+
// For all other properties, return the original
|
|
238
|
+
return (target as any)[prop];
|
|
239
|
+
}
|
|
240
|
+
}) as SupabaseClient<Database>;
|
|
194
241
|
}
|
|
195
242
|
}
|
|
196
243
|
|
package/src/rbac/security.ts
CHANGED
|
@@ -187,6 +187,9 @@ export class RBACSecurityValidator {
|
|
|
187
187
|
* Log security event for monitoring
|
|
188
188
|
* @param event - Security event details
|
|
189
189
|
*/
|
|
190
|
+
private static rateLimitWarningCount = new Map<UUID, { count: number; lastWarning: number }>();
|
|
191
|
+
private static readonly RATE_LIMIT_WARNING_THROTTLE_MS = 5000; // Only warn once per 5 seconds per user
|
|
192
|
+
|
|
190
193
|
static logSecurityEvent(event: {
|
|
191
194
|
type:
|
|
192
195
|
| 'permission_denied'
|
|
@@ -209,7 +212,40 @@ export class RBACSecurityValidator {
|
|
|
209
212
|
severity: this.getEventSeverity(event.type),
|
|
210
213
|
};
|
|
211
214
|
|
|
212
|
-
//
|
|
215
|
+
// Throttle rate limit warnings to prevent console flooding
|
|
216
|
+
if (event.type === 'rate_limit_exceeded') {
|
|
217
|
+
const now = Date.now();
|
|
218
|
+
const userWarning = this.rateLimitWarningCount.get(event.userId);
|
|
219
|
+
|
|
220
|
+
if (userWarning) {
|
|
221
|
+
const timeSinceLastWarning = now - userWarning.lastWarning;
|
|
222
|
+
if (timeSinceLastWarning < this.RATE_LIMIT_WARNING_THROTTLE_MS) {
|
|
223
|
+
// Still within throttle window - increment count but don't log
|
|
224
|
+
userWarning.count++;
|
|
225
|
+
this.rateLimitWarningCount.set(event.userId, userWarning);
|
|
226
|
+
return; // Skip logging to prevent console flooding
|
|
227
|
+
} else {
|
|
228
|
+
// Throttle window expired - log with count and reset
|
|
229
|
+
log.warn('Security event (throttled):', {
|
|
230
|
+
...securityEvent,
|
|
231
|
+
details: {
|
|
232
|
+
...securityEvent.details,
|
|
233
|
+
suppressedWarnings: userWarning.count,
|
|
234
|
+
message: `Rate limit exceeded (${userWarning.count + 1} times in last ${Math.round(timeSinceLastWarning / 1000)}s)`
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
this.rateLimitWarningCount.set(event.userId, { count: 0, lastWarning: now });
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
} else {
|
|
241
|
+
// First warning for this user - log it
|
|
242
|
+
this.rateLimitWarningCount.set(event.userId, { count: 0, lastWarning: now });
|
|
243
|
+
log.warn('Security event:', securityEvent);
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Log other security events normally
|
|
213
249
|
log.warn('Security event:', securityEvent);
|
|
214
250
|
|
|
215
251
|
// TODO: Send to security monitoring service
|