@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.
Files changed (543) hide show
  1. package/README.md +20 -0
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/agentSessions/BridgeHostInstance.d.ts +25 -0
  4. package/dist/agentSessions/BridgeHostInstance.d.ts.map +1 -0
  5. package/dist/agentSessions/BridgeHostInstance.js +30 -0
  6. package/dist/agentSessions/BridgeHostInstance.js.map +1 -0
  7. package/dist/agentSessions/HostInstance.d.ts +75 -11
  8. package/dist/agentSessions/HostInstance.d.ts.map +1 -1
  9. package/dist/agentSessions/HostInstance.js +99 -28
  10. package/dist/agentSessions/HostInstance.js.map +1 -1
  11. package/dist/agentSessions/ReturningVisitorRecap.d.ts.map +1 -1
  12. package/dist/agentSessions/ReturningVisitorRecap.js +7 -3
  13. package/dist/agentSessions/ReturningVisitorRecap.js.map +1 -1
  14. package/dist/agentSessions/SessionJanitor.d.ts +236 -27
  15. package/dist/agentSessions/SessionJanitor.d.ts.map +1 -1
  16. package/dist/agentSessions/SessionJanitor.js +682 -54
  17. package/dist/agentSessions/SessionJanitor.js.map +1 -1
  18. package/dist/agentSessions/SessionManager.d.ts +48 -3
  19. package/dist/agentSessions/SessionManager.d.ts.map +1 -1
  20. package/dist/agentSessions/SessionManager.js +112 -9
  21. package/dist/agentSessions/SessionManager.js.map +1 -1
  22. package/dist/agentSessions/SessionRunIDVerifier.d.ts +63 -0
  23. package/dist/agentSessions/SessionRunIDVerifier.d.ts.map +1 -0
  24. package/dist/agentSessions/SessionRunIDVerifier.js +129 -0
  25. package/dist/agentSessions/SessionRunIDVerifier.js.map +1 -0
  26. package/dist/agentSessions/index.d.ts +2 -0
  27. package/dist/agentSessions/index.d.ts.map +1 -1
  28. package/dist/agentSessions/index.js +10 -3
  29. package/dist/agentSessions/index.js.map +1 -1
  30. package/dist/apiRoot.d.ts +32 -0
  31. package/dist/apiRoot.d.ts.map +1 -0
  32. package/dist/apiRoot.js +67 -0
  33. package/dist/apiRoot.js.map +1 -0
  34. package/dist/auth/AuthProviderCatalogRouter.d.ts.map +1 -1
  35. package/dist/auth/AuthProviderCatalogRouter.js +25 -0
  36. package/dist/auth/AuthProviderCatalogRouter.js.map +1 -1
  37. package/dist/auth/LoginScreenEngine.d.ts +22 -0
  38. package/dist/auth/LoginScreenEngine.d.ts.map +1 -0
  39. package/dist/auth/LoginScreenEngine.js +57 -0
  40. package/dist/auth/LoginScreenEngine.js.map +1 -0
  41. package/dist/auth/actionAuthorization.d.ts +40 -0
  42. package/dist/auth/actionAuthorization.d.ts.map +1 -0
  43. package/dist/auth/actionAuthorization.js +94 -0
  44. package/dist/auth/actionAuthorization.js.map +1 -0
  45. package/dist/auth/index.d.ts +1 -0
  46. package/dist/auth/index.d.ts.map +1 -1
  47. package/dist/auth/index.js +4 -10
  48. package/dist/auth/index.js.map +1 -1
  49. package/dist/auth/magicLink/MagicLinkRouter.d.ts.map +1 -1
  50. package/dist/auth/magicLink/MagicLinkRouter.js +3 -2
  51. package/dist/auth/magicLink/MagicLinkRouter.js.map +1 -1
  52. package/dist/auth/magicLink/MagicLinkService.d.ts.map +1 -1
  53. package/dist/auth/magicLink/MagicLinkService.js +6 -3
  54. package/dist/auth/magicLink/MagicLinkService.js.map +1 -1
  55. package/dist/auth/newUsers.d.ts +10 -0
  56. package/dist/auth/newUsers.d.ts.map +1 -1
  57. package/dist/auth/newUsers.js +80 -11
  58. package/dist/auth/newUsers.js.map +1 -1
  59. package/dist/config.d.ts +2514 -22
  60. package/dist/config.d.ts.map +1 -1
  61. package/dist/config.js +166 -4
  62. package/dist/config.js.map +1 -1
  63. package/dist/context.d.ts +8 -0
  64. package/dist/context.d.ts.map +1 -1
  65. package/dist/context.js +14 -11
  66. package/dist/context.js.map +1 -1
  67. package/dist/coreRoutes.d.ts +29 -0
  68. package/dist/coreRoutes.d.ts.map +1 -0
  69. package/dist/coreRoutes.js +142 -0
  70. package/dist/coreRoutes.js.map +1 -0
  71. package/dist/generated/graphql-schemas/__mj.d.ts +504 -3
  72. package/dist/generated/graphql-schemas/__mj.d.ts.map +1 -1
  73. package/dist/generated/graphql-schemas/__mj.js +2456 -7
  74. package/dist/generated/graphql-schemas/__mj.js.map +1 -1
  75. package/dist/generic/CacheInvalidationResolver.d.ts +43 -8
  76. package/dist/generic/CacheInvalidationResolver.d.ts.map +1 -1
  77. package/dist/generic/CacheInvalidationResolver.js +59 -19
  78. package/dist/generic/CacheInvalidationResolver.js.map +1 -1
  79. package/dist/generic/OrphanedConversationDetailReconciler.js +3 -3
  80. package/dist/generic/OrphanedConversationDetailReconciler.js.map +1 -1
  81. package/dist/generic/PushStatusResolver.js +1 -1
  82. package/dist/generic/PushStatusResolver.js.map +1 -1
  83. package/dist/generic/ResolverBase.d.ts +123 -48
  84. package/dist/generic/ResolverBase.d.ts.map +1 -1
  85. package/dist/generic/ResolverBase.js +293 -305
  86. package/dist/generic/ResolverBase.js.map +1 -1
  87. package/dist/generic/RunViewResolver.d.ts.map +1 -1
  88. package/dist/generic/RunViewResolver.js +16 -0
  89. package/dist/generic/RunViewResolver.js.map +1 -1
  90. package/dist/globalCors.d.ts +33 -0
  91. package/dist/globalCors.d.ts.map +1 -0
  92. package/dist/globalCors.js +58 -0
  93. package/dist/globalCors.js.map +1 -0
  94. package/dist/index.d.ts +17 -0
  95. package/dist/index.d.ts.map +1 -1
  96. package/dist/index.js +219 -278
  97. package/dist/index.js.map +1 -1
  98. package/dist/isolatedProvider.d.ts +20 -0
  99. package/dist/isolatedProvider.d.ts.map +1 -0
  100. package/dist/isolatedProvider.js +22 -0
  101. package/dist/isolatedProvider.js.map +1 -0
  102. package/dist/multiTenancy/index.d.ts.map +1 -1
  103. package/dist/multiTenancy/index.js +22 -2
  104. package/dist/multiTenancy/index.js.map +1 -1
  105. package/dist/realtimeProxy/RealtimeProxyServer.d.ts +44 -4
  106. package/dist/realtimeProxy/RealtimeProxyServer.d.ts.map +1 -1
  107. package/dist/realtimeProxy/RealtimeProxyServer.js +121 -16
  108. package/dist/realtimeProxy/RealtimeProxyServer.js.map +1 -1
  109. package/dist/realtimeProxy/RealtimeRelayTunnel.d.ts +171 -0
  110. package/dist/realtimeProxy/RealtimeRelayTunnel.d.ts.map +1 -0
  111. package/dist/realtimeProxy/RealtimeRelayTunnel.js +532 -0
  112. package/dist/realtimeProxy/RealtimeRelayTunnel.js.map +1 -0
  113. package/dist/realtimeSessions/RealtimeSessionEventService.d.ts +148 -0
  114. package/dist/realtimeSessions/RealtimeSessionEventService.d.ts.map +1 -0
  115. package/dist/realtimeSessions/RealtimeSessionEventService.js +191 -0
  116. package/dist/realtimeSessions/RealtimeSessionEventService.js.map +1 -0
  117. package/dist/realtimeSessions/RealtimeSessionVerificationService.d.ts +66 -0
  118. package/dist/realtimeSessions/RealtimeSessionVerificationService.d.ts.map +1 -0
  119. package/dist/realtimeSessions/RealtimeSessionVerificationService.js +139 -0
  120. package/dist/realtimeSessions/RealtimeSessionVerificationService.js.map +1 -0
  121. package/dist/realtimeSessions/RealtimeVerifyRouter.d.ts +38 -0
  122. package/dist/realtimeSessions/RealtimeVerifyRouter.d.ts.map +1 -0
  123. package/dist/realtimeSessions/RealtimeVerifyRouter.js +99 -0
  124. package/dist/realtimeSessions/RealtimeVerifyRouter.js.map +1 -0
  125. package/dist/realtimeSessions/RecordingAssemblyScheduler.d.ts +100 -0
  126. package/dist/realtimeSessions/RecordingAssemblyScheduler.d.ts.map +1 -0
  127. package/dist/realtimeSessions/RecordingAssemblyScheduler.js +173 -0
  128. package/dist/realtimeSessions/RecordingAssemblyScheduler.js.map +1 -0
  129. package/dist/realtimeSessions/SessionVerificationPortsBase.d.ts +61 -0
  130. package/dist/realtimeSessions/SessionVerificationPortsBase.d.ts.map +1 -0
  131. package/dist/realtimeSessions/SessionVerificationPortsBase.js +149 -0
  132. package/dist/realtimeSessions/SessionVerificationPortsBase.js.map +1 -0
  133. package/dist/realtimeSessions/SlidingWindowRateLimiter.d.ts +57 -0
  134. package/dist/realtimeSessions/SlidingWindowRateLimiter.d.ts.map +1 -0
  135. package/dist/realtimeSessions/SlidingWindowRateLimiter.js +69 -0
  136. package/dist/realtimeSessions/SlidingWindowRateLimiter.js.map +1 -0
  137. package/dist/realtimeSessions/index.d.ts +19 -0
  138. package/dist/realtimeSessions/index.d.ts.map +1 -0
  139. package/dist/realtimeSessions/index.js +19 -0
  140. package/dist/realtimeSessions/index.js.map +1 -0
  141. package/dist/realtimeSessions/ownedRealtimeSession.d.ts +30 -0
  142. package/dist/realtimeSessions/ownedRealtimeSession.d.ts.map +1 -0
  143. package/dist/realtimeSessions/ownedRealtimeSession.js +47 -0
  144. package/dist/realtimeSessions/ownedRealtimeSession.js.map +1 -0
  145. package/dist/realtimeSessions/sessionAccess.d.ts +92 -0
  146. package/dist/realtimeSessions/sessionAccess.d.ts.map +1 -0
  147. package/dist/realtimeSessions/sessionAccess.js +94 -0
  148. package/dist/realtimeSessions/sessionAccess.js.map +1 -0
  149. package/dist/realtimeSessions/sessionConfigStamps.d.ts +70 -0
  150. package/dist/realtimeSessions/sessionConfigStamps.d.ts.map +1 -0
  151. package/dist/realtimeSessions/sessionConfigStamps.js +93 -0
  152. package/dist/realtimeSessions/sessionConfigStamps.js.map +1 -0
  153. package/dist/realtimeSessions/subscriptionAuthorization.d.ts +65 -0
  154. package/dist/realtimeSessions/subscriptionAuthorization.d.ts.map +1 -0
  155. package/dist/realtimeSessions/subscriptionAuthorization.js +71 -0
  156. package/dist/realtimeSessions/subscriptionAuthorization.js.map +1 -0
  157. package/dist/realtimeSessions/verificationCore.d.ts +243 -0
  158. package/dist/realtimeSessions/verificationCore.d.ts.map +1 -0
  159. package/dist/realtimeSessions/verificationCore.js +356 -0
  160. package/dist/realtimeSessions/verificationCore.js.map +1 -0
  161. package/dist/realtimeSessions/verificationPages.d.ts +66 -0
  162. package/dist/realtimeSessions/verificationPages.d.ts.map +1 -0
  163. package/dist/realtimeSessions/verificationPages.js +110 -0
  164. package/dist/realtimeSessions/verificationPages.js.map +1 -0
  165. package/dist/realtimeSessions/verificationPolicy.d.ts +147 -0
  166. package/dist/realtimeSessions/verificationPolicy.d.ts.map +1 -0
  167. package/dist/realtimeSessions/verificationPolicy.js +249 -0
  168. package/dist/realtimeSessions/verificationPolicy.js.map +1 -0
  169. package/dist/realtimeSessions/verificationWorkflow.d.ts +263 -0
  170. package/dist/realtimeSessions/verificationWorkflow.d.ts.map +1 -0
  171. package/dist/realtimeSessions/verificationWorkflow.js +435 -0
  172. package/dist/realtimeSessions/verificationWorkflow.js.map +1 -0
  173. package/dist/realtimeWidget/widgetGuestElevation.d.ts +20 -2
  174. package/dist/realtimeWidget/widgetGuestElevation.d.ts.map +1 -1
  175. package/dist/realtimeWidget/widgetGuestElevation.js +31 -2
  176. package/dist/realtimeWidget/widgetGuestElevation.js.map +1 -1
  177. package/dist/resolvers/ActionResolver.d.ts +31 -5
  178. package/dist/resolvers/ActionResolver.d.ts.map +1 -1
  179. package/dist/resolvers/ActionResolver.js +75 -14
  180. package/dist/resolvers/ActionResolver.js.map +1 -1
  181. package/dist/resolvers/AdhocQueryResolver.d.ts +14 -1
  182. package/dist/resolvers/AdhocQueryResolver.d.ts.map +1 -1
  183. package/dist/resolvers/AdhocQueryResolver.js +21 -5
  184. package/dist/resolvers/AdhocQueryResolver.js.map +1 -1
  185. package/dist/resolvers/ArtifactFileResolver.d.ts +5 -1
  186. package/dist/resolvers/ArtifactFileResolver.d.ts.map +1 -1
  187. package/dist/resolvers/ArtifactFileResolver.js +9 -7
  188. package/dist/resolvers/ArtifactFileResolver.js.map +1 -1
  189. package/dist/resolvers/CacheStatsResolver.d.ts +27 -0
  190. package/dist/resolvers/CacheStatsResolver.d.ts.map +1 -1
  191. package/dist/resolvers/CacheStatsResolver.js +113 -2
  192. package/dist/resolvers/CacheStatsResolver.js.map +1 -1
  193. package/dist/resolvers/ClientToolRequestResolver.d.ts +4 -2
  194. package/dist/resolvers/ClientToolRequestResolver.d.ts.map +1 -1
  195. package/dist/resolvers/ClientToolRequestResolver.js +28 -10
  196. package/dist/resolvers/ClientToolRequestResolver.js.map +1 -1
  197. package/dist/resolvers/ConversationRunEventsResolver.d.ts +8 -4
  198. package/dist/resolvers/ConversationRunEventsResolver.d.ts.map +1 -1
  199. package/dist/resolvers/ConversationRunEventsResolver.js +6 -6
  200. package/dist/resolvers/ConversationRunEventsResolver.js.map +1 -1
  201. package/dist/resolvers/DatasetResolver.d.ts +24 -3
  202. package/dist/resolvers/DatasetResolver.d.ts.map +1 -1
  203. package/dist/resolvers/DatasetResolver.js +57 -8
  204. package/dist/resolvers/DatasetResolver.js.map +1 -1
  205. package/dist/resolvers/EntityRecordNameResolver.d.ts +2 -1
  206. package/dist/resolvers/EntityRecordNameResolver.d.ts.map +1 -1
  207. package/dist/resolvers/EntityRecordNameResolver.js +3 -2
  208. package/dist/resolvers/EntityRecordNameResolver.js.map +1 -1
  209. package/dist/resolvers/FetchEntityVectorsResolver.d.ts +27 -1
  210. package/dist/resolvers/FetchEntityVectorsResolver.d.ts.map +1 -1
  211. package/dist/resolvers/FetchEntityVectorsResolver.js +148 -2
  212. package/dist/resolvers/FetchEntityVectorsResolver.js.map +1 -1
  213. package/dist/resolvers/FileResolver.d.ts +82 -11
  214. package/dist/resolvers/FileResolver.d.ts.map +1 -1
  215. package/dist/resolvers/FileResolver.js +279 -101
  216. package/dist/resolvers/FileResolver.js.map +1 -1
  217. package/dist/resolvers/GetDataContextDataResolver.d.ts +33 -7
  218. package/dist/resolvers/GetDataContextDataResolver.d.ts.map +1 -1
  219. package/dist/resolvers/GetDataContextDataResolver.js +117 -38
  220. package/dist/resolvers/GetDataContextDataResolver.js.map +1 -1
  221. package/dist/resolvers/GetDataResolver.d.ts.map +1 -1
  222. package/dist/resolvers/GetDataResolver.js +6 -3
  223. package/dist/resolvers/GetDataResolver.js.map +1 -1
  224. package/dist/resolvers/HumanHandoffResolver.d.ts.map +1 -1
  225. package/dist/resolvers/HumanHandoffResolver.js +7 -1
  226. package/dist/resolvers/HumanHandoffResolver.js.map +1 -1
  227. package/dist/resolvers/IntegrationDiscoveryResolver.d.ts.map +1 -1
  228. package/dist/resolvers/IntegrationDiscoveryResolver.js +4 -2
  229. package/dist/resolvers/IntegrationDiscoveryResolver.js.map +1 -1
  230. package/dist/resolvers/MCPResolver.d.ts.map +1 -1
  231. package/dist/resolvers/MCPResolver.js +9 -4
  232. package/dist/resolvers/MCPResolver.js.map +1 -1
  233. package/dist/resolvers/QueryResolver.d.ts +2 -0
  234. package/dist/resolvers/QueryResolver.d.ts.map +1 -1
  235. package/dist/resolvers/QueryResolver.js +13 -0
  236. package/dist/resolvers/QueryResolver.js.map +1 -1
  237. package/dist/resolvers/RealtimeBridgeResolver.d.ts +54 -2
  238. package/dist/resolvers/RealtimeBridgeResolver.d.ts.map +1 -1
  239. package/dist/resolvers/RealtimeBridgeResolver.js +155 -10
  240. package/dist/resolvers/RealtimeBridgeResolver.js.map +1 -1
  241. package/dist/resolvers/RealtimeClientSessionResolver.d.ts +157 -33
  242. package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
  243. package/dist/resolvers/RealtimeClientSessionResolver.js +404 -116
  244. package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
  245. package/dist/resolvers/RealtimeSessionEventsResolver.d.ts +61 -0
  246. package/dist/resolvers/RealtimeSessionEventsResolver.d.ts.map +1 -0
  247. package/dist/resolvers/RealtimeSessionEventsResolver.js +130 -0
  248. package/dist/resolvers/RealtimeSessionEventsResolver.js.map +1 -0
  249. package/dist/resolvers/RealtimeSessionVerificationResolver.d.ts +85 -0
  250. package/dist/resolvers/RealtimeSessionVerificationResolver.d.ts.map +1 -0
  251. package/dist/resolvers/RealtimeSessionVerificationResolver.js +188 -0
  252. package/dist/resolvers/RealtimeSessionVerificationResolver.js.map +1 -0
  253. package/dist/resolvers/RemoteBrowserActionResolver.d.ts +2 -0
  254. package/dist/resolvers/RemoteBrowserActionResolver.d.ts.map +1 -1
  255. package/dist/resolvers/RemoteBrowserActionResolver.js +5 -1
  256. package/dist/resolvers/RemoteBrowserActionResolver.js.map +1 -1
  257. package/dist/resolvers/RunAIAgentResolver.d.ts +10 -0
  258. package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
  259. package/dist/resolvers/RunAIAgentResolver.js +100 -14
  260. package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
  261. package/dist/resolvers/RunTemplateResolver.d.ts.map +1 -1
  262. package/dist/resolvers/RunTemplateResolver.js +12 -11
  263. package/dist/resolvers/RunTemplateResolver.js.map +1 -1
  264. package/dist/resolvers/SearchKnowledgeStreamResolver.d.ts +12 -1
  265. package/dist/resolvers/SearchKnowledgeStreamResolver.d.ts.map +1 -1
  266. package/dist/resolvers/SearchKnowledgeStreamResolver.js +15 -2
  267. package/dist/resolvers/SearchKnowledgeStreamResolver.js.map +1 -1
  268. package/dist/resolvers/SqlLoggingConfigResolver.d.ts.map +1 -1
  269. package/dist/resolvers/SqlLoggingConfigResolver.js +2 -3
  270. package/dist/resolvers/SqlLoggingConfigResolver.js.map +1 -1
  271. package/dist/resolvers/SyncDataResolver.d.ts.map +1 -1
  272. package/dist/resolvers/SyncDataResolver.js +6 -2
  273. package/dist/resolvers/SyncDataResolver.js.map +1 -1
  274. package/dist/resolvers/SyncRolesUsersResolver.d.ts +2 -0
  275. package/dist/resolvers/SyncRolesUsersResolver.d.ts.map +1 -1
  276. package/dist/resolvers/SyncRolesUsersResolver.js +23 -6
  277. package/dist/resolvers/SyncRolesUsersResolver.js.map +1 -1
  278. package/dist/resolvers/TaskGraphFrameResolver.d.ts +2 -1
  279. package/dist/resolvers/TaskGraphFrameResolver.d.ts.map +1 -1
  280. package/dist/resolvers/TaskGraphFrameResolver.js +28 -1
  281. package/dist/resolvers/TaskGraphFrameResolver.js.map +1 -1
  282. package/dist/resolvers/TestQuerySQLResolver.d.ts +24 -0
  283. package/dist/resolvers/TestQuerySQLResolver.d.ts.map +1 -1
  284. package/dist/resolvers/TestQuerySQLResolver.js +65 -13
  285. package/dist/resolvers/TestQuerySQLResolver.js.map +1 -1
  286. package/dist/resolvers/TransactionGroupResolver.d.ts +19 -2
  287. package/dist/resolvers/TransactionGroupResolver.d.ts.map +1 -1
  288. package/dist/resolvers/TransactionGroupResolver.js +102 -24
  289. package/dist/resolvers/TransactionGroupResolver.js.map +1 -1
  290. package/dist/resolvers/UserAvatarResolver.d.ts +16 -0
  291. package/dist/resolvers/UserAvatarResolver.d.ts.map +1 -0
  292. package/dist/resolvers/UserAvatarResolver.js +124 -0
  293. package/dist/resolvers/UserAvatarResolver.js.map +1 -0
  294. package/dist/resolvers/UserResolver.d.ts.map +1 -1
  295. package/dist/resolvers/UserResolver.js +2 -17
  296. package/dist/resolvers/UserResolver.js.map +1 -1
  297. package/dist/resolvers/agent-run-data-guard.d.ts +31 -0
  298. package/dist/resolvers/agent-run-data-guard.d.ts.map +1 -0
  299. package/dist/resolvers/agent-run-data-guard.js +72 -0
  300. package/dist/resolvers/agent-run-data-guard.js.map +1 -0
  301. package/dist/resolvers/agentVisionConsentAudit.d.ts +37 -0
  302. package/dist/resolvers/agentVisionConsentAudit.d.ts.map +1 -0
  303. package/dist/resolvers/agentVisionConsentAudit.js +63 -0
  304. package/dist/resolvers/agentVisionConsentAudit.js.map +1 -0
  305. package/dist/resolvers/avatarInputValidation.d.ts +40 -0
  306. package/dist/resolvers/avatarInputValidation.d.ts.map +1 -0
  307. package/dist/resolvers/avatarInputValidation.js +97 -0
  308. package/dist/resolvers/avatarInputValidation.js.map +1 -0
  309. package/dist/resolvers/currentUserRoles.d.ts +29 -0
  310. package/dist/resolvers/currentUserRoles.d.ts.map +1 -1
  311. package/dist/resolvers/currentUserRoles.js +30 -0
  312. package/dist/resolvers/currentUserRoles.js.map +1 -1
  313. package/dist/resolvers/meetings/meetingMutations.d.ts +6 -0
  314. package/dist/resolvers/meetings/meetingMutations.d.ts.map +1 -1
  315. package/dist/resolvers/meetings/meetingMutations.js +21 -0
  316. package/dist/resolvers/meetings/meetingMutations.js.map +1 -1
  317. package/dist/rest/RealtimeRecordingHandler.d.ts +49 -0
  318. package/dist/rest/RealtimeRecordingHandler.d.ts.map +1 -0
  319. package/dist/rest/RealtimeRecordingHandler.js +383 -0
  320. package/dist/rest/RealtimeRecordingHandler.js.map +1 -0
  321. package/dist/rest/ViewOperationsHandler.d.ts +3 -1
  322. package/dist/rest/ViewOperationsHandler.d.ts.map +1 -1
  323. package/dist/rest/ViewOperationsHandler.js +21 -12
  324. package/dist/rest/ViewOperationsHandler.js.map +1 -1
  325. package/dist/rest/setupRESTEndpoints.d.ts +6 -0
  326. package/dist/rest/setupRESTEndpoints.d.ts.map +1 -1
  327. package/dist/rest/setupRESTEndpoints.js +6 -0
  328. package/dist/rest/setupRESTEndpoints.js.map +1 -1
  329. package/dist/serverExtensionReservedRoots.d.ts +12 -10
  330. package/dist/serverExtensionReservedRoots.d.ts.map +1 -1
  331. package/dist/serverExtensionReservedRoots.js +14 -17
  332. package/dist/serverExtensionReservedRoots.js.map +1 -1
  333. package/dist/services/MJStorageBlobStore.d.ts +8 -1
  334. package/dist/services/MJStorageBlobStore.d.ts.map +1 -1
  335. package/dist/services/MJStorageBlobStore.js +25 -19
  336. package/dist/services/MJStorageBlobStore.js.map +1 -1
  337. package/dist/services/StartTaskGraphDispatcher.js +2 -2
  338. package/dist/services/StartTaskGraphDispatcher.js.map +1 -1
  339. package/dist/services/TaskGraphActionRunner.d.ts +5 -3
  340. package/dist/services/TaskGraphActionRunner.d.ts.map +1 -1
  341. package/dist/services/TaskGraphActionRunner.js +27 -5
  342. package/dist/services/TaskGraphActionRunner.js.map +1 -1
  343. package/dist/services/TaskGraphAgentRunner.d.ts +14 -2
  344. package/dist/services/TaskGraphAgentRunner.d.ts.map +1 -1
  345. package/dist/services/TaskGraphAgentRunner.js +157 -9
  346. package/dist/services/TaskGraphAgentRunner.js.map +1 -1
  347. package/dist/services/TaskGraphContinuationDeliverer.d.ts +57 -4
  348. package/dist/services/TaskGraphContinuationDeliverer.d.ts.map +1 -1
  349. package/dist/services/TaskGraphContinuationDeliverer.js +607 -18
  350. package/dist/services/TaskGraphContinuationDeliverer.js.map +1 -1
  351. package/dist/sharedCache.d.ts +105 -0
  352. package/dist/sharedCache.d.ts.map +1 -0
  353. package/dist/sharedCache.js +279 -0
  354. package/dist/sharedCache.js.map +1 -0
  355. package/dist/types.d.ts +6 -0
  356. package/dist/types.d.ts.map +1 -1
  357. package/dist/types.js.map +1 -1
  358. package/package.json +99 -96
  359. package/src/__tests__/ActionResolver.authorization.test.ts +353 -0
  360. package/src/__tests__/AdhocQueryResolver.sqlAuthorizer.test.ts +104 -0
  361. package/src/__tests__/BridgeHostInstance.test.ts +232 -0
  362. package/src/__tests__/ClientToolRequestResolver.test.ts +116 -0
  363. package/src/__tests__/DatasetResolver.itemFilters.test.ts +201 -0
  364. package/src/__tests__/EntityRecordNameResolver.rowSecurity.test.ts +152 -0
  365. package/src/__tests__/FetchEntityVectorsResolver.test.ts +433 -0
  366. package/src/__tests__/FileResolver.storageAccess.test.ts +562 -0
  367. package/src/__tests__/GetDataContextDataResolver.sqlItems.test.ts +416 -0
  368. package/src/__tests__/HostInstance.test.ts +84 -0
  369. package/src/__tests__/HumanHandoffResolver.test.ts +17 -0
  370. package/src/__tests__/ListOperationsResolver.adhocScreen.test.ts +137 -0
  371. package/src/__tests__/LoginScreenEngine.test.ts +86 -0
  372. package/src/__tests__/MJStorageBlobStore.storageGate.test.ts +63 -0
  373. package/src/__tests__/MeetingResolver.test.ts +75 -1
  374. package/src/__tests__/RealtimeBridgeResolver.test.ts +415 -6
  375. package/src/__tests__/RealtimeClientSessionResolver.configTamper.test.ts +383 -0
  376. package/src/__tests__/RealtimeClientSessionResolver.test.ts +682 -58
  377. package/src/__tests__/RealtimeProxyServer.test.ts +16 -1
  378. package/src/__tests__/RealtimeRelay.test.ts +876 -0
  379. package/src/__tests__/RecordingAssemblyScheduler.test.ts +178 -0
  380. package/src/__tests__/RemoteBrowserActionResolver.goalRunLink.test.ts +129 -0
  381. package/src/__tests__/ResolverBase.adhocReadScope.test.ts +133 -2
  382. package/src/__tests__/ResolverBase.aggregateScreen.test.ts +174 -0
  383. package/src/__tests__/ResolverBase.balancedClause.test.ts +155 -0
  384. package/src/__tests__/ResolverBase.clauseUnscopedRead.test.ts +127 -0
  385. package/src/__tests__/ResolverBase.clientOldValues.test.ts +212 -6
  386. package/src/__tests__/ResolverBase.filterEscaping.test.ts +5 -2
  387. package/src/__tests__/ReturningVisitorRecap.test.ts +115 -0
  388. package/src/__tests__/RunAIAgentResolver.branch.test.ts +170 -0
  389. package/src/__tests__/RunAIAgentResolver.historyFrom.test.ts +6 -4
  390. package/src/__tests__/RunAIAgentResolver.runDataGuard.test.ts +258 -0
  391. package/src/__tests__/RunAIAgentResolver.stoppedPredecessor.test.ts +166 -0
  392. package/src/__tests__/RunTemplateResolver.test.ts +132 -0
  393. package/src/__tests__/RunViewResolver.cacheCheckForwarding.test.ts +63 -0
  394. package/src/__tests__/RunViewResolver.cacheCheckScreen.test.ts +165 -0
  395. package/src/__tests__/SearchKnowledgeStreamResolver.test.ts +161 -0
  396. package/src/__tests__/SessionJanitor.test.ts +1203 -21
  397. package/src/__tests__/SessionManager.test.ts +240 -17
  398. package/src/__tests__/SessionRunIDVerifier.test.ts +251 -0
  399. package/src/__tests__/SyncRolesUsersResolver.userRoles.test.ts +97 -0
  400. package/src/__tests__/TaskGraphActionRunner.durablePayload.test.ts +25 -0
  401. package/src/__tests__/TaskGraphAgentRunner.test.ts +266 -0
  402. package/src/__tests__/TaskGraphContinuationDeliverer.test.ts +403 -22
  403. package/src/__tests__/TaskGraphFrameResolver.test.ts +22 -0
  404. package/src/__tests__/TestQuerySQLResolver.test.ts +274 -0
  405. package/src/__tests__/TransactionGroupResolver.refusals.test.ts +98 -1
  406. package/src/__tests__/UpdateMJDataContextItem.oldValues.test.ts +220 -0
  407. package/src/__tests__/UserAvatarResolver.test.ts +255 -0
  408. package/src/__tests__/UserResolver.currentUser.test.ts +16 -1
  409. package/src/__tests__/ViewOperationsHandler.clauseScreen.test.ts +157 -0
  410. package/src/__tests__/actionAuthorization.test.ts +130 -0
  411. package/src/__tests__/agent-run-data-guard.test.ts +130 -0
  412. package/src/__tests__/agentVisionConsentAudit.test.ts +118 -0
  413. package/src/__tests__/apiRootBoot.test.ts +202 -0
  414. package/src/__tests__/avatarInputValidation.test.ts +160 -0
  415. package/src/__tests__/cacheInvalidationRecordData.test.ts +64 -0
  416. package/src/__tests__/conversationRunEvents.test.ts +56 -14
  417. package/src/__tests__/globalCors.test.ts +217 -0
  418. package/src/__tests__/isolatedProviderTransactions.test.ts +169 -0
  419. package/src/__tests__/magicLinkService.consume.test.ts +6 -0
  420. package/src/__tests__/magicLinkService.provisionLog.test.ts +5 -0
  421. package/src/__tests__/multiTenancy.postgresRewrite.test.ts +181 -0
  422. package/src/__tests__/multiTenancy.security.test.ts +51 -0
  423. package/src/__tests__/multiTenancy.test.ts +1 -1
  424. package/src/__tests__/newUsers.template.test.ts +151 -0
  425. package/src/__tests__/newUsers.test.ts +74 -5
  426. package/src/__tests__/orphanedConversationDetailReconciler.test.ts +17 -2
  427. package/src/__tests__/ownedRealtimeSession.test.ts +39 -0
  428. package/src/__tests__/pushStatusResolver.filter.test.ts +7 -0
  429. package/src/__tests__/realtimeRecordingHandler.test.ts +652 -0
  430. package/src/__tests__/realtimeSessions/RealtimeSessionEventService.test.ts +201 -0
  431. package/src/__tests__/realtimeSessions/RealtimeSessionEventsResolver.test.ts +215 -0
  432. package/src/__tests__/realtimeSessions/RealtimeSessionVerificationResolver.test.ts +102 -0
  433. package/src/__tests__/realtimeSessions/RealtimeSessionVerificationService.test.ts +349 -0
  434. package/src/__tests__/realtimeSessions/RealtimeVerifyRouter.test.ts +131 -0
  435. package/src/__tests__/realtimeSessions/SlidingWindowRateLimiter.test.ts +56 -0
  436. package/src/__tests__/realtimeSessions/helpers.ts +4 -0
  437. package/src/__tests__/realtimeSessions/sessionAccess.test.ts +129 -0
  438. package/src/__tests__/realtimeSessions/sessionConfigStamps.test.ts +124 -0
  439. package/src/__tests__/realtimeSessions/verificationCore.test.ts +355 -0
  440. package/src/__tests__/realtimeSessions/verificationPages.test.ts +84 -0
  441. package/src/__tests__/realtimeSessions/verificationPolicy.test.ts +226 -0
  442. package/src/__tests__/realtimeSessions/verificationWorkflow.test.ts +633 -0
  443. package/src/__tests__/resolverBase.fls.test.ts +87 -4
  444. package/src/__tests__/serverExtensionHostOverlay.test.ts +66 -0
  445. package/src/__tests__/serverExtensionReservedRoots.test.ts +11 -96
  446. package/src/__tests__/sharedCache.test.ts +312 -0
  447. package/src/__tests__/widgetGuestElevation.test.ts +44 -0
  448. package/src/agentSessions/BridgeHostInstance.ts +32 -0
  449. package/src/agentSessions/HostInstance.ts +124 -28
  450. package/src/agentSessions/ReturningVisitorRecap.ts +7 -3
  451. package/src/agentSessions/SessionJanitor.ts +821 -59
  452. package/src/agentSessions/SessionManager.ts +138 -26
  453. package/src/agentSessions/SessionRunIDVerifier.ts +171 -0
  454. package/src/agentSessions/index.ts +10 -3
  455. package/src/apiRoot.ts +78 -0
  456. package/src/auth/AuthProviderCatalogRouter.ts +26 -0
  457. package/src/auth/LoginScreenEngine.ts +50 -0
  458. package/src/auth/actionAuthorization.ts +116 -0
  459. package/src/auth/index.ts +4 -8
  460. package/src/auth/magicLink/MagicLinkRouter.ts +3 -2
  461. package/src/auth/magicLink/MagicLinkService.ts +6 -3
  462. package/src/auth/newUsers.ts +99 -11
  463. package/src/config.ts +171 -5
  464. package/src/context.ts +15 -10
  465. package/src/coreRoutes.ts +166 -0
  466. package/src/generated/graphql-schemas/__mj.ts +1815 -57
  467. package/src/generic/CacheInvalidationResolver.ts +73 -18
  468. package/src/generic/OrphanedConversationDetailReconciler.ts +3 -3
  469. package/src/generic/PushStatusResolver.ts +1 -1
  470. package/src/generic/ResolverBase.ts +335 -326
  471. package/src/generic/RunViewResolver.ts +21 -0
  472. package/src/globalCors.ts +71 -0
  473. package/src/index.ts +231 -300
  474. package/src/isolatedProvider.ts +22 -0
  475. package/src/multiTenancy/index.ts +24 -2
  476. package/src/realtimeProxy/RealtimeProxyServer.ts +148 -16
  477. package/src/realtimeProxy/RealtimeRelayTunnel.ts +645 -0
  478. package/src/realtimeSessions/README.md +179 -0
  479. package/src/realtimeSessions/RealtimeSessionEventService.ts +274 -0
  480. package/src/realtimeSessions/RealtimeSessionVerificationService.ts +168 -0
  481. package/src/realtimeSessions/RealtimeVerifyRouter.ts +109 -0
  482. package/src/realtimeSessions/RecordingAssemblyScheduler.ts +234 -0
  483. package/src/realtimeSessions/SessionVerificationPortsBase.ts +189 -0
  484. package/src/realtimeSessions/SlidingWindowRateLimiter.ts +92 -0
  485. package/src/realtimeSessions/index.ts +18 -0
  486. package/src/realtimeSessions/ownedRealtimeSession.ts +55 -0
  487. package/src/realtimeSessions/sessionAccess.ts +145 -0
  488. package/src/realtimeSessions/sessionConfigStamps.ts +123 -0
  489. package/src/realtimeSessions/subscriptionAuthorization.ts +116 -0
  490. package/src/realtimeSessions/verificationCore.ts +502 -0
  491. package/src/realtimeSessions/verificationPages.ts +149 -0
  492. package/src/realtimeSessions/verificationPolicy.ts +321 -0
  493. package/src/realtimeSessions/verificationWorkflow.ts +702 -0
  494. package/src/realtimeWidget/widgetGuestElevation.ts +34 -2
  495. package/src/resolvers/ActionResolver.ts +84 -21
  496. package/src/resolvers/AdhocQueryResolver.ts +24 -6
  497. package/src/resolvers/ArtifactFileResolver.ts +9 -8
  498. package/src/resolvers/CacheStatsResolver.ts +89 -2
  499. package/src/resolvers/ClientToolRequestResolver.ts +25 -7
  500. package/src/resolvers/ConversationRunEventsResolver.ts +15 -11
  501. package/src/resolvers/DatasetResolver.ts +70 -10
  502. package/src/resolvers/EntityRecordNameResolver.ts +3 -2
  503. package/src/resolvers/FetchEntityVectorsResolver.ts +179 -2
  504. package/src/resolvers/FileResolver.ts +321 -106
  505. package/src/resolvers/GetDataContextDataResolver.ts +139 -41
  506. package/src/resolvers/GetDataResolver.ts +6 -3
  507. package/src/resolvers/HumanHandoffResolver.ts +8 -0
  508. package/src/resolvers/IntegrationDiscoveryResolver.ts +4 -2
  509. package/src/resolvers/MCPResolver.ts +8 -5
  510. package/src/resolvers/QueryResolver.ts +11 -0
  511. package/src/resolvers/RealtimeBridgeResolver.ts +163 -11
  512. package/src/resolvers/RealtimeClientSessionResolver.ts +511 -129
  513. package/src/resolvers/RealtimeSessionEventsResolver.ts +133 -0
  514. package/src/resolvers/RealtimeSessionVerificationResolver.ts +174 -0
  515. package/src/resolvers/RemoteBrowserActionResolver.ts +11 -1
  516. package/src/resolvers/RunAIAgentResolver.ts +116 -14
  517. package/src/resolvers/RunTemplateResolver.ts +13 -12
  518. package/src/resolvers/SearchKnowledgeStreamResolver.ts +19 -3
  519. package/src/resolvers/SqlLoggingConfigResolver.ts +2 -4
  520. package/src/resolvers/SyncDataResolver.ts +6 -2
  521. package/src/resolvers/SyncRolesUsersResolver.ts +24 -6
  522. package/src/resolvers/TaskGraphFrameResolver.ts +33 -1
  523. package/src/resolvers/TestQuerySQLResolver.ts +68 -13
  524. package/src/resolvers/TransactionGroupResolver.ts +131 -27
  525. package/src/resolvers/UserAvatarResolver.ts +111 -0
  526. package/src/resolvers/UserResolver.ts +2 -16
  527. package/src/resolvers/__tests__/GetDataResolver.validation.test.ts +95 -0
  528. package/src/resolvers/agent-run-data-guard.ts +89 -0
  529. package/src/resolvers/agentVisionConsentAudit.ts +82 -0
  530. package/src/resolvers/avatarInputValidation.ts +123 -0
  531. package/src/resolvers/currentUserRoles.ts +32 -1
  532. package/src/resolvers/meetings/meetingMutations.ts +21 -0
  533. package/src/rest/RealtimeRecordingHandler.ts +464 -0
  534. package/src/rest/ViewOperationsHandler.ts +29 -13
  535. package/src/rest/setupRESTEndpoints.ts +6 -0
  536. package/src/serverExtensionReservedRoots.ts +14 -17
  537. package/src/services/MJStorageBlobStore.ts +31 -30
  538. package/src/services/StartTaskGraphDispatcher.ts +2 -2
  539. package/src/services/TaskGraphActionRunner.ts +25 -5
  540. package/src/services/TaskGraphAgentRunner.ts +188 -11
  541. package/src/services/TaskGraphContinuationDeliverer.ts +713 -17
  542. package/src/sharedCache.ts +305 -0
  543. package/src/types.ts +7 -0
