@memberjunction/server 6.2.0-edge.3 → 6.2.0-edge.5
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 +20 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/agentSessions/BridgeHostInstance.d.ts +25 -0
- package/dist/agentSessions/BridgeHostInstance.d.ts.map +1 -0
- package/dist/agentSessions/BridgeHostInstance.js +30 -0
- package/dist/agentSessions/BridgeHostInstance.js.map +1 -0
- package/dist/agentSessions/HostInstance.d.ts +75 -11
- package/dist/agentSessions/HostInstance.d.ts.map +1 -1
- package/dist/agentSessions/HostInstance.js +99 -28
- package/dist/agentSessions/HostInstance.js.map +1 -1
- package/dist/agentSessions/ReturningVisitorRecap.d.ts.map +1 -1
- package/dist/agentSessions/ReturningVisitorRecap.js +7 -3
- package/dist/agentSessions/ReturningVisitorRecap.js.map +1 -1
- package/dist/agentSessions/SessionJanitor.d.ts +236 -27
- package/dist/agentSessions/SessionJanitor.d.ts.map +1 -1
- package/dist/agentSessions/SessionJanitor.js +682 -54
- package/dist/agentSessions/SessionJanitor.js.map +1 -1
- package/dist/agentSessions/SessionManager.d.ts +48 -3
- package/dist/agentSessions/SessionManager.d.ts.map +1 -1
- package/dist/agentSessions/SessionManager.js +112 -9
- package/dist/agentSessions/SessionManager.js.map +1 -1
- package/dist/agentSessions/SessionRunIDVerifier.d.ts +63 -0
- package/dist/agentSessions/SessionRunIDVerifier.d.ts.map +1 -0
- package/dist/agentSessions/SessionRunIDVerifier.js +129 -0
- package/dist/agentSessions/SessionRunIDVerifier.js.map +1 -0
- package/dist/agentSessions/index.d.ts +2 -0
- package/dist/agentSessions/index.d.ts.map +1 -1
- package/dist/agentSessions/index.js +10 -3
- package/dist/agentSessions/index.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 +25 -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/actionAuthorization.d.ts +40 -0
- package/dist/auth/actionAuthorization.d.ts.map +1 -0
- package/dist/auth/actionAuthorization.js +94 -0
- package/dist/auth/actionAuthorization.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 +4 -10
- package/dist/auth/index.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/MagicLinkService.d.ts.map +1 -1
- package/dist/auth/magicLink/MagicLinkService.js +6 -3
- package/dist/auth/magicLink/MagicLinkService.js.map +1 -1
- package/dist/auth/newUsers.d.ts +10 -0
- package/dist/auth/newUsers.d.ts.map +1 -1
- package/dist/auth/newUsers.js +80 -11
- package/dist/auth/newUsers.js.map +1 -1
- package/dist/config.d.ts +2514 -22
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +166 -4
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +8 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +14 -11
- 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 +142 -0
- package/dist/coreRoutes.js.map +1 -0
- package/dist/generated/graphql-schemas/__mj.d.ts +504 -3
- package/dist/generated/graphql-schemas/__mj.d.ts.map +1 -1
- package/dist/generated/graphql-schemas/__mj.js +2456 -7
- package/dist/generated/graphql-schemas/__mj.js.map +1 -1
- package/dist/generic/CacheInvalidationResolver.d.ts +43 -8
- package/dist/generic/CacheInvalidationResolver.d.ts.map +1 -1
- package/dist/generic/CacheInvalidationResolver.js +59 -19
- package/dist/generic/CacheInvalidationResolver.js.map +1 -1
- package/dist/generic/OrphanedConversationDetailReconciler.js +3 -3
- package/dist/generic/OrphanedConversationDetailReconciler.js.map +1 -1
- package/dist/generic/PushStatusResolver.js +1 -1
- package/dist/generic/PushStatusResolver.js.map +1 -1
- package/dist/generic/ResolverBase.d.ts +123 -48
- package/dist/generic/ResolverBase.d.ts.map +1 -1
- package/dist/generic/ResolverBase.js +293 -305
- package/dist/generic/ResolverBase.js.map +1 -1
- package/dist/generic/RunViewResolver.d.ts.map +1 -1
- package/dist/generic/RunViewResolver.js +16 -0
- package/dist/generic/RunViewResolver.js.map +1 -1
- 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 +17 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +219 -278
- package/dist/index.js.map +1 -1
- package/dist/isolatedProvider.d.ts +20 -0
- package/dist/isolatedProvider.d.ts.map +1 -0
- package/dist/isolatedProvider.js +22 -0
- package/dist/isolatedProvider.js.map +1 -0
- 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/realtimeProxy/RealtimeProxyServer.d.ts +44 -4
- package/dist/realtimeProxy/RealtimeProxyServer.d.ts.map +1 -1
- package/dist/realtimeProxy/RealtimeProxyServer.js +121 -16
- package/dist/realtimeProxy/RealtimeProxyServer.js.map +1 -1
- package/dist/realtimeProxy/RealtimeRelayTunnel.d.ts +171 -0
- package/dist/realtimeProxy/RealtimeRelayTunnel.d.ts.map +1 -0
- package/dist/realtimeProxy/RealtimeRelayTunnel.js +532 -0
- package/dist/realtimeProxy/RealtimeRelayTunnel.js.map +1 -0
- package/dist/realtimeSessions/RealtimeSessionEventService.d.ts +148 -0
- package/dist/realtimeSessions/RealtimeSessionEventService.d.ts.map +1 -0
- package/dist/realtimeSessions/RealtimeSessionEventService.js +191 -0
- package/dist/realtimeSessions/RealtimeSessionEventService.js.map +1 -0
- package/dist/realtimeSessions/RealtimeSessionVerificationService.d.ts +66 -0
- package/dist/realtimeSessions/RealtimeSessionVerificationService.d.ts.map +1 -0
- package/dist/realtimeSessions/RealtimeSessionVerificationService.js +139 -0
- package/dist/realtimeSessions/RealtimeSessionVerificationService.js.map +1 -0
- package/dist/realtimeSessions/RealtimeVerifyRouter.d.ts +38 -0
- package/dist/realtimeSessions/RealtimeVerifyRouter.d.ts.map +1 -0
- package/dist/realtimeSessions/RealtimeVerifyRouter.js +99 -0
- package/dist/realtimeSessions/RealtimeVerifyRouter.js.map +1 -0
- 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 +61 -0
- package/dist/realtimeSessions/SessionVerificationPortsBase.d.ts.map +1 -0
- package/dist/realtimeSessions/SessionVerificationPortsBase.js +149 -0
- package/dist/realtimeSessions/SessionVerificationPortsBase.js.map +1 -0
- package/dist/realtimeSessions/SlidingWindowRateLimiter.d.ts +57 -0
- package/dist/realtimeSessions/SlidingWindowRateLimiter.d.ts.map +1 -0
- package/dist/realtimeSessions/SlidingWindowRateLimiter.js +69 -0
- package/dist/realtimeSessions/SlidingWindowRateLimiter.js.map +1 -0
- package/dist/realtimeSessions/index.d.ts +19 -0
- package/dist/realtimeSessions/index.d.ts.map +1 -0
- package/dist/realtimeSessions/index.js +19 -0
- package/dist/realtimeSessions/index.js.map +1 -0
- package/dist/realtimeSessions/ownedRealtimeSession.d.ts +30 -0
- package/dist/realtimeSessions/ownedRealtimeSession.d.ts.map +1 -0
- package/dist/realtimeSessions/ownedRealtimeSession.js +47 -0
- package/dist/realtimeSessions/ownedRealtimeSession.js.map +1 -0
- package/dist/realtimeSessions/sessionAccess.d.ts +92 -0
- package/dist/realtimeSessions/sessionAccess.d.ts.map +1 -0
- package/dist/realtimeSessions/sessionAccess.js +94 -0
- package/dist/realtimeSessions/sessionAccess.js.map +1 -0
- package/dist/realtimeSessions/sessionConfigStamps.d.ts +70 -0
- package/dist/realtimeSessions/sessionConfigStamps.d.ts.map +1 -0
- package/dist/realtimeSessions/sessionConfigStamps.js +93 -0
- package/dist/realtimeSessions/sessionConfigStamps.js.map +1 -0
- package/dist/realtimeSessions/subscriptionAuthorization.d.ts +65 -0
- package/dist/realtimeSessions/subscriptionAuthorization.d.ts.map +1 -0
- package/dist/realtimeSessions/subscriptionAuthorization.js +71 -0
- package/dist/realtimeSessions/subscriptionAuthorization.js.map +1 -0
- package/dist/realtimeSessions/verificationCore.d.ts +243 -0
- package/dist/realtimeSessions/verificationCore.d.ts.map +1 -0
- package/dist/realtimeSessions/verificationCore.js +356 -0
- package/dist/realtimeSessions/verificationCore.js.map +1 -0
- package/dist/realtimeSessions/verificationPages.d.ts +66 -0
- package/dist/realtimeSessions/verificationPages.d.ts.map +1 -0
- package/dist/realtimeSessions/verificationPages.js +110 -0
- package/dist/realtimeSessions/verificationPages.js.map +1 -0
- package/dist/realtimeSessions/verificationPolicy.d.ts +147 -0
- package/dist/realtimeSessions/verificationPolicy.d.ts.map +1 -0
- package/dist/realtimeSessions/verificationPolicy.js +249 -0
- package/dist/realtimeSessions/verificationPolicy.js.map +1 -0
- package/dist/realtimeSessions/verificationWorkflow.d.ts +263 -0
- package/dist/realtimeSessions/verificationWorkflow.d.ts.map +1 -0
- package/dist/realtimeSessions/verificationWorkflow.js +435 -0
- package/dist/realtimeSessions/verificationWorkflow.js.map +1 -0
- package/dist/realtimeWidget/widgetGuestElevation.d.ts +20 -2
- package/dist/realtimeWidget/widgetGuestElevation.d.ts.map +1 -1
- package/dist/realtimeWidget/widgetGuestElevation.js +31 -2
- package/dist/realtimeWidget/widgetGuestElevation.js.map +1 -1
- package/dist/resolvers/ActionResolver.d.ts +31 -5
- package/dist/resolvers/ActionResolver.d.ts.map +1 -1
- package/dist/resolvers/ActionResolver.js +75 -14
- package/dist/resolvers/ActionResolver.js.map +1 -1
- package/dist/resolvers/AdhocQueryResolver.d.ts +14 -1
- package/dist/resolvers/AdhocQueryResolver.d.ts.map +1 -1
- package/dist/resolvers/AdhocQueryResolver.js +21 -5
- package/dist/resolvers/AdhocQueryResolver.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/CacheStatsResolver.d.ts +27 -0
- package/dist/resolvers/CacheStatsResolver.d.ts.map +1 -1
- package/dist/resolvers/CacheStatsResolver.js +113 -2
- package/dist/resolvers/CacheStatsResolver.js.map +1 -1
- package/dist/resolvers/ClientToolRequestResolver.d.ts +4 -2
- package/dist/resolvers/ClientToolRequestResolver.d.ts.map +1 -1
- package/dist/resolvers/ClientToolRequestResolver.js +28 -10
- package/dist/resolvers/ClientToolRequestResolver.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/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 +27 -1
- package/dist/resolvers/FetchEntityVectorsResolver.d.ts.map +1 -1
- package/dist/resolvers/FetchEntityVectorsResolver.js +148 -2
- package/dist/resolvers/FetchEntityVectorsResolver.js.map +1 -1
- package/dist/resolvers/FileResolver.d.ts +82 -11
- package/dist/resolvers/FileResolver.d.ts.map +1 -1
- package/dist/resolvers/FileResolver.js +279 -101
- 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/HumanHandoffResolver.d.ts.map +1 -1
- package/dist/resolvers/HumanHandoffResolver.js +7 -1
- package/dist/resolvers/HumanHandoffResolver.js.map +1 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.d.ts.map +1 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.js +4 -2
- package/dist/resolvers/IntegrationDiscoveryResolver.js.map +1 -1
- package/dist/resolvers/MCPResolver.d.ts.map +1 -1
- package/dist/resolvers/MCPResolver.js +9 -4
- package/dist/resolvers/MCPResolver.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 +13 -0
- package/dist/resolvers/QueryResolver.js.map +1 -1
- package/dist/resolvers/RealtimeBridgeResolver.d.ts +54 -2
- package/dist/resolvers/RealtimeBridgeResolver.d.ts.map +1 -1
- package/dist/resolvers/RealtimeBridgeResolver.js +155 -10
- package/dist/resolvers/RealtimeBridgeResolver.js.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts +157 -33
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.js +404 -116
- package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
- package/dist/resolvers/RealtimeSessionEventsResolver.d.ts +61 -0
- package/dist/resolvers/RealtimeSessionEventsResolver.d.ts.map +1 -0
- package/dist/resolvers/RealtimeSessionEventsResolver.js +130 -0
- package/dist/resolvers/RealtimeSessionEventsResolver.js.map +1 -0
- package/dist/resolvers/RealtimeSessionVerificationResolver.d.ts +85 -0
- package/dist/resolvers/RealtimeSessionVerificationResolver.d.ts.map +1 -0
- package/dist/resolvers/RealtimeSessionVerificationResolver.js +188 -0
- package/dist/resolvers/RealtimeSessionVerificationResolver.js.map +1 -0
- package/dist/resolvers/RemoteBrowserActionResolver.d.ts +2 -0
- package/dist/resolvers/RemoteBrowserActionResolver.d.ts.map +1 -1
- package/dist/resolvers/RemoteBrowserActionResolver.js +5 -1
- package/dist/resolvers/RemoteBrowserActionResolver.js.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.d.ts +10 -0
- package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.js +100 -14
- package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
- package/dist/resolvers/RunTemplateResolver.d.ts.map +1 -1
- package/dist/resolvers/RunTemplateResolver.js +12 -11
- package/dist/resolvers/RunTemplateResolver.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 +6 -2
- package/dist/resolvers/SyncDataResolver.js.map +1 -1
- package/dist/resolvers/SyncRolesUsersResolver.d.ts +2 -0
- package/dist/resolvers/SyncRolesUsersResolver.d.ts.map +1 -1
- package/dist/resolvers/SyncRolesUsersResolver.js +23 -6
- package/dist/resolvers/SyncRolesUsersResolver.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 +65 -13
- package/dist/resolvers/TestQuerySQLResolver.js.map +1 -1
- package/dist/resolvers/TransactionGroupResolver.d.ts +19 -2
- package/dist/resolvers/TransactionGroupResolver.d.ts.map +1 -1
- package/dist/resolvers/TransactionGroupResolver.js +102 -24
- package/dist/resolvers/TransactionGroupResolver.js.map +1 -1
- package/dist/resolvers/UserAvatarResolver.d.ts +16 -0
- package/dist/resolvers/UserAvatarResolver.d.ts.map +1 -0
- package/dist/resolvers/UserAvatarResolver.js +124 -0
- package/dist/resolvers/UserAvatarResolver.js.map +1 -0
- package/dist/resolvers/UserResolver.d.ts.map +1 -1
- package/dist/resolvers/UserResolver.js +2 -17
- package/dist/resolvers/UserResolver.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/resolvers/agentVisionConsentAudit.d.ts +37 -0
- package/dist/resolvers/agentVisionConsentAudit.d.ts.map +1 -0
- package/dist/resolvers/agentVisionConsentAudit.js +63 -0
- package/dist/resolvers/agentVisionConsentAudit.js.map +1 -0
- package/dist/resolvers/avatarInputValidation.d.ts +40 -0
- package/dist/resolvers/avatarInputValidation.d.ts.map +1 -0
- package/dist/resolvers/avatarInputValidation.js +97 -0
- package/dist/resolvers/avatarInputValidation.js.map +1 -0
- package/dist/resolvers/currentUserRoles.d.ts +29 -0
- package/dist/resolvers/currentUserRoles.d.ts.map +1 -1
- package/dist/resolvers/currentUserRoles.js +30 -0
- package/dist/resolvers/currentUserRoles.js.map +1 -1
- package/dist/resolvers/meetings/meetingMutations.d.ts +6 -0
- package/dist/resolvers/meetings/meetingMutations.d.ts.map +1 -1
- package/dist/resolvers/meetings/meetingMutations.js +21 -0
- package/dist/resolvers/meetings/meetingMutations.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 +3 -1
- package/dist/rest/ViewOperationsHandler.d.ts.map +1 -1
- package/dist/rest/ViewOperationsHandler.js +21 -12
- 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/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 +57 -4
- package/dist/services/TaskGraphContinuationDeliverer.d.ts.map +1 -1
- package/dist/services/TaskGraphContinuationDeliverer.js +607 -18
- package/dist/services/TaskGraphContinuationDeliverer.js.map +1 -1
- package/dist/sharedCache.d.ts +105 -0
- package/dist/sharedCache.d.ts.map +1 -0
- package/dist/sharedCache.js +279 -0
- package/dist/sharedCache.js.map +1 -0
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +99 -96
- package/src/__tests__/ActionResolver.authorization.test.ts +353 -0
- package/src/__tests__/AdhocQueryResolver.sqlAuthorizer.test.ts +104 -0
- package/src/__tests__/BridgeHostInstance.test.ts +232 -0
- package/src/__tests__/ClientToolRequestResolver.test.ts +116 -0
- package/src/__tests__/DatasetResolver.itemFilters.test.ts +201 -0
- package/src/__tests__/EntityRecordNameResolver.rowSecurity.test.ts +152 -0
- package/src/__tests__/FetchEntityVectorsResolver.test.ts +433 -0
- package/src/__tests__/FileResolver.storageAccess.test.ts +562 -0
- package/src/__tests__/GetDataContextDataResolver.sqlItems.test.ts +416 -0
- package/src/__tests__/HostInstance.test.ts +84 -0
- package/src/__tests__/HumanHandoffResolver.test.ts +17 -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__/MeetingResolver.test.ts +75 -1
- package/src/__tests__/RealtimeBridgeResolver.test.ts +415 -6
- package/src/__tests__/RealtimeClientSessionResolver.configTamper.test.ts +383 -0
- package/src/__tests__/RealtimeClientSessionResolver.test.ts +682 -58
- package/src/__tests__/RealtimeProxyServer.test.ts +16 -1
- package/src/__tests__/RealtimeRelay.test.ts +876 -0
- package/src/__tests__/RecordingAssemblyScheduler.test.ts +178 -0
- package/src/__tests__/RemoteBrowserActionResolver.goalRunLink.test.ts +129 -0
- package/src/__tests__/ResolverBase.adhocReadScope.test.ts +133 -2
- package/src/__tests__/ResolverBase.aggregateScreen.test.ts +174 -0
- 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 +212 -6
- package/src/__tests__/ResolverBase.filterEscaping.test.ts +5 -2
- package/src/__tests__/ReturningVisitorRecap.test.ts +115 -0
- package/src/__tests__/RunAIAgentResolver.branch.test.ts +170 -0
- package/src/__tests__/RunAIAgentResolver.historyFrom.test.ts +6 -4
- package/src/__tests__/RunAIAgentResolver.runDataGuard.test.ts +258 -0
- package/src/__tests__/RunAIAgentResolver.stoppedPredecessor.test.ts +166 -0
- package/src/__tests__/RunTemplateResolver.test.ts +132 -0
- package/src/__tests__/RunViewResolver.cacheCheckForwarding.test.ts +63 -0
- package/src/__tests__/RunViewResolver.cacheCheckScreen.test.ts +165 -0
- package/src/__tests__/SearchKnowledgeStreamResolver.test.ts +161 -0
- package/src/__tests__/SessionJanitor.test.ts +1203 -21
- package/src/__tests__/SessionManager.test.ts +240 -17
- package/src/__tests__/SessionRunIDVerifier.test.ts +251 -0
- package/src/__tests__/SyncRolesUsersResolver.userRoles.test.ts +97 -0
- package/src/__tests__/TaskGraphActionRunner.durablePayload.test.ts +25 -0
- package/src/__tests__/TaskGraphAgentRunner.test.ts +266 -0
- package/src/__tests__/TaskGraphContinuationDeliverer.test.ts +403 -22
- package/src/__tests__/TaskGraphFrameResolver.test.ts +22 -0
- package/src/__tests__/TestQuerySQLResolver.test.ts +274 -0
- package/src/__tests__/TransactionGroupResolver.refusals.test.ts +98 -1
- package/src/__tests__/UpdateMJDataContextItem.oldValues.test.ts +220 -0
- package/src/__tests__/UserAvatarResolver.test.ts +255 -0
- package/src/__tests__/UserResolver.currentUser.test.ts +16 -1
- package/src/__tests__/ViewOperationsHandler.clauseScreen.test.ts +157 -0
- package/src/__tests__/actionAuthorization.test.ts +130 -0
- package/src/__tests__/agent-run-data-guard.test.ts +130 -0
- package/src/__tests__/agentVisionConsentAudit.test.ts +118 -0
- package/src/__tests__/apiRootBoot.test.ts +202 -0
- package/src/__tests__/avatarInputValidation.test.ts +160 -0
- package/src/__tests__/cacheInvalidationRecordData.test.ts +64 -0
- package/src/__tests__/conversationRunEvents.test.ts +56 -14
- package/src/__tests__/globalCors.test.ts +217 -0
- package/src/__tests__/isolatedProviderTransactions.test.ts +169 -0
- package/src/__tests__/magicLinkService.consume.test.ts +6 -0
- package/src/__tests__/magicLinkService.provisionLog.test.ts +5 -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__/newUsers.template.test.ts +151 -0
- package/src/__tests__/newUsers.test.ts +74 -5
- package/src/__tests__/orphanedConversationDetailReconciler.test.ts +17 -2
- package/src/__tests__/ownedRealtimeSession.test.ts +39 -0
- package/src/__tests__/pushStatusResolver.filter.test.ts +7 -0
- package/src/__tests__/realtimeRecordingHandler.test.ts +652 -0
- package/src/__tests__/realtimeSessions/RealtimeSessionEventService.test.ts +201 -0
- package/src/__tests__/realtimeSessions/RealtimeSessionEventsResolver.test.ts +215 -0
- package/src/__tests__/realtimeSessions/RealtimeSessionVerificationResolver.test.ts +102 -0
- package/src/__tests__/realtimeSessions/RealtimeSessionVerificationService.test.ts +349 -0
- package/src/__tests__/realtimeSessions/RealtimeVerifyRouter.test.ts +131 -0
- package/src/__tests__/realtimeSessions/SlidingWindowRateLimiter.test.ts +56 -0
- package/src/__tests__/realtimeSessions/helpers.ts +4 -0
- package/src/__tests__/realtimeSessions/sessionAccess.test.ts +129 -0
- package/src/__tests__/realtimeSessions/sessionConfigStamps.test.ts +124 -0
- package/src/__tests__/realtimeSessions/verificationCore.test.ts +355 -0
- package/src/__tests__/realtimeSessions/verificationPages.test.ts +84 -0
- package/src/__tests__/realtimeSessions/verificationPolicy.test.ts +226 -0
- package/src/__tests__/realtimeSessions/verificationWorkflow.test.ts +633 -0
- package/src/__tests__/resolverBase.fls.test.ts +87 -4
- package/src/__tests__/serverExtensionHostOverlay.test.ts +66 -0
- package/src/__tests__/serverExtensionReservedRoots.test.ts +11 -96
- package/src/__tests__/sharedCache.test.ts +312 -0
- package/src/__tests__/widgetGuestElevation.test.ts +44 -0
- package/src/agentSessions/BridgeHostInstance.ts +32 -0
- package/src/agentSessions/HostInstance.ts +124 -28
- package/src/agentSessions/ReturningVisitorRecap.ts +7 -3
- package/src/agentSessions/SessionJanitor.ts +821 -59
- package/src/agentSessions/SessionManager.ts +138 -26
- package/src/agentSessions/SessionRunIDVerifier.ts +171 -0
- package/src/agentSessions/index.ts +10 -3
- package/src/apiRoot.ts +78 -0
- package/src/auth/AuthProviderCatalogRouter.ts +26 -0
- package/src/auth/LoginScreenEngine.ts +50 -0
- package/src/auth/actionAuthorization.ts +116 -0
- package/src/auth/index.ts +4 -8
- package/src/auth/magicLink/MagicLinkRouter.ts +3 -2
- package/src/auth/magicLink/MagicLinkService.ts +6 -3
- package/src/auth/newUsers.ts +99 -11
- package/src/config.ts +171 -5
- package/src/context.ts +15 -10
- package/src/coreRoutes.ts +166 -0
- package/src/generated/graphql-schemas/__mj.ts +1815 -57
- package/src/generic/CacheInvalidationResolver.ts +73 -18
- package/src/generic/OrphanedConversationDetailReconciler.ts +3 -3
- package/src/generic/PushStatusResolver.ts +1 -1
- package/src/generic/ResolverBase.ts +335 -326
- package/src/generic/RunViewResolver.ts +21 -0
- package/src/globalCors.ts +71 -0
- package/src/index.ts +231 -300
- package/src/isolatedProvider.ts +22 -0
- package/src/multiTenancy/index.ts +24 -2
- package/src/realtimeProxy/RealtimeProxyServer.ts +148 -16
- package/src/realtimeProxy/RealtimeRelayTunnel.ts +645 -0
- package/src/realtimeSessions/README.md +179 -0
- package/src/realtimeSessions/RealtimeSessionEventService.ts +274 -0
- package/src/realtimeSessions/RealtimeSessionVerificationService.ts +168 -0
- package/src/realtimeSessions/RealtimeVerifyRouter.ts +109 -0
- package/src/realtimeSessions/RecordingAssemblyScheduler.ts +234 -0
- package/src/realtimeSessions/SessionVerificationPortsBase.ts +189 -0
- package/src/realtimeSessions/SlidingWindowRateLimiter.ts +92 -0
- package/src/realtimeSessions/index.ts +18 -0
- package/src/realtimeSessions/ownedRealtimeSession.ts +55 -0
- package/src/realtimeSessions/sessionAccess.ts +145 -0
- package/src/realtimeSessions/sessionConfigStamps.ts +123 -0
- package/src/realtimeSessions/subscriptionAuthorization.ts +116 -0
- package/src/realtimeSessions/verificationCore.ts +502 -0
- package/src/realtimeSessions/verificationPages.ts +149 -0
- package/src/realtimeSessions/verificationPolicy.ts +321 -0
- package/src/realtimeSessions/verificationWorkflow.ts +702 -0
- package/src/realtimeWidget/widgetGuestElevation.ts +34 -2
- package/src/resolvers/ActionResolver.ts +84 -21
- package/src/resolvers/AdhocQueryResolver.ts +24 -6
- package/src/resolvers/ArtifactFileResolver.ts +9 -8
- package/src/resolvers/CacheStatsResolver.ts +89 -2
- package/src/resolvers/ClientToolRequestResolver.ts +25 -7
- package/src/resolvers/ConversationRunEventsResolver.ts +15 -11
- package/src/resolvers/DatasetResolver.ts +70 -10
- package/src/resolvers/EntityRecordNameResolver.ts +3 -2
- package/src/resolvers/FetchEntityVectorsResolver.ts +179 -2
- package/src/resolvers/FileResolver.ts +321 -106
- package/src/resolvers/GetDataContextDataResolver.ts +139 -41
- package/src/resolvers/GetDataResolver.ts +6 -3
- package/src/resolvers/HumanHandoffResolver.ts +8 -0
- package/src/resolvers/IntegrationDiscoveryResolver.ts +4 -2
- package/src/resolvers/MCPResolver.ts +8 -5
- package/src/resolvers/QueryResolver.ts +11 -0
- package/src/resolvers/RealtimeBridgeResolver.ts +163 -11
- package/src/resolvers/RealtimeClientSessionResolver.ts +511 -129
- package/src/resolvers/RealtimeSessionEventsResolver.ts +133 -0
- package/src/resolvers/RealtimeSessionVerificationResolver.ts +174 -0
- package/src/resolvers/RemoteBrowserActionResolver.ts +11 -1
- package/src/resolvers/RunAIAgentResolver.ts +116 -14
- package/src/resolvers/RunTemplateResolver.ts +13 -12
- package/src/resolvers/SearchKnowledgeStreamResolver.ts +19 -3
- package/src/resolvers/SqlLoggingConfigResolver.ts +2 -4
- package/src/resolvers/SyncDataResolver.ts +6 -2
- package/src/resolvers/SyncRolesUsersResolver.ts +24 -6
- package/src/resolvers/TaskGraphFrameResolver.ts +33 -1
- package/src/resolvers/TestQuerySQLResolver.ts +68 -13
- package/src/resolvers/TransactionGroupResolver.ts +131 -27
- package/src/resolvers/UserAvatarResolver.ts +111 -0
- package/src/resolvers/UserResolver.ts +2 -16
- package/src/resolvers/__tests__/GetDataResolver.validation.test.ts +95 -0
- package/src/resolvers/agent-run-data-guard.ts +89 -0
- package/src/resolvers/agentVisionConsentAudit.ts +82 -0
- package/src/resolvers/avatarInputValidation.ts +123 -0
- package/src/resolvers/currentUserRoles.ts +32 -1
- package/src/resolvers/meetings/meetingMutations.ts +21 -0
- package/src/rest/RealtimeRecordingHandler.ts +464 -0
- package/src/rest/ViewOperationsHandler.ts +29 -13
- package/src/rest/setupRESTEndpoints.ts +6 -0
- package/src/serverExtensionReservedRoots.ts +14 -17
- 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 +713 -17
- package/src/sharedCache.ts +305 -0
- package/src/types.ts +7 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Server-side publisher for **realtime session events** — the hook an app (or MJ itself)
|
|
3
|
+
* calls to push a typed event into ONE live realtime session.
|
|
4
|
+
*
|
|
5
|
+
* The wire contract (event types, payload shapes, parsing) lives in `@memberjunction/ai-core-plus`
|
|
6
|
+
* (`realtime-session-events.ts`). This module owns the transport: it publishes onto MJServer's
|
|
7
|
+
* existing PubSub (`PubSubManager`) so the `RealtimeSessionEvents` GraphQL subscription can deliver it.
|
|
8
|
+
*
|
|
9
|
+
* ## Routing is part of the payload
|
|
10
|
+
*
|
|
11
|
+
* Every published event carries a snapshot of who may see it — the session's owner (`OwnerUserID`) and
|
|
12
|
+
* the session's anonymous scope id (`ScopeKey`). The subscription filter compares that snapshot with
|
|
13
|
+
* the **connection's** authenticated identity, so a subscriber who guesses another session's id still
|
|
14
|
+
* receives nothing. These two fields are server-internal: the GraphQL notification type does not
|
|
15
|
+
* expose them.
|
|
16
|
+
*
|
|
17
|
+
* ## Multiple server instances
|
|
18
|
+
*
|
|
19
|
+
* PubSub is in-process. Behind a load balancer the browser's WebSocket can live on a different replica
|
|
20
|
+
* than the one that handled the verification link. {@link RealtimeSessionEventService.SetReplicationHook}
|
|
21
|
+
* lets the host fan events out (the server wires it to Redis when `REDIS_URL` is set, exactly as it does
|
|
22
|
+
* for push-status updates), and {@link RealtimeSessionEventService.PublishReplicated} republishes an event
|
|
23
|
+
* that arrived from another instance.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* // From an Open App's server code, after it finished some work for a live session:
|
|
28
|
+
* await RealtimeSessionEventService.Instance.Publish({
|
|
29
|
+
* AgentSessionID: sessionId,
|
|
30
|
+
* Type: 'acme.quote.ready',
|
|
31
|
+
* Payload: { QuoteID: quote.ID },
|
|
32
|
+
* ContextUser: systemUser,
|
|
33
|
+
* });
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* @module @memberjunction/server/realtimeSessions
|
|
37
|
+
*/
|
|
38
|
+
import { IMetadataProvider, UserInfo } from '@memberjunction/core';
|
|
39
|
+
import { BaseSingleton } from '@memberjunction/global';
|
|
40
|
+
import { type RealtimeSessionEventPayload, type RealtimeSessionEventType } from '@memberjunction/ai-core-plus';
|
|
41
|
+
/** The PubSub topic every realtime session event is published on. */
|
|
42
|
+
export declare const REALTIME_SESSION_EVENTS_TOPIC = "REALTIME_SESSION_EVENTS";
|
|
43
|
+
/**
|
|
44
|
+
* What is actually published on {@link REALTIME_SESSION_EVENTS_TOPIC}: the wire event plus the
|
|
45
|
+
* server-internal routing snapshot.
|
|
46
|
+
*/
|
|
47
|
+
export type RealtimeSessionEventTopicPayload = {
|
|
48
|
+
Type: string;
|
|
49
|
+
AgentSessionID: string;
|
|
50
|
+
OccurredAt: string;
|
|
51
|
+
/** The event payload, JSON-encoded. */
|
|
52
|
+
PayloadJson: string;
|
|
53
|
+
/** `AIAgentSession.UserID` — compared with the subscriber connection's user. Server-internal. */
|
|
54
|
+
OwnerUserID: string;
|
|
55
|
+
/** `Conversation.ExternalID` — compared with the subscriber's signed scope. Server-internal. */
|
|
56
|
+
ScopeKey: string | null;
|
|
57
|
+
/**
|
|
58
|
+
* `MJGlobal.ProcessUUID` of the instance that first published the event; lets an instance drop its
|
|
59
|
+
* own message when it echoes back from the replication bus.
|
|
60
|
+
*/
|
|
61
|
+
SourceServerId?: string;
|
|
62
|
+
};
|
|
63
|
+
/** Who may receive an event, resolved from the session at publish time. */
|
|
64
|
+
export interface RealtimeSessionEventRouting {
|
|
65
|
+
/** The session the event is addressed to. */
|
|
66
|
+
AgentSessionID: string;
|
|
67
|
+
/** The session's owner. */
|
|
68
|
+
OwnerUserID: string;
|
|
69
|
+
/** The session conversation's `ExternalID` (anonymous scope id), or null. */
|
|
70
|
+
ScopeKey: string | null;
|
|
71
|
+
}
|
|
72
|
+
/** Input to {@link RealtimeSessionEventService.Publish}. */
|
|
73
|
+
export interface PublishRealtimeSessionEventInput<T extends RealtimeSessionEventType> {
|
|
74
|
+
/** The session to address. */
|
|
75
|
+
AgentSessionID: string;
|
|
76
|
+
/** Event type — a key of `RealtimeSessionEventPayloadMap`. */
|
|
77
|
+
Type: T;
|
|
78
|
+
/** Type-specific data; must be JSON-serializable. */
|
|
79
|
+
Payload: RealtimeSessionEventPayload<T>;
|
|
80
|
+
/**
|
|
81
|
+
* The identity to read the session under. Server-side publishers pass a system/service user — the
|
|
82
|
+
* session row is being addressed by the server, not on a caller's behalf.
|
|
83
|
+
*/
|
|
84
|
+
ContextUser: UserInfo;
|
|
85
|
+
/** Provider to read the session with. Defaults to the process-global provider (server bootstrap use). */
|
|
86
|
+
Provider?: IMetadataProvider;
|
|
87
|
+
}
|
|
88
|
+
/** Outcome of a publish. A failure is never silent: it is also logged. */
|
|
89
|
+
export interface PublishRealtimeSessionEventResult {
|
|
90
|
+
/** True when the event was handed to the PubSub. */
|
|
91
|
+
Success: boolean;
|
|
92
|
+
/** Why it was not, when it was not. */
|
|
93
|
+
ErrorMessage?: string;
|
|
94
|
+
}
|
|
95
|
+
/** Called for every locally-published event so the host can replicate it to other instances. */
|
|
96
|
+
export type RealtimeSessionEventReplicationHook = (payload: RealtimeSessionEventTopicPayload) => void;
|
|
97
|
+
/**
|
|
98
|
+
* Publishes realtime session events. A {@link BaseSingleton}: there is one publisher per process, and
|
|
99
|
+
* the replication hook is process-wide state.
|
|
100
|
+
*/
|
|
101
|
+
export declare class RealtimeSessionEventService extends BaseSingleton<RealtimeSessionEventService> {
|
|
102
|
+
private replicationHook;
|
|
103
|
+
protected constructor();
|
|
104
|
+
/** The process-wide instance. */
|
|
105
|
+
static get Instance(): RealtimeSessionEventService;
|
|
106
|
+
/**
|
|
107
|
+
* Publishes an event to one live session. Reads the session to snapshot its owner and scope, so the
|
|
108
|
+
* caller never supplies (and can never get wrong) who may receive the event.
|
|
109
|
+
*
|
|
110
|
+
* Does not require the session to be open: an event for a closed session simply reaches no
|
|
111
|
+
* subscriber.
|
|
112
|
+
*
|
|
113
|
+
* @returns a result rather than throwing — event delivery is best-effort, durable state lives
|
|
114
|
+
* elsewhere (the verification status query is the backstop for a missed `identity.verified`).
|
|
115
|
+
*/
|
|
116
|
+
Publish<T extends RealtimeSessionEventType>(input: PublishRealtimeSessionEventInput<T>): Promise<PublishRealtimeSessionEventResult>;
|
|
117
|
+
/**
|
|
118
|
+
* Publishes an event when the caller already holds the session's routing (the verification service
|
|
119
|
+
* has just loaded the session, so it must not pay a second read).
|
|
120
|
+
*/
|
|
121
|
+
PublishRouted<T extends RealtimeSessionEventType>(routing: RealtimeSessionEventRouting, type: T, payload: RealtimeSessionEventPayload<T>): PublishRealtimeSessionEventResult;
|
|
122
|
+
/**
|
|
123
|
+
* Republishes an event that arrived from another server instance onto THIS instance's local topic
|
|
124
|
+
* only (never back through the replication hook, so there is no loop). The subscription filter still
|
|
125
|
+
* decides who receives it — a replica has no say in who sees what.
|
|
126
|
+
*/
|
|
127
|
+
PublishReplicated(payload: RealtimeSessionEventTopicPayload): void;
|
|
128
|
+
/**
|
|
129
|
+
* Registers (or, with no argument, clears) the cross-instance fan-out hook. Inversion of control:
|
|
130
|
+
* this module must not know that Redis exists.
|
|
131
|
+
*/
|
|
132
|
+
SetReplicationHook(hook?: RealtimeSessionEventReplicationHook): void;
|
|
133
|
+
/** Hands a locally-published event to the replication hook, never letting a bus failure break local delivery. */
|
|
134
|
+
private replicate;
|
|
135
|
+
private fail;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Validates an event received from the cross-instance message bus before it is republished locally.
|
|
139
|
+
*
|
|
140
|
+
* The bus carries messages from other processes, so every field is type-checked. Fails closed: an event
|
|
141
|
+
* with no routing identity can never be delivered safely, so it is dropped.
|
|
142
|
+
*
|
|
143
|
+
* @param raw - the JSON text taken off the bus
|
|
144
|
+
* @param localServerId - this process's `MJGlobal.ProcessUUID`, used to drop our own echo
|
|
145
|
+
* @returns the event to republish, or `null` to drop it
|
|
146
|
+
*/
|
|
147
|
+
export declare function ParseReplicatedRealtimeSessionEvent(raw: string, localServerId: string): RealtimeSessionEventTopicPayload | null;
|
|
148
|
+
//# sourceMappingURL=RealtimeSessionEventService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RealtimeSessionEventService.d.ts","sourceRoot":"","sources":["../../src/realtimeSessions/RealtimeSessionEventService.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,EAAE,iBAAiB,EAAsB,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACvF,OAAO,EAAE,aAAa,EAAY,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAEH,KAAK,2BAA2B,EAChC,KAAK,wBAAwB,EAChC,MAAM,8BAA8B,CAAC;AAItC,qEAAqE;AACrE,eAAO,MAAM,6BAA6B,4BAA4B,CAAC;AAEvE;;;GAGG;AACH,MAAM,MAAM,gCAAgC,GAAG;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,uCAAuC;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,iGAAiG;IACjG,WAAW,EAAE,MAAM,CAAC;IACpB,gGAAgG;IAChG,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,2EAA2E;AAC3E,MAAM,WAAW,2BAA2B;IACxC,6CAA6C;IAC7C,cAAc,EAAE,MAAM,CAAC;IACvB,2BAA2B;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,4DAA4D;AAC5D,MAAM,WAAW,gCAAgC,CAAC,CAAC,SAAS,wBAAwB;IAChF,8BAA8B;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,8DAA8D;IAC9D,IAAI,EAAE,CAAC,CAAC;IACR,qDAAqD;IACrD,OAAO,EAAE,2BAA2B,CAAC,CAAC,CAAC,CAAC;IACxC;;;OAGG;IACH,WAAW,EAAE,QAAQ,CAAC;IACtB,yGAAyG;IACzG,QAAQ,CAAC,EAAE,iBAAiB,CAAC;CAChC;AAED,0EAA0E;AAC1E,MAAM,WAAW,iCAAiC;IAC9C,oDAAoD;IACpD,OAAO,EAAE,OAAO,CAAC;IACjB,uCAAuC;IACvC,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,gGAAgG;AAChG,MAAM,MAAM,mCAAmC,GAAG,CAAC,OAAO,EAAE,gCAAgC,KAAK,IAAI,CAAC;AAEtG;;;GAGG;AACH,qBAAa,2BAA4B,SAAQ,aAAa,CAAC,2BAA2B,CAAC;IACvF,OAAO,CAAC,eAAe,CAAkD;IAEzE,SAAS;IAIT,iCAAiC;IACjC,WAAkB,QAAQ,IAAI,2BAA2B,CAExD;IAED;;;;;;;;;OASG;IACU,OAAO,CAAC,CAAC,SAAS,wBAAwB,EACnD,KAAK,EAAE,gCAAgC,CAAC,CAAC,CAAC,GAC3C,OAAO,CAAC,iCAAiC,CAAC;IAqB7C;;;OAGG;IACI,aAAa,CAAC,CAAC,SAAS,wBAAwB,EACnD,OAAO,EAAE,2BAA2B,EACpC,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,2BAA2B,CAAC,CAAC,CAAC,GACxC,iCAAiC;IAqBpC;;;;OAIG;IACI,iBAAiB,CAAC,OAAO,EAAE,gCAAgC,GAAG,IAAI;IAIzE;;;OAGG;IACI,kBAAkB,CAAC,IAAI,CAAC,EAAE,mCAAmC,GAAG,IAAI;IAI3E,iHAAiH;IACjH,OAAO,CAAC,SAAS;IAYjB,OAAO,CAAC,IAAI;CAIf;AAED;;;;;;;;;GASG;AACH,wBAAgB,mCAAmC,CAAC,GAAG,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,gCAAgC,GAAG,IAAI,CAkC/H"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Server-side publisher for **realtime session events** — the hook an app (or MJ itself)
|
|
3
|
+
* calls to push a typed event into ONE live realtime session.
|
|
4
|
+
*
|
|
5
|
+
* The wire contract (event types, payload shapes, parsing) lives in `@memberjunction/ai-core-plus`
|
|
6
|
+
* (`realtime-session-events.ts`). This module owns the transport: it publishes onto MJServer's
|
|
7
|
+
* existing PubSub (`PubSubManager`) so the `RealtimeSessionEvents` GraphQL subscription can deliver it.
|
|
8
|
+
*
|
|
9
|
+
* ## Routing is part of the payload
|
|
10
|
+
*
|
|
11
|
+
* Every published event carries a snapshot of who may see it — the session's owner (`OwnerUserID`) and
|
|
12
|
+
* the session's anonymous scope id (`ScopeKey`). The subscription filter compares that snapshot with
|
|
13
|
+
* the **connection's** authenticated identity, so a subscriber who guesses another session's id still
|
|
14
|
+
* receives nothing. These two fields are server-internal: the GraphQL notification type does not
|
|
15
|
+
* expose them.
|
|
16
|
+
*
|
|
17
|
+
* ## Multiple server instances
|
|
18
|
+
*
|
|
19
|
+
* PubSub is in-process. Behind a load balancer the browser's WebSocket can live on a different replica
|
|
20
|
+
* than the one that handled the verification link. {@link RealtimeSessionEventService.SetReplicationHook}
|
|
21
|
+
* lets the host fan events out (the server wires it to Redis when `REDIS_URL` is set, exactly as it does
|
|
22
|
+
* for push-status updates), and {@link RealtimeSessionEventService.PublishReplicated} republishes an event
|
|
23
|
+
* that arrived from another instance.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* // From an Open App's server code, after it finished some work for a live session:
|
|
28
|
+
* await RealtimeSessionEventService.Instance.Publish({
|
|
29
|
+
* AgentSessionID: sessionId,
|
|
30
|
+
* Type: 'acme.quote.ready',
|
|
31
|
+
* Payload: { QuoteID: quote.ID },
|
|
32
|
+
* ContextUser: systemUser,
|
|
33
|
+
* });
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* @module @memberjunction/server/realtimeSessions
|
|
37
|
+
*/
|
|
38
|
+
import { LogError, Metadata } from '@memberjunction/core';
|
|
39
|
+
import { BaseSingleton, MJGlobal } from '@memberjunction/global';
|
|
40
|
+
import { SerializeRealtimeSessionEvent, } from '@memberjunction/ai-core-plus';
|
|
41
|
+
import { PubSubManager } from '../generic/PubSubManager.js';
|
|
42
|
+
import { LoadSessionForAccess } from './sessionAccess.js';
|
|
43
|
+
/** The PubSub topic every realtime session event is published on. */
|
|
44
|
+
export const REALTIME_SESSION_EVENTS_TOPIC = 'REALTIME_SESSION_EVENTS';
|
|
45
|
+
/**
|
|
46
|
+
* Publishes realtime session events. A {@link BaseSingleton}: there is one publisher per process, and
|
|
47
|
+
* the replication hook is process-wide state.
|
|
48
|
+
*/
|
|
49
|
+
export class RealtimeSessionEventService extends BaseSingleton {
|
|
50
|
+
constructor() {
|
|
51
|
+
super();
|
|
52
|
+
}
|
|
53
|
+
/** The process-wide instance. */
|
|
54
|
+
static get Instance() {
|
|
55
|
+
return super.getInstance();
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Publishes an event to one live session. Reads the session to snapshot its owner and scope, so the
|
|
59
|
+
* caller never supplies (and can never get wrong) who may receive the event.
|
|
60
|
+
*
|
|
61
|
+
* Does not require the session to be open: an event for a closed session simply reaches no
|
|
62
|
+
* subscriber.
|
|
63
|
+
*
|
|
64
|
+
* @returns a result rather than throwing — event delivery is best-effort, durable state lives
|
|
65
|
+
* elsewhere (the verification status query is the backstop for a missed `identity.verified`).
|
|
66
|
+
*/
|
|
67
|
+
async Publish(input) {
|
|
68
|
+
try {
|
|
69
|
+
const provider = input.Provider ?? Metadata.Provider; // global-provider-ok: documented last-resort fallback for server-bootstrap publishers
|
|
70
|
+
const loaded = await LoadSessionForAccess(input.AgentSessionID, input.ContextUser, provider);
|
|
71
|
+
if (!loaded) {
|
|
72
|
+
return this.fail(`Realtime session ${input.AgentSessionID} not found; event '${input.Type}' not published.`);
|
|
73
|
+
}
|
|
74
|
+
return this.PublishRouted({
|
|
75
|
+
AgentSessionID: loaded.Session.ID,
|
|
76
|
+
OwnerUserID: loaded.Session.UserID,
|
|
77
|
+
ScopeKey: loaded.ConversationExternalID,
|
|
78
|
+
}, input.Type, input.Payload);
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
return this.fail(`Publishing '${input.Type}' to session ${input.AgentSessionID} failed: ${errorText(error)}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Publishes an event when the caller already holds the session's routing (the verification service
|
|
86
|
+
* has just loaded the session, so it must not pay a second read).
|
|
87
|
+
*/
|
|
88
|
+
PublishRouted(routing, type, payload) {
|
|
89
|
+
const wire = SerializeRealtimeSessionEvent({
|
|
90
|
+
Type: type,
|
|
91
|
+
AgentSessionID: routing.AgentSessionID,
|
|
92
|
+
OccurredAt: new Date().toISOString(),
|
|
93
|
+
Payload: payload,
|
|
94
|
+
});
|
|
95
|
+
const topicPayload = {
|
|
96
|
+
...wire,
|
|
97
|
+
OwnerUserID: routing.OwnerUserID,
|
|
98
|
+
ScopeKey: routing.ScopeKey,
|
|
99
|
+
SourceServerId: MJGlobal.Instance.ProcessUUID,
|
|
100
|
+
};
|
|
101
|
+
if (!PubSubManager.Instance.PubSubEngine) {
|
|
102
|
+
return this.fail(`PubSub is not configured; event '${type}' for session ${routing.AgentSessionID} not published.`);
|
|
103
|
+
}
|
|
104
|
+
PubSubManager.Instance.Publish(REALTIME_SESSION_EVENTS_TOPIC, topicPayload);
|
|
105
|
+
this.replicate(topicPayload);
|
|
106
|
+
return { Success: true };
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Republishes an event that arrived from another server instance onto THIS instance's local topic
|
|
110
|
+
* only (never back through the replication hook, so there is no loop). The subscription filter still
|
|
111
|
+
* decides who receives it — a replica has no say in who sees what.
|
|
112
|
+
*/
|
|
113
|
+
PublishReplicated(payload) {
|
|
114
|
+
PubSubManager.Instance.Publish(REALTIME_SESSION_EVENTS_TOPIC, payload);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Registers (or, with no argument, clears) the cross-instance fan-out hook. Inversion of control:
|
|
118
|
+
* this module must not know that Redis exists.
|
|
119
|
+
*/
|
|
120
|
+
SetReplicationHook(hook) {
|
|
121
|
+
this.replicationHook = hook;
|
|
122
|
+
}
|
|
123
|
+
/** Hands a locally-published event to the replication hook, never letting a bus failure break local delivery. */
|
|
124
|
+
replicate(payload) {
|
|
125
|
+
if (!this.replicationHook) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
try {
|
|
129
|
+
this.replicationHook(payload);
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
// Replication is an optimisation over the durable status query; local delivery already happened.
|
|
133
|
+
LogError(`RealtimeSessionEventService: replication hook failed: ${errorText(error)}`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
fail(message) {
|
|
137
|
+
LogError(`RealtimeSessionEventService: ${message}`);
|
|
138
|
+
return { Success: false, ErrorMessage: message };
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Validates an event received from the cross-instance message bus before it is republished locally.
|
|
143
|
+
*
|
|
144
|
+
* The bus carries messages from other processes, so every field is type-checked. Fails closed: an event
|
|
145
|
+
* with no routing identity can never be delivered safely, so it is dropped.
|
|
146
|
+
*
|
|
147
|
+
* @param raw - the JSON text taken off the bus
|
|
148
|
+
* @param localServerId - this process's `MJGlobal.ProcessUUID`, used to drop our own echo
|
|
149
|
+
* @returns the event to republish, or `null` to drop it
|
|
150
|
+
*/
|
|
151
|
+
export function ParseReplicatedRealtimeSessionEvent(raw, localServerId) {
|
|
152
|
+
let parsed;
|
|
153
|
+
try {
|
|
154
|
+
parsed = JSON.parse(raw);
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
return null; // not JSON: nothing to deliver
|
|
158
|
+
}
|
|
159
|
+
if (typeof parsed !== 'object' || parsed === null) {
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
const record = parsed;
|
|
163
|
+
const { Type, AgentSessionID, OccurredAt, PayloadJson, OwnerUserID, ScopeKey, SourceServerId } = record;
|
|
164
|
+
if (SourceServerId === localServerId) {
|
|
165
|
+
return null; // our own message, echoed back
|
|
166
|
+
}
|
|
167
|
+
const requiredStrings = [Type, AgentSessionID, OccurredAt, PayloadJson, OwnerUserID];
|
|
168
|
+
if (requiredStrings.some((value) => typeof value !== 'string' || value.length === 0)) {
|
|
169
|
+
return null; // includes a missing owner: fail closed
|
|
170
|
+
}
|
|
171
|
+
if (ScopeKey !== null && ScopeKey !== undefined && typeof ScopeKey !== 'string') {
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
if (SourceServerId !== undefined && typeof SourceServerId !== 'string') {
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
return {
|
|
178
|
+
Type: Type,
|
|
179
|
+
AgentSessionID: AgentSessionID,
|
|
180
|
+
OccurredAt: OccurredAt,
|
|
181
|
+
PayloadJson: PayloadJson,
|
|
182
|
+
OwnerUserID: OwnerUserID,
|
|
183
|
+
ScopeKey: typeof ScopeKey === 'string' ? ScopeKey : null,
|
|
184
|
+
SourceServerId: typeof SourceServerId === 'string' ? SourceServerId : undefined,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
/** Message text of an unknown thrown value. */
|
|
188
|
+
function errorText(error) {
|
|
189
|
+
return error instanceof Error ? error.message : String(error);
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=RealtimeSessionEventService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RealtimeSessionEventService.js","sourceRoot":"","sources":["../../src/realtimeSessions/RealtimeSessionEventService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `RealtimeSessionVerificationService` — the production wiring of mid-session identity
|
|
3
|
+
* verification: the real {@link VerificationPorts} (session read/write, email, event publish, audit)
|
|
4
|
+
* behind a process-wide singleton the GraphQL resolver and the public verify route both call.
|
|
5
|
+
*
|
|
6
|
+
* The decisions live in `verificationWorkflow.ts`; this file is deliberately thin glue. See that
|
|
7
|
+
* module's header for the operation table, what verification does and does not do, and the
|
|
8
|
+
* concurrency contract; see `README.md` in this folder for the end-to-end flow and security model.
|
|
9
|
+
*
|
|
10
|
+
* The session-facing half of the ports (reads, trusted writes, event publish, audit — and the reasoning
|
|
11
|
+
* for which identity performs which) is {@link SessionVerificationPortsBase}; this file adds the server
|
|
12
|
+
* configuration to it.
|
|
13
|
+
*
|
|
14
|
+
* @module @memberjunction/server/realtimeSessions
|
|
15
|
+
*/
|
|
16
|
+
import type { UserInfo } from '@memberjunction/core';
|
|
17
|
+
import { BaseSingleton } from '@memberjunction/global';
|
|
18
|
+
import { SessionVerificationPortsBase } from './SessionVerificationPortsBase.js';
|
|
19
|
+
import { type OutboundEmail, type PrincipalCaller, type VerificationOperationResult, type VerificationSettings } from './verificationWorkflow.js';
|
|
20
|
+
/**
|
|
21
|
+
* The production ports: {@link SessionVerificationPortsBase} plus the server configuration — the settings
|
|
22
|
+
* read from `realtime.identityVerification`, the configured service principal, and delivery through the
|
|
23
|
+
* configured communication provider. Exported for tests and for hosts that want to compose their own
|
|
24
|
+
* workflow around them; application code should use {@link RealtimeSessionVerificationService}.
|
|
25
|
+
*/
|
|
26
|
+
export declare class RuntimeVerificationPorts extends SessionVerificationPortsBase {
|
|
27
|
+
GetSettings(): VerificationSettings;
|
|
28
|
+
SendEmail(email: OutboundEmail): Promise<{
|
|
29
|
+
Success: boolean;
|
|
30
|
+
ErrorMessage?: string;
|
|
31
|
+
}>;
|
|
32
|
+
/** The configured service principal (see {@link SessionVerificationPortsBase}). */
|
|
33
|
+
protected ResolveServiceUser(): UserInfo | null;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The process-wide verification service. Call it from the `RealtimeSessionVerificationResolver`
|
|
37
|
+
* (authenticated principal) and the public `/realtime/verify` router (link capability).
|
|
38
|
+
*/
|
|
39
|
+
export declare class RealtimeSessionVerificationService extends BaseSingleton<RealtimeSessionVerificationService> {
|
|
40
|
+
private workflow;
|
|
41
|
+
protected constructor();
|
|
42
|
+
/** The process-wide instance. */
|
|
43
|
+
static get Instance(): RealtimeSessionVerificationService;
|
|
44
|
+
/** Whether verification is switched on and able to send mail. */
|
|
45
|
+
get IsEnabled(): boolean;
|
|
46
|
+
/** See {@link RealtimeSessionVerificationWorkflow.RequestVerification}. */
|
|
47
|
+
RequestVerification(input: {
|
|
48
|
+
AgentSessionID: string;
|
|
49
|
+
Name: string;
|
|
50
|
+
Email: string;
|
|
51
|
+
}, caller: PrincipalCaller): Promise<VerificationOperationResult>;
|
|
52
|
+
/** See {@link RealtimeSessionVerificationWorkflow.SubmitCode}. */
|
|
53
|
+
SubmitCode(input: {
|
|
54
|
+
AgentSessionID: string;
|
|
55
|
+
Code: string;
|
|
56
|
+
}, caller: PrincipalCaller): Promise<VerificationOperationResult>;
|
|
57
|
+
/** See {@link RealtimeSessionVerificationWorkflow.RedeemLink}. */
|
|
58
|
+
RedeemLink(token: string, clientIp?: string): Promise<VerificationOperationResult>;
|
|
59
|
+
/** See {@link RealtimeSessionVerificationWorkflow.GetStatus}. */
|
|
60
|
+
GetStatus(input: {
|
|
61
|
+
AgentSessionID: string;
|
|
62
|
+
}, caller: PrincipalCaller): Promise<VerificationOperationResult>;
|
|
63
|
+
/** The workflow is created on first use so its limiters pick up the loaded config. */
|
|
64
|
+
private getWorkflow;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=RealtimeSessionVerificationService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RealtimeSessionVerificationService.d.ts","sourceRoot":"","sources":["../../src/realtimeSessions/RealtimeSessionVerificationService.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAuB,MAAM,wBAAwB,CAAC;AAM5E,OAAO,EAAE,4BAA4B,EAAE,MAAM,mCAAmC,CAAC;AAEjF,OAAO,EAEH,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,2BAA2B,EAChC,KAAK,oBAAoB,EAC5B,MAAM,2BAA2B,CAAC;AA0CnC;;;;;GAKG;AACH,qBAAa,wBAAyB,SAAQ,4BAA4B;IAC/D,WAAW,IAAI,oBAAoB;IAI7B,SAAS,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAyBlG,mFAAmF;IACnF,SAAS,CAAC,kBAAkB,IAAI,QAAQ,GAAG,IAAI;CAIlD;AAED;;;GAGG;AACH,qBAAa,kCAAmC,SAAQ,aAAa,CAAC,kCAAkC,CAAC;IACrG,OAAO,CAAC,QAAQ,CAAkD;IAElE,SAAS;IAIT,iCAAiC;IACjC,WAAkB,QAAQ,IAAI,kCAAkC,CAE/D;IAED,iEAAiE;IACjE,IAAW,SAAS,IAAI,OAAO,CAE9B;IAED,2EAA2E;IACpE,mBAAmB,CACtB,KAAK,EAAE;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAC9D,MAAM,EAAE,eAAe,GACxB,OAAO,CAAC,2BAA2B,CAAC;IAIvC,kEAAkE;IAC3D,UAAU,CAAC,KAAK,EAAE;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,2BAA2B,CAAC;IAIjI,kEAAkE;IAC3D,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,2BAA2B,CAAC;IAIzF,iEAAiE;IAC1D,SAAS,CAAC,KAAK,EAAE;QAAE,cAAc,EAAE,MAAM,CAAA;KAAE,EAAE,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,2BAA2B,CAAC;IAIlH,sFAAsF;IACtF,OAAO,CAAC,WAAW;CAMtB"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `RealtimeSessionVerificationService` — the production wiring of mid-session identity
|
|
3
|
+
* verification: the real {@link VerificationPorts} (session read/write, email, event publish, audit)
|
|
4
|
+
* behind a process-wide singleton the GraphQL resolver and the public verify route both call.
|
|
5
|
+
*
|
|
6
|
+
* The decisions live in `verificationWorkflow.ts`; this file is deliberately thin glue. See that
|
|
7
|
+
* module's header for the operation table, what verification does and does not do, and the
|
|
8
|
+
* concurrency contract; see `README.md` in this folder for the end-to-end flow and security model.
|
|
9
|
+
*
|
|
10
|
+
* The session-facing half of the ports (reads, trusted writes, event publish, audit — and the reasoning
|
|
11
|
+
* for which identity performs which) is {@link SessionVerificationPortsBase}; this file adds the server
|
|
12
|
+
* configuration to it.
|
|
13
|
+
*
|
|
14
|
+
* @module @memberjunction/server/realtimeSessions
|
|
15
|
+
*/
|
|
16
|
+
import { BaseSingleton, TrimTrailingSlashes } from '@memberjunction/global';
|
|
17
|
+
import { CommunicationEngine } from '@memberjunction/communication-engine';
|
|
18
|
+
import { Message } from '@memberjunction/communication-types';
|
|
19
|
+
import { UserCache } from '@memberjunction/generic-database-provider';
|
|
20
|
+
import { configInfo } from '../config.js';
|
|
21
|
+
import { ResolveConfiguredPrincipal } from '../auth/principals.js';
|
|
22
|
+
import { SessionVerificationPortsBase } from './SessionVerificationPortsBase.js';
|
|
23
|
+
import { ReadIdentityVerificationPolicyLayer } from './verificationPolicy.js';
|
|
24
|
+
import { RealtimeSessionVerificationWorkflow, } from './verificationWorkflow.js';
|
|
25
|
+
import { ConfiguredPublicUrl } from '../apiRoot.js';
|
|
26
|
+
/** Purpose label for principal-resolution diagnostics. */
|
|
27
|
+
const PRINCIPAL_PURPOSE = 'RealtimeVerification';
|
|
28
|
+
/** The base URL emailed links are built from: explicit setting, else the server's public URL (same derivation magic links use). */
|
|
29
|
+
function resolvePublicBaseUrl(explicit) {
|
|
30
|
+
const candidate = explicit?.trim() || ConfiguredPublicUrl();
|
|
31
|
+
return candidate ? TrimTrailingSlashes(candidate) : undefined;
|
|
32
|
+
}
|
|
33
|
+
/** The shortest `hmacSecret` accepted. */
|
|
34
|
+
const MIN_HMAC_SECRET_LENGTH = 16;
|
|
35
|
+
/** True when the configured HMAC secret is long enough to protect the stored code hash. */
|
|
36
|
+
function hasUsableHmacSecret(secret) {
|
|
37
|
+
return !!secret && secret.length >= MIN_HMAC_SECRET_LENGTH;
|
|
38
|
+
}
|
|
39
|
+
/** Reads the live settings from server config. */
|
|
40
|
+
function readSettings() {
|
|
41
|
+
const cfg = configInfo.realtime?.identityVerification;
|
|
42
|
+
const limits = cfg?.rateLimits;
|
|
43
|
+
return {
|
|
44
|
+
// A feature that cannot send mail, or cannot protect the codes it issues, is not available — whatever `enabled` says.
|
|
45
|
+
Enabled: !!cfg?.enabled && !!cfg.communicationProvider && hasUsableHmacSecret(cfg.hmacSecret),
|
|
46
|
+
CodeHashKey: cfg?.hmacSecret ?? '',
|
|
47
|
+
PolicyDefaults: ReadIdentityVerificationPolicyLayer(cfg?.policy),
|
|
48
|
+
PublicBaseUrl: resolvePublicBaseUrl(cfg?.publicBaseUrl),
|
|
49
|
+
RateLimits: {
|
|
50
|
+
SendWindowMs: limits?.sendWindowMs ?? 3_600_000,
|
|
51
|
+
PerIpSends: limits?.perIpSends ?? 10,
|
|
52
|
+
PerEmailDomainSends: limits?.perEmailDomainSends ?? 30,
|
|
53
|
+
PerEmailSends: limits?.perEmailSends ?? 3,
|
|
54
|
+
CodeAttemptWindowMs: limits?.codeAttemptWindowMs ?? 600_000,
|
|
55
|
+
PerSessionCodeAttempts: limits?.perSessionCodeAttempts ?? 10,
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The production ports: {@link SessionVerificationPortsBase} plus the server configuration — the settings
|
|
61
|
+
* read from `realtime.identityVerification`, the configured service principal, and delivery through the
|
|
62
|
+
* configured communication provider. Exported for tests and for hosts that want to compose their own
|
|
63
|
+
* workflow around them; application code should use {@link RealtimeSessionVerificationService}.
|
|
64
|
+
*/
|
|
65
|
+
export class RuntimeVerificationPorts extends SessionVerificationPortsBase {
|
|
66
|
+
GetSettings() {
|
|
67
|
+
return readSettings();
|
|
68
|
+
}
|
|
69
|
+
async SendEmail(email) {
|
|
70
|
+
const cfg = configInfo.realtime?.identityVerification;
|
|
71
|
+
const user = this.ResolveServiceUser();
|
|
72
|
+
if (!cfg?.communicationProvider || !user) {
|
|
73
|
+
return { Success: false, ErrorMessage: 'No communication provider or service principal is configured.' };
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
const engine = CommunicationEngine.Instance;
|
|
77
|
+
await engine.Config(false, user);
|
|
78
|
+
const message = new Message();
|
|
79
|
+
// Rehearsal mode: the engine builds and LOGS the message but never delivers it (see the config docs).
|
|
80
|
+
message.DryRun = cfg.deliveryMode === 'dry-run';
|
|
81
|
+
message.From = cfg.fromAddress ?? '';
|
|
82
|
+
message.To = email.To;
|
|
83
|
+
message.Subject = email.Subject;
|
|
84
|
+
message.Body = email.Text;
|
|
85
|
+
message.HTMLBody = email.Html;
|
|
86
|
+
const result = await engine.SendSingleMessage(cfg.communicationProvider, 'Email', message);
|
|
87
|
+
return result?.Success ? { Success: true } : { Success: false, ErrorMessage: result?.Error ?? 'unknown provider error' };
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
return { Success: false, ErrorMessage: error instanceof Error ? error.message : String(error) };
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/** The configured service principal (see {@link SessionVerificationPortsBase}). */
|
|
94
|
+
ResolveServiceUser() {
|
|
95
|
+
const configured = configInfo.realtime?.identityVerification?.contextUserForVerification;
|
|
96
|
+
return ResolveConfiguredPrincipal(configured, PRINCIPAL_PURPOSE) ?? UserCache.Instance.GetSystemUser() ?? null;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* The process-wide verification service. Call it from the `RealtimeSessionVerificationResolver`
|
|
101
|
+
* (authenticated principal) and the public `/realtime/verify` router (link capability).
|
|
102
|
+
*/
|
|
103
|
+
export class RealtimeSessionVerificationService extends BaseSingleton {
|
|
104
|
+
constructor() {
|
|
105
|
+
super();
|
|
106
|
+
}
|
|
107
|
+
/** The process-wide instance. */
|
|
108
|
+
static get Instance() {
|
|
109
|
+
return super.getInstance();
|
|
110
|
+
}
|
|
111
|
+
/** Whether verification is switched on and able to send mail. */
|
|
112
|
+
get IsEnabled() {
|
|
113
|
+
return readSettings().Enabled;
|
|
114
|
+
}
|
|
115
|
+
/** See {@link RealtimeSessionVerificationWorkflow.RequestVerification}. */
|
|
116
|
+
RequestVerification(input, caller) {
|
|
117
|
+
return this.getWorkflow().RequestVerification(input, caller);
|
|
118
|
+
}
|
|
119
|
+
/** See {@link RealtimeSessionVerificationWorkflow.SubmitCode}. */
|
|
120
|
+
SubmitCode(input, caller) {
|
|
121
|
+
return this.getWorkflow().SubmitCode(input, caller);
|
|
122
|
+
}
|
|
123
|
+
/** See {@link RealtimeSessionVerificationWorkflow.RedeemLink}. */
|
|
124
|
+
RedeemLink(token, clientIp) {
|
|
125
|
+
return this.getWorkflow().RedeemLink(token, { Kind: 'link', ClientIp: clientIp });
|
|
126
|
+
}
|
|
127
|
+
/** See {@link RealtimeSessionVerificationWorkflow.GetStatus}. */
|
|
128
|
+
GetStatus(input, caller) {
|
|
129
|
+
return this.getWorkflow().GetStatus(input, caller);
|
|
130
|
+
}
|
|
131
|
+
/** The workflow is created on first use so its limiters pick up the loaded config. */
|
|
132
|
+
getWorkflow() {
|
|
133
|
+
if (!this.workflow) {
|
|
134
|
+
this.workflow = new RealtimeSessionVerificationWorkflow(new RuntimeVerificationPorts());
|
|
135
|
+
}
|
|
136
|
+
return this.workflow;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=RealtimeSessionVerificationService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RealtimeSessionVerificationService.js","sourceRoot":"","sources":["../../src/realtimeSessions/RealtimeSessionVerificationService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview The PUBLIC verify-link routes of mid-session identity verification.
|
|
3
|
+
*
|
|
4
|
+
* Mounted BEFORE the unified auth middleware (the person opening the emailed link — often on another
|
|
5
|
+
* device — holds no MJ token; the single-use token IS the capability).
|
|
6
|
+
*
|
|
7
|
+
* | Route | Effect |
|
|
8
|
+
* |---|---|
|
|
9
|
+
* | `GET /realtime/verify/:token` | Renders a one-button confirmation page. **No side effects.** |
|
|
10
|
+
* | `POST /realtime/verify` (form field `token`) | Redeems the token; renders "You're verified" or the uniform failure page. |
|
|
11
|
+
*
|
|
12
|
+
* ## Why the redemption is a POST
|
|
13
|
+
*
|
|
14
|
+
* Mail scanners and link previewers GET every URL in a message. A GET that consumed the single-use token
|
|
15
|
+
* would let a scanner burn it before the human clicks. The magic-link redeem endpoint made the same
|
|
16
|
+
* choice. The human's click submits the form.
|
|
17
|
+
*
|
|
18
|
+
* ## What the responses reveal
|
|
19
|
+
*
|
|
20
|
+
* Nothing about any session. A malformed token, an unknown session, an expired link, a used link and a
|
|
21
|
+
* voided verification all render the SAME page with the SAME status; success is a bare "You're verified".
|
|
22
|
+
* Responses are `no-store`, never framed, sent with `Referrer-Policy: no-referrer` (the token is in the
|
|
23
|
+
* URL of the GET), and carry a CSP that forbids everything but the page's own inline style.
|
|
24
|
+
*
|
|
25
|
+
* @module @memberjunction/server/realtimeSessions
|
|
26
|
+
*/
|
|
27
|
+
import { Router } from 'express';
|
|
28
|
+
import { RealtimeSessionVerificationService } from './RealtimeSessionVerificationService.js';
|
|
29
|
+
/** Mount path of the public verify routes. Under `/realtime`, which is already reserved against server extensions. */
|
|
30
|
+
export declare const REALTIME_VERIFY_MOUNT_PATH = "/realtime/verify";
|
|
31
|
+
/**
|
|
32
|
+
* Builds the public verify router. Mount at {@link REALTIME_VERIFY_MOUNT_PATH} BEFORE the auth
|
|
33
|
+
* middleware.
|
|
34
|
+
*
|
|
35
|
+
* @param service - the verification service (injectable for tests; defaults to the process singleton)
|
|
36
|
+
*/
|
|
37
|
+
export declare function CreateRealtimeVerifyRouter(service?: Pick<RealtimeSessionVerificationService, 'RedeemLink'>): Router;
|
|
38
|
+
//# sourceMappingURL=RealtimeVerifyRouter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RealtimeVerifyRouter.d.ts","sourceRoot":"","sources":["../../src/realtimeSessions/RealtimeVerifyRouter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,MAAM,EAA2C,MAAM,SAAS,CAAC;AAI1E,OAAO,EAAE,kCAAkC,EAAE,MAAM,yCAAyC,CAAC;AAI7F,sHAAsH;AACtH,eAAO,MAAM,0BAA0B,qBAAqB,CAAC;AAoB7D;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACtC,OAAO,GAAE,IAAI,CAAC,kCAAkC,EAAE,YAAY,CAA+C,GAC9G,MAAM,CA4CR"}
|