@memberjunction/server 6.2.0-edge.3 → 6.2.0-edge.4
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/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 +173 -25
- package/dist/agentSessions/SessionJanitor.d.ts.map +1 -1
- package/dist/agentSessions/SessionJanitor.js +452 -54
- package/dist/agentSessions/SessionJanitor.js.map +1 -1
- package/dist/agentSessions/SessionManager.d.ts +43 -2
- package/dist/agentSessions/SessionManager.d.ts.map +1 -1
- package/dist/agentSessions/SessionManager.js +99 -8
- 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/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.map +1 -1
- package/dist/auth/index.js +3 -10
- package/dist/auth/index.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 +2378 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +123 -0
- 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/generated/graphql-schemas/__mj.d.ts +135 -0
- package/dist/generated/graphql-schemas/__mj.d.ts.map +1 -1
- package/dist/generated/graphql-schemas/__mj.js +706 -0
- package/dist/generated/graphql-schemas/__mj.js.map +1 -1
- package/dist/generic/OrphanedConversationDetailReconciler.js +3 -3
- package/dist/generic/OrphanedConversationDetailReconciler.js.map +1 -1
- package/dist/generic/ResolverBase.d.ts +20 -4
- package/dist/generic/ResolverBase.d.ts.map +1 -1
- package/dist/generic/ResolverBase.js +39 -10
- package/dist/generic/ResolverBase.js.map +1 -1
- package/dist/generic/RunViewResolver.d.ts.map +1 -1
- package/dist/generic/RunViewResolver.js +4 -0
- package/dist/generic/RunViewResolver.js.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +120 -131
- 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/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 +138 -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 +98 -0
- package/dist/realtimeSessions/RealtimeVerifyRouter.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 +17 -0
- package/dist/realtimeSessions/index.d.ts.map +1 -0
- package/dist/realtimeSessions/index.js +17 -0
- package/dist/realtimeSessions/index.js.map +1 -0
- package/dist/realtimeSessions/sessionAccess.d.ts +86 -0
- package/dist/realtimeSessions/sessionAccess.d.ts.map +1 -0
- package/dist/realtimeSessions/sessionAccess.js +90 -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/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/FetchEntityVectorsResolver.d.ts +12 -1
- package/dist/resolvers/FetchEntityVectorsResolver.d.ts.map +1 -1
- package/dist/resolvers/FetchEntityVectorsResolver.js +83 -2
- package/dist/resolvers/FetchEntityVectorsResolver.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/MCPResolver.d.ts.map +1 -1
- package/dist/resolvers/MCPResolver.js +9 -4
- package/dist/resolvers/MCPResolver.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 +155 -25
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.js +394 -90
- 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 +68 -11
- 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/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/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/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/services/TaskGraphContinuationDeliverer.d.ts +4 -3
- package/dist/services/TaskGraphContinuationDeliverer.d.ts.map +1 -1
- package/dist/services/TaskGraphContinuationDeliverer.js +13 -7
- 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 +276 -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 +97 -95
- 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__/FetchEntityVectorsResolver.test.ts +285 -0
- package/src/__tests__/HostInstance.test.ts +84 -0
- package/src/__tests__/HumanHandoffResolver.test.ts +17 -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__/RemoteBrowserActionResolver.goalRunLink.test.ts +129 -0
- package/src/__tests__/ResolverBase.aggregateScreen.test.ts +174 -0
- package/src/__tests__/ResolverBase.clientOldValues.test.ts +6 -3
- package/src/__tests__/ReturningVisitorRecap.test.ts +115 -0
- package/src/__tests__/RunAIAgentResolver.branch.test.ts +169 -0
- package/src/__tests__/RunAIAgentResolver.historyFrom.test.ts +4 -4
- 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__/SessionJanitor.test.ts +845 -18
- package/src/__tests__/SessionManager.test.ts +213 -17
- package/src/__tests__/SessionRunIDVerifier.test.ts +251 -0
- package/src/__tests__/SyncRolesUsersResolver.userRoles.test.ts +97 -0
- package/src/__tests__/TaskGraphContinuationDeliverer.test.ts +50 -3
- package/src/__tests__/UserAvatarResolver.test.ts +255 -0
- package/src/__tests__/UserResolver.currentUser.test.ts +16 -1
- package/src/__tests__/actionAuthorization.test.ts +130 -0
- package/src/__tests__/agentVisionConsentAudit.test.ts +118 -0
- package/src/__tests__/avatarInputValidation.test.ts +160 -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__/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__/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__/serverExtensionReservedRoots.test.ts +2 -0
- package/src/__tests__/sharedCache.test.ts +310 -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 +543 -57
- package/src/agentSessions/SessionManager.ts +125 -25
- package/src/agentSessions/SessionRunIDVerifier.ts +171 -0
- package/src/agentSessions/index.ts +10 -3
- package/src/auth/actionAuthorization.ts +116 -0
- package/src/auth/index.ts +3 -8
- package/src/auth/magicLink/MagicLinkService.ts +6 -3
- package/src/auth/newUsers.ts +99 -11
- package/src/config.ts +125 -0
- package/src/context.ts +15 -10
- package/src/generated/graphql-schemas/__mj.ts +496 -1
- package/src/generic/OrphanedConversationDetailReconciler.ts +3 -3
- package/src/generic/ResolverBase.ts +39 -9
- package/src/generic/RunViewResolver.ts +4 -0
- package/src/index.ts +132 -143
- package/src/isolatedProvider.ts +22 -0
- 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 +167 -0
- package/src/realtimeSessions/RealtimeVerifyRouter.ts +108 -0
- package/src/realtimeSessions/SessionVerificationPortsBase.ts +189 -0
- package/src/realtimeSessions/SlidingWindowRateLimiter.ts +92 -0
- package/src/realtimeSessions/index.ts +16 -0
- package/src/realtimeSessions/sessionAccess.ts +141 -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/CacheStatsResolver.ts +89 -2
- package/src/resolvers/ClientToolRequestResolver.ts +25 -7
- package/src/resolvers/FetchEntityVectorsResolver.ts +97 -2
- package/src/resolvers/HumanHandoffResolver.ts +8 -0
- package/src/resolvers/MCPResolver.ts +8 -5
- package/src/resolvers/RealtimeBridgeResolver.ts +163 -11
- package/src/resolvers/RealtimeClientSessionResolver.ts +501 -96
- 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 +78 -11
- package/src/resolvers/RunTemplateResolver.ts +13 -12
- package/src/resolvers/SyncDataResolver.ts +6 -2
- package/src/resolvers/SyncRolesUsersResolver.ts +24 -6
- package/src/resolvers/UserAvatarResolver.ts +111 -0
- package/src/resolvers/UserResolver.ts +2 -16
- 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/services/TaskGraphContinuationDeliverer.ts +13 -7
- package/src/sharedCache.ts +302 -0
- package/src/types.ts +7 -0
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview The orchestration of mid-session identity verification, written against **ports** so the
|
|
3
|
+
* whole policy surface (every refusal, every limit, deadline extension, single use) is unit-testable
|
|
4
|
+
* without a database, a mail server or a PubSub.
|
|
5
|
+
*
|
|
6
|
+
* {@link RealtimeSessionVerificationWorkflow} owns the decisions and their order; the injected
|
|
7
|
+
* {@link VerificationPorts} own the side effects (read the session, write its `Config`, send the email,
|
|
8
|
+
* publish the event, write the audit row). `RealtimeSessionVerificationService` wires the real ports.
|
|
9
|
+
*
|
|
10
|
+
* ## Operations
|
|
11
|
+
*
|
|
12
|
+
* | Operation | Caller | What it does |
|
|
13
|
+
* |---|---|---|
|
|
14
|
+
* | {@link RealtimeSessionVerificationWorkflow.RequestVerification} | the session's own principal | validates, applies policy + limits, stores a pending verification, emails link + code |
|
|
15
|
+
* | {@link RealtimeSessionVerificationWorkflow.SubmitCode} | the session's own principal | redeems the typed code |
|
|
16
|
+
* | {@link RealtimeSessionVerificationWorkflow.RedeemLink} | anyone holding the emailed link (public route) | redeems the link token |
|
|
17
|
+
* | {@link RealtimeSessionVerificationWorkflow.GetStatus} | the session's own principal | reads the current state (the durable backstop for a missed event) |
|
|
18
|
+
*
|
|
19
|
+
* ## What a successful verification does — and does not do
|
|
20
|
+
*
|
|
21
|
+
* It records the verified identity on the session, **extends the session's deadline** when policy says
|
|
22
|
+
* to, publishes `identity.verified`, and writes an audit entry. It does **not** create an MJ user, swap
|
|
23
|
+
* the session's principal, or link a Person/User: the principal never changes, so ownership and
|
|
24
|
+
* row-level security are untouched. Linking the verified email to a record is an application decision,
|
|
25
|
+
* made by a server-side subscriber to the event.
|
|
26
|
+
*
|
|
27
|
+
* ## Concurrency
|
|
28
|
+
*
|
|
29
|
+
* Operations on one session are serialised in-process (a per-session mutex) so two simultaneous
|
|
30
|
+
* redemptions cannot both pass, and every write re-reads the session's current state first. Across
|
|
31
|
+
* *replicas* the database offers no compare-and-swap on `Config`, so strict single-use and attempt
|
|
32
|
+
* counting are exact per instance and best-effort across them: the worst a cross-replica race can do is
|
|
33
|
+
* let two simultaneous redemptions of the same valid secret both succeed (they converge on the same
|
|
34
|
+
* verified identity) or let a burst of parallel guesses count as one attempt. The per-session attempt
|
|
35
|
+
* rate limiter and the code's 6-digit space bound the latter.
|
|
36
|
+
*
|
|
37
|
+
* @module @memberjunction/server/realtimeSessions
|
|
38
|
+
*/
|
|
39
|
+
import { LogError, LogStatus } from '@memberjunction/core';
|
|
40
|
+
import { IsValidUUID } from '@memberjunction/global';
|
|
41
|
+
import { AuthorizeSessionAccess } from './sessionAccess.js';
|
|
42
|
+
import { SlidingWindowRateLimiter } from './SlidingWindowRateLimiter.js';
|
|
43
|
+
import { EvaluateEmailDomainPolicy, ParseEmailAddress, ReadIdentityVerificationPolicyLayer, ResolveIdentityVerificationPolicy, } from './verificationPolicy.js';
|
|
44
|
+
import { ComputeVerifiedDeadline, EvaluateRedemption, IssueVerification, NormalizeVerificationCode, ParseConfigObject, ParseVerificationToken, ReadIdentityVerificationState, SanitizeVerificationName, WriteIdentityVerificationState, } from './verificationCore.js';
|
|
45
|
+
import { BuildVerificationEmail } from './verificationPages.js';
|
|
46
|
+
/** Builds a failure result. */
|
|
47
|
+
function failure(code, message, extra = {}) {
|
|
48
|
+
return { Success: false, VerificationState: 'unverified', ErrorCode: code, Message: message, ...extra };
|
|
49
|
+
}
|
|
50
|
+
/** Result for a session that is already verified (idempotent success). */
|
|
51
|
+
function alreadyVerified(state) {
|
|
52
|
+
return {
|
|
53
|
+
Success: true,
|
|
54
|
+
VerificationState: 'verified',
|
|
55
|
+
VerifiedEmail: state.Verified?.Email,
|
|
56
|
+
VerifiedAt: state.Verified?.VerifiedAt,
|
|
57
|
+
Message: 'Your email is already verified.',
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
const SESSION_NOT_FOUND = 'Session not found.';
|
|
61
|
+
const UNAVAILABLE = 'Email verification is not available.';
|
|
62
|
+
/**
|
|
63
|
+
* The decisions and their order. See the module header for the contract.
|
|
64
|
+
*/
|
|
65
|
+
export class RealtimeSessionVerificationWorkflow {
|
|
66
|
+
constructor(ports) {
|
|
67
|
+
this.ports = ports;
|
|
68
|
+
this.locks = new Map();
|
|
69
|
+
const limits = ports.GetSettings().RateLimits;
|
|
70
|
+
this.ipLimiter = new SlidingWindowRateLimiter({ Limit: limits.PerIpSends, WindowMs: limits.SendWindowMs });
|
|
71
|
+
this.domainLimiter = new SlidingWindowRateLimiter({ Limit: limits.PerEmailDomainSends, WindowMs: limits.SendWindowMs });
|
|
72
|
+
this.emailLimiter = new SlidingWindowRateLimiter({ Limit: limits.PerEmailSends, WindowMs: limits.SendWindowMs });
|
|
73
|
+
this.codeLimiter = new SlidingWindowRateLimiter({ Limit: limits.PerSessionCodeAttempts, WindowMs: limits.CodeAttemptWindowMs });
|
|
74
|
+
}
|
|
75
|
+
/** Whether the feature is switched on. */
|
|
76
|
+
get IsEnabled() {
|
|
77
|
+
return this.ports.GetSettings().Enabled;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Asks to verify `Email` for the caller's session: validates, applies policy and limits, stores a
|
|
81
|
+
* pending verification (hashes only) and emails a one-time link plus a typed code.
|
|
82
|
+
*
|
|
83
|
+
* Nothing is consumed unless the email is actually sent: a delivery failure rolls the stored state back.
|
|
84
|
+
*/
|
|
85
|
+
async RequestVerification(input, caller) {
|
|
86
|
+
const settings = this.ports.GetSettings();
|
|
87
|
+
if (!settings.Enabled || !settings.PublicBaseUrl) {
|
|
88
|
+
return failure('verification_unavailable', UNAVAILABLE);
|
|
89
|
+
}
|
|
90
|
+
const name = SanitizeVerificationName(input.Name);
|
|
91
|
+
if (!name) {
|
|
92
|
+
return failure('invalid_input', 'Please enter your name.');
|
|
93
|
+
}
|
|
94
|
+
const email = ParseEmailAddress(input.Email);
|
|
95
|
+
if (!email.Ok) {
|
|
96
|
+
return failure('invalid_email', 'Please enter a valid email address.');
|
|
97
|
+
}
|
|
98
|
+
return this.withSessionLock(input.AgentSessionID, async () => {
|
|
99
|
+
const access = await this.authorize(input.AgentSessionID, caller, false);
|
|
100
|
+
if (access.Ok === false) {
|
|
101
|
+
return access.Result;
|
|
102
|
+
}
|
|
103
|
+
const state = ReadIdentityVerificationState(access.Session.ConfigRaw, ReadIdentityVerificationPolicyLayer);
|
|
104
|
+
if (state.Verified) {
|
|
105
|
+
return alreadyVerified(state);
|
|
106
|
+
}
|
|
107
|
+
const policy = ResolveIdentityVerificationPolicy([settings.PolicyDefaults, state.Policy]);
|
|
108
|
+
const refusal = this.checkRequestRefusals(email, state, policy, caller);
|
|
109
|
+
return refusal ?? this.issueAndSend(access.Session, { Email: email.Email, Name: name }, policy, caller, settings);
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Redeems the typed code for the caller's session. Wrong entries are counted against the pending
|
|
114
|
+
* verification and void it at `maxCodeAttempts`; submissions are also rate limited per session.
|
|
115
|
+
*/
|
|
116
|
+
async SubmitCode(input, caller) {
|
|
117
|
+
const settings = this.ports.GetSettings();
|
|
118
|
+
if (!settings.Enabled) {
|
|
119
|
+
return failure('verification_unavailable', UNAVAILABLE);
|
|
120
|
+
}
|
|
121
|
+
if (!IsValidUUID(input.AgentSessionID)) {
|
|
122
|
+
return failure('session_not_found', SESSION_NOT_FOUND);
|
|
123
|
+
}
|
|
124
|
+
const gate = this.codeLimiter.TryConsume(input.AgentSessionID.toLowerCase(), this.ports.Now());
|
|
125
|
+
if (!gate.Allowed) {
|
|
126
|
+
return failure('rate_limited', 'Too many attempts. Please wait a moment and try again.', {
|
|
127
|
+
RetryAfterSeconds: Math.ceil(gate.RetryAfterMs / 1000),
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
const code = NormalizeVerificationCode(input.Code);
|
|
131
|
+
if (!code) {
|
|
132
|
+
// Cannot match any stored code, so it must not burn the person's attempts either.
|
|
133
|
+
return failure('invalid_code', 'That code is not valid. Check it and try again.');
|
|
134
|
+
}
|
|
135
|
+
return this.withSessionLock(input.AgentSessionID, async () => {
|
|
136
|
+
const access = await this.authorize(input.AgentSessionID, caller, false);
|
|
137
|
+
if (access.Ok === false) {
|
|
138
|
+
return access.Result;
|
|
139
|
+
}
|
|
140
|
+
return this.redeem(input.AgentSessionID, caller, { Kind: 'code', Code: code, AgentSessionID: input.AgentSessionID });
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Redeems an emailed link token. The capability IS the token, so there is no principal; every
|
|
145
|
+
* failure — malformed, unknown, expired, used, voided — is the same result so the response cannot
|
|
146
|
+
* be used to learn anything about a session.
|
|
147
|
+
*/
|
|
148
|
+
async RedeemLink(token, caller) {
|
|
149
|
+
if (!this.ports.GetSettings().Enabled) {
|
|
150
|
+
return failure('verification_unavailable', UNAVAILABLE);
|
|
151
|
+
}
|
|
152
|
+
const parsed = ParseVerificationToken(token);
|
|
153
|
+
if (!parsed) {
|
|
154
|
+
return failure('invalid_link', 'This link is no longer valid.');
|
|
155
|
+
}
|
|
156
|
+
return this.withSessionLock(parsed.AgentSessionID, () => this.redeem(parsed.AgentSessionID, caller, { Kind: 'token', Token: token }));
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Reads the session's verification state. This is the **durable** counterpart of the
|
|
160
|
+
* `identity.verified` event: a subscriber that was disconnected when the event fired recovers by
|
|
161
|
+
* asking here.
|
|
162
|
+
*/
|
|
163
|
+
async GetStatus(input, caller) {
|
|
164
|
+
const settings = this.ports.GetSettings();
|
|
165
|
+
if (!settings.Enabled) {
|
|
166
|
+
return failure('verification_unavailable', UNAVAILABLE);
|
|
167
|
+
}
|
|
168
|
+
const access = await this.authorize(input.AgentSessionID, caller, true);
|
|
169
|
+
if (access.Ok === false) {
|
|
170
|
+
return access.Result;
|
|
171
|
+
}
|
|
172
|
+
const state = ReadIdentityVerificationState(access.Session.ConfigRaw, ReadIdentityVerificationPolicyLayer);
|
|
173
|
+
if (state.Verified) {
|
|
174
|
+
return alreadyVerified(state);
|
|
175
|
+
}
|
|
176
|
+
const policy = ResolveIdentityVerificationPolicy([settings.PolicyDefaults, state.Policy]);
|
|
177
|
+
const pendingLive = state.Pending && Date.parse(state.Pending.ExpiresAt) > this.ports.Now() ? state.Pending : undefined;
|
|
178
|
+
return {
|
|
179
|
+
Success: true,
|
|
180
|
+
VerificationState: pendingLive ? 'pending' : 'unverified',
|
|
181
|
+
ExpiresAt: pendingLive?.ExpiresAt,
|
|
182
|
+
SendsRemaining: Math.max(0, policy.maxSendsPerSession - state.SendCount),
|
|
183
|
+
AttemptsRemaining: pendingLive ? Math.max(0, policy.maxCodeAttempts - pendingLive.CodeAttempts) : undefined,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
// ───────────── request internals ─────────────
|
|
187
|
+
/** The policy and limit refusals of a request, in order; null when the request may proceed. */
|
|
188
|
+
checkRequestRefusals(email, state, policy, caller) {
|
|
189
|
+
const domain = EvaluateEmailDomainPolicy(email.Domain, policy);
|
|
190
|
+
if (domain.Allowed === false) {
|
|
191
|
+
return domain.Reason === 'domain_blocked'
|
|
192
|
+
? failure('domain_blocked', 'Email addresses from that domain cannot be used here.')
|
|
193
|
+
: failure('consumer_domain', 'Please use your work email address.');
|
|
194
|
+
}
|
|
195
|
+
if (state.SendCount >= policy.maxSendsPerSession) {
|
|
196
|
+
return failure('send_limit_reached', 'The maximum number of verification emails for this conversation has been reached.', {
|
|
197
|
+
SendsRemaining: 0,
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
return this.checkSendRateLimits(email, caller.ClientIp);
|
|
201
|
+
}
|
|
202
|
+
/** Applies the per-IP, per-domain and per-address send limits; null when all admit the send. */
|
|
203
|
+
checkSendRateLimits(email, clientIp) {
|
|
204
|
+
const now = this.ports.Now();
|
|
205
|
+
const decisions = [
|
|
206
|
+
clientIp ? this.ipLimiter.TryConsume(clientIp, now) : { Allowed: true, RetryAfterMs: 0 },
|
|
207
|
+
this.domainLimiter.TryConsume(email.Domain, now),
|
|
208
|
+
this.emailLimiter.TryConsume(email.Email, now),
|
|
209
|
+
];
|
|
210
|
+
const refused = decisions.find((decision) => !decision.Allowed);
|
|
211
|
+
if (!refused) {
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
return failure('rate_limited', 'Too many verification requests. Please try again later.', {
|
|
215
|
+
RetryAfterSeconds: Math.ceil(refused.RetryAfterMs / 1000),
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
/** Stores the pending verification, emails it, and rolls the store back if the email cannot be sent. */
|
|
219
|
+
async issueAndSend(session, recipient, policy, caller, settings) {
|
|
220
|
+
const issued = IssueVerification({
|
|
221
|
+
AgentSessionID: session.AgentSessionID,
|
|
222
|
+
Email: recipient.Email,
|
|
223
|
+
Name: recipient.Name,
|
|
224
|
+
TtlMinutes: policy.linkTtlMinutes,
|
|
225
|
+
NowMs: this.ports.Now(),
|
|
226
|
+
CodeHashKey: settings.CodeHashKey,
|
|
227
|
+
});
|
|
228
|
+
const stored = await this.ports.MutateSessionConfig(session.AgentSessionID, caller, (current) => {
|
|
229
|
+
const state = ReadIdentityVerificationState(current.ConfigRaw, ReadIdentityVerificationPolicyLayer);
|
|
230
|
+
if (state.Verified) {
|
|
231
|
+
return { NextConfigRaw: null, Outcome: { Kind: 'already_verified' } };
|
|
232
|
+
}
|
|
233
|
+
if (state.SendCount >= policy.maxSendsPerSession) {
|
|
234
|
+
return { NextConfigRaw: null, Outcome: { Kind: 'send_limit' } };
|
|
235
|
+
}
|
|
236
|
+
const next = { ...state, SendCount: state.SendCount + 1, Pending: issued.Pending };
|
|
237
|
+
return { NextConfigRaw: WriteIdentityVerificationState(current.ConfigRaw, next), Outcome: { Kind: 'stored', SendCount: next.SendCount } };
|
|
238
|
+
});
|
|
239
|
+
const early = this.requestStoreRefusal(stored);
|
|
240
|
+
if (early || stored.Outcome?.Kind !== 'stored') {
|
|
241
|
+
return early ?? failure('persist_failed', 'We could not start verification. Please try again.');
|
|
242
|
+
}
|
|
243
|
+
const email = BuildVerificationEmail({
|
|
244
|
+
Name: recipient.Name,
|
|
245
|
+
Code: issued.Code,
|
|
246
|
+
LinkUrl: `${settings.PublicBaseUrl}/realtime/verify/${issued.Token}`,
|
|
247
|
+
TtlMinutes: policy.linkTtlMinutes,
|
|
248
|
+
});
|
|
249
|
+
const sent = await this.ports.SendEmail({ To: recipient.Email, Subject: email.Subject, Text: email.Text, Html: email.Html });
|
|
250
|
+
if (!sent.Success) {
|
|
251
|
+
LogError(`RealtimeSessionVerification: email to the verifier of session ${session.AgentSessionID} failed: ${sent.ErrorMessage ?? 'unknown error'}`);
|
|
252
|
+
await this.rollbackPending(session.AgentSessionID, caller, issued.Pending.TokenHash);
|
|
253
|
+
return failure('email_send_failed', 'We could not send the email. Please check the address and try again.');
|
|
254
|
+
}
|
|
255
|
+
return {
|
|
256
|
+
Success: true,
|
|
257
|
+
VerificationState: 'pending',
|
|
258
|
+
ExpiresAt: issued.Pending.ExpiresAt,
|
|
259
|
+
SendsRemaining: Math.max(0, policy.maxSendsPerSession - stored.Outcome.SendCount),
|
|
260
|
+
Message: 'We emailed you a link and a code.',
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
/** Maps a failed/short-circuited store into a result; null when the pending verification was stored. */
|
|
264
|
+
requestStoreRefusal(stored) {
|
|
265
|
+
if (stored.Outcome?.Kind === 'already_verified') {
|
|
266
|
+
return { Success: true, VerificationState: 'verified', Message: 'Your email is already verified.' };
|
|
267
|
+
}
|
|
268
|
+
if (stored.Outcome?.Kind === 'send_limit') {
|
|
269
|
+
return failure('send_limit_reached', 'The maximum number of verification emails for this conversation has been reached.', {
|
|
270
|
+
SendsRemaining: 0,
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
if (!stored.Persisted) {
|
|
274
|
+
return failure('persist_failed', 'We could not start verification. Please try again.');
|
|
275
|
+
}
|
|
276
|
+
return null;
|
|
277
|
+
}
|
|
278
|
+
/** Removes the pending verification (and the send it counted) if it is still the one we stored. */
|
|
279
|
+
async rollbackPending(agentSessionId, caller, tokenHash) {
|
|
280
|
+
const result = await this.ports.MutateSessionConfig(agentSessionId, caller, (current) => {
|
|
281
|
+
const state = ReadIdentityVerificationState(current.ConfigRaw, ReadIdentityVerificationPolicyLayer);
|
|
282
|
+
if (state.Pending?.TokenHash !== tokenHash) {
|
|
283
|
+
return { NextConfigRaw: null, Outcome: undefined };
|
|
284
|
+
}
|
|
285
|
+
const { Pending: _dropped, ...rest } = state;
|
|
286
|
+
return { NextConfigRaw: WriteIdentityVerificationState(current.ConfigRaw, { ...rest, SendCount: Math.max(0, state.SendCount - 1) }), Outcome: undefined };
|
|
287
|
+
});
|
|
288
|
+
if (!result.Persisted && result.ErrorMessage) {
|
|
289
|
+
LogError(`RealtimeSessionVerification: could not roll back the pending verification of session ${agentSessionId}: ${result.ErrorMessage}`);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
// ───────────── redemption internals ─────────────
|
|
293
|
+
/**
|
|
294
|
+
* Shared by the code and link paths: re-read the session, decide the redemption on its CURRENT
|
|
295
|
+
* state, persist the resulting state (and the extended deadline on success), and on success
|
|
296
|
+
* publish the event and write the audit entry.
|
|
297
|
+
*/
|
|
298
|
+
async redeem(agentSessionId, caller, credential) {
|
|
299
|
+
const settings = this.ports.GetSettings();
|
|
300
|
+
const nowMs = this.ports.Now();
|
|
301
|
+
const result = await this.ports.MutateSessionConfig(agentSessionId, caller, (current) => {
|
|
302
|
+
const state = ReadIdentityVerificationState(current.ConfigRaw, ReadIdentityVerificationPolicyLayer);
|
|
303
|
+
const policy = ResolveIdentityVerificationPolicy([settings.PolicyDefaults, state.Policy]);
|
|
304
|
+
const decision = EvaluateRedemption(state, credential, nowMs, policy, settings.CodeHashKey);
|
|
305
|
+
const deadlineIso = decision.Outcome === 'verified' && current.Status !== 'Closed'
|
|
306
|
+
? ComputeVerifiedDeadline({
|
|
307
|
+
CurrentDeadlineIso: readDeadline(current.ConfigRaw),
|
|
308
|
+
SessionStartedAtMs: current.StartedAtMs,
|
|
309
|
+
VerifiedMaxSeconds: policy.verifiedMaxSeconds,
|
|
310
|
+
})
|
|
311
|
+
: undefined;
|
|
312
|
+
const changed = decision.Next !== state;
|
|
313
|
+
return {
|
|
314
|
+
NextConfigRaw: changed ? WriteIdentityVerificationState(current.ConfigRaw, decision.Next, deadlineIso) : null,
|
|
315
|
+
Outcome: { Decision: decision, DeadlineIso: deadlineIso },
|
|
316
|
+
};
|
|
317
|
+
});
|
|
318
|
+
if (!result.Session || !result.Outcome) {
|
|
319
|
+
// The session could not be read (or does not exist). For the link that is "invalid"; for the code
|
|
320
|
+
// path the caller was already authorized, so it is a server fault.
|
|
321
|
+
return caller.Kind === 'link'
|
|
322
|
+
? failure('invalid_link', 'This link is no longer valid.')
|
|
323
|
+
: failure('persist_failed', 'We could not check that code. Please try again.');
|
|
324
|
+
}
|
|
325
|
+
const { Decision, DeadlineIso } = result.Outcome;
|
|
326
|
+
if (Decision.Outcome === 'verified') {
|
|
327
|
+
return this.completeVerification(result.Session, result.Persisted, result.ErrorMessage, Decision.Verified, DeadlineIso, caller);
|
|
328
|
+
}
|
|
329
|
+
return this.refusalResult(Decision, caller);
|
|
330
|
+
}
|
|
331
|
+
/** Success path: surface persistence failure, otherwise publish + audit and build the result. */
|
|
332
|
+
async completeVerification(session, persisted, persistError, verified, deadlineIso, caller) {
|
|
333
|
+
if (!persisted) {
|
|
334
|
+
LogError(`RealtimeSessionVerification: verified session ${session.AgentSessionID} but could not persist it: ${persistError ?? 'unknown error'}`);
|
|
335
|
+
return failure('persist_failed', 'We could not record your verification. Please try again.');
|
|
336
|
+
}
|
|
337
|
+
if (session.Status !== 'Closed') {
|
|
338
|
+
this.ports.PublishVerified({ AgentSessionID: session.AgentSessionID, OwnerUserID: session.OwnerUserID, ScopeKey: session.ConversationExternalID }, {
|
|
339
|
+
VerifiedEmail: verified.Email,
|
|
340
|
+
VerifiedName: verified.Name,
|
|
341
|
+
VerifiedAt: verified.VerifiedAt,
|
|
342
|
+
Method: verified.Method,
|
|
343
|
+
MaxSessionDeadlineIso: deadlineIso,
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
await this.ports.WriteAudit({
|
|
347
|
+
AgentSessionID: session.AgentSessionID,
|
|
348
|
+
OwnerUserID: session.OwnerUserID,
|
|
349
|
+
Email: verified.Email,
|
|
350
|
+
Method: verified.Method,
|
|
351
|
+
ClientIp: caller.ClientIp,
|
|
352
|
+
MaxSessionDeadlineIso: deadlineIso,
|
|
353
|
+
});
|
|
354
|
+
LogStatus(`RealtimeSessionVerification: session ${session.AgentSessionID} verified by ${verified.Method}${deadlineIso ? `; deadline extended to ${deadlineIso}` : ''}.`);
|
|
355
|
+
return {
|
|
356
|
+
Success: true,
|
|
357
|
+
VerificationState: 'verified',
|
|
358
|
+
VerifiedEmail: verified.Email,
|
|
359
|
+
VerifiedAt: verified.VerifiedAt,
|
|
360
|
+
MaxSessionDeadlineIso: deadlineIso,
|
|
361
|
+
Message: "You're verified.",
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
/** Maps a rejected redemption to a result (uniform for the link path). */
|
|
365
|
+
refusalResult(decision, caller) {
|
|
366
|
+
if (caller.Kind === 'link') {
|
|
367
|
+
return failure('invalid_link', 'This link is no longer valid.');
|
|
368
|
+
}
|
|
369
|
+
switch (decision.Reason) {
|
|
370
|
+
case 'already_verified':
|
|
371
|
+
return alreadyVerified(decision.Next);
|
|
372
|
+
case 'no_pending':
|
|
373
|
+
return failure('no_pending_verification', 'There is no verification waiting. Request a new email.');
|
|
374
|
+
case 'expired':
|
|
375
|
+
return failure('code_expired', 'That code has expired. Request a new email.');
|
|
376
|
+
case 'attempts_exhausted':
|
|
377
|
+
return failure('attempts_exhausted', 'Too many incorrect codes. Request a new email.', { AttemptsRemaining: 0 });
|
|
378
|
+
case 'invalid':
|
|
379
|
+
default:
|
|
380
|
+
return failure('invalid_code', 'That code is not correct.', { VerificationState: 'pending', AttemptsRemaining: decision.AttemptsRemaining });
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
// ───────────── shared internals ─────────────
|
|
384
|
+
/**
|
|
385
|
+
* Loads the session as the caller and applies {@link AuthorizeSessionAccess}. Not-found and
|
|
386
|
+
* not-yours are the same result so a caller cannot enumerate other people's session ids; the real
|
|
387
|
+
* reason is logged server-side.
|
|
388
|
+
*/
|
|
389
|
+
async authorize(agentSessionId, caller, allowClosed) {
|
|
390
|
+
const notFound = { Ok: false, Result: failure('session_not_found', SESSION_NOT_FOUND) };
|
|
391
|
+
if (!IsValidUUID(agentSessionId)) {
|
|
392
|
+
return notFound;
|
|
393
|
+
}
|
|
394
|
+
const session = await this.ports.LoadSession(agentSessionId, caller);
|
|
395
|
+
if (!session) {
|
|
396
|
+
return notFound;
|
|
397
|
+
}
|
|
398
|
+
const decision = AuthorizeSessionAccess({ SessionUserID: session.OwnerUserID, ConversationExternalID: session.ConversationExternalID }, caller.ContextUser);
|
|
399
|
+
if (decision.Allowed === false) {
|
|
400
|
+
LogError(`RealtimeSessionVerification: refused user ${caller.ContextUser.ID} on session ${agentSessionId} (${decision.Reason}).`);
|
|
401
|
+
return notFound;
|
|
402
|
+
}
|
|
403
|
+
if (!allowClosed && session.Status === 'Closed') {
|
|
404
|
+
return { Ok: false, Result: failure('session_closed', 'This conversation has ended.') };
|
|
405
|
+
}
|
|
406
|
+
return { Ok: true, Session: session };
|
|
407
|
+
}
|
|
408
|
+
/** Serialises operations on one session within this process (see the module header). */
|
|
409
|
+
async withSessionLock(agentSessionId, work) {
|
|
410
|
+
const key = agentSessionId.toLowerCase();
|
|
411
|
+
const previous = this.locks.get(key) ?? Promise.resolve();
|
|
412
|
+
let release = () => undefined;
|
|
413
|
+
const gate = new Promise((resolve) => {
|
|
414
|
+
release = resolve;
|
|
415
|
+
});
|
|
416
|
+
const tail = previous.then(() => gate);
|
|
417
|
+
this.locks.set(key, tail);
|
|
418
|
+
try {
|
|
419
|
+
await previous;
|
|
420
|
+
return await work();
|
|
421
|
+
}
|
|
422
|
+
finally {
|
|
423
|
+
release();
|
|
424
|
+
if (this.locks.get(key) === tail) {
|
|
425
|
+
this.locks.delete(key);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
/** The stored `maxSessionDeadlineIso`, when it is a string. */
|
|
431
|
+
function readDeadline(configRaw) {
|
|
432
|
+
const value = ParseConfigObject(configRaw)['maxSessionDeadlineIso'];
|
|
433
|
+
return typeof value === 'string' ? value : undefined;
|
|
434
|
+
}
|
|
435
|
+
//# sourceMappingURL=verificationWorkflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verificationWorkflow.js","sourceRoot":"","sources":["../../src/realtimeSessions/verificationWorkflow.ts"],"names":[],"mappings":"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"}
|
|
@@ -52,8 +52,10 @@ export declare function resolveWidgetGuestRunContext(userPayload: UserPayload, p
|
|
|
52
52
|
* A scoped anonymous session (`IsMagicLinkAnonymous` + `MagicLinkScope.ResourceID`) holds only the
|
|
53
53
|
* narrow relay grants its invite's role carries — deliberately NOT the AI run entities, whose rows
|
|
54
54
|
* leak the rendered system prompt. Unlike {@link resolveWidgetGuestRunContext} no widget instance is
|
|
55
|
-
* required:
|
|
56
|
-
*
|
|
55
|
+
* required: the realtime target is the session config's `targetAgentID`, which the owner can edit, so
|
|
56
|
+
* the relay re-checks `CanRun` on it for the CALLER before this elevation. Direct actions are refused
|
|
57
|
+
* for these callers before elevation, so only the delegated agent run and the run-entity writes
|
|
58
|
+
* execute as the system user.
|
|
57
59
|
*
|
|
58
60
|
* PUBLIC WEB-WIDGET guests are deliberately EXCLUDED (returned unchanged): their seeded role writes
|
|
59
61
|
* run rows under the guest principal, which the `Widget Guest: Own Agent Runs` RLS read filter
|
|
@@ -66,6 +68,22 @@ export declare function resolveWidgetGuestRunContext(userPayload: UserPayload, p
|
|
|
66
68
|
* work RUNS AS after ownership is proven.
|
|
67
69
|
*/
|
|
68
70
|
export declare function ResolveScopedAnonymousRunUser(contextUser: UserInfo): UserInfo;
|
|
71
|
+
/**
|
|
72
|
+
* The principal a client-direct call's consolidated RECORDING STORE runs as, once the caller has
|
|
73
|
+
* already passed the session-ownership and consent gates (#5195).
|
|
74
|
+
*
|
|
75
|
+
* The store writes `MJ: Files`, the file↔session link and the session's recording stamp — server
|
|
76
|
+
* plumbing attributed through the session link, never through the caller. A signed-in user whose only
|
|
77
|
+
* role is the stock UI role cannot create `MJ: Files`, so running the store as the caller lost every
|
|
78
|
+
* such user's recording (the object landed in storage, the row never did). It therefore runs as the
|
|
79
|
+
* system user for signed-in owners, and anonymous sessions keep exactly the
|
|
80
|
+
* {@link ResolveScopedAnonymousRunUser} behaviour (PUBLIC WEB-WIDGET guests stay on the caller for the
|
|
81
|
+
* same RLS reason documented there).
|
|
82
|
+
*
|
|
83
|
+
* Fails CLOSED: with no system user available the caller is returned, i.e. today's behaviour.
|
|
84
|
+
* Ownership/consent gates must NEVER use this.
|
|
85
|
+
*/
|
|
86
|
+
export declare function ResolveRecordingStoreUser(contextUser: UserInfo): UserInfo;
|
|
69
87
|
/**
|
|
70
88
|
* Builds an elevated {@link UserPayload} that runs subsequent agent work as `elevatedUser` while
|
|
71
89
|
* preserving the guest's `sessionId` — so progress/streaming PubSub still routes to the guest's
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"widgetGuestElevation.d.ts","sourceRoot":"","sources":["../../src/realtimeWidget/widgetGuestElevation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAqB,KAAK,QAAQ,EAAE,KAAK,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACnG,OAAO,KAAK,EAAE,kCAAkC,EAAE,MAAM,+BAA+B,CAAC;AAExF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAI/C;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB;IACpC,mGAAmG;IACnG,YAAY,EAAE,QAAQ,CAAC;IACvB,gFAAgF;IAChF,MAAM,EAAE,kCAAkC,CAAC;IAC3C,+FAA+F;IAC/F,aAAa,EAAE,MAAM,CAAC;IACtB,2GAA2G;IAC3G,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;GASG;AACH,wBAAsB,4BAA4B,CAChD,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,oBAAoB,GAC7B,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAyBvC;AAED,4DAA4D;AAC5D,wBAAsB,4BAA4B,CAChD,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,oBAAoB,GAC7B,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAEvC;AAED
|
|
1
|
+
{"version":3,"file":"widgetGuestElevation.d.ts","sourceRoot":"","sources":["../../src/realtimeWidget/widgetGuestElevation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAqB,KAAK,QAAQ,EAAE,KAAK,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACnG,OAAO,KAAK,EAAE,kCAAkC,EAAE,MAAM,+BAA+B,CAAC;AAExF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAI/C;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB;IACpC,mGAAmG;IACnG,YAAY,EAAE,QAAQ,CAAC;IACvB,gFAAgF;IAChF,MAAM,EAAE,kCAAkC,CAAC;IAC3C,+FAA+F;IAC/F,aAAa,EAAE,MAAM,CAAC;IACtB,2GAA2G;IAC3G,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;GASG;AACH,wBAAsB,4BAA4B,CAChD,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,oBAAoB,GAC7B,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAyBvC;AAED,4DAA4D;AAC5D,wBAAsB,4BAA4B,CAChD,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,oBAAoB,GAC7B,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAEvC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,6BAA6B,CAAC,WAAW,EAAE,QAAQ,GAAG,QAAQ,CAkB7E;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,QAAQ,GAAG,QAAQ,CAazE;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,GAAG,WAAW,CAOhG;AAED,kDAAkD;AAClD,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,GAAG,WAAW,CAEhG"}
|
|
@@ -60,8 +60,10 @@ export async function resolveWidgetGuestRunContext(userPayload, provider) {
|
|
|
60
60
|
* A scoped anonymous session (`IsMagicLinkAnonymous` + `MagicLinkScope.ResourceID`) holds only the
|
|
61
61
|
* narrow relay grants its invite's role carries — deliberately NOT the AI run entities, whose rows
|
|
62
62
|
* leak the rendered system prompt. Unlike {@link resolveWidgetGuestRunContext} no widget instance is
|
|
63
|
-
* required:
|
|
64
|
-
*
|
|
63
|
+
* required: the realtime target is the session config's `targetAgentID`, which the owner can edit, so
|
|
64
|
+
* the relay re-checks `CanRun` on it for the CALLER before this elevation. Direct actions are refused
|
|
65
|
+
* for these callers before elevation, so only the delegated agent run and the run-entity writes
|
|
66
|
+
* execute as the system user.
|
|
65
67
|
*
|
|
66
68
|
* PUBLIC WEB-WIDGET guests are deliberately EXCLUDED (returned unchanged): their seeded role writes
|
|
67
69
|
* run rows under the guest principal, which the `Widget Guest: Own Agent Runs` RLS read filter
|
|
@@ -88,6 +90,33 @@ export function ResolveScopedAnonymousRunUser(contextUser) {
|
|
|
88
90
|
// per-call log line would flood a live session's log. The dispatch path logs the elevation once.
|
|
89
91
|
return systemUser;
|
|
90
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* The principal a client-direct call's consolidated RECORDING STORE runs as, once the caller has
|
|
95
|
+
* already passed the session-ownership and consent gates (#5195).
|
|
96
|
+
*
|
|
97
|
+
* The store writes `MJ: Files`, the file↔session link and the session's recording stamp — server
|
|
98
|
+
* plumbing attributed through the session link, never through the caller. A signed-in user whose only
|
|
99
|
+
* role is the stock UI role cannot create `MJ: Files`, so running the store as the caller lost every
|
|
100
|
+
* such user's recording (the object landed in storage, the row never did). It therefore runs as the
|
|
101
|
+
* system user for signed-in owners, and anonymous sessions keep exactly the
|
|
102
|
+
* {@link ResolveScopedAnonymousRunUser} behaviour (PUBLIC WEB-WIDGET guests stay on the caller for the
|
|
103
|
+
* same RLS reason documented there).
|
|
104
|
+
*
|
|
105
|
+
* Fails CLOSED: with no system user available the caller is returned, i.e. today's behaviour.
|
|
106
|
+
* Ownership/consent gates must NEVER use this.
|
|
107
|
+
*/
|
|
108
|
+
export function ResolveRecordingStoreUser(contextUser) {
|
|
109
|
+
if (contextUser?.IsMagicLinkAnonymous || contextUser?.WidgetGuestContext?.WidgetID) {
|
|
110
|
+
return ResolveScopedAnonymousRunUser(contextUser);
|
|
111
|
+
}
|
|
112
|
+
const systemUser = UserCache.Instance.GetSystemUser();
|
|
113
|
+
if (!systemUser) {
|
|
114
|
+
LogError(`[Realtime] Cannot elevate the recording store for user ${contextUser?.ID}: no system user available; ` +
|
|
115
|
+
'storing as the caller.');
|
|
116
|
+
return contextUser;
|
|
117
|
+
}
|
|
118
|
+
return systemUser;
|
|
119
|
+
}
|
|
91
120
|
/**
|
|
92
121
|
* Builds an elevated {@link UserPayload} that runs subsequent agent work as `elevatedUser` while
|
|
93
122
|
* preserving the guest's `sessionId` — so progress/streaming PubSub still routes to the guest's
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"widgetGuestElevation.js","sourceRoot":"","sources":["../../src/realtimeWidget/widgetGuestElevation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,OAAO,EAAE,QAAQ,EAA4C,MAAM,sBAAsB,CAAC;AAEnG,OAAO,EAAE,SAAS,EAAE,MAAM,2CAA2C,CAAC;AAGtE,MAAM,aAAa,GAAG,mCAAmC,CAAC;AAmB1D;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAChD,WAAwB,EACxB,QAA8B;IAE9B,MAAM,KAAK,GAAG,WAAW,EAAE,UAAkC,CAAC;IAC9D,MAAM,QAAQ,GAAG,KAAK,EAAE,kBAAkB,EAAE,QAAQ,CAAC;IACrD,IAAI,CAAC,KAAK,EAAE,oBAAoB,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,YAAY,GAAG,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC;IACxD,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,QAAQ,CAAC,2EAA2E,CAAC,CAAC;QACtF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,QAAQ,EAAE,YAAY,EAAE,QAAQ,CAAC,CAAC;IACtE,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,QAAQ,CAAC,4BAA4B,QAAQ,mDAAmD,CAAC,CAAC;QAClG,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO;QACL,YAAY,EAAE,YAAY;QAC1B,MAAM,EAAE,MAAM;QACd,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,cAAc,EAAE,KAAK,CAAC,cAAc,EAAE,UAAU;KACjD,CAAC;AACJ,CAAC;AAED,4DAA4D;AAC5D,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAChD,WAAwB,EACxB,QAA8B;IAE9B,OAAO,4BAA4B,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;AAC7D,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"widgetGuestElevation.js","sourceRoot":"","sources":["../../src/realtimeWidget/widgetGuestElevation.ts"],"names":[],"mappings":"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"}
|
|
@@ -34,8 +34,8 @@ export declare class RunActionInput {
|
|
|
34
34
|
*/
|
|
35
35
|
Params?: ActionParamInput[];
|
|
36
36
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
37
|
+
* Ignored. A run started through this API always writes an action execution log row; the field
|
|
38
|
+
* remains so that clients which send it still validate.
|
|
39
39
|
*/
|
|
40
40
|
SkipActionLog?: boolean;
|
|
41
41
|
}
|
|
@@ -121,12 +121,39 @@ export declare class ActionResultOutput {
|
|
|
121
121
|
*/
|
|
122
122
|
export declare class ActionResolver extends ResolverBase {
|
|
123
123
|
/**
|
|
124
|
-
* Mutation for running an action
|
|
124
|
+
* Mutation for running an action.
|
|
125
|
+
*
|
|
126
|
+
* Scope-limited sessions are refused. Any other caller must be authorized for the action — see
|
|
127
|
+
* {@link EvaluateActionRunAuthorization}: an Owner may run any action; anyone else needs a role that
|
|
128
|
+
* holds an authorization linked to the action through `MJ: Action Authorizations`, or, when the
|
|
129
|
+
* action has no such link, an action class that authorizes its caller itself. The run is always
|
|
130
|
+
* logged.
|
|
125
131
|
* @param input The input parameters for running the action
|
|
126
132
|
* @param ctx The GraphQL context containing user authentication information
|
|
127
133
|
* @returns The result of running the action
|
|
128
134
|
*/
|
|
129
135
|
RunAction(input: RunActionInput, ctx: AppContext): Promise<ActionResultOutput>;
|
|
136
|
+
/**
|
|
137
|
+
* The authenticated caller of RunAction. A scope-limited session is refused: its confinement exists
|
|
138
|
+
* only as row-level-security filters, and an action can reach data and services those filters never
|
|
139
|
+
* cover.
|
|
140
|
+
* @throws Error when there is no user or the session is scope-limited
|
|
141
|
+
*/
|
|
142
|
+
private getRunActionPrincipal;
|
|
143
|
+
/**
|
|
144
|
+
* Refuses the run unless the caller is authorized for the action — see
|
|
145
|
+
* {@link EvaluateActionRunAuthorization}. The `MJ: Action Authorizations` rows, the authorization
|
|
146
|
+
* tree and the role grants all come from the request's provider, or all from the global provider
|
|
147
|
+
* when the request carries none.
|
|
148
|
+
* @throws Error when the caller may not run the action
|
|
149
|
+
*/
|
|
150
|
+
private assertCanRunAction;
|
|
151
|
+
/**
|
|
152
|
+
* The AuthorizationID of each `MJ: Action Authorizations` row for the action. Read as the system
|
|
153
|
+
* user: this is the server's own authorization decision, so it must not depend on whether the
|
|
154
|
+
* caller can read that entity.
|
|
155
|
+
*/
|
|
156
|
+
private loadActionAuthorizationIDs;
|
|
130
157
|
/**
|
|
131
158
|
* Finds an action by its ID
|
|
132
159
|
* @param actionID The ID of the action to find
|
|
@@ -143,11 +170,10 @@ export declare class ActionResolver extends ResolverBase {
|
|
|
143
170
|
*/
|
|
144
171
|
private parseActionParameters;
|
|
145
172
|
/**
|
|
146
|
-
* Executes an action
|
|
173
|
+
* Executes an action. The run is always logged: a client cannot switch off the action execution log.
|
|
147
174
|
* @param action The action to execute
|
|
148
175
|
* @param user The user context
|
|
149
176
|
* @param params The action parameters
|
|
150
|
-
* @param skipActionLog Whether to skip action logging
|
|
151
177
|
* @returns The action result
|
|
152
178
|
* @private
|
|
153
179
|
*/
|