@@ -0,0 +1,55 @@
1
+ /**
2
+ * @fileoverview The ownership gate for client-direct realtime session writes: the GraphQL mutations of
3
+ * `RealtimeClientSessionResolver` and the recording REST routes both load the session through
4
+ * {@link LoadOwnedRealtimeSession}, so "may this caller write to this session?" is decided in one place.
5
+ *
6
+ * @module @memberjunction/server/realtimeSessions
7
+ */
8
+ import { IMetadataProvider, LogError, UserInfo } from '@memberjunction/core';
9
+ import { UUIDsEqual } from '@memberjunction/global';
10
+ import type { MJAIAgentSessionEntity } from '@memberjunction/core-entities';
11
+
12
+ const SESSION_ENTITY = 'MJ: AI Agent Sessions';
13
+
14
+ /** The session does not exist, or the caller cannot read it. */
15
+ export class RealtimeSessionNotFoundError extends Error {
16
+ constructor(public readonly AgentSessionID: string) {
17
+ super(`Realtime session ${AgentSessionID} not found`);
18
+ this.name = 'RealtimeSessionNotFoundError';
19
+ }
20
+ }
21
+
22
+ /** The session exists but belongs to another user. */
23
+ export class RealtimeSessionOwnershipError extends Error {
24
+ constructor(public readonly AgentSessionID: string) {
25
+ super('Not authorized: you do not own this realtime session');
26
+ this.name = 'RealtimeSessionOwnershipError';
27
+ }
28
+ }
29
+
30
+ /**
31
+ * Loads a session under the caller's identity and enforces ownership (`UserID === contextUser.ID`). It
32
+ * deliberately does NOT reject `Closed` sessions: the final channel-state flush and the recording terminal
33
+ * signal legitimately arrive after the session closed. A scoped-anonymous widget guest owns the session it
34
+ * minted, so the same check covers it; loading as the caller also applies the entity's row-level security.
35
+ *
36
+ * @throws RealtimeSessionNotFoundError when the row does not load
37
+ * @throws RealtimeSessionOwnershipError when the caller is not the owner (logged with both user ids)
38
+ */
39
+ export async function LoadOwnedRealtimeSession(
40
+ agentSessionId: string,
41
+ contextUser: UserInfo,
42
+ provider: IMetadataProvider,
43
+ ): Promise<MJAIAgentSessionEntity> {
44
+ const session = await provider.GetEntityObject<MJAIAgentSessionEntity>(SESSION_ENTITY, contextUser);
45
+ if (!(await session.Load(agentSessionId))) {
46
+ throw new RealtimeSessionNotFoundError(agentSessionId);
47
+ }
48
+ if (!UUIDsEqual(session.UserID, contextUser.ID)) {
49
+ LogError(
50
+ `LoadOwnedRealtimeSession: ownership check failed — user ${contextUser.ID} attempted to operate on session ${agentSessionId} owned by ${session.UserID}`,
51
+ );
52
+ throw new RealtimeSessionOwnershipError(agentSessionId);
53
+ }
54
+ return session;
55
+ }
@@ -0,0 +1,145 @@
1
+ /**
2
+ * @fileoverview Who may see and act on ONE realtime session.
3
+ *
4
+ * One pure decision ({@link AuthorizeSessionAccess}) shared by everything that addresses a live
5
+ * session on behalf of a caller: the `RealtimeSessionEvents` subscription (at subscribe time AND for
6
+ * every delivered event), the verification mutations, and the status query. Keeping it in one place
7
+ * is what stops "who owns this session?" from being re-derived — slightly differently — in each.
8
+ *
9
+ * ## The two ownership rules
10
+ *
11
+ * 1. **Owner.** The session's `UserID` must be the caller's user.
12
+ * 2. **Scope.** A *named* user is fully identified by (1). An **anonymous widget guest** is not:
13
+ * every guest authenticates as the one shared Anonymous user, so (1) alone would let any guest
14
+ * address any other guest's session. What separates guests is the signed per-session scope in
15
+ * their token (`MagicLinkScope.ResourceID`), which `SessionManager` stamps onto the session's
16
+ * Conversation as `ExternalID`. So a principal that carries a scope must match it, and an
17
+ * anonymous principal that carries NO scope is refused outright — it cannot be told apart from
18
+ * every other anonymous principal.
19
+ *
20
+ * The decision is deliberately pure (no I/O) so it can be applied identically to a freshly loaded
21
+ * row at subscribe time and to the owner/scope snapshot carried inside each published event.
22
+ *
23
+ * @module @memberjunction/server/realtimeSessions
24
+ */
25
+
26
+ import { IMetadataProvider, LogError, UserInfo } from '@memberjunction/core';
27
+ import { IsValidUUID, UUIDsEqual } from '@memberjunction/global';
28
+ import type { MJAIAgentSessionEntity, MJConversationEntity } from '@memberjunction/core-entities';
29
+
30
+ /** Entity names, centralised so the `MJ: ` prefix convention lives in one place. */
31
+ const SESSION_ENTITY = 'MJ: AI Agent Sessions';
32
+ const CONVERSATION_ENTITY = 'MJ: Conversations';
33
+
34
+ /** What the decision needs to know about the session. */
35
+ export interface SessionAccessSubject {
36
+ /** `AIAgentSession.UserID`. */
37
+ SessionUserID: string;
38
+ /**
39
+ * `Conversation.ExternalID` of the session's conversation — the signed per-session scope id for an
40
+ * anonymous guest. `null`/`undefined` when the conversation has none (a named user's session) or
41
+ * could not be loaded.
42
+ */
43
+ ConversationExternalID: string | null | undefined;
44
+ }
45
+
46
+ /** What the decision needs to know about the caller (a subset of `UserInfo`). */
47
+ export interface SessionAccessPrincipal {
48
+ /** The caller's user id. */
49
+ ID: string;
50
+ /** True for the shared-Anonymous-user principal of a public-widget guest. */
51
+ IsMagicLinkAnonymous?: boolean;
52
+ /** The signed per-session scope carried by the caller's token, when any. */
53
+ MagicLinkScope?: { ResourceID?: string } | undefined;
54
+ }
55
+
56
+ /** Why access was refused. Callers log the reason; clients get a uniform refusal. */
57
+ export type SessionAccessRefusal = 'not_owner' | 'scope_missing' | 'scope_mismatch';
58
+
59
+ /** Outcome of {@link AuthorizeSessionAccess}. */
60
+ export type SessionAccessDecision = { Allowed: true } | { Allowed: false; Reason: SessionAccessRefusal };
61
+
62
+ /**
63
+ * Decides whether `principal` may address the session described by `subject`.
64
+ *
65
+ * Fails closed: anything that cannot be positively matched is refused.
66
+ *
67
+ * @param subject - owner + scope of the session
68
+ * @param principal - the authenticated caller (from the server-built `UserInfo`, never from client args)
69
+ */
70
+ export function AuthorizeSessionAccess(
71
+ subject: SessionAccessSubject,
72
+ principal: SessionAccessPrincipal | null | undefined,
73
+ ): SessionAccessDecision {
74
+ if (!principal?.ID || !subject.SessionUserID || !UUIDsEqual(subject.SessionUserID, principal.ID)) {
75
+ return { Allowed: false, Reason: 'not_owner' };
76
+ }
77
+ const scopeId = principal.MagicLinkScope?.ResourceID;
78
+ if (!scopeId) {
79
+ // An anonymous principal without a per-session scope is indistinguishable from every other
80
+ // anonymous principal: owning "the Anonymous user's" session proves nothing.
81
+ return principal.IsMagicLinkAnonymous ? { Allowed: false, Reason: 'scope_missing' } : { Allowed: true };
82
+ }
83
+ // Scope ids are opaque base64url strings (case-significant), so compare exactly — not UUIDsEqual.
84
+ return subject.ConversationExternalID === scopeId ? { Allowed: true } : { Allowed: false, Reason: 'scope_mismatch' };
85
+ }
86
+
87
+ /** A session row together with the one fact about its conversation the decision needs. */
88
+ export interface LoadedSessionForAccess {
89
+ /** The session entity, loaded under the caller's own identity (so RLS applied to the read). */
90
+ Session: MJAIAgentSessionEntity;
91
+ /** The session's conversation `ExternalID` (anonymous scope id), or null. */
92
+ ConversationExternalID: string | null;
93
+ }
94
+
95
+ /**
96
+ * Loads a session (and its conversation's scope id) under `contextUser`'s identity.
97
+ *
98
+ * Loading as the caller — rather than as a privileged user — means the entity layer's row-level
99
+ * security (`Widget Guest: Own Agent Sessions`, `UI: Own Agent Sessions`) is the FIRST gate; the
100
+ * explicit {@link AuthorizeSessionAccess} check that follows is defence in depth.
101
+ *
102
+ * @returns the loaded session, or `null` when the id is malformed, the row does not exist, or the
103
+ * caller cannot read it. Failure to read the conversation yields `ConversationExternalID: null`,
104
+ * which {@link AuthorizeSessionAccess} then treats as "no scope to match" (refused for a scoped caller).
105
+ */
106
+ export async function LoadSessionForAccess(
107
+ agentSessionId: string,
108
+ contextUser: UserInfo,
109
+ provider: IMetadataProvider,
110
+ ): Promise<LoadedSessionForAccess | null> {
111
+ if (!IsValidUUID(agentSessionId)) {
112
+ return null;
113
+ }
114
+ const session = await provider.GetEntityObject<MJAIAgentSessionEntity>(SESSION_ENTITY, contextUser);
115
+ if (!(await session.Load(agentSessionId))) {
116
+ return null;
117
+ }
118
+ return { Session: session, ConversationExternalID: await LoadSessionConversationExternalID(session, contextUser, provider) };
119
+ }
120
+
121
+ /**
122
+ * Reads an already-loaded session's conversation `ExternalID` (the anonymous scope id) under `contextUser`;
123
+ * null when there is no conversation or it cannot be read (logged). For callers that loaded the session
124
+ * through another gate and only need the scope half of {@link AuthorizeSessionAccess}'s subject.
125
+ */
126
+ export async function LoadSessionConversationExternalID(
127
+ session: MJAIAgentSessionEntity,
128
+ contextUser: UserInfo,
129
+ provider: IMetadataProvider,
130
+ ): Promise<string | null> {
131
+ if (!session.ConversationID) {
132
+ return null;
133
+ }
134
+ try {
135
+ const conversation = await provider.GetEntityObject<MJConversationEntity>(CONVERSATION_ENTITY, contextUser);
136
+ if (!(await conversation.Load(session.ConversationID))) {
137
+ return null;
138
+ }
139
+ return conversation.ExternalID ?? null;
140
+ } catch (error) {
141
+ const message = error instanceof Error ? error.message : String(error);
142
+ LogError(`LoadSessionForAccess: could not read conversation ${session.ConversationID} of session ${session.ID}: ${message}`);
143
+ return null;
144
+ }
145
+ }
@@ -0,0 +1,123 @@
1
+ /**
2
+ * @fileoverview What the session-start path stamps into a new realtime session's `Config` for identity
3
+ * verification: the policy snapshot, the unverified duration cap, and any verified identity carried
4
+ * forward from the session being resumed.
5
+ *
6
+ * Split in two so the decision is testable without a database:
7
+ *
8
+ * - {@link BuildMintConfigStamps} — **pure**. Given the resolved realtime config, the existing `Config`
9
+ * and an optional inherited identity, returns the `Config` to write (or `null` when there is nothing
10
+ * to stamp).
11
+ * - {@link LoadInheritedVerifiedIdentity} — the one read: the prior session's verified identity, only
12
+ * when the new caller is authorized on that prior session.
13
+ *
14
+ * Everything stamped here lives under server-authoritative keys (`identityVerification`,
15
+ * `maxSessionDeadlineIso`); the caller writes it inside `RunWithTrustedSessionConfigWrites`.
16
+ *
17
+ * ## Resume after the cap
18
+ *
19
+ * If an unverified session hits its cap before the person verifies, the janitor closes it. A verify link
20
+ * redeemed afterwards still records the verification on that (closed) session, and a **new** session
21
+ * started with `lastSessionId` pointing at it inherits the verified identity (and, with it, the
22
+ * `verifiedMaxSeconds` cap instead of the unverified one). Inheritance requires the same ownership/scope
23
+ * authorization as any other access to the prior session, so a stranger cannot adopt someone else's
24
+ * verification by naming their session id.
25
+ *
26
+ * @module @memberjunction/server/realtimeSessions
27
+ */
28
+
29
+ import type { IMetadataProvider, UserInfo } from '@memberjunction/core';
30
+ import { AuthorizeSessionAccess, LoadSessionForAccess } from './sessionAccess.js';
31
+ import {
32
+ ExtractIdentityVerificationPolicyFromRealtimeConfig,
33
+ ReadIdentityVerificationPolicyLayer,
34
+ TightenSessionDeadline,
35
+ } from './verificationPolicy.js';
36
+ import {
37
+ ParseConfigObject,
38
+ ReadIdentityVerificationState,
39
+ WriteIdentityVerificationState,
40
+ type IdentityVerificationState,
41
+ type VerifiedIdentity,
42
+ } from './verificationCore.js';
43
+
44
+ /** The `Config` to persist at session start. */
45
+ export interface MintConfigStampPlan {
46
+ NextConfigRaw: string;
47
+ }
48
+
49
+ /**
50
+ * Decides what to stamp into a freshly created session's `Config`.
51
+ *
52
+ * - **Policy snapshot.** The cascade's verification layer (`channels.config.IdentityVerification` plus the
53
+ * duration caps) is copied onto the session, so the rules a person is held to are fixed at mint,
54
+ * server-side, and cannot be chosen by the caller later.
55
+ * - **Duration cap.** When the cascade configures `unverifiedMaxSeconds` (or, for a session that inherited
56
+ * a verified identity, `verifiedMaxSeconds`), the session's absolute deadline is set to now + cap —
57
+ * applied to ANY principal, not only widget guests — and never loosens a tighter deadline already
58
+ * stamped (the widget voice cap).
59
+ * - **Inherited identity.** A verified identity carried forward from the resumed session.
60
+ *
61
+ * @param args.EffectiveRealtime - `EffectiveConfig.realtime` of the resolved config (any shape; read defensively)
62
+ * @param args.ExistingConfigRaw - the session's current `Config`
63
+ * @param args.InheritedVerified - verified identity from the session being resumed, if any
64
+ * @param args.NowMs - the current time, epoch ms
65
+ * @returns the `Config` to write, or `null` when nothing needs stamping
66
+ */
67
+ export function BuildMintConfigStamps(args: {
68
+ EffectiveRealtime: unknown;
69
+ ExistingConfigRaw: string | null;
70
+ InheritedVerified?: VerifiedIdentity;
71
+ NowMs: number;
72
+ }): MintConfigStampPlan | null {
73
+ const layer = ExtractIdentityVerificationPolicyFromRealtimeConfig(args.EffectiveRealtime);
74
+ const hasPolicy = Object.keys(layer).length > 0;
75
+ if (!hasPolicy && !args.InheritedVerified) {
76
+ return null;
77
+ }
78
+ const existingState = ReadIdentityVerificationState(args.ExistingConfigRaw, ReadIdentityVerificationPolicyLayer);
79
+ const state: IdentityVerificationState = {
80
+ ...existingState,
81
+ ...(hasPolicy ? { Policy: layer } : {}),
82
+ ...(args.InheritedVerified ? { Verified: args.InheritedVerified } : {}),
83
+ };
84
+ const capSeconds = args.InheritedVerified ? (layer.verifiedMaxSeconds ?? layer.unverifiedMaxSeconds) : layer.unverifiedMaxSeconds;
85
+ const existingDeadline = ParseConfigObject(args.ExistingConfigRaw)['maxSessionDeadlineIso'];
86
+ const deadlineIso = capSeconds
87
+ ? TightenSessionDeadline(typeof existingDeadline === 'string' ? existingDeadline : undefined, args.NowMs + capSeconds * 1000)
88
+ : undefined;
89
+ return { NextConfigRaw: WriteIdentityVerificationState(args.ExistingConfigRaw, state, deadlineIso) };
90
+ }
91
+
92
+ /**
93
+ * The verified identity of the session being resumed, when the caller may inherit it.
94
+ *
95
+ * Reads the prior session as the caller and requires {@link AuthorizeSessionAccess} to allow it; any
96
+ * failure (no such session, not the caller's, unreadable) yields `undefined` — inheritance is a
97
+ * convenience and must never block a session start.
98
+ *
99
+ * @param lastSessionId - the `lastSessionId` the client supplied at start
100
+ * @param contextUser - the starting caller
101
+ * @param provider - request-scoped provider
102
+ */
103
+ export async function LoadInheritedVerifiedIdentity(
104
+ lastSessionId: string | undefined,
105
+ contextUser: UserInfo,
106
+ provider: IMetadataProvider,
107
+ ): Promise<VerifiedIdentity | undefined> {
108
+ if (!lastSessionId) {
109
+ return undefined;
110
+ }
111
+ const prior = await LoadSessionForAccess(lastSessionId, contextUser, provider);
112
+ if (!prior) {
113
+ return undefined;
114
+ }
115
+ const decision = AuthorizeSessionAccess(
116
+ { SessionUserID: prior.Session.UserID, ConversationExternalID: prior.ConversationExternalID },
117
+ contextUser,
118
+ );
119
+ if (decision.Allowed === false) {
120
+ return undefined;
121
+ }
122
+ return ReadIdentityVerificationState(prior.Session.Config_, ReadIdentityVerificationPolicyLayer).Verified;
123
+ }
@@ -0,0 +1,116 @@
1
+ /**
2
+ * @fileoverview The authorization of the `RealtimeSessionEvents` subscription, free of GraphQL schema
3
+ * decorators and server configuration so it can be exercised — and reused — without loading either.
4
+ *
5
+ * It is applied twice on purpose (see `RealtimeSessionEventsResolver`): once when the subscription is
6
+ * opened ({@link AuthorizeRealtimeSessionSubscription}) and once for every event
7
+ * ({@link RealtimeSessionEventsFilter}). In neither check does a client-supplied value decide who
8
+ * receives anything: `agentSessionId` only selects WHICH of the caller's own sessions to listen to; the
9
+ * identity it is checked against comes from the server-authenticated connection context.
10
+ *
11
+ * @module @memberjunction/server/realtimeSessions
12
+ */
13
+
14
+ import { IMetadataProvider, LogError, Metadata, UserInfo } from '@memberjunction/core';
15
+ import { IsValidUUID, UUIDsEqual } from '@memberjunction/global';
16
+ import type { UserPayload } from '../types.js';
17
+ import { AuthorizeSessionAccess, LoadSessionForAccess, type LoadedSessionForAccess } from './sessionAccess.js';
18
+ import type { RealtimeSessionEventTopicPayload } from './RealtimeSessionEventService.js';
19
+
20
+ /**
21
+ * Arguments of the subscription. `agentSessionId` is camelCase because it is the GraphQL argument name
22
+ * graphql-js hands to `subscribe` and to the filter — it is the wire contract, not an API of ours.
23
+ */
24
+ export interface RealtimeSessionEventsArgs {
25
+ agentSessionId?: string;
26
+ }
27
+
28
+ /**
29
+ * The slice of the WebSocket connection context the authorization reads. `userPayload` is camelCase to
30
+ * match `AppContext.userPayload`, the member graphql-ws populates and every resolver already destructures.
31
+ */
32
+ export interface RealtimeSessionEventsContext {
33
+ userPayload?: UserPayload;
34
+ }
35
+
36
+ /** Why a subscription request was refused (logged; the client always gets the same message). */
37
+ const REFUSAL_MESSAGE = 'Realtime session not found.';
38
+
39
+ /** The principal the connection authenticated as, or undefined. */
40
+ function connectionPrincipal(context: RealtimeSessionEventsContext | undefined): UserInfo | undefined {
41
+ return context?.userPayload?.userRecord as UserInfo | undefined;
42
+ }
43
+
44
+ /**
45
+ * Per-event filter. Exported because it is the security-critical gate and must be testable in isolation.
46
+ *
47
+ * An event reaches a subscriber only when BOTH hold:
48
+ * 1. it is addressed to the session the subscriber asked for, and
49
+ * 2. the event's owner/scope snapshot passes {@link AuthorizeSessionAccess} for the connection's
50
+ * authenticated principal.
51
+ *
52
+ * Fails closed: a missing connection identity, a missing owner on the event, or a missing argument never matches.
53
+ */
54
+ export function RealtimeSessionEventsFilter(data: {
55
+ payload: RealtimeSessionEventTopicPayload;
56
+ args: RealtimeSessionEventsArgs;
57
+ context: RealtimeSessionEventsContext | undefined;
58
+ }): boolean {
59
+ const { payload, args, context } = data;
60
+ if (typeof args?.agentSessionId !== 'string' || !payload?.AgentSessionID || !UUIDsEqual(payload.AgentSessionID, args.agentSessionId)) {
61
+ return false;
62
+ }
63
+ const decision = AuthorizeSessionAccess(
64
+ { SessionUserID: payload.OwnerUserID, ConversationExternalID: payload.ScopeKey },
65
+ connectionPrincipal(context),
66
+ );
67
+ return decision.Allowed;
68
+ }
69
+
70
+ /** Dependencies of {@link AuthorizeRealtimeSessionSubscription}, injectable for tests. */
71
+ export interface SubscriptionAuthorizationDeps {
72
+ /** Loads a session under the caller's identity. */
73
+ LoadSession: (agentSessionId: string, user: UserInfo, provider: IMetadataProvider) => Promise<LoadedSessionForAccess | null>;
74
+ /** The provider to read with (a WebSocket context carries no request-scoped providers). */
75
+ GetProvider: () => IMetadataProvider;
76
+ }
77
+
78
+ /** Production dependencies. */
79
+ export const DEFAULT_SUBSCRIPTION_AUTHORIZATION_DEPS: SubscriptionAuthorizationDeps = {
80
+ LoadSession: LoadSessionForAccess,
81
+ GetProvider: () => Metadata.Provider, // global-provider-ok: a WebSocket subscription context has no per-request providers
82
+ };
83
+
84
+ /**
85
+ * Subscribe-time authorization: loads the session as the connection's principal and requires
86
+ * {@link AuthorizeSessionAccess} to allow it. Throws {@link REFUSAL_MESSAGE} (uniformly) otherwise.
87
+ *
88
+ * @param args - the subscription arguments
89
+ * @param context - the connection context (server-authenticated)
90
+ * @param deps - injectable dependencies (tests)
91
+ * @returns the validated session id
92
+ */
93
+ export async function AuthorizeRealtimeSessionSubscription(
94
+ args: RealtimeSessionEventsArgs,
95
+ context: RealtimeSessionEventsContext | undefined,
96
+ deps: SubscriptionAuthorizationDeps = DEFAULT_SUBSCRIPTION_AUTHORIZATION_DEPS,
97
+ ): Promise<string> {
98
+ const principal = connectionPrincipal(context);
99
+ const agentSessionId = args?.agentSessionId;
100
+ if (!principal || typeof agentSessionId !== 'string' || !IsValidUUID(agentSessionId)) {
101
+ throw new Error(REFUSAL_MESSAGE);
102
+ }
103
+ const loaded = await deps.LoadSession(agentSessionId, principal, deps.GetProvider());
104
+ if (!loaded) {
105
+ throw new Error(REFUSAL_MESSAGE);
106
+ }
107
+ const decision = AuthorizeSessionAccess(
108
+ { SessionUserID: loaded.Session.UserID, ConversationExternalID: loaded.ConversationExternalID },
109
+ principal,
110
+ );
111
+ if (decision.Allowed === false) {
112
+ LogError(`RealtimeSessionEvents: refused subscription by user ${principal.ID} to session ${agentSessionId} (${decision.Reason}).`);
113
+ throw new Error(REFUSAL_MESSAGE);
114
+ }
115
+ return agentSessionId;
116
+ }