@memberjunction/server 6.2.0-edge.2 → 6.2.0-edge.4

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