@memberjunction/server 6.2.0-edge.5 → 6.2.0-edge.7
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/README.md +96 -1
- package/dist/.tsbuildinfo +1 -1
- package/dist/agentSessions/BridgeHostInstance.d.ts +8 -3
- package/dist/agentSessions/BridgeHostInstance.d.ts.map +1 -1
- package/dist/agentSessions/BridgeHostInstance.js +14 -4
- package/dist/agentSessions/BridgeHostInstance.js.map +1 -1
- package/dist/agentSessions/HandoffOfferExpiry.d.ts +10 -0
- package/dist/agentSessions/HandoffOfferExpiry.d.ts.map +1 -0
- package/dist/agentSessions/HandoffOfferExpiry.js +18 -0
- package/dist/agentSessions/HandoffOfferExpiry.js.map +1 -0
- package/dist/agentSessions/ReturningVisitorRecap.js +1 -0
- package/dist/agentSessions/ReturningVisitorRecap.js.map +1 -1
- package/dist/agentSessions/SessionJanitor.d.ts +34 -11
- package/dist/agentSessions/SessionJanitor.d.ts.map +1 -1
- package/dist/agentSessions/SessionJanitor.js +88 -44
- package/dist/agentSessions/SessionJanitor.js.map +1 -1
- package/dist/agentSessions/SessionManager.d.ts +29 -9
- package/dist/agentSessions/SessionManager.d.ts.map +1 -1
- package/dist/agentSessions/SessionManager.js +62 -16
- package/dist/agentSessions/SessionManager.js.map +1 -1
- package/dist/agentSessions/conversationBrowsers.d.ts +61 -0
- package/dist/agentSessions/conversationBrowsers.d.ts.map +1 -0
- package/dist/agentSessions/conversationBrowsers.js +118 -0
- package/dist/agentSessions/conversationBrowsers.js.map +1 -0
- package/dist/agentSessions/sessionDeadline.d.ts +43 -0
- package/dist/agentSessions/sessionDeadline.d.ts.map +1 -0
- package/dist/agentSessions/sessionDeadline.js +68 -0
- package/dist/agentSessions/sessionDeadline.js.map +1 -0
- package/dist/auth/APIKeyScopeAuth.d.ts.map +1 -1
- package/dist/auth/APIKeyScopeAuth.js +5 -4
- package/dist/auth/APIKeyScopeAuth.js.map +1 -1
- package/dist/auth/AuthProviderCatalogRouter.d.ts.map +1 -1
- package/dist/auth/AuthProviderCatalogRouter.js +2 -0
- package/dist/auth/AuthProviderCatalogRouter.js.map +1 -1
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +51 -10
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/initializeProviders.d.ts +10 -0
- package/dist/auth/initializeProviders.d.ts.map +1 -1
- package/dist/auth/initializeProviders.js +37 -1
- package/dist/auth/initializeProviders.js.map +1 -1
- package/dist/auth/localDevAuth.d.ts +79 -0
- package/dist/auth/localDevAuth.d.ts.map +1 -0
- package/dist/auth/localDevAuth.js +439 -0
- package/dist/auth/localDevAuth.js.map +1 -0
- package/dist/auth/loginEmailResolution.d.ts +41 -0
- package/dist/auth/loginEmailResolution.d.ts.map +1 -0
- package/dist/auth/loginEmailResolution.js +47 -0
- package/dist/auth/loginEmailResolution.js.map +1 -0
- package/dist/auth/magicLink/MagicLinkKeys.d.ts +51 -3
- package/dist/auth/magicLink/MagicLinkKeys.d.ts.map +1 -1
- package/dist/auth/magicLink/MagicLinkKeys.js +130 -13
- package/dist/auth/magicLink/MagicLinkKeys.js.map +1 -1
- package/dist/auth/magicLink/MagicLinkRouter.d.ts +3 -0
- package/dist/auth/magicLink/MagicLinkRouter.d.ts.map +1 -1
- package/dist/auth/magicLink/MagicLinkRouter.js +23 -5
- package/dist/auth/magicLink/MagicLinkRouter.js.map +1 -1
- package/dist/auth/magicLink/MagicLinkService.d.ts +39 -5
- package/dist/auth/magicLink/MagicLinkService.d.ts.map +1 -1
- package/dist/auth/magicLink/MagicLinkService.js +221 -9
- package/dist/auth/magicLink/MagicLinkService.js.map +1 -1
- package/dist/auth/magicLink/index.d.ts +1 -1
- package/dist/auth/magicLink/index.d.ts.map +1 -1
- package/dist/auth/magicLink/index.js +1 -1
- package/dist/auth/magicLink/index.js.map +1 -1
- package/dist/auth/magicLink/redeemLanding.d.ts +2 -2
- package/dist/auth/magicLink/redeemLanding.d.ts.map +1 -1
- package/dist/auth/magicLink/redeemLanding.js +7 -4
- package/dist/auth/magicLink/redeemLanding.js.map +1 -1
- package/dist/auth/magicLink/types.d.ts +39 -3
- package/dist/auth/magicLink/types.d.ts.map +1 -1
- package/dist/auth/magicLink/types.js +0 -4
- package/dist/auth/magicLink/types.js.map +1 -1
- package/dist/auth/newUsers.d.ts.map +1 -1
- package/dist/auth/newUsers.js +1 -0
- package/dist/auth/newUsers.js.map +1 -1
- package/dist/auth/sessionUserClone.d.ts +1 -1
- package/dist/auth/sessionUserClone.d.ts.map +1 -1
- package/dist/auth/sessionUserClone.js +3 -2
- package/dist/auth/sessionUserClone.js.map +1 -1
- package/dist/backgroundSweepConfigUnits.d.ts +231 -0
- package/dist/backgroundSweepConfigUnits.d.ts.map +1 -0
- package/dist/backgroundSweepConfigUnits.js +180 -0
- package/dist/backgroundSweepConfigUnits.js.map +1 -0
- package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.d.ts +292 -0
- package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.d.ts.map +1 -0
- package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.js +442 -0
- package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.js.map +1 -0
- package/dist/broadcast/index.d.ts +6 -0
- package/dist/broadcast/index.d.ts.map +1 -0
- package/dist/broadcast/index.js +6 -0
- package/dist/broadcast/index.js.map +1 -0
- package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.d.ts +43 -0
- package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.d.ts.map +1 -0
- package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.js +144 -0
- package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.js.map +1 -0
- package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.d.ts +46 -0
- package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.d.ts.map +1 -0
- package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.js +149 -0
- package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.js.map +1 -0
- package/dist/broadcast/providers/GCPPubSubBroadcastProvider.d.ts +49 -0
- package/dist/broadcast/providers/GCPPubSubBroadcastProvider.d.ts.map +1 -0
- package/dist/broadcast/providers/GCPPubSubBroadcastProvider.js +131 -0
- package/dist/broadcast/providers/GCPPubSubBroadcastProvider.js.map +1 -0
- package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.d.ts +24 -0
- package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.d.ts.map +1 -0
- package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.js +51 -0
- package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.js.map +1 -0
- package/dist/cache.d.ts +3 -2
- package/dist/cache.d.ts.map +1 -1
- package/dist/cache.js.map +1 -1
- package/dist/config.d.ts +1402 -8
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +120 -0
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +5 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +64 -12
- package/dist/context.js.map +1 -1
- package/dist/coreRoutes.d.ts +3 -1
- package/dist/coreRoutes.d.ts.map +1 -1
- package/dist/coreRoutes.js +20 -4
- package/dist/coreRoutes.js.map +1 -1
- package/dist/generated/graphql-schemas/__mj.d.ts +863 -14
- package/dist/generated/graphql-schemas/__mj.d.ts.map +1 -1
- package/dist/generated/graphql-schemas/__mj.js +4167 -62
- package/dist/generated/graphql-schemas/__mj.js.map +1 -1
- package/dist/generic/CacheInvalidationResolver.d.ts +50 -30
- package/dist/generic/CacheInvalidationResolver.d.ts.map +1 -1
- package/dist/generic/CacheInvalidationResolver.js +154 -79
- package/dist/generic/CacheInvalidationResolver.js.map +1 -1
- package/dist/generic/OrphanedConversationDetailReconciler.d.ts +11 -0
- package/dist/generic/OrphanedConversationDetailReconciler.d.ts.map +1 -1
- package/dist/generic/OrphanedConversationDetailReconciler.js +29 -1
- package/dist/generic/OrphanedConversationDetailReconciler.js.map +1 -1
- package/dist/generic/PubSubManager.d.ts +10 -0
- package/dist/generic/PubSubManager.d.ts.map +1 -1
- package/dist/generic/PubSubManager.js +44 -1
- package/dist/generic/PubSubManager.js.map +1 -1
- package/dist/generic/PushStatusResolver.d.ts +39 -6
- package/dist/generic/PushStatusResolver.d.ts.map +1 -1
- package/dist/generic/PushStatusResolver.js +93 -11
- package/dist/generic/PushStatusResolver.js.map +1 -1
- package/dist/generic/ResolverBase.d.ts +114 -29
- package/dist/generic/ResolverBase.d.ts.map +1 -1
- package/dist/generic/ResolverBase.js +509 -220
- package/dist/generic/ResolverBase.js.map +1 -1
- package/dist/generic/RunViewResolver.d.ts +15 -3
- package/dist/generic/RunViewResolver.d.ts.map +1 -1
- package/dist/generic/RunViewResolver.js +126 -20
- package/dist/generic/RunViewResolver.js.map +1 -1
- package/dist/generic/actionOutputFieldSecurity.d.ts +26 -0
- package/dist/generic/actionOutputFieldSecurity.d.ts.map +1 -0
- package/dist/generic/actionOutputFieldSecurity.js +47 -0
- package/dist/generic/actionOutputFieldSecurity.js.map +1 -0
- package/dist/generic/fieldSecurityTransport.d.ts +30 -0
- package/dist/generic/fieldSecurityTransport.d.ts.map +1 -0
- package/dist/generic/fieldSecurityTransport.js +30 -0
- package/dist/generic/fieldSecurityTransport.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +262 -84
- package/dist/index.js.map +1 -1
- package/dist/integration/ConnectionPause.d.ts +121 -0
- package/dist/integration/ConnectionPause.d.ts.map +1 -0
- package/dist/integration/ConnectionPause.js +183 -0
- package/dist/integration/ConnectionPause.js.map +1 -0
- package/dist/integration/CustomColumnPromoter.d.ts +72 -6
- package/dist/integration/CustomColumnPromoter.d.ts.map +1 -1
- package/dist/integration/CustomColumnPromoter.js +93 -47
- package/dist/integration/CustomColumnPromoter.js.map +1 -1
- package/dist/integration/EntityMapLifecycle.d.ts +78 -4
- package/dist/integration/EntityMapLifecycle.d.ts.map +1 -1
- package/dist/integration/EntityMapLifecycle.js +199 -5
- package/dist/integration/EntityMapLifecycle.js.map +1 -1
- package/dist/integration/InactiveRowWarnings.d.ts +31 -0
- package/dist/integration/InactiveRowWarnings.d.ts.map +1 -1
- package/dist/integration/InactiveRowWarnings.js +29 -0
- package/dist/integration/InactiveRowWarnings.js.map +1 -1
- package/dist/integration/ObjectNamesByID.d.ts +28 -0
- package/dist/integration/ObjectNamesByID.d.ts.map +1 -0
- package/dist/integration/ObjectNamesByID.js +87 -0
- package/dist/integration/ObjectNamesByID.js.map +1 -0
- package/dist/integration/PostRestartIntrospect.d.ts +26 -0
- package/dist/integration/PostRestartIntrospect.d.ts.map +1 -0
- package/dist/integration/PostRestartIntrospect.js +27 -0
- package/dist/integration/PostRestartIntrospect.js.map +1 -0
- package/dist/integration/RSUPostRestartProgress.d.ts +176 -0
- package/dist/integration/RSUPostRestartProgress.d.ts.map +1 -0
- package/dist/integration/RSUPostRestartProgress.js +323 -0
- package/dist/integration/RSUPostRestartProgress.js.map +1 -0
- package/dist/integration/RSUProgressBridge.d.ts +41 -2
- package/dist/integration/RSUProgressBridge.d.ts.map +1 -1
- package/dist/integration/RSUProgressBridge.js +84 -1
- package/dist/integration/RSUProgressBridge.js.map +1 -1
- package/dist/integration/RunArtifactAuthorization.d.ts +39 -0
- package/dist/integration/RunArtifactAuthorization.d.ts.map +1 -0
- package/dist/integration/RunArtifactAuthorization.js +45 -0
- package/dist/integration/RunArtifactAuthorization.js.map +1 -0
- package/dist/integration/SchemaRefreshLaunch.d.ts +9 -0
- package/dist/integration/SchemaRefreshLaunch.d.ts.map +1 -1
- package/dist/integration/SchemaRefreshLaunch.js +3 -2
- package/dist/integration/SchemaRefreshLaunch.js.map +1 -1
- package/dist/integration/ScopedFieldsForBuild.d.ts +46 -0
- package/dist/integration/ScopedFieldsForBuild.d.ts.map +1 -0
- package/dist/integration/ScopedFieldsForBuild.js +91 -0
- package/dist/integration/ScopedFieldsForBuild.js.map +1 -0
- package/dist/integration/TargetConfigGuard.d.ts +40 -0
- package/dist/integration/TargetConfigGuard.d.ts.map +1 -0
- package/dist/integration/TargetConfigGuard.js +40 -0
- package/dist/integration/TargetConfigGuard.js.map +1 -0
- package/dist/logging/variablesLoggingMiddleware.d.ts +12 -0
- package/dist/logging/variablesLoggingMiddleware.d.ts.map +1 -1
- package/dist/logging/variablesLoggingMiddleware.js +50 -1
- package/dist/logging/variablesLoggingMiddleware.js.map +1 -1
- package/dist/realtimeSessions/SessionVerificationPortsBase.d.ts.map +1 -1
- package/dist/realtimeSessions/SessionVerificationPortsBase.js +1 -0
- package/dist/realtimeSessions/SessionVerificationPortsBase.js.map +1 -1
- package/dist/realtimeSessions/ownedRealtimeSession.d.ts +8 -6
- package/dist/realtimeSessions/ownedRealtimeSession.d.ts.map +1 -1
- package/dist/realtimeSessions/ownedRealtimeSession.js +14 -6
- package/dist/realtimeSessions/ownedRealtimeSession.js.map +1 -1
- package/dist/realtimeSessions/sessionAccess.d.ts +103 -11
- package/dist/realtimeSessions/sessionAccess.d.ts.map +1 -1
- package/dist/realtimeSessions/sessionAccess.js +147 -22
- package/dist/realtimeSessions/sessionAccess.js.map +1 -1
- package/dist/realtimeSessions/sessionConfigStamps.js +1 -1
- package/dist/realtimeSessions/sessionConfigStamps.js.map +1 -1
- package/dist/realtimeSessions/subscriptionAuthorization.d.ts.map +1 -1
- package/dist/realtimeSessions/subscriptionAuthorization.js +5 -2
- package/dist/realtimeSessions/subscriptionAuthorization.js.map +1 -1
- package/dist/realtimeSessions/verificationWorkflow.d.ts +2 -0
- package/dist/realtimeSessions/verificationWorkflow.d.ts.map +1 -1
- package/dist/realtimeSessions/verificationWorkflow.js +1 -1
- package/dist/realtimeSessions/verificationWorkflow.js.map +1 -1
- package/dist/realtimeWidget/WidgetRouter.d.ts.map +1 -1
- package/dist/realtimeWidget/WidgetRouter.js +19 -3
- package/dist/realtimeWidget/WidgetRouter.js.map +1 -1
- package/dist/realtimeWidget/WidgetSessionService.d.ts +67 -7
- package/dist/realtimeWidget/WidgetSessionService.d.ts.map +1 -1
- package/dist/realtimeWidget/WidgetSessionService.js +203 -19
- package/dist/realtimeWidget/WidgetSessionService.js.map +1 -1
- package/dist/realtimeWidget/host-identity.d.ts +1 -1
- package/dist/realtimeWidget/host-identity.js +1 -1
- package/dist/realtimeWidget/visitorIdentity.d.ts.map +1 -1
- package/dist/realtimeWidget/visitorIdentity.js +1 -0
- package/dist/realtimeWidget/visitorIdentity.js.map +1 -1
- package/dist/realtimeWidget/widgetCore.d.ts +20 -1
- package/dist/realtimeWidget/widgetCore.d.ts.map +1 -1
- package/dist/realtimeWidget/widgetCore.js +21 -8
- package/dist/realtimeWidget/widgetCore.js.map +1 -1
- package/dist/realtimeWidget/widgetGuestElevation.d.ts +1 -1
- package/dist/realtimeWidget/widgetGuestElevation.d.ts.map +1 -1
- package/dist/realtimeWidget/widgetGuestElevation.js +3 -1
- package/dist/realtimeWidget/widgetGuestElevation.js.map +1 -1
- package/dist/requestOrigin.d.ts +22 -0
- package/dist/requestOrigin.d.ts.map +1 -0
- package/dist/requestOrigin.js +60 -0
- package/dist/requestOrigin.js.map +1 -0
- package/dist/resolvers/ActionResolver.d.ts +19 -1
- package/dist/resolvers/ActionResolver.d.ts.map +1 -1
- package/dist/resolvers/ActionResolver.js +63 -12
- package/dist/resolvers/ActionResolver.js.map +1 -1
- package/dist/resolvers/AdhocQueryResolver.d.ts.map +1 -1
- package/dist/resolvers/AdhocQueryResolver.js +1 -0
- package/dist/resolvers/AdhocQueryResolver.js.map +1 -1
- package/dist/resolvers/AgentRunStatusPublisher.d.ts +18 -4
- package/dist/resolvers/AgentRunStatusPublisher.d.ts.map +1 -1
- package/dist/resolvers/AgentRunStatusPublisher.js +32 -8
- package/dist/resolvers/AgentRunStatusPublisher.js.map +1 -1
- package/dist/resolvers/AgentSessionResolver.d.ts +10 -4
- package/dist/resolvers/AgentSessionResolver.d.ts.map +1 -1
- package/dist/resolvers/AgentSessionResolver.js +44 -17
- package/dist/resolvers/AgentSessionResolver.js.map +1 -1
- package/dist/resolvers/AutotagPipelineResolver.d.ts.map +1 -1
- package/dist/resolvers/AutotagPipelineResolver.js +2 -1
- package/dist/resolvers/AutotagPipelineResolver.js.map +1 -1
- package/dist/resolvers/ConversationRunEventsResolver.d.ts.map +1 -1
- package/dist/resolvers/ConversationRunEventsResolver.js +2 -0
- package/dist/resolvers/ConversationRunEventsResolver.js.map +1 -1
- package/dist/resolvers/EntityCommunicationsResolver.d.ts +13 -1
- package/dist/resolvers/EntityCommunicationsResolver.d.ts.map +1 -1
- package/dist/resolvers/EntityCommunicationsResolver.js +50 -14
- package/dist/resolvers/EntityCommunicationsResolver.js.map +1 -1
- package/dist/resolvers/ExecuteRemoteOperationResolver.d.ts +6 -0
- package/dist/resolvers/ExecuteRemoteOperationResolver.d.ts.map +1 -1
- package/dist/resolvers/ExecuteRemoteOperationResolver.js +30 -7
- package/dist/resolvers/ExecuteRemoteOperationResolver.js.map +1 -1
- package/dist/resolvers/FetchEntityVectorsResolver.d.ts +28 -0
- package/dist/resolvers/FetchEntityVectorsResolver.d.ts.map +1 -1
- package/dist/resolvers/FetchEntityVectorsResolver.js +117 -21
- package/dist/resolvers/FetchEntityVectorsResolver.js.map +1 -1
- package/dist/resolvers/FileCategoryResolver.d.ts.map +1 -1
- package/dist/resolvers/FileCategoryResolver.js +1 -0
- package/dist/resolvers/FileCategoryResolver.js.map +1 -1
- package/dist/resolvers/FileResolver.d.ts +5 -0
- package/dist/resolvers/FileResolver.d.ts.map +1 -1
- package/dist/resolvers/FileResolver.js +13 -4
- package/dist/resolvers/FileResolver.js.map +1 -1
- package/dist/resolvers/GetDataResolver.d.ts.map +1 -1
- package/dist/resolvers/GetDataResolver.js +34 -13
- package/dist/resolvers/GetDataResolver.js.map +1 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.d.ts +401 -11
- package/dist/resolvers/IntegrationDiscoveryResolver.d.ts.map +1 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.js +2713 -1290
- package/dist/resolvers/IntegrationDiscoveryResolver.js.map +1 -1
- package/dist/resolvers/MCPResolver.d.ts.map +1 -1
- package/dist/resolvers/MCPResolver.js +13 -2
- package/dist/resolvers/MCPResolver.js.map +1 -1
- package/dist/resolvers/MergeRecordsResolver.d.ts +8 -1
- package/dist/resolvers/MergeRecordsResolver.d.ts.map +1 -1
- package/dist/resolvers/MergeRecordsResolver.js +31 -3
- package/dist/resolvers/MergeRecordsResolver.js.map +1 -1
- package/dist/resolvers/PipelineProgressResolver.d.ts +6 -0
- package/dist/resolvers/PipelineProgressResolver.d.ts.map +1 -1
- package/dist/resolvers/PipelineProgressResolver.js +5 -3
- package/dist/resolvers/PipelineProgressResolver.js.map +1 -1
- package/dist/resolvers/QueryResolver.d.ts.map +1 -1
- package/dist/resolvers/QueryResolver.js +20 -6
- package/dist/resolvers/QueryResolver.js.map +1 -1
- package/dist/resolvers/QuerySystemUserResolver.d.ts +38 -0
- package/dist/resolvers/QuerySystemUserResolver.d.ts.map +1 -1
- package/dist/resolvers/QuerySystemUserResolver.js +184 -88
- package/dist/resolvers/QuerySystemUserResolver.js.map +1 -1
- package/dist/resolvers/RSUResolver.d.ts.map +1 -1
- package/dist/resolvers/RSUResolver.js +12 -0
- package/dist/resolvers/RSUResolver.js.map +1 -1
- package/dist/resolvers/RealtimeBridgeResolver.d.ts.map +1 -1
- package/dist/resolvers/RealtimeBridgeResolver.js +1 -0
- package/dist/resolvers/RealtimeBridgeResolver.js.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts +22 -2
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.js +118 -33
- package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
- package/dist/resolvers/RemoteBrowserActionResolver.d.ts +62 -10
- package/dist/resolvers/RemoteBrowserActionResolver.d.ts.map +1 -1
- package/dist/resolvers/RemoteBrowserActionResolver.js +224 -39
- package/dist/resolvers/RemoteBrowserActionResolver.js.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.d.ts +80 -16
- package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.js +388 -125
- package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
- package/dist/resolvers/RunAIPromptResolver.d.ts +5 -3
- package/dist/resolvers/RunAIPromptResolver.d.ts.map +1 -1
- package/dist/resolvers/RunAIPromptResolver.js +19 -18
- package/dist/resolvers/RunAIPromptResolver.js.map +1 -1
- package/dist/resolvers/RunTemplateResolver.d.ts.map +1 -1
- package/dist/resolvers/RunTemplateResolver.js +7 -5
- package/dist/resolvers/RunTemplateResolver.js.map +1 -1
- package/dist/resolvers/RunTestResolver.d.ts.map +1 -1
- package/dist/resolvers/RunTestResolver.js +3 -1
- package/dist/resolvers/RunTestResolver.js.map +1 -1
- package/dist/resolvers/SyncDataResolver.d.ts.map +1 -1
- package/dist/resolvers/SyncDataResolver.js +4 -0
- package/dist/resolvers/SyncDataResolver.js.map +1 -1
- package/dist/resolvers/TestQuerySQLResolver.d.ts.map +1 -1
- package/dist/resolvers/TestQuerySQLResolver.js +1 -0
- package/dist/resolvers/TestQuerySQLResolver.js.map +1 -1
- package/dist/resolvers/TransactionGroupResolver.d.ts +17 -2
- package/dist/resolvers/TransactionGroupResolver.d.ts.map +1 -1
- package/dist/resolvers/TransactionGroupResolver.js +60 -15
- package/dist/resolvers/TransactionGroupResolver.js.map +1 -1
- package/dist/resolvers/UserViewResolver.d.ts +1 -1
- package/dist/resolvers/UserViewResolver.d.ts.map +1 -1
- package/dist/resolvers/UserViewResolver.js +2 -1
- package/dist/resolvers/UserViewResolver.js.map +1 -1
- package/dist/resolvers/meetingRecordingRegistration.d.ts.map +1 -1
- package/dist/resolvers/meetingRecordingRegistration.js +2 -0
- package/dist/resolvers/meetingRecordingRegistration.js.map +1 -1
- package/dist/rest/EntityCRUDHandler.d.ts +6 -0
- package/dist/rest/EntityCRUDHandler.d.ts.map +1 -1
- package/dist/rest/EntityCRUDHandler.js +19 -5
- package/dist/rest/EntityCRUDHandler.js.map +1 -1
- package/dist/rest/MediaAccessKeys.d.ts.map +1 -1
- package/dist/rest/MediaAccessKeys.js +6 -2
- package/dist/rest/MediaAccessKeys.js.map +1 -1
- package/dist/rest/OAuthCallbackHandler.d.ts.map +1 -1
- package/dist/rest/OAuthCallbackHandler.js +11 -5
- package/dist/rest/OAuthCallbackHandler.js.map +1 -1
- package/dist/rest/RESTEndpointHandler.d.ts.map +1 -1
- package/dist/rest/RESTEndpointHandler.js +8 -5
- package/dist/rest/RESTEndpointHandler.js.map +1 -1
- package/dist/rest/RealtimeRecordingHandler.d.ts +3 -3
- package/dist/rest/RealtimeRecordingHandler.d.ts.map +1 -1
- package/dist/rest/RealtimeRecordingHandler.js +6 -8
- package/dist/rest/RealtimeRecordingHandler.js.map +1 -1
- package/dist/rest/ViewOperationsHandler.d.ts +6 -0
- package/dist/rest/ViewOperationsHandler.d.ts.map +1 -1
- package/dist/rest/ViewOperationsHandler.js +24 -6
- package/dist/rest/ViewOperationsHandler.js.map +1 -1
- package/dist/rest/setupRESTEndpoints.d.ts +3 -1
- package/dist/rest/setupRESTEndpoints.d.ts.map +1 -1
- package/dist/rest/setupRESTEndpoints.js +11 -2
- package/dist/rest/setupRESTEndpoints.js.map +1 -1
- package/dist/serverRoleConfigUnits.d.ts +29 -0
- package/dist/serverRoleConfigUnits.d.ts.map +1 -0
- package/dist/serverRoleConfigUnits.js +33 -0
- package/dist/serverRoleConfigUnits.js.map +1 -0
- package/dist/services/DurableEntityActionTaskSubmitter.d.ts.map +1 -1
- package/dist/services/DurableEntityActionTaskSubmitter.js +6 -1
- package/dist/services/DurableEntityActionTaskSubmitter.js.map +1 -1
- package/dist/services/TaskGraphActionRunner.d.ts.map +1 -1
- package/dist/services/TaskGraphActionRunner.js +2 -26
- package/dist/services/TaskGraphActionRunner.js.map +1 -1
- package/dist/services/TaskGraphAgentRunner.d.ts +6 -0
- package/dist/services/TaskGraphAgentRunner.d.ts.map +1 -1
- package/dist/services/TaskGraphAgentRunner.js +38 -0
- package/dist/services/TaskGraphAgentRunner.js.map +1 -1
- package/dist/services/TaskGraphContinuationDeliverer.d.ts +5 -0
- package/dist/services/TaskGraphContinuationDeliverer.d.ts.map +1 -1
- package/dist/services/TaskGraphContinuationDeliverer.js +43 -15
- package/dist/services/TaskGraphContinuationDeliverer.js.map +1 -1
- package/dist/services/WorkQueueHostService.d.ts +2 -1
- package/dist/services/WorkQueueHostService.d.ts.map +1 -1
- package/dist/services/WorkQueueHostService.js +19 -4
- package/dist/services/WorkQueueHostService.js.map +1 -1
- package/dist/services/workQueueConfig.d.ts +2 -2
- package/dist/services/workQueueConfig.js +5 -5
- package/dist/services/workQueueConfig.js.map +1 -1
- package/dist/sharedCache.js +1 -1
- package/dist/sharedCache.js.map +1 -1
- package/dist/types.d.ts +40 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +98 -98
- package/src/__tests__/APIKeyScopeAuth.test.ts +4 -8
- package/src/__tests__/ActionResolver.fieldSecurity.test.ts +237 -0
- package/src/__tests__/ActiveOperations.test.ts +68 -0
- package/src/__tests__/AdhocQueryResolver.dialect.test.ts +137 -0
- package/src/__tests__/AgentRunStatusPublisher.test.ts +49 -0
- package/src/__tests__/AgentSessionResolver.ownership.test.ts +150 -0
- package/src/__tests__/AssertTargetConfigs.test.ts +75 -0
- package/src/__tests__/BatchApplyParity.test.ts +109 -0
- package/src/__tests__/BridgeHostInstance.test.ts +42 -0
- package/src/__tests__/CollectInactiveRowWarnings.test.ts +115 -0
- package/src/__tests__/ConnectionPause.test.ts +192 -0
- package/src/__tests__/ConnectionPauseResolver.test.ts +166 -0
- package/src/__tests__/ConnectionPauseSave.test.ts +143 -0
- package/src/__tests__/CustomColumnPromoterCompletion.test.ts +142 -0
- package/src/__tests__/CustomColumnPromoterOnePass.test.ts +15 -1
- package/src/__tests__/DeleteConnectionRemovesPerConnectionCatalog.test.ts +51 -0
- package/src/__tests__/DetachedDiscoveryStart.test.ts +65 -0
- package/src/__tests__/DurableEntityActionTaskSubmitter.test.ts +73 -0
- package/src/__tests__/EntityCommunicationsResolver.actingUser.test.ts +151 -0
- package/src/__tests__/EntityMapLifecycle.rekey.test.ts +252 -0
- package/src/__tests__/EvolutionActsOnWhatItDetects.test.ts +113 -0
- package/src/__tests__/ExecuteRemoteOperationResolver.test.ts +213 -0
- package/src/__tests__/FetchEntityVectorsResolver.test.ts +206 -3
- package/src/__tests__/FileResolver.fieldSecurity.test.ts +82 -0
- package/src/__tests__/HandoffOfferExpiry.test.ts +40 -0
- package/src/__tests__/IntegrationRunArtifactAuthorization.test.ts +126 -0
- package/src/__tests__/MagicLinkKeys.test.ts +102 -0
- package/src/__tests__/MediaAccessKeys.test.ts +57 -10
- package/src/__tests__/NewArrivalsDefaultDisabled.test.ts +50 -0
- package/src/__tests__/ObjectNamesByID.test.ts +176 -0
- package/src/__tests__/PipelineProgressResolver.filter.test.ts +58 -0
- package/src/__tests__/PostRestartMapsInCatalogScope.test.ts +146 -0
- package/src/__tests__/QuerySystemUserResolver.childRows.test.ts +80 -0
- package/src/__tests__/QuerySystemUserResolver.collision.test.ts +200 -0
- package/src/__tests__/QuerySystemUserResolver.fieldSecurity.test.ts +49 -0
- package/src/__tests__/QuerySystemUserResolver.permissions.test.ts +132 -0
- package/src/__tests__/RESTEndpointHandler.test.ts +25 -0
- package/src/__tests__/RSUPostRestartProgress.test.ts +343 -0
- package/src/__tests__/RSUProgressBridge.test.ts +188 -5
- package/src/__tests__/RSUStartupSweepWiring.test.ts +30 -0
- package/src/__tests__/ReactivateRefreshMessage.test.ts +10 -3
- package/src/__tests__/RealtimeClientSessionResolver.configTamper.test.ts +23 -3
- package/src/__tests__/RealtimeClientSessionResolver.test.ts +346 -46
- package/src/__tests__/{RefreshAdoptsNewColumns.test.ts → RefreshReportsNewColumns.test.ts} +25 -16
- package/src/__tests__/RemoteBrowserActionRecovery.test.ts +287 -0
- package/src/__tests__/RemoteBrowserActionResolver.goalRunLink.test.ts +3 -0
- package/src/__tests__/RemoteBrowserActionResolver.ownership.test.ts +100 -0
- package/src/__tests__/RemoteBrowserAudioStream.test.ts +3 -0
- package/src/__tests__/RemoteBrowserSnapshot.test.ts +3 -0
- package/src/__tests__/ResolverBase.clientOldValues.test.ts +344 -14
- package/src/__tests__/ResolverBase.deleteReturnProjection.test.ts +52 -0
- package/src/__tests__/ResolverBase.encryptedApiZeroReencrypt.test.ts +307 -0
- package/src/__tests__/ResolverBase.entityMessageRelay.test.ts +227 -0
- package/src/__tests__/ResolverBase.includeBinaryFields.test.ts +83 -1
- package/src/__tests__/ResolverBase.publishStatusUpdate.test.ts +68 -0
- package/src/__tests__/ResolverBase.userViewCacheAndDedup.test.ts +130 -0
- package/src/__tests__/RunAIAgentResolver.branch.test.ts +72 -13
- package/src/__tests__/RunAIAgentResolver.consultPredecessor.test.ts +289 -0
- package/src/__tests__/RunAIAgentResolver.conversationWriter.test.ts +210 -0
- package/src/__tests__/RunAIAgentResolver.fireAndForgetCompletion.test.ts +209 -0
- package/src/__tests__/RunAIAgentResolver.handoff.test.ts +649 -0
- package/src/__tests__/RunAIAgentResolver.historyFrom.test.ts +19 -27
- package/src/__tests__/RunAIAgentResolver.runDataGuard.test.ts +10 -2
- package/src/__tests__/RunAIAgentResolver.serverReply.test.ts +358 -0
- package/src/__tests__/RunAIAgentResolver.stoppedPredecessor.test.ts +91 -13
- package/src/__tests__/RunTemplateResolver.test.ts +35 -2
- package/src/__tests__/RunViewResolver.cacheCheckForwarding.test.ts +11 -0
- package/src/__tests__/SchemaEvolutionCustomColumns.test.ts +119 -0
- package/src/__tests__/SchemaRefreshLaunch.test.ts +24 -2
- package/src/__tests__/ScopedFieldsForBuild.test.ts +192 -0
- package/src/__tests__/SessionJanitor.test.ts +195 -4
- package/src/__tests__/SessionManager.test.ts +164 -0
- package/src/__tests__/TaskGraphActionRunner.durablePayload.test.ts +2 -2
- package/src/__tests__/TaskGraphAgentRunner.test.ts +272 -16
- package/src/__tests__/TaskGraphContinuationDeliverer.test.ts +114 -3
- package/src/__tests__/TransactionGroupResolver.fieldSecurity.test.ts +199 -0
- package/src/__tests__/UserViewResolver.updateWhereClause.test.ts +15 -0
- package/src/__tests__/ViewOperationsHandler.test.ts +9 -7
- package/src/__tests__/WidgetSessionService.test.ts +583 -4
- package/src/__tests__/WorkQueueHostService.test.ts +25 -7
- package/src/__tests__/apiRootBoot.test.ts +1 -1
- package/src/__tests__/backgroundSweepConfigUnits.test.ts +153 -0
- package/src/__tests__/buildMagicLinkSessionUser.test.ts +96 -0
- package/src/__tests__/cacheBroadcastProviders.test.ts +403 -0
- package/src/__tests__/cacheInvalidationRecordData.test.ts +45 -0
- package/src/__tests__/contextRequestOrigin.test.ts +105 -0
- package/src/__tests__/conversationBrowsers.test.ts +62 -0
- package/src/__tests__/fieldSecurityFixtures.ts +91 -0
- package/src/__tests__/globalCors.test.ts +3 -3
- package/src/__tests__/localDevAuth.test.ts +196 -0
- package/src/__tests__/magicLinkExtensionCapabilities.test.ts +413 -0
- package/src/__tests__/orphanedConversationDetailReconciler.start.test.ts +82 -0
- package/src/__tests__/orphanedConversationDetailReconciler.test.ts +10 -0
- package/src/__tests__/ownedRealtimeSession.test.ts +14 -0
- package/src/__tests__/pushStatusResolver.filter.test.ts +57 -1
- package/src/__tests__/realtimeRecordingHandler.test.ts +24 -2
- package/src/__tests__/realtimeSessions/RealtimeSessionEventsResolver.test.ts +29 -1
- package/src/__tests__/realtimeSessions/ownedRealtimeSession.anonymous.test.ts +31 -0
- package/src/__tests__/realtimeSessions/ownedRealtimeSession.namedScoped.test.ts +37 -0
- package/src/__tests__/realtimeSessions/sessionAccess.test.ts +224 -7
- package/src/__tests__/realtimeSessions/sessionConfigStamps.test.ts +1 -1
- package/src/__tests__/realtimeSessions/verificationWorkflow.test.ts +25 -4
- package/src/__tests__/requestOrigin.test.ts +104 -0
- package/src/__tests__/resolverBase.cloudEventChangedFields.test.ts +157 -0
- package/src/__tests__/resolverBase.fieldSecurityTransport.test.ts +222 -0
- package/src/__tests__/resolverBase.fls.test.ts +146 -97
- package/src/__tests__/restTransport.fieldSecurity.test.ts +148 -0
- package/src/__tests__/runParamsTimeZone.test.ts +179 -0
- package/src/__tests__/runStreams.fieldSecurity.test.ts +100 -0
- package/src/__tests__/runViewProperties.test.ts +114 -0
- package/src/__tests__/scalabilityBenchmarks.test.ts +765 -0
- package/src/__tests__/scalabilityDatabaseIntegration.test.ts +207 -0
- package/src/__tests__/securityHardeningPr6034.test.ts +120 -0
- package/src/__tests__/sessionDeadline.test.ts +51 -0
- package/src/__tests__/sessionUserClone.test.ts +5 -1
- package/src/__tests__/sharedCache.test.ts +11 -0
- package/src/__tests__/startupSweepOrder.test.ts +40 -0
- package/src/__tests__/unifiedAuth.test.ts +101 -1
- package/src/__tests__/widgetGuestElevation.test.ts +2 -0
- package/src/agentSessions/BridgeHostInstance.ts +20 -5
- package/src/agentSessions/HandoffOfferExpiry.ts +18 -0
- package/src/agentSessions/ReturningVisitorRecap.ts +1 -0
- package/src/agentSessions/SessionJanitor.ts +95 -45
- package/src/agentSessions/SessionManager.ts +73 -20
- package/src/agentSessions/conversationBrowsers.ts +143 -0
- package/src/agentSessions/sessionDeadline.ts +81 -0
- package/src/auth/APIKeyScopeAuth.ts +5 -4
- package/src/auth/AuthProviderCatalogRouter.ts +3 -0
- package/src/auth/__tests__/loginEmailResolution.test.ts +67 -0
- package/src/auth/index.ts +56 -12
- package/src/auth/initializeProviders.ts +43 -1
- package/src/auth/localDevAuth.ts +528 -0
- package/src/auth/loginEmailResolution.ts +67 -0
- package/src/auth/magicLink/MagicLinkKeys.ts +147 -15
- package/src/auth/magicLink/MagicLinkRouter.ts +33 -6
- package/src/auth/magicLink/MagicLinkService.ts +250 -10
- package/src/auth/magicLink/index.ts +1 -1
- package/src/auth/magicLink/redeemLanding.ts +7 -4
- package/src/auth/magicLink/types.ts +38 -3
- package/src/auth/newUsers.ts +1 -0
- package/src/auth/sessionUserClone.ts +3 -2
- package/src/backgroundSweepConfigUnits.ts +213 -0
- package/src/broadcast/BaseCacheInvalidationBroadcastProvider.ts +674 -0
- package/src/broadcast/index.ts +5 -0
- package/src/broadcast/providers/AWSIoTCoreBroadcastProvider.ts +180 -0
- package/src/broadcast/providers/AzureWebPubSubBroadcastProvider.ts +182 -0
- package/src/broadcast/providers/GCPPubSubBroadcastProvider.ts +169 -0
- package/src/broadcast/providers/SequencedRoleBucketBroadcastProvider.ts +57 -0
- package/src/cache.ts +2 -1
- package/src/config.ts +138 -0
- package/src/context.ts +71 -14
- package/src/coreRoutes.ts +29 -7
- package/src/generated/graphql-schemas/__mj.ts +4145 -1193
- package/src/generic/CacheInvalidationResolver.ts +135 -78
- package/src/generic/OrphanedConversationDetailReconciler.ts +36 -3
- package/src/generic/PubSubManager.ts +54 -1
- package/src/generic/PushStatusResolver.ts +108 -11
- package/src/generic/ResolverBase.ts +635 -234
- package/src/generic/RunViewResolver.ts +176 -64
- package/src/generic/actionOutputFieldSecurity.ts +75 -0
- package/src/generic/fieldSecurityTransport.ts +62 -0
- package/src/index.ts +310 -85
- package/src/integration/ConnectionPause.ts +222 -0
- package/src/integration/CustomColumnPromoter.ts +129 -54
- package/src/integration/EntityMapLifecycle.ts +229 -6
- package/src/integration/InactiveRowWarnings.ts +50 -0
- package/src/integration/ObjectNamesByID.ts +97 -0
- package/src/integration/PostRestartIntrospect.ts +49 -0
- package/src/integration/RSUPostRestartProgress.ts +359 -0
- package/src/integration/RSUProgressBridge.ts +85 -2
- package/src/integration/RunArtifactAuthorization.ts +65 -0
- package/src/integration/SchemaRefreshLaunch.ts +12 -2
- package/src/integration/ScopedFieldsForBuild.ts +113 -0
- package/src/integration/TargetConfigGuard.ts +71 -0
- package/src/logging/variablesLoggingMiddleware.ts +59 -3
- package/src/realtimeSessions/README.md +7 -3
- package/src/realtimeSessions/SessionVerificationPortsBase.ts +1 -0
- package/src/realtimeSessions/ownedRealtimeSession.ts +16 -6
- package/src/realtimeSessions/sessionAccess.ts +211 -25
- package/src/realtimeSessions/sessionConfigStamps.ts +1 -1
- package/src/realtimeSessions/subscriptionAuthorization.ts +4 -2
- package/src/realtimeSessions/verificationWorkflow.ts +3 -1
- package/src/realtimeWidget/WidgetRouter.ts +22 -4
- package/src/realtimeWidget/WidgetSessionService.ts +254 -17
- package/src/realtimeWidget/host-identity.ts +1 -1
- package/src/realtimeWidget/visitorIdentity.ts +1 -0
- package/src/realtimeWidget/widgetCore.ts +34 -9
- package/src/realtimeWidget/widgetGuestElevation.ts +3 -1
- package/src/requestOrigin.ts +64 -0
- package/src/resolvers/ActionResolver.ts +78 -15
- package/src/resolvers/AdhocQueryResolver.ts +1 -0
- package/src/resolvers/AgentRunStatusPublisher.ts +36 -8
- package/src/resolvers/AgentSessionResolver.ts +50 -18
- package/src/resolvers/AutotagPipelineResolver.ts +2 -1
- package/src/resolvers/ConversationRunEventsResolver.ts +2 -0
- package/src/resolvers/EntityCommunicationsResolver.ts +56 -15
- package/src/resolvers/ExecuteRemoteOperationResolver.ts +41 -9
- package/src/resolvers/FetchEntityVectorsResolver.ts +132 -21
- package/src/resolvers/FileCategoryResolver.ts +1 -0
- package/src/resolvers/FileResolver.ts +14 -4
- package/src/resolvers/GetDataResolver.ts +35 -13
- package/src/resolvers/IntegrationDiscoveryResolver.ts +1570 -209
- package/src/resolvers/MCPResolver.ts +15 -2
- package/src/resolvers/MergeRecordsResolver.ts +23 -2
- package/src/resolvers/PipelineProgressResolver.ts +12 -3
- package/src/resolvers/QueryResolver.ts +20 -6
- package/src/resolvers/QuerySystemUserResolver.ts +207 -99
- package/src/resolvers/RSUResolver.ts +12 -0
- package/src/resolvers/RealtimeBridgeResolver.ts +1 -0
- package/src/resolvers/RealtimeClientSessionResolver.ts +144 -40
- package/src/resolvers/RemoteBrowserActionResolver.ts +252 -37
- package/src/resolvers/RunAIAgentResolver.ts +518 -163
- package/src/resolvers/RunAIPromptResolver.ts +18 -18
- package/src/resolvers/RunTemplateResolver.ts +9 -5
- package/src/resolvers/RunTestResolver.ts +3 -1
- package/src/resolvers/SyncDataResolver.ts +4 -0
- package/src/resolvers/TestQuerySQLResolver.ts +1 -0
- package/src/resolvers/TransactionGroupResolver.ts +66 -15
- package/src/resolvers/UserViewResolver.ts +2 -1
- package/src/resolvers/__tests__/GetDataResolver.tokens.test.ts +52 -0
- package/src/resolvers/__tests__/MergeRecordsResolver.test.ts +43 -0
- package/src/resolvers/meetingRecordingRegistration.ts +2 -0
- package/src/rest/EntityCRUDHandler.ts +22 -5
- package/src/rest/MediaAccessKeys.ts +6 -2
- package/src/rest/OAuthCallbackHandler.ts +13 -5
- package/src/rest/RESTEndpointHandler.ts +8 -5
- package/src/rest/RealtimeRecordingHandler.ts +9 -10
- package/src/rest/ViewOperationsHandler.ts +26 -7
- package/src/rest/setupRESTEndpoints.ts +11 -2
- package/src/serverRoleConfigUnits.ts +48 -0
- package/src/services/DurableEntityActionTaskSubmitter.ts +10 -2
- package/src/services/TaskGraphActionRunner.ts +2 -23
- package/src/services/TaskGraphAgentRunner.ts +43 -0
- package/src/services/TaskGraphContinuationDeliverer.ts +53 -20
- package/src/services/WorkQueueHostService.ts +26 -4
- package/src/services/workQueueConfig.ts +5 -5
- package/src/sharedCache.ts +1 -1
- package/src/types.ts +41 -1
- package/src/services/TaskOrchestration-Integration.md +0 -188
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Tests for ResolverBase.
|
|
3
|
-
*
|
|
2
|
+
* Tests for ResolverBase.AssertClientInputFieldSecurity — the field-level-security gate on the
|
|
3
|
+
* update path — and MustLoadTruthFromDatabase.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* it
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* load-truth-from-DB branch so denied fields hold real values a stripped SetMany never
|
|
12
|
-
* touches.
|
|
5
|
+
* A read-denied field is absent from every payload the client receives, so a value coming back
|
|
6
|
+
* for it can only be fabricated. The gate REFUSES such a value (new values and OldValues alike)
|
|
7
|
+
* rather than dropping it, and refuses a key that names no field with the identical message, so
|
|
8
|
+
* the refusal cannot be used to learn which columns exist. Its `true` return (the caller is
|
|
9
|
+
* denied something) forces the caller onto the load-truth-from-DB branch, so denied fields keep
|
|
10
|
+
* the values the database holds.
|
|
13
11
|
*/
|
|
14
12
|
import { describe, it, expect, vi, beforeEach, beforeAll, afterAll } from 'vitest';
|
|
15
13
|
|
|
@@ -116,7 +114,7 @@ vi.mock('@memberjunction/core-entities', () => ({}));
|
|
|
116
114
|
|
|
117
115
|
// ─── Import after mocks ──────────────────────────────────────────────────
|
|
118
116
|
import { ResolverBase } from '../generic/ResolverBase';
|
|
119
|
-
import { EntityInfo, Metadata, RowLevelSecurityFilterInfo, UserInfo, UserRoleInfo } from '@memberjunction/core';
|
|
117
|
+
import { EntityInfo, FieldSecurityClientInputMessage, IMetadataProvider, Metadata, RowLevelSecurityFilterInfo, UserInfo, UserRoleInfo } from '@memberjunction/core';
|
|
120
118
|
|
|
121
119
|
// ─── Metadata builders (mirrors MJCore's fieldSecurity.enforcement tests) ──
|
|
122
120
|
|
|
@@ -189,7 +187,7 @@ type ClientInput = { OldValues___?: Array<{ Key: string; Value: unknown }> } & R
|
|
|
189
187
|
/** Subclass that exposes the protected guards for testing. */
|
|
190
188
|
class TestResolver extends ResolverBase {
|
|
191
189
|
public TestStrip(entityInfo: EntityInfo, userInfo: UserInfo, input: ClientInput, clientNewValues: Record<string, unknown>): boolean {
|
|
192
|
-
return this.
|
|
190
|
+
return this.AssertClientInputFieldSecurity(entityInfo, userInfo, input, clientNewValues);
|
|
193
191
|
}
|
|
194
192
|
|
|
195
193
|
/** The user defaults to HR, whose permission rows carry no row filter; pass null for a missing user. */
|
|
@@ -210,7 +208,10 @@ function makeClientPayload(fields: Record<string, unknown>, oldValues?: Array<{
|
|
|
210
208
|
|
|
211
209
|
// ─── Tests ────────────────────────────────────────────────────────────────
|
|
212
210
|
|
|
213
|
-
|
|
211
|
+
/** The refusal for `key` on Employees: one wording for a denied key and for a key that names no field. */
|
|
212
|
+
const refusalFor = (key: string) => FieldSecurityClientInputMessage(key, 'Employees');
|
|
213
|
+
|
|
214
|
+
describe('ResolverBase.AssertClientInputFieldSecurity', () => {
|
|
214
215
|
let resolver: TestResolver;
|
|
215
216
|
let flsEntity: EntityInfo;
|
|
216
217
|
let noFlsEntity: EntityInfo;
|
|
@@ -221,93 +222,78 @@ describe('ResolverBase.StripDeniedReadFieldsFromClientInput', () => {
|
|
|
221
222
|
noFlsEntity = new EntityInfo(employeeEntityInit(false));
|
|
222
223
|
});
|
|
223
224
|
|
|
224
|
-
it('
|
|
225
|
+
it('REGRESSION: refuses a value for a denied-read field instead of silently dropping it', () => {
|
|
225
226
|
const { input, clientNewValues } = makeClientPayload({ ID: '1', Notes: 'edited', Salary: 0 });
|
|
226
|
-
|
|
227
|
+
expect(() => resolver.TestStrip(flsEntity, buildUser([INTERN_ROLE_ID]), input, clientNewValues))
|
|
228
|
+
.toThrow(refusalFor('Salary'));
|
|
229
|
+
});
|
|
227
230
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
231
|
+
it('REGRESSION: refuses a key that names no field with the SAME message as a denied one', () => {
|
|
232
|
+
const { input, clientNewValues } = makeClientPayload({ ID: '1', Notes: 'edited', Bogus: 0 });
|
|
233
|
+
let denied = '';
|
|
234
|
+
let unknown = '';
|
|
235
|
+
try { resolver.TestStrip(flsEntity, buildUser([INTERN_ROLE_ID]), makeClientPayload({ ID: '1', Salary: 0 }).input, { ID: '1', Salary: 0 }); }
|
|
236
|
+
catch (e) { denied = (e as Error).message; }
|
|
237
|
+
try { resolver.TestStrip(flsEntity, buildUser([INTERN_ROLE_ID]), input, clientNewValues); }
|
|
238
|
+
catch (e) { unknown = (e as Error).message; }
|
|
239
|
+
|
|
240
|
+
expect(unknown).toBe(refusalFor('Bogus'));
|
|
241
|
+
expect(denied.replace("'Salary'", "'X'")).toBe(unknown.replace("'Bogus'", "'X'"));
|
|
232
242
|
});
|
|
233
243
|
|
|
234
|
-
it('
|
|
244
|
+
it('REGRESSION: refuses a denied field named only in OldValues___', () => {
|
|
235
245
|
const { input, clientNewValues } = makeClientPayload(
|
|
236
|
-
{ ID: '1', Notes: 'edited'
|
|
246
|
+
{ ID: '1', Notes: 'edited' },
|
|
237
247
|
[{ Key: 'ID', Value: '1' }, { Key: 'Notes', Value: 'orig' }, { Key: 'Salary', Value: '0' }]
|
|
238
248
|
);
|
|
239
|
-
resolver.TestStrip(flsEntity, buildUser([INTERN_ROLE_ID]), input, clientNewValues)
|
|
240
|
-
|
|
241
|
-
expect(input.OldValues___).toEqual([{ Key: 'ID', Value: '1' }, { Key: 'Notes', Value: 'orig' }]);
|
|
249
|
+
expect(() => resolver.TestStrip(flsEntity, buildUser([INTERN_ROLE_ID]), input, clientNewValues))
|
|
250
|
+
.toThrow(refusalFor('Salary'));
|
|
242
251
|
});
|
|
243
252
|
|
|
244
|
-
it('
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
);
|
|
250
|
-
const result = resolver.TestStrip(flsEntity, buildUser([INTERN_ROLE_ID]), input, clientNewValues);
|
|
253
|
+
it('matches the CodeName of a denied field with a space in its name', () => {
|
|
254
|
+
const { input, clientNewValues } = makeClientPayload({ ID: '1', Notes: 'edited', Base_Salary: 100 });
|
|
255
|
+
expect(() => resolver.TestStrip(flsEntity, buildUser([INTERN_ROLE_ID]), input, clientNewValues))
|
|
256
|
+
.toThrow(refusalFor('Base_Salary'));
|
|
257
|
+
});
|
|
251
258
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
expect(
|
|
259
|
+
it('matches input keys case-insensitively (wire casing must not defeat the gate)', () => {
|
|
260
|
+
const { input, clientNewValues } = makeClientPayload({ ID: '1', SALARY: 0 });
|
|
261
|
+
expect(() => resolver.TestStrip(flsEntity, buildUser([INTERN_ROLE_ID]), input, clientNewValues))
|
|
262
|
+
.toThrow(refusalFor('SALARY'));
|
|
255
263
|
});
|
|
256
264
|
|
|
257
|
-
it('
|
|
265
|
+
it('accepts permitted fields and metadata blobs untouched, and returns true', () => {
|
|
258
266
|
const restore = { marker: true };
|
|
259
|
-
const { input, clientNewValues } = makeClientPayload({ ID: '1', Name: 'Ada', Notes: 'n',
|
|
267
|
+
const { input, clientNewValues } = makeClientPayload({ ID: '1', Name: 'Ada', Notes: 'n' }, [{ Key: 'Notes', Value: 'o' }]);
|
|
260
268
|
(input as Record<string, unknown>)['RestoreContext___'] = restore;
|
|
261
|
-
resolver.TestStrip(flsEntity, buildUser([INTERN_ROLE_ID]), input, clientNewValues);
|
|
262
269
|
|
|
270
|
+
expect(resolver.TestStrip(flsEntity, buildUser([INTERN_ROLE_ID]), input, clientNewValues)).toBe(true);
|
|
263
271
|
expect(clientNewValues).toEqual({ ID: '1', Name: 'Ada', Notes: 'n' });
|
|
264
272
|
expect(input['RestoreContext___']).toBe(restore);
|
|
265
|
-
expect(input
|
|
273
|
+
expect(input.OldValues___).toEqual([{ Key: 'Notes', Value: 'o' }]);
|
|
266
274
|
});
|
|
267
275
|
|
|
268
|
-
it('returns true
|
|
276
|
+
it('returns true when the caller is denied anything, so the truth-load is still forced', () => {
|
|
269
277
|
const { input, clientNewValues } = makeClientPayload({ ID: '1', Notes: 'edited' });
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
expect(result).toBe(true);
|
|
273
|
-
expect(clientNewValues).toEqual({ ID: '1', Notes: 'edited' });
|
|
278
|
+
expect(resolver.TestStrip(flsEntity, buildUser([INTERN_ROLE_ID]), input, clientNewValues)).toBe(true);
|
|
274
279
|
});
|
|
275
280
|
|
|
276
281
|
it('is a no-op returning false when the entity has no field security', () => {
|
|
277
|
-
const { input, clientNewValues } = makeClientPayload({ ID: '1', Salary: 12345 });
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
expect(result).toBe(false);
|
|
282
|
+
const { input, clientNewValues } = makeClientPayload({ ID: '1', Salary: 12345, Bogus: 1 });
|
|
283
|
+
expect(resolver.TestStrip(noFlsEntity, buildUser([INTERN_ROLE_ID]), input, clientNewValues)).toBe(false);
|
|
281
284
|
expect(clientNewValues['Salary']).toBe(12345);
|
|
282
|
-
expect(input['Salary']).toBe(12345);
|
|
283
285
|
});
|
|
284
286
|
|
|
285
287
|
it('is a no-op returning false for a user who HOLDS the granting role', () => {
|
|
286
|
-
const { input, clientNewValues } = makeClientPayload(
|
|
287
|
-
|
|
288
|
-
[{ Key: 'Salary', Value: '85000' }]
|
|
289
|
-
);
|
|
290
|
-
const result = resolver.TestStrip(flsEntity, buildUser([HR_ROLE_ID]), input, clientNewValues);
|
|
291
|
-
|
|
292
|
-
expect(result).toBe(false);
|
|
288
|
+
const { input, clientNewValues } = makeClientPayload({ ID: '1', Salary: 99000 }, [{ Key: 'Salary', Value: '85000' }]);
|
|
289
|
+
expect(resolver.TestStrip(flsEntity, buildUser([HR_ROLE_ID]), input, clientNewValues)).toBe(false);
|
|
293
290
|
expect(clientNewValues['Salary']).toBe(99000);
|
|
294
291
|
expect(input.OldValues___).toHaveLength(1);
|
|
295
292
|
});
|
|
296
293
|
|
|
297
294
|
it('is a no-op returning false without a user', () => {
|
|
298
295
|
const { input, clientNewValues } = makeClientPayload({ ID: '1', Salary: 1 });
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
expect(result).toBe(false);
|
|
302
|
-
expect(clientNewValues['Salary']).toBe(1);
|
|
303
|
-
});
|
|
304
|
-
|
|
305
|
-
it('matches input keys case-insensitively (wire casing must not defeat the strip)', () => {
|
|
306
|
-
const { input, clientNewValues } = makeClientPayload({ ID: '1', SALARY: 0 });
|
|
307
|
-
const result = resolver.TestStrip(flsEntity, buildUser([INTERN_ROLE_ID]), input, clientNewValues);
|
|
308
|
-
|
|
309
|
-
expect(result).toBe(true);
|
|
310
|
-
expect(clientNewValues).not.toHaveProperty('SALARY');
|
|
296
|
+
expect(resolver.TestStrip(flsEntity, undefined as unknown as UserInfo, input, clientNewValues)).toBe(false);
|
|
311
297
|
});
|
|
312
298
|
});
|
|
313
299
|
|
|
@@ -318,7 +304,7 @@ describe('ResolverBase.StripDeniedReadFieldsFromClientInput', () => {
|
|
|
318
304
|
// cannot see. These tests write the forbidden rows DIRECTLY into metadata, bypassing the
|
|
319
305
|
// constraint, and assert the runtime still refuses to produce a write-only outcome.
|
|
320
306
|
|
|
321
|
-
describe('write-only fields are unreachable, so
|
|
307
|
+
describe('write-only fields are unreachable, so a value for any denied-read field is refused', () => {
|
|
322
308
|
const resolver = new TestResolver();
|
|
323
309
|
|
|
324
310
|
/**
|
|
@@ -345,37 +331,11 @@ describe('write-only fields are unreachable, so every denied-read field is strip
|
|
|
345
331
|
expect(entity.GetDeniedUpdateFields(intern).has('salary')).toBe(true);
|
|
346
332
|
});
|
|
347
333
|
|
|
348
|
-
it('
|
|
334
|
+
it('refuses the value anyway — a client cannot have a legitimate value for a field it never saw', () => {
|
|
349
335
|
const entity = forbiddenWriteOnlyEntity();
|
|
350
336
|
const { input, clientNewValues } = makeClientPayload({ ID: '1', Salary: 123456 });
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
expect(result).toBe(true); // truth-load still forced — the denied-read set is non-empty
|
|
354
|
-
expect(clientNewValues).not.toHaveProperty('Salary');
|
|
355
|
-
expect(input).not.toHaveProperty('Salary');
|
|
356
|
-
});
|
|
357
|
-
|
|
358
|
-
it('removes the OldValues entry too (the client cannot know a true old value)', () => {
|
|
359
|
-
const entity = forbiddenWriteOnlyEntity();
|
|
360
|
-
const { input, clientNewValues } = makeClientPayload(
|
|
361
|
-
{ ID: '1', Salary: 123456 },
|
|
362
|
-
[{ Key: 'ID', Value: '1' }, { Key: 'Salary', Value: '99' }]
|
|
363
|
-
);
|
|
364
|
-
resolver.TestStrip(entity, buildUser([INTERN_ROLE_ID]), input, clientNewValues);
|
|
365
|
-
|
|
366
|
-
expect(input.OldValues___).toEqual([{ Key: 'ID', Value: '1' }]);
|
|
367
|
-
expect(clientNewValues).not.toHaveProperty('Salary');
|
|
368
|
-
});
|
|
369
|
-
|
|
370
|
-
it('strips EVERY denied-read field, with no update-permission split', () => {
|
|
371
|
-
// Base Salary is denied read AND update; Salary carries the forbidden write-only row.
|
|
372
|
-
// Both are stripped, because denied-read ∩ denied-update is now just denied-read.
|
|
373
|
-
const entity = forbiddenWriteOnlyEntity();
|
|
374
|
-
const { input, clientNewValues } = makeClientPayload({ ID: '1', Salary: 123456, Base_Salary: 7 });
|
|
375
|
-
resolver.TestStrip(entity, buildUser([INTERN_ROLE_ID]), input, clientNewValues);
|
|
376
|
-
|
|
377
|
-
expect(clientNewValues).not.toHaveProperty('Salary');
|
|
378
|
-
expect(clientNewValues).not.toHaveProperty('Base_Salary');
|
|
337
|
+
expect(() => resolver.TestStrip(entity, buildUser([INTERN_ROLE_ID]), input, clientNewValues))
|
|
338
|
+
.toThrow(refusalFor('Salary'));
|
|
379
339
|
});
|
|
380
340
|
});
|
|
381
341
|
|
|
@@ -564,3 +524,92 @@ describe('ResolverBase.MustLoadTruthFromDatabase: Update row filters (#4919)', (
|
|
|
564
524
|
expect(resolver.TestMustLoadTruth(entity, claimsNewStatusAsOld(), false, false, buildUser([INTERN_ROLE_ID]))).toBe(false);
|
|
565
525
|
});
|
|
566
526
|
});
|
|
527
|
+
|
|
528
|
+
/**
|
|
529
|
+
* IS-A children. A child carries its parent's fields as mirror fields of its own and nearly never
|
|
530
|
+
* has its own `EnableFieldLevelSecurity` on, so both guards must ask whether field security
|
|
531
|
+
* applies through the chain (`FieldLevelSecurityApplies`), not the child's own flag.
|
|
532
|
+
*/
|
|
533
|
+
describe('ResolverBase field-security guards on an IS-A child', () => {
|
|
534
|
+
const CHILD_ID = 'entity-contractors';
|
|
535
|
+
let resolver: TestResolver;
|
|
536
|
+
|
|
537
|
+
/** A `Contractors` IS-A `Employees` child with its own flag OFF and a mirror of every parent field. */
|
|
538
|
+
function childOf(parentInit: Record<string, unknown>): EntityInfo {
|
|
539
|
+
const entities: EntityInfo[] = [];
|
|
540
|
+
const provider = {
|
|
541
|
+
EntityByID: (id: string) => entities.find((e) => e.ID === id),
|
|
542
|
+
Entities: entities,
|
|
543
|
+
} as unknown as IMetadataProvider;
|
|
544
|
+
const parentFields = parentInit['Fields'] as Array<Record<string, unknown>>;
|
|
545
|
+
const childInit: Record<string, unknown> = {
|
|
546
|
+
...parentInit,
|
|
547
|
+
ID: CHILD_ID,
|
|
548
|
+
Name: 'Contractors',
|
|
549
|
+
BaseTable: 'Contractor',
|
|
550
|
+
BaseView: 'vwContractors',
|
|
551
|
+
ParentID: ENTITY_ID,
|
|
552
|
+
EnableFieldLevelSecurity: false,
|
|
553
|
+
Permissions: (parentInit['Permissions'] as Array<Record<string, unknown>>).map((p) => ({ ...p, EntityID: CHILD_ID })),
|
|
554
|
+
Fields: parentFields.map((f) => ({ ID: `c-${f['ID']}`, EntityID: CHILD_ID, Sequence: f['Sequence'], Name: f['Name'], Entity: 'Contractors', Type: f['Type'], IsPrimaryKey: f['IsPrimaryKey'] })),
|
|
555
|
+
};
|
|
556
|
+
entities.push(new EntityInfo(parentInit, provider), new EntityInfo(childInit, provider));
|
|
557
|
+
return entities[1];
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
beforeEach(() => {
|
|
561
|
+
resolver = new TestResolver();
|
|
562
|
+
});
|
|
563
|
+
|
|
564
|
+
it('REGRESSION: AssertClientInputFieldSecurity refuses a field the parent denies in the child\'s input', () => {
|
|
565
|
+
const child = childOf(employeeEntityInit(true));
|
|
566
|
+
expect(child.EnableFieldLevelSecurity).toBe(false);
|
|
567
|
+
const { input, clientNewValues } = makeClientPayload({ ID: '1', Notes: 'edited', Salary: 0 }, [{ Key: 'Salary', Value: '0' }]);
|
|
568
|
+
|
|
569
|
+
expect(() => resolver.TestStrip(child, buildUser([INTERN_ROLE_ID]), input, clientNewValues))
|
|
570
|
+
.toThrow(FieldSecurityClientInputMessage('Salary', 'Contractors'));
|
|
571
|
+
const allowed = makeClientPayload({ ID: '1', Notes: 'edited' });
|
|
572
|
+
expect(resolver.TestStrip(child, buildUser([INTERN_ROLE_ID]), allowed.input, allowed.clientNewValues)).toBe(true);
|
|
573
|
+
});
|
|
574
|
+
|
|
575
|
+
it('AssertClientInputFieldSecurity leaves the child\'s input alone when no ancestor has field security', () => {
|
|
576
|
+
const child = childOf(employeeEntityInit(false));
|
|
577
|
+
const { input, clientNewValues } = makeClientPayload({ ID: '1', Salary: 0 });
|
|
578
|
+
expect(resolver.TestStrip(child, buildUser([INTERN_ROLE_ID]), input, clientNewValues)).toBe(false);
|
|
579
|
+
expect(clientNewValues).toEqual({ ID: '1', Salary: 0 });
|
|
580
|
+
});
|
|
581
|
+
|
|
582
|
+
/** Employees where the intern may read every field but not update Salary, with tracking off. */
|
|
583
|
+
function readAllowUpdateDenyInit(withFls: boolean): Record<string, unknown> {
|
|
584
|
+
const init = employeeEntityInit(withFls);
|
|
585
|
+
init['TrackRecordChanges'] = false;
|
|
586
|
+
const fields = init['Fields'] as Array<Record<string, unknown>>;
|
|
587
|
+
for (const f of fields) {
|
|
588
|
+
if (f['ID'] !== 'f-id') f['EntityFieldPermissions'] = openTo(f['ID'] as string);
|
|
589
|
+
}
|
|
590
|
+
fields.find((f) => f['ID'] === 'f-salary')!['EntityFieldPermissions'] = [
|
|
591
|
+
...openTo('f-salary', [HR_ROLE_ID]),
|
|
592
|
+
{ ID: 'f-salary-intern', EntityFieldID: 'f-salary', RoleID: INTERN_ROLE_ID, ReadAccess: 'Allow', UpdateAccess: 'Deny', CreateAccess: 'Deny' },
|
|
593
|
+
];
|
|
594
|
+
return init;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
const pinnedOldValues = (): ClientInput => ({
|
|
598
|
+
ID: '1',
|
|
599
|
+
Notes: 'edited',
|
|
600
|
+
OldValues___: [{ Key: 'ID', Value: '1' }, { Key: 'Notes', Value: 'original' }, { Key: 'Salary', Value: '999999' }],
|
|
601
|
+
});
|
|
602
|
+
|
|
603
|
+
it('REGRESSION: MustLoadTruthFromDatabase forces the truth-load on a child whose parent has field security', () => {
|
|
604
|
+
const child = childOf(readAllowUpdateDenyInit(true));
|
|
605
|
+
child.TrackRecordChanges = false;
|
|
606
|
+
expect(child.GetDeniedReadFields(buildUser([INTERN_ROLE_ID])).size).toBe(0);
|
|
607
|
+
expect(resolver.TestMustLoadTruth(child, pinnedOldValues(), false, false)).toBe(true);
|
|
608
|
+
});
|
|
609
|
+
|
|
610
|
+
it('MustLoadTruthFromDatabase keeps the OldValues shortcut on a child when no ancestor has field security', () => {
|
|
611
|
+
const child = childOf(readAllowUpdateDenyInit(false));
|
|
612
|
+
child.TrackRecordChanges = false;
|
|
613
|
+
expect(resolver.TestMustLoadTruth(child, pinnedOldValues(), false, false)).toBe(false);
|
|
614
|
+
});
|
|
615
|
+
});
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Field-level security on the REST transport (rest/EntityCRUDHandler.ts, rest/ViewOperationsHandler.ts).
|
|
3
|
+
*
|
|
4
|
+
* Output: every record and every view row is projected for the caller. The entity objects and
|
|
5
|
+
* view results here are deliberately FULL WIDTH, standing in for any value not narrowed at its
|
|
6
|
+
* source; the response must still omit what the caller may not read.
|
|
7
|
+
*
|
|
8
|
+
* Input: a restricted caller's create or update body is refused when it names a field the caller
|
|
9
|
+
* may not read, or a key that names no field, with the same message for both.
|
|
10
|
+
*
|
|
11
|
+
* Views: callers may not ask for `entity_object` results, whose serialization would send an
|
|
12
|
+
* entity object's internal state rather than its projected fields.
|
|
13
|
+
*/
|
|
14
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
15
|
+
|
|
16
|
+
const { mockGetEntityObject, mockRunViewFn, mockRunViewsFn, mockEntityList } = vi.hoisted(() => ({
|
|
17
|
+
mockGetEntityObject: vi.fn(),
|
|
18
|
+
mockRunViewFn: vi.fn(),
|
|
19
|
+
mockRunViewsFn: vi.fn(),
|
|
20
|
+
mockEntityList: [] as unknown[],
|
|
21
|
+
}));
|
|
22
|
+
|
|
23
|
+
vi.mock('@memberjunction/core', async (importOriginal) => {
|
|
24
|
+
const actual = await importOriginal<typeof import('@memberjunction/core')>();
|
|
25
|
+
class MockMetadata {
|
|
26
|
+
public get Entities() { return mockEntityList; }
|
|
27
|
+
public EntityByID() { return undefined; }
|
|
28
|
+
public GetEntityObject(entityName: string, contextUser?: unknown): Promise<unknown> {
|
|
29
|
+
return mockGetEntityObject(entityName, contextUser);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
class MockRunView {
|
|
33
|
+
public RunView(params: unknown, contextUser?: unknown): Promise<unknown> { return mockRunViewFn(params, contextUser); }
|
|
34
|
+
public RunViews(params: unknown[], contextUser?: unknown): Promise<unknown> { return mockRunViewsFn(params, contextUser); }
|
|
35
|
+
}
|
|
36
|
+
return { ...actual, Metadata: MockMetadata, RunView: MockRunView, LogError: vi.fn() };
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
vi.mock('@memberjunction/generic-database-provider', () => ({
|
|
40
|
+
ClientClauseScreen: { ScreenViewClauses: vi.fn(), DialectFor: vi.fn() },
|
|
41
|
+
}));
|
|
42
|
+
|
|
43
|
+
import { EntityInfo, RunViewParams } from '@memberjunction/core';
|
|
44
|
+
import { EntityCRUDHandler } from '../rest/EntityCRUDHandler.js';
|
|
45
|
+
import { ViewOperationsHandler } from '../rest/ViewOperationsHandler.js';
|
|
46
|
+
import { EmployeeEntity, FullWidthEmployeeRow, HRUser, Intern, RefusalFor, SECRET_SALARY } from './fieldSecurityFixtures.js';
|
|
47
|
+
|
|
48
|
+
function fullWidthEntity(entityInfo: EntityInfo) {
|
|
49
|
+
return {
|
|
50
|
+
EntityInfo: entityInfo,
|
|
51
|
+
Dirty: true,
|
|
52
|
+
LatestResult: null,
|
|
53
|
+
CheckPermissions: vi.fn(() => true),
|
|
54
|
+
NewRecord: vi.fn(),
|
|
55
|
+
Set: vi.fn(),
|
|
56
|
+
Validate: vi.fn(() => ({ Success: true, Errors: [] })),
|
|
57
|
+
Save: vi.fn(async () => true),
|
|
58
|
+
InnerLoad: vi.fn(async () => true),
|
|
59
|
+
GetDataObject: vi.fn(async () => FullWidthEmployeeRow()),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
let entity: ReturnType<typeof fullWidthEntity>;
|
|
64
|
+
|
|
65
|
+
beforeEach(() => {
|
|
66
|
+
vi.clearAllMocks();
|
|
67
|
+
entity = fullWidthEntity(EmployeeEntity());
|
|
68
|
+
mockGetEntityObject.mockImplementation(async () => entity);
|
|
69
|
+
mockEntityList.length = 0;
|
|
70
|
+
mockEntityList.push(EmployeeEntity());
|
|
71
|
+
mockRunViewFn.mockResolvedValue({ Success: true, Results: [FullWidthEmployeeRow()] });
|
|
72
|
+
mockRunViewsFn.mockResolvedValue([{ Success: true, Results: [FullWidthEmployeeRow()] }]);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
describe('REST entity CRUD: responses are projected for the caller', () => {
|
|
76
|
+
it('REGRESSION: GetEntity omits a denied field from a full-width record', async () => {
|
|
77
|
+
const result = await EntityCRUDHandler.GetEntity('Employees', 'emp-1', null, Intern());
|
|
78
|
+
expect(result.entity).toEqual({ ID: 'emp-1', Name: 'Ada', Notes: 'n' });
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('REGRESSION: CreateEntity and UpdateEntity omit a denied field from the saved record', async () => {
|
|
82
|
+
const created = await EntityCRUDHandler.CreateEntity('Employees', { Name: 'Ada' }, Intern());
|
|
83
|
+
const updated = await EntityCRUDHandler.UpdateEntity('Employees', 'emp-1', { Notes: 'x' }, Intern());
|
|
84
|
+
expect(JSON.stringify([created, updated])).not.toContain(String(SECRET_SALARY));
|
|
85
|
+
expect(created.entity).toMatchObject({ ID: 'emp-1', Name: 'Ada' });
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it('a caller who may read the field still receives it', async () => {
|
|
89
|
+
const result = await EntityCRUDHandler.GetEntity('Employees', 'emp-1', null, HRUser());
|
|
90
|
+
expect(result.entity).toMatchObject({ Salary: SECRET_SALARY });
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
describe('REST entity CRUD: client input is gated for a restricted caller', () => {
|
|
95
|
+
it.each([
|
|
96
|
+
['a denied field', 'Salary'],
|
|
97
|
+
['a key that names no field', 'Bogus'],
|
|
98
|
+
])('REGRESSION: CreateEntity refuses %s with the same message, before anything is set', async (_label, key) => {
|
|
99
|
+
const result = await EntityCRUDHandler.CreateEntity('Employees', { Name: 'Ada', [key]: 1 }, Intern());
|
|
100
|
+
expect(result).toMatchObject({ success: false, error: RefusalFor(key) });
|
|
101
|
+
expect(entity.Set).not.toHaveBeenCalled();
|
|
102
|
+
expect(entity.Save).not.toHaveBeenCalled();
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it.each([
|
|
106
|
+
['a denied field', 'Salary'],
|
|
107
|
+
['a key that names no field', 'Bogus'],
|
|
108
|
+
])('REGRESSION: UpdateEntity refuses %s with the same message, before anything is set', async (_label, key) => {
|
|
109
|
+
const result = await EntityCRUDHandler.UpdateEntity('Employees', 'emp-1', { Notes: 'x', [key]: 1 }, Intern());
|
|
110
|
+
expect(result).toMatchObject({ success: false, error: RefusalFor(key) });
|
|
111
|
+
expect(entity.Set).not.toHaveBeenCalled();
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('accepts the save-options key and readable fields', async () => {
|
|
115
|
+
const result = await EntityCRUDHandler.UpdateEntity('Employees', 'emp-1', { Notes: 'x', options: { SkipEntityActions: true } }, Intern());
|
|
116
|
+
expect(result.success).toBe(true);
|
|
117
|
+
expect(entity.Set).toHaveBeenCalledWith('Notes', 'x');
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
describe('REST views: rows are projected and entity objects never cross the wire', () => {
|
|
122
|
+
it('REGRESSION: RunView omits a denied field from full-width rows', async () => {
|
|
123
|
+
const outcome = await ViewOperationsHandler.RunView({ EntityName: 'Employees' }, Intern());
|
|
124
|
+
expect(outcome.result?.Results).toEqual([{ ID: 'emp-1', Name: 'Ada', Notes: 'n' }]);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it('REGRESSION: RunViews omits a denied field from every result set', async () => {
|
|
128
|
+
const outcome = await ViewOperationsHandler.RunViews([{ EntityName: 'Employees' }], Intern());
|
|
129
|
+
expect(JSON.stringify(outcome.results)).not.toContain(String(SECRET_SALARY));
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it('REGRESSION: ListEntities omits a denied field from full-width rows', async () => {
|
|
133
|
+
const result = await ViewOperationsHandler.ListEntities({ EntityName: 'Employees' }, Intern());
|
|
134
|
+
expect(JSON.stringify(result)).not.toContain(String(SECRET_SALARY));
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it('REGRESSION: a caller-chosen entity_object ResultType is forced to simple, singly and in a batch', async () => {
|
|
138
|
+
await ViewOperationsHandler.RunView({ EntityName: 'Employees', ResultType: 'entity_object' }, Intern());
|
|
139
|
+
await ViewOperationsHandler.RunViews([{ EntityName: 'Employees', ResultType: 'entity_object' }], Intern());
|
|
140
|
+
expect((mockRunViewFn.mock.calls[0][0] as RunViewParams).ResultType).toBe('simple');
|
|
141
|
+
expect((mockRunViewsFn.mock.calls[0][0] as RunViewParams[])[0].ResultType).toBe('simple');
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
it('a caller who may read the field still receives it', async () => {
|
|
145
|
+
const outcome = await ViewOperationsHandler.RunView({ EntityName: 'Employees' }, HRUser());
|
|
146
|
+
expect(outcome.result?.Results[0]).toMatchObject({ Salary: SECRET_SALARY });
|
|
147
|
+
});
|
|
148
|
+
});
|