@memberjunction/server 6.2.0-edge.4 → 6.2.0-edge.6
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 +47 -1
- package/dist/.tsbuildinfo +1 -1
- package/dist/agentSessions/SessionJanitor.d.ts +91 -30
- package/dist/agentSessions/SessionJanitor.d.ts.map +1 -1
- package/dist/agentSessions/SessionJanitor.js +311 -81
- package/dist/agentSessions/SessionJanitor.js.map +1 -1
- package/dist/agentSessions/SessionManager.d.ts +17 -3
- package/dist/agentSessions/SessionManager.d.ts.map +1 -1
- package/dist/agentSessions/SessionManager.js +44 -10
- package/dist/agentSessions/SessionManager.js.map +1 -1
- package/dist/apiRoot.d.ts +32 -0
- package/dist/apiRoot.d.ts.map +1 -0
- package/dist/apiRoot.js +67 -0
- package/dist/apiRoot.js.map +1 -0
- package/dist/auth/AuthProviderCatalogRouter.d.ts.map +1 -1
- package/dist/auth/AuthProviderCatalogRouter.js +27 -0
- package/dist/auth/AuthProviderCatalogRouter.js.map +1 -1
- package/dist/auth/LoginScreenEngine.d.ts +22 -0
- package/dist/auth/LoginScreenEngine.d.ts.map +1 -0
- package/dist/auth/LoginScreenEngine.js +57 -0
- package/dist/auth/LoginScreenEngine.js.map +1 -0
- package/dist/auth/index.d.ts +1 -0
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +52 -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/magicLink/MagicLinkKeys.d.ts +2 -2
- package/dist/auth/magicLink/MagicLinkKeys.d.ts.map +1 -1
- package/dist/auth/magicLink/MagicLinkKeys.js +1 -1
- package/dist/auth/magicLink/MagicLinkKeys.js.map +1 -1
- package/dist/auth/magicLink/MagicLinkRouter.d.ts.map +1 -1
- package/dist/auth/magicLink/MagicLinkRouter.js +3 -2
- package/dist/auth/magicLink/MagicLinkRouter.js.map +1 -1
- package/dist/auth/magicLink/types.d.ts +12 -0
- package/dist/auth/magicLink/types.d.ts.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/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 +632 -22
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +104 -4
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +3 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +29 -8
- package/dist/context.js.map +1 -1
- package/dist/coreRoutes.d.ts +29 -0
- package/dist/coreRoutes.d.ts.map +1 -0
- package/dist/coreRoutes.js +156 -0
- package/dist/coreRoutes.js.map +1 -0
- package/dist/generated/graphql-schemas/__mj.d.ts +1016 -29
- package/dist/generated/graphql-schemas/__mj.d.ts.map +1 -1
- package/dist/generated/graphql-schemas/__mj.js +5125 -434
- package/dist/generated/graphql-schemas/__mj.js.map +1 -1
- package/dist/generic/CacheInvalidationResolver.d.ts +85 -30
- package/dist/generic/CacheInvalidationResolver.d.ts.map +1 -1
- package/dist/generic/CacheInvalidationResolver.js +175 -60
- package/dist/generic/CacheInvalidationResolver.js.map +1 -1
- package/dist/generic/OrphanedConversationDetailReconciler.d.ts.map +1 -1
- package/dist/generic/OrphanedConversationDetailReconciler.js +2 -0
- 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 +94 -12
- package/dist/generic/PushStatusResolver.js.map +1 -1
- package/dist/generic/ResolverBase.d.ts +168 -69
- package/dist/generic/ResolverBase.d.ts.map +1 -1
- package/dist/generic/ResolverBase.js +464 -405
- package/dist/generic/ResolverBase.js.map +1 -1
- package/dist/generic/RunViewResolver.d.ts +11 -3
- package/dist/generic/RunViewResolver.d.ts.map +1 -1
- package/dist/generic/RunViewResolver.js +91 -13
- 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/globalCors.d.ts +33 -0
- package/dist/globalCors.d.ts.map +1 -0
- package/dist/globalCors.js +58 -0
- package/dist/globalCors.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +230 -222
- package/dist/index.js.map +1 -1
- package/dist/integration/CustomColumnPromoter.d.ts.map +1 -1
- package/dist/integration/CustomColumnPromoter.js +6 -1
- package/dist/integration/CustomColumnPromoter.js.map +1 -1
- 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/multiTenancy/index.d.ts.map +1 -1
- package/dist/multiTenancy/index.js +22 -2
- package/dist/multiTenancy/index.js.map +1 -1
- package/dist/realtimeSessions/RealtimeSessionVerificationService.d.ts.map +1 -1
- package/dist/realtimeSessions/RealtimeSessionVerificationService.js +2 -1
- package/dist/realtimeSessions/RealtimeSessionVerificationService.js.map +1 -1
- package/dist/realtimeSessions/RealtimeVerifyRouter.d.ts.map +1 -1
- package/dist/realtimeSessions/RealtimeVerifyRouter.js +2 -1
- package/dist/realtimeSessions/RealtimeVerifyRouter.js.map +1 -1
- package/dist/realtimeSessions/RecordingAssemblyScheduler.d.ts +100 -0
- package/dist/realtimeSessions/RecordingAssemblyScheduler.d.ts.map +1 -0
- package/dist/realtimeSessions/RecordingAssemblyScheduler.js +173 -0
- package/dist/realtimeSessions/RecordingAssemblyScheduler.js.map +1 -0
- 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/index.d.ts +2 -0
- package/dist/realtimeSessions/index.d.ts.map +1 -1
- package/dist/realtimeSessions/index.js +2 -0
- package/dist/realtimeSessions/index.js.map +1 -1
- package/dist/realtimeSessions/ownedRealtimeSession.d.ts +32 -0
- package/dist/realtimeSessions/ownedRealtimeSession.d.ts.map +1 -0
- package/dist/realtimeSessions/ownedRealtimeSession.js +56 -0
- package/dist/realtimeSessions/ownedRealtimeSession.js.map +1 -0
- package/dist/realtimeSessions/sessionAccess.d.ts +91 -8
- package/dist/realtimeSessions/sessionAccess.d.ts.map +1 -1
- package/dist/realtimeSessions/sessionAccess.js +127 -20
- 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 +201 -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/widgetCore.d.ts +20 -1
- package/dist/realtimeWidget/widgetCore.d.ts.map +1 -1
- package/dist/realtimeWidget/widgetCore.js +17 -1
- 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 +2 -1
- package/dist/realtimeWidget/widgetGuestElevation.js.map +1 -1
- 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 +40 -17
- package/dist/resolvers/AgentSessionResolver.js.map +1 -1
- package/dist/resolvers/ArtifactFileResolver.d.ts +5 -1
- package/dist/resolvers/ArtifactFileResolver.d.ts.map +1 -1
- package/dist/resolvers/ArtifactFileResolver.js +9 -7
- package/dist/resolvers/ArtifactFileResolver.js.map +1 -1
- package/dist/resolvers/ConversationRunEventsResolver.d.ts +8 -4
- package/dist/resolvers/ConversationRunEventsResolver.d.ts.map +1 -1
- package/dist/resolvers/ConversationRunEventsResolver.js +6 -6
- package/dist/resolvers/ConversationRunEventsResolver.js.map +1 -1
- package/dist/resolvers/DatasetResolver.d.ts +24 -3
- package/dist/resolvers/DatasetResolver.d.ts.map +1 -1
- package/dist/resolvers/DatasetResolver.js +57 -8
- package/dist/resolvers/DatasetResolver.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/EntityRecordNameResolver.d.ts +2 -1
- package/dist/resolvers/EntityRecordNameResolver.d.ts.map +1 -1
- package/dist/resolvers/EntityRecordNameResolver.js +3 -2
- package/dist/resolvers/EntityRecordNameResolver.js.map +1 -1
- package/dist/resolvers/FetchEntityVectorsResolver.d.ts +46 -3
- package/dist/resolvers/FetchEntityVectorsResolver.d.ts.map +1 -1
- package/dist/resolvers/FetchEntityVectorsResolver.js +211 -50
- 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 +87 -11
- package/dist/resolvers/FileResolver.d.ts.map +1 -1
- package/dist/resolvers/FileResolver.js +292 -105
- package/dist/resolvers/FileResolver.js.map +1 -1
- package/dist/resolvers/GetDataContextDataResolver.d.ts +33 -7
- package/dist/resolvers/GetDataContextDataResolver.d.ts.map +1 -1
- package/dist/resolvers/GetDataContextDataResolver.js +117 -38
- package/dist/resolvers/GetDataContextDataResolver.js.map +1 -1
- package/dist/resolvers/GetDataResolver.d.ts.map +1 -1
- package/dist/resolvers/GetDataResolver.js +6 -3
- package/dist/resolvers/GetDataResolver.js.map +1 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.d.ts.map +1 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.js +49 -9
- package/dist/resolvers/IntegrationDiscoveryResolver.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 +2 -0
- package/dist/resolvers/QueryResolver.d.ts.map +1 -1
- package/dist/resolvers/QueryResolver.js +33 -6
- package/dist/resolvers/QueryResolver.js.map +1 -1
- package/dist/resolvers/QuerySystemUserResolver.d.ts +2 -0
- package/dist/resolvers/QuerySystemUserResolver.d.ts.map +1 -1
- package/dist/resolvers/QuerySystemUserResolver.js +15 -6
- 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/RealtimeClientSessionResolver.d.ts +18 -10
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.js +92 -54
- package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
- package/dist/resolvers/RemoteBrowserActionResolver.d.ts.map +1 -1
- package/dist/resolvers/RemoteBrowserActionResolver.js +11 -9
- package/dist/resolvers/RemoteBrowserActionResolver.js.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.d.ts +56 -8
- package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.js +241 -67
- package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
- package/dist/resolvers/RunTemplateResolver.d.ts.map +1 -1
- package/dist/resolvers/RunTemplateResolver.js +4 -4
- 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/SearchKnowledgeStreamResolver.d.ts +12 -1
- package/dist/resolvers/SearchKnowledgeStreamResolver.d.ts.map +1 -1
- package/dist/resolvers/SearchKnowledgeStreamResolver.js +15 -2
- package/dist/resolvers/SearchKnowledgeStreamResolver.js.map +1 -1
- package/dist/resolvers/SqlLoggingConfigResolver.d.ts.map +1 -1
- package/dist/resolvers/SqlLoggingConfigResolver.js +2 -3
- package/dist/resolvers/SqlLoggingConfigResolver.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/TaskGraphFrameResolver.d.ts +2 -1
- package/dist/resolvers/TaskGraphFrameResolver.d.ts.map +1 -1
- package/dist/resolvers/TaskGraphFrameResolver.js +28 -1
- package/dist/resolvers/TaskGraphFrameResolver.js.map +1 -1
- package/dist/resolvers/TestQuerySQLResolver.d.ts +24 -0
- package/dist/resolvers/TestQuerySQLResolver.d.ts.map +1 -1
- package/dist/resolvers/TestQuerySQLResolver.js +66 -13
- package/dist/resolvers/TestQuerySQLResolver.js.map +1 -1
- package/dist/resolvers/TransactionGroupResolver.d.ts +34 -2
- package/dist/resolvers/TransactionGroupResolver.d.ts.map +1 -1
- package/dist/resolvers/TransactionGroupResolver.js +150 -27
- 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/agent-run-data-guard.d.ts +31 -0
- package/dist/resolvers/agent-run-data-guard.d.ts.map +1 -0
- package/dist/resolvers/agent-run-data-guard.js +72 -0
- package/dist/resolvers/agent-run-data-guard.js.map +1 -0
- 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/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 +49 -0
- package/dist/rest/RealtimeRecordingHandler.d.ts.map +1 -0
- package/dist/rest/RealtimeRecordingHandler.js +383 -0
- package/dist/rest/RealtimeRecordingHandler.js.map +1 -0
- package/dist/rest/ViewOperationsHandler.d.ts +9 -1
- package/dist/rest/ViewOperationsHandler.d.ts.map +1 -1
- package/dist/rest/ViewOperationsHandler.js +43 -17
- package/dist/rest/ViewOperationsHandler.js.map +1 -1
- package/dist/rest/setupRESTEndpoints.d.ts +6 -0
- package/dist/rest/setupRESTEndpoints.d.ts.map +1 -1
- package/dist/rest/setupRESTEndpoints.js +6 -0
- package/dist/rest/setupRESTEndpoints.js.map +1 -1
- package/dist/serverExtensionReservedRoots.d.ts +12 -10
- package/dist/serverExtensionReservedRoots.d.ts.map +1 -1
- package/dist/serverExtensionReservedRoots.js +14 -17
- package/dist/serverExtensionReservedRoots.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/MJStorageBlobStore.d.ts +8 -1
- package/dist/services/MJStorageBlobStore.d.ts.map +1 -1
- package/dist/services/MJStorageBlobStore.js +25 -19
- package/dist/services/MJStorageBlobStore.js.map +1 -1
- package/dist/services/StartTaskGraphDispatcher.js +2 -2
- package/dist/services/StartTaskGraphDispatcher.js.map +1 -1
- package/dist/services/TaskGraphActionRunner.d.ts +5 -3
- package/dist/services/TaskGraphActionRunner.d.ts.map +1 -1
- package/dist/services/TaskGraphActionRunner.js +27 -5
- package/dist/services/TaskGraphActionRunner.js.map +1 -1
- package/dist/services/TaskGraphAgentRunner.d.ts +14 -2
- package/dist/services/TaskGraphAgentRunner.d.ts.map +1 -1
- package/dist/services/TaskGraphAgentRunner.js +157 -9
- package/dist/services/TaskGraphAgentRunner.js.map +1 -1
- package/dist/services/TaskGraphContinuationDeliverer.d.ts +59 -2
- package/dist/services/TaskGraphContinuationDeliverer.d.ts.map +1 -1
- package/dist/services/TaskGraphContinuationDeliverer.js +626 -16
- package/dist/services/TaskGraphContinuationDeliverer.js.map +1 -1
- package/dist/sharedCache.d.ts.map +1 -1
- package/dist/sharedCache.js +3 -0
- package/dist/sharedCache.js.map +1 -1
- package/dist/types.d.ts +23 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +99 -98
- package/src/__tests__/ActionResolver.fieldSecurity.test.ts +237 -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 +137 -0
- package/src/__tests__/CustomColumnPromoterOnePass.test.ts +15 -1
- package/src/__tests__/DatasetResolver.itemFilters.test.ts +201 -0
- package/src/__tests__/EntityCommunicationsResolver.actingUser.test.ts +151 -0
- package/src/__tests__/EntityRecordNameResolver.rowSecurity.test.ts +152 -0
- package/src/__tests__/EvolutionActsOnWhatItDetects.test.ts +113 -0
- package/src/__tests__/FetchEntityVectorsResolver.test.ts +369 -18
- package/src/__tests__/FileResolver.fieldSecurity.test.ts +82 -0
- package/src/__tests__/FileResolver.storageAccess.test.ts +562 -0
- package/src/__tests__/GetDataContextDataResolver.sqlItems.test.ts +416 -0
- package/src/__tests__/ListOperationsResolver.adhocScreen.test.ts +137 -0
- package/src/__tests__/LoginScreenEngine.test.ts +86 -0
- package/src/__tests__/MJStorageBlobStore.storageGate.test.ts +63 -0
- package/src/__tests__/PipelineProgressResolver.filter.test.ts +58 -0
- package/src/__tests__/QuerySystemUserResolver.fieldSecurity.test.ts +49 -0
- package/src/__tests__/RESTEndpointHandler.test.ts +25 -0
- package/src/__tests__/RealtimeClientSessionResolver.configTamper.test.ts +23 -3
- package/src/__tests__/RealtimeClientSessionResolver.test.ts +324 -46
- package/src/__tests__/RecordingAssemblyScheduler.test.ts +178 -0
- package/src/__tests__/RemoteBrowserActionResolver.ownership.test.ts +98 -0
- package/src/__tests__/ResolverBase.adhocReadScope.test.ts +133 -2
- package/src/__tests__/ResolverBase.balancedClause.test.ts +155 -0
- package/src/__tests__/ResolverBase.clauseUnscopedRead.test.ts +127 -0
- package/src/__tests__/ResolverBase.clientOldValues.test.ts +243 -7
- package/src/__tests__/ResolverBase.deleteReturnProjection.test.ts +52 -0
- package/src/__tests__/ResolverBase.entityMessageRelay.test.ts +176 -0
- package/src/__tests__/ResolverBase.filterEscaping.test.ts +5 -2
- package/src/__tests__/ResolverBase.includeBinaryFields.test.ts +23 -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 +69 -13
- package/src/__tests__/RunAIAgentResolver.conversationWriter.test.ts +210 -0
- package/src/__tests__/RunAIAgentResolver.fireAndForgetCompletion.test.ts +209 -0
- package/src/__tests__/RunAIAgentResolver.historyFrom.test.ts +20 -28
- package/src/__tests__/RunAIAgentResolver.runDataGuard.test.ts +264 -0
- package/src/__tests__/RunAIAgentResolver.serverReply.test.ts +358 -0
- package/src/__tests__/RunAIAgentResolver.stoppedPredecessor.test.ts +4 -1
- package/src/__tests__/RunTemplateResolver.test.ts +35 -2
- package/src/__tests__/RunViewResolver.cacheCheckForwarding.test.ts +11 -0
- package/src/__tests__/RunViewResolver.cacheCheckScreen.test.ts +165 -0
- package/src/__tests__/SearchKnowledgeStreamResolver.test.ts +161 -0
- package/src/__tests__/SessionJanitor.test.ts +365 -10
- package/src/__tests__/SessionManager.test.ts +122 -0
- package/src/__tests__/TaskGraphActionRunner.durablePayload.test.ts +25 -0
- package/src/__tests__/TaskGraphAgentRunner.test.ts +266 -0
- package/src/__tests__/TaskGraphContinuationDeliverer.test.ts +468 -23
- package/src/__tests__/TaskGraphFrameResolver.test.ts +22 -0
- package/src/__tests__/TestQuerySQLResolver.test.ts +274 -0
- package/src/__tests__/TransactionGroupResolver.fieldSecurity.test.ts +199 -0
- package/src/__tests__/TransactionGroupResolver.refusals.test.ts +98 -1
- package/src/__tests__/UpdateMJDataContextItem.oldValues.test.ts +220 -0
- package/src/__tests__/UserViewResolver.updateWhereClause.test.ts +15 -0
- package/src/__tests__/ViewOperationsHandler.clauseScreen.test.ts +157 -0
- package/src/__tests__/ViewOperationsHandler.test.ts +7 -2
- package/src/__tests__/WidgetSessionService.test.ts +583 -4
- package/src/__tests__/agent-run-data-guard.test.ts +130 -0
- package/src/__tests__/apiRootBoot.test.ts +202 -0
- package/src/__tests__/buildMagicLinkSessionUser.test.ts +96 -0
- package/src/__tests__/cacheBroadcastProviders.test.ts +403 -0
- package/src/__tests__/cacheInvalidationRecordData.test.ts +109 -0
- package/src/__tests__/conversationRunEvents.test.ts +56 -14
- package/src/__tests__/fieldSecurityFixtures.ts +91 -0
- package/src/__tests__/globalCors.test.ts +217 -0
- package/src/__tests__/localDevAuth.test.ts +196 -0
- package/src/__tests__/multiTenancy.postgresRewrite.test.ts +181 -0
- package/src/__tests__/multiTenancy.security.test.ts +51 -0
- package/src/__tests__/multiTenancy.test.ts +1 -1
- package/src/__tests__/orphanedConversationDetailReconciler.test.ts +10 -0
- package/src/__tests__/ownedRealtimeSession.test.ts +39 -0
- package/src/__tests__/pushStatusResolver.filter.test.ts +64 -1
- package/src/__tests__/realtimeRecordingHandler.test.ts +669 -0
- 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 +146 -7
- package/src/__tests__/realtimeSessions/sessionConfigStamps.test.ts +1 -1
- package/src/__tests__/realtimeSessions/verificationWorkflow.test.ts +25 -4
- 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__/serverExtensionHostOverlay.test.ts +66 -0
- package/src/__tests__/serverExtensionReservedRoots.test.ts +11 -98
- package/src/__tests__/sessionUserClone.test.ts +5 -1
- package/src/__tests__/sharedCache.test.ts +5 -3
- package/src/__tests__/startupSweepOrder.test.ts +40 -0
- package/src/__tests__/unifiedAuth.test.ts +28 -0
- package/src/__tests__/widgetGuestElevation.test.ts +2 -0
- package/src/agentSessions/SessionJanitor.ts +369 -93
- package/src/agentSessions/SessionManager.ts +45 -10
- package/src/apiRoot.ts +78 -0
- package/src/auth/AuthProviderCatalogRouter.ts +29 -0
- package/src/auth/LoginScreenEngine.ts +50 -0
- package/src/auth/index.ts +57 -12
- package/src/auth/initializeProviders.ts +43 -1
- package/src/auth/localDevAuth.ts +528 -0
- package/src/auth/magicLink/MagicLinkKeys.ts +2 -2
- package/src/auth/magicLink/MagicLinkRouter.ts +3 -2
- package/src/auth/magicLink/types.ts +10 -0
- package/src/auth/sessionUserClone.ts +3 -2
- 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 +115 -5
- package/src/context.ts +32 -8
- package/src/coreRoutes.ts +181 -0
- package/src/generated/graphql-schemas/__mj.ts +3684 -284
- package/src/generic/CacheInvalidationResolver.ts +172 -60
- package/src/generic/OrphanedConversationDetailReconciler.ts +4 -2
- package/src/generic/PubSubManager.ts +54 -1
- package/src/generic/PushStatusResolver.ts +109 -12
- package/src/generic/ResolverBase.ts +540 -431
- package/src/generic/RunViewResolver.ts +97 -15
- package/src/generic/actionOutputFieldSecurity.ts +75 -0
- package/src/generic/fieldSecurityTransport.ts +62 -0
- package/src/globalCors.ts +71 -0
- package/src/index.ts +239 -238
- package/src/integration/CustomColumnPromoter.ts +6 -1
- package/src/logging/variablesLoggingMiddleware.ts +59 -3
- package/src/multiTenancy/index.ts +24 -2
- package/src/realtimeSessions/README.md +7 -3
- package/src/realtimeSessions/RealtimeSessionVerificationService.ts +2 -1
- package/src/realtimeSessions/RealtimeVerifyRouter.ts +2 -1
- package/src/realtimeSessions/RecordingAssemblyScheduler.ts +234 -0
- package/src/realtimeSessions/SessionVerificationPortsBase.ts +1 -0
- package/src/realtimeSessions/index.ts +2 -0
- package/src/realtimeSessions/ownedRealtimeSession.ts +69 -0
- package/src/realtimeSessions/sessionAccess.ts +183 -23
- 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 +252 -17
- package/src/realtimeWidget/host-identity.ts +1 -1
- package/src/realtimeWidget/widgetCore.ts +30 -1
- package/src/realtimeWidget/widgetGuestElevation.ts +2 -1
- 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 +46 -18
- package/src/resolvers/ArtifactFileResolver.ts +9 -8
- package/src/resolvers/ConversationRunEventsResolver.ts +15 -11
- package/src/resolvers/DatasetResolver.ts +70 -10
- package/src/resolvers/EntityCommunicationsResolver.ts +56 -15
- package/src/resolvers/EntityRecordNameResolver.ts +3 -2
- package/src/resolvers/FetchEntityVectorsResolver.ts +248 -55
- package/src/resolvers/FileCategoryResolver.ts +1 -0
- package/src/resolvers/FileResolver.ts +334 -109
- package/src/resolvers/GetDataContextDataResolver.ts +139 -41
- package/src/resolvers/GetDataResolver.ts +6 -3
- package/src/resolvers/IntegrationDiscoveryResolver.ts +53 -9
- package/src/resolvers/MergeRecordsResolver.ts +23 -2
- package/src/resolvers/PipelineProgressResolver.ts +12 -3
- package/src/resolvers/QueryResolver.ts +31 -6
- package/src/resolvers/QuerySystemUserResolver.ts +15 -6
- package/src/resolvers/RSUResolver.ts +12 -0
- package/src/resolvers/RealtimeClientSessionResolver.ts +114 -66
- package/src/resolvers/RemoteBrowserActionResolver.ts +15 -10
- package/src/resolvers/RunAIAgentResolver.ts +296 -85
- package/src/resolvers/RunTemplateResolver.ts +6 -4
- package/src/resolvers/RunTestResolver.ts +3 -1
- package/src/resolvers/SearchKnowledgeStreamResolver.ts +19 -3
- package/src/resolvers/SqlLoggingConfigResolver.ts +2 -4
- package/src/resolvers/SyncDataResolver.ts +4 -0
- package/src/resolvers/TaskGraphFrameResolver.ts +33 -1
- package/src/resolvers/TestQuerySQLResolver.ts +69 -13
- package/src/resolvers/TransactionGroupResolver.ts +185 -30
- package/src/resolvers/UserViewResolver.ts +2 -1
- package/src/resolvers/__tests__/GetDataResolver.validation.test.ts +95 -0
- package/src/resolvers/__tests__/MergeRecordsResolver.test.ts +43 -0
- package/src/resolvers/agent-run-data-guard.ts +89 -0
- package/src/rest/EntityCRUDHandler.ts +22 -5
- package/src/rest/RESTEndpointHandler.ts +8 -5
- package/src/rest/RealtimeRecordingHandler.ts +467 -0
- package/src/rest/ViewOperationsHandler.ts +52 -18
- package/src/rest/setupRESTEndpoints.ts +6 -0
- package/src/serverExtensionReservedRoots.ts +14 -17
- package/src/serverRoleConfigUnits.ts +48 -0
- package/src/services/MJStorageBlobStore.ts +31 -30
- package/src/services/StartTaskGraphDispatcher.ts +2 -2
- package/src/services/TaskGraphActionRunner.ts +25 -5
- package/src/services/TaskGraphAgentRunner.ts +188 -11
- package/src/services/TaskGraphContinuationDeliverer.ts +738 -16
- package/src/sharedCache.ts +3 -0
- package/src/types.ts +23 -1
package/src/index.ts
CHANGED
|
@@ -4,7 +4,7 @@ dotenv.config({ quiet: true });
|
|
|
4
4
|
|
|
5
5
|
import { expressMiddleware } from '@as-integrations/express5';
|
|
6
6
|
import { mergeSchemas } from '@graphql-tools/schema';
|
|
7
|
-
import { Metadata, DatabasePlatform, SetProvider, StartupManager as StartupManagerImport, BaseEntity, BaseEntityEvent, RunView, DatabaseProviderBase, ProviderBase, ResolveStartupMode } from '@memberjunction/core';
|
|
7
|
+
import { Metadata, DatabasePlatform, SetProvider, StartupManager as StartupManagerImport, BaseEntity, BaseEntityEvent, RunView, DatabaseProviderBase, ProviderBase, ResolveStartupMode, UserInfo } from '@memberjunction/core';
|
|
8
8
|
import { UserCache, resolveDbPlatformFromEnv } from '@memberjunction/generic-database-provider';
|
|
9
9
|
import { MJGlobal, MJEventType, UUIDsEqual, ShutdownRegistry } from '@memberjunction/global';
|
|
10
10
|
import { setupSQLServerClient, SQLServerDataProvider, SQLServerProviderConfigData } from '@memberjunction/sqlserver-dataprovider';
|
|
@@ -38,24 +38,18 @@ import { default as jwt } from 'jsonwebtoken';
|
|
|
38
38
|
import { contextFunction, CreateReadOnlyProvider, CreateUnifiedAuthMiddleware, getUserPayload } from './context.js';
|
|
39
39
|
import { UserPayload } from './types.js';
|
|
40
40
|
import { requireSystemUserDirective, publicDirective } from './directives/index.js';
|
|
41
|
-
import { variablesLoggingMiddleware } from './logging/variablesLoggingMiddleware.js';
|
|
41
|
+
import { ApplyRootVariablesLoggingMiddleware, variablesLoggingMiddleware } from './logging/variablesLoggingMiddleware.js';
|
|
42
42
|
import { auditResolversForUndecoratedArgs } from './logging/bootAudit.js';
|
|
43
43
|
import { StartupLogger } from './logging/StartupLogger.js';
|
|
44
44
|
import { AuthProviderFactory } from '@memberjunction/auth-providers';
|
|
45
45
|
import createMSSQLConfig from './orm.js';
|
|
46
46
|
import { setupRESTEndpoints } from './rest/setupRESTEndpoints.js';
|
|
47
|
-
import {
|
|
48
|
-
import {
|
|
49
|
-
import {
|
|
50
|
-
import {
|
|
51
|
-
import { REALTIME_SDP_EXCHANGE_PATH } from '@memberjunction/ai';
|
|
52
|
-
import { createMagicLinkHandler, createMagicLinkJwksRouter, registerMagicLinkAuthProvider, MAGIC_LINK_MOUNT_PATH } from './auth/magicLink/index.js';
|
|
53
|
-
import { createWidgetHandler, WIDGET_MOUNT_PATH } from './realtimeWidget/index.js';
|
|
47
|
+
import { CreateRealtimeRecordingRouter, REALTIME_RECORDING_MOUNT_PATH } from './rest/RealtimeRecordingHandler.js';
|
|
48
|
+
import { LoadOwnedRealtimeSession } from './realtimeSessions/ownedRealtimeSession.js';
|
|
49
|
+
import { AuthorizeAnonymousRoomSessions, LoadSessionConversationScope } from './realtimeSessions/sessionAccess.js';
|
|
50
|
+
import { RecordingAssemblyScheduler } from './realtimeSessions/RecordingAssemblyScheduler.js';
|
|
54
51
|
import {
|
|
55
|
-
CreateRealtimeVerifyRouter,
|
|
56
|
-
REALTIME_VERIFY_MOUNT_PATH,
|
|
57
52
|
RealtimeSessionEventService,
|
|
58
|
-
RealtimeSessionVerificationService,
|
|
59
53
|
ParseReplicatedRealtimeSessionEvent,
|
|
60
54
|
type RealtimeSessionEventTopicPayload,
|
|
61
55
|
} from './realtimeSessions/index.js';
|
|
@@ -67,7 +61,6 @@ import { ScheduledJobsService } from './services/ScheduledJobsService.js';
|
|
|
67
61
|
import { IntegrationSyncWorkerService } from './services/IntegrationSyncWorkerService.js';
|
|
68
62
|
import { LocalCacheManager, StartupManager, TelemetryManager, TelemetryLevel, LogStatus, LogError, SetVerboseLogging } from '@memberjunction/core';
|
|
69
63
|
import { getSystemUser, validateAuthProvidersRegistered } from './auth/index.js';
|
|
70
|
-
import { createAuthProviderCatalogRouter, AUTH_CATALOG_MOUNT_PATH } from './auth/AuthProviderCatalogRouter.js';
|
|
71
64
|
import { GetAPIKeyEngine } from '@memberjunction/api-keys';
|
|
72
65
|
import { ActionEngineServer } from '@memberjunction/actions';
|
|
73
66
|
import { CreateAdhocSQLAuthorizer } from './resolvers/AdhocQueryResolver.js';
|
|
@@ -80,14 +73,14 @@ import {
|
|
|
80
73
|
SetHandoffOfferPublishHook,
|
|
81
74
|
ParseReplicatedHandoffOfferUpdate,
|
|
82
75
|
} from './resolvers/HumanHandoffResolver.js';
|
|
83
|
-
import { RoomHandoffEngine } from '@memberjunction/livekit-room-server';
|
|
76
|
+
import { RoomAuthorizationService, RoomHandoffEngine } from '@memberjunction/livekit-room-server';
|
|
84
77
|
// Type-only: the provider is built in ./sharedCache.ts. Still needed here because the handoff-offer
|
|
85
78
|
// fan-out below stays in this file — see the note at its call site.
|
|
86
79
|
import type { RedisLocalStorageProvider } from '@memberjunction/redis-provider';
|
|
87
|
-
import { IntegrationProgressEmitter } from '@memberjunction/integration-progress-artifacts';
|
|
80
|
+
import { IntegrationProgressEmitter, SweepInterruptedRuns } from '@memberjunction/integration-progress-artifacts';
|
|
88
81
|
import { PublishIntegrationProgress } from './resolvers/IntegrationProgressResolver.js';
|
|
89
82
|
import { RegisterRSUProgressBridge } from './integration/RSUProgressBridge.js';
|
|
90
|
-
import { ClientToolRequestManager, AgentRunWatchdog } from '@memberjunction/ai-agents';
|
|
83
|
+
import { ClientToolRequestManager, AgentRunWatchdog, SqlRealtimeRecordingLedger } from '@memberjunction/ai-agents';
|
|
91
84
|
import { BindBridgeEngineHostInstance, SessionJanitor, SetHostInstancePort, StartBridgeOrphanReconciliation } from './agentSessions/index.js';
|
|
92
85
|
import { StartTaskGraphDispatcher } from './services/StartTaskGraphDispatcher.js';
|
|
93
86
|
import { MJServerWorkQueueProviderSource, StartWorkQueueHost } from './services/WorkQueueHostService.js';
|
|
@@ -103,14 +96,22 @@ import {
|
|
|
103
96
|
MJCompanyIntegrationFieldMapEntity,
|
|
104
97
|
MJScheduledJobEntity,
|
|
105
98
|
} from '@memberjunction/core-entities';
|
|
106
|
-
import { ServerExtensionLoader, ServerExtensionConfig, mergeServerExtensionConfigs, prepareServerExtensionConfigs, describeServerExtensionMount, InstallMediaUpgradeDispatcher, IsGraphQLWsPath } from '@memberjunction/server-extensions-core';
|
|
107
|
-
import {
|
|
99
|
+
import { ServerExtensionLoader, ServerExtensionConfig, mergeServerExtensionConfigs, prepareServerExtensionConfigs, describeServerExtensionMount, InstallMediaUpgradeDispatcher, IsGraphQLWsPath, GetCorsOwningServerExtensionRoots } from '@memberjunction/server-extensions-core';
|
|
100
|
+
import { CreateExtensionOwnedPreflightFallback, CreateGlobalCorsMiddleware } from './globalCors.js';
|
|
101
|
+
import { CoreReservedServerExtensionRoots } from './serverExtensionReservedRoots.js';
|
|
102
|
+
import { ApiRoute, ApiRootPath, ConfiguredPublicUrl } from './apiRoot.js';
|
|
103
|
+
import { MountHealthcheckRoute, MountPublicCoreRoutes, MountExtensionHealthRoute, MountAuthCatalogRoute, MountAuthenticatedCoreRoutes } from './coreRoutes.js';
|
|
108
104
|
import { MetadataCacheRefreshIntervalSeconds } from './providerConfigUnits.js';
|
|
109
105
|
import { CreateMetadataRefreshSignalHandler, METADATA_REFRESH_SIGNAL } from './metadataRefreshSignal.js';
|
|
106
|
+
import { CacheInvalidationBroadcastManager } from './broadcast/index.js';
|
|
107
|
+
import { ResolveServerRole, ShouldRunBackgroundWorkers } from './serverRoleConfigUnits.js';
|
|
110
108
|
|
|
111
109
|
const cacheRefreshInterval = configInfo.databaseSettings.metadataCacheRefreshInterval;
|
|
112
110
|
|
|
113
111
|
export { MetadataCacheRefreshIntervalSeconds } from './providerConfigUnits.js';
|
|
112
|
+
export * from './serverRoleConfigUnits.js';
|
|
113
|
+
export * from './broadcast/index.js';
|
|
114
|
+
export { ApplyRootVariablesLoggingMiddleware } from './logging/variablesLoggingMiddleware.js';
|
|
114
115
|
|
|
115
116
|
/**
|
|
116
117
|
* Returns the configured database platform from the `DB_PLATFORM` environment
|
|
@@ -142,6 +143,7 @@ export { Int, Float, ID } from 'type-graphql';
|
|
|
142
143
|
export { NewUserBase } from './auth/newUsers.js';
|
|
143
144
|
export { CreateIsolatedProvider } from './isolatedProvider.js';
|
|
144
145
|
export { configInfo, DEFAULT_SERVER_CONFIG } from './config.js';
|
|
146
|
+
export { ApiRoute, ApiRootPath, ConfiguredPublicUrl, JoinApiRoute, NormalizeApiRootPath, type ApiRouteOptions } from './apiRoot.js';
|
|
145
147
|
export { ServerExtensionLoader, BaseServerExtension, DefaultServerExtensionServiceRegistry } from '@memberjunction/server-extensions-core';
|
|
146
148
|
export type {
|
|
147
149
|
ServerExtensionConfig,
|
|
@@ -251,6 +253,7 @@ export * from './resolvers/FileCategoryResolver.js';
|
|
|
251
253
|
export * from './resolvers/FileResolver.js';
|
|
252
254
|
export * from './rest/MediaAccessKeys.js';
|
|
253
255
|
export * from './rest/MediaStreamHandler.js';
|
|
256
|
+
export * from './rest/RealtimeRecordingHandler.js';
|
|
254
257
|
export * from './resolvers/InfoResolver.js';
|
|
255
258
|
export * from './resolvers/PotentialDuplicateRecordResolver.js';
|
|
256
259
|
export * from './resolvers/DuplicateEntryCheckResolver.js';
|
|
@@ -303,7 +306,15 @@ const localPath = (p: string) => {
|
|
|
303
306
|
return resolvedPath;
|
|
304
307
|
};
|
|
305
308
|
|
|
306
|
-
|
|
309
|
+
/**
|
|
310
|
+
* Creates the Express application MJServer serves on. `X-Powered-By` is disabled: it only
|
|
311
|
+
* advertises the framework to scanners. {@link Serve} disables it again on a host-supplied app.
|
|
312
|
+
*/
|
|
313
|
+
export const CreateApp = (): Application => {
|
|
314
|
+
const app = express();
|
|
315
|
+
app.disable('x-powered-by');
|
|
316
|
+
return app;
|
|
317
|
+
};
|
|
307
318
|
|
|
308
319
|
/** @deprecated Use {@link CreateApp}. */
|
|
309
320
|
export const createApp = CreateApp;
|
|
@@ -426,6 +437,9 @@ export const Serve = async (resolverPaths: Array<string>, app: Application = Cre
|
|
|
426
437
|
SetHostInstancePort(graphqlPort);
|
|
427
438
|
// The realtime bridge engine stamps its bridge rows with the same identity and reconciles orphans by it (#5310).
|
|
428
439
|
BindBridgeEngineHostInstance();
|
|
440
|
+
// An anonymous visitor may join only the LiveKit agent-session room it owns by scope; the room gate cannot import
|
|
441
|
+
// this package's session-access decision, so it is handed in here, before any resolver runs (MJ#6044).
|
|
442
|
+
RoomAuthorizationService.Instance.SetAnonymousSessionOwnerCheck(AuthorizeAnonymousRoomSessions);
|
|
429
443
|
// Level-gated startup logger. Resolves verbosity from telemetry.level (single
|
|
430
444
|
// operator knob). At `standard` (default), per-phase timings are collapsed into
|
|
431
445
|
// the one-line summary; at `verbose`+ each phase prints inline as before.
|
|
@@ -485,6 +499,8 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
485
499
|
// Every API pool carries the statement and idle-in-transaction timeouts from connection #1.
|
|
486
500
|
const pgConnectionConfig = BuildPostgreSQLConnectionConfig(pgEndpoint, configInfo.databaseSettings, 'api');
|
|
487
501
|
const pgPool = new pg.default.Pool(ToPGPoolConfig(pgConnectionConfig));
|
|
502
|
+
// An idle connection the server drops is emitted on the pool; without a listener Node exits.
|
|
503
|
+
pgPool.on('error', (err) => console.error('[PostgreSQL pool] Idle connection error (connection evicted):', err.message));
|
|
488
504
|
|
|
489
505
|
// Verify connection
|
|
490
506
|
const testClient = await pgPool.connect();
|
|
@@ -502,6 +518,7 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
502
518
|
...ToPGPoolConfig(BuildPostgreSQLConnectionConfig({ ...pgEndpoint, ...pgReadOnlyCredentials }, configInfo.databaseSettings, 'read-only')),
|
|
503
519
|
types: MJPostgresTypes,
|
|
504
520
|
});
|
|
521
|
+
readOnlyPgPool.on('error', (err) => console.error('[PostgreSQL read-only pool] Idle connection error (connection evicted):', err.message));
|
|
505
522
|
const readOnlyTestClient = await readOnlyPgPool.connect();
|
|
506
523
|
try {
|
|
507
524
|
for (const warning of await DescribeReadOnlyLoginOverreach(readOnlyTestClient, mj_core_schema)) {
|
|
@@ -588,6 +605,7 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
588
605
|
'codegen',
|
|
589
606
|
);
|
|
590
607
|
const codegenPgPool = new pg.default.Pool(ToPGPoolConfig(codegenPgConnectionConfig));
|
|
608
|
+
codegenPgPool.on('error', (err) => console.error('[PostgreSQL CodeGen pool] Idle connection error (connection evicted):', err.message));
|
|
591
609
|
const codegenTestClient = await codegenPgPool.connect();
|
|
592
610
|
await codegenTestClient.query('SELECT 1');
|
|
593
611
|
codegenTestClient.release();
|
|
@@ -626,7 +644,7 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
626
644
|
startupLog.LogIf('verbose', 'RSU in-process CodeGen runner initialized (PostgreSQL).');
|
|
627
645
|
|
|
628
646
|
// Inject CodeGen output paths for targeted git staging
|
|
629
|
-
const { initializeConfig } = await import('@memberjunction/codegen-lib');
|
|
647
|
+
const { initializeConfig, ResolveAdditionalSchemaInfoPath } = await import('@memberjunction/codegen-lib');
|
|
630
648
|
const cgConfig = initializeConfig(rsuWorkDir);
|
|
631
649
|
const outputPaths = (cgConfig.output ?? []).map((o: { directory: string }) => o.directory);
|
|
632
650
|
RuntimeSchemaManager.Instance.SetCodeGenOutputPaths(outputPaths);
|
|
@@ -635,9 +653,12 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
635
653
|
// Point RSU's soft PK/FK writer at the SAME file CodeGen reads (mj.config.cjs
|
|
636
654
|
// `additionalSchemaInfo`), or RSU writes soft PKs to its own default path while
|
|
637
655
|
// CodeGen reads a different one and skips integration tables with "No primary key found".
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
656
|
+
// Inject the ABSOLUTE path CodeGen resolves (env override, else relative to the mj.config
|
|
657
|
+
// file's directory) so RSU, the resolvers and CodeGen agree whatever their cwd (#5858).
|
|
658
|
+
const resolvedSchemaInfoPath = ResolveAdditionalSchemaInfoPath();
|
|
659
|
+
if (resolvedSchemaInfoPath) {
|
|
660
|
+
RuntimeSchemaManager.Instance.SetAdditionalSchemaInfoPath(resolvedSchemaInfoPath);
|
|
661
|
+
startupLog.LogIf('verbose', `RSU additionalSchemaInfo path: ${resolvedSchemaInfoPath}`);
|
|
641
662
|
} else if (RuntimeSchemaManager.Instance.IsEnabled) {
|
|
642
663
|
// U5 — boot-time assert: RSU is enabled but CodeGen has NO additionalSchemaInfo path
|
|
643
664
|
// configured, so RSU's soft-PK/FK writes land in a file CodeGen never reads. Every
|
|
@@ -645,7 +666,7 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
645
666
|
// named, and actionable — grep for RSU_ADDITIONAL_SCHEMA_INFO_DIVERGENCE.
|
|
646
667
|
console.error(
|
|
647
668
|
`[RSU_ADDITIONAL_SCHEMA_INFO_DIVERGENCE] Runtime Schema Update is ENABLED but mj.config.cjs has no ` +
|
|
648
|
-
`'additionalSchemaInfo' setting — RSU writes soft PK/FK definitions to '${
|
|
669
|
+
`'additionalSchemaInfo' setting (and RSU_ADDITIONAL_SCHEMA_INFO_PATH is unset) — RSU writes soft PK/FK definitions to '${RuntimeSchemaManager.Instance.AdditionalSchemaInfoPath}' ` +
|
|
649
670
|
`while CodeGen reads none, so resolved soft primary keys will be silently LOST at codegen time. ` +
|
|
650
671
|
`Set 'additionalSchemaInfo' in mj.config.cjs to the same file so the write path and read path agree.`
|
|
651
672
|
);
|
|
@@ -771,7 +792,7 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
771
792
|
startupLog.LogIf('verbose', 'RSU in-process CodeGen runner initialized.');
|
|
772
793
|
|
|
773
794
|
// Inject CodeGen output paths for targeted git staging
|
|
774
|
-
const { initializeConfig } = await import('@memberjunction/codegen-lib');
|
|
795
|
+
const { initializeConfig, ResolveAdditionalSchemaInfoPath } = await import('@memberjunction/codegen-lib');
|
|
775
796
|
const codegenConfig = initializeConfig(rsuWorkDir);
|
|
776
797
|
const outputPaths = (codegenConfig.output ?? []).map((o: { directory: string }) => o.directory);
|
|
777
798
|
RuntimeSchemaManager.Instance.SetCodeGenOutputPaths(outputPaths);
|
|
@@ -781,14 +802,17 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
781
802
|
// `additionalSchemaInfo`). Without this, RSU writes soft PKs to its own default
|
|
782
803
|
// path while CodeGen reads a different one and skips every integration table
|
|
783
804
|
// with "No primary key found".
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
805
|
+
// Inject the ABSOLUTE path CodeGen resolves (env override, else relative to the mj.config
|
|
806
|
+
// file's directory) so RSU, the resolvers and CodeGen agree whatever their cwd (#5858).
|
|
807
|
+
const resolvedSchemaInfoPath = ResolveAdditionalSchemaInfoPath();
|
|
808
|
+
if (resolvedSchemaInfoPath) {
|
|
809
|
+
RuntimeSchemaManager.Instance.SetAdditionalSchemaInfoPath(resolvedSchemaInfoPath);
|
|
810
|
+
startupLog.LogIf('verbose', `RSU additionalSchemaInfo path: ${resolvedSchemaInfoPath}`);
|
|
787
811
|
} else if (RuntimeSchemaManager.Instance.IsEnabled) {
|
|
788
812
|
// U5 — boot-time assert: write path ≠ read path (see the PostgreSQL branch for detail).
|
|
789
813
|
console.error(
|
|
790
814
|
`[RSU_ADDITIONAL_SCHEMA_INFO_DIVERGENCE] Runtime Schema Update is ENABLED but mj.config.cjs has no ` +
|
|
791
|
-
`'additionalSchemaInfo' setting — RSU writes soft PK/FK definitions to '${
|
|
815
|
+
`'additionalSchemaInfo' setting (and RSU_ADDITIONAL_SCHEMA_INFO_PATH is unset) — RSU writes soft PK/FK definitions to '${RuntimeSchemaManager.Instance.AdditionalSchemaInfoPath}' ` +
|
|
792
816
|
`while CodeGen reads none, so resolved soft primary keys will be silently LOST at codegen time. ` +
|
|
793
817
|
`Set 'additionalSchemaInfo' in mj.config.cjs to the same file so the write path and read path agree.`
|
|
794
818
|
);
|
|
@@ -839,6 +863,8 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
839
863
|
if (sharedCache) {
|
|
840
864
|
await LocalCacheManager.Instance.SetStorageProvider(sharedCache);
|
|
841
865
|
}
|
|
866
|
+
// The derived per-entry ceiling, so the boot log says what the largest cacheable entry actually is.
|
|
867
|
+
startupLog.LogIf('verbose', `LocalCacheManager: largest cacheable entry ${Math.floor(LocalCacheManager.Instance.MaxEntrySizeBytes / 1024 / 1024)} MB (maxEntryPercentOfCache: ${configInfo.cacheSettings?.maxEntryPercentOfCache ?? 'auto'})`);
|
|
842
868
|
const engineSweepMs = StartEngineSweeper(configInfo.cacheSettings);
|
|
843
869
|
startupLog.LogIf('verbose', engineSweepMs > 0 ? `Engine/database sweep every ${engineSweepMs / 1000}s` : 'Engine/database sweep disabled');
|
|
844
870
|
const userCacheCheckMs = StartUserCacheChecks(configInfo.cacheSettings);
|
|
@@ -1022,6 +1048,7 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
1022
1048
|
// config.ts loads and validates at module scope, so importing it there would pull full config
|
|
1023
1049
|
// validation into every import chain that touches the resolver, unit tests included.
|
|
1024
1050
|
ConfigureRecordDataBroadcast(configInfo.cacheSettings?.recordDataBroadcastEntities);
|
|
1051
|
+
CacheInvalidationBroadcastManager.Instance.Configure(configInfo.cacheSettings?.broadcast);
|
|
1025
1052
|
|
|
1026
1053
|
// Global listener: broadcast CACHE_INVALIDATION to all browser clients whenever
|
|
1027
1054
|
// ANY BaseEntity save/delete occurs on this server — regardless of whether it
|
|
@@ -1044,7 +1071,8 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
1044
1071
|
// fires for server-internal saves too (agents, actions, orchestrator), which are exactly
|
|
1045
1072
|
// the ones no browser session asked for.
|
|
1046
1073
|
recordData:
|
|
1047
|
-
beEvent.type === 'save' && MayBroadcastRecordData(entityName)
|
|
1074
|
+
beEvent.type === 'save' && MayBroadcastRecordData(entityName, beEvent.baseEntity.EntityInfo)
|
|
1075
|
+
// fls-guard: MayBroadcastRecordData refuses FLS entities and Record Changes
|
|
1048
1076
|
? JSON.stringify(beEvent.baseEntity.GetAll())
|
|
1049
1077
|
: undefined,
|
|
1050
1078
|
});
|
|
@@ -1095,7 +1123,6 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
1095
1123
|
scalarsMap: [{ type: Date, scalar: GraphQLTimestamp }],
|
|
1096
1124
|
emitSchemaFile: websiteRunFromPackage !== 1,
|
|
1097
1125
|
pubSub,
|
|
1098
|
-
globalMiddlewares: [variablesLoggingMiddleware],
|
|
1099
1126
|
});
|
|
1100
1127
|
const buildMs = performance.now() - tBuild;
|
|
1101
1128
|
|
|
@@ -1122,6 +1149,7 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
1122
1149
|
auditResolversForUndecoratedArgs();
|
|
1123
1150
|
|
|
1124
1151
|
const tTransform = performance.now();
|
|
1152
|
+
schema = ApplyRootVariablesLoggingMiddleware(schema);
|
|
1125
1153
|
schema = requireSystemUserDirective.transformer(schema);
|
|
1126
1154
|
schema = publicDirective.transformer(schema);
|
|
1127
1155
|
|
|
@@ -1270,6 +1298,9 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
1270
1298
|
await apolloServer.start();
|
|
1271
1299
|
|
|
1272
1300
|
// Fix #8: Add compression for better throughput performance
|
|
1301
|
+
// Never advertise the framework (`X-Powered-By: Express`) — the host may have passed its own app.
|
|
1302
|
+
app.disable('x-powered-by');
|
|
1303
|
+
|
|
1273
1304
|
app.use(compression({
|
|
1274
1305
|
// Don't compress responses smaller than 1KB
|
|
1275
1306
|
threshold: 1024,
|
|
@@ -1290,114 +1321,23 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
1290
1321
|
level: 6
|
|
1291
1322
|
}));
|
|
1292
1323
|
|
|
1293
|
-
// Health check
|
|
1294
|
-
//
|
|
1295
|
-
|
|
1296
|
-
// clients (e.g. MJExplorer's connectivity poller) can read the response.
|
|
1297
|
-
app.get('/healthcheck', cors<cors.CorsRequest>(), (_req, res) => {
|
|
1298
|
-
res.status(200).json({ status: 'ok' });
|
|
1299
|
-
});
|
|
1324
|
+
// Health check — before every middleware contribution and the auth middleware, so cloud platform
|
|
1325
|
+
// probes never generate auth noise. Every core route mounts under MJAPI_BASE_PATH (see apiRoot.ts).
|
|
1326
|
+
MountHealthcheckRoute(app);
|
|
1300
1327
|
|
|
1301
1328
|
// Apply middleware-contributed pre-auth handlers (after compression, before routes)
|
|
1302
1329
|
for (const mw of mwPreAuth) {
|
|
1303
1330
|
app.use(mw);
|
|
1304
1331
|
}
|
|
1305
1332
|
|
|
1306
|
-
// ───
|
|
1307
|
-
|
|
1333
|
+
// ─── Public core routes (unauthenticated, registered BEFORE auth) ─────
|
|
1334
|
+
// OAuth callback, eSignature, media, realtime SDP broker, magic-link, widget, realtime verify — see
|
|
1335
|
+
// coreRoutes.ts. New custom routes belong in Server Extensions, never in serve().
|
|
1336
|
+
// oauthPublicUrl is the configured public URL, derived as it always was; it is also the magic-link JWT
|
|
1337
|
+
// issuer, so it stays untrimmed. Outward links use ApiRoute(…, { absolute: true }) instead.
|
|
1338
|
+
const oauthPublicUrl = ConfiguredPublicUrl();
|
|
1308
1339
|
startupLog.LogIf('verbose', `[OAuth] publicUrl: ${oauthPublicUrl}`);
|
|
1309
|
-
|
|
1310
|
-
let oauthAuthenticatedRouter: ReturnType<typeof createOAuthCallbackHandler>['authenticatedRouter'] | undefined;
|
|
1311
|
-
if (oauthPublicUrl) {
|
|
1312
|
-
const { callbackRouter, authenticatedRouter } = createOAuthCallbackHandler({
|
|
1313
|
-
publicUrl: oauthPublicUrl,
|
|
1314
|
-
successRedirectUrl: `${oauthPublicUrl}/oauth/success`,
|
|
1315
|
-
errorRedirectUrl: `${oauthPublicUrl}/oauth/error`,
|
|
1316
|
-
// Constrains where a caller-supplied frontendReturnUrl may point (open-redirect guard).
|
|
1317
|
-
allowedFrontendOrigins: configInfo.cors?.allowedOrigins ?? ['*']
|
|
1318
|
-
});
|
|
1319
|
-
oauthAuthenticatedRouter = authenticatedRouter;
|
|
1320
|
-
|
|
1321
|
-
const oauthCors = cors<cors.CorsRequest>();
|
|
1322
|
-
|
|
1323
|
-
// OAuth callback is unauthenticated (called by external auth server)
|
|
1324
|
-
app.use('/oauth', oauthCors, callbackRouter);
|
|
1325
|
-
startupLog.LogIf('verbose', '[OAuth] Callback route registered at /oauth/callback');
|
|
1326
|
-
}
|
|
1327
|
-
|
|
1328
|
-
// ─── Core HTTP Routes (Static Core Infrastructure) ─────────────────────────
|
|
1329
|
-
// IMPORTANT ARCHITECTURAL NOTE:
|
|
1330
|
-
// The route mounts below are strictly reserved for core framework infrastructure (OAuth, eSignature,
|
|
1331
|
-
// media streaming, realtime WebRTC broker, magic-link, widgets).
|
|
1332
|
-
// ALL new custom routes, external webhooks, vendor adapters, and application integrations MUST be
|
|
1333
|
-
// implemented as Server Extensions (subclasses of BaseServerExtension in @memberjunction/server-extensions-core)
|
|
1334
|
-
// mounted via ServerExtensionLoader — NEVER hardcoded as ad-hoc app.use() in serve().
|
|
1335
|
-
// See guides/SERVER_EXTENSIONS_GUIDE.md for complete patterns and best practices.
|
|
1336
|
-
|
|
1337
|
-
// ─── eSignature webhook (unauthenticated, registered BEFORE auth) ─────
|
|
1338
|
-
// Called by external signature providers (DocuSign Connect, etc.) without an MJ bearer token.
|
|
1339
|
-
// The provider DRIVER verifies the payload signature/HMAC; MJ auth does not apply here.
|
|
1340
|
-
app.use('/esignature', cors<cors.CorsRequest>(), createSignatureWebhookHandler());
|
|
1341
|
-
startupLog.LogIf('verbose', '[eSignature] Webhook route registered at /esignature/webhook/:driverKey');
|
|
1342
|
-
|
|
1343
|
-
// ─── Authenticated media streaming (token-gated, registered BEFORE auth) ─────
|
|
1344
|
-
// The `?token=` query param (minted by CreateMediaAccessToken after a per-user permission
|
|
1345
|
-
// check) is the capability — the route verifies it itself, so it does NOT use the MJ bearer
|
|
1346
|
-
// auth middleware (an <audio>/<video> element can't send Authorization headers).
|
|
1347
|
-
app.use('/media', cors<cors.CorsRequest>(), createMediaStreamRouter());
|
|
1348
|
-
startupLog.LogIf('verbose', '[Media] Streaming route registered at /media/:fileId');
|
|
1349
|
-
|
|
1350
|
-
// ─── Realtime WebRTC SDP broker (ticket-gated, registered BEFORE auth) ───────
|
|
1351
|
-
if (configInfo.realtime?.enabled) {
|
|
1352
|
-
app.use(REALTIME_SDP_EXCHANGE_PATH, cors<cors.CorsRequest>(), createRealtimeSdpBrokerRouter());
|
|
1353
|
-
startupLog.LogIf('verbose', `[Realtime] WebRTC SDP broker registered at ${REALTIME_SDP_EXCHANGE_PATH}`);
|
|
1354
|
-
}
|
|
1355
|
-
|
|
1356
|
-
// ─── Magic-link routes (MJ-issued, app-scoped external access) ───────────
|
|
1357
|
-
// Public router (JWKS + redeem) mounts BEFORE the auth middleware; the
|
|
1358
|
-
// authenticated invite-creation router mounts AFTER it (see below).
|
|
1359
|
-
let widgetAuthenticatedRouter: ReturnType<typeof createWidgetHandler>['authenticatedRouter'] | undefined;
|
|
1360
|
-
let magicLinkAuthenticatedRouter: ReturnType<typeof createMagicLinkHandler>['authenticatedRouter'] | undefined;
|
|
1361
|
-
if (configInfo.magicLink?.enabled) {
|
|
1362
|
-
const { publicRouter, authenticatedRouter } = createMagicLinkHandler(oauthPublicUrl, configInfo.magicLink);
|
|
1363
|
-
magicLinkAuthenticatedRouter = authenticatedRouter;
|
|
1364
|
-
registerMagicLinkAuthProvider(oauthPublicUrl, configInfo.magicLink);
|
|
1365
|
-
app.use(MAGIC_LINK_MOUNT_PATH, cors<cors.CorsRequest>(), publicRouter);
|
|
1366
|
-
startupLog.LogIf('verbose', `[MagicLink] Public routes registered at ${MAGIC_LINK_MOUNT_PATH}/redeem and ${MAGIC_LINK_MOUNT_PATH}/jwks.json`);
|
|
1367
|
-
}
|
|
1368
|
-
|
|
1369
|
-
// ─── Public web widget: guest-session mint (PUBLIC, before auth mw) ───────
|
|
1370
|
-
// Visitors hold no MJ JWT yet, so POST /widget/session is public. It reuses the
|
|
1371
|
-
// magic-link RS256 key + `magic-link` auth provider (ensured idempotently inside
|
|
1372
|
-
// createWidgetHandler), so it stands on its own even if magicLink.enabled is false.
|
|
1373
|
-
if (configInfo.widget?.enabled) {
|
|
1374
|
-
const { publicRouter: widgetRouter, authenticatedRouter: widgetAuthRouter } = createWidgetHandler(oauthPublicUrl, configInfo.widget);
|
|
1375
|
-
widgetAuthenticatedRouter = widgetAuthRouter;
|
|
1376
|
-
app.use(WIDGET_MOUNT_PATH, cors<cors.CorsRequest>(), widgetRouter);
|
|
1377
|
-
// The widget reuses the magic-link RS256 key + auth provider to validate guest
|
|
1378
|
-
// tokens, which validates by fetching the JWKS at MAGIC_LINK_MOUNT_PATH/jwks.json.
|
|
1379
|
-
// When magic-link itself is disabled its public router (which serves JWKS) never
|
|
1380
|
-
// mounts, so publish the key here — otherwise every guest token fails validation
|
|
1381
|
-
// (the auth middleware can't fetch the public key) and the widget 401s.
|
|
1382
|
-
if (!configInfo.magicLink?.enabled) {
|
|
1383
|
-
app.use(MAGIC_LINK_MOUNT_PATH, cors<cors.CorsRequest>(), createMagicLinkJwksRouter());
|
|
1384
|
-
startupLog.LogIf('verbose', `[Widget] Published reused signing key at ${MAGIC_LINK_MOUNT_PATH}/jwks.json (magic-link flow disabled)`);
|
|
1385
|
-
}
|
|
1386
|
-
startupLog.LogIf('verbose', `[Widget] Public routes registered at ${WIDGET_MOUNT_PATH}/session and ${WIDGET_MOUNT_PATH}/session/refresh`);
|
|
1387
|
-
}
|
|
1388
|
-
|
|
1389
|
-
// ─── Realtime identity verification: PUBLIC verify-link routes (before auth mw) ───
|
|
1390
|
-
// The person opening the emailed link holds no MJ token — the single-use token is the capability.
|
|
1391
|
-
// GET only renders a confirm button; the POST redeems (mail scanners GET every link). Mounted only
|
|
1392
|
-
// when verification is enabled AND able to send mail AND able to protect its codes (see
|
|
1393
|
-
// realtime.identityVerification config: communicationProvider + hmacSecret).
|
|
1394
|
-
if (configInfo.realtime?.identityVerification?.enabled && !RealtimeSessionVerificationService.Instance.IsEnabled) {
|
|
1395
|
-
console.warn('[RealtimeVerify] realtime.identityVerification.enabled is true but verification is unavailable: it needs a communicationProvider and an hmacSecret of at least 16 characters.');
|
|
1396
|
-
}
|
|
1397
|
-
if (RealtimeSessionVerificationService.Instance.IsEnabled) {
|
|
1398
|
-
app.use(REALTIME_VERIFY_MOUNT_PATH, cors<cors.CorsRequest>(), CreateRealtimeVerifyRouter());
|
|
1399
|
-
startupLog.LogIf('verbose', `[RealtimeVerify] Public routes registered at ${REALTIME_VERIFY_MOUNT_PATH}/:token (GET) and ${REALTIME_VERIFY_MOUNT_PATH} (POST)`);
|
|
1400
|
-
}
|
|
1340
|
+
const coreAuthenticatedRouters = MountPublicCoreRoutes(app, oauthPublicUrl, startupLog);
|
|
1401
1341
|
|
|
1402
1342
|
// ─── Server extensions loader & shared service registry ───────────────────
|
|
1403
1343
|
const extensionLoader = new ServerExtensionLoader();
|
|
@@ -1468,9 +1408,9 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
1468
1408
|
|
|
1469
1409
|
// Open App packages publish their extensions; host mj.config.cjs overlays by DriverClass
|
|
1470
1410
|
// (and remains the only source for host-only extensions such as Slack/Teams).
|
|
1471
|
-
//
|
|
1472
|
-
//
|
|
1473
|
-
//
|
|
1411
|
+
// Every RootPath is relative to MJAPI_BASE_PATH: apiRootPath composes the real mount path, and
|
|
1412
|
+
// extraReservedRoots (also relative) must list every core mount in coreRoutes.ts, otherwise an
|
|
1413
|
+
// Open App can claim it.
|
|
1474
1414
|
const extensionConfigs = prepareServerExtensionConfigs(
|
|
1475
1415
|
mergeServerExtensionConfigs(
|
|
1476
1416
|
options?.serverExtensions ?? [],
|
|
@@ -1479,7 +1419,8 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
1479
1419
|
{
|
|
1480
1420
|
onInvalid: (message) => LogError(message),
|
|
1481
1421
|
onOverlap: (message) => LogStatus(message),
|
|
1482
|
-
extraReservedRoots:
|
|
1422
|
+
extraReservedRoots: CoreReservedServerExtensionRoots(),
|
|
1423
|
+
apiRootPath: ApiRootPath(),
|
|
1483
1424
|
},
|
|
1484
1425
|
);
|
|
1485
1426
|
for (const cfg of extensionConfigs) {
|
|
@@ -1490,27 +1431,14 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
1490
1431
|
// Without this, the browser blocks 401 responses from the auth middleware
|
|
1491
1432
|
// because they lack Access-Control-Allow-Origin headers, preventing the
|
|
1492
1433
|
// client from reading the error code and triggering token refresh.
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
//
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
app.use(cors<cors.CorsRequest>({
|
|
1502
|
-
origin: (origin, callback) => {
|
|
1503
|
-
// Allow all origins when ['*'] (default/backward-compatible),
|
|
1504
|
-
// or when no Origin header (server-to-server calls).
|
|
1505
|
-
if (corsWildcard || !origin || corsAllowed.includes(origin)) {
|
|
1506
|
-
callback(null, true);
|
|
1507
|
-
} else {
|
|
1508
|
-
callback(new Error(`Origin ${origin} not allowed by CORS`));
|
|
1509
|
-
}
|
|
1510
|
-
},
|
|
1511
|
-
credentials: corsWildcard ? false : (configInfo.cors?.allowCredentials ?? true),
|
|
1512
|
-
maxAge: configInfo.cors?.maxAge ?? 86400,
|
|
1513
|
-
}));
|
|
1434
|
+
// Extensions that declare `OwnsCORS: true` (ServerExtensionConfig) are exempt: the global
|
|
1435
|
+
// middleware skips their RootPaths so it neither reflects an origin onto their responses nor
|
|
1436
|
+
// answers their preflights — the extension's own OPTIONS handling and origin policy run instead.
|
|
1437
|
+
const corsOwnedExtensionRoots = GetCorsOwningServerExtensionRoots(extensionConfigs);
|
|
1438
|
+
if (corsOwnedExtensionRoots.length > 0) {
|
|
1439
|
+
LogStatus(`Global CORS skips extension-owned roots: ${corsOwnedExtensionRoots.join(', ')}`);
|
|
1440
|
+
}
|
|
1441
|
+
app.use(CreateGlobalCorsMiddleware(configInfo.cors, corsOwnedExtensionRoots));
|
|
1514
1442
|
|
|
1515
1443
|
// ─── Pre-auth server extensions (before auth — extensions handle their own auth) ─────
|
|
1516
1444
|
// Slack uses HMAC signature verification, Teams uses Bot Framework JWT validation.
|
|
@@ -1521,23 +1449,12 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
1521
1449
|
phase: 'pre-auth',
|
|
1522
1450
|
httpServer,
|
|
1523
1451
|
publicUrl: oauthPublicUrl,
|
|
1452
|
+
apiRootPath: ApiRootPath(),
|
|
1524
1453
|
});
|
|
1525
1454
|
}
|
|
1526
1455
|
|
|
1527
|
-
|
|
1528
|
-
app
|
|
1529
|
-
const results = await extensionLoader.HealthCheckAll();
|
|
1530
|
-
const allHealthy = results.length === 0 || results.every(r => r.Healthy);
|
|
1531
|
-
res.status(allHealthy ? 200 : 503).json({ extensions: results });
|
|
1532
|
-
});
|
|
1533
|
-
|
|
1534
|
-
// ─── Public authentication-provider catalog (PUBLIC, before auth mw) ──────
|
|
1535
|
-
// The browser needs the provider list BEFORE it holds a token, so this is necessarily
|
|
1536
|
-
// unauthenticated and must mount ahead of the auth middleware. It publishes only the
|
|
1537
|
-
// non-secret allow-list (see AuthProviderEngine.GetPublicCatalog) — the same values a
|
|
1538
|
-
// single-provider SPA already compiled into its bundle.
|
|
1539
|
-
app.use(AUTH_CATALOG_MOUNT_PATH, cors<cors.CorsRequest>(), createAuthProviderCatalogRouter());
|
|
1540
|
-
startupLog.LogIf('verbose', `[Auth] Public provider catalog registered at ${AUTH_CATALOG_MOUNT_PATH}/providers`);
|
|
1456
|
+
MountExtensionHealthRoute(app, extensionLoader);
|
|
1457
|
+
MountAuthCatalogRoute(app, startupLog);
|
|
1541
1458
|
|
|
1542
1459
|
// ─── Unified auth middleware (replaces both REST authMiddleware and contextFunction auth) ─────
|
|
1543
1460
|
app.use(CreateUnifiedAuthMiddleware(dataSources));
|
|
@@ -1550,25 +1467,16 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
1550
1467
|
app.use(mw);
|
|
1551
1468
|
}
|
|
1552
1469
|
|
|
1553
|
-
// ───
|
|
1554
|
-
|
|
1555
|
-
const oauthCors = cors<cors.CorsRequest>();
|
|
1556
|
-
app.use('/oauth', oauthCors, BodyParser.json(), oauthAuthenticatedRouter);
|
|
1557
|
-
startupLog.LogIf('verbose', '[OAuth] Authenticated routes registered at /oauth/status, /oauth/initiate, and /oauth/exchange');
|
|
1558
|
-
}
|
|
1470
|
+
// ─── Authenticated core routes: OAuth status/initiate/exchange, magic-link create, widget resolve-identity ─────
|
|
1471
|
+
MountAuthenticatedCoreRoutes(app, coreAuthenticatedRouters, startupLog);
|
|
1559
1472
|
|
|
1560
|
-
// ───
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
// Mounts after the unified auth middleware so a verified visitor (post magic-link upgrade) can
|
|
1568
|
-
// promote their anonymous returning-visitor trail to the verified record.
|
|
1569
|
-
if (widgetAuthenticatedRouter) {
|
|
1570
|
-
app.use(WIDGET_MOUNT_PATH, cors<cors.CorsRequest>(), widgetAuthenticatedRouter);
|
|
1571
|
-
startupLog.LogIf('verbose', `[Widget] Authenticated route registered at ${WIDGET_MOUNT_PATH}/resolve-identity`);
|
|
1473
|
+
// ─── Realtime recording shards + terminal signal (authenticated, owner-gated) ─────
|
|
1474
|
+
// The browser uploads a client-direct call's recording as Opus shards and a keepalive terminal request;
|
|
1475
|
+
// assembly runs off the request path on the scheduler. Needs a SQL provider: the ledger calls procs.
|
|
1476
|
+
if (configInfo.realtime?.enabled) {
|
|
1477
|
+
if (mountRealtimeRecordingRoutes(app)) {
|
|
1478
|
+
startupLog.LogIf('verbose', `[Realtime] Recording routes registered at ${ApiRoute(REALTIME_RECORDING_MOUNT_PATH)}/:agentSessionId/shard/:index and /end`);
|
|
1479
|
+
}
|
|
1572
1480
|
}
|
|
1573
1481
|
|
|
1574
1482
|
// ─── Post-auth server extensions ──────────────────────────────────────────
|
|
@@ -1579,15 +1487,24 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
1579
1487
|
phase: 'post-auth',
|
|
1580
1488
|
httpServer,
|
|
1581
1489
|
publicUrl: oauthPublicUrl,
|
|
1490
|
+
apiRootPath: ApiRootPath(),
|
|
1582
1491
|
});
|
|
1583
1492
|
}
|
|
1584
1493
|
|
|
1494
|
+
// Every extension has now had its chance at the request: a preflight under an extension-owned
|
|
1495
|
+
// root that none of them answered is refused here, instead of falling through to the GraphQL
|
|
1496
|
+
// mount's cors(), which would approve it for every origin.
|
|
1497
|
+
if (corsOwnedExtensionRoots.length > 0) {
|
|
1498
|
+
app.use(CreateExtensionOwnedPreflightFallback(corsOwnedExtensionRoots));
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1585
1501
|
// ─── Cross-extension lifecycle hook: OnAllExtensionsMounted ───────────────
|
|
1586
1502
|
// Called after all extensions across both pre-auth and post-auth phases are mounted.
|
|
1587
1503
|
// Extensions can wire themselves to services registered by other extensions or core.
|
|
1588
1504
|
await extensionLoader.NotifyAllExtensionsMounted({
|
|
1589
1505
|
httpServer,
|
|
1590
1506
|
publicUrl: oauthPublicUrl,
|
|
1507
|
+
apiRootPath: ApiRootPath(),
|
|
1591
1508
|
});
|
|
1592
1509
|
|
|
1593
1510
|
// Install the single path-routing WebSocket-upgrade dispatcher AFTER all extensions across both
|
|
@@ -1633,11 +1550,29 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
1633
1550
|
// ─── GraphQL middleware (contextFunction reads req.userPayload, no re-auth) ─────
|
|
1634
1551
|
app.use(
|
|
1635
1552
|
graphqlRootPath,
|
|
1636
|
-
cors<cors.CorsRequest>(
|
|
1553
|
+
cors<cors.CorsRequest>({
|
|
1554
|
+
exposedHeaders: ['X-MJ-Cache-Seq', 'X-MJ-Server-ID'],
|
|
1555
|
+
}),
|
|
1637
1556
|
BodyParser.json({ limit: '50mb' }),
|
|
1638
1557
|
// Express 5 leaves req.body as undefined for non-JSON or empty bodies;
|
|
1639
1558
|
// Apollo Server's expressMiddleware requires req.body to be defined.
|
|
1640
|
-
|
|
1559
|
+
// Also piggyback the latest monotonic cache invalidation sequence and server process ID
|
|
1560
|
+
// onto every GraphQL HTTP response so clients can detect and recover missed invalidations.
|
|
1561
|
+
(req, res, next) => {
|
|
1562
|
+
if (req.body === undefined) req.body = {};
|
|
1563
|
+
const broadcastProvider = CacheInvalidationBroadcastManager.Instance.Provider;
|
|
1564
|
+
res.setHeader('X-MJ-Cache-Seq', String(broadcastProvider.CurrentSequence));
|
|
1565
|
+
res.setHeader('X-MJ-Server-ID', broadcastProvider.ServerProcessID);
|
|
1566
|
+
const originalWriteHead = res.writeHead.bind(res);
|
|
1567
|
+
res.writeHead = ((...args: Parameters<typeof res.writeHead>) => {
|
|
1568
|
+
if (!res.headersSent) {
|
|
1569
|
+
res.setHeader('X-MJ-Cache-Seq', String(broadcastProvider.CurrentSequence));
|
|
1570
|
+
res.setHeader('X-MJ-Server-ID', broadcastProvider.ServerProcessID);
|
|
1571
|
+
}
|
|
1572
|
+
return originalWriteHead(...args);
|
|
1573
|
+
}) as typeof res.writeHead;
|
|
1574
|
+
next();
|
|
1575
|
+
},
|
|
1641
1576
|
expressMiddleware(apolloServer, {
|
|
1642
1577
|
context: contextFunction({
|
|
1643
1578
|
setupComplete$,
|
|
@@ -1652,9 +1587,26 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
1652
1587
|
app.use(mw);
|
|
1653
1588
|
}
|
|
1654
1589
|
|
|
1590
|
+
const serverRole = ResolveServerRole(configInfo.serverRole ?? process.env.MJ_SERVER_ROLE);
|
|
1591
|
+
const runBackgroundWorkers = ShouldRunBackgroundWorkers(serverRole);
|
|
1592
|
+
if (!runBackgroundWorkers) {
|
|
1593
|
+
LogStatus(`[ServerRole] Running in '${serverRole}' mode — background worker services are disabled on this replica.`);
|
|
1594
|
+
}
|
|
1595
|
+
|
|
1596
|
+
// Close out run artifacts a dead process left open, BEFORE anything below can start a new run.
|
|
1597
|
+
//
|
|
1598
|
+
// A killed process (OOM killer, SIGKILL, host reboot) never writes its run's terminal result, so
|
|
1599
|
+
// the run reads as in-flight forever: the wizard spins, the active-operations panel shows a step
|
|
1600
|
+
// that will never advance, and no failure is reported anywhere. Sound only before the first new
|
|
1601
|
+
// run: artifacts are process-local, so anything still in flight as THIS process starts belongs
|
|
1602
|
+
// to a process that no longer exists. That is why it runs here, ahead of the scheduler, the
|
|
1603
|
+
// integration sync worker (its Start() polls immediately), the HTTP listener (a request can
|
|
1604
|
+
// start a discovery) and pending RSU work, and why it is awaited. It needs none of them.
|
|
1605
|
+
await SweepInterruptedRuns(undefined, msg => console.warn(msg));
|
|
1606
|
+
|
|
1655
1607
|
// Initialize and start scheduled jobs service if enabled
|
|
1656
1608
|
let scheduledJobsService: ScheduledJobsService | null = null;
|
|
1657
|
-
if (configInfo.scheduledJobs?.enabled) {
|
|
1609
|
+
if (runBackgroundWorkers && configInfo.scheduledJobs?.enabled) {
|
|
1658
1610
|
try {
|
|
1659
1611
|
scheduledJobsService = new ScheduledJobsService(configInfo.scheduledJobs);
|
|
1660
1612
|
await scheduledJobsService.Initialize();
|
|
@@ -1668,7 +1620,7 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
1668
1620
|
// Initialize and start the integration sync worker if enabled (PR 1 item 8).
|
|
1669
1621
|
// Off by default — deployments that don't opt in keep running syncs inline.
|
|
1670
1622
|
let integrationSyncWorker: IntegrationSyncWorkerService | null = null;
|
|
1671
|
-
if (configInfo.integrationSyncWorker?.enabled) {
|
|
1623
|
+
if (runBackgroundWorkers && configInfo.integrationSyncWorker?.enabled) {
|
|
1672
1624
|
try {
|
|
1673
1625
|
integrationSyncWorker = new IntegrationSyncWorkerService(configInfo.integrationSyncWorker);
|
|
1674
1626
|
await integrationSyncWorker.Initialize();
|
|
@@ -1706,52 +1658,55 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
1706
1658
|
}
|
|
1707
1659
|
startupLog.PrintSummary();
|
|
1708
1660
|
|
|
1709
|
-
// Process pending RSU work from pre-restart (entity maps, field maps, sync)
|
|
1710
|
-
processRSUPendingWork().catch(err => console.warn(`RSU pending work processing failed: ${err}`));
|
|
1711
|
-
|
|
1712
|
-
// Resume any integration syncs that were orphaned by the previous process restart
|
|
1713
1661
|
const resumeUser = UserCache.Instance.GetSystemUser();
|
|
1714
|
-
if (resumeUser) {
|
|
1715
|
-
IntegrationEngine.Instance.ResumeOrphanedSyncs(resumeUser)
|
|
1716
|
-
.catch(err => console.warn(`[IntegrationEngine] Orphaned sync resume failed: ${err}`));
|
|
1717
|
-
}
|
|
1718
1662
|
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
//
|
|
1730
|
-
//
|
|
1731
|
-
//
|
|
1732
|
-
//
|
|
1733
|
-
//
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1663
|
+
if (runBackgroundWorkers) {
|
|
1664
|
+
// Process pending RSU work from pre-restart (entity maps, field maps, sync)
|
|
1665
|
+
processRSUPendingWork().catch(err => console.warn(`RSU pending work processing failed: ${err}`));
|
|
1666
|
+
|
|
1667
|
+
// Resume any integration syncs that were orphaned by the previous process restart
|
|
1668
|
+
if (resumeUser) {
|
|
1669
|
+
IntegrationEngine.Instance.ResumeOrphanedSyncs(resumeUser)
|
|
1670
|
+
.catch(err => console.warn(`[IntegrationEngine] Orphaned sync resume failed: ${err}`));
|
|
1671
|
+
}
|
|
1672
|
+
|
|
1673
|
+
// Force-fail any agent runs left 'Running' by a process that died (restart/crash/OOM) or whose
|
|
1674
|
+
// terminal-state write never landed. Staleness-based, so it never touches runs another healthy
|
|
1675
|
+
// instance is still heart-beating. The watchdog also self-registers for graceful-shutdown
|
|
1676
|
+
// cancellation (via ShutdownRegistry) once it begins tracking this process's first live run.
|
|
1677
|
+
if (resumeUser && Metadata.Provider instanceof DatabaseProviderBase) { // global-provider-ok: server startup recovery — one-shot orphaned-run sweep at boot
|
|
1678
|
+
const sweepUser = resumeUser;
|
|
1679
|
+
const sweepProvider = Metadata.Provider; // global-provider-ok: server startup recovery — one-shot orphaned-run sweep at boot
|
|
1680
|
+
AgentRunWatchdog.SweepOrphanedRuns(sweepProvider, sweepUser)
|
|
1681
|
+
.catch(err => console.warn(`[AgentRunWatchdog] Startup sweep failed: ${err}`));
|
|
1682
|
+
|
|
1683
|
+
// The watchdog repairs the RUN; nothing repaired the conversation detail, which is the row the
|
|
1684
|
+
// chat actually renders from (MJ #4222). A process that dies mid-run leaves a terminal run
|
|
1685
|
+
// beside a message that still claims to be generating, and it spins forever for anyone who
|
|
1686
|
+
// opens it. Runs at boot (closes restart orphans) and on a timer (closes mid-life orphans),
|
|
1687
|
+
// mirroring the watchdog's own two-phase shape.
|
|
1688
|
+
const reconcileOrphans = () =>
|
|
1689
|
+
ReconcileOrphanedConversationDetails(sweepProvider, sweepUser)
|
|
1690
|
+
.catch(err => console.warn(`[OrphanDetailReconciler] Pass failed: ${err}`));
|
|
1691
|
+
void reconcileOrphans();
|
|
1692
|
+
const orphanDetailTimer = setInterval(() => void reconcileOrphans(), ORPHAN_DETAIL_SWEEP_INTERVAL_MS);
|
|
1693
|
+
ShutdownRegistry.Instance.Register({
|
|
1694
|
+
ShutdownName: 'OrphanDetailReconciler',
|
|
1695
|
+
Shutdown: () => { clearInterval(orphanDetailTimer); },
|
|
1696
|
+
});
|
|
1697
|
+
}
|
|
1744
1698
|
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1699
|
+
// Launch the AI Agent Session janitor: run own-host orphan recovery once at boot, then a periodic tick
|
|
1700
|
+
// that closes stale and over-deadline sessions and rebuilds lost realtime recordings from their
|
|
1701
|
+
// crash-recovery shards (storage reads and writes). Self-registers with ShutdownRegistry, so its timer
|
|
1702
|
+
// is cleared by the gracefulShutdown drain below (no explicit Stop() wiring needed here).
|
|
1703
|
+
if (resumeUser && Metadata.Provider instanceof DatabaseProviderBase) { // global-provider-ok: server startup recovery — boot-time session janitor uses the server's own provider
|
|
1704
|
+
SessionJanitor.Instance.Start(Metadata.Provider, resumeUser) // global-provider-ok: server-owned background reconciler runs under the server's provider + system user
|
|
1705
|
+
.catch(err => console.warn(`[SessionJanitor] Startup failed: ${err}`));
|
|
1706
|
+
// The bridge engine's orphan reconcile likewise starts only now that this process holds its port, so it can't
|
|
1707
|
+
// take the live bridges of another MJAPI still serving that port for its own orphans (#5310).
|
|
1708
|
+
StartBridgeOrphanReconciliation(Metadata.Provider, resumeUser); // global-provider-ok: server-owned background reconciler runs under the server's provider + system user
|
|
1709
|
+
}
|
|
1755
1710
|
}
|
|
1756
1711
|
|
|
1757
1712
|
// Launch the durable task-graph dispatcher: claim Pending tasks, execute them with a fresh
|
|
@@ -1780,7 +1735,7 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
1780
1735
|
// StartTaskGraphDispatcher); this gives the agent seam the same.
|
|
1781
1736
|
SuppressTaskGraphSubmission('MJ_DISABLE_TASK_GRAPH_DISPATCHER=1 is set on this host');
|
|
1782
1737
|
LogStatus('[TaskGraphDispatcher] Disabled by MJ_DISABLE_TASK_GRAPH_DISPATCHER=1 — this process will neither accept nor execute task graphs.');
|
|
1783
|
-
} else if (resumeUser && taskGraphPool instanceof sql.ConnectionPool) {
|
|
1738
|
+
} else if (runBackgroundWorkers && resumeUser && taskGraphPool instanceof sql.ConnectionPool) {
|
|
1784
1739
|
StartTaskGraphDispatcher(taskGraphPool, resumeUser)
|
|
1785
1740
|
.catch(err => console.warn(`[TaskGraphDispatcher] Startup failed: ${err}`));
|
|
1786
1741
|
}
|
|
@@ -1790,7 +1745,7 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
1790
1745
|
// ShutdownAll() drains it (up to 2 × shutdownDrainMs) before the HTTP server closes.
|
|
1791
1746
|
// Not awaited: a slow engine load must not delay readiness, and a failure never stops the API.
|
|
1792
1747
|
const workQueueProvider = Metadata.Provider; // global-provider-ok: server startup — the work-queue host runs on the server's own provider
|
|
1793
|
-
if (configInfo.workQueue?.enabled && workQueueProvider instanceof DatabaseProviderBase) {
|
|
1748
|
+
if (runBackgroundWorkers && configInfo.workQueue?.enabled && workQueueProvider instanceof DatabaseProviderBase) {
|
|
1794
1749
|
const workQueuePool = dataSources[0]?.dataSource;
|
|
1795
1750
|
const providerSource = new MJServerWorkQueueProviderSource(workQueuePool instanceof sql.ConnectionPool ? workQueuePool : null, workQueueProvider);
|
|
1796
1751
|
StartWorkQueueHost(configInfo.workQueue, workQueueProvider, providerSource)
|
|
@@ -2280,3 +2235,49 @@ function createMSSQLCompatPool(pgPool: import('pg').Pool): sql.ConnectionPool {
|
|
|
2280
2235
|
return wrapper as unknown as sql.ConnectionPool;
|
|
2281
2236
|
}
|
|
2282
2237
|
|
|
2238
|
+
// Defined below serve() on purpose: serverExtensionReservedRoots.test.ts treats every app.use() that appears
|
|
2239
|
+
// textually before the unified auth middleware as a pre-auth mount, and these routes are mounted post-auth.
|
|
2240
|
+
/**
|
|
2241
|
+
* Mounts the realtime recording shard/terminal routes (post-auth) and starts the assembly scheduler they
|
|
2242
|
+
* hand work to. Skipped, with a warning, when the server's provider is not a SQL provider (the ledger calls
|
|
2243
|
+
* stored procedures). Without a system user the routes still store shards, and the janitor assembles them.
|
|
2244
|
+
* Returns whether the routes were mounted.
|
|
2245
|
+
*/
|
|
2246
|
+
function mountRealtimeRecordingRoutes(app: Application): boolean {
|
|
2247
|
+
const provider = Metadata.Provider; // global-provider-ok: REST endpoint — no per-request provider injection in REST middleware yet; the ledger's procs run as the server's SQL login either way
|
|
2248
|
+
if (!(provider instanceof DatabaseProviderBase)) {
|
|
2249
|
+
console.warn('[Realtime] Recording routes not mounted: the server provider is not a DatabaseProviderBase');
|
|
2250
|
+
return false;
|
|
2251
|
+
}
|
|
2252
|
+
const graceMs = (): number => configInfo.realtime.recordingAssemblyGraceSeconds * 1000;
|
|
2253
|
+
const systemUser = UserCache.Instance.GetSystemUser();
|
|
2254
|
+
const runWorkers = ShouldRunBackgroundWorkers(ResolveServerRole(configInfo.serverRole ?? process.env.MJ_SERVER_ROLE));
|
|
2255
|
+
if (systemUser && runWorkers) {
|
|
2256
|
+
RecordingAssemblyScheduler.Instance.Start({ Provider: provider, SystemUser: systemUser, GraceMs: graceMs });
|
|
2257
|
+
} else if (!systemUser) {
|
|
2258
|
+
LogError('[Realtime] Recording assembly scheduler not started: no system user; the session janitor assembles recordings instead');
|
|
2259
|
+
}
|
|
2260
|
+
app.use(ApiRoute(REALTIME_RECORDING_MOUNT_PATH), cors<cors.CorsRequest>(), CreateRealtimeRecordingRouter({
|
|
2261
|
+
ResolveCaller: req => {
|
|
2262
|
+
const user: UserInfo | undefined = req.userPayload?.userRecord;
|
|
2263
|
+
return user ? { ContextUser: user, Provider: provider } : null;
|
|
2264
|
+
},
|
|
2265
|
+
LoadOwnedSession: LoadOwnedRealtimeSession,
|
|
2266
|
+
LoadConversationScope: LoadSessionConversationScope,
|
|
2267
|
+
CreateLedger: (ledgerProvider, contextUser) => new SqlRealtimeRecordingLedger(ledgerProvider, contextUser),
|
|
2268
|
+
Scheduler: RecordingAssemblyScheduler.Instance,
|
|
2269
|
+
GraceMs: graceMs,
|
|
2270
|
+
SystemUser: () => UserCache.Instance.GetSystemUser() ?? null,
|
|
2271
|
+
}));
|
|
2272
|
+
return true;
|
|
2273
|
+
}
|
|
2274
|
+
|
|
2275
|
+
// Public-edge building blocks for Open Apps that run their own pre-auth edge and mint
|
|
2276
|
+
// scope-limited guest sessions (e.g. a ballot edge: verify a credential, then mint a short-lived
|
|
2277
|
+
// session scoped to one resource). They are the same pieces WidgetSessionService uses; a generic
|
|
2278
|
+
// public-widget session mint remains the long-term replacement.
|
|
2279
|
+
export { BuildSessionClaims, MagicLinkKeyManager, MagicLinkService, HashToken, GenerateRawToken } from './auth/magicLink/index.js';
|
|
2280
|
+
export type { MagicLinkJWTClaims } from './auth/magicLink/index.js';
|
|
2281
|
+
export { VerifyHostAssertion } from './realtimeWidget/host-identity.js';
|
|
2282
|
+
export type { HostAssertedIdentity, HostAssertionResult } from './realtimeWidget/host-identity.js';
|
|
2283
|
+
export { IsScopeLimitedPrincipal } from './auth/scopeLimitedPrincipal.js';
|