@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,207 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { describe, it, expect, beforeAll, afterAll, vi } from 'vitest';
|
|
3
|
+
import sql from 'mssql';
|
|
4
|
+
import { RunViewParams, RunViewResult, SetProvider, UserInfo } from '@memberjunction/core';
|
|
5
|
+
import { GenericDatabaseProvider, UserCache } from '@memberjunction/generic-database-provider';
|
|
6
|
+
import { SQLServerDataProvider, SQLServerProviderConfigData } from '@memberjunction/sqlserver-dataprovider';
|
|
7
|
+
import {
|
|
8
|
+
CacheInvalidationBroadcastManager,
|
|
9
|
+
SequencedRoleBucketBroadcastProvider,
|
|
10
|
+
} from '../broadcast/index.js';
|
|
11
|
+
|
|
12
|
+
const IT_DB_NAME = process.env.MJ_IT_DB;
|
|
13
|
+
|
|
14
|
+
describe.skipIf(!IT_DB_NAME)('MJServer Scalability Architecture — Live SQL Server Integration', () => {
|
|
15
|
+
let pool: sql.ConnectionPool;
|
|
16
|
+
let sharedProvider: SQLServerDataProvider;
|
|
17
|
+
let sysUser: UserInfo;
|
|
18
|
+
|
|
19
|
+
beforeAll(async () => {
|
|
20
|
+
pool = new sql.ConnectionPool({
|
|
21
|
+
server: process.env.MJ_IT_HOST || 'localhost',
|
|
22
|
+
port: parseInt(process.env.MJ_IT_PORT || '1433', 10),
|
|
23
|
+
database: IT_DB_NAME,
|
|
24
|
+
user: process.env.MJ_IT_USER || 'sa',
|
|
25
|
+
password: process.env.MJ_IT_PASSWORD || 'GHWUc7QKZNT8GQiqnJHdEPonPcukY2WA',
|
|
26
|
+
options: {
|
|
27
|
+
encrypt: false,
|
|
28
|
+
trustServerCertificate: true,
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
await pool.connect();
|
|
32
|
+
|
|
33
|
+
sharedProvider = new SQLServerDataProvider();
|
|
34
|
+
const config = new SQLServerProviderConfigData(pool, '__mj', 0);
|
|
35
|
+
await sharedProvider.Config(config);
|
|
36
|
+
SetProvider(sharedProvider);
|
|
37
|
+
await UserCache.Instance.Refresh(sharedProvider, 0);
|
|
38
|
+
|
|
39
|
+
const foundUser =
|
|
40
|
+
UserCache.Instance.GetSystemUser() ||
|
|
41
|
+
UserCache.Instance.Users.find((u) => u.IsActive && u.Type === 'Owner') ||
|
|
42
|
+
UserCache.Instance.Users[0];
|
|
43
|
+
if (!foundUser) {
|
|
44
|
+
throw new Error(`No user found in ${IT_DB_NAME}`);
|
|
45
|
+
}
|
|
46
|
+
sysUser = foundUser;
|
|
47
|
+
}, 60_000);
|
|
48
|
+
|
|
49
|
+
afterAll(async () => {
|
|
50
|
+
if (pool?.connected) {
|
|
51
|
+
await pool.close();
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('creates per-request SQLServerDataProvider with zero-copy prototype-delegated metadata shell and lazy transaction queues', async () => {
|
|
56
|
+
const reqProvider = new SQLServerDataProvider();
|
|
57
|
+
const reqConfig = new SQLServerProviderConfigData(
|
|
58
|
+
pool,
|
|
59
|
+
'__mj',
|
|
60
|
+
0,
|
|
61
|
+
undefined,
|
|
62
|
+
undefined,
|
|
63
|
+
false // ignoreExistingMetadata = false -> reuses shared metadata shell
|
|
64
|
+
);
|
|
65
|
+
await reqProvider.Config(reqConfig);
|
|
66
|
+
|
|
67
|
+
// Verify lazy RxJS Subjects are NOT allocated on a read-only request provider
|
|
68
|
+
const internal = reqProvider as unknown as {
|
|
69
|
+
_sqlQueue$: unknown;
|
|
70
|
+
_transactionState$: unknown;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
expect(internal._sqlQueue$).toBeNull();
|
|
74
|
+
expect(internal._transactionState$).toBeNull();
|
|
75
|
+
|
|
76
|
+
// Verify zero-copy prototype delegation to shared metadata
|
|
77
|
+
expect(Object.getPrototypeOf(reqProvider.AllMetadata)).toBe(sharedProvider.AllMetadata);
|
|
78
|
+
expect(reqProvider.Entities.length).toBeGreaterThan(50);
|
|
79
|
+
expect(reqProvider.Entities).toBe(sharedProvider.Entities);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('coalesces 10 concurrent identical InternalRunView calls against SQL Server into a single SQL execution and isolates result mutations', async () => {
|
|
83
|
+
// Warm up the view column order cache for vwEntities (must return >=1 row so sortViewRowKeys caches sys.columns)
|
|
84
|
+
await sharedProvider.RunView(
|
|
85
|
+
{
|
|
86
|
+
EntityName: 'MJ: Entities',
|
|
87
|
+
ExtraFilter: "Name = 'MJ: Entities'",
|
|
88
|
+
ResultType: 'simple',
|
|
89
|
+
IgnoreMaxRows: true,
|
|
90
|
+
},
|
|
91
|
+
sysUser
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
const executeSpy = vi.spyOn(sharedProvider, 'ExecuteSQL');
|
|
95
|
+
const internalRunner = sharedProvider as unknown as {
|
|
96
|
+
InternalRunView<T>(params: RunViewParams, contextUser?: UserInfo): Promise<RunViewResult<T>>;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
try {
|
|
100
|
+
const concurrentCount = 10;
|
|
101
|
+
const promises = Array.from({ length: concurrentCount }, () =>
|
|
102
|
+
internalRunner.InternalRunView<Record<string, unknown>>(
|
|
103
|
+
{
|
|
104
|
+
EntityName: 'MJ: Entities',
|
|
105
|
+
ExtraFilter: "SchemaName = '__mj' AND Name LIKE 'MJ: %'",
|
|
106
|
+
OrderBy: 'Name ASC',
|
|
107
|
+
IgnoreMaxRows: true,
|
|
108
|
+
ResultType: 'simple',
|
|
109
|
+
},
|
|
110
|
+
sysUser
|
|
111
|
+
)
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
const results = await Promise.all(promises);
|
|
115
|
+
|
|
116
|
+
// Only 1 physical SQL execution should have been issued for the 10 identical concurrent views
|
|
117
|
+
expect(executeSpy).toHaveBeenCalledTimes(1);
|
|
118
|
+
|
|
119
|
+
for (const res of results) {
|
|
120
|
+
expect(res.Success).toBe(true);
|
|
121
|
+
expect(res.Results.length).toBeGreaterThan(0);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Mutating caller 0's result array or row object must not affect caller 1's result
|
|
125
|
+
const originalName = results[1].Results[0].Name;
|
|
126
|
+
const originalLength = results[1].Results.length;
|
|
127
|
+
results[0].Results[0].Name = 'MUTATED_IN_CALLER_0';
|
|
128
|
+
results[0].Results.pop();
|
|
129
|
+
|
|
130
|
+
expect(results[1].Results[0].Name).toBe(originalName);
|
|
131
|
+
expect(results[0].Results.length).toBe(originalLength - 1);
|
|
132
|
+
expect(results[1].Results.length).toBe(originalLength);
|
|
133
|
+
} finally {
|
|
134
|
+
executeSpy.mockRestore();
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('bounds concurrent SQL executions in RunViews to MaxConcurrentViewsPerBatch', async () => {
|
|
139
|
+
let activeCount = 0;
|
|
140
|
+
let maxObservedConcurrency = 0;
|
|
141
|
+
|
|
142
|
+
const originalExecuteSQL = sharedProvider.ExecuteSQL.bind(sharedProvider);
|
|
143
|
+
const executeSpy = vi.spyOn(sharedProvider, 'ExecuteSQL').mockImplementation(async (query, params, options, contextUser) => {
|
|
144
|
+
activeCount++;
|
|
145
|
+
if (activeCount > maxObservedConcurrency) {
|
|
146
|
+
maxObservedConcurrency = activeCount;
|
|
147
|
+
}
|
|
148
|
+
try {
|
|
149
|
+
return await originalExecuteSQL(query, params, options, contextUser);
|
|
150
|
+
} finally {
|
|
151
|
+
activeCount--;
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
try {
|
|
156
|
+
const batchParams = Array.from({ length: 16 }, (_, idx) => ({
|
|
157
|
+
EntityName: 'MJ: Entities',
|
|
158
|
+
ExtraFilter: `SchemaName = '__mj' AND UserViewMaxRows IS NULL AND ${idx} = ${idx}`,
|
|
159
|
+
IgnoreMaxRows: true,
|
|
160
|
+
ResultType: 'simple' as const,
|
|
161
|
+
}));
|
|
162
|
+
|
|
163
|
+
const batchResults = await sharedProvider.RunViews(batchParams, sysUser);
|
|
164
|
+
expect(batchResults).toHaveLength(16);
|
|
165
|
+
for (const r of batchResults) {
|
|
166
|
+
expect(r.Success).toBe(true);
|
|
167
|
+
}
|
|
168
|
+
expect(maxObservedConcurrency).toBeLessThanOrEqual(GenericDatabaseProvider.MaxConcurrentViewsPerBatch);
|
|
169
|
+
expect(maxObservedConcurrency).toBeGreaterThan(1);
|
|
170
|
+
} finally {
|
|
171
|
+
executeSpy.mockRestore();
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it('sequences and shapes cache invalidation broadcasts against live entity metadata and replays delta catch-up', async () => {
|
|
176
|
+
const provider = CacheInvalidationBroadcastManager.Instance.Configure({
|
|
177
|
+
provider: 'SequencedRoleBucket',
|
|
178
|
+
ringBufferSize: 500,
|
|
179
|
+
}) as SequencedRoleBucketBroadcastProvider;
|
|
180
|
+
expect(provider).toBeInstanceOf(SequencedRoleBucketBroadcastProvider);
|
|
181
|
+
|
|
182
|
+
const baseSeq = provider.CurrentSequence;
|
|
183
|
+
const entityInfo = sharedProvider.Entities.find((e) => e.Name === 'MJ: Entities');
|
|
184
|
+
expect(entityInfo).toBeDefined();
|
|
185
|
+
|
|
186
|
+
const published = provider.RecordInvalidation({
|
|
187
|
+
entityName: 'MJ: Entities',
|
|
188
|
+
primaryKeyValues: JSON.stringify([{ FieldName: 'ID', Value: entityInfo!.ID }]),
|
|
189
|
+
action: 'save',
|
|
190
|
+
sourceServerId: 'it-server-node-1',
|
|
191
|
+
timestamp: new Date(),
|
|
192
|
+
recordData: JSON.stringify({ ID: entityInfo!.ID, Name: entityInfo!.Name }),
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
expect(published.sequence).toBe(baseSeq + 1);
|
|
196
|
+
expect(provider.CurrentSequence).toBe(baseSeq + 1);
|
|
197
|
+
|
|
198
|
+
// Verify delta catch-up shapes payload for sysUser against real MJ: Entities metadata
|
|
199
|
+
const catchUp = provider.GetChangesSince(baseSeq, sysUser);
|
|
200
|
+
expect(catchUp.RequiresFullRefresh).toBe(false);
|
|
201
|
+
expect(catchUp.CurrentSequence).toBe(baseSeq + 1);
|
|
202
|
+
expect(catchUp.Events).toHaveLength(1);
|
|
203
|
+
expect(catchUp.Events[0].EntityName).toBe('MJ: Entities');
|
|
204
|
+
expect(catchUp.Events[0].Sequence).toBe(baseSeq + 1);
|
|
205
|
+
expect(catchUp.Events[0].RecordData).toContain(entityInfo!.Name);
|
|
206
|
+
});
|
|
207
|
+
});
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
3
|
+
import type express from 'express';
|
|
4
|
+
|
|
5
|
+
const logStatusExCalls: Array<{ message: string; verboseOnly?: boolean }> = [];
|
|
6
|
+
const runViewSpy = vi.fn();
|
|
7
|
+
|
|
8
|
+
vi.mock('@memberjunction/core', async () => {
|
|
9
|
+
const actual = await vi.importActual<typeof import('@memberjunction/core')>('@memberjunction/core');
|
|
10
|
+
return {
|
|
11
|
+
...actual,
|
|
12
|
+
LogStatusEx: vi.fn((entry: { message: string; verboseOnly?: boolean }) => {
|
|
13
|
+
logStatusExCalls.push(entry);
|
|
14
|
+
}),
|
|
15
|
+
RunView: class MockRunView {
|
|
16
|
+
public RunView = runViewSpy;
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
import {
|
|
22
|
+
DEFAULT_REST_API_OPTIONS,
|
|
23
|
+
REST_API_BASE_PATH,
|
|
24
|
+
SetupRESTEndpoints,
|
|
25
|
+
} from '../rest/setupRESTEndpoints.js';
|
|
26
|
+
import { OAuthCallbackHandler } from '../rest/OAuthCallbackHandler.js';
|
|
27
|
+
import type { UserInfo } from '@memberjunction/core';
|
|
28
|
+
|
|
29
|
+
function createSpyExpressApp(): { app: express.Application; useCalls: express.RequestHandler[][] } {
|
|
30
|
+
const useCalls: express.RequestHandler[][] = [];
|
|
31
|
+
const partialApp = {
|
|
32
|
+
use: vi.fn((...args: express.RequestHandler[]) => {
|
|
33
|
+
useCalls.push(args);
|
|
34
|
+
return partialApp as express.Application;
|
|
35
|
+
}),
|
|
36
|
+
};
|
|
37
|
+
return { app: partialApp as express.Application, useCalls };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
describe('PR #6034 security hardening in MJServer', () => {
|
|
41
|
+
beforeEach(() => {
|
|
42
|
+
logStatusExCalls.length = 0;
|
|
43
|
+
runViewSpy.mockReset();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
describe('SetupRESTEndpoints fail-closed default & auth warning', () => {
|
|
47
|
+
it('defaults DEFAULT_REST_API_OPTIONS.enabled to false and mounts nothing when called without options', () => {
|
|
48
|
+
expect(DEFAULT_REST_API_OPTIONS.enabled).toBe(false);
|
|
49
|
+
|
|
50
|
+
const { app, useCalls } = createSpyExpressApp();
|
|
51
|
+
SetupRESTEndpoints(app);
|
|
52
|
+
|
|
53
|
+
expect(useCalls).toHaveLength(0);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('logs a non-verbose warning when enabled without a route-level authMiddleware', () => {
|
|
57
|
+
const { app, useCalls } = createSpyExpressApp();
|
|
58
|
+
SetupRESTEndpoints(app, { enabled: true });
|
|
59
|
+
|
|
60
|
+
expect(useCalls).toHaveLength(1);
|
|
61
|
+
expect(useCalls[0][0]).toBe(REST_API_BASE_PATH);
|
|
62
|
+
const warning = logStatusExCalls.find((c) =>
|
|
63
|
+
c.message.includes('WITHOUT a route-level auth middleware'),
|
|
64
|
+
);
|
|
65
|
+
expect(warning).toBeDefined();
|
|
66
|
+
expect(warning?.verboseOnly).toBeUndefined();
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('mounts authMiddleware and omits the unauthenticated warning when authMiddleware is supplied', () => {
|
|
70
|
+
const { app, useCalls } = createSpyExpressApp();
|
|
71
|
+
const authMw: express.RequestHandler = (_req, _res, next) => next();
|
|
72
|
+
|
|
73
|
+
SetupRESTEndpoints(app, { enabled: true }, authMw);
|
|
74
|
+
|
|
75
|
+
expect(useCalls).toHaveLength(1);
|
|
76
|
+
expect(useCalls[0]).toContain(authMw);
|
|
77
|
+
const warning = logStatusExCalls.find((c) =>
|
|
78
|
+
c.message.includes('WITHOUT a route-level auth middleware'),
|
|
79
|
+
);
|
|
80
|
+
expect(warning).toBeUndefined();
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
describe('OAuthCallbackHandler UUID validation on ExtraFilter IDs', () => {
|
|
85
|
+
it('refuses SQL injection connectionId before executing RunView', async () => {
|
|
86
|
+
const handler = new OAuthCallbackHandler({ baseUrl: 'https://api.example.com' });
|
|
87
|
+
const fakeUser = { ID: '00000000-0000-0000-0000-000000000001' } as UserInfo;
|
|
88
|
+
|
|
89
|
+
const loader = Reflect.get(handler, 'loadConnectionConfig') as (
|
|
90
|
+
connectionId: string,
|
|
91
|
+
contextUser: UserInfo,
|
|
92
|
+
) => Promise<Record<string, string> | null>;
|
|
93
|
+
|
|
94
|
+
const injectedResult = await loader.call(handler, "' OR '1'='1", fakeUser);
|
|
95
|
+
expect(injectedResult).toBeNull();
|
|
96
|
+
expect(runViewSpy).not.toHaveBeenCalled();
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('refuses non-UUID MCPServerID returned from connection lookup before querying servers', async () => {
|
|
100
|
+
runViewSpy.mockResolvedValueOnce({
|
|
101
|
+
Success: true,
|
|
102
|
+
Results: [{ MCPServerID: "1234' UNION SELECT * FROM __mj.vwUsers --" }],
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
const handler = new OAuthCallbackHandler({ baseUrl: 'https://api.example.com' });
|
|
106
|
+
const fakeUser = { ID: '00000000-0000-0000-0000-000000000001' } as UserInfo;
|
|
107
|
+
const validConnId = '11111111-2222-3333-4444-555555555555';
|
|
108
|
+
|
|
109
|
+
const loader = Reflect.get(handler, 'loadConnectionConfig') as (
|
|
110
|
+
connectionId: string,
|
|
111
|
+
contextUser: UserInfo,
|
|
112
|
+
) => Promise<Record<string, string> | null>;
|
|
113
|
+
|
|
114
|
+
const result = await loader.call(handler, validConnId, fakeUser);
|
|
115
|
+
expect(result).toBeNull();
|
|
116
|
+
// First query ran with validated connectionId; second query was blocked before executing
|
|
117
|
+
expect(runViewSpy).toHaveBeenCalledTimes(1);
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { ExpiryCloseReason, ParseSessionDeadlineMs, VerifyTimeLimitClaim } from '../agentSessions/sessionDeadline.js';
|
|
3
|
+
|
|
4
|
+
const T = Date.parse('2026-10-29T12:00:00Z');
|
|
5
|
+
const MIN = 60_000;
|
|
6
|
+
const row = (lastActive: number | null, deadline?: number): { LastActiveAt: Date | string | null; Config_: string } => ({
|
|
7
|
+
LastActiveAt: lastActive === null ? null : new Date(lastActive),
|
|
8
|
+
Config_: deadline === undefined ? '{}' : JSON.stringify({ maxSessionDeadlineIso: new Date(deadline).toISOString() }),
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
describe('ExpiryCloseReason', () => {
|
|
12
|
+
it('deadline passed, recently active → TimeLimit', () => expect(ExpiryCloseReason(row(T - MIN, T - MIN), T, 15 * MIN)).toBe('TimeLimit'));
|
|
13
|
+
it('idle past threshold, no deadline → Idle', () => expect(ExpiryCloseReason(row(T - 16 * MIN), T, 15 * MIN)).toBe('Idle'));
|
|
14
|
+
it('both passed, idle moment earlier → Idle', () => expect(ExpiryCloseReason(row(T - 20 * MIN, T - 2 * MIN), T, 15 * MIN)).toBe('Idle'));
|
|
15
|
+
it('both passed, deadline moment earlier → TimeLimit', () => expect(ExpiryCloseReason(row(T - 16 * MIN, T - 5 * MIN), T, 15 * MIN)).toBe('TimeLimit'));
|
|
16
|
+
it('same instant → TimeLimit', () => expect(ExpiryCloseReason(row(T - 15 * MIN, T), T, 15 * MIN)).toBe('TimeLimit'));
|
|
17
|
+
it('nothing passed → null', () => expect(ExpiryCloseReason(row(T - MIN, T + MIN), T, 15 * MIN)).toBeNull());
|
|
18
|
+
it('a row without LastActiveAt is never Idle', () => {
|
|
19
|
+
expect(ExpiryCloseReason(row(null), T, 15 * MIN)).toBeNull();
|
|
20
|
+
expect(ExpiryCloseReason(row(null, T - MIN), T, 15 * MIN)).toBe('TimeLimit');
|
|
21
|
+
});
|
|
22
|
+
it('nowMs exactly at the deadline → TimeLimit', () => expect(ExpiryCloseReason(row(T - MIN, T), T, 15 * MIN)).toBe('TimeLimit'));
|
|
23
|
+
it('a string LastActiveAt past the threshold → Idle', () => {
|
|
24
|
+
const r = { ...row(null), LastActiveAt: new Date(T - 16 * MIN).toISOString() };
|
|
25
|
+
expect(ExpiryCloseReason(r, T, 15 * MIN)).toBe('Idle');
|
|
26
|
+
});
|
|
27
|
+
it('an invalid LastActiveAt string is never Idle, TimeLimit still works', () => {
|
|
28
|
+
expect(ExpiryCloseReason({ ...row(null), LastActiveAt: 'garbage' }, T, 15 * MIN)).toBeNull();
|
|
29
|
+
expect(ExpiryCloseReason({ ...row(null, T - MIN), LastActiveAt: 'garbage' }, T, 15 * MIN)).toBe('TimeLimit');
|
|
30
|
+
});
|
|
31
|
+
it('a non-finite closeThresholdMs is never Idle', () => expect(ExpiryCloseReason(row(T - 99 * MIN), T, Number.NaN)).toBeNull());
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
describe('ParseSessionDeadlineMs', () => {
|
|
35
|
+
it('reads an ISO deadline', () => expect(ParseSessionDeadlineMs(JSON.stringify({ maxSessionDeadlineIso: '2026-10-29T12:00:00Z' }))).toBe(T));
|
|
36
|
+
it('treats a malformed deadline as absent', () => {
|
|
37
|
+
expect(ParseSessionDeadlineMs(JSON.stringify({ maxSessionDeadlineIso: 'soon' }))).toBeNull();
|
|
38
|
+
expect(ParseSessionDeadlineMs(JSON.stringify({ maxSessionDeadlineIso: 42 }))).toBeNull();
|
|
39
|
+
expect(ParseSessionDeadlineMs('not json')).toBeNull();
|
|
40
|
+
expect(ParseSessionDeadlineMs(null)).toBeNull();
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
describe('VerifyTimeLimitClaim', () => {
|
|
45
|
+
it('deadline passed → TimeLimit', () => expect(VerifyTimeLimitClaim(row(T - MIN, T - MIN), T)).toBe('TimeLimit'));
|
|
46
|
+
it('50 s ahead (inside the skew) → TimeLimit', () => expect(VerifyTimeLimitClaim(row(T - MIN, T + 50_000), T)).toBe('TimeLimit'));
|
|
47
|
+
it('10 min ahead → Explicit', () => expect(VerifyTimeLimitClaim(row(T - MIN, T + 10 * MIN), T)).toBe('Explicit'));
|
|
48
|
+
it('no stored deadline → Explicit', () => expect(VerifyTimeLimitClaim(row(T - MIN), T)).toBe('Explicit'));
|
|
49
|
+
it('Config_ null → Explicit', () => expect(VerifyTimeLimitClaim({ LastActiveAt: new Date(T), Config_: null }, T)).toBe('Explicit'));
|
|
50
|
+
it('a long-idle session is never promoted to TimeLimit by idleness', () => expect(VerifyTimeLimitClaim(row(T - 999 * MIN), T)).toBe('Explicit'));
|
|
51
|
+
});
|
|
@@ -43,6 +43,7 @@ function buildSourceUser(): UserInfo {
|
|
|
43
43
|
user.ReturningVisitorContext = { VisitorKey: 'vk-1' };
|
|
44
44
|
user.WidgetGuestContext = { WidgetID: 'W0000000-0000-0000-0000-000000000001' };
|
|
45
45
|
user.IsMagicLinkAnonymous = true;
|
|
46
|
+
user.AnonymousVisitorID = 'visitor-sid-1';
|
|
46
47
|
return user;
|
|
47
48
|
}
|
|
48
49
|
|
|
@@ -99,13 +100,14 @@ describe('CloneUserForSessionContext', () => {
|
|
|
99
100
|
expect(clone.APIKeyRowFilters).toHaveLength(1);
|
|
100
101
|
});
|
|
101
102
|
|
|
102
|
-
it('preserves ReturningVisitorContext, WidgetGuestContext, and
|
|
103
|
+
it('preserves ReturningVisitorContext, WidgetGuestContext, IsMagicLinkAnonymous, and AnonymousVisitorID', () => {
|
|
103
104
|
const source = buildSourceUser();
|
|
104
105
|
const clone = CloneUserForSessionContext(source);
|
|
105
106
|
|
|
106
107
|
expect(clone.ReturningVisitorContext).toEqual({ VisitorKey: 'vk-1' });
|
|
107
108
|
expect(clone.WidgetGuestContext).toEqual({ WidgetID: 'W0000000-0000-0000-0000-000000000001' });
|
|
108
109
|
expect(clone.IsMagicLinkAnonymous).toBe(true);
|
|
110
|
+
expect(clone.AnonymousVisitorID).toBe('visitor-sid-1');
|
|
109
111
|
});
|
|
110
112
|
|
|
111
113
|
it('stamping new contexts on the clone does NOT write through to the source', () => {
|
|
@@ -120,6 +122,7 @@ describe('CloneUserForSessionContext', () => {
|
|
|
120
122
|
clone.APIKeyActingContext = { ActingOrganizationID: 'ORG-OTHER' };
|
|
121
123
|
clone.APIKeyRowFilters = newBindings;
|
|
122
124
|
clone.IsMagicLinkAnonymous = false;
|
|
125
|
+
clone.AnonymousVisitorID = 'visitor-sid-OTHER';
|
|
123
126
|
|
|
124
127
|
// The source (potentially the shared UserCache instance) must be untouched
|
|
125
128
|
expect(source.TenantContext).toEqual({ TenantID: 'tenant-1', Source: 'header' });
|
|
@@ -128,6 +131,7 @@ describe('CloneUserForSessionContext', () => {
|
|
|
128
131
|
expect(source.APIKeyRowFilters).toHaveLength(1);
|
|
129
132
|
expect(source.APIKeyRowFilters?.[0].FilterID).toBe('F0000000-0000-0000-0000-000000000001');
|
|
130
133
|
expect(source.IsMagicLinkAnonymous).toBe(true);
|
|
134
|
+
expect(source.AnonymousVisitorID).toBe('visitor-sid-1');
|
|
131
135
|
});
|
|
132
136
|
|
|
133
137
|
it('clearing contexts on the clone does NOT clear them on the source', () => {
|
|
@@ -80,6 +80,17 @@ describe('shared cache event routing', () => {
|
|
|
80
80
|
expect(publish).toHaveBeenCalledWith('CACHE_INVALIDATION', expect.objectContaining({ entityName: 'MJ: AI Models', action: 'set', primaryKeyValues: null }));
|
|
81
81
|
});
|
|
82
82
|
|
|
83
|
+
it('dispatches a RunView row_delta to LocalCacheManager while normalizing browser CACHE_INVALIDATION action to set', () => {
|
|
84
|
+
const deltaEvt = event({
|
|
85
|
+
CacheKey: 'MJ: AI Models|_|_|-1|0|_|_|imr:1',
|
|
86
|
+
Action: 'row_delta',
|
|
87
|
+
Data: JSON.stringify({ primaryKeyFields: ['ID'], upsertedRows: [{ ID: '1' }], deletedPrimaryKeys: [], rowCount: 1, maxUpdatedAt: '' }),
|
|
88
|
+
});
|
|
89
|
+
RouteSharedCacheEvent(deltaEvt, provider(false));
|
|
90
|
+
expect(dispatch).toHaveBeenCalledWith(deltaEvt);
|
|
91
|
+
expect(publish).toHaveBeenCalledWith('CACHE_INVALIDATION', expect.objectContaining({ entityName: 'MJ: AI Models', action: 'set', primaryKeyValues: null }));
|
|
92
|
+
});
|
|
93
|
+
|
|
83
94
|
it('does not relay other categories or category clears to browsers', () => {
|
|
84
95
|
RouteSharedCacheEvent(event({ Category: 'default', CacheKey: '___MJCore_Metadata_AllMetadata' }), provider(false));
|
|
85
96
|
RouteSharedCacheEvent(event({ Category: 'DatasetCache', CacheKey: 'ds' }), provider(false));
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `SweepInterruptedRuns` closes out run artifacts a dead process left open. It is only sound
|
|
3
|
+
* BEFORE anything in this process can start a run: a run started first is still in flight when
|
|
4
|
+
* the sweep looks, so the sweep marks a live run "killed" and the wizard and active-operations
|
|
5
|
+
* panel report a failure for work that is still going.
|
|
6
|
+
*
|
|
7
|
+
* Booting the server is far too heavy for a unit test, so this pins the order in the source:
|
|
8
|
+
* the sweep is awaited before the scheduler, the integration sync worker (whose Start() polls
|
|
9
|
+
* immediately), the HTTP listener, and pending RSU work.
|
|
10
|
+
*/
|
|
11
|
+
import { readFileSync } from 'node:fs';
|
|
12
|
+
import { join } from 'node:path';
|
|
13
|
+
import { describe, expect, it } from 'vitest';
|
|
14
|
+
|
|
15
|
+
const source = readFileSync(join(__dirname, '..', 'index.ts'), 'utf8')
|
|
16
|
+
.replace(/\/\*[\s\S]*?\*\//g, '')
|
|
17
|
+
.replace(/^\s*\/\/.*$/gm, '');
|
|
18
|
+
|
|
19
|
+
function at(needle: string): number {
|
|
20
|
+
const i = source.indexOf(needle);
|
|
21
|
+
expect(i, `not found in index.ts: ${needle}`).toBeGreaterThan(-1);
|
|
22
|
+
return i;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
describe('startup: the interrupted-run sweep runs before anything can start a run', () => {
|
|
26
|
+
const sweep = () => at('await SweepInterruptedRuns(');
|
|
27
|
+
|
|
28
|
+
it.each([
|
|
29
|
+
['the scheduled jobs service', 'scheduledJobsService.Start()'],
|
|
30
|
+
['the integration sync worker', 'integrationSyncWorker.Start()'],
|
|
31
|
+
['the HTTP listener', 'httpServer.listen('],
|
|
32
|
+
['pending RSU work', 'processRSUPendingWork().catch('],
|
|
33
|
+
])('precedes %s', (_label, needle) => {
|
|
34
|
+
expect(sweep()).toBeLessThan(at(needle));
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('is called exactly once', () => {
|
|
38
|
+
expect(source.split('await SweepInterruptedRuns(').length - 1).toBe(1);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* module (context.ts), vi.mock cannot intercept the intra-module call.
|
|
9
9
|
* Instead we mock the LOWER-LEVEL dependencies that `getUserPayload` calls.
|
|
10
10
|
*/
|
|
11
|
-
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
11
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
12
12
|
|
|
13
13
|
// ─── Hoisted mocks (available inside vi.mock factories) ─────────────────────
|
|
14
14
|
const {
|
|
@@ -102,6 +102,7 @@ vi.mock('@memberjunction/api-keys', () => ({
|
|
|
102
102
|
}));
|
|
103
103
|
|
|
104
104
|
import { CreateUnifiedAuthMiddleware } from '../context.js';
|
|
105
|
+
import { userEmailMap } from '../config.js';
|
|
105
106
|
import type { Request, Response, NextFunction } from 'express';
|
|
106
107
|
import type { DataSourceInfo } from '../types.js';
|
|
107
108
|
|
|
@@ -136,6 +137,8 @@ function makeMockRes(): Response & { _status: number; _json: Record<string, unkn
|
|
|
136
137
|
}
|
|
137
138
|
|
|
138
139
|
const mockDataSources: DataSourceInfo[] = [];
|
|
140
|
+
/** The mocked config's map object; tests add entries and the afterEach clears them. */
|
|
141
|
+
const mockedUserEmailMap = userEmailMap as Record<string, string>;
|
|
139
142
|
const MOCK_POOL = {} as unknown as import('mssql').ConnectionPool;
|
|
140
143
|
|
|
141
144
|
const mockUserRecord = {
|
|
@@ -263,6 +266,34 @@ describe('createUnifiedAuthMiddleware', () => {
|
|
|
263
266
|
});
|
|
264
267
|
});
|
|
265
268
|
|
|
269
|
+
describe('x-mj-timezone header', () => {
|
|
270
|
+
beforeEach(() => {
|
|
271
|
+
setupSuccessfulAuth();
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
async function payloadFor(headers: Record<string, string>) {
|
|
275
|
+
const req = makeMockReq({ headers: { authorization: 'Bearer valid-token', ...headers } });
|
|
276
|
+
await middleware(req, makeMockRes(), vi.fn());
|
|
277
|
+
return req.userPayload!;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
it('carries a valid IANA zone on the user payload', async () => {
|
|
281
|
+
expect((await payloadFor({ 'x-mj-timezone': 'Pacific/Auckland' })).TimeZone).toBe('Pacific/Auckland');
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
it('drops an invalid zone, so callers fall back to UTC', async () => {
|
|
285
|
+
expect((await payloadFor({ 'x-mj-timezone': 'Mars/Olympus_Mons' })).TimeZone).toBeUndefined();
|
|
286
|
+
expect((await payloadFor({ 'x-mj-timezone': "UTC'; DROP TABLE x;--" })).TimeZone).toBeUndefined();
|
|
287
|
+
expect((await payloadFor({ 'x-mj-timezone': '' })).TimeZone).toBeUndefined();
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
it('leaves the payload exactly as before when the header is absent', async () => {
|
|
291
|
+
const payload = await payloadFor({});
|
|
292
|
+
expect(payload.TimeZone).toBeUndefined();
|
|
293
|
+
expect(Object.keys(payload)).not.toContain('TimeZone');
|
|
294
|
+
});
|
|
295
|
+
});
|
|
296
|
+
|
|
266
297
|
describe('Authentication failures', () => {
|
|
267
298
|
it('should return 401 when no authorization header is provided, quietly (no stack-trace log)', async () => {
|
|
268
299
|
mockGetReadOnlyDS.mockReturnValue(MOCK_POOL);
|
|
@@ -436,3 +467,72 @@ describe('createUnifiedAuthMiddleware', () => {
|
|
|
436
467
|
});
|
|
437
468
|
});
|
|
438
469
|
});
|
|
470
|
+
|
|
471
|
+
// ─── Login identity reporting ───────────────────────────────────────────────
|
|
472
|
+
// The session-audit block runs once per issued token (deduped on iss/sub/iat), so each test
|
|
473
|
+
// presents a token with its own `iat`.
|
|
474
|
+
|
|
475
|
+
describe('login identity reporting', () => {
|
|
476
|
+
let middleware: ReturnType<typeof CreateUnifiedAuthMiddleware>;
|
|
477
|
+
let iat = 1_700_000_000;
|
|
478
|
+
|
|
479
|
+
function presentToken(email: string): void {
|
|
480
|
+
iat += 1;
|
|
481
|
+
mockJwtDecode.mockReturnValue({
|
|
482
|
+
iss: 'https://test-issuer.com',
|
|
483
|
+
sub: 'user-1',
|
|
484
|
+
iat,
|
|
485
|
+
exp: Math.floor(Date.now() / 1000) + 3600,
|
|
486
|
+
});
|
|
487
|
+
mockExtractUserInfo.mockReturnValue({ email, preferredUsername: email });
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
async function authenticate(): Promise<void> {
|
|
491
|
+
const req = makeMockReq({ headers: { authorization: `Bearer token-${iat}` } });
|
|
492
|
+
await middleware(req, makeMockRes(), vi.fn());
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
function warnings(spy: ReturnType<typeof vi.spyOn>): string[] {
|
|
496
|
+
return spy.mock.calls.map((call) => String(call[0]));
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
beforeEach(() => {
|
|
500
|
+
vi.clearAllMocks();
|
|
501
|
+
setupSuccessfulAuth();
|
|
502
|
+
middleware = CreateUnifiedAuthMiddleware(mockDataSources);
|
|
503
|
+
});
|
|
504
|
+
|
|
505
|
+
afterEach(() => {
|
|
506
|
+
for (const key of Object.keys(mockedUserEmailMap)) {
|
|
507
|
+
delete mockedUserEmailMap[key];
|
|
508
|
+
}
|
|
509
|
+
});
|
|
510
|
+
|
|
511
|
+
it('logs nothing when the token identity and the user record agree', async () => {
|
|
512
|
+
const warn = vi.spyOn(console, 'warn').mockImplementation(() => undefined);
|
|
513
|
+
presentToken('test@example.com');
|
|
514
|
+
await authenticate();
|
|
515
|
+
expect(warnings(warn).filter((w) => w.startsWith('[Auth]'))).toEqual([]);
|
|
516
|
+
warn.mockRestore();
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
it('looks the user up by the mapped email and logs the remap', async () => {
|
|
520
|
+
const warn = vi.spyOn(console, 'warn').mockImplementation(() => undefined);
|
|
521
|
+
mockedUserEmailMap['other@example.org'] = 'test@example.com';
|
|
522
|
+
presentToken('other@example.org');
|
|
523
|
+
await authenticate();
|
|
524
|
+
expect(mockVerifyUserRecord.mock.calls[0][0]).toBe('test@example.com');
|
|
525
|
+
expect(warnings(warn)).toContainEqual(expect.stringContaining("USER_EMAIL_MAP remapped login 'other@example.org' to 'test@example.com'"));
|
|
526
|
+
warn.mockRestore();
|
|
527
|
+
});
|
|
528
|
+
|
|
529
|
+
it('logs a login that resolved to a record with a different email', async () => {
|
|
530
|
+
const warn = vi.spyOn(console, 'warn').mockImplementation(() => undefined);
|
|
531
|
+
presentToken('someone-else@example.org');
|
|
532
|
+
await authenticate();
|
|
533
|
+
expect(warnings(warn)).toContainEqual(
|
|
534
|
+
expect.stringContaining("Login identity 'someone-else@example.org' resolved to user user-1 with a different email (test@example.com)"),
|
|
535
|
+
);
|
|
536
|
+
warn.mockRestore();
|
|
537
|
+
});
|
|
538
|
+
});
|
|
@@ -155,6 +155,8 @@ describe('widgetGuestElevation — elevateUserPayload', () => {
|
|
|
155
155
|
expect(elevated.isSystemUser).toBe(true);
|
|
156
156
|
// The session id MUST be preserved so progress/streaming still routes to the guest's websocket.
|
|
157
157
|
expect(elevated.sessionId).toBe('sess-123');
|
|
158
|
+
// The guest it stands in for, so conversation writes can stay the guest's (MJ#4791).
|
|
159
|
+
expect(elevated.ElevatedFrom).toBe(guestPayload.userRecord);
|
|
158
160
|
});
|
|
159
161
|
|
|
160
162
|
it('does not mutate the original guest payload', () => {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { IMetadataProvider, UserInfo } from '@memberjunction/core';
|
|
1
|
+
import { IMetadataProvider, LogError, UserInfo } from '@memberjunction/core';
|
|
2
2
|
import { AIBridgeEngine } from '@memberjunction/ai-bridge-server';
|
|
3
3
|
import { GetCurrentHostInstance } from './HostInstance.js';
|
|
4
|
+
import { DEFAULT_BRIDGE_RECONCILER_SETTINGS, type BridgeReconcilerSettings } from '../backgroundSweepConfigUnits.js';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Gives the realtime bridge engine (`AIBridgeEngine`) this MJAPI instance's identity, the one its agent-session rows
|
|
@@ -17,8 +18,11 @@ export function BindBridgeEngineHostInstance(): void {
|
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
|
-
* Starts the realtime bridge engine's orphan reconcile: now, then every 10 minutes
|
|
21
|
-
* boot of this instance left `Connecting` or `Connected` (reason `Janitor`)
|
|
21
|
+
* Starts the realtime bridge engine's orphan reconcile: now, then every `settings.sweepIntervalMs` (10 minutes by
|
|
22
|
+
* default), it closes the bridges an earlier boot of this instance left `Connecting` or `Connected` (reason `Janitor`)
|
|
23
|
+
* and finalizes their co-agent runs. With `settings.enabled` false it reconciles once now and schedules no repeat, so an
|
|
24
|
+
* idle server sends no periodic queries for it (`agentSessions.bridgeReconciler`; see the Serverless Database
|
|
25
|
+
* Auto-Pause guide).
|
|
22
26
|
*
|
|
23
27
|
* `Serve` calls it once the server listens on its port, where it starts the session janitor. Holding the port is what
|
|
24
28
|
* makes another boot of this instance a process that has ended; before that, an MJAPI started on a port another MJAPI
|
|
@@ -26,7 +30,18 @@ export function BindBridgeEngineHostInstance(): void {
|
|
|
26
30
|
*
|
|
27
31
|
* @param provider The server's metadata provider, for the reads and writes.
|
|
28
32
|
* @param systemUser The user the writes run as.
|
|
33
|
+
* @param settings Whether to repeat the reconcile, and how often. Defaults to the shipped settings.
|
|
29
34
|
*/
|
|
30
|
-
export function StartBridgeOrphanReconciliation(
|
|
31
|
-
|
|
35
|
+
export function StartBridgeOrphanReconciliation(
|
|
36
|
+
provider: IMetadataProvider,
|
|
37
|
+
systemUser: UserInfo,
|
|
38
|
+
settings: BridgeReconcilerSettings = DEFAULT_BRIDGE_RECONCILER_SETTINGS,
|
|
39
|
+
): void {
|
|
40
|
+
if (settings.enabled) {
|
|
41
|
+
AIBridgeEngine.Instance.StartOrphanReconciliation(systemUser, provider, settings.sweepIntervalMs);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
void AIBridgeEngine.Instance.ReconcileOrphans(systemUser, provider).catch((err) =>
|
|
45
|
+
LogError(`[AIBridgeEngine] orphan reconciliation failed: ${err instanceof Error ? err.message : String(err)}`),
|
|
46
|
+
);
|
|
32
47
|
}
|