@jmruthers/pace-core 0.5.191 → 0.6.1
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 +29 -0
- package/README.md +7 -1
- package/cursor-rules/00-pace-core-compliance.mdc +372 -0
- package/cursor-rules/01-standards-compliance.mdc +275 -0
- package/cursor-rules/02-project-structure.mdc +200 -0
- package/cursor-rules/03-solid-principles.mdc +341 -0
- package/cursor-rules/04-testing-standards.mdc +315 -0
- package/cursor-rules/05-bug-reports-and-features.mdc +246 -0
- package/cursor-rules/06-code-quality.mdc +392 -0
- package/cursor-rules/07-tech-stack-compliance.mdc +309 -0
- package/cursor-rules/CHANGELOG.md +101 -0
- package/cursor-rules/README.md +191 -0
- package/dist/{AuthService-CbP_utw2.d.ts → AuthService-DjnJHDtC.d.ts} +1 -0
- package/dist/{DataTable-Be6dH_dR.d.ts → DataTable-CH1U5Tpy.d.ts} +1 -1
- package/dist/{DataTable-WKRZD47S.js → DataTable-DQ7RSOHE.js} +8 -7
- package/dist/{PublicPageProvider-ULXC_u6U.d.ts → PublicPageProvider-ce4xlHYA.d.ts} +37 -156
- package/dist/{UnifiedAuthProvider-BYA9qB-o.d.ts → UnifiedAuthProvider-185Ih4dj.d.ts} +2 -0
- package/dist/{UnifiedAuthProvider-FTSG5XH7.js → UnifiedAuthProvider-ATAP5UTR.js} +3 -3
- package/dist/{api-IHKALJZD.js → api-N774RPUA.js} +2 -2
- package/dist/{chunk-6C4YBBJM.js → chunk-3QRJFVBR.js} +1 -1
- package/dist/chunk-3QRJFVBR.js.map +1 -0
- package/dist/{chunk-OETXORNB.js → chunk-3XTALGJF.js} +211 -136
- package/dist/chunk-3XTALGJF.js.map +1 -0
- package/dist/{chunk-6TQDD426.js → chunk-4N5C5XZU.js} +47 -228
- package/dist/chunk-4N5C5XZU.js.map +1 -0
- package/dist/{chunk-LOMZXPSN.js → chunk-4ZC4GX36.js} +47 -74
- package/dist/chunk-4ZC4GX36.js.map +1 -0
- package/dist/{chunk-6LTQQAT6.js → chunk-BYFSK72L.js} +357 -158
- package/dist/chunk-BYFSK72L.js.map +1 -0
- package/dist/{chunk-XYXSXPUK.js → chunk-EXUD6RNJ.js} +50 -10
- package/dist/chunk-EXUD6RNJ.js.map +1 -0
- package/dist/{chunk-VKB2CO4Z.js → chunk-GLK6VM3F.js} +244 -249
- package/dist/chunk-GLK6VM3F.js.map +1 -0
- package/dist/{chunk-HW3OVDUF.js → chunk-J36DSWQK.js} +1 -1
- package/dist/{chunk-HW3OVDUF.js.map → chunk-J36DSWQK.js.map} +1 -1
- package/dist/{chunk-XNYQOL3Z.js → chunk-JBKQ3SAO.js} +9 -18
- package/dist/chunk-JBKQ3SAO.js.map +1 -0
- package/dist/{chunk-ROXMHMY2.js → chunk-KNC55RTG.js} +13 -3
- package/dist/{chunk-ROXMHMY2.js.map → chunk-KNC55RTG.js.map} +1 -1
- package/dist/{chunk-QWWZ5CAQ.js → chunk-LXQLPRQ2.js} +2 -2
- package/dist/{chunk-ULHIJK66.js → chunk-T33XF5ZC.js} +255 -140
- package/dist/chunk-T33XF5ZC.js.map +1 -0
- package/dist/{chunk-VRGWKHDB.js → chunk-XM25TVIE.js} +100 -33
- package/dist/chunk-XM25TVIE.js.map +1 -0
- package/dist/components.d.ts +4 -4
- package/dist/components.js +9 -9
- package/dist/hooks.d.ts +6 -6
- package/dist/hooks.js +20 -25
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +11 -11
- package/dist/index.js +18 -21
- package/dist/index.js.map +1 -1
- package/dist/providers.d.ts +3 -3
- package/dist/providers.js +2 -2
- package/dist/rbac/index.d.ts +2 -20
- package/dist/rbac/index.js +7 -9
- package/dist/{usePublicRouteParams-TZe0gy-4.d.ts → usePublicRouteParams-BJAlWfuJ.d.ts} +3 -3
- package/dist/{useToast-C8gR5ir4.d.ts → useToast-AyaT-x7p.d.ts} +2 -2
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +3 -3
- package/docs/api/classes/ColumnFactory.md +1 -1
- package/docs/api/classes/ErrorBoundary.md +1 -1
- package/docs/api/classes/InvalidScopeError.md +1 -1
- package/docs/api/classes/Logger.md +1 -1
- package/docs/api/classes/MissingUserContextError.md +1 -1
- package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
- package/docs/api/classes/PermissionDeniedError.md +2 -2
- package/docs/api/classes/RBACAuditManager.md +2 -2
- package/docs/api/classes/RBACCache.md +1 -1
- package/docs/api/classes/RBACEngine.md +2 -2
- package/docs/api/classes/RBACError.md +1 -1
- package/docs/api/classes/RBACNotInitializedError.md +1 -1
- package/docs/api/classes/SecureSupabaseClient.md +10 -10
- package/docs/api/classes/StorageUtils.md +1 -1
- package/docs/api/enums/FileCategory.md +1 -1
- package/docs/api/enums/LogLevel.md +1 -1
- package/docs/api/enums/RBACErrorCode.md +1 -1
- package/docs/api/enums/RPCFunction.md +1 -1
- package/docs/api/interfaces/AddressFieldProps.md +1 -1
- package/docs/api/interfaces/AddressFieldRef.md +1 -1
- package/docs/api/interfaces/AggregateConfig.md +1 -1
- package/docs/api/interfaces/AutocompleteOptions.md +1 -1
- package/docs/api/interfaces/AvatarProps.md +1 -1
- package/docs/api/interfaces/BadgeProps.md +1 -1
- package/docs/api/interfaces/ButtonProps.md +1 -1
- package/docs/api/interfaces/CalendarProps.md +1 -1
- package/docs/api/interfaces/CardProps.md +1 -1
- package/docs/api/interfaces/ColorPalette.md +1 -1
- package/docs/api/interfaces/ColorShade.md +1 -1
- package/docs/api/interfaces/ComplianceResult.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 +1 -1
- package/docs/api/interfaces/DataTableColumn.md +1 -1
- package/docs/api/interfaces/DataTableProps.md +1 -1
- package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
- package/docs/api/interfaces/DatabaseComplianceResult.md +1 -1
- package/docs/api/interfaces/DatabaseIssue.md +1 -1
- 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 +1 -1
- package/docs/api/interfaces/ExportOptions.md +1 -1
- package/docs/api/interfaces/FileDisplayProps.md +24 -11
- package/docs/api/interfaces/FileMetadata.md +1 -1
- package/docs/api/interfaces/FileReference.md +1 -1
- package/docs/api/interfaces/FileSizeLimits.md +1 -1
- package/docs/api/interfaces/FileUploadOptions.md +1 -1
- package/docs/api/interfaces/FileUploadProps.md +1 -1
- package/docs/api/interfaces/FooterProps.md +1 -1
- package/docs/api/interfaces/FormFieldProps.md +1 -1
- package/docs/api/interfaces/FormProps.md +1 -1
- package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
- package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
- package/docs/api/interfaces/InputProps.md +1 -1
- package/docs/api/interfaces/LabelProps.md +1 -1
- package/docs/api/interfaces/LoggerConfig.md +1 -1
- package/docs/api/interfaces/LoginFormProps.md +1 -1
- package/docs/api/interfaces/NavigationAccessRecord.md +2 -2
- package/docs/api/interfaces/NavigationContextType.md +1 -1
- package/docs/api/interfaces/NavigationGuardProps.md +1 -1
- package/docs/api/interfaces/NavigationItem.md +1 -1
- package/docs/api/interfaces/NavigationMenuProps.md +1 -1
- package/docs/api/interfaces/NavigationProviderProps.md +1 -1
- package/docs/api/interfaces/Organisation.md +1 -1
- package/docs/api/interfaces/OrganisationContextType.md +1 -1
- package/docs/api/interfaces/OrganisationMembership.md +1 -1
- package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
- package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
- package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
- 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 +2 -2
- package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
- package/docs/api/interfaces/PaletteData.md +1 -1
- package/docs/api/interfaces/ParsedAddress.md +1 -1
- package/docs/api/interfaces/PermissionEnforcerProps.md +4 -4
- package/docs/api/interfaces/ProgressProps.md +1 -1
- package/docs/api/interfaces/ProtectedRouteProps.md +1 -1
- package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
- package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
- package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
- package/docs/api/interfaces/QuickFix.md +1 -1
- package/docs/api/interfaces/RBACAccessValidateParams.md +1 -1
- package/docs/api/interfaces/RBACAccessValidateResult.md +1 -1
- package/docs/api/interfaces/RBACAuditLogParams.md +1 -1
- package/docs/api/interfaces/RBACAuditLogResult.md +1 -1
- package/docs/api/interfaces/RBACConfig.md +2 -2
- package/docs/api/interfaces/RBACContext.md +1 -1
- package/docs/api/interfaces/RBACLogger.md +1 -1
- package/docs/api/interfaces/RBACPageAccessCheckParams.md +1 -1
- package/docs/api/interfaces/RBACPerformanceMetrics.md +1 -1
- package/docs/api/interfaces/RBACPermissionCheckParams.md +1 -1
- package/docs/api/interfaces/RBACPermissionCheckResult.md +2 -2
- package/docs/api/interfaces/RBACPermissionsGetParams.md +1 -1
- package/docs/api/interfaces/RBACPermissionsGetResult.md +1 -1
- package/docs/api/interfaces/RBACResult.md +1 -1
- package/docs/api/interfaces/RBACRoleGrantParams.md +2 -2
- package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
- package/docs/api/interfaces/RBACRoleRevokeParams.md +2 -2
- package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
- package/docs/api/interfaces/RBACRoleValidateParams.md +2 -2
- package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
- package/docs/api/interfaces/RBACRolesListParams.md +1 -1
- package/docs/api/interfaces/RBACRolesListResult.md +2 -2
- package/docs/api/interfaces/RBACSessionTrackParams.md +1 -1
- package/docs/api/interfaces/RBACSessionTrackResult.md +1 -1
- 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 +2 -2
- package/docs/api/interfaces/RouteConfig.md +2 -2
- package/docs/api/interfaces/RuntimeComplianceResult.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 +1 -1
- package/docs/api/interfaces/SetupIssue.md +1 -1
- 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 +1 -1
- package/docs/api/interfaces/TextareaProps.md +1 -1
- package/docs/api/interfaces/ToastActionElement.md +1 -1
- package/docs/api/interfaces/ToastProps.md +1 -1
- package/docs/api/interfaces/UnifiedAuthContextType.md +60 -38
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +13 -13
- package/docs/api/interfaces/UseFormDialogOptions.md +1 -1
- package/docs/api/interfaces/UseFormDialogReturn.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoOptions.md +2 -2
- package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
- 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 +1 -1
- package/docs/api/interfaces/UserProfile.md +1 -1
- package/docs/api/modules.md +194 -209
- package/docs/getting-started/cursor-rules.md +262 -0
- package/docs/getting-started/installation-guide.md +6 -1
- package/docs/getting-started/quick-start.md +6 -1
- package/docs/migration/MIGRATION_GUIDE.md +4 -4
- package/docs/migration/REACT_19_MIGRATION.md +227 -0
- package/docs/migration/database-changes-december-2025.md +2 -1
- package/docs/rbac/event-based-apps.md +124 -6
- package/docs/standards/README.md +39 -0
- package/docs/troubleshooting/migration.md +4 -4
- package/examples/PublicPages/PublicEventPage.tsx +1 -1
- package/package.json +11 -6
- package/scripts/audit-consuming-app.cjs +961 -0
- package/scripts/check-pace-core-compliance.cjs +315 -61
- package/scripts/install-cursor-rules.cjs +236 -0
- package/src/__tests__/helpers/test-providers.tsx +1 -1
- package/src/__tests__/helpers/test-utils.tsx +1 -1
- package/src/__tests__/rls-policies.test.ts +3 -1
- package/src/components/Badge/Badge.tsx +2 -4
- package/src/components/Button/Button.tsx +5 -4
- package/src/components/Calendar/Calendar.tsx +1 -1
- package/src/components/DataTable/DataTable.test.tsx +57 -93
- package/src/components/DataTable/DataTable.tsx +2 -2
- package/src/components/DataTable/__tests__/DataTable.default-state.test.tsx +172 -45
- package/src/components/DataTable/__tests__/DataTable.grouping-aggregation.test.tsx +121 -28
- package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +9 -8
- package/src/components/DataTable/__tests__/DataTableCore.test.tsx +20 -52
- package/src/components/DataTable/__tests__/a11y.basic.test.tsx +170 -34
- package/src/components/DataTable/__tests__/keyboard.test.tsx +75 -12
- package/src/components/DataTable/__tests__/pagination.modes.test.tsx +88 -16
- package/src/components/DataTable/__tests__/ssr.strict-mode.test.tsx +12 -12
- package/src/components/DataTable/components/AccessDeniedPage.tsx +1 -1
- package/src/components/DataTable/components/BulkOperationsDropdown.tsx +1 -1
- package/src/components/DataTable/components/DataTableCore.tsx +4 -7
- package/src/components/DataTable/components/DataTableModals.tsx +1 -1
- package/src/components/DataTable/components/EditableRow.tsx +1 -1
- package/src/components/DataTable/components/UnifiedTableBody.tsx +86 -17
- package/src/components/DataTable/components/__tests__/DataTableModals.test.tsx +23 -23
- package/src/components/DataTable/components/__tests__/EditableRow.test.tsx +11 -11
- package/src/components/DataTable/components/__tests__/ExpandButton.test.tsx +36 -36
- package/src/components/DataTable/components/__tests__/GroupHeader.test.tsx +27 -27
- package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +39 -39
- package/src/components/DataTable/components/__tests__/UnifiedTableBody.test.tsx +33 -33
- package/src/components/DataTable/components/__tests__/ViewRowModal.test.tsx +29 -29
- package/src/components/DataTable/hooks/useColumnReordering.ts +2 -2
- package/src/components/DataTable/hooks/useDataTablePermissions.ts +75 -10
- package/src/components/DataTable/hooks/useKeyboardNavigation.ts +2 -2
- package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +8 -14
- package/src/components/Dialog/Dialog.tsx +6 -5
- package/src/components/ErrorBoundary/ErrorBoundary.tsx +1 -1
- package/src/components/EventSelector/EventSelector.tsx +1 -1
- package/src/components/FileDisplay/FileDisplay.test.tsx +4 -3
- package/src/components/FileDisplay/FileDisplay.tsx +16 -4
- package/src/components/Footer/Footer.tsx +1 -1
- package/src/components/Form/Form.test.tsx +36 -15
- package/src/components/Form/Form.tsx +30 -26
- package/src/components/Header/Header.tsx +1 -1
- package/src/components/InactivityWarningModal/InactivityWarningModal.test.tsx +40 -40
- package/src/components/InactivityWarningModal/InactivityWarningModal.tsx +1 -1
- package/src/components/Input/Input.tsx +28 -30
- package/src/components/Label/Label.tsx +1 -1
- package/src/components/LoadingSpinner/LoadingSpinner.tsx +1 -1
- package/src/components/LoginForm/LoginForm.test.tsx +42 -42
- package/src/components/LoginForm/LoginForm.tsx +8 -8
- package/src/components/NavigationMenu/NavigationMenu.test.tsx +6 -4
- package/src/components/NavigationMenu/NavigationMenu.tsx +2 -11
- package/src/components/OrganisationSelector/OrganisationSelector.tsx +0 -1
- package/src/components/PaceAppLayout/PaceAppLayout.performance.test.tsx +1 -1
- package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +75 -52
- package/src/components/PaceAppLayout/PaceAppLayout.tsx +98 -69
- package/src/components/PaceAppLayout/README.md +1 -1
- package/src/components/PaceLoginPage/PaceLoginPage.tsx +1 -8
- package/src/components/PasswordChange/PasswordChangeForm.test.tsx +33 -33
- package/src/components/PasswordChange/PasswordChangeForm.tsx +1 -1
- package/src/components/Progress/Progress.tsx +1 -1
- package/src/components/ProtectedRoute/ProtectedRoute.test.tsx +5 -9
- package/src/components/ProtectedRoute/ProtectedRoute.tsx +0 -1
- package/src/components/PublicLayout/PublicPageLayout.tsx +1 -1
- package/src/components/PublicLayout/PublicPageProvider.tsx +0 -1
- package/src/components/Select/Select.tsx +33 -22
- package/src/components/SessionRestorationLoader/SessionRestorationLoader.tsx +1 -1
- package/src/components/Table/Table.tsx +1 -1
- package/src/components/Textarea/Textarea.tsx +27 -29
- package/src/components/Toast/Toast.tsx +1 -1
- package/src/components/Tooltip/Tooltip.tsx +1 -1
- package/src/components/UserMenu/UserMenu.tsx +1 -1
- package/src/hooks/__tests__/hooks.integration.test.tsx +80 -55
- package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +14 -7
- package/src/hooks/__tests__/useStorage.unit.test.ts +36 -36
- package/src/hooks/public/usePublicEvent.ts +1 -1
- package/src/hooks/public/usePublicEventLogo.ts +1 -1
- package/src/hooks/public/usePublicRouteParams.ts +1 -1
- package/src/hooks/services/useAuthService.ts +21 -3
- package/src/hooks/services/useEventService.ts +21 -3
- package/src/hooks/services/useInactivityService.ts +21 -3
- package/src/hooks/services/useOrganisationService.ts +21 -3
- package/src/hooks/useDataTableState.ts +8 -18
- package/src/hooks/useFileDisplay.ts +10 -17
- package/src/hooks/useFocusManagement.ts +2 -2
- package/src/hooks/useFocusTrap.ts +4 -4
- package/src/hooks/useFormDialog.ts +8 -7
- package/src/hooks/useInactivityTracker.ts +1 -1
- package/src/hooks/usePermissionCache.ts +1 -1
- package/src/hooks/useSecureDataAccess.test.ts +16 -9
- package/src/hooks/useSecureDataAccess.ts +22 -6
- package/src/hooks/useToast.ts +2 -2
- package/src/providers/__tests__/OrganisationProvider.test.tsx +57 -13
- package/src/providers/__tests__/ProviderLifecycle.test.tsx +21 -6
- package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +10 -10
- package/src/providers/services/EventServiceProvider.tsx +0 -8
- package/src/providers/services/UnifiedAuthProvider.tsx +196 -46
- package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +13 -3
- package/src/rbac/__tests__/adapters.comprehensive.test.tsx +34 -40
- package/src/rbac/__tests__/isSuperAdmin.real.test.ts +82 -0
- package/src/rbac/adapters.tsx +3 -22
- package/src/rbac/api.test.ts +2 -2
- package/src/rbac/api.ts +7 -1
- package/src/rbac/components/EnhancedNavigationMenu.tsx +3 -16
- package/src/rbac/components/NavigationGuard.tsx +2 -11
- package/src/rbac/components/NavigationProvider.tsx +1 -2
- package/src/rbac/components/PagePermissionGuard.tsx +1 -1
- package/src/rbac/components/PagePermissionProvider.tsx +1 -1
- package/src/rbac/components/PermissionEnforcer.tsx +46 -13
- package/src/rbac/components/RoleBasedRouter.tsx +1 -1
- package/src/rbac/components/SecureDataProvider.tsx +1 -2
- package/src/rbac/components/__tests__/EnhancedNavigationMenu.test.tsx +7 -43
- package/src/rbac/components/__tests__/NavigationGuard.test.tsx +4 -11
- package/src/rbac/components/__tests__/NavigationProvider.test.tsx +3 -3
- package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +1 -1
- package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +1 -1
- package/src/rbac/engine.ts +14 -2
- package/src/rbac/hooks/index.ts +0 -3
- package/src/rbac/hooks/usePermissions.ts +51 -11
- package/src/rbac/hooks/useRBAC.ts +3 -13
- package/src/rbac/hooks/useResolvedScope.test.ts +75 -54
- package/src/rbac/hooks/useResolvedScope.ts +58 -33
- package/src/rbac/hooks/useSecureSupabase.ts +4 -9
- package/src/rbac/secureClient.ts +43 -0
- package/src/services/EventService.ts +4 -57
- package/src/services/InactivityService.ts +127 -34
- package/src/services/OrganisationService.ts +68 -10
- package/src/utils/security/secureDataAccess.test.ts +31 -20
- package/src/utils/security/secureDataAccess.ts +4 -3
- package/dist/chunk-6C4YBBJM.js.map +0 -1
- package/dist/chunk-6LTQQAT6.js.map +0 -1
- package/dist/chunk-6TQDD426.js.map +0 -1
- package/dist/chunk-LOMZXPSN.js.map +0 -1
- package/dist/chunk-OETXORNB.js.map +0 -1
- package/dist/chunk-ULHIJK66.js.map +0 -1
- package/dist/chunk-VKB2CO4Z.js.map +0 -1
- package/dist/chunk-VRGWKHDB.js.map +0 -1
- package/dist/chunk-XNYQOL3Z.js.map +0 -1
- package/dist/chunk-XYXSXPUK.js.map +0 -1
- package/scripts/check-pace-core-compliance.js +0 -512
- package/src/rbac/hooks/useSuperAdminBypass.ts +0 -126
- package/src/utils/context/superAdminOverride.ts +0 -58
- /package/dist/{DataTable-WKRZD47S.js.map → DataTable-DQ7RSOHE.js.map} +0 -0
- /package/dist/{UnifiedAuthProvider-FTSG5XH7.js.map → UnifiedAuthProvider-ATAP5UTR.js.map} +0 -0
- /package/dist/{api-IHKALJZD.js.map → api-N774RPUA.js.map} +0 -0
- /package/dist/{chunk-QWWZ5CAQ.js.map → chunk-LXQLPRQ2.js.map} +0 -0
- /package/examples/{rbac → RBAC}/CompleteRBACExample.tsx +0 -0
- /package/examples/{rbac → RBAC}/EventBasedApp.tsx +0 -0
- /package/examples/{rbac → RBAC}/PermissionExample.tsx +0 -0
- /package/examples/{rbac → RBAC}/index.ts +0 -0
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
* ```
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
-
import { useState
|
|
26
|
+
import { useState } from 'react';
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
29
|
* Options for configuring the useFormDialog hook behavior
|
|
@@ -115,27 +115,28 @@ export function useFormDialog<T = unknown>({
|
|
|
115
115
|
const [isOpen, setIsOpen] = useState(false);
|
|
116
116
|
const [formData, setFormData] = useState<T | null>(null);
|
|
117
117
|
|
|
118
|
-
|
|
118
|
+
// React Compiler handles memoization automatically
|
|
119
|
+
const openDialog = (data: T | null = null) => {
|
|
119
120
|
setFormData(data);
|
|
120
121
|
setIsOpen(true);
|
|
121
122
|
onOpenChange?.(true);
|
|
122
|
-
}
|
|
123
|
+
};
|
|
123
124
|
|
|
124
|
-
const closeDialog =
|
|
125
|
+
const closeDialog = () => {
|
|
125
126
|
setIsOpen(false);
|
|
126
127
|
if (resetOnClose) {
|
|
127
128
|
setFormData(null);
|
|
128
129
|
}
|
|
129
130
|
onOpenChange?.(false);
|
|
130
|
-
}
|
|
131
|
+
};
|
|
131
132
|
|
|
132
|
-
const handleOpenChange =
|
|
133
|
+
const handleOpenChange = (open: boolean) => {
|
|
133
134
|
setIsOpen(open);
|
|
134
135
|
if (!open && resetOnClose) {
|
|
135
136
|
setFormData(null);
|
|
136
137
|
}
|
|
137
138
|
onOpenChange?.(open);
|
|
138
|
-
}
|
|
139
|
+
};
|
|
139
140
|
|
|
140
141
|
return {
|
|
141
142
|
isOpen,
|
|
@@ -15,7 +15,7 @@ import { useOrganisations } from './useOrganisations';
|
|
|
15
15
|
import { setOrganisationContext } from '../utils/context/organisationContext';
|
|
16
16
|
import { createMockSupabaseClient, createMockQueryBuilderWithData } from '../__tests__/helpers/supabaseMock';
|
|
17
17
|
import { useResolvedScope } from '../rbac/hooks/useResolvedScope';
|
|
18
|
-
import {
|
|
18
|
+
import { useOrganisationSecurity } from './useOrganisationSecurity';
|
|
19
19
|
|
|
20
20
|
// Mock the providers
|
|
21
21
|
vi.mock('../providers', () => ({
|
|
@@ -36,9 +36,9 @@ vi.mock('../rbac/hooks/useResolvedScope', () => ({
|
|
|
36
36
|
useResolvedScope: vi.fn()
|
|
37
37
|
}));
|
|
38
38
|
|
|
39
|
-
// Mock
|
|
40
|
-
vi.mock('
|
|
41
|
-
|
|
39
|
+
// Mock useOrganisationSecurity
|
|
40
|
+
vi.mock('./useOrganisationSecurity', () => ({
|
|
41
|
+
useOrganisationSecurity: vi.fn()
|
|
42
42
|
}));
|
|
43
43
|
|
|
44
44
|
|
|
@@ -47,7 +47,7 @@ describe('useSecureDataAccess', () => {
|
|
|
47
47
|
const mockUseOrganisations = vi.mocked(useOrganisations);
|
|
48
48
|
const mockSetOrganisationContext = vi.mocked(setOrganisationContext);
|
|
49
49
|
const mockUseResolvedScope = vi.mocked(useResolvedScope);
|
|
50
|
-
const
|
|
50
|
+
const mockUseOrganisationSecurity = vi.mocked(useOrganisationSecurity);
|
|
51
51
|
|
|
52
52
|
const mockUser = {
|
|
53
53
|
id: 'user-123',
|
|
@@ -119,10 +119,17 @@ describe('useSecureDataAccess', () => {
|
|
|
119
119
|
error: null,
|
|
120
120
|
});
|
|
121
121
|
|
|
122
|
-
// Mock
|
|
123
|
-
|
|
124
|
-
isSuperAdmin: false,
|
|
125
|
-
|
|
122
|
+
// Mock useOrganisationSecurity to return not super admin
|
|
123
|
+
mockUseOrganisationSecurity.mockReturnValue({
|
|
124
|
+
superAdminContext: { isSuperAdmin: false, hasGlobalAccess: false, canManageAllOrganisations: false },
|
|
125
|
+
validateOrganisationAccess: vi.fn(),
|
|
126
|
+
hasMinimumRole: vi.fn(),
|
|
127
|
+
canAccessChildOrganisations: vi.fn(),
|
|
128
|
+
checkPermission: vi.fn(),
|
|
129
|
+
getPermissions: vi.fn(),
|
|
130
|
+
logOrganisationAccess: vi.fn(),
|
|
131
|
+
canManageOrganisation: vi.fn(),
|
|
132
|
+
} as any);
|
|
126
133
|
});
|
|
127
134
|
|
|
128
135
|
describe('Hook Initialization', () => {
|
|
@@ -59,7 +59,7 @@ import { setOrganisationContext } from '../utils/context/organisationContext';
|
|
|
59
59
|
import { logger } from '../utils/core/logger';
|
|
60
60
|
import type { Permission } from '../rbac/types';
|
|
61
61
|
import type { OrganisationSecurityError } from '../types/organisation';
|
|
62
|
-
import {
|
|
62
|
+
import { useOrganisationSecurity } from './useOrganisationSecurity';
|
|
63
63
|
import { useResolvedScope } from '../rbac/hooks/useResolvedScope';
|
|
64
64
|
|
|
65
65
|
export interface SecureDataAccessReturn {
|
|
@@ -158,7 +158,8 @@ export function useSecureDataAccess(): SecureDataAccessReturn {
|
|
|
158
158
|
const eventServiceContext = useContext(EventServiceContext);
|
|
159
159
|
const eventFromContext = eventServiceContext?.eventService?.getSelectedEvent() || null;
|
|
160
160
|
const effectiveSelectedEvent = selectedEvent || eventFromContext;
|
|
161
|
-
const {
|
|
161
|
+
const { superAdminContext } = useOrganisationSecurity();
|
|
162
|
+
const isSuperAdmin = superAdminContext.isSuperAdmin;
|
|
162
163
|
|
|
163
164
|
// Use resolved scope to get organisationId (derived from event if needed)
|
|
164
165
|
const { resolvedScope } = useResolvedScope({
|
|
@@ -236,9 +237,11 @@ export function useSecureDataAccess(): SecureDataAccessReturn {
|
|
|
236
237
|
// SECURITY: Phase 2 additions - complete organisation table mapping
|
|
237
238
|
'organisation_audit_log', 'organisation_invitations', 'organisation_app_access',
|
|
238
239
|
// SECURITY: Emergency additions for Phase 1 fixes
|
|
239
|
-
'cake_meal', 'cake_mealtype',
|
|
240
|
-
// NOTE:
|
|
241
|
-
// are
|
|
240
|
+
'cake_meal', 'cake_mealtype',
|
|
241
|
+
// NOTE: core_person, core_member, core_contact, core_consent, core_identification,
|
|
242
|
+
// core_qualification, and medi_profile are person-scoped tables that do NOT have
|
|
243
|
+
// organisation_id columns. They were removed as part of the person-scoped profiles migration.
|
|
244
|
+
// Do NOT add organisation_id filters to these tables - it will cause 400 errors.
|
|
242
245
|
// SECURITY: Phase 3A additions - medical and personal data
|
|
243
246
|
// NOTE: medi_condition, medi_diet, medi_action_plan, medi_profile_versions are now person-scoped
|
|
244
247
|
// (via medi_profile) - removed from this list
|
|
@@ -369,7 +372,20 @@ export function useSecureDataAccess(): SecureDataAccessReturn {
|
|
|
369
372
|
// SECURITY: Phase 2 additions - complete organisation table mapping
|
|
370
373
|
'organisation_audit_log', 'organisation_invitations', 'organisation_app_access',
|
|
371
374
|
// SECURITY: Emergency additions for Phase 1 fixes
|
|
372
|
-
'cake_meal', 'cake_mealtype', 'core_person',
|
|
375
|
+
'cake_meal', 'cake_mealtype', 'core_person',
|
|
376
|
+
// SECURITY: These tables still have organisation_id columns and must be filtered
|
|
377
|
+
'core_member', 'core_contact', 'core_consent', 'core_identification', 'core_qualification',
|
|
378
|
+
'medi_profile',
|
|
379
|
+
// SECURITY: Phase 3A additions - medical and personal data
|
|
380
|
+
'medi_condition', 'medi_diet', 'medi_action_plan', 'medi_profile_versions',
|
|
381
|
+
'core_identification_type',
|
|
382
|
+
'form_responses', 'form_response_values', 'forms',
|
|
383
|
+
// SECURITY: Phase 3B additions - remaining critical tables
|
|
384
|
+
'invoice', 'line_item', 'credit_balance', 'payment_method',
|
|
385
|
+
'form_contexts', 'form_field_config', 'form_fields',
|
|
386
|
+
'cake_delivery', 'cake_diettype', 'cake_diner', 'cake_dish', 'cake_item',
|
|
387
|
+
'cake_logistics', 'cake_mealplan', 'cake_package', 'cake_recipe', 'cake_supplier',
|
|
388
|
+
'cake_supply', 'cake_unit', 'event_app_access', 'base_application', 'base_questions'
|
|
373
389
|
];
|
|
374
390
|
|
|
375
391
|
if (!bypassOrganisationFilter && organisationId && tablesWithOrganisation.includes(table)) {
|
package/src/hooks/useToast.ts
CHANGED
|
@@ -23,7 +23,7 @@ export interface ToastProps {
|
|
|
23
23
|
description?: React.ReactNode;
|
|
24
24
|
variant?: 'default' | 'destructive' | 'success';
|
|
25
25
|
onClose?: () => void;
|
|
26
|
-
action?: React.ReactElement
|
|
26
|
+
action?: React.ReactElement<any>;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
/**
|
|
@@ -40,7 +40,7 @@ type ToasterToast = ToastProps & {
|
|
|
40
40
|
/** Optional description content */
|
|
41
41
|
description?: React.ReactNode
|
|
42
42
|
/** Optional action button */
|
|
43
|
-
action?: React.ReactElement
|
|
43
|
+
action?: React.ReactElement<any>
|
|
44
44
|
/** Open state */
|
|
45
45
|
open?: boolean
|
|
46
46
|
/** Open change handler */
|
|
@@ -17,9 +17,14 @@ vi.mock('../../utils/debugLogger', () => ({
|
|
|
17
17
|
},
|
|
18
18
|
}));
|
|
19
19
|
|
|
20
|
-
// Mock setOrganisationContext
|
|
20
|
+
// Mock setOrganisationContext - make it resolve immediately to avoid delays
|
|
21
21
|
vi.mock('../../utils/context/organisationContext', () => ({
|
|
22
|
-
setOrganisationContext: vi.fn().
|
|
22
|
+
setOrganisationContext: vi.fn().mockImplementation(() => Promise.resolve(undefined)),
|
|
23
|
+
}));
|
|
24
|
+
|
|
25
|
+
// Mock isSuperAdmin to return false (normal user, not super admin)
|
|
26
|
+
vi.mock('../../rbac/api', () => ({
|
|
27
|
+
isSuperAdmin: vi.fn().mockResolvedValue(false),
|
|
23
28
|
}));
|
|
24
29
|
|
|
25
30
|
// Create mock user and session
|
|
@@ -63,18 +68,36 @@ const createMockSupabaseClient = () => {
|
|
|
63
68
|
role: 'org_admin',
|
|
64
69
|
status: 'active',
|
|
65
70
|
granted_at: '2023-01-01T00:00:00Z',
|
|
71
|
+
granted_by: null,
|
|
66
72
|
revoked_at: null,
|
|
67
|
-
|
|
73
|
+
revoked_by: null,
|
|
74
|
+
notes: null,
|
|
75
|
+
created_at: '2023-01-01T00:00:00Z',
|
|
76
|
+
updated_at: '2023-01-01T00:00:00Z',
|
|
77
|
+
core_organisations: {
|
|
78
|
+
id: orgId,
|
|
79
|
+
name: 'Test Organisation 1',
|
|
80
|
+
display_name: 'Test Organisation 1',
|
|
81
|
+
subscription_tier: 'basic',
|
|
82
|
+
settings: {},
|
|
83
|
+
is_active: true,
|
|
84
|
+
parent_id: null,
|
|
85
|
+
created_at: '2023-01-01T00:00:00Z',
|
|
86
|
+
updated_at: '2023-01-01T00:00:00Z'
|
|
87
|
+
}
|
|
68
88
|
}],
|
|
69
89
|
error: null
|
|
70
90
|
})
|
|
71
91
|
};
|
|
72
92
|
|
|
93
|
+
// Mock RPC function for setOrganisationContext
|
|
94
|
+
const mockRpc = vi.fn().mockResolvedValue({
|
|
95
|
+
data: null,
|
|
96
|
+
error: null,
|
|
97
|
+
});
|
|
98
|
+
|
|
73
99
|
return {
|
|
74
|
-
rpc:
|
|
75
|
-
data: [],
|
|
76
|
-
error: null,
|
|
77
|
-
}),
|
|
100
|
+
rpc: mockRpc,
|
|
78
101
|
from: vi.fn((table: string) => {
|
|
79
102
|
if (table === 'rbac_organisation_roles') {
|
|
80
103
|
return mockQueryBuilder;
|
|
@@ -127,6 +150,8 @@ describe('OrganisationProvider', () => {
|
|
|
127
150
|
|
|
128
151
|
beforeEach(() => {
|
|
129
152
|
vi.clearAllMocks();
|
|
153
|
+
// Clear localStorage to ensure clean state
|
|
154
|
+
localStorage.clear();
|
|
130
155
|
mockSupabaseClient = createMockSupabaseClient();
|
|
131
156
|
});
|
|
132
157
|
|
|
@@ -140,10 +165,19 @@ describe('OrganisationProvider', () => {
|
|
|
140
165
|
|
|
141
166
|
expect(screen.getByTestId('test-component')).toBeInTheDocument();
|
|
142
167
|
|
|
143
|
-
// Wait for organisations to load
|
|
168
|
+
// Wait for organisations to load - OrganisationService initializes asynchronously
|
|
169
|
+
// The service calls notify() in finally block, and useOrganisationService has 50ms debounce
|
|
170
|
+
// Also need to account for the 2 second minimum retry delay in loadUserOrganisations
|
|
144
171
|
await waitFor(() => {
|
|
145
|
-
|
|
146
|
-
|
|
172
|
+
const count = screen.getByTestId('organisations-count').textContent;
|
|
173
|
+
const error = screen.getByTestId('error').textContent;
|
|
174
|
+
// Log for debugging if test fails
|
|
175
|
+
if (count !== '1' || error !== 'no-error') {
|
|
176
|
+
console.log('Test state:', { count, error, isLoading: screen.getByTestId('isLoading').textContent });
|
|
177
|
+
}
|
|
178
|
+
expect(count).toBe('1');
|
|
179
|
+
expect(error).toBe('no-error');
|
|
180
|
+
}, { timeout: 15000, interval: 200 });
|
|
147
181
|
|
|
148
182
|
expect(screen.getByTestId('isLoading')).toHaveTextContent('false');
|
|
149
183
|
expect(screen.getByTestId('error')).toHaveTextContent('no-error');
|
|
@@ -169,10 +203,20 @@ describe('OrganisationProvider', () => {
|
|
|
169
203
|
);
|
|
170
204
|
|
|
171
205
|
// Wait for organisations to load and selected organisation to be set
|
|
206
|
+
// The service calls notify() in finally block, and useOrganisationService has 50ms debounce
|
|
207
|
+
// Also need to account for the 2 second minimum retry delay in loadUserOrganisations
|
|
172
208
|
await waitFor(() => {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
209
|
+
const count = screen.getByTestId('organisations-count').textContent;
|
|
210
|
+
const error = screen.getByTestId('error').textContent;
|
|
211
|
+
const selectedOrg = screen.getByTestId('selectedOrg').textContent;
|
|
212
|
+
// Log for debugging if test fails
|
|
213
|
+
if (count !== '1' || error !== 'no-error' || selectedOrg === 'no-org') {
|
|
214
|
+
console.log('Test state:', { count, error, selectedOrg, isLoading: screen.getByTestId('isLoading').textContent });
|
|
215
|
+
}
|
|
216
|
+
expect(count).toBe('1');
|
|
217
|
+
expect(error).toBe('no-error');
|
|
218
|
+
expect(selectedOrg).not.toBe('no-org');
|
|
219
|
+
}, { timeout: 15000, interval: 200 });
|
|
176
220
|
|
|
177
221
|
expect(screen.getByTestId('organisations-count')).toHaveTextContent('1');
|
|
178
222
|
expect(screen.getByTestId('isLoading')).toHaveTextContent('false');
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* Tests for provider lifecycle management, state persistence, cleanup, and edge cases.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { render, screen, fireEvent } from '@testing-library/react';
|
|
10
|
+
import { render, screen, fireEvent, act } from '@testing-library/react';
|
|
11
11
|
import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
12
12
|
import React, { ReactNode, useState } from 'react';
|
|
13
13
|
import { createMockSupabaseClient } from '../../__tests__/helpers/supabaseMock';
|
|
@@ -88,8 +88,12 @@ describe('Provider Lifecycle Tests', () => {
|
|
|
88
88
|
it('should cleanup subscription listeners', () => {
|
|
89
89
|
const cleanup = vi.fn();
|
|
90
90
|
const TestComponent = () => {
|
|
91
|
+
const cleanupRef = React.useRef(cleanup);
|
|
91
92
|
React.useEffect(() => {
|
|
92
|
-
|
|
93
|
+
// Return a function that calls cleanup from ref
|
|
94
|
+
return () => {
|
|
95
|
+
cleanupRef.current();
|
|
96
|
+
};
|
|
93
97
|
}, []);
|
|
94
98
|
return <div data-testid="listener-test">Test</div>;
|
|
95
99
|
};
|
|
@@ -98,7 +102,9 @@ describe('Provider Lifecycle Tests', () => {
|
|
|
98
102
|
|
|
99
103
|
expect(screen.getByTestId('listener-test')).toBeInTheDocument();
|
|
100
104
|
|
|
101
|
-
|
|
105
|
+
act(() => {
|
|
106
|
+
unmountComponent();
|
|
107
|
+
});
|
|
102
108
|
|
|
103
109
|
// Cleanup should be called on unmount
|
|
104
110
|
expect(cleanup).toHaveBeenCalled();
|
|
@@ -109,13 +115,22 @@ describe('Provider Lifecycle Tests', () => {
|
|
|
109
115
|
const cleanup2 = vi.fn();
|
|
110
116
|
|
|
111
117
|
const TestComponent = () => {
|
|
112
|
-
React.
|
|
113
|
-
React.
|
|
118
|
+
const cleanup1Ref = React.useRef(cleanup1);
|
|
119
|
+
const cleanup2Ref = React.useRef(cleanup2);
|
|
120
|
+
React.useEffect(() => {
|
|
121
|
+
return () => cleanup1Ref.current();
|
|
122
|
+
}, []);
|
|
123
|
+
React.useEffect(() => {
|
|
124
|
+
return () => cleanup2Ref.current();
|
|
125
|
+
}, []);
|
|
114
126
|
return <div data-testid="multi-listener">Test</div>;
|
|
115
127
|
};
|
|
116
128
|
|
|
117
129
|
const { unmount: unmountComponent } = render(<TestComponent />);
|
|
118
|
-
|
|
130
|
+
|
|
131
|
+
act(() => {
|
|
132
|
+
unmountComponent();
|
|
133
|
+
});
|
|
119
134
|
|
|
120
135
|
expect(cleanup1).toHaveBeenCalled();
|
|
121
136
|
expect(cleanup2).toHaveBeenCalled();
|
|
@@ -72,7 +72,7 @@ const TestComponent = () => {
|
|
|
72
72
|
|
|
73
73
|
describe('UnifiedAuthProvider', () => {
|
|
74
74
|
let mockSupabaseClient: ReturnType<typeof createMockSupabaseClient>;
|
|
75
|
-
const
|
|
75
|
+
const baseProps = {
|
|
76
76
|
idleTimeoutMs: 30 * 60 * 1000,
|
|
77
77
|
warnBeforeMs: 60 * 1000,
|
|
78
78
|
onIdleLogout: vi.fn(),
|
|
@@ -86,7 +86,7 @@ describe('UnifiedAuthProvider', () => {
|
|
|
86
86
|
describe('Rendering', () => {
|
|
87
87
|
it('renders without crashing', () => {
|
|
88
88
|
render(
|
|
89
|
-
<UnifiedAuthProvider supabaseClient={mockSupabaseClient} {...
|
|
89
|
+
<UnifiedAuthProvider supabaseClient={mockSupabaseClient} {...baseProps}>
|
|
90
90
|
<TestComponent />
|
|
91
91
|
</UnifiedAuthProvider>
|
|
92
92
|
);
|
|
@@ -96,7 +96,7 @@ describe('UnifiedAuthProvider', () => {
|
|
|
96
96
|
|
|
97
97
|
it('renders with custom app name', () => {
|
|
98
98
|
render(
|
|
99
|
-
<UnifiedAuthProvider supabaseClient={mockSupabaseClient} appName="Custom App" {...
|
|
99
|
+
<UnifiedAuthProvider supabaseClient={mockSupabaseClient} appName="Custom App" {...baseProps}>
|
|
100
100
|
<TestComponent />
|
|
101
101
|
</UnifiedAuthProvider>
|
|
102
102
|
);
|
|
@@ -118,7 +118,7 @@ describe('UnifiedAuthProvider', () => {
|
|
|
118
118
|
describe('Context Values', () => {
|
|
119
119
|
it('provides all required context values', async () => {
|
|
120
120
|
render(
|
|
121
|
-
<UnifiedAuthProvider supabaseClient={mockSupabaseClient} appName="Test App" {...
|
|
121
|
+
<UnifiedAuthProvider supabaseClient={mockSupabaseClient} appName="Test App" {...baseProps}>
|
|
122
122
|
<TestComponent />
|
|
123
123
|
</UnifiedAuthProvider>
|
|
124
124
|
);
|
|
@@ -182,7 +182,7 @@ describe('UnifiedAuthProvider', () => {
|
|
|
182
182
|
|
|
183
183
|
it('uses default configuration', () => {
|
|
184
184
|
render(
|
|
185
|
-
<UnifiedAuthProvider supabaseClient={mockSupabaseClient} {...
|
|
185
|
+
<UnifiedAuthProvider supabaseClient={mockSupabaseClient} {...baseProps}>
|
|
186
186
|
<TestComponent />
|
|
187
187
|
</UnifiedAuthProvider>
|
|
188
188
|
);
|
|
@@ -207,7 +207,7 @@ describe('UnifiedAuthProvider', () => {
|
|
|
207
207
|
};
|
|
208
208
|
|
|
209
209
|
render(
|
|
210
|
-
<UnifiedAuthProvider supabaseClient={mockSupabaseClient} appName="Test App" {...
|
|
210
|
+
<UnifiedAuthProvider supabaseClient={mockSupabaseClient} appName="Test App" {...baseProps}>
|
|
211
211
|
<TestCompositionComponent />
|
|
212
212
|
</UnifiedAuthProvider>
|
|
213
213
|
);
|
|
@@ -236,7 +236,7 @@ describe('UnifiedAuthProvider', () => {
|
|
|
236
236
|
};
|
|
237
237
|
|
|
238
238
|
render(
|
|
239
|
-
<UnifiedAuthProvider supabaseClient={mockSupabaseClient} appName="Test App" {...
|
|
239
|
+
<UnifiedAuthProvider supabaseClient={mockSupabaseClient} appName="Test App" {...baseProps}>
|
|
240
240
|
<TestCompleteContextComponent />
|
|
241
241
|
</UnifiedAuthProvider>
|
|
242
242
|
);
|
|
@@ -428,7 +428,7 @@ describe('UnifiedAuthProvider', () => {
|
|
|
428
428
|
};
|
|
429
429
|
|
|
430
430
|
render(
|
|
431
|
-
<UnifiedAuthProvider supabaseClient={mockSupabaseClient} appName="Test App" {...
|
|
431
|
+
<UnifiedAuthProvider supabaseClient={mockSupabaseClient} appName="Test App" {...baseProps}>
|
|
432
432
|
<TestHookIntegrationComponent />
|
|
433
433
|
</UnifiedAuthProvider>
|
|
434
434
|
);
|
|
@@ -494,7 +494,7 @@ describe('UnifiedAuthProvider', () => {
|
|
|
494
494
|
};
|
|
495
495
|
|
|
496
496
|
render(
|
|
497
|
-
<UnifiedAuthProvider supabaseClient={mockSupabaseClient} appName="Test App" {...
|
|
497
|
+
<UnifiedAuthProvider supabaseClient={mockSupabaseClient} appName="Test App" {...baseProps}>
|
|
498
498
|
<TestConcurrentComponent />
|
|
499
499
|
</UnifiedAuthProvider>
|
|
500
500
|
);
|
|
@@ -554,7 +554,7 @@ describe('UnifiedAuthProvider', () => {
|
|
|
554
554
|
};
|
|
555
555
|
|
|
556
556
|
render(
|
|
557
|
-
<UnifiedAuthProvider supabaseClient={mockSupabaseClient} appName="Test App" enableRBAC={true} {...
|
|
557
|
+
<UnifiedAuthProvider supabaseClient={mockSupabaseClient} appName="Test App" enableRBAC={true} {...baseProps}>
|
|
558
558
|
<TestRBACConfigComponent />
|
|
559
559
|
</UnifiedAuthProvider>
|
|
560
560
|
);
|
|
@@ -63,14 +63,6 @@ export function EventServiceProvider({
|
|
|
63
63
|
initializingRef.current = true;
|
|
64
64
|
|
|
65
65
|
try {
|
|
66
|
-
logger.debug('EventServiceProvider', 'Updating dependencies and initializing', {
|
|
67
|
-
hasUser: !!user,
|
|
68
|
-
hasSession: !!session,
|
|
69
|
-
appName,
|
|
70
|
-
hasSelectedOrganisation: !!selectedOrganisation,
|
|
71
|
-
organisationId: selectedOrganisation?.id
|
|
72
|
-
});
|
|
73
|
-
|
|
74
66
|
// Update dependencies (now async to handle user change cleanup)
|
|
75
67
|
await eventService.updateDependencies(supabaseClient, user, session, appName, selectedOrganisation, setSelectedEventId);
|
|
76
68
|
|