@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,57 @@
1
+ /**
2
+ * @fileoverview A small in-memory sliding-window rate limiter keyed by string, with an injectable
3
+ * clock so it is deterministic under test.
4
+ *
5
+ * Used for the limits that the HTTP-layer `express-rate-limit` cannot express because the request is a
6
+ * GraphQL mutation (per IP / per email domain / per recipient on verification sends, and per session on
7
+ * code attempts). The HTTP verify route uses `express-rate-limit` directly, the same way the widget
8
+ * and magic-link routers do.
9
+ *
10
+ * **Per-instance, best-effort.** State is in process memory, so with several server replicas each
11
+ * enforces its own budget. That is the same trade the widget mint limiter makes. The limits that must
12
+ * hold across replicas — sends per session and code attempts per verification — are NOT here: they are
13
+ * persisted on the session (`identityVerification`) and enforced from the database.
14
+ *
15
+ * @module @memberjunction/server/realtimeSessions
16
+ */
17
+ /** Outcome of {@link SlidingWindowRateLimiter.TryConsume}. */
18
+ export interface RateLimitDecision {
19
+ /** True when the event fits the budget (and was counted). */
20
+ Allowed: boolean;
21
+ /** When refused, ms until the oldest counted event leaves the window. 0 when allowed. */
22
+ RetryAfterMs: number;
23
+ }
24
+ /** Construction options. */
25
+ export interface SlidingWindowRateLimiterOptions {
26
+ /** Events allowed per key per window. A limit of 0 or less disables the limiter (everything allowed). */
27
+ Limit: number;
28
+ /** Window length in ms. */
29
+ WindowMs: number;
30
+ /** Upper bound on distinct keys held in memory; the oldest-seen keys are evicted past it. Default 10 000. */
31
+ MaxKeys?: number;
32
+ }
33
+ /**
34
+ * Counts events per key over a sliding window.
35
+ *
36
+ * Memory is bounded two ways: a key's timestamps older than the window are dropped whenever the key is
37
+ * touched, and when the number of keys exceeds `MaxKeys` the least-recently-inserted keys are evicted
38
+ * (an evicted key simply starts a fresh window — the limiter fails open by forgetting, never closed).
39
+ */
40
+ export declare class SlidingWindowRateLimiter {
41
+ private readonly options;
42
+ private readonly events;
43
+ private readonly maxKeys;
44
+ constructor(options: SlidingWindowRateLimiterOptions);
45
+ /**
46
+ * Counts one event for `key` if the budget allows.
47
+ *
48
+ * @param key - what is being limited (an IP, a domain, a session id…); callers normalise it
49
+ * @param nowMs - the current time, epoch ms
50
+ */
51
+ TryConsume(key: string, nowMs: number): RateLimitDecision;
52
+ /** Number of keys currently tracked (exposed for tests and diagnostics). */
53
+ get TrackedKeyCount(): number;
54
+ /** Re-inserts `key` (moving it to the newest position) and evicts the oldest keys past the bound. */
55
+ private store;
56
+ }
57
+ //# sourceMappingURL=SlidingWindowRateLimiter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SlidingWindowRateLimiter.d.ts","sourceRoot":"","sources":["../../src/realtimeSessions/SlidingWindowRateLimiter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,8DAA8D;AAC9D,MAAM,WAAW,iBAAiB;IAC9B,6DAA6D;IAC7D,OAAO,EAAE,OAAO,CAAC;IACjB,yFAAyF;IACzF,YAAY,EAAE,MAAM,CAAC;CACxB;AAED,4BAA4B;AAC5B,MAAM,WAAW,+BAA+B;IAC5C,yGAAyG;IACzG,KAAK,EAAE,MAAM,CAAC;IACd,2BAA2B;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,6GAA6G;IAC7G,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAKD;;;;;;GAMG;AACH,qBAAa,wBAAwB;IAIrB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAHpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA+B;IACtD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAEJ,OAAO,EAAE,+BAA+B;IAIrE;;;;;OAKG;IACI,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,iBAAiB;IAehE,4EAA4E;IAC5E,IAAW,eAAe,IAAI,MAAM,CAEnC;IAED,qGAAqG;IACrG,OAAO,CAAC,KAAK;CAWhB"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * @fileoverview A small in-memory sliding-window rate limiter keyed by string, with an injectable
3
+ * clock so it is deterministic under test.
4
+ *
5
+ * Used for the limits that the HTTP-layer `express-rate-limit` cannot express because the request is a
6
+ * GraphQL mutation (per IP / per email domain / per recipient on verification sends, and per session on
7
+ * code attempts). The HTTP verify route uses `express-rate-limit` directly, the same way the widget
8
+ * and magic-link routers do.
9
+ *
10
+ * **Per-instance, best-effort.** State is in process memory, so with several server replicas each
11
+ * enforces its own budget. That is the same trade the widget mint limiter makes. The limits that must
12
+ * hold across replicas — sends per session and code attempts per verification — are NOT here: they are
13
+ * persisted on the session (`identityVerification`) and enforced from the database.
14
+ *
15
+ * @module @memberjunction/server/realtimeSessions
16
+ */
17
+ /** Default bound on distinct keys held. */
18
+ const DEFAULT_MAX_KEYS = 10_000;
19
+ /**
20
+ * Counts events per key over a sliding window.
21
+ *
22
+ * Memory is bounded two ways: a key's timestamps older than the window are dropped whenever the key is
23
+ * touched, and when the number of keys exceeds `MaxKeys` the least-recently-inserted keys are evicted
24
+ * (an evicted key simply starts a fresh window — the limiter fails open by forgetting, never closed).
25
+ */
26
+ export class SlidingWindowRateLimiter {
27
+ constructor(options) {
28
+ this.options = options;
29
+ this.events = new Map();
30
+ this.maxKeys = options.MaxKeys ?? DEFAULT_MAX_KEYS;
31
+ }
32
+ /**
33
+ * Counts one event for `key` if the budget allows.
34
+ *
35
+ * @param key - what is being limited (an IP, a domain, a session id…); callers normalise it
36
+ * @param nowMs - the current time, epoch ms
37
+ */
38
+ TryConsume(key, nowMs) {
39
+ if (this.options.Limit <= 0) {
40
+ return { Allowed: true, RetryAfterMs: 0 };
41
+ }
42
+ const windowStart = nowMs - this.options.WindowMs;
43
+ const live = (this.events.get(key) ?? []).filter((t) => t > windowStart);
44
+ if (live.length >= this.options.Limit) {
45
+ this.store(key, live);
46
+ return { Allowed: false, RetryAfterMs: Math.max(0, live[0] + this.options.WindowMs - nowMs) };
47
+ }
48
+ live.push(nowMs);
49
+ this.store(key, live);
50
+ return { Allowed: true, RetryAfterMs: 0 };
51
+ }
52
+ /** Number of keys currently tracked (exposed for tests and diagnostics). */
53
+ get TrackedKeyCount() {
54
+ return this.events.size;
55
+ }
56
+ /** Re-inserts `key` (moving it to the newest position) and evicts the oldest keys past the bound. */
57
+ store(key, timestamps) {
58
+ this.events.delete(key);
59
+ this.events.set(key, timestamps);
60
+ while (this.events.size > this.maxKeys) {
61
+ const oldest = this.events.keys().next();
62
+ if (oldest.done) {
63
+ break;
64
+ }
65
+ this.events.delete(oldest.value);
66
+ }
67
+ }
68
+ }
69
+ //# sourceMappingURL=SlidingWindowRateLimiter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SlidingWindowRateLimiter.js","sourceRoot":"","sources":["../../src/realtimeSessions/SlidingWindowRateLimiter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAoBH,2CAA2C;AAC3C,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEhC;;;;;;GAMG;AACH,MAAM,OAAO,wBAAwB;IAIjC,YAA6B,OAAwC;QAAxC,YAAO,GAAP,OAAO,CAAiC;QAHpD,WAAM,GAAG,IAAI,GAAG,EAAoB,CAAC;QAIlD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,gBAAgB,CAAC;IACvD,CAAC;IAED;;;;;OAKG;IACI,UAAU,CAAC,GAAW,EAAE,KAAa;QACxC,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC;YAC1B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC;QAC9C,CAAC;QACD,MAAM,WAAW,GAAG,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;QAClD,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC;QACzE,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACpC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACtB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,GAAG,KAAK,CAAC,EAAE,CAAC;QAClG,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjB,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACtB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC;IAC9C,CAAC;IAED,4EAA4E;IAC5E,IAAW,eAAe;QACtB,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;IAC5B,CAAC;IAED,qGAAqG;IAC7F,KAAK,CAAC,GAAW,EAAE,UAAoB;QAC3C,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACxB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QACjC,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YACrC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;YACzC,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;gBACd,MAAM;YACV,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACrC,CAAC;IACL,CAAC;CACJ"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @fileoverview Realtime session events + mid-session identity verification — module barrel.
3
+ * @module @memberjunction/server/realtimeSessions
4
+ */
5
+ export * from './sessionAccess.js';
6
+ export * from './subscriptionAuthorization.js';
7
+ export * from './RealtimeSessionEventService.js';
8
+ export * from './verificationPolicy.js';
9
+ export * from './verificationCore.js';
10
+ export * from './SlidingWindowRateLimiter.js';
11
+ export * from './verificationPages.js';
12
+ export * from './verificationWorkflow.js';
13
+ export * from './sessionConfigStamps.js';
14
+ export * from './SessionVerificationPortsBase.js';
15
+ export * from './RealtimeSessionVerificationService.js';
16
+ export * from './RealtimeVerifyRouter.js';
17
+ export * from './ownedRealtimeSession.js';
18
+ export * from './RecordingAssemblyScheduler.js';
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/realtimeSessions/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,cAAc,oBAAoB,CAAC;AACnC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,kCAAkC,CAAC;AACjD,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,mCAAmC,CAAC;AAClD,cAAc,yCAAyC,CAAC;AACxD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iCAAiC,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @fileoverview Realtime session events + mid-session identity verification — module barrel.
3
+ * @module @memberjunction/server/realtimeSessions
4
+ */
5
+ export * from './sessionAccess.js';
6
+ export * from './subscriptionAuthorization.js';
7
+ export * from './RealtimeSessionEventService.js';
8
+ export * from './verificationPolicy.js';
9
+ export * from './verificationCore.js';
10
+ export * from './SlidingWindowRateLimiter.js';
11
+ export * from './verificationPages.js';
12
+ export * from './verificationWorkflow.js';
13
+ export * from './sessionConfigStamps.js';
14
+ export * from './SessionVerificationPortsBase.js';
15
+ export * from './RealtimeSessionVerificationService.js';
16
+ export * from './RealtimeVerifyRouter.js';
17
+ export * from './ownedRealtimeSession.js';
18
+ export * from './RecordingAssemblyScheduler.js';
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/realtimeSessions/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,cAAc,oBAAoB,CAAC;AACnC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,kCAAkC,CAAC;AACjD,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,mCAAmC,CAAC;AAClD,cAAc,yCAAyC,CAAC;AACxD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iCAAiC,CAAC"}
@@ -0,0 +1,30 @@
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, UserInfo } from '@memberjunction/core';
9
+ import type { MJAIAgentSessionEntity } from '@memberjunction/core-entities';
10
+ /** The session does not exist, or the caller cannot read it. */
11
+ export declare class RealtimeSessionNotFoundError extends Error {
12
+ readonly AgentSessionID: string;
13
+ constructor(AgentSessionID: string);
14
+ }
15
+ /** The session exists but belongs to another user. */
16
+ export declare class RealtimeSessionOwnershipError extends Error {
17
+ readonly AgentSessionID: string;
18
+ constructor(AgentSessionID: string);
19
+ }
20
+ /**
21
+ * Loads a session under the caller's identity and enforces ownership (`UserID === contextUser.ID`). It
22
+ * deliberately does NOT reject `Closed` sessions: the final channel-state flush and the recording terminal
23
+ * signal legitimately arrive after the session closed. A scoped-anonymous widget guest owns the session it
24
+ * minted, so the same check covers it; loading as the caller also applies the entity's row-level security.
25
+ *
26
+ * @throws RealtimeSessionNotFoundError when the row does not load
27
+ * @throws RealtimeSessionOwnershipError when the caller is not the owner (logged with both user ids)
28
+ */
29
+ export declare function LoadOwnedRealtimeSession(agentSessionId: string, contextUser: UserInfo, provider: IMetadataProvider): Promise<MJAIAgentSessionEntity>;
30
+ //# sourceMappingURL=ownedRealtimeSession.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ownedRealtimeSession.d.ts","sourceRoot":"","sources":["../../src/realtimeSessions/ownedRealtimeSession.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,iBAAiB,EAAY,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAE7E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAI5E,gEAAgE;AAChE,qBAAa,4BAA6B,SAAQ,KAAK;aACvB,cAAc,EAAE,MAAM;gBAAtB,cAAc,EAAE,MAAM;CAIrD;AAED,sDAAsD;AACtD,qBAAa,6BAA8B,SAAQ,KAAK;aACxB,cAAc,EAAE,MAAM;gBAAtB,cAAc,EAAE,MAAM;CAIrD;AAED;;;;;;;;GAQG;AACH,wBAAsB,wBAAwB,CAC1C,cAAc,EAAE,MAAM,EACtB,WAAW,EAAE,QAAQ,EACrB,QAAQ,EAAE,iBAAiB,GAC5B,OAAO,CAAC,sBAAsB,CAAC,CAYjC"}
@@ -0,0 +1,47 @@
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 { LogError } from '@memberjunction/core';
9
+ import { UUIDsEqual } from '@memberjunction/global';
10
+ const SESSION_ENTITY = 'MJ: AI Agent Sessions';
11
+ /** The session does not exist, or the caller cannot read it. */
12
+ export class RealtimeSessionNotFoundError extends Error {
13
+ constructor(AgentSessionID) {
14
+ super(`Realtime session ${AgentSessionID} not found`);
15
+ this.AgentSessionID = AgentSessionID;
16
+ this.name = 'RealtimeSessionNotFoundError';
17
+ }
18
+ }
19
+ /** The session exists but belongs to another user. */
20
+ export class RealtimeSessionOwnershipError extends Error {
21
+ constructor(AgentSessionID) {
22
+ super('Not authorized: you do not own this realtime session');
23
+ this.AgentSessionID = AgentSessionID;
24
+ this.name = 'RealtimeSessionOwnershipError';
25
+ }
26
+ }
27
+ /**
28
+ * Loads a session under the caller's identity and enforces ownership (`UserID === contextUser.ID`). It
29
+ * deliberately does NOT reject `Closed` sessions: the final channel-state flush and the recording terminal
30
+ * signal legitimately arrive after the session closed. A scoped-anonymous widget guest owns the session it
31
+ * minted, so the same check covers it; loading as the caller also applies the entity's row-level security.
32
+ *
33
+ * @throws RealtimeSessionNotFoundError when the row does not load
34
+ * @throws RealtimeSessionOwnershipError when the caller is not the owner (logged with both user ids)
35
+ */
36
+ export async function LoadOwnedRealtimeSession(agentSessionId, contextUser, provider) {
37
+ const session = await provider.GetEntityObject(SESSION_ENTITY, contextUser);
38
+ if (!(await session.Load(agentSessionId))) {
39
+ throw new RealtimeSessionNotFoundError(agentSessionId);
40
+ }
41
+ if (!UUIDsEqual(session.UserID, contextUser.ID)) {
42
+ LogError(`LoadOwnedRealtimeSession: ownership check failed — user ${contextUser.ID} attempted to operate on session ${agentSessionId} owned by ${session.UserID}`);
43
+ throw new RealtimeSessionOwnershipError(agentSessionId);
44
+ }
45
+ return session;
46
+ }
47
+ //# sourceMappingURL=ownedRealtimeSession.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ownedRealtimeSession.js","sourceRoot":"","sources":["../../src/realtimeSessions/ownedRealtimeSession.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAqB,QAAQ,EAAY,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGpD,MAAM,cAAc,GAAG,uBAAuB,CAAC;AAE/C,gEAAgE;AAChE,MAAM,OAAO,4BAA6B,SAAQ,KAAK;IACnD,YAA4B,cAAsB;QAC9C,KAAK,CAAC,oBAAoB,cAAc,YAAY,CAAC,CAAC;QAD9B,mBAAc,GAAd,cAAc,CAAQ;QAE9C,IAAI,CAAC,IAAI,GAAG,8BAA8B,CAAC;IAC/C,CAAC;CACJ;AAED,sDAAsD;AACtD,MAAM,OAAO,6BAA8B,SAAQ,KAAK;IACpD,YAA4B,cAAsB;QAC9C,KAAK,CAAC,sDAAsD,CAAC,CAAC;QADtC,mBAAc,GAAd,cAAc,CAAQ;QAE9C,IAAI,CAAC,IAAI,GAAG,+BAA+B,CAAC;IAChD,CAAC;CACJ;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC1C,cAAsB,EACtB,WAAqB,EACrB,QAA2B;IAE3B,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,eAAe,CAAyB,cAAc,EAAE,WAAW,CAAC,CAAC;IACpG,IAAI,CAAC,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,4BAA4B,CAAC,cAAc,CAAC,CAAC;IAC3D,CAAC;IACD,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,CAAC,EAAE,CAAC;QAC9C,QAAQ,CACJ,2DAA2D,WAAW,CAAC,EAAE,oCAAoC,cAAc,aAAa,OAAO,CAAC,MAAM,EAAE,CAC3J,CAAC;QACF,MAAM,IAAI,6BAA6B,CAAC,cAAc,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,OAAO,CAAC;AACnB,CAAC"}
@@ -0,0 +1,92 @@
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
+ import { IMetadataProvider, UserInfo } from '@memberjunction/core';
26
+ import type { MJAIAgentSessionEntity } from '@memberjunction/core-entities';
27
+ /** What the decision needs to know about the session. */
28
+ export interface SessionAccessSubject {
29
+ /** `AIAgentSession.UserID`. */
30
+ SessionUserID: string;
31
+ /**
32
+ * `Conversation.ExternalID` of the session's conversation — the signed per-session scope id for an
33
+ * anonymous guest. `null`/`undefined` when the conversation has none (a named user's session) or
34
+ * could not be loaded.
35
+ */
36
+ ConversationExternalID: string | null | undefined;
37
+ }
38
+ /** What the decision needs to know about the caller (a subset of `UserInfo`). */
39
+ export interface SessionAccessPrincipal {
40
+ /** The caller's user id. */
41
+ ID: string;
42
+ /** True for the shared-Anonymous-user principal of a public-widget guest. */
43
+ IsMagicLinkAnonymous?: boolean;
44
+ /** The signed per-session scope carried by the caller's token, when any. */
45
+ MagicLinkScope?: {
46
+ ResourceID?: string;
47
+ } | undefined;
48
+ }
49
+ /** Why access was refused. Callers log the reason; clients get a uniform refusal. */
50
+ export type SessionAccessRefusal = 'not_owner' | 'scope_missing' | 'scope_mismatch';
51
+ /** Outcome of {@link AuthorizeSessionAccess}. */
52
+ export type SessionAccessDecision = {
53
+ Allowed: true;
54
+ } | {
55
+ Allowed: false;
56
+ Reason: SessionAccessRefusal;
57
+ };
58
+ /**
59
+ * Decides whether `principal` may address the session described by `subject`.
60
+ *
61
+ * Fails closed: anything that cannot be positively matched is refused.
62
+ *
63
+ * @param subject - owner + scope of the session
64
+ * @param principal - the authenticated caller (from the server-built `UserInfo`, never from client args)
65
+ */
66
+ export declare function AuthorizeSessionAccess(subject: SessionAccessSubject, principal: SessionAccessPrincipal | null | undefined): SessionAccessDecision;
67
+ /** A session row together with the one fact about its conversation the decision needs. */
68
+ export interface LoadedSessionForAccess {
69
+ /** The session entity, loaded under the caller's own identity (so RLS applied to the read). */
70
+ Session: MJAIAgentSessionEntity;
71
+ /** The session's conversation `ExternalID` (anonymous scope id), or null. */
72
+ ConversationExternalID: string | null;
73
+ }
74
+ /**
75
+ * Loads a session (and its conversation's scope id) under `contextUser`'s identity.
76
+ *
77
+ * Loading as the caller — rather than as a privileged user — means the entity layer's row-level
78
+ * security (`Widget Guest: Own Agent Sessions`, `UI: Own Agent Sessions`) is the FIRST gate; the
79
+ * explicit {@link AuthorizeSessionAccess} check that follows is defence in depth.
80
+ *
81
+ * @returns the loaded session, or `null` when the id is malformed, the row does not exist, or the
82
+ * caller cannot read it. Failure to read the conversation yields `ConversationExternalID: null`,
83
+ * which {@link AuthorizeSessionAccess} then treats as "no scope to match" (refused for a scoped caller).
84
+ */
85
+ export declare function LoadSessionForAccess(agentSessionId: string, contextUser: UserInfo, provider: IMetadataProvider): Promise<LoadedSessionForAccess | null>;
86
+ /**
87
+ * Reads an already-loaded session's conversation `ExternalID` (the anonymous scope id) under `contextUser`;
88
+ * null when there is no conversation or it cannot be read (logged). For callers that loaded the session
89
+ * through another gate and only need the scope half of {@link AuthorizeSessionAccess}'s subject.
90
+ */
91
+ export declare function LoadSessionConversationExternalID(session: MJAIAgentSessionEntity, contextUser: UserInfo, provider: IMetadataProvider): Promise<string | null>;
92
+ //# sourceMappingURL=sessionAccess.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessionAccess.d.ts","sourceRoot":"","sources":["../../src/realtimeSessions/sessionAccess.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,iBAAiB,EAAY,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAE7E,OAAO,KAAK,EAAE,sBAAsB,EAAwB,MAAM,+BAA+B,CAAC;AAMlG,yDAAyD;AACzD,MAAM,WAAW,oBAAoB;IACjC,+BAA+B;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,sBAAsB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CACrD;AAED,iFAAiF;AACjF,MAAM,WAAW,sBAAsB;IACnC,4BAA4B;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,6EAA6E;IAC7E,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,4EAA4E;IAC5E,cAAc,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;CACxD;AAED,qFAAqF;AACrF,MAAM,MAAM,oBAAoB,GAAG,WAAW,GAAG,eAAe,GAAG,gBAAgB,CAAC;AAEpF,iDAAiD;AACjD,MAAM,MAAM,qBAAqB,GAAG;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,oBAAoB,CAAA;CAAE,CAAC;AAEzG;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAClC,OAAO,EAAE,oBAAoB,EAC7B,SAAS,EAAE,sBAAsB,GAAG,IAAI,GAAG,SAAS,GACrD,qBAAqB,CAYvB;AAED,0FAA0F;AAC1F,MAAM,WAAW,sBAAsB;IACnC,+FAA+F;IAC/F,OAAO,EAAE,sBAAsB,CAAC;IAChC,6EAA6E;IAC7E,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAC;CACzC;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,oBAAoB,CACtC,cAAc,EAAE,MAAM,EACtB,WAAW,EAAE,QAAQ,EACrB,QAAQ,EAAE,iBAAiB,GAC5B,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC,CASxC;AAED;;;;GAIG;AACH,wBAAsB,iCAAiC,CACnD,OAAO,EAAE,sBAAsB,EAC/B,WAAW,EAAE,QAAQ,EACrB,QAAQ,EAAE,iBAAiB,GAC5B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAexB"}
@@ -0,0 +1,94 @@
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
+ import { LogError } from '@memberjunction/core';
26
+ import { IsValidUUID, UUIDsEqual } from '@memberjunction/global';
27
+ /** Entity names, centralised so the `MJ: ` prefix convention lives in one place. */
28
+ const SESSION_ENTITY = 'MJ: AI Agent Sessions';
29
+ const CONVERSATION_ENTITY = 'MJ: Conversations';
30
+ /**
31
+ * Decides whether `principal` may address the session described by `subject`.
32
+ *
33
+ * Fails closed: anything that cannot be positively matched is refused.
34
+ *
35
+ * @param subject - owner + scope of the session
36
+ * @param principal - the authenticated caller (from the server-built `UserInfo`, never from client args)
37
+ */
38
+ export function AuthorizeSessionAccess(subject, principal) {
39
+ if (!principal?.ID || !subject.SessionUserID || !UUIDsEqual(subject.SessionUserID, principal.ID)) {
40
+ return { Allowed: false, Reason: 'not_owner' };
41
+ }
42
+ const scopeId = principal.MagicLinkScope?.ResourceID;
43
+ if (!scopeId) {
44
+ // An anonymous principal without a per-session scope is indistinguishable from every other
45
+ // anonymous principal: owning "the Anonymous user's" session proves nothing.
46
+ return principal.IsMagicLinkAnonymous ? { Allowed: false, Reason: 'scope_missing' } : { Allowed: true };
47
+ }
48
+ // Scope ids are opaque base64url strings (case-significant), so compare exactly — not UUIDsEqual.
49
+ return subject.ConversationExternalID === scopeId ? { Allowed: true } : { Allowed: false, Reason: 'scope_mismatch' };
50
+ }
51
+ /**
52
+ * Loads a session (and its conversation's scope id) under `contextUser`'s identity.
53
+ *
54
+ * Loading as the caller — rather than as a privileged user — means the entity layer's row-level
55
+ * security (`Widget Guest: Own Agent Sessions`, `UI: Own Agent Sessions`) is the FIRST gate; the
56
+ * explicit {@link AuthorizeSessionAccess} check that follows is defence in depth.
57
+ *
58
+ * @returns the loaded session, or `null` when the id is malformed, the row does not exist, or the
59
+ * caller cannot read it. Failure to read the conversation yields `ConversationExternalID: null`,
60
+ * which {@link AuthorizeSessionAccess} then treats as "no scope to match" (refused for a scoped caller).
61
+ */
62
+ export async function LoadSessionForAccess(agentSessionId, contextUser, provider) {
63
+ if (!IsValidUUID(agentSessionId)) {
64
+ return null;
65
+ }
66
+ const session = await provider.GetEntityObject(SESSION_ENTITY, contextUser);
67
+ if (!(await session.Load(agentSessionId))) {
68
+ return null;
69
+ }
70
+ return { Session: session, ConversationExternalID: await LoadSessionConversationExternalID(session, contextUser, provider) };
71
+ }
72
+ /**
73
+ * Reads an already-loaded session's conversation `ExternalID` (the anonymous scope id) under `contextUser`;
74
+ * null when there is no conversation or it cannot be read (logged). For callers that loaded the session
75
+ * through another gate and only need the scope half of {@link AuthorizeSessionAccess}'s subject.
76
+ */
77
+ export async function LoadSessionConversationExternalID(session, contextUser, provider) {
78
+ if (!session.ConversationID) {
79
+ return null;
80
+ }
81
+ try {
82
+ const conversation = await provider.GetEntityObject(CONVERSATION_ENTITY, contextUser);
83
+ if (!(await conversation.Load(session.ConversationID))) {
84
+ return null;
85
+ }
86
+ return conversation.ExternalID ?? null;
87
+ }
88
+ catch (error) {
89
+ const message = error instanceof Error ? error.message : String(error);
90
+ LogError(`LoadSessionForAccess: could not read conversation ${session.ConversationID} of session ${session.ID}: ${message}`);
91
+ return null;
92
+ }
93
+ }
94
+ //# sourceMappingURL=sessionAccess.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessionAccess.js","sourceRoot":"","sources":["../../src/realtimeSessions/sessionAccess.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAqB,QAAQ,EAAY,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGjE,oFAAoF;AACpF,MAAM,cAAc,GAAG,uBAAuB,CAAC;AAC/C,MAAM,mBAAmB,GAAG,mBAAmB,CAAC;AA8BhD;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CAClC,OAA6B,EAC7B,SAAoD;IAEpD,IAAI,CAAC,SAAS,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,aAAa,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,aAAa,EAAE,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC;QAC/F,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IACnD,CAAC;IACD,MAAM,OAAO,GAAG,SAAS,CAAC,cAAc,EAAE,UAAU,CAAC;IACrD,IAAI,CAAC,OAAO,EAAE,CAAC;QACX,2FAA2F;QAC3F,6EAA6E;QAC7E,OAAO,SAAS,CAAC,oBAAoB,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC5G,CAAC;IACD,kGAAkG;IAClG,OAAO,OAAO,CAAC,sBAAsB,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC;AACzH,CAAC;AAUD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACtC,cAAsB,EACtB,WAAqB,EACrB,QAA2B;IAE3B,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,eAAe,CAAyB,cAAc,EAAE,WAAW,CAAC,CAAC;IACpG,IAAI,CAAC,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC;QACxC,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,CAAC,EAAE,CAAC;AACjI,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,iCAAiC,CACnD,OAA+B,EAC/B,WAAqB,EACrB,QAA2B;IAE3B,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,IAAI,CAAC;QACD,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,eAAe,CAAuB,mBAAmB,EAAE,WAAW,CAAC,CAAC;QAC5G,IAAI,CAAC,CAAC,MAAM,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC;YACrD,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,OAAO,YAAY,CAAC,UAAU,IAAI,IAAI,CAAC;IAC3C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,QAAQ,CAAC,qDAAqD,OAAO,CAAC,cAAc,eAAe,OAAO,CAAC,EAAE,KAAK,OAAO,EAAE,CAAC,CAAC;QAC7H,OAAO,IAAI,CAAC;IAChB,CAAC;AACL,CAAC"}
@@ -0,0 +1,70 @@
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
+ import type { IMetadataProvider, UserInfo } from '@memberjunction/core';
29
+ import { type VerifiedIdentity } from './verificationCore.js';
30
+ /** The `Config` to persist at session start. */
31
+ export interface MintConfigStampPlan {
32
+ NextConfigRaw: string;
33
+ }
34
+ /**
35
+ * Decides what to stamp into a freshly created session's `Config`.
36
+ *
37
+ * - **Policy snapshot.** The cascade's verification layer (`channels.config.IdentityVerification` plus the
38
+ * duration caps) is copied onto the session, so the rules a person is held to are fixed at mint,
39
+ * server-side, and cannot be chosen by the caller later.
40
+ * - **Duration cap.** When the cascade configures `unverifiedMaxSeconds` (or, for a session that inherited
41
+ * a verified identity, `verifiedMaxSeconds`), the session's absolute deadline is set to now + cap —
42
+ * applied to ANY principal, not only widget guests — and never loosens a tighter deadline already
43
+ * stamped (the widget voice cap).
44
+ * - **Inherited identity.** A verified identity carried forward from the resumed session.
45
+ *
46
+ * @param args.EffectiveRealtime - `EffectiveConfig.realtime` of the resolved config (any shape; read defensively)
47
+ * @param args.ExistingConfigRaw - the session's current `Config`
48
+ * @param args.InheritedVerified - verified identity from the session being resumed, if any
49
+ * @param args.NowMs - the current time, epoch ms
50
+ * @returns the `Config` to write, or `null` when nothing needs stamping
51
+ */
52
+ export declare function BuildMintConfigStamps(args: {
53
+ EffectiveRealtime: unknown;
54
+ ExistingConfigRaw: string | null;
55
+ InheritedVerified?: VerifiedIdentity;
56
+ NowMs: number;
57
+ }): MintConfigStampPlan | null;
58
+ /**
59
+ * The verified identity of the session being resumed, when the caller may inherit it.
60
+ *
61
+ * Reads the prior session as the caller and requires {@link AuthorizeSessionAccess} to allow it; any
62
+ * failure (no such session, not the caller's, unreadable) yields `undefined` — inheritance is a
63
+ * convenience and must never block a session start.
64
+ *
65
+ * @param lastSessionId - the `lastSessionId` the client supplied at start
66
+ * @param contextUser - the starting caller
67
+ * @param provider - request-scoped provider
68
+ */
69
+ export declare function LoadInheritedVerifiedIdentity(lastSessionId: string | undefined, contextUser: UserInfo, provider: IMetadataProvider): Promise<VerifiedIdentity | undefined>;
70
+ //# sourceMappingURL=sessionConfigStamps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessionConfigStamps.d.ts","sourceRoot":"","sources":["../../src/realtimeSessions/sessionConfigStamps.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAOxE,OAAO,EAKH,KAAK,gBAAgB,EACxB,MAAM,uBAAuB,CAAC;AAE/B,gDAAgD;AAChD,MAAM,WAAW,mBAAmB;IAChC,aAAa,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE;IACxC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,iBAAiB,CAAC,EAAE,gBAAgB,CAAC;IACrC,KAAK,EAAE,MAAM,CAAC;CACjB,GAAG,mBAAmB,GAAG,IAAI,CAkB7B;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,6BAA6B,CAC/C,aAAa,EAAE,MAAM,GAAG,SAAS,EACjC,WAAW,EAAE,QAAQ,EACrB,QAAQ,EAAE,iBAAiB,GAC5B,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAgBvC"}
@@ -0,0 +1,93 @@
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
+ import { AuthorizeSessionAccess, LoadSessionForAccess } from './sessionAccess.js';
29
+ import { ExtractIdentityVerificationPolicyFromRealtimeConfig, ReadIdentityVerificationPolicyLayer, TightenSessionDeadline, } from './verificationPolicy.js';
30
+ import { ParseConfigObject, ReadIdentityVerificationState, WriteIdentityVerificationState, } from './verificationCore.js';
31
+ /**
32
+ * Decides what to stamp into a freshly created session's `Config`.
33
+ *
34
+ * - **Policy snapshot.** The cascade's verification layer (`channels.config.IdentityVerification` plus the
35
+ * duration caps) is copied onto the session, so the rules a person is held to are fixed at mint,
36
+ * server-side, and cannot be chosen by the caller later.
37
+ * - **Duration cap.** When the cascade configures `unverifiedMaxSeconds` (or, for a session that inherited
38
+ * a verified identity, `verifiedMaxSeconds`), the session's absolute deadline is set to now + cap —
39
+ * applied to ANY principal, not only widget guests — and never loosens a tighter deadline already
40
+ * stamped (the widget voice cap).
41
+ * - **Inherited identity.** A verified identity carried forward from the resumed session.
42
+ *
43
+ * @param args.EffectiveRealtime - `EffectiveConfig.realtime` of the resolved config (any shape; read defensively)
44
+ * @param args.ExistingConfigRaw - the session's current `Config`
45
+ * @param args.InheritedVerified - verified identity from the session being resumed, if any
46
+ * @param args.NowMs - the current time, epoch ms
47
+ * @returns the `Config` to write, or `null` when nothing needs stamping
48
+ */
49
+ export function BuildMintConfigStamps(args) {
50
+ const layer = ExtractIdentityVerificationPolicyFromRealtimeConfig(args.EffectiveRealtime);
51
+ const hasPolicy = Object.keys(layer).length > 0;
52
+ if (!hasPolicy && !args.InheritedVerified) {
53
+ return null;
54
+ }
55
+ const existingState = ReadIdentityVerificationState(args.ExistingConfigRaw, ReadIdentityVerificationPolicyLayer);
56
+ const state = {
57
+ ...existingState,
58
+ ...(hasPolicy ? { Policy: layer } : {}),
59
+ ...(args.InheritedVerified ? { Verified: args.InheritedVerified } : {}),
60
+ };
61
+ const capSeconds = args.InheritedVerified ? (layer.verifiedMaxSeconds ?? layer.unverifiedMaxSeconds) : layer.unverifiedMaxSeconds;
62
+ const existingDeadline = ParseConfigObject(args.ExistingConfigRaw)['maxSessionDeadlineIso'];
63
+ const deadlineIso = capSeconds
64
+ ? TightenSessionDeadline(typeof existingDeadline === 'string' ? existingDeadline : undefined, args.NowMs + capSeconds * 1000)
65
+ : undefined;
66
+ return { NextConfigRaw: WriteIdentityVerificationState(args.ExistingConfigRaw, state, deadlineIso) };
67
+ }
68
+ /**
69
+ * The verified identity of the session being resumed, when the caller may inherit it.
70
+ *
71
+ * Reads the prior session as the caller and requires {@link AuthorizeSessionAccess} to allow it; any
72
+ * failure (no such session, not the caller's, unreadable) yields `undefined` — inheritance is a
73
+ * convenience and must never block a session start.
74
+ *
75
+ * @param lastSessionId - the `lastSessionId` the client supplied at start
76
+ * @param contextUser - the starting caller
77
+ * @param provider - request-scoped provider
78
+ */
79
+ export async function LoadInheritedVerifiedIdentity(lastSessionId, contextUser, provider) {
80
+ if (!lastSessionId) {
81
+ return undefined;
82
+ }
83
+ const prior = await LoadSessionForAccess(lastSessionId, contextUser, provider);
84
+ if (!prior) {
85
+ return undefined;
86
+ }
87
+ const decision = AuthorizeSessionAccess({ SessionUserID: prior.Session.UserID, ConversationExternalID: prior.ConversationExternalID }, contextUser);
88
+ if (decision.Allowed === false) {
89
+ return undefined;
90
+ }
91
+ return ReadIdentityVerificationState(prior.Session.Config_, ReadIdentityVerificationPolicyLayer).Verified;
92
+ }
93
+ //# sourceMappingURL=sessionConfigStamps.js.map