@jmruthers/pace-core 0.6.11 → 0.6.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{DataTable-EFYP2QLE.js → DataTable-AQAHSFLM.js} +7 -6
- package/dist/{api-BZR2CYXL.js → api-6OQXYT67.js} +2 -1
- package/dist/{chunk-L5LFKKLJ.js → chunk-2GBDPPUC.js} +1 -1
- package/dist/{chunk-J2KQK6DG.js → chunk-AP5FG7W4.js} +2 -2
- package/dist/{chunk-UZNAFKGW.js → chunk-GHCUP64P.js} +1 -21
- package/dist/{chunk-V7FTM2LU.js → chunk-H6RTU4DZ.js} +37 -19
- package/dist/{chunk-KJXRL3XE.js → chunk-HQTYP6BX.js} +79 -45
- package/dist/{chunk-YFTFFJIV.js → chunk-M7QE7XOA.js} +3 -3
- package/dist/{chunk-YYTWKVHO.js → chunk-MVVWZ7JV.js} +25 -30
- package/dist/{chunk-PCSHBLPB.js → chunk-NJ7FGQWB.js} +5 -5
- package/dist/{chunk-WY6Y7KC3.js → chunk-QWIG36BZ.js} +3 -3
- package/dist/{chunk-4R3T5ENU.js → chunk-S57OLCLO.js} +9 -6
- package/dist/chunk-VFLR5K2H.js +23 -0
- package/dist/{chunk-2OEVOGGR.js → chunk-Y2LWSLLB.js} +41 -25
- package/dist/{chunk-7A6IMHH2.js → chunk-YFGNMB67.js} +75 -6
- package/dist/components.d.ts +3 -3
- package/dist/components.js +13 -12
- package/dist/{functions-DH45k8ec.d.ts → functions-hF5ImHCr.d.ts} +1 -1
- package/dist/hooks.js +8 -7
- package/dist/index.d.ts +5 -5
- package/dist/index.js +17 -16
- package/dist/providers.js +3 -2
- package/dist/rbac/index.d.ts +10 -10
- package/dist/rbac/index.js +9 -8
- package/dist/{types-BE2sEHKd.d.ts → types-Besvoyzb.d.ts} +1 -1
- package/dist/{types-CvOPXWWZ.d.ts → types-CGHrxfqc.d.ts} +3 -0
- package/dist/types.d.ts +2 -2
- package/dist/{usePublicPageContext-B91dGYW1.d.ts → usePublicPageContext-BQrHf95t.d.ts} +1 -1
- package/dist/utils.js +4 -3
- package/docs/api/@jmruthers/namespaces/DialogPortal/README.md +14 -0
- package/docs/api/@jmruthers/namespaces/DialogPortal/variables/displayName.md +11 -0
- package/docs/api/README.md +6 -2
- package/docs/api/_media/README.md +186 -0
- package/docs/api/classes/ColumnFactory.md +225 -0
- package/docs/api/classes/Logger.md +246 -0
- package/docs/api/classes/RBACAuditManager.md +299 -0
- package/docs/api/classes/RBACCache.md +389 -0
- package/docs/api/classes/RBACEngine.md +181 -0
- package/docs/api/classes/SecureSupabaseClient.md +168 -0
- package/docs/api/classes/StorageUtils.md +324 -0
- package/docs/api/enumerations/FileCategory.md +137 -0
- package/docs/api/enumerations/LogLevel.md +43 -0
- package/docs/api/enumerations/RBACErrorCode.md +169 -0
- package/docs/api/enumerations/RPCFunction.md +89 -0
- package/docs/api/functions/AccessDenied.md +30 -0
- package/docs/api/functions/AppSwitcher.md +21 -0
- package/docs/api/functions/Badge.md +42 -0
- package/docs/api/functions/ContextSelector.md +43 -0
- package/docs/api/functions/DataTable.md +36 -0
- package/docs/api/functions/DatePickerWithTimezone.md +28 -0
- package/docs/api/functions/DialogBody.md +24 -0
- package/docs/api/functions/DialogFooter.md +24 -0
- package/docs/api/functions/DialogHeader.md +24 -0
- package/docs/api/functions/ErrorBoundaryProvider.md +28 -0
- package/docs/api/functions/EventServiceProvider.md +28 -0
- package/docs/api/functions/FileDisplay.md +25 -0
- package/docs/api/functions/FileUpload.md +21 -0
- package/docs/api/functions/Form.md +50 -0
- package/docs/api/functions/FormField.md +102 -0
- package/docs/api/functions/Header.md +21 -0
- package/docs/api/functions/InactivityServiceProvider.md +28 -0
- package/docs/api/functions/InactivityWarningModal.md +21 -0
- package/docs/api/functions/Input.md +49 -0
- package/docs/api/functions/NavigationGuard.md +31 -0
- package/docs/api/functions/OrganisationServiceProvider.md +28 -0
- package/docs/api/functions/PaceAppLayout.md +169 -0
- package/docs/api/functions/PasswordChangeForm.md +21 -0
- package/docs/api/functions/ProtectedRoute.md +37 -0
- package/docs/api/functions/PublicPageFooter.md +21 -0
- package/docs/api/functions/PublicPageHeader.md +21 -0
- package/docs/api/functions/PublicPageLayout.md +33 -0
- package/docs/api/functions/PublicPageProvider.md +30 -0
- package/docs/api/functions/Textarea.md +49 -0
- package/docs/api/functions/Toaster.md +34 -0
- package/docs/api/functions/UnifiedAuthProvider.md +28 -0
- package/docs/api/functions/applyPalette.md +33 -0
- package/docs/api/functions/archiveFile.md +47 -0
- package/docs/api/functions/average.md +63 -0
- package/docs/api/functions/buildAppUrl.md +46 -0
- package/docs/api/functions/clearInFlightRequests.md +17 -0
- package/docs/api/functions/clearPalette.md +18 -0
- package/docs/api/functions/clearPublicEventCache.md +18 -0
- package/docs/api/functions/clearPublicFileDisplayCache.md +18 -0
- package/docs/api/functions/clearPublicLogoCache.md +18 -0
- package/docs/api/functions/cn.md +21 -0
- package/docs/api/functions/count.md +56 -0
- package/docs/api/functions/createAuditManager.md +45 -0
- package/docs/api/functions/createBaseClient.md +75 -0
- package/docs/api/functions/createLogger.md +95 -0
- package/docs/api/functions/createRBACConfig.md +21 -0
- package/docs/api/functions/createRBACEngine.md +33 -0
- package/docs/api/functions/createRBACExpressMiddleware.md +84 -0
- package/docs/api/functions/createRBACMiddleware.md +88 -0
- package/docs/api/functions/createSecureClient.md +80 -0
- package/docs/api/functions/createSecureDataAccess.md +39 -0
- package/docs/api/functions/deleteFile.md +33 -0
- package/docs/api/functions/disablePerformanceMonitoring.md +17 -0
- package/docs/api/functions/downloadFile.md +33 -0
- package/docs/api/functions/emitAuditEvent.md +27 -0
- package/docs/api/functions/enablePerformanceMonitoring.md +17 -0
- package/docs/api/functions/err.md +23 -0
- package/docs/api/functions/exportToCSV.md +56 -0
- package/docs/api/functions/exportToCSVWithTableRows.md +46 -0
- package/docs/api/functions/extractEventCodeFromPath.md +24 -0
- package/docs/api/functions/extractFileMetadata.md +33 -0
- package/docs/api/functions/formatCompactNumber.md +27 -0
- package/docs/api/functions/formatCurrency.md +31 -0
- package/docs/api/functions/formatDate.md +23 -0
- package/docs/api/functions/formatDateTime.md +24 -0
- package/docs/api/functions/formatFileSize.md +23 -0
- package/docs/api/functions/formatInTimeZone.md +46 -0
- package/docs/api/functions/formatNumber.md +31 -0
- package/docs/api/functions/formatPercent.md +64 -0
- package/docs/api/functions/formatTime.md +24 -0
- package/docs/api/functions/formatTimeInTimeZone.md +40 -0
- package/docs/api/functions/fromSupabaseClient.md +49 -0
- package/docs/api/functions/fromZonedTime.md +41 -0
- package/docs/api/functions/generateCSVContent.md +55 -0
- package/docs/api/functions/generateFilePath.md +29 -0
- package/docs/api/functions/generateFileUrlsBatch.md +33 -0
- package/docs/api/functions/generatePublicRoutePath.md +27 -0
- package/docs/api/functions/generateUniqueFileName.md +24 -0
- package/docs/api/functions/getAccessLevel.md +48 -0
- package/docs/api/functions/getAllAppPorts.md +19 -0
- package/docs/api/functions/getAllStylePaths.md +15 -0
- package/docs/api/functions/getAppConfig.md +17 -0
- package/docs/api/functions/getAppPort.md +34 -0
- package/docs/api/functions/getBucketName.md +27 -0
- package/docs/api/functions/getCurrentAppId.md +17 -0
- package/docs/api/functions/getCurrentAppName.md +17 -0
- package/docs/api/functions/getFileSizeLimit.md +23 -0
- package/docs/api/functions/getGlobalAuditManager.md +19 -0
- package/docs/api/functions/getInFlightRequestCount.md +19 -0
- package/docs/api/functions/getPerformanceMetrics.md +17 -0
- package/docs/api/functions/getPerformanceSummary.md +17 -0
- package/docs/api/functions/getPermissionMap.md +52 -0
- package/docs/api/functions/getPublicEventCacheStats.md +25 -0
- package/docs/api/functions/getPublicFileDisplayCacheStats.md +25 -0
- package/docs/api/functions/getPublicLogoCacheStats.md +25 -0
- package/docs/api/functions/getPublicUrl.md +39 -0
- package/docs/api/functions/getRBACConfig.md +15 -0
- package/docs/api/functions/getRBACLogger.md +15 -0
- package/docs/api/functions/getRoleContext.md +31 -0
- package/docs/api/functions/getSignedUrl.md +34 -0
- package/docs/api/functions/getStylePath.md +21 -0
- package/docs/api/functions/getTimeZoneDifference.md +40 -0
- package/docs/api/functions/getTimezoneAbbreviation.md +40 -0
- package/docs/api/functions/getUserTimeZone.md +26 -0
- package/docs/api/functions/hasAllPermissions.md +41 -0
- package/docs/api/functions/hasAnyPermission.md +41 -0
- package/docs/api/functions/isDebugMode.md +15 -0
- package/docs/api/functions/isDevelopmentMode.md +15 -0
- package/docs/api/functions/isErr.md +29 -0
- package/docs/api/functions/isOk.md +29 -0
- package/docs/api/functions/isPerformanceMonitoringEnabled.md +17 -0
- package/docs/api/functions/isPermitted.md +58 -0
- package/docs/api/functions/isPermittedCached.md +36 -0
- package/docs/api/functions/isRBACInitialized.md +19 -0
- package/docs/api/functions/isSecureClient.md +38 -0
- package/docs/api/functions/isValidPermission.md +27 -0
- package/docs/api/functions/listFiles.md +29 -0
- package/docs/api/functions/max.md +63 -0
- package/docs/api/functions/min.md +63 -0
- package/docs/api/functions/ok.md +29 -0
- package/docs/api/functions/parseAndNormalizeEventColours.md +105 -0
- package/docs/api/functions/recordAuditEvent.md +23 -0
- package/docs/api/functions/recordPermissionCheck.md +31 -0
- package/docs/api/functions/resetPerformanceMetrics.md +17 -0
- package/docs/api/functions/resolveAppContext.md +27 -0
- package/docs/api/functions/roundToNearestMinutes.md +41 -0
- package/docs/api/functions/sanitizeFormData.md +49 -0
- package/docs/api/functions/sanitizeHtml.md +39 -0
- package/docs/api/functions/sanitizeUserInput.md +27 -0
- package/docs/api/functions/setAppConfig.md +23 -0
- package/docs/api/functions/setGlobalAuditManager.md +25 -0
- package/docs/api/functions/setupRBAC.md +31 -0
- package/docs/api/functions/sum.md +63 -0
- package/docs/api/functions/toZonedTime.md +41 -0
- package/docs/api/functions/uploadFile.md +32 -0
- package/docs/api/functions/useAccessLevel.md +71 -0
- package/docs/api/functions/useAccessibleApps.md +55 -0
- package/docs/api/functions/useAppConfig.md +20 -0
- package/docs/api/functions/useAuthService.md +15 -0
- package/docs/api/functions/useCan.md +99 -0
- package/docs/api/functions/useEventService.md +15 -0
- package/docs/api/functions/useEventTheme.md +26 -0
- package/docs/api/functions/useEvents.md +45 -0
- package/docs/api/functions/useFileReference.md +264 -0
- package/docs/api/functions/useFileReferenceById.md +63 -0
- package/docs/api/functions/useFileReferenceForRecord.md +129 -0
- package/docs/api/functions/useFilesByCategory.md +80 -0
- package/docs/api/functions/useFormDialog.md +62 -0
- package/docs/api/functions/useInactivityService.md +15 -0
- package/docs/api/functions/useInactivityTracker.md +21 -0
- package/docs/api/functions/useIsPublicPage.md +19 -0
- package/docs/api/functions/useMultiplePermissions.md +88 -0
- package/docs/api/functions/useOptionalEvents.md +31 -0
- package/docs/api/functions/useOrganisationPermissions.md +27 -0
- package/docs/api/functions/useOrganisationSecurity.md +15 -0
- package/docs/api/functions/useOrganisationService.md +15 -0
- package/docs/api/functions/useOrganisations.md +48 -0
- package/docs/api/functions/usePermissions.md +130 -0
- package/docs/api/functions/usePublicEvent.md +36 -0
- package/docs/api/functions/usePublicEventCode.md +32 -0
- package/docs/api/functions/usePublicEventLogo.md +48 -0
- package/docs/api/functions/usePublicFileDisplay.md +54 -0
- package/docs/api/functions/usePublicPageContext.md +19 -0
- package/docs/api/functions/usePublicRouteParams.md +31 -0
- package/docs/api/functions/useRBAC.md +21 -0
- package/docs/api/functions/useResolvedScope.md +46 -0
- package/docs/api/functions/useResourcePermissions.md +25 -0
- package/docs/api/functions/useRoleManagement.md +121 -0
- package/docs/api/functions/useSecureSupabase.md +51 -0
- package/docs/api/functions/useSessionRestoration.md +15 -0
- package/docs/api/functions/useSessionTracking.md +62 -0
- package/docs/api/functions/useToast.md +83 -0
- package/docs/api/functions/useUnifiedAuth.md +24 -0
- package/docs/api/functions/useZodForm.md +27 -0
- package/docs/api/functions/validateFileSize.md +31 -0
- package/docs/api/functions/warnIfInsecureClient.md +40 -0
- package/docs/api/functions/withAccessLevelGuard.md +67 -0
- package/docs/api/functions/withPermissionGuard.md +73 -0
- package/docs/api/functions/withRoleGuard.md +86 -0
- package/docs/api/globals.md +502 -0
- package/docs/api/interfaces/AccessDeniedProps.md +87 -0
- package/docs/api/interfaces/AccessibleApp.md +41 -0
- package/docs/api/interfaces/AddressFieldProps.md +195 -0
- package/docs/api/interfaces/AddressFieldRef.md +67 -0
- package/docs/api/interfaces/AggregateConfig.md +35 -0
- package/docs/api/interfaces/AppSwitcherProps.md +51 -0
- package/docs/api/interfaces/AuthSessionData.md +27 -0
- package/docs/api/interfaces/AutocompleteOptions.md +61 -0
- package/docs/api/interfaces/AvatarProps.md +97 -0
- package/docs/api/interfaces/BadgeProps.md +30 -0
- package/docs/api/interfaces/BuildAppUrlOptions.md +41 -0
- package/docs/api/interfaces/ButtonProps.md +46 -0
- package/docs/api/interfaces/CalendarProps.md +60 -0
- package/docs/api/interfaces/CardProps.md +56 -0
- package/docs/api/interfaces/ColorPalette.md +13 -0
- package/docs/api/interfaces/ColorShade.md +58 -0
- package/docs/api/interfaces/ContextSelectorProps.md +131 -0
- package/docs/api/interfaces/DataRecord.md +16 -0
- package/docs/api/interfaces/DataTableAction.md +198 -0
- package/docs/api/interfaces/DataTableColumn.md +422 -0
- package/docs/api/interfaces/DataTableProps.md +511 -0
- package/docs/api/interfaces/DataTableToolbarButton.md +75 -0
- package/docs/api/interfaces/DatePickerWithTimezoneProps.md +75 -0
- package/docs/api/interfaces/DialogBodyProps.md +55 -0
- package/docs/api/interfaces/DialogCloseProps.md +25 -0
- package/docs/api/interfaces/DialogContentProps.md +160 -0
- package/docs/api/interfaces/DialogFooterProps.md +25 -0
- package/docs/api/interfaces/DialogHeaderProps.md +25 -0
- package/docs/api/interfaces/DialogPortalProps.md +19 -0
- package/docs/api/interfaces/DialogProps.md +53 -0
- package/docs/api/interfaces/DialogTriggerProps.md +53 -0
- package/docs/api/interfaces/EmptyStateConfig.md +55 -0
- package/docs/api/interfaces/ErrorBoundaryProps.md +131 -0
- package/docs/api/interfaces/ErrorBoundaryProviderProps.md +31 -0
- package/docs/api/interfaces/ErrorBoundaryState.md +61 -0
- package/docs/api/interfaces/EventAppRoleData.md +54 -0
- package/docs/api/interfaces/ExportColumn.md +69 -0
- package/docs/api/interfaces/ExportOptions.md +109 -0
- package/docs/api/interfaces/FileDisplayProps.md +192 -0
- package/docs/api/interfaces/FileMetadata.md +97 -0
- package/docs/api/interfaces/FileReference.md +89 -0
- package/docs/api/interfaces/FileSizeLimits.md +13 -0
- package/docs/api/interfaces/FileUploadOptions.md +107 -0
- package/docs/api/interfaces/FooterProps.md +37 -0
- package/docs/api/interfaces/FormFieldProps.md +171 -0
- package/docs/api/interfaces/FormProps.md +93 -0
- package/docs/api/interfaces/GrantEventAppRoleParams.md +97 -0
- package/docs/api/interfaces/ImportSummary.md +49 -0
- package/docs/api/interfaces/InactivityWarningModalProps.md +87 -0
- package/docs/api/interfaces/InputProps.md +46 -0
- package/docs/api/interfaces/InvalidScopeError.md +37 -0
- package/docs/api/interfaces/LabelProps.md +85 -0
- package/docs/api/interfaces/LoggerConfig.md +51 -0
- package/docs/api/interfaces/LoginFormProps.md +146 -0
- package/docs/api/interfaces/MissingUserContextError.md +37 -0
- package/docs/api/interfaces/NavigationGuardProps.md +109 -0
- package/docs/api/interfaces/NavigationItem.md +91 -0
- package/docs/api/interfaces/NavigationMenuProps.md +169 -0
- package/docs/api/interfaces/Organisation.md +105 -0
- package/docs/api/interfaces/OrganisationContextRequiredError.md +37 -0
- package/docs/api/interfaces/OrganisationMembership.md +105 -0
- package/docs/api/interfaces/OrganisationSecurityError.md +49 -0
- package/docs/api/interfaces/PaceAppLayoutPermissionConfig.md +127 -0
- package/docs/api/interfaces/PaceAppLayoutRouteConfigItem.md +91 -0
- package/docs/api/interfaces/PaceAppLayoutRoutingConfig.md +79 -0
- package/docs/api/interfaces/PaceLoginPageProps.md +41 -0
- package/docs/api/interfaces/PagePermissionGuardProps.md +143 -0
- package/docs/api/interfaces/PaletteData.md +33 -0
- package/docs/api/interfaces/ParsedAddress.md +91 -0
- package/docs/api/interfaces/PermissionDeniedError.md +37 -0
- package/docs/api/interfaces/ProgressProps.md +35 -0
- package/docs/api/interfaces/ProtectedRouteProps.md +67 -0
- package/docs/api/interfaces/PublicPageFooterProps.md +97 -0
- package/docs/api/interfaces/PublicPageHeaderProps.md +99 -0
- package/docs/api/interfaces/PublicPageLayoutProps.md +153 -0
- package/docs/api/interfaces/RBACAccessValidateParams.md +41 -0
- package/docs/api/interfaces/RBACAccessValidateResult.md +33 -0
- package/docs/api/interfaces/RBACAuditLogParams.md +65 -0
- package/docs/api/interfaces/RBACAuditLogResult.md +41 -0
- package/docs/api/interfaces/RBACContext.md +41 -0
- package/docs/api/interfaces/RBACError.md +37 -0
- package/docs/api/interfaces/RBACLogger.md +97 -0
- package/docs/api/interfaces/RBACNotInitializedError.md +37 -0
- package/docs/api/interfaces/RBACPageAccessCheckParams.md +57 -0
- package/docs/api/interfaces/RBACPerformanceMetrics.md +109 -0
- package/docs/api/interfaces/RBACPermissionCheckParams.md +57 -0
- package/docs/api/interfaces/RBACPermissionCheckResult.md +41 -0
- package/docs/api/interfaces/RBACPermissionsGetParams.md +49 -0
- package/docs/api/interfaces/RBACPermissionsGetResult.md +49 -0
- package/docs/api/interfaces/RBACResult.md +47 -0
- package/docs/api/interfaces/RBACRoleGrantParams.md +49 -0
- package/docs/api/interfaces/RBACRoleGrantResult.md +41 -0
- package/docs/api/interfaces/RBACRoleRevokeParams.md +49 -0
- package/docs/api/interfaces/RBACRoleRevokeResult.md +41 -0
- package/docs/api/interfaces/RBACRoleValidateParams.md +41 -0
- package/docs/api/interfaces/RBACRoleValidateResult.md +49 -0
- package/docs/api/interfaces/RBACRolesListParams.md +41 -0
- package/docs/api/interfaces/RBACRolesListResult.md +57 -0
- package/docs/api/interfaces/RBACSessionTrackParams.md +57 -0
- package/docs/api/interfaces/RBACSessionTrackResult.md +41 -0
- package/docs/api/interfaces/ResourcePermissions.md +119 -0
- package/docs/api/interfaces/RevokeEventAppRoleParams.md +81 -0
- package/docs/api/interfaces/RoleManagementResult.md +41 -0
- package/docs/api/interfaces/SessionRestorationLoaderProps.md +29 -0
- package/docs/api/interfaces/StorageConfig.md +33 -0
- package/docs/api/interfaces/StorageFileInfo.md +57 -0
- package/docs/api/interfaces/StorageFileMetadata.md +113 -0
- package/docs/api/interfaces/StorageListOptions.md +79 -0
- package/docs/api/interfaces/StorageListResult.md +33 -0
- package/docs/api/interfaces/StorageUploadOptions.md +81 -0
- package/docs/api/interfaces/StorageUploadResult.md +49 -0
- package/docs/api/interfaces/StorageUploadSuccess.md +35 -0
- package/docs/api/interfaces/StorageUrlOptions.md +49 -0
- package/docs/api/interfaces/StyleImport.md +17 -0
- package/docs/api/interfaces/SwitchProps.md +30 -0
- package/docs/api/interfaces/TabsContentProps.md +13 -0
- package/docs/api/interfaces/TabsListProps.md +13 -0
- package/docs/api/interfaces/TabsProps.md +13 -0
- package/docs/api/interfaces/TabsTriggerProps.md +41 -0
- package/docs/api/interfaces/TextareaProps.md +43 -0
- package/docs/api/interfaces/ToastActionElement.md +16 -0
- package/docs/api/interfaces/ToastProps.md +13 -0
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +129 -0
- package/docs/api/interfaces/UseAccessibleAppsReturn.md +55 -0
- package/docs/api/interfaces/UseFormDialogOptions.md +49 -0
- package/docs/api/interfaces/UseFormDialogReturn.md +95 -0
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +103 -0
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +91 -0
- package/docs/api/interfaces/UsePublicEventLogoOptions.md +69 -0
- package/docs/api/interfaces/UsePublicEventLogoReturn.md +66 -0
- package/docs/api/interfaces/UsePublicEventOptions.md +29 -0
- package/docs/api/interfaces/UsePublicEventReturn.md +56 -0
- package/docs/api/interfaces/UsePublicFileDisplayOptions.md +39 -0
- package/docs/api/interfaces/UsePublicFileDisplayReturn.md +96 -0
- package/docs/api/interfaces/UsePublicRouteParamsReturn.md +76 -0
- package/docs/api/interfaces/UseResolvedScopeOptions.md +49 -0
- package/docs/api/interfaces/UseResolvedScopeReturn.md +39 -0
- package/docs/api/interfaces/UseResourcePermissionsOptions.md +29 -0
- package/docs/api/interfaces/UserEventAccess.md +92 -0
- package/docs/api/interfaces/UserMenuProps.md +69 -0
- package/docs/api/interfaces/UserProfile.md +49 -0
- package/docs/api/type-aliases/AccessLevel.md +11 -0
- package/docs/api/type-aliases/AccessLevelContext.md +14 -0
- package/docs/api/type-aliases/AllPermissions.md +11 -0
- package/docs/api/type-aliases/ApiError.md +37 -0
- package/docs/api/type-aliases/ApiResult.md +19 -0
- package/docs/api/type-aliases/AuditEventType.md +11 -0
- package/docs/api/type-aliases/BadgeVariant.md +18 -0
- package/docs/api/type-aliases/DataTableFeatureConfig.md +14 -0
- package/docs/api/type-aliases/DialogSize.md +13 -0
- package/docs/api/type-aliases/EventAppRole.md +11 -0
- package/docs/api/type-aliases/FileUploadProps.md +15 -0
- package/docs/api/type-aliases/GetRowId.md +33 -0
- package/docs/api/type-aliases/GlobalErrorHandler.md +35 -0
- package/docs/api/type-aliases/GlobalRole.md +11 -0
- package/docs/api/type-aliases/ImportHandlerResult.md +13 -0
- package/docs/api/type-aliases/NavigationMode.md +13 -0
- package/docs/api/type-aliases/Operation.md +11 -0
- package/docs/api/type-aliases/OrganisationContextType.md +13 -0
- package/docs/api/type-aliases/OrganisationRole.md +11 -0
- package/docs/api/type-aliases/PaceAppLayoutProps.md +14 -0
- package/docs/api/type-aliases/Permission.md +11 -0
- package/docs/api/type-aliases/PermissionCheck.md +46 -0
- package/docs/api/type-aliases/PermissionMap.md +11 -0
- package/docs/api/type-aliases/PermissionSource.md +13 -0
- package/docs/api/type-aliases/RBACConfig.md +13 -0
- package/docs/api/type-aliases/RBACFunctionResponse.md +57 -0
- package/docs/api/type-aliases/Scope.md +41 -0
- package/docs/api/type-aliases/SessionType.md +11 -0
- package/docs/api/type-aliases/UUID.md +11 -0
- package/docs/api/type-aliases/UnifiedAuthContextType.md +13 -0
- package/docs/api/type-aliases/UseFileReferenceForRecordReturn.md +161 -0
- package/docs/api/type-aliases/UseFileReferenceOptions.md +35 -0
- package/docs/api/type-aliases/UseFileReferenceReturn.md +13 -0
- package/docs/api/variables/ALL_PERMISSIONS.md +281 -0
- package/docs/api/variables/APP_PATH_MAPPING.md +14 -0
- package/docs/api/variables/AddressField.md +41 -0
- package/docs/api/variables/Alert.md +11 -0
- package/docs/api/variables/AlertDescription.md +11 -0
- package/docs/api/variables/AlertTitle.md +11 -0
- package/docs/api/variables/Avatar.md +13 -0
- package/docs/api/variables/Button.md +31 -0
- package/docs/api/variables/CACHE_PATTERNS.md +89 -0
- package/docs/api/variables/Calendar.md +74 -0
- package/docs/api/variables/Card.md +11 -0
- package/docs/api/variables/CardActions.md +11 -0
- package/docs/api/variables/CardContent.md +11 -0
- package/docs/api/variables/CardDescription.md +11 -0
- package/docs/api/variables/CardFooter.md +11 -0
- package/docs/api/variables/CardHeader.md +11 -0
- package/docs/api/variables/CardTitle.md +11 -0
- package/docs/api/variables/Checkbox.md +11 -0
- package/docs/api/variables/DEFAULT_APP_PORT_MAP.md +14 -0
- package/docs/api/variables/DEFAULT_FILE_SIZE_LIMIT.md +13 -0
- package/docs/api/variables/Dialog.md +14 -0
- package/docs/api/variables/DialogClose.md +14 -0
- package/docs/api/variables/DialogContent.md +28 -0
- package/docs/api/variables/DialogDescription.md +14 -0
- package/docs/api/variables/DialogPortal.md +14 -0
- package/docs/api/variables/DialogTitle.md +14 -0
- package/docs/api/variables/DialogTrigger.md +14 -0
- package/docs/api/variables/EVENT_APP_PERMISSIONS.md +109 -0
- package/docs/api/variables/ErrorBoundary.md +15 -0
- package/docs/api/variables/FILE_SIZE_LIMITS.md +13 -0
- package/docs/api/variables/Footer.md +11 -0
- package/docs/api/variables/GLOBAL_PERMISSIONS.md +29 -0
- package/docs/api/variables/Label.md +34 -0
- package/docs/api/variables/LoadingSpinner.md +28 -0
- package/docs/api/variables/LoginForm.md +34 -0
- package/docs/api/variables/NavigationMenu.md +203 -0
- package/docs/api/variables/ORGANISATION_PERMISSIONS.md +89 -0
- package/docs/api/variables/PAGE_PERMISSIONS.md +93 -0
- package/docs/api/variables/PaceLoginPage.md +40 -0
- package/docs/api/variables/PagePermissionGuard.md +11 -0
- package/docs/api/variables/Progress.md +32 -0
- package/docs/api/variables/SECURE_CLIENT_SYMBOL.md +14 -0
- package/docs/api/variables/STORAGE_CONFIG.md +13 -0
- package/docs/api/variables/Select.md +26 -0
- package/docs/api/variables/SelectContent.md +26 -0
- package/docs/api/variables/SelectGroup.md +26 -0
- package/docs/api/variables/SelectItem.md +26 -0
- package/docs/api/variables/SelectLabel.md +26 -0
- package/docs/api/variables/SelectSeparator.md +26 -0
- package/docs/api/variables/SelectTrigger.md +26 -0
- package/docs/api/variables/SelectValue.md +26 -0
- package/docs/api/variables/SessionRestorationLoader.md +11 -0
- package/docs/api/variables/Switch.md +23 -0
- package/docs/api/variables/Table.md +35 -0
- package/docs/api/variables/TableBody.md +11 -0
- package/docs/api/variables/TableCaption.md +11 -0
- package/docs/api/variables/TableCell.md +11 -0
- package/docs/api/variables/TableFooter.md +11 -0
- package/docs/api/variables/TableHead.md +11 -0
- package/docs/api/variables/TableHeader.md +11 -0
- package/docs/api/variables/TableRow.md +11 -0
- package/docs/api/variables/Tabs.md +25 -0
- package/docs/api/variables/TabsContent.md +24 -0
- package/docs/api/variables/TabsList.md +25 -0
- package/docs/api/variables/TabsTrigger.md +34 -0
- package/docs/api/variables/Toast.md +36 -0
- package/docs/api/variables/ToastAction.md +32 -0
- package/docs/api/variables/ToastClose.md +32 -0
- package/docs/api/variables/ToastDescription.md +32 -0
- package/docs/api/variables/ToastProvider.md +11 -0
- package/docs/api/variables/ToastTitle.md +32 -0
- package/docs/api/variables/ToastViewport.md +26 -0
- package/docs/api/variables/Tooltip.md +34 -0
- package/docs/api/variables/TooltipContent.md +34 -0
- package/docs/api/variables/TooltipProvider.md +11 -0
- package/docs/api/variables/TooltipRoot.md +11 -0
- package/docs/api/variables/TooltipTrigger.md +11 -0
- package/docs/api/variables/UserMenu.md +11 -0
- package/docs/api/variables/emailSchema.md +13 -0
- package/docs/api/variables/logger.md +203 -0
- package/docs/api/variables/nameSchema.md +13 -0
- package/docs/api/variables/passwordSchema.md +13 -0
- package/docs/api/variables/phoneSchema.md +13 -0
- package/docs/api/variables/rbacCache.md +16 -0
- package/docs/api/variables/styleConfig.md +25 -0
- package/docs/api/variables/urlSchema.md +13 -0
- package/docs/api-reference/hooks.md +2 -0
- package/docs/implementation-guides/data-tables.md +8 -0
- package/docs/rbac/getting-started.md +7 -0
- package/docs/rbac/troubleshooting.md +5 -1
- package/package.json +3 -3
- package/src/components/DataTable/hooks/useDataTableEffectiveActions.ts +29 -19
- package/src/components/DataTable/hooks/useDataTableScope.test.ts +5 -13
- package/src/components/DataTable/hooks/useDataTableScope.ts +16 -14
- package/src/components/Dialog/useDialogLifecycle.test.ts +4 -1
- package/src/components/FileDisplay/useFileDisplay.unit.test.ts +12 -8
- package/src/components/PaceAppLayout/PaceAppLayout.edge-cases.test.tsx +33 -9
- package/src/components/PaceAppLayout/useFilteredNavItems.ts +22 -7
- package/src/components/PaceAppLayout/usePaceAppLayoutConfig.ts +44 -23
- package/src/components/PaceAppLayout/usePaceAppLayoutPermissions.ts +1 -1
- package/src/components/PaceAppLayout/usePaceAppLayoutScope.ts +6 -4
- package/src/components/PaceAppLayout/useRoleBasedRouteAccess.ts +2 -2
- package/src/hooks/useAppConfig.unit.test.ts +74 -66
- package/src/hooks/useComponentPerformance.unit.test.tsx +6 -4
- package/src/hooks/useFileUrl.unit.test.ts +1 -3
- package/src/hooks/useInactivityTracker.unit.test.ts +6 -2
- package/src/hooks/usePerformanceMonitor.unit.test.ts +6 -16
- package/src/hooks/usePublicEvent.simple.test.ts +32 -47
- package/src/hooks/usePublicEvent.test.ts +9 -15
- package/src/providers/services/AuthServiceProvider.test.tsx +10 -5
- package/src/providers/services/EventServiceProvider.test.tsx +8 -3
- package/src/providers/services/InactivityServiceProvider.test.tsx +8 -3
- package/src/providers/services/OrganisationServiceProvider.test.tsx +8 -3
- package/src/rbac/README.md +7 -5
- package/src/rbac/api.test.ts +113 -56
- package/src/rbac/api.ts +80 -10
- package/src/rbac/components/NavigationGuard.tsx +2 -1
- package/src/rbac/components/PagePermissionGuard.test.tsx +23 -10
- package/src/rbac/engine.ts +23 -1
- package/src/rbac/hooks/permissions/runPermissionCheck.ts +18 -4
- package/src/rbac/hooks/permissions/useCan.test.ts +59 -20
- package/src/rbac/hooks/permissions/useCan.ts +7 -3
- package/src/rbac/hooks/permissions/useMultiplePermissions.ts +18 -9
- package/src/rbac/hooks/useCan.test.ts +2 -3
- package/src/rbac/hooks/usePageGuardScope.ts +6 -4
- package/src/rbac/hooks/usePagePermissionCheck.ts +4 -4
- package/src/rbac/hooks/useResolvedScope.ts +16 -10
- package/src/rbac/hooks/useResourcePermissions.test.ts +48 -58
- package/src/rbac/hooks/useResourcePermissions.ts +11 -20
- package/src/rbac/types.ts +3 -0
- package/src/services/AuthService.edge-cases.test.ts +2 -2
- package/src/services/EventService.ts +9 -4
- package/src/utils/file-reference/file-reference.test.ts +25 -14
- package/src/utils/supabase/createBaseClient.test.ts +30 -13
- package/docs/api/modules.md +0 -10028
|
@@ -365,7 +365,7 @@ describe('useResourcePermissions Hook', () => {
|
|
|
365
365
|
);
|
|
366
366
|
});
|
|
367
367
|
|
|
368
|
-
it('
|
|
368
|
+
it('passes null scope to useCan when resolvedScope is null', () => {
|
|
369
369
|
mockUseResolvedScope.mockReturnValue({
|
|
370
370
|
resolvedScope: null,
|
|
371
371
|
isLoading: false,
|
|
@@ -374,15 +374,9 @@ describe('useResourcePermissions Hook', () => {
|
|
|
374
374
|
|
|
375
375
|
renderHook(() => useResourcePermissions('contacts'));
|
|
376
376
|
|
|
377
|
-
const fallbackScope: Scope = {
|
|
378
|
-
organisationId: 'org-123',
|
|
379
|
-
eventId: 'event-123',
|
|
380
|
-
appId: undefined,
|
|
381
|
-
};
|
|
382
|
-
|
|
383
377
|
expect(mockUseCan).toHaveBeenCalledWith(
|
|
384
378
|
expect.any(String),
|
|
385
|
-
|
|
379
|
+
null,
|
|
386
380
|
expect.any(String),
|
|
387
381
|
undefined,
|
|
388
382
|
true,
|
|
@@ -391,7 +385,7 @@ describe('useResourcePermissions Hook', () => {
|
|
|
391
385
|
);
|
|
392
386
|
});
|
|
393
387
|
|
|
394
|
-
it('handles missing organisation
|
|
388
|
+
it('handles missing organisation by passing null scope when resolvedScope is null', () => {
|
|
395
389
|
mockUseOrganisations.mockReturnValue({
|
|
396
390
|
selectedOrganisation: null,
|
|
397
391
|
} as any);
|
|
@@ -404,15 +398,9 @@ describe('useResourcePermissions Hook', () => {
|
|
|
404
398
|
|
|
405
399
|
renderHook(() => useResourcePermissions('contacts'));
|
|
406
400
|
|
|
407
|
-
const fallbackScope: Scope = {
|
|
408
|
-
organisationId: '',
|
|
409
|
-
eventId: 'event-123',
|
|
410
|
-
appId: undefined,
|
|
411
|
-
};
|
|
412
|
-
|
|
413
401
|
expect(mockUseCan).toHaveBeenCalledWith(
|
|
414
402
|
expect.any(String),
|
|
415
|
-
|
|
403
|
+
null,
|
|
416
404
|
expect.any(String),
|
|
417
405
|
undefined,
|
|
418
406
|
true,
|
|
@@ -421,7 +409,7 @@ describe('useResourcePermissions Hook', () => {
|
|
|
421
409
|
);
|
|
422
410
|
});
|
|
423
411
|
|
|
424
|
-
it('handles missing event
|
|
412
|
+
it('handles missing event by passing null scope when resolvedScope is null', () => {
|
|
425
413
|
mockUseEvents.mockReturnValue({
|
|
426
414
|
selectedEvent: null,
|
|
427
415
|
} as any);
|
|
@@ -434,15 +422,38 @@ describe('useResourcePermissions Hook', () => {
|
|
|
434
422
|
|
|
435
423
|
renderHook(() => useResourcePermissions('contacts'));
|
|
436
424
|
|
|
437
|
-
|
|
425
|
+
expect(mockUseCan).toHaveBeenCalledWith(
|
|
426
|
+
expect.any(String),
|
|
427
|
+
null,
|
|
428
|
+
expect.any(String),
|
|
429
|
+
undefined,
|
|
430
|
+
true,
|
|
431
|
+
null,
|
|
432
|
+
undefined
|
|
433
|
+
);
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
it('handles missing event gracefully when resolvedScope is set', () => {
|
|
437
|
+
mockUseEvents.mockReturnValue({
|
|
438
|
+
selectedEvent: null,
|
|
439
|
+
} as any);
|
|
440
|
+
|
|
441
|
+
const scopeWithOrgOnly: Scope = {
|
|
438
442
|
organisationId: 'org-123',
|
|
439
443
|
eventId: undefined,
|
|
440
444
|
appId: undefined,
|
|
441
445
|
};
|
|
446
|
+
mockUseResolvedScope.mockReturnValue({
|
|
447
|
+
resolvedScope: scopeWithOrgOnly,
|
|
448
|
+
isLoading: false,
|
|
449
|
+
error: null,
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
renderHook(() => useResourcePermissions('contacts'));
|
|
442
453
|
|
|
443
454
|
expect(mockUseCan).toHaveBeenCalledWith(
|
|
444
455
|
expect.any(String),
|
|
445
|
-
|
|
456
|
+
scopeWithOrgOnly,
|
|
446
457
|
expect.any(String),
|
|
447
458
|
undefined,
|
|
448
459
|
true,
|
|
@@ -877,19 +888,12 @@ describe('useResourcePermissions Hook', () => {
|
|
|
877
888
|
|
|
878
889
|
renderHook(() => useResourcePermissions('planning'));
|
|
879
890
|
|
|
880
|
-
//
|
|
881
|
-
// because resolvedScope is null, so hasAppId is false
|
|
882
|
-
const fallbackScope: Scope = {
|
|
883
|
-
organisationId: 'org-123',
|
|
884
|
-
eventId: 'event-123',
|
|
885
|
-
appId: undefined,
|
|
886
|
-
};
|
|
887
|
-
|
|
891
|
+
// When resolvedScope is null we pass null to useCan (no fallback)
|
|
888
892
|
expect(mockUseCan).toHaveBeenCalledWith(
|
|
889
893
|
'user-123',
|
|
890
|
-
|
|
891
|
-
'create:planning',
|
|
892
|
-
undefined,
|
|
894
|
+
null,
|
|
895
|
+
'create:planning',
|
|
896
|
+
undefined,
|
|
893
897
|
true,
|
|
894
898
|
null,
|
|
895
899
|
undefined
|
|
@@ -1348,17 +1352,11 @@ describe('useResourcePermissions Hook', () => {
|
|
|
1348
1352
|
|
|
1349
1353
|
it('handles scope transition from resolved to null', async () => {
|
|
1350
1354
|
mockIsSuperAdmin.mockResolvedValue(false);
|
|
1351
|
-
mockUseResolvedScope
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
})
|
|
1357
|
-
.mockReturnValueOnce({
|
|
1358
|
-
resolvedScope: null,
|
|
1359
|
-
isLoading: false,
|
|
1360
|
-
error: null,
|
|
1361
|
-
});
|
|
1355
|
+
mockUseResolvedScope.mockReturnValue({
|
|
1356
|
+
resolvedScope: mockScope,
|
|
1357
|
+
isLoading: false,
|
|
1358
|
+
error: null,
|
|
1359
|
+
});
|
|
1362
1360
|
mockUseCan.mockReturnValue({
|
|
1363
1361
|
can: false,
|
|
1364
1362
|
isLoading: false,
|
|
@@ -1370,27 +1368,19 @@ describe('useResourcePermissions Hook', () => {
|
|
|
1370
1368
|
|
|
1371
1369
|
await waitFor(() => {
|
|
1372
1370
|
expect(result.current.isLoading).toBe(false);
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
expect(result.current.scope.eventId).toBe(mockScope.eventId);
|
|
1376
|
-
// appId may be undefined in fallback scope, so only check if it exists in mockScope
|
|
1377
|
-
// The hook may use fallback scope even when resolvedScope is provided, so be flexible
|
|
1378
|
-
});
|
|
1371
|
+
expect(result.current.scope).toEqual(mockScope);
|
|
1372
|
+
}, { timeout: 3000 });
|
|
1379
1373
|
|
|
1380
|
-
//
|
|
1374
|
+
// Switch to null scope
|
|
1375
|
+
mockUseResolvedScope.mockReturnValue({
|
|
1376
|
+
resolvedScope: null,
|
|
1377
|
+
isLoading: false,
|
|
1378
|
+
error: null,
|
|
1379
|
+
});
|
|
1381
1380
|
rerender();
|
|
1382
1381
|
|
|
1383
1382
|
await waitFor(() => {
|
|
1384
|
-
|
|
1385
|
-
// Scope falls back to selectedOrganisation/selectedEvent when resolvedScope is null
|
|
1386
|
-
expect(result.current).toBeDefined();
|
|
1387
|
-
expect(result.current.scope).toBeDefined();
|
|
1388
|
-
// Scope should have organisationId from selectedOrganisation fallback
|
|
1389
|
-
// The fallback scope has different structure (appId: undefined vs 'app-123'), so just check orgId and eventId
|
|
1390
|
-
expect(result.current.scope.organisationId).toBe('org-123');
|
|
1391
|
-
expect(result.current.scope.eventId).toBe('event-123');
|
|
1392
|
-
// appId may be undefined in fallback scope, but the hook might still have the previous appId
|
|
1393
|
-
// So just verify the scope is defined and has the expected orgId and eventId
|
|
1383
|
+
expect(result.current.scope).toBeNull();
|
|
1394
1384
|
}, { timeout: 3000 });
|
|
1395
1385
|
});
|
|
1396
1386
|
|
|
@@ -66,8 +66,8 @@ export interface ResourcePermissions {
|
|
|
66
66
|
canDelete: (resource: string) => boolean;
|
|
67
67
|
/** Check if user can read resources of this type */
|
|
68
68
|
canRead: (resource: string) => boolean;
|
|
69
|
-
/** The resolved scope object (for advanced use cases) */
|
|
70
|
-
scope: Scope;
|
|
69
|
+
/** The resolved scope object (for advanced use cases); null when not yet resolved. */
|
|
70
|
+
scope: Scope | null;
|
|
71
71
|
/** Whether any permission check is currently loading */
|
|
72
72
|
isLoading: boolean;
|
|
73
73
|
/** Error from any permission check or scope resolution */
|
|
@@ -147,7 +147,7 @@ function buildResourcePermissions(params: {
|
|
|
147
147
|
canUpdateResult: boolean;
|
|
148
148
|
canDeleteResult: boolean;
|
|
149
149
|
canReadResult: boolean;
|
|
150
|
-
scope: Scope;
|
|
150
|
+
scope: Scope | null;
|
|
151
151
|
isLoading: boolean;
|
|
152
152
|
error: Error | null;
|
|
153
153
|
}): ResourcePermissions {
|
|
@@ -203,17 +203,8 @@ export function useResourcePermissions(
|
|
|
203
203
|
selectedEventOrganisationId: selectedEvent?.organisation_id || null
|
|
204
204
|
});
|
|
205
205
|
|
|
206
|
-
//
|
|
207
|
-
|
|
208
|
-
// If resolvedScope is null (still loading), we can't determine if we should use page permissions
|
|
209
|
-
// so we must wait for scope resolution to complete
|
|
210
|
-
const scope: Scope = useMemo(() => {
|
|
211
|
-
return resolvedScope || {
|
|
212
|
-
organisationId: selectedOrganisation?.id || '',
|
|
213
|
-
eventId: selectedEvent?.event_id || undefined,
|
|
214
|
-
appId: undefined
|
|
215
|
-
};
|
|
216
|
-
}, [resolvedScope, selectedOrganisation?.id, selectedEvent?.event_id]);
|
|
206
|
+
// Pass only resolvedScope to useCan — null when not ready; no fallback (avoids invalid_input).
|
|
207
|
+
const scopeForPermissionCheck: Scope | null = resolvedScope;
|
|
217
208
|
|
|
218
209
|
// CRITICAL FIX: Only use page permissions when appId is actually available in resolvedScope
|
|
219
210
|
// If scope is still loading (resolvedScope is null), we can't know if appId will be available
|
|
@@ -240,7 +231,7 @@ export function useResourcePermissions(
|
|
|
240
231
|
// But we must ensure permission strings are correct before calling useCan
|
|
241
232
|
const { can: canCreateResult, isLoading: createLoading, error: createError } = useCan(
|
|
242
233
|
user?.id || '',
|
|
243
|
-
|
|
234
|
+
scopeForPermissionCheck,
|
|
244
235
|
createPermission as Permission,
|
|
245
236
|
pageId, // Pass resource name as pageId when appId is available to enable page permission checks
|
|
246
237
|
true, // useCache
|
|
@@ -250,7 +241,7 @@ export function useResourcePermissions(
|
|
|
250
241
|
|
|
251
242
|
const { can: canUpdateResult, isLoading: updateLoading, error: updateError } = useCan(
|
|
252
243
|
user?.id || '',
|
|
253
|
-
|
|
244
|
+
scopeForPermissionCheck,
|
|
254
245
|
updatePermission as Permission,
|
|
255
246
|
pageId, // Pass resource name as pageId when appId is available to enable page permission checks
|
|
256
247
|
true, // useCache
|
|
@@ -260,7 +251,7 @@ export function useResourcePermissions(
|
|
|
260
251
|
|
|
261
252
|
const { can: canDeleteResult, isLoading: deleteLoading, error: deleteError } = useCan(
|
|
262
253
|
user?.id || '',
|
|
263
|
-
|
|
254
|
+
scopeForPermissionCheck,
|
|
264
255
|
deletePermission as Permission,
|
|
265
256
|
pageId, // Pass resource name as pageId when appId is available to enable page permission checks
|
|
266
257
|
true, // useCache
|
|
@@ -271,7 +262,7 @@ export function useResourcePermissions(
|
|
|
271
262
|
// Optional read permission check
|
|
272
263
|
const { can: canReadResult, isLoading: readLoading, error: readError } = useCan(
|
|
273
264
|
user?.id || '',
|
|
274
|
-
|
|
265
|
+
scopeForPermissionCheck,
|
|
275
266
|
readPermission as Permission,
|
|
276
267
|
pageId, // Pass resource name as pageId when appId is available to enable page permission checks
|
|
277
268
|
true, // useCache
|
|
@@ -313,7 +304,7 @@ export function useResourcePermissions(
|
|
|
313
304
|
canUpdateResult,
|
|
314
305
|
canDeleteResult,
|
|
315
306
|
canReadResult,
|
|
316
|
-
scope,
|
|
307
|
+
scope: scopeForPermissionCheck,
|
|
317
308
|
isLoading,
|
|
318
309
|
error,
|
|
319
310
|
}),
|
|
@@ -326,7 +317,7 @@ export function useResourcePermissions(
|
|
|
326
317
|
canUpdateResult,
|
|
327
318
|
canDeleteResult,
|
|
328
319
|
canReadResult,
|
|
329
|
-
|
|
320
|
+
scopeForPermissionCheck,
|
|
330
321
|
isLoading,
|
|
331
322
|
error,
|
|
332
323
|
]
|
package/src/rbac/types.ts
CHANGED
|
@@ -31,6 +31,9 @@ export type AccessLevel =
|
|
|
31
31
|
/**
|
|
32
32
|
* Scope defines the context for permission checks.
|
|
33
33
|
* Can include organisation, event, and/or app identifiers.
|
|
34
|
+
*
|
|
35
|
+
* Convention: For permission-check APIs (e.g. useCan, useMultiplePermissions), pass Scope | null.
|
|
36
|
+
* null means scope not yet resolved — the hook stays in loading and does not call the RPC.
|
|
34
37
|
*/
|
|
35
38
|
export type Scope = {
|
|
36
39
|
organisationId?: UUID;
|
|
@@ -579,7 +579,7 @@ describe('AuthService Edge Cases and Complex Scenarios', () => {
|
|
|
579
579
|
expect(authService.isAuthenticated()).toBe(false);
|
|
580
580
|
});
|
|
581
581
|
|
|
582
|
-
it('handles sign out during session restoration', async () => {
|
|
582
|
+
it('handles sign out during session restoration', { timeout: 15000 }, async () => {
|
|
583
583
|
vi.useFakeTimers();
|
|
584
584
|
|
|
585
585
|
mockSupabase.auth.getSession.mockImplementation(() => {
|
|
@@ -606,7 +606,7 @@ describe('AuthService Edge Cases and Complex Scenarios', () => {
|
|
|
606
606
|
expect(authService.isAuthenticated()).toBe(false);
|
|
607
607
|
|
|
608
608
|
vi.useRealTimers();
|
|
609
|
-
}
|
|
609
|
+
});
|
|
610
610
|
|
|
611
611
|
it('handles refreshSession with invalid session data', async () => {
|
|
612
612
|
mockSupabase.auth.refreshSession.mockResolvedValue({
|
|
@@ -228,10 +228,15 @@ export class EventService extends BaseService implements IEventService {
|
|
|
228
228
|
// Event methods
|
|
229
229
|
setSelectedEvent(event: Event | null): void {
|
|
230
230
|
if (event) {
|
|
231
|
-
//
|
|
232
|
-
//
|
|
233
|
-
|
|
234
|
-
|
|
231
|
+
// Ensure organisation_id is set when we have selectedOrganisation, so scope resolution
|
|
232
|
+
// (useResolvedScope / useDataTableScope) gets org early and permission checks succeed.
|
|
233
|
+
const orgId = (event as { organisation_id?: string | null }).organisation_id;
|
|
234
|
+
const missingOrg = !orgId || (typeof orgId === 'string' && orgId.trim() === '');
|
|
235
|
+
const eventToStore: Event =
|
|
236
|
+
missingOrg && this.selectedOrganisation?.id
|
|
237
|
+
? ({ ...event, organisation_id: this.selectedOrganisation.id } as Event)
|
|
238
|
+
: event;
|
|
239
|
+
this.selectedEvent = eventToStore;
|
|
235
240
|
this.setSelectedEventId?.(event.event_id);
|
|
236
241
|
// Persist asynchronously (don't await to avoid blocking)
|
|
237
242
|
this.persistEventSelection(event.event_id).catch(error => {
|
|
@@ -675,15 +675,20 @@ describe('[service] FileReferenceServiceImpl', () => {
|
|
|
675
675
|
tags: ['updated']
|
|
676
676
|
}
|
|
677
677
|
};
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
678
|
+
|
|
679
|
+
const updateChain = {
|
|
680
|
+
update: vi.fn().mockReturnThis(),
|
|
681
|
+
eq: vi.fn().mockReturnThis(),
|
|
682
|
+
select: vi.fn().mockReturnThis(),
|
|
683
|
+
single: vi.fn().mockResolvedValue({
|
|
684
|
+
data: { ...mockFileReference, ...updates },
|
|
685
|
+
error: null
|
|
686
|
+
})
|
|
687
|
+
};
|
|
688
|
+
(mockSupabase.from as any).mockReturnValue(updateChain);
|
|
689
|
+
|
|
685
690
|
const result = await service.updateFileReference('file-ref-123', updates);
|
|
686
|
-
|
|
691
|
+
|
|
687
692
|
expect(expectOk(result)).toEqual(expect.objectContaining(updates));
|
|
688
693
|
});
|
|
689
694
|
|
|
@@ -1036,12 +1041,18 @@ describe('[service] FileReferenceServiceImpl', () => {
|
|
|
1036
1041
|
|
|
1037
1042
|
it('handles updateFileReference errors', async () => {
|
|
1038
1043
|
const updates = { file_metadata: { tags: ['updated'] } };
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1044
|
+
|
|
1045
|
+
const updateChain = {
|
|
1046
|
+
update: vi.fn().mockReturnThis(),
|
|
1047
|
+
eq: vi.fn().mockReturnThis(),
|
|
1048
|
+
select: vi.fn().mockReturnThis(),
|
|
1049
|
+
single: vi.fn().mockResolvedValue({
|
|
1050
|
+
data: null,
|
|
1051
|
+
error: { message: 'Update failed', code: 'ERR' }
|
|
1052
|
+
})
|
|
1053
|
+
};
|
|
1054
|
+
(mockSupabase.from as any).mockReturnValue(updateChain);
|
|
1055
|
+
|
|
1045
1056
|
const result = await service.updateFileReference('file-ref-123', updates);
|
|
1046
1057
|
expect(result.ok).toBe(false);
|
|
1047
1058
|
if (!result.ok) expect(result.error.message).toContain('Update failed');
|
|
@@ -46,16 +46,21 @@ describe('[unit] createBaseClient', () => {
|
|
|
46
46
|
|
|
47
47
|
beforeEach(() => {
|
|
48
48
|
vi.clearAllMocks();
|
|
49
|
-
// Set production mode by default to bypass stack check
|
|
50
49
|
process.env.NODE_ENV = 'production';
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
Object.defineProperty(import.meta, 'env', {
|
|
51
|
+
value: { MODE: 'production', PROD: true },
|
|
52
|
+
writable: true,
|
|
53
|
+
configurable: true,
|
|
54
|
+
});
|
|
53
55
|
});
|
|
54
56
|
|
|
55
57
|
afterEach(() => {
|
|
56
58
|
delete process.env.NODE_ENV;
|
|
57
|
-
|
|
58
|
-
|
|
59
|
+
Object.defineProperty(import.meta, 'env', {
|
|
60
|
+
value: {},
|
|
61
|
+
writable: true,
|
|
62
|
+
configurable: true,
|
|
63
|
+
});
|
|
59
64
|
});
|
|
60
65
|
|
|
61
66
|
describe('Client Creation', () => {
|
|
@@ -104,8 +109,11 @@ describe('[unit] createBaseClient', () => {
|
|
|
104
109
|
describe('Context Validation', () => {
|
|
105
110
|
it('allows creation in production mode', () => {
|
|
106
111
|
process.env.NODE_ENV = 'production';
|
|
107
|
-
|
|
108
|
-
|
|
112
|
+
Object.defineProperty(import.meta, 'env', {
|
|
113
|
+
value: { MODE: 'production', PROD: true },
|
|
114
|
+
writable: true,
|
|
115
|
+
configurable: true,
|
|
116
|
+
});
|
|
109
117
|
|
|
110
118
|
expect(() => {
|
|
111
119
|
createBaseClient(mockSupabaseUrl, mockSupabaseKey);
|
|
@@ -114,8 +122,11 @@ describe('[unit] createBaseClient', () => {
|
|
|
114
122
|
|
|
115
123
|
it('allows creation with null stack (production build)', () => {
|
|
116
124
|
process.env.NODE_ENV = 'production';
|
|
117
|
-
|
|
118
|
-
|
|
125
|
+
Object.defineProperty(import.meta, 'env', {
|
|
126
|
+
value: { MODE: 'production', PROD: true },
|
|
127
|
+
writable: true,
|
|
128
|
+
configurable: true,
|
|
129
|
+
});
|
|
119
130
|
|
|
120
131
|
// Mock Error to return null stack
|
|
121
132
|
const originalError = Error;
|
|
@@ -141,8 +152,11 @@ describe('[unit] createBaseClient', () => {
|
|
|
141
152
|
describe('Error Handling', () => {
|
|
142
153
|
it('throws error when called from unauthorized location in development', () => {
|
|
143
154
|
process.env.NODE_ENV = 'development';
|
|
144
|
-
|
|
145
|
-
|
|
155
|
+
Object.defineProperty(import.meta, 'env', {
|
|
156
|
+
value: { MODE: 'development' },
|
|
157
|
+
writable: true,
|
|
158
|
+
configurable: true,
|
|
159
|
+
});
|
|
146
160
|
|
|
147
161
|
// Mock Error to return unauthorized stack
|
|
148
162
|
const originalError = Error;
|
|
@@ -167,8 +181,11 @@ describe('[unit] createBaseClient', () => {
|
|
|
167
181
|
it('logs error to Logger when called from unauthorized location', () => {
|
|
168
182
|
mockLoggerError.mockClear();
|
|
169
183
|
process.env.NODE_ENV = 'development';
|
|
170
|
-
|
|
171
|
-
|
|
184
|
+
Object.defineProperty(import.meta, 'env', {
|
|
185
|
+
value: { MODE: 'development' },
|
|
186
|
+
writable: true,
|
|
187
|
+
configurable: true,
|
|
188
|
+
});
|
|
172
189
|
|
|
173
190
|
// Mock Error to return unauthorized stack
|
|
174
191
|
const originalError = Error;
|