@memberjunction/server 6.2.0-edge.5 → 6.2.0-edge.7

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 (664) hide show
  1. package/README.md +96 -1
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/agentSessions/BridgeHostInstance.d.ts +8 -3
  4. package/dist/agentSessions/BridgeHostInstance.d.ts.map +1 -1
  5. package/dist/agentSessions/BridgeHostInstance.js +14 -4
  6. package/dist/agentSessions/BridgeHostInstance.js.map +1 -1
  7. package/dist/agentSessions/HandoffOfferExpiry.d.ts +10 -0
  8. package/dist/agentSessions/HandoffOfferExpiry.d.ts.map +1 -0
  9. package/dist/agentSessions/HandoffOfferExpiry.js +18 -0
  10. package/dist/agentSessions/HandoffOfferExpiry.js.map +1 -0
  11. package/dist/agentSessions/ReturningVisitorRecap.js +1 -0
  12. package/dist/agentSessions/ReturningVisitorRecap.js.map +1 -1
  13. package/dist/agentSessions/SessionJanitor.d.ts +34 -11
  14. package/dist/agentSessions/SessionJanitor.d.ts.map +1 -1
  15. package/dist/agentSessions/SessionJanitor.js +88 -44
  16. package/dist/agentSessions/SessionJanitor.js.map +1 -1
  17. package/dist/agentSessions/SessionManager.d.ts +29 -9
  18. package/dist/agentSessions/SessionManager.d.ts.map +1 -1
  19. package/dist/agentSessions/SessionManager.js +62 -16
  20. package/dist/agentSessions/SessionManager.js.map +1 -1
  21. package/dist/agentSessions/conversationBrowsers.d.ts +61 -0
  22. package/dist/agentSessions/conversationBrowsers.d.ts.map +1 -0
  23. package/dist/agentSessions/conversationBrowsers.js +118 -0
  24. package/dist/agentSessions/conversationBrowsers.js.map +1 -0
  25. package/dist/agentSessions/sessionDeadline.d.ts +43 -0
  26. package/dist/agentSessions/sessionDeadline.d.ts.map +1 -0
  27. package/dist/agentSessions/sessionDeadline.js +68 -0
  28. package/dist/agentSessions/sessionDeadline.js.map +1 -0
  29. package/dist/auth/APIKeyScopeAuth.d.ts.map +1 -1
  30. package/dist/auth/APIKeyScopeAuth.js +5 -4
  31. package/dist/auth/APIKeyScopeAuth.js.map +1 -1
  32. package/dist/auth/AuthProviderCatalogRouter.d.ts.map +1 -1
  33. package/dist/auth/AuthProviderCatalogRouter.js +2 -0
  34. package/dist/auth/AuthProviderCatalogRouter.js.map +1 -1
  35. package/dist/auth/index.d.ts.map +1 -1
  36. package/dist/auth/index.js +51 -10
  37. package/dist/auth/index.js.map +1 -1
  38. package/dist/auth/initializeProviders.d.ts +10 -0
  39. package/dist/auth/initializeProviders.d.ts.map +1 -1
  40. package/dist/auth/initializeProviders.js +37 -1
  41. package/dist/auth/initializeProviders.js.map +1 -1
  42. package/dist/auth/localDevAuth.d.ts +79 -0
  43. package/dist/auth/localDevAuth.d.ts.map +1 -0
  44. package/dist/auth/localDevAuth.js +439 -0
  45. package/dist/auth/localDevAuth.js.map +1 -0
  46. package/dist/auth/loginEmailResolution.d.ts +41 -0
  47. package/dist/auth/loginEmailResolution.d.ts.map +1 -0
  48. package/dist/auth/loginEmailResolution.js +47 -0
  49. package/dist/auth/loginEmailResolution.js.map +1 -0
  50. package/dist/auth/magicLink/MagicLinkKeys.d.ts +51 -3
  51. package/dist/auth/magicLink/MagicLinkKeys.d.ts.map +1 -1
  52. package/dist/auth/magicLink/MagicLinkKeys.js +130 -13
  53. package/dist/auth/magicLink/MagicLinkKeys.js.map +1 -1
  54. package/dist/auth/magicLink/MagicLinkRouter.d.ts +3 -0
  55. package/dist/auth/magicLink/MagicLinkRouter.d.ts.map +1 -1
  56. package/dist/auth/magicLink/MagicLinkRouter.js +23 -5
  57. package/dist/auth/magicLink/MagicLinkRouter.js.map +1 -1
  58. package/dist/auth/magicLink/MagicLinkService.d.ts +39 -5
  59. package/dist/auth/magicLink/MagicLinkService.d.ts.map +1 -1
  60. package/dist/auth/magicLink/MagicLinkService.js +221 -9
  61. package/dist/auth/magicLink/MagicLinkService.js.map +1 -1
  62. package/dist/auth/magicLink/index.d.ts +1 -1
  63. package/dist/auth/magicLink/index.d.ts.map +1 -1
  64. package/dist/auth/magicLink/index.js +1 -1
  65. package/dist/auth/magicLink/index.js.map +1 -1
  66. package/dist/auth/magicLink/redeemLanding.d.ts +2 -2
  67. package/dist/auth/magicLink/redeemLanding.d.ts.map +1 -1
  68. package/dist/auth/magicLink/redeemLanding.js +7 -4
  69. package/dist/auth/magicLink/redeemLanding.js.map +1 -1
  70. package/dist/auth/magicLink/types.d.ts +39 -3
  71. package/dist/auth/magicLink/types.d.ts.map +1 -1
  72. package/dist/auth/magicLink/types.js +0 -4
  73. package/dist/auth/magicLink/types.js.map +1 -1
  74. package/dist/auth/newUsers.d.ts.map +1 -1
  75. package/dist/auth/newUsers.js +1 -0
  76. package/dist/auth/newUsers.js.map +1 -1
  77. package/dist/auth/sessionUserClone.d.ts +1 -1
  78. package/dist/auth/sessionUserClone.d.ts.map +1 -1
  79. package/dist/auth/sessionUserClone.js +3 -2
  80. package/dist/auth/sessionUserClone.js.map +1 -1
  81. package/dist/backgroundSweepConfigUnits.d.ts +231 -0
  82. package/dist/backgroundSweepConfigUnits.d.ts.map +1 -0
  83. package/dist/backgroundSweepConfigUnits.js +180 -0
  84. package/dist/backgroundSweepConfigUnits.js.map +1 -0
  85. package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.d.ts +292 -0
  86. package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.d.ts.map +1 -0
  87. package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.js +442 -0
  88. package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.js.map +1 -0
  89. package/dist/broadcast/index.d.ts +6 -0
  90. package/dist/broadcast/index.d.ts.map +1 -0
  91. package/dist/broadcast/index.js +6 -0
  92. package/dist/broadcast/index.js.map +1 -0
  93. package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.d.ts +43 -0
  94. package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.d.ts.map +1 -0
  95. package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.js +144 -0
  96. package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.js.map +1 -0
  97. package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.d.ts +46 -0
  98. package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.d.ts.map +1 -0
  99. package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.js +149 -0
  100. package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.js.map +1 -0
  101. package/dist/broadcast/providers/GCPPubSubBroadcastProvider.d.ts +49 -0
  102. package/dist/broadcast/providers/GCPPubSubBroadcastProvider.d.ts.map +1 -0
  103. package/dist/broadcast/providers/GCPPubSubBroadcastProvider.js +131 -0
  104. package/dist/broadcast/providers/GCPPubSubBroadcastProvider.js.map +1 -0
  105. package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.d.ts +24 -0
  106. package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.d.ts.map +1 -0
  107. package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.js +51 -0
  108. package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.js.map +1 -0
  109. package/dist/cache.d.ts +3 -2
  110. package/dist/cache.d.ts.map +1 -1
  111. package/dist/cache.js.map +1 -1
  112. package/dist/config.d.ts +1402 -8
  113. package/dist/config.d.ts.map +1 -1
  114. package/dist/config.js +120 -0
  115. package/dist/config.js.map +1 -1
  116. package/dist/context.d.ts +5 -1
  117. package/dist/context.d.ts.map +1 -1
  118. package/dist/context.js +64 -12
  119. package/dist/context.js.map +1 -1
  120. package/dist/coreRoutes.d.ts +3 -1
  121. package/dist/coreRoutes.d.ts.map +1 -1
  122. package/dist/coreRoutes.js +20 -4
  123. package/dist/coreRoutes.js.map +1 -1
  124. package/dist/generated/graphql-schemas/__mj.d.ts +863 -14
  125. package/dist/generated/graphql-schemas/__mj.d.ts.map +1 -1
  126. package/dist/generated/graphql-schemas/__mj.js +4167 -62
  127. package/dist/generated/graphql-schemas/__mj.js.map +1 -1
  128. package/dist/generic/CacheInvalidationResolver.d.ts +50 -30
  129. package/dist/generic/CacheInvalidationResolver.d.ts.map +1 -1
  130. package/dist/generic/CacheInvalidationResolver.js +154 -79
  131. package/dist/generic/CacheInvalidationResolver.js.map +1 -1
  132. package/dist/generic/OrphanedConversationDetailReconciler.d.ts +11 -0
  133. package/dist/generic/OrphanedConversationDetailReconciler.d.ts.map +1 -1
  134. package/dist/generic/OrphanedConversationDetailReconciler.js +29 -1
  135. package/dist/generic/OrphanedConversationDetailReconciler.js.map +1 -1
  136. package/dist/generic/PubSubManager.d.ts +10 -0
  137. package/dist/generic/PubSubManager.d.ts.map +1 -1
  138. package/dist/generic/PubSubManager.js +44 -1
  139. package/dist/generic/PubSubManager.js.map +1 -1
  140. package/dist/generic/PushStatusResolver.d.ts +39 -6
  141. package/dist/generic/PushStatusResolver.d.ts.map +1 -1
  142. package/dist/generic/PushStatusResolver.js +93 -11
  143. package/dist/generic/PushStatusResolver.js.map +1 -1
  144. package/dist/generic/ResolverBase.d.ts +114 -29
  145. package/dist/generic/ResolverBase.d.ts.map +1 -1
  146. package/dist/generic/ResolverBase.js +509 -220
  147. package/dist/generic/ResolverBase.js.map +1 -1
  148. package/dist/generic/RunViewResolver.d.ts +15 -3
  149. package/dist/generic/RunViewResolver.d.ts.map +1 -1
  150. package/dist/generic/RunViewResolver.js +126 -20
  151. package/dist/generic/RunViewResolver.js.map +1 -1
  152. package/dist/generic/actionOutputFieldSecurity.d.ts +26 -0
  153. package/dist/generic/actionOutputFieldSecurity.d.ts.map +1 -0
  154. package/dist/generic/actionOutputFieldSecurity.js +47 -0
  155. package/dist/generic/actionOutputFieldSecurity.js.map +1 -0
  156. package/dist/generic/fieldSecurityTransport.d.ts +30 -0
  157. package/dist/generic/fieldSecurityTransport.d.ts.map +1 -0
  158. package/dist/generic/fieldSecurityTransport.js +30 -0
  159. package/dist/generic/fieldSecurityTransport.js.map +1 -0
  160. package/dist/index.d.ts +4 -0
  161. package/dist/index.d.ts.map +1 -1
  162. package/dist/index.js +262 -84
  163. package/dist/index.js.map +1 -1
  164. package/dist/integration/ConnectionPause.d.ts +121 -0
  165. package/dist/integration/ConnectionPause.d.ts.map +1 -0
  166. package/dist/integration/ConnectionPause.js +183 -0
  167. package/dist/integration/ConnectionPause.js.map +1 -0
  168. package/dist/integration/CustomColumnPromoter.d.ts +72 -6
  169. package/dist/integration/CustomColumnPromoter.d.ts.map +1 -1
  170. package/dist/integration/CustomColumnPromoter.js +93 -47
  171. package/dist/integration/CustomColumnPromoter.js.map +1 -1
  172. package/dist/integration/EntityMapLifecycle.d.ts +78 -4
  173. package/dist/integration/EntityMapLifecycle.d.ts.map +1 -1
  174. package/dist/integration/EntityMapLifecycle.js +199 -5
  175. package/dist/integration/EntityMapLifecycle.js.map +1 -1
  176. package/dist/integration/InactiveRowWarnings.d.ts +31 -0
  177. package/dist/integration/InactiveRowWarnings.d.ts.map +1 -1
  178. package/dist/integration/InactiveRowWarnings.js +29 -0
  179. package/dist/integration/InactiveRowWarnings.js.map +1 -1
  180. package/dist/integration/ObjectNamesByID.d.ts +28 -0
  181. package/dist/integration/ObjectNamesByID.d.ts.map +1 -0
  182. package/dist/integration/ObjectNamesByID.js +87 -0
  183. package/dist/integration/ObjectNamesByID.js.map +1 -0
  184. package/dist/integration/PostRestartIntrospect.d.ts +26 -0
  185. package/dist/integration/PostRestartIntrospect.d.ts.map +1 -0
  186. package/dist/integration/PostRestartIntrospect.js +27 -0
  187. package/dist/integration/PostRestartIntrospect.js.map +1 -0
  188. package/dist/integration/RSUPostRestartProgress.d.ts +176 -0
  189. package/dist/integration/RSUPostRestartProgress.d.ts.map +1 -0
  190. package/dist/integration/RSUPostRestartProgress.js +323 -0
  191. package/dist/integration/RSUPostRestartProgress.js.map +1 -0
  192. package/dist/integration/RSUProgressBridge.d.ts +41 -2
  193. package/dist/integration/RSUProgressBridge.d.ts.map +1 -1
  194. package/dist/integration/RSUProgressBridge.js +84 -1
  195. package/dist/integration/RSUProgressBridge.js.map +1 -1
  196. package/dist/integration/RunArtifactAuthorization.d.ts +39 -0
  197. package/dist/integration/RunArtifactAuthorization.d.ts.map +1 -0
  198. package/dist/integration/RunArtifactAuthorization.js +45 -0
  199. package/dist/integration/RunArtifactAuthorization.js.map +1 -0
  200. package/dist/integration/SchemaRefreshLaunch.d.ts +9 -0
  201. package/dist/integration/SchemaRefreshLaunch.d.ts.map +1 -1
  202. package/dist/integration/SchemaRefreshLaunch.js +3 -2
  203. package/dist/integration/SchemaRefreshLaunch.js.map +1 -1
  204. package/dist/integration/ScopedFieldsForBuild.d.ts +46 -0
  205. package/dist/integration/ScopedFieldsForBuild.d.ts.map +1 -0
  206. package/dist/integration/ScopedFieldsForBuild.js +91 -0
  207. package/dist/integration/ScopedFieldsForBuild.js.map +1 -0
  208. package/dist/integration/TargetConfigGuard.d.ts +40 -0
  209. package/dist/integration/TargetConfigGuard.d.ts.map +1 -0
  210. package/dist/integration/TargetConfigGuard.js +40 -0
  211. package/dist/integration/TargetConfigGuard.js.map +1 -0
  212. package/dist/logging/variablesLoggingMiddleware.d.ts +12 -0
  213. package/dist/logging/variablesLoggingMiddleware.d.ts.map +1 -1
  214. package/dist/logging/variablesLoggingMiddleware.js +50 -1
  215. package/dist/logging/variablesLoggingMiddleware.js.map +1 -1
  216. package/dist/realtimeSessions/SessionVerificationPortsBase.d.ts.map +1 -1
  217. package/dist/realtimeSessions/SessionVerificationPortsBase.js +1 -0
  218. package/dist/realtimeSessions/SessionVerificationPortsBase.js.map +1 -1
  219. package/dist/realtimeSessions/ownedRealtimeSession.d.ts +8 -6
  220. package/dist/realtimeSessions/ownedRealtimeSession.d.ts.map +1 -1
  221. package/dist/realtimeSessions/ownedRealtimeSession.js +14 -6
  222. package/dist/realtimeSessions/ownedRealtimeSession.js.map +1 -1
  223. package/dist/realtimeSessions/sessionAccess.d.ts +103 -11
  224. package/dist/realtimeSessions/sessionAccess.d.ts.map +1 -1
  225. package/dist/realtimeSessions/sessionAccess.js +147 -22
  226. package/dist/realtimeSessions/sessionAccess.js.map +1 -1
  227. package/dist/realtimeSessions/sessionConfigStamps.js +1 -1
  228. package/dist/realtimeSessions/sessionConfigStamps.js.map +1 -1
  229. package/dist/realtimeSessions/subscriptionAuthorization.d.ts.map +1 -1
  230. package/dist/realtimeSessions/subscriptionAuthorization.js +5 -2
  231. package/dist/realtimeSessions/subscriptionAuthorization.js.map +1 -1
  232. package/dist/realtimeSessions/verificationWorkflow.d.ts +2 -0
  233. package/dist/realtimeSessions/verificationWorkflow.d.ts.map +1 -1
  234. package/dist/realtimeSessions/verificationWorkflow.js +1 -1
  235. package/dist/realtimeSessions/verificationWorkflow.js.map +1 -1
  236. package/dist/realtimeWidget/WidgetRouter.d.ts.map +1 -1
  237. package/dist/realtimeWidget/WidgetRouter.js +19 -3
  238. package/dist/realtimeWidget/WidgetRouter.js.map +1 -1
  239. package/dist/realtimeWidget/WidgetSessionService.d.ts +67 -7
  240. package/dist/realtimeWidget/WidgetSessionService.d.ts.map +1 -1
  241. package/dist/realtimeWidget/WidgetSessionService.js +203 -19
  242. package/dist/realtimeWidget/WidgetSessionService.js.map +1 -1
  243. package/dist/realtimeWidget/host-identity.d.ts +1 -1
  244. package/dist/realtimeWidget/host-identity.js +1 -1
  245. package/dist/realtimeWidget/visitorIdentity.d.ts.map +1 -1
  246. package/dist/realtimeWidget/visitorIdentity.js +1 -0
  247. package/dist/realtimeWidget/visitorIdentity.js.map +1 -1
  248. package/dist/realtimeWidget/widgetCore.d.ts +20 -1
  249. package/dist/realtimeWidget/widgetCore.d.ts.map +1 -1
  250. package/dist/realtimeWidget/widgetCore.js +21 -8
  251. package/dist/realtimeWidget/widgetCore.js.map +1 -1
  252. package/dist/realtimeWidget/widgetGuestElevation.d.ts +1 -1
  253. package/dist/realtimeWidget/widgetGuestElevation.d.ts.map +1 -1
  254. package/dist/realtimeWidget/widgetGuestElevation.js +3 -1
  255. package/dist/realtimeWidget/widgetGuestElevation.js.map +1 -1
  256. package/dist/requestOrigin.d.ts +22 -0
  257. package/dist/requestOrigin.d.ts.map +1 -0
  258. package/dist/requestOrigin.js +60 -0
  259. package/dist/requestOrigin.js.map +1 -0
  260. package/dist/resolvers/ActionResolver.d.ts +19 -1
  261. package/dist/resolvers/ActionResolver.d.ts.map +1 -1
  262. package/dist/resolvers/ActionResolver.js +63 -12
  263. package/dist/resolvers/ActionResolver.js.map +1 -1
  264. package/dist/resolvers/AdhocQueryResolver.d.ts.map +1 -1
  265. package/dist/resolvers/AdhocQueryResolver.js +1 -0
  266. package/dist/resolvers/AdhocQueryResolver.js.map +1 -1
  267. package/dist/resolvers/AgentRunStatusPublisher.d.ts +18 -4
  268. package/dist/resolvers/AgentRunStatusPublisher.d.ts.map +1 -1
  269. package/dist/resolvers/AgentRunStatusPublisher.js +32 -8
  270. package/dist/resolvers/AgentRunStatusPublisher.js.map +1 -1
  271. package/dist/resolvers/AgentSessionResolver.d.ts +10 -4
  272. package/dist/resolvers/AgentSessionResolver.d.ts.map +1 -1
  273. package/dist/resolvers/AgentSessionResolver.js +44 -17
  274. package/dist/resolvers/AgentSessionResolver.js.map +1 -1
  275. package/dist/resolvers/AutotagPipelineResolver.d.ts.map +1 -1
  276. package/dist/resolvers/AutotagPipelineResolver.js +2 -1
  277. package/dist/resolvers/AutotagPipelineResolver.js.map +1 -1
  278. package/dist/resolvers/ConversationRunEventsResolver.d.ts.map +1 -1
  279. package/dist/resolvers/ConversationRunEventsResolver.js +2 -0
  280. package/dist/resolvers/ConversationRunEventsResolver.js.map +1 -1
  281. package/dist/resolvers/EntityCommunicationsResolver.d.ts +13 -1
  282. package/dist/resolvers/EntityCommunicationsResolver.d.ts.map +1 -1
  283. package/dist/resolvers/EntityCommunicationsResolver.js +50 -14
  284. package/dist/resolvers/EntityCommunicationsResolver.js.map +1 -1
  285. package/dist/resolvers/ExecuteRemoteOperationResolver.d.ts +6 -0
  286. package/dist/resolvers/ExecuteRemoteOperationResolver.d.ts.map +1 -1
  287. package/dist/resolvers/ExecuteRemoteOperationResolver.js +30 -7
  288. package/dist/resolvers/ExecuteRemoteOperationResolver.js.map +1 -1
  289. package/dist/resolvers/FetchEntityVectorsResolver.d.ts +28 -0
  290. package/dist/resolvers/FetchEntityVectorsResolver.d.ts.map +1 -1
  291. package/dist/resolvers/FetchEntityVectorsResolver.js +117 -21
  292. package/dist/resolvers/FetchEntityVectorsResolver.js.map +1 -1
  293. package/dist/resolvers/FileCategoryResolver.d.ts.map +1 -1
  294. package/dist/resolvers/FileCategoryResolver.js +1 -0
  295. package/dist/resolvers/FileCategoryResolver.js.map +1 -1
  296. package/dist/resolvers/FileResolver.d.ts +5 -0
  297. package/dist/resolvers/FileResolver.d.ts.map +1 -1
  298. package/dist/resolvers/FileResolver.js +13 -4
  299. package/dist/resolvers/FileResolver.js.map +1 -1
  300. package/dist/resolvers/GetDataResolver.d.ts.map +1 -1
  301. package/dist/resolvers/GetDataResolver.js +34 -13
  302. package/dist/resolvers/GetDataResolver.js.map +1 -1
  303. package/dist/resolvers/IntegrationDiscoveryResolver.d.ts +401 -11
  304. package/dist/resolvers/IntegrationDiscoveryResolver.d.ts.map +1 -1
  305. package/dist/resolvers/IntegrationDiscoveryResolver.js +2713 -1290
  306. package/dist/resolvers/IntegrationDiscoveryResolver.js.map +1 -1
  307. package/dist/resolvers/MCPResolver.d.ts.map +1 -1
  308. package/dist/resolvers/MCPResolver.js +13 -2
  309. package/dist/resolvers/MCPResolver.js.map +1 -1
  310. package/dist/resolvers/MergeRecordsResolver.d.ts +8 -1
  311. package/dist/resolvers/MergeRecordsResolver.d.ts.map +1 -1
  312. package/dist/resolvers/MergeRecordsResolver.js +31 -3
  313. package/dist/resolvers/MergeRecordsResolver.js.map +1 -1
  314. package/dist/resolvers/PipelineProgressResolver.d.ts +6 -0
  315. package/dist/resolvers/PipelineProgressResolver.d.ts.map +1 -1
  316. package/dist/resolvers/PipelineProgressResolver.js +5 -3
  317. package/dist/resolvers/PipelineProgressResolver.js.map +1 -1
  318. package/dist/resolvers/QueryResolver.d.ts.map +1 -1
  319. package/dist/resolvers/QueryResolver.js +20 -6
  320. package/dist/resolvers/QueryResolver.js.map +1 -1
  321. package/dist/resolvers/QuerySystemUserResolver.d.ts +38 -0
  322. package/dist/resolvers/QuerySystemUserResolver.d.ts.map +1 -1
  323. package/dist/resolvers/QuerySystemUserResolver.js +184 -88
  324. package/dist/resolvers/QuerySystemUserResolver.js.map +1 -1
  325. package/dist/resolvers/RSUResolver.d.ts.map +1 -1
  326. package/dist/resolvers/RSUResolver.js +12 -0
  327. package/dist/resolvers/RSUResolver.js.map +1 -1
  328. package/dist/resolvers/RealtimeBridgeResolver.d.ts.map +1 -1
  329. package/dist/resolvers/RealtimeBridgeResolver.js +1 -0
  330. package/dist/resolvers/RealtimeBridgeResolver.js.map +1 -1
  331. package/dist/resolvers/RealtimeClientSessionResolver.d.ts +22 -2
  332. package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
  333. package/dist/resolvers/RealtimeClientSessionResolver.js +118 -33
  334. package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
  335. package/dist/resolvers/RemoteBrowserActionResolver.d.ts +62 -10
  336. package/dist/resolvers/RemoteBrowserActionResolver.d.ts.map +1 -1
  337. package/dist/resolvers/RemoteBrowserActionResolver.js +224 -39
  338. package/dist/resolvers/RemoteBrowserActionResolver.js.map +1 -1
  339. package/dist/resolvers/RunAIAgentResolver.d.ts +80 -16
  340. package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
  341. package/dist/resolvers/RunAIAgentResolver.js +388 -125
  342. package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
  343. package/dist/resolvers/RunAIPromptResolver.d.ts +5 -3
  344. package/dist/resolvers/RunAIPromptResolver.d.ts.map +1 -1
  345. package/dist/resolvers/RunAIPromptResolver.js +19 -18
  346. package/dist/resolvers/RunAIPromptResolver.js.map +1 -1
  347. package/dist/resolvers/RunTemplateResolver.d.ts.map +1 -1
  348. package/dist/resolvers/RunTemplateResolver.js +7 -5
  349. package/dist/resolvers/RunTemplateResolver.js.map +1 -1
  350. package/dist/resolvers/RunTestResolver.d.ts.map +1 -1
  351. package/dist/resolvers/RunTestResolver.js +3 -1
  352. package/dist/resolvers/RunTestResolver.js.map +1 -1
  353. package/dist/resolvers/SyncDataResolver.d.ts.map +1 -1
  354. package/dist/resolvers/SyncDataResolver.js +4 -0
  355. package/dist/resolvers/SyncDataResolver.js.map +1 -1
  356. package/dist/resolvers/TestQuerySQLResolver.d.ts.map +1 -1
  357. package/dist/resolvers/TestQuerySQLResolver.js +1 -0
  358. package/dist/resolvers/TestQuerySQLResolver.js.map +1 -1
  359. package/dist/resolvers/TransactionGroupResolver.d.ts +17 -2
  360. package/dist/resolvers/TransactionGroupResolver.d.ts.map +1 -1
  361. package/dist/resolvers/TransactionGroupResolver.js +60 -15
  362. package/dist/resolvers/TransactionGroupResolver.js.map +1 -1
  363. package/dist/resolvers/UserViewResolver.d.ts +1 -1
  364. package/dist/resolvers/UserViewResolver.d.ts.map +1 -1
  365. package/dist/resolvers/UserViewResolver.js +2 -1
  366. package/dist/resolvers/UserViewResolver.js.map +1 -1
  367. package/dist/resolvers/meetingRecordingRegistration.d.ts.map +1 -1
  368. package/dist/resolvers/meetingRecordingRegistration.js +2 -0
  369. package/dist/resolvers/meetingRecordingRegistration.js.map +1 -1
  370. package/dist/rest/EntityCRUDHandler.d.ts +6 -0
  371. package/dist/rest/EntityCRUDHandler.d.ts.map +1 -1
  372. package/dist/rest/EntityCRUDHandler.js +19 -5
  373. package/dist/rest/EntityCRUDHandler.js.map +1 -1
  374. package/dist/rest/MediaAccessKeys.d.ts.map +1 -1
  375. package/dist/rest/MediaAccessKeys.js +6 -2
  376. package/dist/rest/MediaAccessKeys.js.map +1 -1
  377. package/dist/rest/OAuthCallbackHandler.d.ts.map +1 -1
  378. package/dist/rest/OAuthCallbackHandler.js +11 -5
  379. package/dist/rest/OAuthCallbackHandler.js.map +1 -1
  380. package/dist/rest/RESTEndpointHandler.d.ts.map +1 -1
  381. package/dist/rest/RESTEndpointHandler.js +8 -5
  382. package/dist/rest/RESTEndpointHandler.js.map +1 -1
  383. package/dist/rest/RealtimeRecordingHandler.d.ts +3 -3
  384. package/dist/rest/RealtimeRecordingHandler.d.ts.map +1 -1
  385. package/dist/rest/RealtimeRecordingHandler.js +6 -8
  386. package/dist/rest/RealtimeRecordingHandler.js.map +1 -1
  387. package/dist/rest/ViewOperationsHandler.d.ts +6 -0
  388. package/dist/rest/ViewOperationsHandler.d.ts.map +1 -1
  389. package/dist/rest/ViewOperationsHandler.js +24 -6
  390. package/dist/rest/ViewOperationsHandler.js.map +1 -1
  391. package/dist/rest/setupRESTEndpoints.d.ts +3 -1
  392. package/dist/rest/setupRESTEndpoints.d.ts.map +1 -1
  393. package/dist/rest/setupRESTEndpoints.js +11 -2
  394. package/dist/rest/setupRESTEndpoints.js.map +1 -1
  395. package/dist/serverRoleConfigUnits.d.ts +29 -0
  396. package/dist/serverRoleConfigUnits.d.ts.map +1 -0
  397. package/dist/serverRoleConfigUnits.js +33 -0
  398. package/dist/serverRoleConfigUnits.js.map +1 -0
  399. package/dist/services/DurableEntityActionTaskSubmitter.d.ts.map +1 -1
  400. package/dist/services/DurableEntityActionTaskSubmitter.js +6 -1
  401. package/dist/services/DurableEntityActionTaskSubmitter.js.map +1 -1
  402. package/dist/services/TaskGraphActionRunner.d.ts.map +1 -1
  403. package/dist/services/TaskGraphActionRunner.js +2 -26
  404. package/dist/services/TaskGraphActionRunner.js.map +1 -1
  405. package/dist/services/TaskGraphAgentRunner.d.ts +6 -0
  406. package/dist/services/TaskGraphAgentRunner.d.ts.map +1 -1
  407. package/dist/services/TaskGraphAgentRunner.js +38 -0
  408. package/dist/services/TaskGraphAgentRunner.js.map +1 -1
  409. package/dist/services/TaskGraphContinuationDeliverer.d.ts +5 -0
  410. package/dist/services/TaskGraphContinuationDeliverer.d.ts.map +1 -1
  411. package/dist/services/TaskGraphContinuationDeliverer.js +43 -15
  412. package/dist/services/TaskGraphContinuationDeliverer.js.map +1 -1
  413. package/dist/services/WorkQueueHostService.d.ts +2 -1
  414. package/dist/services/WorkQueueHostService.d.ts.map +1 -1
  415. package/dist/services/WorkQueueHostService.js +19 -4
  416. package/dist/services/WorkQueueHostService.js.map +1 -1
  417. package/dist/services/workQueueConfig.d.ts +2 -2
  418. package/dist/services/workQueueConfig.js +5 -5
  419. package/dist/services/workQueueConfig.js.map +1 -1
  420. package/dist/sharedCache.js +1 -1
  421. package/dist/sharedCache.js.map +1 -1
  422. package/dist/types.d.ts +40 -1
  423. package/dist/types.d.ts.map +1 -1
  424. package/dist/types.js.map +1 -1
  425. package/package.json +98 -98
  426. package/src/__tests__/APIKeyScopeAuth.test.ts +4 -8
  427. package/src/__tests__/ActionResolver.fieldSecurity.test.ts +237 -0
  428. package/src/__tests__/ActiveOperations.test.ts +68 -0
  429. package/src/__tests__/AdhocQueryResolver.dialect.test.ts +137 -0
  430. package/src/__tests__/AgentRunStatusPublisher.test.ts +49 -0
  431. package/src/__tests__/AgentSessionResolver.ownership.test.ts +150 -0
  432. package/src/__tests__/AssertTargetConfigs.test.ts +75 -0
  433. package/src/__tests__/BatchApplyParity.test.ts +109 -0
  434. package/src/__tests__/BridgeHostInstance.test.ts +42 -0
  435. package/src/__tests__/CollectInactiveRowWarnings.test.ts +115 -0
  436. package/src/__tests__/ConnectionPause.test.ts +192 -0
  437. package/src/__tests__/ConnectionPauseResolver.test.ts +166 -0
  438. package/src/__tests__/ConnectionPauseSave.test.ts +143 -0
  439. package/src/__tests__/CustomColumnPromoterCompletion.test.ts +142 -0
  440. package/src/__tests__/CustomColumnPromoterOnePass.test.ts +15 -1
  441. package/src/__tests__/DeleteConnectionRemovesPerConnectionCatalog.test.ts +51 -0
  442. package/src/__tests__/DetachedDiscoveryStart.test.ts +65 -0
  443. package/src/__tests__/DurableEntityActionTaskSubmitter.test.ts +73 -0
  444. package/src/__tests__/EntityCommunicationsResolver.actingUser.test.ts +151 -0
  445. package/src/__tests__/EntityMapLifecycle.rekey.test.ts +252 -0
  446. package/src/__tests__/EvolutionActsOnWhatItDetects.test.ts +113 -0
  447. package/src/__tests__/ExecuteRemoteOperationResolver.test.ts +213 -0
  448. package/src/__tests__/FetchEntityVectorsResolver.test.ts +206 -3
  449. package/src/__tests__/FileResolver.fieldSecurity.test.ts +82 -0
  450. package/src/__tests__/HandoffOfferExpiry.test.ts +40 -0
  451. package/src/__tests__/IntegrationRunArtifactAuthorization.test.ts +126 -0
  452. package/src/__tests__/MagicLinkKeys.test.ts +102 -0
  453. package/src/__tests__/MediaAccessKeys.test.ts +57 -10
  454. package/src/__tests__/NewArrivalsDefaultDisabled.test.ts +50 -0
  455. package/src/__tests__/ObjectNamesByID.test.ts +176 -0
  456. package/src/__tests__/PipelineProgressResolver.filter.test.ts +58 -0
  457. package/src/__tests__/PostRestartMapsInCatalogScope.test.ts +146 -0
  458. package/src/__tests__/QuerySystemUserResolver.childRows.test.ts +80 -0
  459. package/src/__tests__/QuerySystemUserResolver.collision.test.ts +200 -0
  460. package/src/__tests__/QuerySystemUserResolver.fieldSecurity.test.ts +49 -0
  461. package/src/__tests__/QuerySystemUserResolver.permissions.test.ts +132 -0
  462. package/src/__tests__/RESTEndpointHandler.test.ts +25 -0
  463. package/src/__tests__/RSUPostRestartProgress.test.ts +343 -0
  464. package/src/__tests__/RSUProgressBridge.test.ts +188 -5
  465. package/src/__tests__/RSUStartupSweepWiring.test.ts +30 -0
  466. package/src/__tests__/ReactivateRefreshMessage.test.ts +10 -3
  467. package/src/__tests__/RealtimeClientSessionResolver.configTamper.test.ts +23 -3
  468. package/src/__tests__/RealtimeClientSessionResolver.test.ts +346 -46
  469. package/src/__tests__/{RefreshAdoptsNewColumns.test.ts → RefreshReportsNewColumns.test.ts} +25 -16
  470. package/src/__tests__/RemoteBrowserActionRecovery.test.ts +287 -0
  471. package/src/__tests__/RemoteBrowserActionResolver.goalRunLink.test.ts +3 -0
  472. package/src/__tests__/RemoteBrowserActionResolver.ownership.test.ts +100 -0
  473. package/src/__tests__/RemoteBrowserAudioStream.test.ts +3 -0
  474. package/src/__tests__/RemoteBrowserSnapshot.test.ts +3 -0
  475. package/src/__tests__/ResolverBase.clientOldValues.test.ts +344 -14
  476. package/src/__tests__/ResolverBase.deleteReturnProjection.test.ts +52 -0
  477. package/src/__tests__/ResolverBase.encryptedApiZeroReencrypt.test.ts +307 -0
  478. package/src/__tests__/ResolverBase.entityMessageRelay.test.ts +227 -0
  479. package/src/__tests__/ResolverBase.includeBinaryFields.test.ts +83 -1
  480. package/src/__tests__/ResolverBase.publishStatusUpdate.test.ts +68 -0
  481. package/src/__tests__/ResolverBase.userViewCacheAndDedup.test.ts +130 -0
  482. package/src/__tests__/RunAIAgentResolver.branch.test.ts +72 -13
  483. package/src/__tests__/RunAIAgentResolver.consultPredecessor.test.ts +289 -0
  484. package/src/__tests__/RunAIAgentResolver.conversationWriter.test.ts +210 -0
  485. package/src/__tests__/RunAIAgentResolver.fireAndForgetCompletion.test.ts +209 -0
  486. package/src/__tests__/RunAIAgentResolver.handoff.test.ts +649 -0
  487. package/src/__tests__/RunAIAgentResolver.historyFrom.test.ts +19 -27
  488. package/src/__tests__/RunAIAgentResolver.runDataGuard.test.ts +10 -2
  489. package/src/__tests__/RunAIAgentResolver.serverReply.test.ts +358 -0
  490. package/src/__tests__/RunAIAgentResolver.stoppedPredecessor.test.ts +91 -13
  491. package/src/__tests__/RunTemplateResolver.test.ts +35 -2
  492. package/src/__tests__/RunViewResolver.cacheCheckForwarding.test.ts +11 -0
  493. package/src/__tests__/SchemaEvolutionCustomColumns.test.ts +119 -0
  494. package/src/__tests__/SchemaRefreshLaunch.test.ts +24 -2
  495. package/src/__tests__/ScopedFieldsForBuild.test.ts +192 -0
  496. package/src/__tests__/SessionJanitor.test.ts +195 -4
  497. package/src/__tests__/SessionManager.test.ts +164 -0
  498. package/src/__tests__/TaskGraphActionRunner.durablePayload.test.ts +2 -2
  499. package/src/__tests__/TaskGraphAgentRunner.test.ts +272 -16
  500. package/src/__tests__/TaskGraphContinuationDeliverer.test.ts +114 -3
  501. package/src/__tests__/TransactionGroupResolver.fieldSecurity.test.ts +199 -0
  502. package/src/__tests__/UserViewResolver.updateWhereClause.test.ts +15 -0
  503. package/src/__tests__/ViewOperationsHandler.test.ts +9 -7
  504. package/src/__tests__/WidgetSessionService.test.ts +583 -4
  505. package/src/__tests__/WorkQueueHostService.test.ts +25 -7
  506. package/src/__tests__/apiRootBoot.test.ts +1 -1
  507. package/src/__tests__/backgroundSweepConfigUnits.test.ts +153 -0
  508. package/src/__tests__/buildMagicLinkSessionUser.test.ts +96 -0
  509. package/src/__tests__/cacheBroadcastProviders.test.ts +403 -0
  510. package/src/__tests__/cacheInvalidationRecordData.test.ts +45 -0
  511. package/src/__tests__/contextRequestOrigin.test.ts +105 -0
  512. package/src/__tests__/conversationBrowsers.test.ts +62 -0
  513. package/src/__tests__/fieldSecurityFixtures.ts +91 -0
  514. package/src/__tests__/globalCors.test.ts +3 -3
  515. package/src/__tests__/localDevAuth.test.ts +196 -0
  516. package/src/__tests__/magicLinkExtensionCapabilities.test.ts +413 -0
  517. package/src/__tests__/orphanedConversationDetailReconciler.start.test.ts +82 -0
  518. package/src/__tests__/orphanedConversationDetailReconciler.test.ts +10 -0
  519. package/src/__tests__/ownedRealtimeSession.test.ts +14 -0
  520. package/src/__tests__/pushStatusResolver.filter.test.ts +57 -1
  521. package/src/__tests__/realtimeRecordingHandler.test.ts +24 -2
  522. package/src/__tests__/realtimeSessions/RealtimeSessionEventsResolver.test.ts +29 -1
  523. package/src/__tests__/realtimeSessions/ownedRealtimeSession.anonymous.test.ts +31 -0
  524. package/src/__tests__/realtimeSessions/ownedRealtimeSession.namedScoped.test.ts +37 -0
  525. package/src/__tests__/realtimeSessions/sessionAccess.test.ts +224 -7
  526. package/src/__tests__/realtimeSessions/sessionConfigStamps.test.ts +1 -1
  527. package/src/__tests__/realtimeSessions/verificationWorkflow.test.ts +25 -4
  528. package/src/__tests__/requestOrigin.test.ts +104 -0
  529. package/src/__tests__/resolverBase.cloudEventChangedFields.test.ts +157 -0
  530. package/src/__tests__/resolverBase.fieldSecurityTransport.test.ts +222 -0
  531. package/src/__tests__/resolverBase.fls.test.ts +146 -97
  532. package/src/__tests__/restTransport.fieldSecurity.test.ts +148 -0
  533. package/src/__tests__/runParamsTimeZone.test.ts +179 -0
  534. package/src/__tests__/runStreams.fieldSecurity.test.ts +100 -0
  535. package/src/__tests__/runViewProperties.test.ts +114 -0
  536. package/src/__tests__/scalabilityBenchmarks.test.ts +765 -0
  537. package/src/__tests__/scalabilityDatabaseIntegration.test.ts +207 -0
  538. package/src/__tests__/securityHardeningPr6034.test.ts +120 -0
  539. package/src/__tests__/sessionDeadline.test.ts +51 -0
  540. package/src/__tests__/sessionUserClone.test.ts +5 -1
  541. package/src/__tests__/sharedCache.test.ts +11 -0
  542. package/src/__tests__/startupSweepOrder.test.ts +40 -0
  543. package/src/__tests__/unifiedAuth.test.ts +101 -1
  544. package/src/__tests__/widgetGuestElevation.test.ts +2 -0
  545. package/src/agentSessions/BridgeHostInstance.ts +20 -5
  546. package/src/agentSessions/HandoffOfferExpiry.ts +18 -0
  547. package/src/agentSessions/ReturningVisitorRecap.ts +1 -0
  548. package/src/agentSessions/SessionJanitor.ts +95 -45
  549. package/src/agentSessions/SessionManager.ts +73 -20
  550. package/src/agentSessions/conversationBrowsers.ts +143 -0
  551. package/src/agentSessions/sessionDeadline.ts +81 -0
  552. package/src/auth/APIKeyScopeAuth.ts +5 -4
  553. package/src/auth/AuthProviderCatalogRouter.ts +3 -0
  554. package/src/auth/__tests__/loginEmailResolution.test.ts +67 -0
  555. package/src/auth/index.ts +56 -12
  556. package/src/auth/initializeProviders.ts +43 -1
  557. package/src/auth/localDevAuth.ts +528 -0
  558. package/src/auth/loginEmailResolution.ts +67 -0
  559. package/src/auth/magicLink/MagicLinkKeys.ts +147 -15
  560. package/src/auth/magicLink/MagicLinkRouter.ts +33 -6
  561. package/src/auth/magicLink/MagicLinkService.ts +250 -10
  562. package/src/auth/magicLink/index.ts +1 -1
  563. package/src/auth/magicLink/redeemLanding.ts +7 -4
  564. package/src/auth/magicLink/types.ts +38 -3
  565. package/src/auth/newUsers.ts +1 -0
  566. package/src/auth/sessionUserClone.ts +3 -2
  567. package/src/backgroundSweepConfigUnits.ts +213 -0
  568. package/src/broadcast/BaseCacheInvalidationBroadcastProvider.ts +674 -0
  569. package/src/broadcast/index.ts +5 -0
  570. package/src/broadcast/providers/AWSIoTCoreBroadcastProvider.ts +180 -0
  571. package/src/broadcast/providers/AzureWebPubSubBroadcastProvider.ts +182 -0
  572. package/src/broadcast/providers/GCPPubSubBroadcastProvider.ts +169 -0
  573. package/src/broadcast/providers/SequencedRoleBucketBroadcastProvider.ts +57 -0
  574. package/src/cache.ts +2 -1
  575. package/src/config.ts +138 -0
  576. package/src/context.ts +71 -14
  577. package/src/coreRoutes.ts +29 -7
  578. package/src/generated/graphql-schemas/__mj.ts +4145 -1193
  579. package/src/generic/CacheInvalidationResolver.ts +135 -78
  580. package/src/generic/OrphanedConversationDetailReconciler.ts +36 -3
  581. package/src/generic/PubSubManager.ts +54 -1
  582. package/src/generic/PushStatusResolver.ts +108 -11
  583. package/src/generic/ResolverBase.ts +635 -234
  584. package/src/generic/RunViewResolver.ts +176 -64
  585. package/src/generic/actionOutputFieldSecurity.ts +75 -0
  586. package/src/generic/fieldSecurityTransport.ts +62 -0
  587. package/src/index.ts +310 -85
  588. package/src/integration/ConnectionPause.ts +222 -0
  589. package/src/integration/CustomColumnPromoter.ts +129 -54
  590. package/src/integration/EntityMapLifecycle.ts +229 -6
  591. package/src/integration/InactiveRowWarnings.ts +50 -0
  592. package/src/integration/ObjectNamesByID.ts +97 -0
  593. package/src/integration/PostRestartIntrospect.ts +49 -0
  594. package/src/integration/RSUPostRestartProgress.ts +359 -0
  595. package/src/integration/RSUProgressBridge.ts +85 -2
  596. package/src/integration/RunArtifactAuthorization.ts +65 -0
  597. package/src/integration/SchemaRefreshLaunch.ts +12 -2
  598. package/src/integration/ScopedFieldsForBuild.ts +113 -0
  599. package/src/integration/TargetConfigGuard.ts +71 -0
  600. package/src/logging/variablesLoggingMiddleware.ts +59 -3
  601. package/src/realtimeSessions/README.md +7 -3
  602. package/src/realtimeSessions/SessionVerificationPortsBase.ts +1 -0
  603. package/src/realtimeSessions/ownedRealtimeSession.ts +16 -6
  604. package/src/realtimeSessions/sessionAccess.ts +211 -25
  605. package/src/realtimeSessions/sessionConfigStamps.ts +1 -1
  606. package/src/realtimeSessions/subscriptionAuthorization.ts +4 -2
  607. package/src/realtimeSessions/verificationWorkflow.ts +3 -1
  608. package/src/realtimeWidget/WidgetRouter.ts +22 -4
  609. package/src/realtimeWidget/WidgetSessionService.ts +254 -17
  610. package/src/realtimeWidget/host-identity.ts +1 -1
  611. package/src/realtimeWidget/visitorIdentity.ts +1 -0
  612. package/src/realtimeWidget/widgetCore.ts +34 -9
  613. package/src/realtimeWidget/widgetGuestElevation.ts +3 -1
  614. package/src/requestOrigin.ts +64 -0
  615. package/src/resolvers/ActionResolver.ts +78 -15
  616. package/src/resolvers/AdhocQueryResolver.ts +1 -0
  617. package/src/resolvers/AgentRunStatusPublisher.ts +36 -8
  618. package/src/resolvers/AgentSessionResolver.ts +50 -18
  619. package/src/resolvers/AutotagPipelineResolver.ts +2 -1
  620. package/src/resolvers/ConversationRunEventsResolver.ts +2 -0
  621. package/src/resolvers/EntityCommunicationsResolver.ts +56 -15
  622. package/src/resolvers/ExecuteRemoteOperationResolver.ts +41 -9
  623. package/src/resolvers/FetchEntityVectorsResolver.ts +132 -21
  624. package/src/resolvers/FileCategoryResolver.ts +1 -0
  625. package/src/resolvers/FileResolver.ts +14 -4
  626. package/src/resolvers/GetDataResolver.ts +35 -13
  627. package/src/resolvers/IntegrationDiscoveryResolver.ts +1570 -209
  628. package/src/resolvers/MCPResolver.ts +15 -2
  629. package/src/resolvers/MergeRecordsResolver.ts +23 -2
  630. package/src/resolvers/PipelineProgressResolver.ts +12 -3
  631. package/src/resolvers/QueryResolver.ts +20 -6
  632. package/src/resolvers/QuerySystemUserResolver.ts +207 -99
  633. package/src/resolvers/RSUResolver.ts +12 -0
  634. package/src/resolvers/RealtimeBridgeResolver.ts +1 -0
  635. package/src/resolvers/RealtimeClientSessionResolver.ts +144 -40
  636. package/src/resolvers/RemoteBrowserActionResolver.ts +252 -37
  637. package/src/resolvers/RunAIAgentResolver.ts +518 -163
  638. package/src/resolvers/RunAIPromptResolver.ts +18 -18
  639. package/src/resolvers/RunTemplateResolver.ts +9 -5
  640. package/src/resolvers/RunTestResolver.ts +3 -1
  641. package/src/resolvers/SyncDataResolver.ts +4 -0
  642. package/src/resolvers/TestQuerySQLResolver.ts +1 -0
  643. package/src/resolvers/TransactionGroupResolver.ts +66 -15
  644. package/src/resolvers/UserViewResolver.ts +2 -1
  645. package/src/resolvers/__tests__/GetDataResolver.tokens.test.ts +52 -0
  646. package/src/resolvers/__tests__/MergeRecordsResolver.test.ts +43 -0
  647. package/src/resolvers/meetingRecordingRegistration.ts +2 -0
  648. package/src/rest/EntityCRUDHandler.ts +22 -5
  649. package/src/rest/MediaAccessKeys.ts +6 -2
  650. package/src/rest/OAuthCallbackHandler.ts +13 -5
  651. package/src/rest/RESTEndpointHandler.ts +8 -5
  652. package/src/rest/RealtimeRecordingHandler.ts +9 -10
  653. package/src/rest/ViewOperationsHandler.ts +26 -7
  654. package/src/rest/setupRESTEndpoints.ts +11 -2
  655. package/src/serverRoleConfigUnits.ts +48 -0
  656. package/src/services/DurableEntityActionTaskSubmitter.ts +10 -2
  657. package/src/services/TaskGraphActionRunner.ts +2 -23
  658. package/src/services/TaskGraphAgentRunner.ts +43 -0
  659. package/src/services/TaskGraphContinuationDeliverer.ts +53 -20
  660. package/src/services/WorkQueueHostService.ts +26 -4
  661. package/src/services/workQueueConfig.ts +5 -5
  662. package/src/sharedCache.ts +1 -1
  663. package/src/types.ts +41 -1
  664. package/src/services/TaskOrchestration-Integration.md +0 -188
