@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
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* #6007: concurrent `CreateQueryExtended` calls with the same name.
|
|
3
|
+
*
|
|
4
|
+
* Every request first checks that the name is free, so N requests that arrive together all pass
|
|
5
|
+
* the check and then race to insert. The database's unique index on (Name, CategoryID) lets one
|
|
6
|
+
* win. Before the fix, every loser found the winner's row and returned it as its own result, even
|
|
7
|
+
* with `AutoResolveCollision`, so N callers shared one query. Now:
|
|
8
|
+
*
|
|
9
|
+
* - with `AutoResolveCollision`, a loser picks a new unique name and inserts again (bounded), so
|
|
10
|
+
* every request gets its own query;
|
|
11
|
+
* - without it, the existing create-or-get behaviour stays: losers get the query that now exists;
|
|
12
|
+
* - the existence lookup reads the database, never a cache.
|
|
13
|
+
*
|
|
14
|
+
* The provider is a stub whose saves yield before inserting, so concurrent saves interleave the
|
|
15
|
+
* way they do against a real database, and whose insert enforces the unique name.
|
|
16
|
+
*/
|
|
17
|
+
import 'reflect-metadata';
|
|
18
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
19
|
+
import type { RunViewParams } from '@memberjunction/core';
|
|
20
|
+
|
|
21
|
+
vi.mock('type-graphql', () => {
|
|
22
|
+
const decoratorFactory = (..._args: unknown[]) => (..._decorated: unknown[]) => undefined;
|
|
23
|
+
const exportNames = ['Arg', 'Ctx', 'Field', 'InputType', 'Mutation', 'ObjectType', 'Resolver', 'PubSub', 'Int', 'Float'];
|
|
24
|
+
return { ...Object.fromEntries(exportNames.map((name) => [name, decoratorFactory])), registerEnumType: () => undefined };
|
|
25
|
+
});
|
|
26
|
+
vi.mock('@memberjunction/core-entities-server', () => ({ MJQueryEntityServer: class {} }));
|
|
27
|
+
vi.mock('../generic/DeleteOptionsInput.js', () => ({ DeleteOptionsInput: class {} }));
|
|
28
|
+
vi.mock('@memberjunction/core', async (importOriginal) => {
|
|
29
|
+
const actual = await importOriginal<typeof import('@memberjunction/core')>();
|
|
30
|
+
return { ...actual, AssertClientInputWritableForUser: () => undefined, LogStatus: () => undefined };
|
|
31
|
+
});
|
|
32
|
+
vi.mock('../generated/generated.js', () => ({
|
|
33
|
+
MJQuery_: class {}, MJQueryField_: class {}, MJQueryParameter_: class {}, MJQueryEntity_: class {}, MJQueryPermission_: class {},
|
|
34
|
+
MJQueryResolver: class {
|
|
35
|
+
protected async CheckAPIKeyScopeAuthorization(): Promise<void> { /* authorized */ }
|
|
36
|
+
protected async AfterCreate(): Promise<void> { /* no event */ }
|
|
37
|
+
protected ListenForEntityMessages(): void { /* no pub/sub */ }
|
|
38
|
+
protected async MapFieldNamesToCodeNames(_entityName: string, values: Record<string, unknown>) { return values; }
|
|
39
|
+
},
|
|
40
|
+
}));
|
|
41
|
+
|
|
42
|
+
import { MJQueryResolverExtended, CreateQuerySystemUserInput } from '../resolvers/QuerySystemUserResolver.js';
|
|
43
|
+
import type { AppContext } from '../types.js';
|
|
44
|
+
|
|
45
|
+
/** One stored query row. */
|
|
46
|
+
interface StoredQuery { ID: string; Name: string; CategoryID: string | null }
|
|
47
|
+
|
|
48
|
+
const CATEGORY = 'C0000000-0000-0000-0000-000000000001';
|
|
49
|
+
let rows: StoredQuery[];
|
|
50
|
+
let lookups: RunViewParams[];
|
|
51
|
+
/** The child-row reads the resolver made, with every cache bypassed or not. */
|
|
52
|
+
let childReads: RunViewParams[];
|
|
53
|
+
/** The field rows stored per query ID, as the database holds them (the query cache holds none). */
|
|
54
|
+
let storedFields: Map<string, Array<{ ID: string; QueryID: string; Name: string; Sequence: number }>>;
|
|
55
|
+
let nextID: number;
|
|
56
|
+
|
|
57
|
+
/** A query record as the stub provider hands out: its insert yields first and enforces the unique name. */
|
|
58
|
+
class StubQueryRecord {
|
|
59
|
+
public ID = '';
|
|
60
|
+
public Name = '';
|
|
61
|
+
public CategoryID: string | null = null;
|
|
62
|
+
public ParameterHints?: Map<string, string>;
|
|
63
|
+
public EntityInfo = {};
|
|
64
|
+
public LatestResult: { Message: string; CompleteMessage: string } | null = null;
|
|
65
|
+
public QueryFields = [];
|
|
66
|
+
public QueryParameters = [];
|
|
67
|
+
public QueryEntities = [];
|
|
68
|
+
public QueryPermissions = [];
|
|
69
|
+
|
|
70
|
+
SetMany(values: Record<string, unknown>): void {
|
|
71
|
+
if (typeof values.Name === 'string') this.Name = values.Name;
|
|
72
|
+
if (typeof values.CategoryID === 'string') this.CategoryID = values.CategoryID;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async Save(): Promise<boolean> {
|
|
76
|
+
await new Promise(resolve => setTimeout(resolve, 1));
|
|
77
|
+
if (rows.some(r => r.Name.toLowerCase() === this.Name.toLowerCase() && r.CategoryID === this.CategoryID)) {
|
|
78
|
+
const message = `Cannot insert duplicate key row in object '__mj.Query' with unique index 'UX_Query_Name_CategoryID'. The duplicate key value is (${this.Name}).`;
|
|
79
|
+
this.LatestResult = { Message: message, CompleteMessage: message };
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
this.ID = `Q${++nextID}`;
|
|
83
|
+
rows.push({ ID: this.ID, Name: this.Name, CategoryID: this.CategoryID });
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async Load(id: string): Promise<boolean> {
|
|
88
|
+
const row = rows.find(r => r.ID === id);
|
|
89
|
+
if (!row) return false;
|
|
90
|
+
Object.assign(this, row);
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
GetAll(): Record<string, unknown> {
|
|
95
|
+
return { ID: this.ID, Name: this.Name, CategoryID: this.CategoryID };
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const provider = {
|
|
100
|
+
async GetEntityObject(): Promise<StubQueryRecord> {
|
|
101
|
+
return new StubQueryRecord();
|
|
102
|
+
},
|
|
103
|
+
async RunViews(params: RunViewParams[]) {
|
|
104
|
+
childReads.push(...params);
|
|
105
|
+
return params.map(p => {
|
|
106
|
+
const queryID = /QueryID='(.*)'/.exec(p.ExtraFilter ?? '')?.[1] ?? '';
|
|
107
|
+
const results = p.EntityName === 'MJ: Query Fields' ? (storedFields.get(queryID) ?? []) : [];
|
|
108
|
+
return { Success: true, Results: results, RowCount: results.length, TotalRowCount: results.length, ExecutionTime: 0, ErrorMessage: '', UserViewRunID: '' };
|
|
109
|
+
});
|
|
110
|
+
},
|
|
111
|
+
async RunView(params: RunViewParams) {
|
|
112
|
+
lookups.push(params);
|
|
113
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
114
|
+
const name = /LOWER\(Name\) = LOWER\('(.*)'\)/.exec(params.ExtraFilter ?? '')?.[1]?.replace(/''/g, "'") ?? '';
|
|
115
|
+
const matches = rows.filter(r => r.Name.toLowerCase() === name.toLowerCase() && r.CategoryID === CATEGORY);
|
|
116
|
+
return { Success: true, Results: matches, RowCount: matches.length, TotalRowCount: matches.length, ExecutionTime: 0, ErrorMessage: '', UserViewRunID: '' };
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const context = {
|
|
121
|
+
providers: [{ provider, type: 'Read-Write' }],
|
|
122
|
+
userPayload: { userRecord: { ID: 'user-1', Email: 'u@example.com', UserRoles: [] } },
|
|
123
|
+
} as unknown as AppContext;
|
|
124
|
+
|
|
125
|
+
function input(name: string, autoResolve: boolean): CreateQuerySystemUserInput {
|
|
126
|
+
return Object.assign(new CreateQuerySystemUserInput(), { Name: name, CategoryID: CATEGORY, SQL: 'SELECT 1 AS One', AutoResolveCollision: autoResolve });
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
async function createConcurrently(count: number, name: string, autoResolve: boolean) {
|
|
130
|
+
const resolver = new MJQueryResolverExtended();
|
|
131
|
+
const pubSub = { publish: async () => undefined } as unknown as Parameters<MJQueryResolverExtended['CreateQueryExtended']>[2];
|
|
132
|
+
return Promise.all(Array.from({ length: count }, () => resolver.CreateQueryExtended(input(name, autoResolve), context, pubSub)));
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
beforeEach(() => {
|
|
136
|
+
rows = [];
|
|
137
|
+
lookups = [];
|
|
138
|
+
childReads = [];
|
|
139
|
+
storedFields = new Map();
|
|
140
|
+
nextID = 0;
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
describe('CreateQueryExtended — concurrent creates with the same name (#6007)', () => {
|
|
144
|
+
it('with AutoResolveCollision, gives every concurrent request its own query with its own name', async () => {
|
|
145
|
+
const results = await createConcurrently(8, 'Revenue By Region', true);
|
|
146
|
+
|
|
147
|
+
expect(results.every(r => r.Success)).toBe(true);
|
|
148
|
+
const ids = new Set(results.map(r => r.Query?.ID));
|
|
149
|
+
const names = new Set(results.map(r => r.Query?.Name));
|
|
150
|
+
expect(ids.size).toBe(8);
|
|
151
|
+
expect(names.size).toBe(8);
|
|
152
|
+
expect(rows).toHaveLength(8);
|
|
153
|
+
expect([...names]).toContain('Revenue By Region');
|
|
154
|
+
expect([...names].filter(n => n !== 'Revenue By Region').every(n => /^Revenue By Region \(\d+\)$/.test(String(n)))).toBe(true);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
it('without AutoResolveCollision, keeps create-or-get: the requests that lose the race get the query that now exists', async () => {
|
|
158
|
+
const results = await createConcurrently(5, 'Orders Today', false);
|
|
159
|
+
|
|
160
|
+
expect(results.every(r => r.Success)).toBe(true);
|
|
161
|
+
expect(rows).toHaveLength(1);
|
|
162
|
+
expect(new Set(results.map(r => r.Query?.ID))).toEqual(new Set([rows[0].ID]));
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it('without AutoResolveCollision, a request that loses the race gets the other query\'s fields, read from the database', async () => {
|
|
166
|
+
const saveOnce = StubQueryRecord.prototype.Save;
|
|
167
|
+
vi.spyOn(StubQueryRecord.prototype, 'Save').mockImplementation(async function (this: StubQueryRecord) {
|
|
168
|
+
const saved = await saveOnce.call(this);
|
|
169
|
+
if (saved) storedFields.set(this.ID, [{ ID: `${this.ID}-f1`, QueryID: this.ID, Name: 'One', Sequence: 1 }]);
|
|
170
|
+
return saved;
|
|
171
|
+
});
|
|
172
|
+
const results = await createConcurrently(3, 'With Fields', false);
|
|
173
|
+
|
|
174
|
+
const winnerID = rows[0].ID;
|
|
175
|
+
const losers = results.filter(r => r.Fields?.length === 1);
|
|
176
|
+
expect(losers).toHaveLength(2);
|
|
177
|
+
expect(losers.every(r => r.Query?.ID === winnerID && r.Fields?.[0].Name === 'One')).toBe(true);
|
|
178
|
+
expect(childReads.length).toBeGreaterThan(0);
|
|
179
|
+
expect(childReads.every(r => r.BypassCache === true)).toBe(true);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it('reads every existence check from the database, never a cache', async () => {
|
|
183
|
+
await createConcurrently(3, 'Uncached', true);
|
|
184
|
+
|
|
185
|
+
expect(lookups.length).toBeGreaterThan(0);
|
|
186
|
+
expect(lookups.every(l => l.BypassCache === true)).toBe(true);
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it('returns the save failure itself when it is not a name race', async () => {
|
|
190
|
+
vi.spyOn(StubQueryRecord.prototype, 'Save').mockImplementationOnce(async function (this: StubQueryRecord) {
|
|
191
|
+
this.LatestResult = { Message: 'Query "Bad" was not saved: MJQ_TAG_IN_STRING_LITERAL', CompleteMessage: 'Query "Bad" was not saved: MJQ_TAG_IN_STRING_LITERAL' };
|
|
192
|
+
return false;
|
|
193
|
+
});
|
|
194
|
+
const [result] = await createConcurrently(1, 'Bad', true);
|
|
195
|
+
|
|
196
|
+
expect(result.Success).toBe(false);
|
|
197
|
+
expect(result.ErrorMessage).toContain('MJQ_TAG_IN_STRING_LITERAL');
|
|
198
|
+
expect(rows).toHaveLength(0);
|
|
199
|
+
});
|
|
200
|
+
});
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The saved query that `CreateQueryExtended` / `UpdateQueryExtended` return is mapped for the
|
|
3
|
+
* CALLER. These mutations are reachable with the `query:create` / `query:update` API-key scopes,
|
|
4
|
+
* not only by the system user, and the record they return is the one just saved, whose re-read
|
|
5
|
+
* holds every column. Mapping it with no context user skipped the field-security projection
|
|
6
|
+
* altogether, so the caller received columns its roles may not read.
|
|
7
|
+
*
|
|
8
|
+
* The base resolver is stubbed with the real projection (`ProjectValuesForCaller`) standing in
|
|
9
|
+
* for its field mapping, so what is pinned is the identity the result is mapped for.
|
|
10
|
+
*/
|
|
11
|
+
import 'reflect-metadata';
|
|
12
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
13
|
+
|
|
14
|
+
vi.mock('type-graphql', () => {
|
|
15
|
+
const decoratorFactory = (..._args: unknown[]) => (..._decorated: unknown[]) => undefined;
|
|
16
|
+
const exportNames = ['Arg', 'Ctx', 'Field', 'InputType', 'Mutation', 'ObjectType', 'Resolver', 'PubSub', 'Int', 'Float'];
|
|
17
|
+
return { ...Object.fromEntries(exportNames.map((name) => [name, decoratorFactory])), registerEnumType: () => undefined };
|
|
18
|
+
});
|
|
19
|
+
vi.mock('@memberjunction/core-entities-server', () => ({ MJQueryEntityServer: class {} }));
|
|
20
|
+
vi.mock('../generic/DeleteOptionsInput.js', () => ({ DeleteOptionsInput: class {} }));
|
|
21
|
+
vi.mock('../generated/generated.js', async () => {
|
|
22
|
+
const { ProjectValuesForCaller } = await import('../generic/fieldSecurityTransport.js');
|
|
23
|
+
const { EmployeeEntity, NoRecordChangesMetadata } = await import('./fieldSecurityFixtures.js');
|
|
24
|
+
return {
|
|
25
|
+
MJQuery_: class {}, MJQueryField_: class {}, MJQueryParameter_: class {}, MJQueryEntity_: class {}, MJQueryPermission_: class {},
|
|
26
|
+
MJQueryResolver: class {
|
|
27
|
+
protected async MapFieldNamesToCodeNames(_entityName: string, values: Record<string, unknown>, contextUser?: unknown) {
|
|
28
|
+
return ProjectValuesForCaller(EmployeeEntity(), values, contextUser as never, NoRecordChangesMetadata);
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
import { MJQueryResolverExtended } from '../resolvers/QuerySystemUserResolver.js';
|
|
35
|
+
import { FullWidthEmployeeRow, Intern, NoRecordChangesMetadata, SECRET_SALARY } from './fieldSecurityFixtures.js';
|
|
36
|
+
|
|
37
|
+
describe('QuerySystemUserResolver: the saved query is mapped for the caller', () => {
|
|
38
|
+
it('REGRESSION: buildSuccessResult never returns a column the caller may not read', async () => {
|
|
39
|
+
const build = (MJQueryResolverExtended.prototype as unknown as {
|
|
40
|
+
buildSuccessResult(entity: unknown, user: unknown, provider: unknown): Promise<{ Query: Record<string, unknown> }>;
|
|
41
|
+
}).buildSuccessResult;
|
|
42
|
+
const entity = { GetAll: () => FullWidthEmployeeRow(), QueryFields: [], QueryParameters: [], QueryEntities: [], QueryPermissions: [] };
|
|
43
|
+
|
|
44
|
+
const result = await build.call(new MJQueryResolverExtended(), entity, Intern(), NoRecordChangesMetadata);
|
|
45
|
+
|
|
46
|
+
expect(JSON.stringify(result.Query)).not.toContain(String(SECRET_SALARY));
|
|
47
|
+
expect(result.Query).toMatchObject({ ID: 'emp-1', Name: 'Ada' });
|
|
48
|
+
});
|
|
49
|
+
});
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `CreateQueryExtended` / `UpdateQueryExtended`: a query-permission row that is not saved or not
|
|
3
|
+
* deleted fails the mutation with the entity's own reason, instead of reporting success.
|
|
4
|
+
*
|
|
5
|
+
* The provider is a stub; permission rows are stubs whose Save / Delete report failure on demand.
|
|
6
|
+
*/
|
|
7
|
+
import 'reflect-metadata';
|
|
8
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
9
|
+
import type { RunViewParams } from '@memberjunction/core';
|
|
10
|
+
import { QueryEngine } from '@memberjunction/core-entities';
|
|
11
|
+
|
|
12
|
+
vi.mock('type-graphql', () => {
|
|
13
|
+
const decoratorFactory = (..._args: unknown[]) => (..._decorated: unknown[]) => undefined;
|
|
14
|
+
const exportNames = ['Arg', 'Ctx', 'Field', 'InputType', 'Mutation', 'ObjectType', 'Resolver', 'PubSub', 'Int', 'Float'];
|
|
15
|
+
return { ...Object.fromEntries(exportNames.map((name) => [name, decoratorFactory])), registerEnumType: () => undefined };
|
|
16
|
+
});
|
|
17
|
+
vi.mock('@memberjunction/core-entities-server', () => ({ MJQueryEntityServer: class {} }));
|
|
18
|
+
vi.mock('../generic/DeleteOptionsInput.js', () => ({ DeleteOptionsInput: class {} }));
|
|
19
|
+
vi.mock('@memberjunction/core', async (importOriginal) => {
|
|
20
|
+
const actual = await importOriginal<typeof import('@memberjunction/core')>();
|
|
21
|
+
return { ...actual, AssertClientInputWritableForUser: () => undefined, LogStatus: () => undefined, LogError: () => undefined };
|
|
22
|
+
});
|
|
23
|
+
vi.mock('../generated/generated.js', () => ({
|
|
24
|
+
MJQuery_: class {}, MJQueryField_: class {}, MJQueryParameter_: class {}, MJQueryEntity_: class {}, MJQueryPermission_: class {},
|
|
25
|
+
MJQueryResolver: class {
|
|
26
|
+
protected async CheckAPIKeyScopeAuthorization(): Promise<void> { /* authorized */ }
|
|
27
|
+
protected async AfterCreate(): Promise<void> { /* no event */ }
|
|
28
|
+
protected ListenForEntityMessages(): void { /* no pub/sub */ }
|
|
29
|
+
protected async MapFieldNamesToCodeNames(_entityName: string, values: Record<string, unknown>) { return values; }
|
|
30
|
+
},
|
|
31
|
+
}));
|
|
32
|
+
|
|
33
|
+
import { MJQueryResolverExtended, CreateQuerySystemUserInput, UpdateQuerySystemUserInput } from '../resolvers/QuerySystemUserResolver.js';
|
|
34
|
+
import type { AppContext } from '../types.js';
|
|
35
|
+
|
|
36
|
+
const QUERY_ID = 'Q0000000-0000-0000-0000-000000000001';
|
|
37
|
+
const ROLE = 'R0000000-0000-0000-0000-000000000001';
|
|
38
|
+
const REFUSED = 'The INSERT statement conflicted with the FOREIGN KEY constraint "FK_QueryPermission_Role".';
|
|
39
|
+
|
|
40
|
+
/** A query or permission row as the stub provider hands out. */
|
|
41
|
+
class StubRecord {
|
|
42
|
+
public ID = '';
|
|
43
|
+
public Name = 'Revenue';
|
|
44
|
+
public CategoryID: string | null = null;
|
|
45
|
+
public QueryID = '';
|
|
46
|
+
public RoleID = '';
|
|
47
|
+
public EntityInfo = {};
|
|
48
|
+
public LatestResult: { Message: string; CompleteMessage: string } | null = null;
|
|
49
|
+
public QueryFields = [];
|
|
50
|
+
public QueryParameters = [];
|
|
51
|
+
public QueryEntities = [];
|
|
52
|
+
public QueryPermissions = [];
|
|
53
|
+
constructor(private readonly entityName: string) {}
|
|
54
|
+
SetMany(): void { /* fields are not inspected */ }
|
|
55
|
+
async Load(id: string): Promise<boolean> { this.ID = id; return true; }
|
|
56
|
+
async Save(): Promise<boolean> {
|
|
57
|
+
if (this.entityName === 'MJ: Query Permissions' && failPermissionSave) {
|
|
58
|
+
this.LatestResult = { Message: REFUSED, CompleteMessage: REFUSED };
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
if (!this.ID) this.ID = QUERY_ID;
|
|
62
|
+
permissionWrites.push(`${this.entityName}:save`);
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
GetAll(): Record<string, unknown> { return { ID: this.ID, Name: this.Name }; }
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
let failPermissionSave: boolean;
|
|
69
|
+
let permissionWrites: string[];
|
|
70
|
+
|
|
71
|
+
const provider = {
|
|
72
|
+
async GetEntityObject(entityName: string): Promise<StubRecord> { return new StubRecord(entityName); },
|
|
73
|
+
async RunView(_params: RunViewParams) {
|
|
74
|
+
return { Success: true, Results: [], RowCount: 0, TotalRowCount: 0, ExecutionTime: 0, ErrorMessage: '', UserViewRunID: '' };
|
|
75
|
+
},
|
|
76
|
+
async RunViews(params: RunViewParams[]) {
|
|
77
|
+
return params.map(() => ({ Success: true, Results: [], RowCount: 0, TotalRowCount: 0, ExecutionTime: 0, ErrorMessage: '', UserViewRunID: '' }));
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const context = {
|
|
82
|
+
providers: [{ provider, type: 'Read-Write' }],
|
|
83
|
+
userPayload: { userRecord: { ID: 'user-1', Email: 'u@example.com', UserRoles: [] } },
|
|
84
|
+
} as unknown as AppContext;
|
|
85
|
+
const pubSub = { publish: async () => undefined } as unknown as Parameters<MJQueryResolverExtended['CreateQueryExtended']>[2];
|
|
86
|
+
|
|
87
|
+
/** A stored permission row whose Delete fails with the entity's reason. */
|
|
88
|
+
function undeletablePermission() {
|
|
89
|
+
return {
|
|
90
|
+
RoleID: ROLE,
|
|
91
|
+
LatestResult: { Message: 'Delete refused by row-level security', CompleteMessage: 'Delete refused by row-level security' },
|
|
92
|
+
Delete: async () => false,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
beforeEach(() => {
|
|
97
|
+
failPermissionSave = false;
|
|
98
|
+
permissionWrites = [];
|
|
99
|
+
vi.restoreAllMocks();
|
|
100
|
+
vi.spyOn(QueryEngine, 'Instance', 'get').mockReturnValue({ GetQueryPermissions: () => [] } as unknown as QueryEngine);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
describe('query permission writes report their failures', () => {
|
|
104
|
+
it('a create whose permission row is not saved fails, naming the query, the role and the reason', async () => {
|
|
105
|
+
failPermissionSave = true;
|
|
106
|
+
const input = Object.assign(new CreateQuerySystemUserInput(), { Name: 'Revenue', SQL: 'SELECT 1 AS One', Permissions: [{ RoleID: ROLE }] });
|
|
107
|
+
const result = await new MJQueryResolverExtended().CreateQueryExtended(input, context, pubSub);
|
|
108
|
+
|
|
109
|
+
expect(result.Success).toBe(false);
|
|
110
|
+
expect(result.ErrorMessage).toContain(`Query 'Revenue' (ID ${QUERY_ID}) was created, but its permissions were not`);
|
|
111
|
+
expect(result.ErrorMessage).toContain(`role ${ROLE}: ${REFUSED}`);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('an update whose new permission row is not saved fails with the reason', async () => {
|
|
115
|
+
failPermissionSave = true;
|
|
116
|
+
const input = Object.assign(new UpdateQuerySystemUserInput(), { ID: QUERY_ID, Permissions: [{ RoleID: ROLE }] });
|
|
117
|
+
const result = await new MJQueryResolverExtended().UpdateQueryExtended(input, context, pubSub);
|
|
118
|
+
|
|
119
|
+
expect(result.Success).toBe(false);
|
|
120
|
+
expect(result.ErrorMessage).toBe(`Failed to update query permissions: Failed to save the query permission for role ${ROLE}: ${REFUSED}`);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it('an update whose old permission row is not deleted fails with the reason and saves no new row', async () => {
|
|
124
|
+
vi.spyOn(QueryEngine, 'Instance', 'get').mockReturnValue({ GetQueryPermissions: () => [undeletablePermission()] } as unknown as QueryEngine);
|
|
125
|
+
const input = Object.assign(new UpdateQuerySystemUserInput(), { ID: QUERY_ID, Permissions: [{ RoleID: ROLE }] });
|
|
126
|
+
const result = await new MJQueryResolverExtended().UpdateQueryExtended(input, context, pubSub);
|
|
127
|
+
|
|
128
|
+
expect(result.Success).toBe(false);
|
|
129
|
+
expect(result.ErrorMessage).toBe(`Failed to update query permissions: Failed to delete the query permission for role ${ROLE}: Delete refused by row-level security`);
|
|
130
|
+
expect(permissionWrites).not.toContain('MJ: Query Permissions:save');
|
|
131
|
+
});
|
|
132
|
+
});
|
|
@@ -110,6 +110,7 @@ interface ReqShape {
|
|
|
110
110
|
query?: Record<string, string>;
|
|
111
111
|
body?: unknown;
|
|
112
112
|
mjUser?: UserInfo;
|
|
113
|
+
timeZone?: string;
|
|
113
114
|
}
|
|
114
115
|
|
|
115
116
|
function makeReq(shape: ReqShape = {}): express.Request {
|
|
@@ -118,6 +119,7 @@ function makeReq(shape: ReqShape = {}): express.Request {
|
|
|
118
119
|
query: shape.query ?? {},
|
|
119
120
|
body: shape.body ?? {},
|
|
120
121
|
mjUser: shape.mjUser ?? MJ_USER,
|
|
122
|
+
userPayload: { TimeZone: shape.timeZone },
|
|
121
123
|
} as unknown as express.Request;
|
|
122
124
|
}
|
|
123
125
|
|
|
@@ -540,6 +542,17 @@ describe('RESTEndpointHandler view routes', () => {
|
|
|
540
542
|
expect(jsonBody()).toEqual({ Success: true, Results: [{ ID: '1' }] });
|
|
541
543
|
});
|
|
542
544
|
|
|
545
|
+
it('drops fields only server code may set, takes the time zone from the header, and keeps the route\'s entity over the body\'s', async () => {
|
|
546
|
+
mockOpsRunView.mockResolvedValue({ success: true, result: { Success: true, Results: [] } });
|
|
547
|
+
const handler = makeHandler();
|
|
548
|
+
const req = makeReq({ params: { entityName: 'Users' }, body: { EntityName: 'Secrets', TimeZone: 'Asia/Tokyo', MaxRows: 5 }, timeZone: 'Europe/Paris' });
|
|
549
|
+
const { res } = makeRes();
|
|
550
|
+
|
|
551
|
+
await handler.runView(req, res);
|
|
552
|
+
|
|
553
|
+
expect(mockOpsRunView).toHaveBeenCalledWith({ EntityName: 'Users', MaxRows: 5, TimeZone: 'Europe/Paris' }, MJ_USER);
|
|
554
|
+
});
|
|
555
|
+
|
|
543
556
|
it('maps view-layer failures to 400', async () => {
|
|
544
557
|
mockOpsRunView.mockResolvedValue({ success: false, error: 'does not have permission' });
|
|
545
558
|
const handler = makeHandler();
|
|
@@ -591,6 +604,18 @@ describe('RESTEndpointHandler view routes', () => {
|
|
|
591
604
|
expect(jsonBody()).toEqual([{ Success: true, Results: [] }]);
|
|
592
605
|
});
|
|
593
606
|
|
|
607
|
+
it('drops fields only server code may set from every batched view', async () => {
|
|
608
|
+
mockOpsRunViews.mockResolvedValue({ success: true, results: [{ Success: true, Results: [] }] });
|
|
609
|
+
const handler = makeHandler();
|
|
610
|
+
const req = makeReq({ body: { params: [{ EntityName: 'Users', TimeZone: 'Asia/Tokyo' }] }, timeZone: 'Europe/Paris' });
|
|
611
|
+
const { res } = makeRes();
|
|
612
|
+
|
|
613
|
+
await handler.runViews(req, res);
|
|
614
|
+
|
|
615
|
+
const [sent] = mockOpsRunViews.mock.calls[0] as [RunViewParams[], UserInfo];
|
|
616
|
+
expect(sent).toEqual([{ EntityName: 'Users', TimeZone: 'Europe/Paris' }]);
|
|
617
|
+
});
|
|
618
|
+
|
|
594
619
|
it('maps view-layer batch failures to 400', async () => {
|
|
595
620
|
mockOpsRunViews.mockResolvedValue({ success: false, error: 'batch failed' });
|
|
596
621
|
const handler = makeHandler();
|