@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
|
@@ -300,7 +300,12 @@ export class IntegrationCustomColumnPromoter {
|
|
|
300
300
|
// step with the database.
|
|
301
301
|
let batchResults: RSUPipelineResult[] = [];
|
|
302
302
|
if (batchInputs.length > 0) {
|
|
303
|
-
|
|
303
|
+
// Retrying variant. This runs UNATTENDED, mid-sync, with no operator watching: a
|
|
304
|
+
// transient ExecuteMigration / RunCodeGen / CompileTypeScript / RestartMJAPI failure
|
|
305
|
+
// drops the whole promotion, and the columns simply stay in overflow until something
|
|
306
|
+
// triggers a promotion again. The wrapper replays only those four steps and only while
|
|
307
|
+
// nothing in the batch was applied, so a partially-applied batch is still returned as-is.
|
|
308
|
+
const batch = await RuntimeSchemaManager.Instance.RunPipelineBatchWithRetry(batchInputs);
|
|
304
309
|
batchResults = batch.Results ?? [];
|
|
305
310
|
// M3: make the freshly-created EntityFields + regenerated sprocs visible in-process
|
|
306
311
|
// ONCE for the whole batch. CRITICAL: the spread below builds sproc calls from this
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { MiddlewareFn } from 'type-graphql';
|
|
1
|
+
import type { MiddlewareFn, ResolverData } from 'type-graphql';
|
|
2
2
|
import { getMetadataStorage } from 'type-graphql';
|
|
3
|
-
import { getNamedType } from 'graphql';
|
|
4
|
-
import type { GraphQLArgument } from 'graphql';
|
|
3
|
+
import { defaultFieldResolver, getNamedType } from 'graphql';
|
|
4
|
+
import type { GraphQLArgument, GraphQLField, GraphQLObjectType, GraphQLSchema } from 'graphql';
|
|
5
5
|
import { configInfo } from '../config.js';
|
|
6
6
|
import type { AppContext } from '../types.js';
|
|
7
7
|
import { RedactArg } from './secretRedactor.js';
|
|
@@ -191,6 +191,62 @@ export const VariablesLoggingMiddleware: MiddlewareFn<AppContext> = async (actio
|
|
|
191
191
|
/** @deprecated Use {@link VariablesLoggingMiddleware}. */
|
|
192
192
|
export const variablesLoggingMiddleware: MiddlewareFn<AppContext> = VariablesLoggingMiddleware;
|
|
193
193
|
|
|
194
|
+
/**
|
|
195
|
+
* Attaches {@link VariablesLoggingMiddleware} ONLY to root `Query`, `Mutation`, and `Subscription`
|
|
196
|
+
* fields on the compiled GraphQLSchema instead of registering it via TypeGraphQL `globalMiddlewares`.
|
|
197
|
+
*
|
|
198
|
+
* Registering a global middleware in TypeGraphQL wraps every scalar and child field resolver across
|
|
199
|
+
* all 300+ `@ObjectType` entities in an async middleware chain, allocating $O(\text{Rows} \times \text{Fields})$
|
|
200
|
+
* Promises per query even when `logVariables` is false or `info.path.prev !== undefined`.
|
|
201
|
+
* Wrapping only the root operation fields reduces middleware invocations from ~15,000 per 500-row
|
|
202
|
+
* `RunView` response down to 1.
|
|
203
|
+
*/
|
|
204
|
+
export function ApplyRootVariablesLoggingMiddleware(
|
|
205
|
+
schema: GraphQLSchema,
|
|
206
|
+
middleware: MiddlewareFn<AppContext> = VariablesLoggingMiddleware
|
|
207
|
+
): GraphQLSchema {
|
|
208
|
+
const rootTypes: Array<GraphQLObjectType | null | undefined> = [
|
|
209
|
+
schema.getQueryType(),
|
|
210
|
+
schema.getMutationType(),
|
|
211
|
+
schema.getSubscriptionType(),
|
|
212
|
+
];
|
|
213
|
+
|
|
214
|
+
for (const rootType of rootTypes) {
|
|
215
|
+
if (!rootType) continue;
|
|
216
|
+
const fields = rootType.getFields();
|
|
217
|
+
for (const field of Object.values(fields) as Array<GraphQLField<unknown, AppContext>>) {
|
|
218
|
+
if (field.resolve) {
|
|
219
|
+
const originalResolve = field.resolve;
|
|
220
|
+
field.resolve = (root, args, context, info) => {
|
|
221
|
+
const action: ResolverData<AppContext> = {
|
|
222
|
+
root,
|
|
223
|
+
args: args as Record<string, unknown>,
|
|
224
|
+
context,
|
|
225
|
+
info,
|
|
226
|
+
};
|
|
227
|
+
return middleware(action, async () => originalResolve(root, args, context, info));
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
if (field.subscribe) {
|
|
231
|
+
const originalSubscribe = field.subscribe;
|
|
232
|
+
field.subscribe = (root, args, context, info) => {
|
|
233
|
+
const action: ResolverData<AppContext> = {
|
|
234
|
+
root,
|
|
235
|
+
args: args as Record<string, unknown>,
|
|
236
|
+
context,
|
|
237
|
+
info,
|
|
238
|
+
};
|
|
239
|
+
return middleware(action, async () =>
|
|
240
|
+
originalSubscribe ? originalSubscribe(root, args, context, info) : defaultFieldResolver(root, args, context, info)
|
|
241
|
+
);
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
return schema;
|
|
248
|
+
}
|
|
249
|
+
|
|
194
250
|
/**
|
|
195
251
|
* Heuristic: an arg is "custom" (i.e. needs `@NoLog` discipline because metadata can't redact it)
|
|
196
252
|
* when its GraphQL input type is not a known `Create<X>Input` / `Update<X>Input` for an entity
|
|
@@ -9,7 +9,9 @@
|
|
|
9
9
|
|
|
10
10
|
import type { RequestHandler } from 'express';
|
|
11
11
|
import type { PreRunViewHook, PreSaveHook } from '@memberjunction/core';
|
|
12
|
-
import { Metadata, type UserInfo, type TenantContext } from '@memberjunction/core';
|
|
12
|
+
import { DatabaseProviderBase, Metadata, type UserInfo, type TenantContext } from '@memberjunction/core';
|
|
13
|
+
import { PostgreSQLDialect, SQLServerDialect, type SQLParserDialect } from '@memberjunction/sql-dialect';
|
|
14
|
+
import { IsBalancedSQLFragment } from '@memberjunction/sql-parser';
|
|
13
15
|
import type { MultiTenancyConfig } from '../config.js';
|
|
14
16
|
import type { UserPayload } from '../types.js';
|
|
15
17
|
import { CloneUserForSessionContext } from '../auth/sessionUserClone.js';
|
|
@@ -161,6 +163,25 @@ function isAdminUser(user: UserInfo, adminRoles: string[]): boolean {
|
|
|
161
163
|
);
|
|
162
164
|
}
|
|
163
165
|
|
|
166
|
+
/** Dialects to read an ExtraFilter with when the active provider's dialect cannot be resolved. */
|
|
167
|
+
const ALL_FILTER_DIALECTS: SQLParserDialect[] = [new SQLServerDialect(), new PostgreSQLDialect()];
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Throws unless the caller's ExtraFilter stays inside the parentheses the tenant predicate is
|
|
171
|
+
* ANDed after. A filter such as `1=1) OR (1=1` would close them early and leave the tenant
|
|
172
|
+
* predicate on one side of an OR the caller controls.
|
|
173
|
+
*/
|
|
174
|
+
function assertExtraFilterBalanced(extraFilter: string): void {
|
|
175
|
+
const provider = Metadata.Provider; // global-provider-ok: same rationale as isEntityScoped above — hooks carry no per-request provider
|
|
176
|
+
const dialects = provider instanceof DatabaseProviderBase ? [provider.Dialect] : ALL_FILTER_DIALECTS;
|
|
177
|
+
for (const dialect of dialects) {
|
|
178
|
+
const check = IsBalancedSQLFragment(extraFilter, dialect);
|
|
179
|
+
if (!check.IsBalanced) {
|
|
180
|
+
throw new Error(`[MultiTenancy] Invalid ExtraFilter: ${check.Reason}`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
164
185
|
/**
|
|
165
186
|
* Creates a PreRunViewHook that auto-injects tenant WHERE clauses
|
|
166
187
|
* into RunView queries for scoped entities.
|
|
@@ -206,7 +227,8 @@ export function CreateTenantPreRunViewHook(config: MultiTenancyConfig): PreRunVi
|
|
|
206
227
|
|
|
207
228
|
// Inject the tenant filter
|
|
208
229
|
if (params.ExtraFilter && typeof params.ExtraFilter === 'string' && params.ExtraFilter.trim().length > 0) {
|
|
209
|
-
|
|
230
|
+
assertExtraFilterBalanced(params.ExtraFilter);
|
|
231
|
+
params.ExtraFilter = `(${params.ExtraFilter}) AND (${tenantFilter})`;
|
|
210
232
|
} else {
|
|
211
233
|
params.ExtraFilter = tenantFilter;
|
|
212
234
|
}
|
|
@@ -64,9 +64,13 @@ The principal comes from the **server-authenticated** context (`userPayload.user
|
|
|
64
64
|
argument. An id argument only selects *which of the caller's own sessions*.
|
|
65
65
|
|
|
66
66
|
A caller may use a session when `AIAgentSession.UserID` equals their user (`UUIDsEqual`). Widget guests all
|
|
67
|
-
share one Anonymous user, so for an anonymous/magic-link principal that is **not enough**: the
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
share one Anonymous user, so for an anonymous/magic-link principal that is **not enough**: the session's
|
|
68
|
+
conversation `ExternalID` must equal the principal's scope identity (`ResolveSessionScopeIdentity`): the
|
|
69
|
+
signed `MagicLinkScope.ResourceID` when the token carries one, else the anonymous visitor's `mj_sid`.
|
|
70
|
+
`SessionManager` stamps that same value when it creates the conversation. An anonymous principal with
|
|
71
|
+
neither is refused outright. A *named* user with a resource scope must match too, which keeps one person's
|
|
72
|
+
different links apart; but it may also use its own session on a conversation that carries no stamp (one
|
|
73
|
+
started from the Conversations app) when its own row-level security let it read that conversation.
|
|
70
74
|
|
|
71
75
|
- Refusals are uniform ("session not found") whether the session is missing or simply not yours, so ids
|
|
72
76
|
cannot be probed.
|
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
type VerificationOperationResult,
|
|
31
31
|
type VerificationSettings,
|
|
32
32
|
} from './verificationWorkflow.js';
|
|
33
|
+
import { ConfiguredPublicUrl } from '../apiRoot.js';
|
|
33
34
|
|
|
34
35
|
/** Purpose label for principal-resolution diagnostics. */
|
|
35
36
|
const PRINCIPAL_PURPOSE = 'RealtimeVerification';
|
|
@@ -37,7 +38,7 @@ const PRINCIPAL_PURPOSE = 'RealtimeVerification';
|
|
|
37
38
|
/** The base URL emailed links are built from: explicit setting, else the server's public URL (same derivation magic links use). */
|
|
38
39
|
function resolvePublicBaseUrl(explicit: string | undefined): string | undefined {
|
|
39
40
|
const candidate =
|
|
40
|
-
explicit?.trim() ||
|
|
41
|
+
explicit?.trim() || ConfiguredPublicUrl();
|
|
41
42
|
return candidate ? TrimTrailingSlashes(candidate) : undefined;
|
|
42
43
|
}
|
|
43
44
|
|
|
@@ -31,6 +31,7 @@ import { LogError } from '@memberjunction/core';
|
|
|
31
31
|
import { configInfo } from '../config.js';
|
|
32
32
|
import { RealtimeSessionVerificationService } from './RealtimeSessionVerificationService.js';
|
|
33
33
|
import { BuildVerifyConfirmHtml, BuildVerifyErrorHtml, BuildVerifyFailureHtml, BuildVerifySuccessHtml } from './verificationPages.js';
|
|
34
|
+
import { ApiRoute } from '../apiRoot.js';
|
|
34
35
|
|
|
35
36
|
/** Mount path of the public verify routes. Under `/realtime`, which is already reserved against server extensions. */
|
|
36
37
|
export const REALTIME_VERIFY_MOUNT_PATH = '/realtime/verify';
|
|
@@ -79,7 +80,7 @@ export function CreateRealtimeVerifyRouter(
|
|
|
79
80
|
// SAFE: renders the confirmation button. Never consumes the token (see the module header).
|
|
80
81
|
router.get('/:token', limiter, (req: Request, res: Response) => {
|
|
81
82
|
const token = typeof req.params.token === 'string' ? req.params.token : '';
|
|
82
|
-
sendPage(res, 200, BuildVerifyConfirmHtml(token, REALTIME_VERIFY_MOUNT_PATH));
|
|
83
|
+
sendPage(res, 200, BuildVerifyConfirmHtml(token, ApiRoute(REALTIME_VERIFY_MOUNT_PATH)));
|
|
83
84
|
});
|
|
84
85
|
|
|
85
86
|
// The side-effecting redemption, gated by a human gesture.
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Per-session timers that assemble a client-direct realtime recording from its shard ledger
|
|
3
|
+
* off the request path.
|
|
4
|
+
*
|
|
5
|
+
* The recording REST routes only record shards and the terminal signal; they never decode. When a route
|
|
6
|
+
* learns a session is ready (every expected shard present) it asks for an assembly now; when shards are
|
|
7
|
+
* missing it asks for one after the grace period, forced to `Partial`. This scheduler turns those requests
|
|
8
|
+
* into at most one pending timer and at most one running assembly per session in this process.
|
|
9
|
+
*
|
|
10
|
+
* Correctness across processes does not depend on it: every run starts with the ledger's atomic
|
|
11
|
+
* `ClaimAssembly`, so of two instances (or two timers) only the claim winner assembles. The per-session
|
|
12
|
+
* guard here only avoids wasted claims. A run that dies with the process leaves the session `Assembling`,
|
|
13
|
+
* and the session janitor's stale re-claim is the backstop for that and for any request dropped here.
|
|
14
|
+
*
|
|
15
|
+
* @module @memberjunction/server/realtimeSessions
|
|
16
|
+
*/
|
|
17
|
+
import { DatabaseProviderBase, LogError, LogStatus, UserInfo } from '@memberjunction/core';
|
|
18
|
+
import { BaseSingleton, IShutdownable, ShutdownRegistry } from '@memberjunction/global';
|
|
19
|
+
import {
|
|
20
|
+
AssembleRealtimeRecordingFromLedger, AssembleRealtimeRecordingInput, AssembleRealtimeRecordingOutcome,
|
|
21
|
+
IRealtimeRecordingLedger, SqlRealtimeRecordingLedger,
|
|
22
|
+
} from '@memberjunction/ai-agents';
|
|
23
|
+
|
|
24
|
+
/** A cancellable one-shot timer. */
|
|
25
|
+
export interface RecordingAssemblyTimer {
|
|
26
|
+
Cancel(): void;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Time source of the scheduler; injectable so tests can drive it. */
|
|
30
|
+
export interface RecordingAssemblyClock {
|
|
31
|
+
/** Milliseconds since the epoch. */
|
|
32
|
+
Now(): number;
|
|
33
|
+
/** Runs `callback` once after `delayMs`. The timer must not keep the process alive. */
|
|
34
|
+
StartTimer(callback: () => void, delayMs: number): RecordingAssemblyTimer;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** The narrow scheduling contract the recording routes depend on. */
|
|
38
|
+
export interface IRecordingAssemblyScheduler {
|
|
39
|
+
/**
|
|
40
|
+
* Requests an assembly of `sessionID` after `delayMs`. `forcePartial` assembles what exists even when
|
|
41
|
+
* shards are missing (the grace period ran out). See {@link RecordingAssemblyScheduler.ScheduleAssembly}.
|
|
42
|
+
*/
|
|
43
|
+
ScheduleAssembly(sessionID: string, delayMs: number, forcePartial: boolean): void;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** What {@link RecordingAssemblyScheduler.Start} needs. */
|
|
47
|
+
export interface RecordingAssemblySchedulerOptions {
|
|
48
|
+
/** The server's own provider; assembly is server-owned background work, not a request. */
|
|
49
|
+
Provider: DatabaseProviderBase;
|
|
50
|
+
/** The user assembly runs as (the system user). */
|
|
51
|
+
SystemUser: UserInfo;
|
|
52
|
+
/** Grace before a `Deferred` (incomplete) assembly is retried as forced `Partial`. */
|
|
53
|
+
GraceMs: () => number;
|
|
54
|
+
/** Defaults to {@link SqlRealtimeRecordingLedger}. */
|
|
55
|
+
CreateLedger?: (provider: DatabaseProviderBase, contextUser: UserInfo) => IRealtimeRecordingLedger;
|
|
56
|
+
/** Defaults to {@link AssembleRealtimeRecordingFromLedger}. */
|
|
57
|
+
Assemble?: (input: AssembleRealtimeRecordingInput) => Promise<AssembleRealtimeRecordingOutcome>;
|
|
58
|
+
/** Defaults to `Date.now` and unref'd `setTimeout`. */
|
|
59
|
+
Clock?: RecordingAssemblyClock;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
interface PendingAssembly {
|
|
63
|
+
DueAt: number;
|
|
64
|
+
ForcePartial: boolean;
|
|
65
|
+
Timer: RecordingAssemblyTimer;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const NODE_CLOCK: RecordingAssemblyClock = {
|
|
69
|
+
Now: () => Date.now(),
|
|
70
|
+
StartTimer: (callback, delayMs) => {
|
|
71
|
+
const handle = setTimeout(callback, delayMs);
|
|
72
|
+
handle.unref?.();
|
|
73
|
+
return { Cancel: () => clearTimeout(handle) };
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Process-wide scheduler of recording assemblies (see the file overview). Call {@link Start} once at
|
|
79
|
+
* server startup; requests made before it (or after {@link Shutdown}) are logged and dropped, leaving the
|
|
80
|
+
* session to the janitor.
|
|
81
|
+
*/
|
|
82
|
+
export class RecordingAssemblyScheduler extends BaseSingleton<RecordingAssemblyScheduler> implements IShutdownable, IRecordingAssemblyScheduler {
|
|
83
|
+
private _options: Required<RecordingAssemblySchedulerOptions> | null = null;
|
|
84
|
+
private _registered = false;
|
|
85
|
+
/** Pending timers keyed by lowercase session id. */
|
|
86
|
+
private readonly pending = new Map<string, PendingAssembly>();
|
|
87
|
+
/** Lowercase ids of sessions with an assembly running in this process. */
|
|
88
|
+
private readonly running = new Set<string>();
|
|
89
|
+
/** Sessions asked for again while running, with the ForcePartial to re-run with. */
|
|
90
|
+
private readonly rerun = new Map<string, boolean>();
|
|
91
|
+
|
|
92
|
+
protected constructor() {
|
|
93
|
+
super();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** Process-wide singleton accessor. */
|
|
97
|
+
public static get Instance(): RecordingAssemblyScheduler {
|
|
98
|
+
return super.getInstance<RecordingAssemblyScheduler>();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** Identifier surfaced in graceful-shutdown logs. */
|
|
102
|
+
public readonly ShutdownName = 'RecordingAssemblyScheduler';
|
|
103
|
+
|
|
104
|
+
/** Configures the scheduler and enables it; calling again replaces the configuration. */
|
|
105
|
+
public Start(options: RecordingAssemblySchedulerOptions): void {
|
|
106
|
+
this._options = {
|
|
107
|
+
CreateLedger: (provider, contextUser) => new SqlRealtimeRecordingLedger(provider, contextUser),
|
|
108
|
+
Assemble: AssembleRealtimeRecordingFromLedger,
|
|
109
|
+
Clock: NODE_CLOCK,
|
|
110
|
+
...options,
|
|
111
|
+
};
|
|
112
|
+
if (!this._registered) {
|
|
113
|
+
ShutdownRegistry.Instance.Register(this);
|
|
114
|
+
this._registered = true;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Requests an assembly of `sessionID` after `delayMs`. One pending timer per session: a request
|
|
120
|
+
* replaces the pending one only when it would fire sooner (at the same time, the merged request keeps
|
|
121
|
+
* `forcePartial` if either had it). A timer that fires while the session's previous run is still going
|
|
122
|
+
* is remembered and run right after it, never alongside it.
|
|
123
|
+
*
|
|
124
|
+
* Trade-off: a sooner un-forced request replaces a pending forced one. If that run comes back
|
|
125
|
+
* `Deferred` (still incomplete), the forced `Partial` is re-scheduled a full grace from then, so a
|
|
126
|
+
* forced Partial can land up to ~2× the grace after the first terminal signal. Accepted: the sooner
|
|
127
|
+
* run completes the recording outright whenever the missing shards did arrive.
|
|
128
|
+
*/
|
|
129
|
+
public ScheduleAssembly(sessionID: string, delayMs: number, forcePartial: boolean): void {
|
|
130
|
+
const options = this._options;
|
|
131
|
+
if (!options) {
|
|
132
|
+
LogError(`RecordingAssemblyScheduler: not running; dropped the assembly request for session ${sessionID} (the session janitor will assemble it)`);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const key = sessionID.toLowerCase();
|
|
136
|
+
const dueAt = options.Clock.Now() + Math.max(0, delayMs);
|
|
137
|
+
const existing = this.pending.get(key);
|
|
138
|
+
if (existing && existing.DueAt < dueAt) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
if (existing && existing.DueAt === dueAt) {
|
|
142
|
+
existing.ForcePartial = existing.ForcePartial || forcePartial;
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
existing?.Timer.Cancel();
|
|
146
|
+
const timer = options.Clock.StartTimer(() => this.onTimer(key, sessionID), dueAt - options.Clock.Now());
|
|
147
|
+
this.pending.set(key, { DueAt: dueAt, ForcePartial: forcePartial, Timer: timer });
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Cancels every pending timer and stops accepting requests until the next {@link Start}. A running
|
|
152
|
+
* assembly is not awaited: if the process exits under it, the session stays `Assembling` and the
|
|
153
|
+
* janitor's stale re-claim finishes it. Idempotent.
|
|
154
|
+
*/
|
|
155
|
+
public Shutdown(): void {
|
|
156
|
+
for (const entry of this.pending.values()) {
|
|
157
|
+
entry.Timer.Cancel();
|
|
158
|
+
}
|
|
159
|
+
this.pending.clear();
|
|
160
|
+
this.rerun.clear();
|
|
161
|
+
this._options = null;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
private onTimer(key: string, sessionID: string): void {
|
|
165
|
+
const entry = this.pending.get(key);
|
|
166
|
+
if (!entry) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
this.pending.delete(key);
|
|
170
|
+
if (this.running.has(key)) {
|
|
171
|
+
this.rerun.set(key, (this.rerun.get(key) ?? false) || entry.ForcePartial);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
void this.runUntilSettled(key, sessionID, entry.ForcePartial);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/** Runs the session's assembly, then any re-run requested meanwhile. Never rejects. */
|
|
178
|
+
private async runUntilSettled(key: string, sessionID: string, forcePartial: boolean): Promise<void> {
|
|
179
|
+
this.running.add(key);
|
|
180
|
+
try {
|
|
181
|
+
let next: boolean | undefined = forcePartial;
|
|
182
|
+
while (next !== undefined) {
|
|
183
|
+
await this.runOnce(sessionID, next);
|
|
184
|
+
next = this.rerun.get(key);
|
|
185
|
+
this.rerun.delete(key);
|
|
186
|
+
}
|
|
187
|
+
} finally {
|
|
188
|
+
this.running.delete(key);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/** One claim + assembly. Logs every failure with the session id; never throws. */
|
|
193
|
+
private async runOnce(sessionID: string, forcePartial: boolean): Promise<void> {
|
|
194
|
+
const options = this._options;
|
|
195
|
+
if (!options) {
|
|
196
|
+
LogStatus(`RecordingAssemblyScheduler: shut down before session ${sessionID} could assemble; the session janitor will assemble it`);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
try {
|
|
200
|
+
const ledger = options.CreateLedger(options.Provider, options.SystemUser);
|
|
201
|
+
const version = await ledger.ClaimAssembly(sessionID, null);
|
|
202
|
+
if (version === null) {
|
|
203
|
+
LogStatus(`RecordingAssemblyScheduler: session ${sessionID} not claimable (assembled, assembling elsewhere, or failed); skipping`);
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
const outcome = await options.Assemble({
|
|
207
|
+
SessionID: sessionID, Version: version, Ledger: ledger,
|
|
208
|
+
ContextUser: options.SystemUser, Provider: options.Provider, ForcePartial: forcePartial,
|
|
209
|
+
});
|
|
210
|
+
this.handleOutcome(sessionID, version, outcome, options);
|
|
211
|
+
} catch (error) {
|
|
212
|
+
LogError(`RecordingAssemblyScheduler: assembly of session ${sessionID} failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
private handleOutcome(
|
|
217
|
+
sessionID: string,
|
|
218
|
+
version: number,
|
|
219
|
+
outcome: AssembleRealtimeRecordingOutcome,
|
|
220
|
+
options: Required<RecordingAssemblySchedulerOptions>,
|
|
221
|
+
): void {
|
|
222
|
+
if (outcome === 'Deferred') {
|
|
223
|
+
// Incomplete and not forced: give missing shards the grace period, then assemble what exists.
|
|
224
|
+
LogStatus(`RecordingAssemblyScheduler: session ${sessionID} (version ${version}) is missing shards; assembling as Partial after the grace period`);
|
|
225
|
+
this.ScheduleAssembly(sessionID, options.GraceMs(), true);
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
if (outcome === 'Retry') {
|
|
229
|
+
LogError(`RecordingAssemblyScheduler: assembly of session ${sessionID} (version ${version}) hit a transient error; the session janitor re-claims it later`);
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
LogStatus(`RecordingAssemblyScheduler: session ${sessionID} (version ${version}) assembly finished: ${outcome}`);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
@@ -54,6 +54,7 @@ function toSnapshot(loaded: LoadedSessionForAccess): SessionSnapshot {
|
|
|
54
54
|
AgentSessionID: Session.ID,
|
|
55
55
|
OwnerUserID: Session.UserID,
|
|
56
56
|
ConversationExternalID: loaded.ConversationExternalID,
|
|
57
|
+
ConversationReadable: loaded.ConversationReadable,
|
|
57
58
|
Status: Session.Status,
|
|
58
59
|
ConfigRaw: Session.Config_,
|
|
59
60
|
// `__mj_CreatedAt` is the row's creation instant — i.e. the session start. It is read-only and
|
|
@@ -14,3 +14,5 @@ export * from './sessionConfigStamps.js';
|
|
|
14
14
|
export * from './SessionVerificationPortsBase.js';
|
|
15
15
|
export * from './RealtimeSessionVerificationService.js';
|
|
16
16
|
export * from './RealtimeVerifyRouter.js';
|
|
17
|
+
export * from './ownedRealtimeSession.js';
|
|
18
|
+
export * from './RecordingAssemblyScheduler.js';
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview The ownership gate for client-direct realtime session writes: the GraphQL mutations of
|
|
3
|
+
* `RealtimeClientSessionResolver` and the recording REST routes both load the session through
|
|
4
|
+
* {@link LoadOwnedRealtimeSession}, so "may this caller write to this session?" is decided in one place.
|
|
5
|
+
*
|
|
6
|
+
* @module @memberjunction/server/realtimeSessions
|
|
7
|
+
*/
|
|
8
|
+
import { IMetadataProvider, LogError, UserInfo } from '@memberjunction/core';
|
|
9
|
+
import { UUIDsEqual } from '@memberjunction/global';
|
|
10
|
+
import type { MJAIAgentSessionEntity } from '@memberjunction/core-entities';
|
|
11
|
+
import { AuthorizeSessionAccess, LoadSessionConversationScope } from './sessionAccess.js';
|
|
12
|
+
|
|
13
|
+
const SESSION_ENTITY = 'MJ: AI Agent Sessions';
|
|
14
|
+
|
|
15
|
+
/** The session does not exist, or the caller cannot read it. */
|
|
16
|
+
export class RealtimeSessionNotFoundError extends Error {
|
|
17
|
+
constructor(public readonly AgentSessionID: string) {
|
|
18
|
+
super(`Realtime session ${AgentSessionID} not found`);
|
|
19
|
+
this.name = 'RealtimeSessionNotFoundError';
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** The session exists but the caller may not use it: another user owns it, or (for a scoped or anonymous caller) its conversation carries another scope identity. */
|
|
24
|
+
export class RealtimeSessionOwnershipError extends Error {
|
|
25
|
+
constructor(public readonly AgentSessionID: string) {
|
|
26
|
+
super('Not authorized: you do not own this realtime session');
|
|
27
|
+
this.name = 'RealtimeSessionOwnershipError';
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Loads a session under the caller's identity and enforces ownership: `UserID === contextUser.ID`, then the
|
|
33
|
+
* scope rule of {@link AuthorizeSessionAccess} (every anonymous visitor shares one Anonymous user, so the
|
|
34
|
+
* session's conversation `ExternalID` must equal the caller's scope identity). It deliberately does NOT
|
|
35
|
+
* reject `Closed` sessions: the final channel-state flush and the recording terminal signal legitimately
|
|
36
|
+
* arrive after the session closed. Loading as the caller also applies the entity's row-level security.
|
|
37
|
+
*
|
|
38
|
+
* @throws RealtimeSessionNotFoundError when the row does not load
|
|
39
|
+
* @throws RealtimeSessionOwnershipError when another user owns the session (logged with both user ids) or
|
|
40
|
+
* the scope rule refuses the caller (logged with the refusal reason)
|
|
41
|
+
*/
|
|
42
|
+
export async function LoadOwnedRealtimeSession(
|
|
43
|
+
agentSessionId: string,
|
|
44
|
+
contextUser: UserInfo,
|
|
45
|
+
provider: IMetadataProvider,
|
|
46
|
+
): Promise<MJAIAgentSessionEntity> {
|
|
47
|
+
const session = await provider.GetEntityObject<MJAIAgentSessionEntity>(SESSION_ENTITY, contextUser);
|
|
48
|
+
if (!(await session.Load(agentSessionId))) {
|
|
49
|
+
throw new RealtimeSessionNotFoundError(agentSessionId);
|
|
50
|
+
}
|
|
51
|
+
if (!UUIDsEqual(session.UserID, contextUser.ID)) {
|
|
52
|
+
LogError(
|
|
53
|
+
`LoadOwnedRealtimeSession: ownership check failed — user ${contextUser.ID} attempted to operate on session ${agentSessionId} owned by ${session.UserID}`,
|
|
54
|
+
);
|
|
55
|
+
throw new RealtimeSessionOwnershipError(agentSessionId);
|
|
56
|
+
}
|
|
57
|
+
const conversation = await LoadSessionConversationScope(session, contextUser, provider);
|
|
58
|
+
const access = AuthorizeSessionAccess(
|
|
59
|
+
{ SessionUserID: session.UserID, ConversationExternalID: conversation.ExternalID, ConversationReadable: conversation.Readable },
|
|
60
|
+
contextUser,
|
|
61
|
+
);
|
|
62
|
+
if (!access.Allowed) {
|
|
63
|
+
LogError(
|
|
64
|
+
`LoadOwnedRealtimeSession: session access refused (${access.Reason}) — user ${contextUser.ID} attempted to operate on session ${agentSessionId}`,
|
|
65
|
+
);
|
|
66
|
+
throw new RealtimeSessionOwnershipError(agentSessionId);
|
|
67
|
+
}
|
|
68
|
+
return session;
|
|
69
|
+
}
|