@@ -0,0 +1,113 @@
1
+ /**
2
+ * The FIELD rows a schema build materializes, for a connection with its own catalog.
3
+ *
4
+ * A schema build (ApplySchema, ApplyAll, ApplyAllBatch, the connector build, schema evolution)
5
+ * reconstructs the source schema from persisted catalog rows and hands it to SchemaBuilder. It used
6
+ * to read each object's fields from the engine's in-memory catalog. Once a connection's field rows
7
+ * are no longer held resident — they are warmed per object on demand, and the only site that warms
8
+ * them is the sync loop — that read answers `[]` for every object of the connection, and an object
9
+ * with no fields materializes nothing. Observed on a per-connection catalog (364 objects, 7,230
10
+ * active fields): the apply logged "Reusing 364 persisted IOs", then ran a migration with an empty
11
+ * table list in 4 ms — no CREATE, no ALTER, no error.
12
+ *
13
+ * So the build reads the connection's field rows itself: one read per {@link SCOPED_FIELDS_CHUNK}
14
+ * objects, plain rows, bypassing the query cache (an answer cached before discovery's persist is the
15
+ * empty set), and without the row cap (one object can carry thousands of fields). A failed read
16
+ * THROWS: an empty answer here is exactly what produced the zero-table apply.
17
+ *
18
+ * Outside a per-connection scope — or for a connection without its own catalog — this returns
19
+ * `null`, and the build reads the shared catalog from memory exactly as before.
20
+ */
21
+ import { RunView, type UserInfo } from '@memberjunction/core';
22
+ import type { MJIntegrationObjectFieldEntity } from '@memberjunction/core-entities';
23
+ import {
24
+ IntegrationEngineBase,
25
+ ENTITY_COMPANY_INTEGRATION_OBJECT_FIELDS,
26
+ type CompanyIntegrationObjectFieldRow,
27
+ } from '@memberjunction/integration-engine-base';
28
+ import { CurrentCatalogCI } from '@memberjunction/integration-engine';
29
+
30
+ /**
31
+ * What a schema build — and a refresh's re-key check — reads off a field row. The shared entity and
32
+ * the per-connection row both satisfy it.
33
+ */
34
+ export type BuildFieldRow = Pick<
35
+ MJIntegrationObjectFieldEntity,
36
+ 'Name' | 'DisplayName' | 'Description' | 'Type' | 'IsRequired' | 'AllowsNull' | 'Length' | 'Precision'
37
+ | 'Scale' | 'DefaultValue' | 'IsPrimaryKey' | 'IsUniqueKey' | 'IsReadOnly' | 'RelatedIntegrationObjectID' | 'Status'
38
+ | 'Sequence'
39
+ >;
40
+
41
+ /** A connection's field rows, keyed by lower-cased per-connection object id. */
42
+ export type ScopedBuildFields = Map<string, CompanyIntegrationObjectFieldRow[]>;
43
+
44
+ /** Objects per read. Each read is one `IN (…)` list, so this bounds the filter's length. */
45
+ export const SCOPED_FIELDS_CHUNK = 200;
46
+
47
+ /** A per-connection field row as the database returns it — before the legacy read names are derived. */
48
+ type StoredFieldRow = Omit<CompanyIntegrationObjectFieldRow, 'IntegrationObjectID' | 'RelatedIntegrationObjectID'>;
49
+
50
+ /**
51
+ * Loads the field rows of the connection in catalog scope for a schema build, or returns `null`
52
+ * when the build should read the shared catalog (no scope, or no per-connection catalog).
53
+ *
54
+ * @throws PER_CONNECTION_FIELDS_UNREADABLE when a read fails — never an empty answer.
55
+ */
56
+ export async function LoadScopedFieldsForBuild(integrationID: string, user: UserInfo): Promise<ScopedBuildFields | null> {
57
+ const ciID = CurrentCatalogCI();
58
+ if (!ciID) return null;
59
+ const engine = IntegrationEngineBase.Instance;
60
+ if (!engine.HasCompanyIntegrationCatalog(ciID)) return null;
61
+
62
+ const objects = engine.GetActiveIntegrationObjects(integrationID);
63
+ const byObject: ScopedBuildFields = new Map();
64
+ const rv = new RunView();
65
+ for (let i = 0; i < objects.length; i += SCOPED_FIELDS_CHUNK) {
66
+ const chunk = objects.slice(i, i + SCOPED_FIELDS_CHUNK);
67
+ const ids = chunk.map(o => `'${String(o.ID).replace(/'/g, "''")}'`).join(',');
68
+ const res = await rv.RunView<StoredFieldRow>({
69
+ EntityName: ENTITY_COMPANY_INTEGRATION_OBJECT_FIELDS,
70
+ ExtraFilter: `CompanyIntegrationObjectID IN (${ids})`,
71
+ ResultType: 'simple',
72
+ BypassCache: true,
73
+ IgnoreMaxRows: true,
74
+ }, user);
75
+ if (!res?.Success) {
76
+ throw new Error(
77
+ `PER_CONNECTION_FIELDS_UNREADABLE: could not read the field rows of connection ${ciID} ` +
78
+ `(objects ${i + 1}-${i + chunk.length} of ${objects.length}): ${res?.ErrorMessage ?? 'unknown error'}. ` +
79
+ `Refusing to build a schema from an empty field list.`
80
+ );
81
+ }
82
+ for (const row of res.Results ?? []) addRow(byObject, row);
83
+ }
84
+ const rowCount = [...byObject.values()].reduce((n, rows) => n + rows.length, 0);
85
+ console.log(`[LoadScopedFieldsForBuild] connection ${ciID}: ${rowCount} field rows for ${byObject.size} of ${objects.length} active objects`);
86
+ return byObject;
87
+ }
88
+
89
+ /**
90
+ * The fields a build reads for one object: the connection's rows when they were loaded, the
91
+ * engine's catalog otherwise. With loaded rows the engine is not consulted at all, so a cold
92
+ * per-connection field cache cannot empty the build.
93
+ */
94
+ export function FieldsForBuild(objectID: string, scoped: ScopedBuildFields | null | undefined, engine: IntegrationEngineBase): BuildFieldRow[] {
95
+ if (scoped) return scoped.get(String(objectID).trim().toLowerCase()) ?? [];
96
+ return engine.GetIntegrationObjectFields(objectID);
97
+ }
98
+
99
+ /**
100
+ * Files one stored row under its object, deriving the two legacy names the build reads
101
+ * (`IntegrationObjectID`, `RelatedIntegrationObjectID`) exactly as the engine's projection does.
102
+ */
103
+ function addRow(byObject: ScopedBuildFields, row: StoredFieldRow): void {
104
+ const key = String(row.CompanyIntegrationObjectID).trim().toLowerCase();
105
+ const projected: CompanyIntegrationObjectFieldRow = {
106
+ ...row,
107
+ IntegrationObjectID: row.CompanyIntegrationObjectID,
108
+ RelatedIntegrationObjectID: row.RelatedCompanyIntegrationObjectID ?? null,
109
+ };
110
+ const bucket = byObject.get(key);
111
+ if (bucket) bucket.push(projected);
112
+ else byObject.set(key, [projected]);
113
+ }
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Refuses a schema build whose selected objects produced no target table.
3
+ *
4
+ * `buildTargetConfigs` drops a selected object that is not in the source schema, has no fields or
5
+ * has no primary key, and logs each drop — but every execution caller then built and ran a migration
6
+ * anyway. With nothing accepted that migration is a header-only file: RSU wrote it, opened and merged
7
+ * a PR, ran CodeGen, redeployed Explorer, and the sync "completed" over zero entity maps, every signal
8
+ * green. Seen 2026-10-29 on a PropFuel connection: three selections requested, three dropped as
9
+ * notInSchema, three empty migrations committed.
10
+ *
11
+ * A caller that asked for tables and gets none has failed, and should hear so with the names it asked
12
+ * for and why each was dropped — in the error itself, because an API or UI caller cannot read the
13
+ * server log line that used to be the only place the reasons appeared. Preview is deliberately not
14
+ * gated: an empty preview is an honest answer.
15
+ */
16
+ import type { TargetTableConfig } from '@memberjunction/integration-schema-builder';
17
+
18
+ /** Why `buildTargetConfigs` left each selected object out. */
19
+ export interface TargetConfigDrops {
20
+ NotInSchema: string[];
21
+ NoFields: string[];
22
+ NoPrimaryKey: string[];
23
+ }
24
+
25
+ /** How many names one list in the error shows before summarising the rest — the summary log's cap. */
26
+ export const TARGET_CONFIG_NAME_SAMPLE = 5;
27
+
28
+ /** An empty set of drop lists, for `buildTargetConfigs` to fill. */
29
+ export function NewTargetConfigDrops(): TargetConfigDrops {
30
+ return { NotInSchema: [], NoFields: [], NoPrimaryKey: [] };
31
+ }
32
+
33
+ /** `a, b, c, d, e and 163 more` — so a large selection cannot make a multi-KB error. */
34
+ export function SampleNames(names: ReadonlyArray<string>): string {
35
+ const head = names.slice(0, TARGET_CONFIG_NAME_SAMPLE).join(', ');
36
+ const rest = names.length - TARGET_CONFIG_NAME_SAMPLE;
37
+ return rest > 0 ? `${head} and ${rest} more` : head;
38
+ }
39
+
40
+ /**
41
+ * Throws `NO_TARGET_TABLES` when objects were selected and none produced a target table.
42
+ *
43
+ * @param drops why each object was dropped; without it the error lists the three possible reasons.
44
+ * @param alreadyCommitted what the caller had already written before the build, for a caller that
45
+ * cannot honestly say "Nothing was applied" (schema evolution persists the catalog and disables the
46
+ * removed objects' maps first).
47
+ */
48
+ export function AssertTargetConfigs(
49
+ objects: ReadonlyArray<{ SourceObjectName: string }>,
50
+ targetConfigs: ReadonlyArray<TargetTableConfig>,
51
+ sourceType: string,
52
+ drops?: TargetConfigDrops,
53
+ alreadyCommitted?: string,
54
+ ): void {
55
+ if (objects.length === 0 || targetConfigs.length > 0) return;
56
+ const reasons = drops ? describeDrops(drops) : '';
57
+ throw new Error(
58
+ `NO_TARGET_TABLES: none of the ${objects.length} selected object(s) for ${sourceType} produced a target table ` +
59
+ `(${SampleNames(objects.map(o => o.SourceObjectName))}). ` +
60
+ (reasons || 'Each was dropped as not in the source schema, without fields, or without a primary key.') +
61
+ ` ${alreadyCommitted ?? 'Nothing was applied.'} Re-run discovery for this connection and apply again.`
62
+ );
63
+ }
64
+
65
+ function describeDrops(drops: TargetConfigDrops): string {
66
+ const parts: string[] = [];
67
+ if (drops.NotInSchema.length > 0) parts.push(`not in the source schema: ${SampleNames(drops.NotInSchema)}`);
68
+ if (drops.NoFields.length > 0) parts.push(`no fields: ${SampleNames(drops.NoFields)}`);
69
+ if (drops.NoPrimaryKey.length > 0) parts.push(`no primary key: ${SampleNames(drops.NoPrimaryKey)}`);
70
+ return parts.length > 0 ? `Dropped as ${parts.join('; ')}.` : '';
71
+ }
@@ -1,7 +1,7 @@
1
- import type { MiddlewareFn } from 'type-graphql';
1
+ import type { MiddlewareFn, ResolverData } from 'type-graphql';
2
2
  import { getMetadataStorage } from 'type-graphql';
3
- import { getNamedType } from 'graphql';
4
- import type { GraphQLArgument } from 'graphql';
3
+ import { defaultFieldResolver, getNamedType } from 'graphql';
4
+ import type { GraphQLArgument, GraphQLField, GraphQLObjectType, GraphQLSchema } from 'graphql';
5
5
  import { configInfo } from '../config.js';
6
6
  import type { AppContext } from '../types.js';
7
7
  import { RedactArg } from './secretRedactor.js';
@@ -191,6 +191,62 @@ export const VariablesLoggingMiddleware: MiddlewareFn<AppContext> = async (actio
191
191
  /** @deprecated Use {@link VariablesLoggingMiddleware}. */
192
192
  export const variablesLoggingMiddleware: MiddlewareFn<AppContext> = VariablesLoggingMiddleware;
193
193
 
194
+ /**
195
+ * Attaches {@link VariablesLoggingMiddleware} ONLY to root `Query`, `Mutation`, and `Subscription`
196
+ * fields on the compiled GraphQLSchema instead of registering it via TypeGraphQL `globalMiddlewares`.
197
+ *
198
+ * Registering a global middleware in TypeGraphQL wraps every scalar and child field resolver across
199
+ * all 300+ `@ObjectType` entities in an async middleware chain, allocating $O(\text{Rows} \times \text{Fields})$
200
+ * Promises per query even when `logVariables` is false or `info.path.prev !== undefined`.
201
+ * Wrapping only the root operation fields reduces middleware invocations from ~15,000 per 500-row
202
+ * `RunView` response down to 1.
203
+ */
204
+ export function ApplyRootVariablesLoggingMiddleware(
205
+ schema: GraphQLSchema,
206
+ middleware: MiddlewareFn<AppContext> = VariablesLoggingMiddleware
207
+ ): GraphQLSchema {
208
+ const rootTypes: Array<GraphQLObjectType | null | undefined> = [
209
+ schema.getQueryType(),
210
+ schema.getMutationType(),
211
+ schema.getSubscriptionType(),
212
+ ];
213
+
214
+ for (const rootType of rootTypes) {
215
+ if (!rootType) continue;
216
+ const fields = rootType.getFields();
217
+ for (const field of Object.values(fields) as Array<GraphQLField<unknown, AppContext>>) {
218
+ if (field.resolve) {
219
+ const originalResolve = field.resolve;
220
+ field.resolve = (root, args, context, info) => {
221
+ const action: ResolverData<AppContext> = {
222
+ root,
223
+ args: args as Record<string, unknown>,
224
+ context,
225
+ info,
226
+ };
227
+ return middleware(action, async () => originalResolve(root, args, context, info));
228
+ };
229
+ }
230
+ if (field.subscribe) {
231
+ const originalSubscribe = field.subscribe;
232
+ field.subscribe = (root, args, context, info) => {
233
+ const action: ResolverData<AppContext> = {
234
+ root,
235
+ args: args as Record<string, unknown>,
236
+ context,
237
+ info,
238
+ };
239
+ return middleware(action, async () =>
240
+ originalSubscribe ? originalSubscribe(root, args, context, info) : defaultFieldResolver(root, args, context, info)
241
+ );
242
+ };
243
+ }
244
+ }
245
+ }
246
+
247
+ return schema;
248
+ }
249
+
194
250
  /**
195
251
  * Heuristic: an arg is "custom" (i.e. needs `@NoLog` discipline because metadata can't redact it)
196
252
  * when its GraphQL input type is not a known `Create<X>Input` / `Update<X>Input` for an entity
@@ -64,9 +64,13 @@ The principal comes from the **server-authenticated** context (`userPayload.user
64
64
  argument. An id argument only selects *which of the caller's own sessions*.
65
65
 
66
66
  A caller may use a session when `AIAgentSession.UserID` equals their user (`UUIDsEqual`). Widget guests all
67
- share one Anonymous user, so for an anonymous/magic-link principal that is **not enough**: the guest's
68
- signed per-session scope (`MagicLinkScope.ResourceID`) must equal the session's conversation `ExternalID`.
69
- An anonymous principal with no scope is refused outright.
67
+ share one Anonymous user, so for an anonymous/magic-link principal that is **not enough**: the session's
68
+ conversation `ExternalID` must equal the principal's scope identity (`ResolveSessionScopeIdentity`): the
69
+ signed `MagicLinkScope.ResourceID` when the token carries one, else the anonymous visitor's `mj_sid`.
70
+ `SessionManager` stamps that same value when it creates the conversation. An anonymous principal with
71
+ neither is refused outright. A *named* user with a resource scope must match too, which keeps one person's
72
+ different links apart; but it may also use its own session on a conversation that carries no stamp (one
73
+ started from the Conversations app) when its own row-level security let it read that conversation.
70
74
 
71
75
  - Refusals are uniform ("session not found") whether the session is missing or simply not yours, so ids
72
76
  cannot be probed.
@@ -54,6 +54,7 @@ function toSnapshot(loaded: LoadedSessionForAccess): SessionSnapshot {
54
54
  AgentSessionID: Session.ID,
55
55
  OwnerUserID: Session.UserID,
56
56
  ConversationExternalID: loaded.ConversationExternalID,
57
+ ConversationReadable: loaded.ConversationReadable,
57
58
  Status: Session.Status,
58
59
  ConfigRaw: Session.Config_,
59
60
  // `__mj_CreatedAt` is the row's creation instant — i.e. the session start. It is read-only and
@@ -8,6 +8,7 @@
8
8
  import { IMetadataProvider, LogError, UserInfo } from '@memberjunction/core';
9
9
  import { UUIDsEqual } from '@memberjunction/global';
10
10
  import type { MJAIAgentSessionEntity } from '@memberjunction/core-entities';
11
+ import { AuthorizeLoadedSession } from './sessionAccess.js';
11
12
 
12
13
  const SESSION_ENTITY = 'MJ: AI Agent Sessions';
13
14
 
@@ -19,7 +20,7 @@ export class RealtimeSessionNotFoundError extends Error {
19
20
  }
20
21
  }
21
22
 
22
- /** The session exists but belongs to another user. */
23
+ /** The session exists but the caller may not use it: another user owns it, or (for a scoped or anonymous caller) its conversation carries another scope identity. */
23
24
  export class RealtimeSessionOwnershipError extends Error {
24
25
  constructor(public readonly AgentSessionID: string) {
25
26
  super('Not authorized: you do not own this realtime session');
@@ -28,13 +29,15 @@ export class RealtimeSessionOwnershipError extends Error {
28
29
  }
29
30
 
30
31
  /**
31
- * Loads a session under the caller's identity and enforces ownership (`UserID === contextUser.ID`). It
32
- * deliberately does NOT reject `Closed` sessions: the final channel-state flush and the recording terminal
33
- * signal legitimately arrive after the session closed. A scoped-anonymous widget guest owns the session it
34
- * minted, so the same check covers it; loading as the caller also applies the entity's row-level security.
32
+ * Loads a session under the caller's identity and enforces ownership: `UserID === contextUser.ID`, then the
33
+ * scope rule of {@link AuthorizeSessionAccess} (every anonymous visitor shares one Anonymous user, so the
34
+ * session's conversation `ExternalID` must equal the caller's scope identity). It deliberately does NOT
35
+ * reject `Closed` sessions: the final channel-state flush and the recording terminal signal legitimately
36
+ * arrive after the session closed. Loading as the caller also applies the entity's row-level security.
35
37
  *
36
38
  * @throws RealtimeSessionNotFoundError when the row does not load
37
- * @throws RealtimeSessionOwnershipError when the caller is not the owner (logged with both user ids)
39
+ * @throws RealtimeSessionOwnershipError when another user owns the session (logged with both user ids) or
40
+ * the scope rule refuses the caller (logged with the refusal reason)
38
41
  */
39
42
  export async function LoadOwnedRealtimeSession(
40
43
  agentSessionId: string,
@@ -51,5 +54,12 @@ export async function LoadOwnedRealtimeSession(
51
54
  );
52
55
  throw new RealtimeSessionOwnershipError(agentSessionId);
53
56
  }
57
+ const access = await AuthorizeLoadedSession(session, contextUser, provider);
58
+ if (!access.Allowed) {
59
+ LogError(
60
+ `LoadOwnedRealtimeSession: session access refused (${access.Reason}) — user ${contextUser.ID} attempted to operate on session ${agentSessionId}`,
61
+ );
62
+ throw new RealtimeSessionOwnershipError(agentSessionId);
63
+ }
54
64
  return session;
55
65
  }
@@ -9,13 +9,17 @@
9
9
  * ## The two ownership rules
10
10
  *
11
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.
12
+ * 2. **Scope.** A *named* user is fully identified by (1). An **anonymous visitor** (widget guest or
13
+ * anonymous magic-link invitee) is not: every one authenticates as the one shared Anonymous user, so
14
+ * (1) alone would let any visitor address any other visitor's session. What separates them is the
15
+ * scope identity {@link ResolveSessionScopeIdentity} reads off the signed token — the resource scope
16
+ * (`MagicLinkScope.ResourceID`) when the token carries one, else the per-token `mj_sid`
17
+ * (`AnonymousVisitorID`). `SessionManager` stamps that same value onto the session's Conversation as
18
+ * `ExternalID`, so a principal with a scope identity must match it, and an anonymous principal with
19
+ * none is refused outright — it cannot be told apart from every other anonymous principal.
20
+ * One allowance: a NAMED principal with a resource scope may also use its own session whose
21
+ * conversation carries no stamp at all, when it could read that conversation (see the comment in
22
+ * {@link AuthorizeSessionAccess}).
19
23
  *
20
24
  * The decision is deliberately pure (no I/O) so it can be applied identically to a freshly loaded
21
25
  * row at subscribe time and to the owner/scope snapshot carried inside each published event.
@@ -41,14 +45,22 @@ export interface SessionAccessSubject {
41
45
  * could not be loaded.
42
46
  */
43
47
  ConversationExternalID: string | null | undefined;
48
+ /**
49
+ * True when the conversation was loaded under the CALLER's identity (so its row-level security allowed
50
+ * the read). Only consulted for a named principal with a resource scope on a conversation that carries
51
+ * no `ExternalID`; omitted means unknown and is treated as unreadable (fail closed).
52
+ */
53
+ ConversationReadable?: boolean;
44
54
  }
45
55
 
46
56
  /** What the decision needs to know about the caller (a subset of `UserInfo`). */
47
57
  export interface SessionAccessPrincipal {
48
58
  /** The caller's user id. */
49
59
  ID: string;
50
- /** True for the shared-Anonymous-user principal of a public-widget guest. */
60
+ /** True for the shared-Anonymous-user principal of a public-widget guest or anonymous magic-link invitee. */
51
61
  IsMagicLinkAnonymous?: boolean;
62
+ /** Per-visitor session identity (`mj_sid`) for an anonymous principal. */
63
+ AnonymousVisitorID?: string;
52
64
  /** The signed per-session scope carried by the caller's token, when any. */
53
65
  MagicLinkScope?: { ResourceID?: string } | undefined;
54
66
  }
@@ -57,7 +69,29 @@ export interface SessionAccessPrincipal {
57
69
  export type SessionAccessRefusal = 'not_owner' | 'scope_missing' | 'scope_mismatch';
58
70
 
59
71
  /** Outcome of {@link AuthorizeSessionAccess}. */
60
- export type SessionAccessDecision = { Allowed: true } | { Allowed: false; Reason: SessionAccessRefusal };
72
+ export type SessionAccessDecision =
73
+ | { Allowed: true; Reason?: undefined }
74
+ | { Allowed: false; Reason: SessionAccessRefusal };
75
+
76
+ /**
77
+ * The scope identity a session is keyed on for `principal` — the one value `SessionManager` stamps as
78
+ * the session conversation's `ExternalID` and {@link AuthorizeSessionAccess} compares against it.
79
+ *
80
+ * - The token's resource scope (`MagicLinkScope.ResourceID`) when it carries one. A widget guest's
81
+ * resource scope IS its `mj_sid`; an anonymous magic-link invite with a `ResourceID` (e.g. a Caliber
82
+ * Invite Scope, one per subject) shares that scope across its redemptions by design, and the
83
+ * `{{ScopeResourceID}}` RLS filters key on the same value, so the visitor can read its own rows.
84
+ * - Otherwise, for an anonymous principal, the per-token `mj_sid` (`AnonymousVisitorID`), which tells two
85
+ * redemptions of an unscoped multi-use invite apart.
86
+ * - Otherwise `undefined` (a named user without a resource scope).
87
+ */
88
+ export function ResolveSessionScopeIdentity(principal: SessionAccessPrincipal): string | undefined {
89
+ const resourceId = principal.MagicLinkScope?.ResourceID;
90
+ if (resourceId) {
91
+ return resourceId;
92
+ }
93
+ return principal.IsMagicLinkAnonymous ? principal.AnonymousVisitorID || undefined : undefined;
94
+ }
61
95
 
62
96
  /**
63
97
  * Decides whether `principal` may address the session described by `subject`.
@@ -74,14 +108,26 @@ export function AuthorizeSessionAccess(
74
108
  if (!principal?.ID || !subject.SessionUserID || !UUIDsEqual(subject.SessionUserID, principal.ID)) {
75
109
  return { Allowed: false, Reason: 'not_owner' };
76
110
  }
77
- const scopeId = principal.MagicLinkScope?.ResourceID;
111
+ const scopeId = ResolveSessionScopeIdentity(principal);
78
112
  if (!scopeId) {
79
- // An anonymous principal without a per-session scope is indistinguishable from every other
80
- // anonymous principal: owning "the Anonymous user's" session proves nothing.
113
+ // A named user without a scope is identified by the owner check alone; an anonymous principal
114
+ // without one cannot be told apart from any other anonymous principal.
81
115
  return principal.IsMagicLinkAnonymous ? { Allowed: false, Reason: 'scope_missing' } : { Allowed: true };
82
116
  }
83
117
  // Scope ids are opaque base64url strings (case-significant), so compare exactly — not UUIDsEqual.
84
- return subject.ConversationExternalID === scopeId ? { Allowed: true } : { Allowed: false, Reason: 'scope_mismatch' };
118
+ if (subject.ConversationExternalID === scopeId) {
119
+ return { Allowed: true };
120
+ }
121
+ // A named user is identified by the owner check; its scope only keeps one link's sessions apart from
122
+ // the same person's other links (magic links resolve the user by email, so one person can hold several).
123
+ // A conversation with no stamp belongs to no link (one started from the Conversations app), so the owner
124
+ // may use it when its own row-level security let it read the conversation. `ExternalID` is not stamped
125
+ // here because other features own that column on their conversations (meeting room names, for example).
126
+ // An anonymous visitor gets no such allowance: the stamp is the only thing that identifies it.
127
+ if (!principal.IsMagicLinkAnonymous && subject.ConversationExternalID === null && subject.ConversationReadable === true) {
128
+ return { Allowed: true };
129
+ }
130
+ return { Allowed: false, Reason: 'scope_mismatch' };
85
131
  }
86
132
 
87
133
  /** A session row together with the one fact about its conversation the decision needs. */
@@ -90,6 +136,8 @@ export interface LoadedSessionForAccess {
90
136
  Session: MJAIAgentSessionEntity;
91
137
  /** The session's conversation `ExternalID` (anonymous scope id), or null. */
92
138
  ConversationExternalID: string | null;
139
+ /** Whether the caller could read the session's conversation (false when there is none). */
140
+ ConversationReadable: boolean;
93
141
  }
94
142
 
95
143
  /**
@@ -115,31 +163,169 @@ export async function LoadSessionForAccess(
115
163
  if (!(await session.Load(agentSessionId))) {
116
164
  return null;
117
165
  }
118
- return { Session: session, ConversationExternalID: await LoadSessionConversationExternalID(session, contextUser, provider) };
166
+ const conversation = await LoadSessionConversationScope(session, contextUser, provider);
167
+ return { Session: session, ConversationExternalID: conversation.ExternalID, ConversationReadable: conversation.Readable };
168
+ }
169
+
170
+ /** What the caller could learn about a session's conversation: the scope half of {@link SessionAccessSubject}. */
171
+ export interface SessionConversationScope {
172
+ /** The conversation's `ExternalID` (the anonymous scope id), or null when it has none or was not read. */
173
+ ExternalID: string | null;
174
+ /** Whether the caller could read the conversation (false when the session has none). */
175
+ Readable: boolean;
176
+ }
177
+
178
+ /** {@link SessionConversationScope} plus the conversation's owner, for a conversation addressed without a session. */
179
+ export interface ConversationScope extends SessionConversationScope {
180
+ /** `Conversation.UserID`, or null when the conversation was not read. */
181
+ UserID: string | null;
119
182
  }
120
183
 
121
184
  /**
122
- * Reads an already-loaded session's conversation `ExternalID` (the anonymous scope id) under `contextUser`;
123
- * null when there is no conversation or it cannot be read (logged). For callers that loaded the session
124
- * through another gate and only need the scope half of {@link AuthorizeSessionAccess}'s subject.
185
+ * Reads an already-loaded session's conversation under `contextUser` (so its row-level security applies).
186
+ * A missing conversation, a refused read and a failed read (logged) all report `Readable: false`. For
187
+ * callers that loaded the session through another gate and only need the scope half of
188
+ * {@link AuthorizeSessionAccess}'s subject.
125
189
  */
126
- export async function LoadSessionConversationExternalID(
190
+ export async function LoadSessionConversationScope(
127
191
  session: MJAIAgentSessionEntity,
128
192
  contextUser: UserInfo,
129
193
  provider: IMetadataProvider,
130
- ): Promise<string | null> {
194
+ ): Promise<SessionConversationScope> {
131
195
  if (!session.ConversationID) {
132
- return null;
196
+ return { ExternalID: null, Readable: false };
197
+ }
198
+ const { ExternalID, Readable } = await LoadConversationScope(session.ConversationID, contextUser, provider);
199
+ return { ExternalID, Readable };
200
+ }
201
+
202
+ /**
203
+ * Decides whether `contextUser` may address an already-loaded `session`: the {@link AuthorizeSessionAccess}
204
+ * decision, reading the session's conversation only when that decision needs it.
205
+ *
206
+ * {@link AuthorizeSessionAccess} decides a principal without a scope identity — a named user with no magic-link
207
+ * scope, the usual signed-in caller — from the owner check alone, and refuses a non-owner before it looks at
208
+ * anything else, so neither needs the conversation read. This function and that one encode the same rule on
209
+ * purpose and live together for that reason: change the rule there, change the read here. The
210
+ * `AuthorizeLoadedSession` table test in `sessionAccess.test.ts` fails if the two ever disagree.
211
+ *
212
+ * @param session - the session, loaded through the caller's own gate
213
+ * @param contextUser - the authenticated caller; the conversation, when read, is read as this user (RLS applies)
214
+ * @param provider - the request-scoped provider
215
+ */
216
+ export async function AuthorizeLoadedSession(
217
+ session: MJAIAgentSessionEntity,
218
+ contextUser: UserInfo,
219
+ provider: IMetadataProvider,
220
+ ): Promise<SessionAccessDecision> {
221
+ const ownsSession = !!contextUser?.ID && !!session.UserID && UUIDsEqual(session.UserID, contextUser.ID);
222
+ if (!ownsSession || !ResolveSessionScopeIdentity(contextUser)) {
223
+ return AuthorizeSessionAccess({ SessionUserID: session.UserID, ConversationExternalID: null, ConversationReadable: false }, contextUser);
224
+ }
225
+ const conversation = await LoadSessionConversationScope(session, contextUser, provider);
226
+ return AuthorizeSessionAccess(
227
+ { SessionUserID: session.UserID, ConversationExternalID: conversation.ExternalID, ConversationReadable: conversation.Readable },
228
+ contextUser,
229
+ );
230
+ }
231
+
232
+ /**
233
+ * Reads a conversation's owner and scope id under `contextUser` (so its row-level security applies), for a
234
+ * caller that addresses the conversation directly rather than through a session — a text agent turn, for
235
+ * example, whose only handle is a message in it. Together with the caller's principal this is exactly the
236
+ * subject {@link AuthorizeSessionAccess} decides on: `SessionUserID` is the conversation's owner, since the
237
+ * session a conversation belongs to is owned by the same user.
238
+ *
239
+ * An empty id, a missing conversation, a refused read and a failed read (logged) all report
240
+ * `Readable: false` with no owner, which {@link AuthorizeSessionAccess} then refuses for any scoped caller.
241
+ */
242
+ export async function LoadConversationScope(
243
+ conversationId: string | null | undefined,
244
+ contextUser: UserInfo,
245
+ provider: IMetadataProvider,
246
+ ): Promise<ConversationScope> {
247
+ const unreadable: ConversationScope = { UserID: null, ExternalID: null, Readable: false };
248
+ if (!conversationId) {
249
+ return unreadable;
133
250
  }
134
251
  try {
135
252
  const conversation = await provider.GetEntityObject<MJConversationEntity>(CONVERSATION_ENTITY, contextUser);
136
- if (!(await conversation.Load(session.ConversationID))) {
137
- return null;
253
+ if (!(await conversation.Load(conversationId))) {
254
+ return unreadable;
138
255
  }
139
- return conversation.ExternalID ?? null;
256
+ return { UserID: conversation.UserID ?? null, ExternalID: conversation.ExternalID ?? null, Readable: true };
140
257
  } catch (error) {
141
258
  const message = error instanceof Error ? error.message : String(error);
142
- LogError(`LoadSessionForAccess: could not read conversation ${session.ConversationID} of session ${session.ID}: ${message}`);
143
- return null;
259
+ LogError(`LoadConversationScope: could not read conversation ${conversationId} for user ${contextUser?.ID}: ${message}`);
260
+ return unreadable;
261
+ }
262
+ }
263
+
264
+ /**
265
+ * Who may run a conversation turn (a text agent turn, addressed by a message in the conversation) in
266
+ * `conversationId`, decided the same way as session access.
267
+ *
268
+ * A NAMED principal is allowed without a read: its entity permissions and row filters already decided
269
+ * whether it could load the message, and a named user is fully identified by its `UserID`. An ANONYMOUS
270
+ * principal is not (see the module doc), so the conversation is read as the caller and
271
+ * {@link AuthorizeSessionAccess} compares its scope id with the conversation's stamp — the same
272
+ * decision #5997 applies to the realtime gates, so the text and voice paths agree on ownership.
273
+ * An unreadable conversation refuses (`not_owner`, there is no owner to match).
274
+ */
275
+ export async function AuthorizeConversationTurn(
276
+ conversationId: string,
277
+ principal: UserInfo,
278
+ provider: IMetadataProvider,
279
+ ): Promise<SessionAccessDecision> {
280
+ if (!principal?.IsMagicLinkAnonymous) {
281
+ return { Allowed: true };
282
+ }
283
+ const scope = await LoadConversationScope(conversationId, principal, provider);
284
+ return AuthorizeSessionAccess(
285
+ { SessionUserID: scope.UserID ?? '', ConversationExternalID: scope.ExternalID, ConversationReadable: scope.Readable },
286
+ principal,
287
+ );
288
+ }
289
+
290
+ /**
291
+ * Whether an anonymous caller owns any of a LiveKit room's agent sessions — the check MJServer registers with
292
+ * `RoomAuthorizationService.SetAnonymousSessionOwnerCheck` (`@memberjunction/livekit-room-server` cannot import
293
+ * this package). Each session is loaded as the caller (its row-level security applies) and decided by
294
+ * {@link AuthorizeSessionAccess}, the same decision every realtime gate makes, so a room admits exactly the visitor
295
+ * whose scope id its session's conversation carries (MJ#6044). Nothing to read, or no provider: refused.
296
+ */
297
+ export async function AuthorizeAnonymousRoomSessions(
298
+ agentSessionIds: string[],
299
+ user: UserInfo,
300
+ provider: IMetadataProvider | undefined,
301
+ ): Promise<boolean> {
302
+ if (agentSessionIds.length === 0 || !provider) {
303
+ return false;
304
+ }
305
+ for (const agentSessionId of agentSessionIds) {
306
+ const loaded = await LoadSessionForAccess(agentSessionId, user, provider);
307
+ if (!loaded) {
308
+ continue;
309
+ }
310
+ const decision = AuthorizeSessionAccess(
311
+ { SessionUserID: loaded.Session.UserID, ConversationExternalID: loaded.ConversationExternalID, ConversationReadable: loaded.ConversationReadable },
312
+ user,
313
+ );
314
+ if (decision.Allowed) {
315
+ return true;
316
+ }
144
317
  }
318
+ return false;
319
+ }
320
+
321
+ /**
322
+ * The session conversation's `ExternalID` alone; null when there is none or it cannot be read.
323
+ * Prefer {@link LoadSessionConversationScope}, which also says whether the read succeeded.
324
+ */
325
+ export async function LoadSessionConversationExternalID(
326
+ session: MJAIAgentSessionEntity,
327
+ contextUser: UserInfo,
328
+ provider: IMetadataProvider,
329
+ ): Promise<string | null> {
330
+ return (await LoadSessionConversationScope(session, contextUser, provider)).ExternalID;
145
331
  }
@@ -113,7 +113,7 @@ export async function LoadInheritedVerifiedIdentity(
113
113
  return undefined;
114
114
  }
115
115
  const decision = AuthorizeSessionAccess(
116
- { SessionUserID: prior.Session.UserID, ConversationExternalID: prior.ConversationExternalID },
116
+ { SessionUserID: prior.Session.UserID, ConversationExternalID: prior.ConversationExternalID, ConversationReadable: prior.ConversationReadable },
117
117
  contextUser,
118
118
  );
119
119
  if (decision.Allowed === false) {