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

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 (560) hide show
  1. package/README.md +47 -1
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/agentSessions/SessionJanitor.d.ts +91 -30
  4. package/dist/agentSessions/SessionJanitor.d.ts.map +1 -1
  5. package/dist/agentSessions/SessionJanitor.js +311 -81
  6. package/dist/agentSessions/SessionJanitor.js.map +1 -1
  7. package/dist/agentSessions/SessionManager.d.ts +17 -3
  8. package/dist/agentSessions/SessionManager.d.ts.map +1 -1
  9. package/dist/agentSessions/SessionManager.js +44 -10
  10. package/dist/agentSessions/SessionManager.js.map +1 -1
  11. package/dist/apiRoot.d.ts +32 -0
  12. package/dist/apiRoot.d.ts.map +1 -0
  13. package/dist/apiRoot.js +67 -0
  14. package/dist/apiRoot.js.map +1 -0
  15. package/dist/auth/AuthProviderCatalogRouter.d.ts.map +1 -1
  16. package/dist/auth/AuthProviderCatalogRouter.js +27 -0
  17. package/dist/auth/AuthProviderCatalogRouter.js.map +1 -1
  18. package/dist/auth/LoginScreenEngine.d.ts +22 -0
  19. package/dist/auth/LoginScreenEngine.d.ts.map +1 -0
  20. package/dist/auth/LoginScreenEngine.js +57 -0
  21. package/dist/auth/LoginScreenEngine.js.map +1 -0
  22. package/dist/auth/index.d.ts +1 -0
  23. package/dist/auth/index.d.ts.map +1 -1
  24. package/dist/auth/index.js +52 -10
  25. package/dist/auth/index.js.map +1 -1
  26. package/dist/auth/initializeProviders.d.ts +10 -0
  27. package/dist/auth/initializeProviders.d.ts.map +1 -1
  28. package/dist/auth/initializeProviders.js +37 -1
  29. package/dist/auth/initializeProviders.js.map +1 -1
  30. package/dist/auth/localDevAuth.d.ts +79 -0
  31. package/dist/auth/localDevAuth.d.ts.map +1 -0
  32. package/dist/auth/localDevAuth.js +439 -0
  33. package/dist/auth/localDevAuth.js.map +1 -0
  34. package/dist/auth/magicLink/MagicLinkKeys.d.ts +2 -2
  35. package/dist/auth/magicLink/MagicLinkKeys.d.ts.map +1 -1
  36. package/dist/auth/magicLink/MagicLinkKeys.js +1 -1
  37. package/dist/auth/magicLink/MagicLinkKeys.js.map +1 -1
  38. package/dist/auth/magicLink/MagicLinkRouter.d.ts.map +1 -1
  39. package/dist/auth/magicLink/MagicLinkRouter.js +3 -2
  40. package/dist/auth/magicLink/MagicLinkRouter.js.map +1 -1
  41. package/dist/auth/magicLink/types.d.ts +12 -0
  42. package/dist/auth/magicLink/types.d.ts.map +1 -1
  43. package/dist/auth/sessionUserClone.d.ts +1 -1
  44. package/dist/auth/sessionUserClone.d.ts.map +1 -1
  45. package/dist/auth/sessionUserClone.js +3 -2
  46. package/dist/auth/sessionUserClone.js.map +1 -1
  47. package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.d.ts +292 -0
  48. package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.d.ts.map +1 -0
  49. package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.js +442 -0
  50. package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.js.map +1 -0
  51. package/dist/broadcast/index.d.ts +6 -0
  52. package/dist/broadcast/index.d.ts.map +1 -0
  53. package/dist/broadcast/index.js +6 -0
  54. package/dist/broadcast/index.js.map +1 -0
  55. package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.d.ts +43 -0
  56. package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.d.ts.map +1 -0
  57. package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.js +144 -0
  58. package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.js.map +1 -0
  59. package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.d.ts +46 -0
  60. package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.d.ts.map +1 -0
  61. package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.js +149 -0
  62. package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.js.map +1 -0
  63. package/dist/broadcast/providers/GCPPubSubBroadcastProvider.d.ts +49 -0
  64. package/dist/broadcast/providers/GCPPubSubBroadcastProvider.d.ts.map +1 -0
  65. package/dist/broadcast/providers/GCPPubSubBroadcastProvider.js +131 -0
  66. package/dist/broadcast/providers/GCPPubSubBroadcastProvider.js.map +1 -0
  67. package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.d.ts +24 -0
  68. package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.d.ts.map +1 -0
  69. package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.js +51 -0
  70. package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.js.map +1 -0
  71. package/dist/cache.d.ts +3 -2
  72. package/dist/cache.d.ts.map +1 -1
  73. package/dist/cache.js.map +1 -1
  74. package/dist/config.d.ts +632 -22
  75. package/dist/config.d.ts.map +1 -1
  76. package/dist/config.js +104 -4
  77. package/dist/config.js.map +1 -1
  78. package/dist/context.d.ts +3 -1
  79. package/dist/context.d.ts.map +1 -1
  80. package/dist/context.js +29 -8
  81. package/dist/context.js.map +1 -1
  82. package/dist/coreRoutes.d.ts +29 -0
  83. package/dist/coreRoutes.d.ts.map +1 -0
  84. package/dist/coreRoutes.js +156 -0
  85. package/dist/coreRoutes.js.map +1 -0
  86. package/dist/generated/graphql-schemas/__mj.d.ts +1016 -29
  87. package/dist/generated/graphql-schemas/__mj.d.ts.map +1 -1
  88. package/dist/generated/graphql-schemas/__mj.js +5125 -434
  89. package/dist/generated/graphql-schemas/__mj.js.map +1 -1
  90. package/dist/generic/CacheInvalidationResolver.d.ts +85 -30
  91. package/dist/generic/CacheInvalidationResolver.d.ts.map +1 -1
  92. package/dist/generic/CacheInvalidationResolver.js +175 -60
  93. package/dist/generic/CacheInvalidationResolver.js.map +1 -1
  94. package/dist/generic/OrphanedConversationDetailReconciler.d.ts.map +1 -1
  95. package/dist/generic/OrphanedConversationDetailReconciler.js +2 -0
  96. package/dist/generic/OrphanedConversationDetailReconciler.js.map +1 -1
  97. package/dist/generic/PubSubManager.d.ts +10 -0
  98. package/dist/generic/PubSubManager.d.ts.map +1 -1
  99. package/dist/generic/PubSubManager.js +44 -1
  100. package/dist/generic/PubSubManager.js.map +1 -1
  101. package/dist/generic/PushStatusResolver.d.ts +39 -6
  102. package/dist/generic/PushStatusResolver.d.ts.map +1 -1
  103. package/dist/generic/PushStatusResolver.js +94 -12
  104. package/dist/generic/PushStatusResolver.js.map +1 -1
  105. package/dist/generic/ResolverBase.d.ts +168 -69
  106. package/dist/generic/ResolverBase.d.ts.map +1 -1
  107. package/dist/generic/ResolverBase.js +464 -405
  108. package/dist/generic/ResolverBase.js.map +1 -1
  109. package/dist/generic/RunViewResolver.d.ts +11 -3
  110. package/dist/generic/RunViewResolver.d.ts.map +1 -1
  111. package/dist/generic/RunViewResolver.js +91 -13
  112. package/dist/generic/RunViewResolver.js.map +1 -1
  113. package/dist/generic/actionOutputFieldSecurity.d.ts +26 -0
  114. package/dist/generic/actionOutputFieldSecurity.d.ts.map +1 -0
  115. package/dist/generic/actionOutputFieldSecurity.js +47 -0
  116. package/dist/generic/actionOutputFieldSecurity.js.map +1 -0
  117. package/dist/generic/fieldSecurityTransport.d.ts +30 -0
  118. package/dist/generic/fieldSecurityTransport.d.ts.map +1 -0
  119. package/dist/generic/fieldSecurityTransport.js +30 -0
  120. package/dist/generic/fieldSecurityTransport.js.map +1 -0
  121. package/dist/globalCors.d.ts +33 -0
  122. package/dist/globalCors.d.ts.map +1 -0
  123. package/dist/globalCors.js +58 -0
  124. package/dist/globalCors.js.map +1 -0
  125. package/dist/index.d.ts +14 -0
  126. package/dist/index.d.ts.map +1 -1
  127. package/dist/index.js +230 -222
  128. package/dist/index.js.map +1 -1
  129. package/dist/integration/CustomColumnPromoter.d.ts.map +1 -1
  130. package/dist/integration/CustomColumnPromoter.js +6 -1
  131. package/dist/integration/CustomColumnPromoter.js.map +1 -1
  132. package/dist/logging/variablesLoggingMiddleware.d.ts +12 -0
  133. package/dist/logging/variablesLoggingMiddleware.d.ts.map +1 -1
  134. package/dist/logging/variablesLoggingMiddleware.js +50 -1
  135. package/dist/logging/variablesLoggingMiddleware.js.map +1 -1
  136. package/dist/multiTenancy/index.d.ts.map +1 -1
  137. package/dist/multiTenancy/index.js +22 -2
  138. package/dist/multiTenancy/index.js.map +1 -1
  139. package/dist/realtimeSessions/RealtimeSessionVerificationService.d.ts.map +1 -1
  140. package/dist/realtimeSessions/RealtimeSessionVerificationService.js +2 -1
  141. package/dist/realtimeSessions/RealtimeSessionVerificationService.js.map +1 -1
  142. package/dist/realtimeSessions/RealtimeVerifyRouter.d.ts.map +1 -1
  143. package/dist/realtimeSessions/RealtimeVerifyRouter.js +2 -1
  144. package/dist/realtimeSessions/RealtimeVerifyRouter.js.map +1 -1
  145. package/dist/realtimeSessions/RecordingAssemblyScheduler.d.ts +100 -0
  146. package/dist/realtimeSessions/RecordingAssemblyScheduler.d.ts.map +1 -0
  147. package/dist/realtimeSessions/RecordingAssemblyScheduler.js +173 -0
  148. package/dist/realtimeSessions/RecordingAssemblyScheduler.js.map +1 -0
  149. package/dist/realtimeSessions/SessionVerificationPortsBase.d.ts.map +1 -1
  150. package/dist/realtimeSessions/SessionVerificationPortsBase.js +1 -0
  151. package/dist/realtimeSessions/SessionVerificationPortsBase.js.map +1 -1
  152. package/dist/realtimeSessions/index.d.ts +2 -0
  153. package/dist/realtimeSessions/index.d.ts.map +1 -1
  154. package/dist/realtimeSessions/index.js +2 -0
  155. package/dist/realtimeSessions/index.js.map +1 -1
  156. package/dist/realtimeSessions/ownedRealtimeSession.d.ts +32 -0
  157. package/dist/realtimeSessions/ownedRealtimeSession.d.ts.map +1 -0
  158. package/dist/realtimeSessions/ownedRealtimeSession.js +56 -0
  159. package/dist/realtimeSessions/ownedRealtimeSession.js.map +1 -0
  160. package/dist/realtimeSessions/sessionAccess.d.ts +91 -8
  161. package/dist/realtimeSessions/sessionAccess.d.ts.map +1 -1
  162. package/dist/realtimeSessions/sessionAccess.js +127 -20
  163. package/dist/realtimeSessions/sessionAccess.js.map +1 -1
  164. package/dist/realtimeSessions/sessionConfigStamps.js +1 -1
  165. package/dist/realtimeSessions/sessionConfigStamps.js.map +1 -1
  166. package/dist/realtimeSessions/subscriptionAuthorization.d.ts.map +1 -1
  167. package/dist/realtimeSessions/subscriptionAuthorization.js +5 -2
  168. package/dist/realtimeSessions/subscriptionAuthorization.js.map +1 -1
  169. package/dist/realtimeSessions/verificationWorkflow.d.ts +2 -0
  170. package/dist/realtimeSessions/verificationWorkflow.d.ts.map +1 -1
  171. package/dist/realtimeSessions/verificationWorkflow.js +1 -1
  172. package/dist/realtimeSessions/verificationWorkflow.js.map +1 -1
  173. package/dist/realtimeWidget/WidgetRouter.d.ts.map +1 -1
  174. package/dist/realtimeWidget/WidgetRouter.js +19 -3
  175. package/dist/realtimeWidget/WidgetRouter.js.map +1 -1
  176. package/dist/realtimeWidget/WidgetSessionService.d.ts +67 -7
  177. package/dist/realtimeWidget/WidgetSessionService.d.ts.map +1 -1
  178. package/dist/realtimeWidget/WidgetSessionService.js +201 -19
  179. package/dist/realtimeWidget/WidgetSessionService.js.map +1 -1
  180. package/dist/realtimeWidget/host-identity.d.ts +1 -1
  181. package/dist/realtimeWidget/host-identity.js +1 -1
  182. package/dist/realtimeWidget/widgetCore.d.ts +20 -1
  183. package/dist/realtimeWidget/widgetCore.d.ts.map +1 -1
  184. package/dist/realtimeWidget/widgetCore.js +17 -1
  185. package/dist/realtimeWidget/widgetCore.js.map +1 -1
  186. package/dist/realtimeWidget/widgetGuestElevation.d.ts +1 -1
  187. package/dist/realtimeWidget/widgetGuestElevation.d.ts.map +1 -1
  188. package/dist/realtimeWidget/widgetGuestElevation.js +2 -1
  189. package/dist/realtimeWidget/widgetGuestElevation.js.map +1 -1
  190. package/dist/resolvers/ActionResolver.d.ts +19 -1
  191. package/dist/resolvers/ActionResolver.d.ts.map +1 -1
  192. package/dist/resolvers/ActionResolver.js +63 -12
  193. package/dist/resolvers/ActionResolver.js.map +1 -1
  194. package/dist/resolvers/AdhocQueryResolver.d.ts.map +1 -1
  195. package/dist/resolvers/AdhocQueryResolver.js +1 -0
  196. package/dist/resolvers/AdhocQueryResolver.js.map +1 -1
  197. package/dist/resolvers/AgentRunStatusPublisher.d.ts +18 -4
  198. package/dist/resolvers/AgentRunStatusPublisher.d.ts.map +1 -1
  199. package/dist/resolvers/AgentRunStatusPublisher.js +32 -8
  200. package/dist/resolvers/AgentRunStatusPublisher.js.map +1 -1
  201. package/dist/resolvers/AgentSessionResolver.d.ts +10 -4
  202. package/dist/resolvers/AgentSessionResolver.d.ts.map +1 -1
  203. package/dist/resolvers/AgentSessionResolver.js +40 -17
  204. package/dist/resolvers/AgentSessionResolver.js.map +1 -1
  205. package/dist/resolvers/ArtifactFileResolver.d.ts +5 -1
  206. package/dist/resolvers/ArtifactFileResolver.d.ts.map +1 -1
  207. package/dist/resolvers/ArtifactFileResolver.js +9 -7
  208. package/dist/resolvers/ArtifactFileResolver.js.map +1 -1
  209. package/dist/resolvers/ConversationRunEventsResolver.d.ts +8 -4
  210. package/dist/resolvers/ConversationRunEventsResolver.d.ts.map +1 -1
  211. package/dist/resolvers/ConversationRunEventsResolver.js +6 -6
  212. package/dist/resolvers/ConversationRunEventsResolver.js.map +1 -1
  213. package/dist/resolvers/DatasetResolver.d.ts +24 -3
  214. package/dist/resolvers/DatasetResolver.d.ts.map +1 -1
  215. package/dist/resolvers/DatasetResolver.js +57 -8
  216. package/dist/resolvers/DatasetResolver.js.map +1 -1
  217. package/dist/resolvers/EntityCommunicationsResolver.d.ts +13 -1
  218. package/dist/resolvers/EntityCommunicationsResolver.d.ts.map +1 -1
  219. package/dist/resolvers/EntityCommunicationsResolver.js +50 -14
  220. package/dist/resolvers/EntityCommunicationsResolver.js.map +1 -1
  221. package/dist/resolvers/EntityRecordNameResolver.d.ts +2 -1
  222. package/dist/resolvers/EntityRecordNameResolver.d.ts.map +1 -1
  223. package/dist/resolvers/EntityRecordNameResolver.js +3 -2
  224. package/dist/resolvers/EntityRecordNameResolver.js.map +1 -1
  225. package/dist/resolvers/FetchEntityVectorsResolver.d.ts +46 -3
  226. package/dist/resolvers/FetchEntityVectorsResolver.d.ts.map +1 -1
  227. package/dist/resolvers/FetchEntityVectorsResolver.js +211 -50
  228. package/dist/resolvers/FetchEntityVectorsResolver.js.map +1 -1
  229. package/dist/resolvers/FileCategoryResolver.d.ts.map +1 -1
  230. package/dist/resolvers/FileCategoryResolver.js +1 -0
  231. package/dist/resolvers/FileCategoryResolver.js.map +1 -1
  232. package/dist/resolvers/FileResolver.d.ts +87 -11
  233. package/dist/resolvers/FileResolver.d.ts.map +1 -1
  234. package/dist/resolvers/FileResolver.js +292 -105
  235. package/dist/resolvers/FileResolver.js.map +1 -1
  236. package/dist/resolvers/GetDataContextDataResolver.d.ts +33 -7
  237. package/dist/resolvers/GetDataContextDataResolver.d.ts.map +1 -1
  238. package/dist/resolvers/GetDataContextDataResolver.js +117 -38
  239. package/dist/resolvers/GetDataContextDataResolver.js.map +1 -1
  240. package/dist/resolvers/GetDataResolver.d.ts.map +1 -1
  241. package/dist/resolvers/GetDataResolver.js +6 -3
  242. package/dist/resolvers/GetDataResolver.js.map +1 -1
  243. package/dist/resolvers/IntegrationDiscoveryResolver.d.ts.map +1 -1
  244. package/dist/resolvers/IntegrationDiscoveryResolver.js +49 -9
  245. package/dist/resolvers/IntegrationDiscoveryResolver.js.map +1 -1
  246. package/dist/resolvers/MergeRecordsResolver.d.ts +8 -1
  247. package/dist/resolvers/MergeRecordsResolver.d.ts.map +1 -1
  248. package/dist/resolvers/MergeRecordsResolver.js +31 -3
  249. package/dist/resolvers/MergeRecordsResolver.js.map +1 -1
  250. package/dist/resolvers/PipelineProgressResolver.d.ts +6 -0
  251. package/dist/resolvers/PipelineProgressResolver.d.ts.map +1 -1
  252. package/dist/resolvers/PipelineProgressResolver.js +5 -3
  253. package/dist/resolvers/PipelineProgressResolver.js.map +1 -1
  254. package/dist/resolvers/QueryResolver.d.ts +2 -0
  255. package/dist/resolvers/QueryResolver.d.ts.map +1 -1
  256. package/dist/resolvers/QueryResolver.js +33 -6
  257. package/dist/resolvers/QueryResolver.js.map +1 -1
  258. package/dist/resolvers/QuerySystemUserResolver.d.ts +2 -0
  259. package/dist/resolvers/QuerySystemUserResolver.d.ts.map +1 -1
  260. package/dist/resolvers/QuerySystemUserResolver.js +15 -6
  261. package/dist/resolvers/QuerySystemUserResolver.js.map +1 -1
  262. package/dist/resolvers/RSUResolver.d.ts.map +1 -1
  263. package/dist/resolvers/RSUResolver.js +12 -0
  264. package/dist/resolvers/RSUResolver.js.map +1 -1
  265. package/dist/resolvers/RealtimeClientSessionResolver.d.ts +18 -10
  266. package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
  267. package/dist/resolvers/RealtimeClientSessionResolver.js +92 -54
  268. package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
  269. package/dist/resolvers/RemoteBrowserActionResolver.d.ts.map +1 -1
  270. package/dist/resolvers/RemoteBrowserActionResolver.js +11 -9
  271. package/dist/resolvers/RemoteBrowserActionResolver.js.map +1 -1
  272. package/dist/resolvers/RunAIAgentResolver.d.ts +56 -8
  273. package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
  274. package/dist/resolvers/RunAIAgentResolver.js +241 -67
  275. package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
  276. package/dist/resolvers/RunTemplateResolver.d.ts.map +1 -1
  277. package/dist/resolvers/RunTemplateResolver.js +4 -4
  278. package/dist/resolvers/RunTemplateResolver.js.map +1 -1
  279. package/dist/resolvers/RunTestResolver.d.ts.map +1 -1
  280. package/dist/resolvers/RunTestResolver.js +3 -1
  281. package/dist/resolvers/RunTestResolver.js.map +1 -1
  282. package/dist/resolvers/SearchKnowledgeStreamResolver.d.ts +12 -1
  283. package/dist/resolvers/SearchKnowledgeStreamResolver.d.ts.map +1 -1
  284. package/dist/resolvers/SearchKnowledgeStreamResolver.js +15 -2
  285. package/dist/resolvers/SearchKnowledgeStreamResolver.js.map +1 -1
  286. package/dist/resolvers/SqlLoggingConfigResolver.d.ts.map +1 -1
  287. package/dist/resolvers/SqlLoggingConfigResolver.js +2 -3
  288. package/dist/resolvers/SqlLoggingConfigResolver.js.map +1 -1
  289. package/dist/resolvers/SyncDataResolver.d.ts.map +1 -1
  290. package/dist/resolvers/SyncDataResolver.js +4 -0
  291. package/dist/resolvers/SyncDataResolver.js.map +1 -1
  292. package/dist/resolvers/TaskGraphFrameResolver.d.ts +2 -1
  293. package/dist/resolvers/TaskGraphFrameResolver.d.ts.map +1 -1
  294. package/dist/resolvers/TaskGraphFrameResolver.js +28 -1
  295. package/dist/resolvers/TaskGraphFrameResolver.js.map +1 -1
  296. package/dist/resolvers/TestQuerySQLResolver.d.ts +24 -0
  297. package/dist/resolvers/TestQuerySQLResolver.d.ts.map +1 -1
  298. package/dist/resolvers/TestQuerySQLResolver.js +66 -13
  299. package/dist/resolvers/TestQuerySQLResolver.js.map +1 -1
  300. package/dist/resolvers/TransactionGroupResolver.d.ts +34 -2
  301. package/dist/resolvers/TransactionGroupResolver.d.ts.map +1 -1
  302. package/dist/resolvers/TransactionGroupResolver.js +150 -27
  303. package/dist/resolvers/TransactionGroupResolver.js.map +1 -1
  304. package/dist/resolvers/UserViewResolver.d.ts +1 -1
  305. package/dist/resolvers/UserViewResolver.d.ts.map +1 -1
  306. package/dist/resolvers/UserViewResolver.js +2 -1
  307. package/dist/resolvers/UserViewResolver.js.map +1 -1
  308. package/dist/resolvers/agent-run-data-guard.d.ts +31 -0
  309. package/dist/resolvers/agent-run-data-guard.d.ts.map +1 -0
  310. package/dist/resolvers/agent-run-data-guard.js +72 -0
  311. package/dist/resolvers/agent-run-data-guard.js.map +1 -0
  312. package/dist/rest/EntityCRUDHandler.d.ts +6 -0
  313. package/dist/rest/EntityCRUDHandler.d.ts.map +1 -1
  314. package/dist/rest/EntityCRUDHandler.js +19 -5
  315. package/dist/rest/EntityCRUDHandler.js.map +1 -1
  316. package/dist/rest/RESTEndpointHandler.d.ts.map +1 -1
  317. package/dist/rest/RESTEndpointHandler.js +8 -5
  318. package/dist/rest/RESTEndpointHandler.js.map +1 -1
  319. package/dist/rest/RealtimeRecordingHandler.d.ts +49 -0
  320. package/dist/rest/RealtimeRecordingHandler.d.ts.map +1 -0
  321. package/dist/rest/RealtimeRecordingHandler.js +383 -0
  322. package/dist/rest/RealtimeRecordingHandler.js.map +1 -0
  323. package/dist/rest/ViewOperationsHandler.d.ts +9 -1
  324. package/dist/rest/ViewOperationsHandler.d.ts.map +1 -1
  325. package/dist/rest/ViewOperationsHandler.js +43 -17
  326. package/dist/rest/ViewOperationsHandler.js.map +1 -1
  327. package/dist/rest/setupRESTEndpoints.d.ts +6 -0
  328. package/dist/rest/setupRESTEndpoints.d.ts.map +1 -1
  329. package/dist/rest/setupRESTEndpoints.js +6 -0
  330. package/dist/rest/setupRESTEndpoints.js.map +1 -1
  331. package/dist/serverExtensionReservedRoots.d.ts +12 -10
  332. package/dist/serverExtensionReservedRoots.d.ts.map +1 -1
  333. package/dist/serverExtensionReservedRoots.js +14 -17
  334. package/dist/serverExtensionReservedRoots.js.map +1 -1
  335. package/dist/serverRoleConfigUnits.d.ts +29 -0
  336. package/dist/serverRoleConfigUnits.d.ts.map +1 -0
  337. package/dist/serverRoleConfigUnits.js +33 -0
  338. package/dist/serverRoleConfigUnits.js.map +1 -0
  339. package/dist/services/MJStorageBlobStore.d.ts +8 -1
  340. package/dist/services/MJStorageBlobStore.d.ts.map +1 -1
  341. package/dist/services/MJStorageBlobStore.js +25 -19
  342. package/dist/services/MJStorageBlobStore.js.map +1 -1
  343. package/dist/services/StartTaskGraphDispatcher.js +2 -2
  344. package/dist/services/StartTaskGraphDispatcher.js.map +1 -1
  345. package/dist/services/TaskGraphActionRunner.d.ts +5 -3
  346. package/dist/services/TaskGraphActionRunner.d.ts.map +1 -1
  347. package/dist/services/TaskGraphActionRunner.js +27 -5
  348. package/dist/services/TaskGraphActionRunner.js.map +1 -1
  349. package/dist/services/TaskGraphAgentRunner.d.ts +14 -2
  350. package/dist/services/TaskGraphAgentRunner.d.ts.map +1 -1
  351. package/dist/services/TaskGraphAgentRunner.js +157 -9
  352. package/dist/services/TaskGraphAgentRunner.js.map +1 -1
  353. package/dist/services/TaskGraphContinuationDeliverer.d.ts +59 -2
  354. package/dist/services/TaskGraphContinuationDeliverer.d.ts.map +1 -1
  355. package/dist/services/TaskGraphContinuationDeliverer.js +626 -16
  356. package/dist/services/TaskGraphContinuationDeliverer.js.map +1 -1
  357. package/dist/sharedCache.d.ts.map +1 -1
  358. package/dist/sharedCache.js +3 -0
  359. package/dist/sharedCache.js.map +1 -1
  360. package/dist/types.d.ts +23 -1
  361. package/dist/types.d.ts.map +1 -1
  362. package/dist/types.js.map +1 -1
  363. package/package.json +99 -98
  364. package/src/__tests__/ActionResolver.fieldSecurity.test.ts +237 -0
  365. package/src/__tests__/AdhocQueryResolver.dialect.test.ts +137 -0
  366. package/src/__tests__/AgentRunStatusPublisher.test.ts +49 -0
  367. package/src/__tests__/AgentSessionResolver.ownership.test.ts +137 -0
  368. package/src/__tests__/CustomColumnPromoterOnePass.test.ts +15 -1
  369. package/src/__tests__/DatasetResolver.itemFilters.test.ts +201 -0
  370. package/src/__tests__/EntityCommunicationsResolver.actingUser.test.ts +151 -0
  371. package/src/__tests__/EntityRecordNameResolver.rowSecurity.test.ts +152 -0
  372. package/src/__tests__/EvolutionActsOnWhatItDetects.test.ts +113 -0
  373. package/src/__tests__/FetchEntityVectorsResolver.test.ts +369 -18
  374. package/src/__tests__/FileResolver.fieldSecurity.test.ts +82 -0
  375. package/src/__tests__/FileResolver.storageAccess.test.ts +562 -0
  376. package/src/__tests__/GetDataContextDataResolver.sqlItems.test.ts +416 -0
  377. package/src/__tests__/ListOperationsResolver.adhocScreen.test.ts +137 -0
  378. package/src/__tests__/LoginScreenEngine.test.ts +86 -0
  379. package/src/__tests__/MJStorageBlobStore.storageGate.test.ts +63 -0
  380. package/src/__tests__/PipelineProgressResolver.filter.test.ts +58 -0
  381. package/src/__tests__/QuerySystemUserResolver.fieldSecurity.test.ts +49 -0
  382. package/src/__tests__/RESTEndpointHandler.test.ts +25 -0
  383. package/src/__tests__/RealtimeClientSessionResolver.configTamper.test.ts +23 -3
  384. package/src/__tests__/RealtimeClientSessionResolver.test.ts +324 -46
  385. package/src/__tests__/RecordingAssemblyScheduler.test.ts +178 -0
  386. package/src/__tests__/RemoteBrowserActionResolver.ownership.test.ts +98 -0
  387. package/src/__tests__/ResolverBase.adhocReadScope.test.ts +133 -2
  388. package/src/__tests__/ResolverBase.balancedClause.test.ts +155 -0
  389. package/src/__tests__/ResolverBase.clauseUnscopedRead.test.ts +127 -0
  390. package/src/__tests__/ResolverBase.clientOldValues.test.ts +243 -7
  391. package/src/__tests__/ResolverBase.deleteReturnProjection.test.ts +52 -0
  392. package/src/__tests__/ResolverBase.entityMessageRelay.test.ts +176 -0
  393. package/src/__tests__/ResolverBase.filterEscaping.test.ts +5 -2
  394. package/src/__tests__/ResolverBase.includeBinaryFields.test.ts +23 -1
  395. package/src/__tests__/ResolverBase.publishStatusUpdate.test.ts +68 -0
  396. package/src/__tests__/ResolverBase.userViewCacheAndDedup.test.ts +130 -0
  397. package/src/__tests__/RunAIAgentResolver.branch.test.ts +69 -13
  398. package/src/__tests__/RunAIAgentResolver.conversationWriter.test.ts +210 -0
  399. package/src/__tests__/RunAIAgentResolver.fireAndForgetCompletion.test.ts +209 -0
  400. package/src/__tests__/RunAIAgentResolver.historyFrom.test.ts +20 -28
  401. package/src/__tests__/RunAIAgentResolver.runDataGuard.test.ts +264 -0
  402. package/src/__tests__/RunAIAgentResolver.serverReply.test.ts +358 -0
  403. package/src/__tests__/RunAIAgentResolver.stoppedPredecessor.test.ts +4 -1
  404. package/src/__tests__/RunTemplateResolver.test.ts +35 -2
  405. package/src/__tests__/RunViewResolver.cacheCheckForwarding.test.ts +11 -0
  406. package/src/__tests__/RunViewResolver.cacheCheckScreen.test.ts +165 -0
  407. package/src/__tests__/SearchKnowledgeStreamResolver.test.ts +161 -0
  408. package/src/__tests__/SessionJanitor.test.ts +365 -10
  409. package/src/__tests__/SessionManager.test.ts +122 -0
  410. package/src/__tests__/TaskGraphActionRunner.durablePayload.test.ts +25 -0
  411. package/src/__tests__/TaskGraphAgentRunner.test.ts +266 -0
  412. package/src/__tests__/TaskGraphContinuationDeliverer.test.ts +468 -23
  413. package/src/__tests__/TaskGraphFrameResolver.test.ts +22 -0
  414. package/src/__tests__/TestQuerySQLResolver.test.ts +274 -0
  415. package/src/__tests__/TransactionGroupResolver.fieldSecurity.test.ts +199 -0
  416. package/src/__tests__/TransactionGroupResolver.refusals.test.ts +98 -1
  417. package/src/__tests__/UpdateMJDataContextItem.oldValues.test.ts +220 -0
  418. package/src/__tests__/UserViewResolver.updateWhereClause.test.ts +15 -0
  419. package/src/__tests__/ViewOperationsHandler.clauseScreen.test.ts +157 -0
  420. package/src/__tests__/ViewOperationsHandler.test.ts +7 -2
  421. package/src/__tests__/WidgetSessionService.test.ts +583 -4
  422. package/src/__tests__/agent-run-data-guard.test.ts +130 -0
  423. package/src/__tests__/apiRootBoot.test.ts +202 -0
  424. package/src/__tests__/buildMagicLinkSessionUser.test.ts +96 -0
  425. package/src/__tests__/cacheBroadcastProviders.test.ts +403 -0
  426. package/src/__tests__/cacheInvalidationRecordData.test.ts +109 -0
  427. package/src/__tests__/conversationRunEvents.test.ts +56 -14
  428. package/src/__tests__/fieldSecurityFixtures.ts +91 -0
  429. package/src/__tests__/globalCors.test.ts +217 -0
  430. package/src/__tests__/localDevAuth.test.ts +196 -0
  431. package/src/__tests__/multiTenancy.postgresRewrite.test.ts +181 -0
  432. package/src/__tests__/multiTenancy.security.test.ts +51 -0
  433. package/src/__tests__/multiTenancy.test.ts +1 -1
  434. package/src/__tests__/orphanedConversationDetailReconciler.test.ts +10 -0
  435. package/src/__tests__/ownedRealtimeSession.test.ts +39 -0
  436. package/src/__tests__/pushStatusResolver.filter.test.ts +64 -1
  437. package/src/__tests__/realtimeRecordingHandler.test.ts +669 -0
  438. package/src/__tests__/realtimeSessions/RealtimeSessionEventsResolver.test.ts +29 -1
  439. package/src/__tests__/realtimeSessions/ownedRealtimeSession.anonymous.test.ts +31 -0
  440. package/src/__tests__/realtimeSessions/ownedRealtimeSession.namedScoped.test.ts +37 -0
  441. package/src/__tests__/realtimeSessions/sessionAccess.test.ts +146 -7
  442. package/src/__tests__/realtimeSessions/sessionConfigStamps.test.ts +1 -1
  443. package/src/__tests__/realtimeSessions/verificationWorkflow.test.ts +25 -4
  444. package/src/__tests__/resolverBase.cloudEventChangedFields.test.ts +157 -0
  445. package/src/__tests__/resolverBase.fieldSecurityTransport.test.ts +222 -0
  446. package/src/__tests__/resolverBase.fls.test.ts +146 -97
  447. package/src/__tests__/restTransport.fieldSecurity.test.ts +148 -0
  448. package/src/__tests__/runParamsTimeZone.test.ts +179 -0
  449. package/src/__tests__/runStreams.fieldSecurity.test.ts +100 -0
  450. package/src/__tests__/runViewProperties.test.ts +114 -0
  451. package/src/__tests__/scalabilityBenchmarks.test.ts +765 -0
  452. package/src/__tests__/scalabilityDatabaseIntegration.test.ts +207 -0
  453. package/src/__tests__/serverExtensionHostOverlay.test.ts +66 -0
  454. package/src/__tests__/serverExtensionReservedRoots.test.ts +11 -98
  455. package/src/__tests__/sessionUserClone.test.ts +5 -1
  456. package/src/__tests__/sharedCache.test.ts +5 -3
  457. package/src/__tests__/startupSweepOrder.test.ts +40 -0
  458. package/src/__tests__/unifiedAuth.test.ts +28 -0
  459. package/src/__tests__/widgetGuestElevation.test.ts +2 -0
  460. package/src/agentSessions/SessionJanitor.ts +369 -93
  461. package/src/agentSessions/SessionManager.ts +45 -10
  462. package/src/apiRoot.ts +78 -0
  463. package/src/auth/AuthProviderCatalogRouter.ts +29 -0
  464. package/src/auth/LoginScreenEngine.ts +50 -0
  465. package/src/auth/index.ts +57 -12
  466. package/src/auth/initializeProviders.ts +43 -1
  467. package/src/auth/localDevAuth.ts +528 -0
  468. package/src/auth/magicLink/MagicLinkKeys.ts +2 -2
  469. package/src/auth/magicLink/MagicLinkRouter.ts +3 -2
  470. package/src/auth/magicLink/types.ts +10 -0
  471. package/src/auth/sessionUserClone.ts +3 -2
  472. package/src/broadcast/BaseCacheInvalidationBroadcastProvider.ts +674 -0
  473. package/src/broadcast/index.ts +5 -0
  474. package/src/broadcast/providers/AWSIoTCoreBroadcastProvider.ts +180 -0
  475. package/src/broadcast/providers/AzureWebPubSubBroadcastProvider.ts +182 -0
  476. package/src/broadcast/providers/GCPPubSubBroadcastProvider.ts +169 -0
  477. package/src/broadcast/providers/SequencedRoleBucketBroadcastProvider.ts +57 -0
  478. package/src/cache.ts +2 -1
  479. package/src/config.ts +115 -5
  480. package/src/context.ts +32 -8
  481. package/src/coreRoutes.ts +181 -0
  482. package/src/generated/graphql-schemas/__mj.ts +3684 -284
  483. package/src/generic/CacheInvalidationResolver.ts +172 -60
  484. package/src/generic/OrphanedConversationDetailReconciler.ts +4 -2
  485. package/src/generic/PubSubManager.ts +54 -1
  486. package/src/generic/PushStatusResolver.ts +109 -12
  487. package/src/generic/ResolverBase.ts +540 -431
  488. package/src/generic/RunViewResolver.ts +97 -15
  489. package/src/generic/actionOutputFieldSecurity.ts +75 -0
  490. package/src/generic/fieldSecurityTransport.ts +62 -0
  491. package/src/globalCors.ts +71 -0
  492. package/src/index.ts +239 -238
  493. package/src/integration/CustomColumnPromoter.ts +6 -1
  494. package/src/logging/variablesLoggingMiddleware.ts +59 -3
  495. package/src/multiTenancy/index.ts +24 -2
  496. package/src/realtimeSessions/README.md +7 -3
  497. package/src/realtimeSessions/RealtimeSessionVerificationService.ts +2 -1
  498. package/src/realtimeSessions/RealtimeVerifyRouter.ts +2 -1
  499. package/src/realtimeSessions/RecordingAssemblyScheduler.ts +234 -0
  500. package/src/realtimeSessions/SessionVerificationPortsBase.ts +1 -0
  501. package/src/realtimeSessions/index.ts +2 -0
  502. package/src/realtimeSessions/ownedRealtimeSession.ts +69 -0
  503. package/src/realtimeSessions/sessionAccess.ts +183 -23
  504. package/src/realtimeSessions/sessionConfigStamps.ts +1 -1
  505. package/src/realtimeSessions/subscriptionAuthorization.ts +4 -2
  506. package/src/realtimeSessions/verificationWorkflow.ts +3 -1
  507. package/src/realtimeWidget/WidgetRouter.ts +22 -4
  508. package/src/realtimeWidget/WidgetSessionService.ts +252 -17
  509. package/src/realtimeWidget/host-identity.ts +1 -1
  510. package/src/realtimeWidget/widgetCore.ts +30 -1
  511. package/src/realtimeWidget/widgetGuestElevation.ts +2 -1
  512. package/src/resolvers/ActionResolver.ts +78 -15
  513. package/src/resolvers/AdhocQueryResolver.ts +1 -0
  514. package/src/resolvers/AgentRunStatusPublisher.ts +36 -8
  515. package/src/resolvers/AgentSessionResolver.ts +46 -18
  516. package/src/resolvers/ArtifactFileResolver.ts +9 -8
  517. package/src/resolvers/ConversationRunEventsResolver.ts +15 -11
  518. package/src/resolvers/DatasetResolver.ts +70 -10
  519. package/src/resolvers/EntityCommunicationsResolver.ts +56 -15
  520. package/src/resolvers/EntityRecordNameResolver.ts +3 -2
  521. package/src/resolvers/FetchEntityVectorsResolver.ts +248 -55
  522. package/src/resolvers/FileCategoryResolver.ts +1 -0
  523. package/src/resolvers/FileResolver.ts +334 -109
  524. package/src/resolvers/GetDataContextDataResolver.ts +139 -41
  525. package/src/resolvers/GetDataResolver.ts +6 -3
  526. package/src/resolvers/IntegrationDiscoveryResolver.ts +53 -9
  527. package/src/resolvers/MergeRecordsResolver.ts +23 -2
  528. package/src/resolvers/PipelineProgressResolver.ts +12 -3
  529. package/src/resolvers/QueryResolver.ts +31 -6
  530. package/src/resolvers/QuerySystemUserResolver.ts +15 -6
  531. package/src/resolvers/RSUResolver.ts +12 -0
  532. package/src/resolvers/RealtimeClientSessionResolver.ts +114 -66
  533. package/src/resolvers/RemoteBrowserActionResolver.ts +15 -10
  534. package/src/resolvers/RunAIAgentResolver.ts +296 -85
  535. package/src/resolvers/RunTemplateResolver.ts +6 -4
  536. package/src/resolvers/RunTestResolver.ts +3 -1
  537. package/src/resolvers/SearchKnowledgeStreamResolver.ts +19 -3
  538. package/src/resolvers/SqlLoggingConfigResolver.ts +2 -4
  539. package/src/resolvers/SyncDataResolver.ts +4 -0
  540. package/src/resolvers/TaskGraphFrameResolver.ts +33 -1
  541. package/src/resolvers/TestQuerySQLResolver.ts +69 -13
  542. package/src/resolvers/TransactionGroupResolver.ts +185 -30
  543. package/src/resolvers/UserViewResolver.ts +2 -1
  544. package/src/resolvers/__tests__/GetDataResolver.validation.test.ts +95 -0
  545. package/src/resolvers/__tests__/MergeRecordsResolver.test.ts +43 -0
  546. package/src/resolvers/agent-run-data-guard.ts +89 -0
  547. package/src/rest/EntityCRUDHandler.ts +22 -5
  548. package/src/rest/RESTEndpointHandler.ts +8 -5
  549. package/src/rest/RealtimeRecordingHandler.ts +467 -0
  550. package/src/rest/ViewOperationsHandler.ts +52 -18
  551. package/src/rest/setupRESTEndpoints.ts +6 -0
  552. package/src/serverExtensionReservedRoots.ts +14 -17
  553. package/src/serverRoleConfigUnits.ts +48 -0
  554. package/src/services/MJStorageBlobStore.ts +31 -30
  555. package/src/services/StartTaskGraphDispatcher.ts +2 -2
  556. package/src/services/TaskGraphActionRunner.ts +25 -5
  557. package/src/services/TaskGraphAgentRunner.ts +188 -11
  558. package/src/services/TaskGraphContinuationDeliverer.ts +738 -16
  559. package/src/sharedCache.ts +3 -0
  560. package/src/types.ts +23 -1
@@ -14,8 +14,10 @@ import type {
14
14
  AgentExecutionStreamingCallback,
15
15
  ExecuteAgentResult,
16
16
  } from '@memberjunction/ai-core-plus';
17
+ import type { EntityInfo } from '@memberjunction/core';
17
18
  import type { UserPayload } from '../types.js';
18
- import { PublishStatusUpdate } from '../generic/PushStatusResolver.js';
19
+ import { PublishStatusUpdate, StatusUpdateOwnerID } from '../generic/PushStatusResolver.js';
20
+ import { ProjectEntityObjectForCaller } from '../generic/fieldSecurityTransport.js';
19
21
 
20
22
  const SIGNIFICANT_STEPS = ['prompt_execution', 'action_execution', 'subagent_execution', 'decision_processing'];
21
23
 
@@ -25,7 +27,8 @@ interface StatusRun {
25
27
  ConversationDetailID?: string;
26
28
  ErrorMessage?: string;
27
29
  Steps?: Array<{ StepName?: string }>;
28
- GetAll?: () => unknown;
30
+ EntityInfo?: EntityInfo | null;
31
+ GetAll?: () => Record<string, unknown>;
29
32
  }
30
33
 
31
34
  export class AgentRunStatusPublisher {
@@ -34,11 +37,15 @@ export class AgentRunStatusPublisher {
34
37
  /**
35
38
  * @param sessionId Session stamped on the message body. Defaults to the payload's session.
36
39
  * The push itself is always addressed to `userPayload.sessionId`, matching the resolver.
40
+ * @param conversationDetailId The run's reply row. When set, every message carries it as
41
+ * `conversationDetailId`, not only the completion, so a client that reconnects mid-run can
42
+ * find its row. When omitted, messages are as before.
37
43
  */
38
44
  constructor(
39
45
  private readonly pubSub: PubSubEngine,
40
46
  private readonly userPayload: UserPayload,
41
47
  private readonly sessionId: string = userPayload.sessionId,
48
+ private readonly conversationDetailId?: string,
42
49
  ) {}
43
50
 
44
51
  /** Latest run observed from a progress event, including steps that are not published. */
@@ -66,7 +73,8 @@ export class AgentRunStatusPublisher {
66
73
  sessionId: this.sessionId,
67
74
  agentRunId: agentRun.ID,
68
75
  type: 'progress',
69
- agentRun: agentRun.GetAll ? agentRun.GetAll() : agentRun,
76
+ ...this.replyRow(),
77
+ agentRun: this.runValues(agentRun),
70
78
  progress: {
71
79
  currentStep: progress.step,
72
80
  percentage: progress.percentage,
@@ -93,7 +101,8 @@ export class AgentRunStatusPublisher {
93
101
  sessionId: this.sessionId,
94
102
  agentRunId: agentRun.ID,
95
103
  type: 'streaming',
96
- agentRun: agentRun.GetAll ? agentRun.GetAll() : agentRun,
104
+ ...this.replyRow(),
105
+ agentRun: this.runValues(agentRun),
97
106
  streaming: {
98
107
  content: chunk.content,
99
108
  isPartial: !chunk.isComplete,
@@ -122,6 +131,7 @@ export class AgentRunStatusPublisher {
122
131
  sessionId: this.sessionId,
123
132
  agentRunId: agentRun.ID,
124
133
  type: 'partial_result',
134
+ ...this.replyRow(),
125
135
  partialResult: {
126
136
  currentStep: lastStep,
127
137
  partialOutput: result.payload || undefined,
@@ -134,7 +144,7 @@ export class AgentRunStatusPublisher {
134
144
  agentRunId: agentRun?.ID || 'unknown',
135
145
  type: 'complete',
136
146
  timestamp: new Date(),
137
- conversationDetailId: conversationDetailId || agentRun?.ConversationDetailID,
147
+ conversationDetailId: conversationDetailId || agentRun?.ConversationDetailID || this.conversationDetailId,
138
148
  success: result.success,
139
149
  errorMessage: agentRun?.ErrorMessage || undefined,
140
150
  result: resultJson || undefined,
@@ -142,8 +152,9 @@ export class AgentRunStatusPublisher {
142
152
  }
143
153
 
144
154
  /**
145
- * Completion for a failure that has no run. The fire-and-forget path uses this when
146
- * `executeAIAgent` rejects. A host uses it the same way: when the turn throws
155
+ * Completion for a failure that has no run result. `executeAIAgent` sends it when the run
156
+ * throws (the agent could not start, the run failed, or its reply could not be saved), so a
157
+ * fire-and-forget client learns the reason. A host uses it the same way: when the turn throws
147
158
  * instead of returning a result, call `PublishFailure` with the reply row's id
148
159
  * and the error. That completion is what tells the chat the reply finished.
149
160
  */
@@ -160,10 +171,27 @@ export class AgentRunStatusPublisher {
160
171
  });
161
172
  }
162
173
 
174
+ /** `{ conversationDetailId }` when this run has a reply row, otherwise nothing, so the message keeps its old shape. */
175
+ private replyRow(): { conversationDetailId?: string } {
176
+ return this.conversationDetailId ? { conversationDetailId: this.conversationDetailId } : {};
177
+ }
178
+
179
+ /**
180
+ * The run's field values as the recipient may read them. The run object comes from the agent
181
+ * engine, which is not bound to this session's user, so it is projected here.
182
+ */
183
+ private runValues(agentRun: StatusRun): unknown {
184
+ if (!agentRun.GetAll) {
185
+ return agentRun;
186
+ }
187
+ const getAll = agentRun.GetAll;
188
+ return ProjectEntityObjectForCaller({ EntityInfo: agentRun.EntityInfo, GetAll: () => getAll.call(agentRun) }, this.userPayload?.userRecord);
189
+ }
190
+
163
191
  private publish(type: 'ExecutionProgress' | 'StreamingContent', data: unknown): void {
164
192
  PublishStatusUpdate(this.pubSub, {
165
193
  sessionId: this.userPayload.sessionId,
166
- ownerUserId: this.userPayload?.userRecord?.ID ?? '',
194
+ ownerUserId: StatusUpdateOwnerID(this.userPayload),
167
195
  message: JSON.stringify({
168
196
  resolver: 'RunAIAgentResolver',
169
197
  type,
@@ -13,12 +13,30 @@
13
13
  */
14
14
  import { Resolver, Mutation, Arg, Ctx, ObjectType, Field } from 'type-graphql';
15
15
  import { AppContext } from '../types.js';
16
- import { UserInfo, IMetadataProvider, LogError } from '@memberjunction/core';
17
- import { UUIDsEqual } from '@memberjunction/global';
18
- import { MJAIAgentSessionEntity } from '@memberjunction/core-entities';
16
+ import { UserInfo, IMetadataProvider } from '@memberjunction/core';
19
17
  import { ResolverBase } from '../generic/ResolverBase.js';
20
18
  import { GetReadWriteProvider } from '../util.js';
21
- import { SessionManager, SessionAuthorizationError } from '../agentSessions/index.js';
19
+ import { SessionManager, SessionAuthorizationError, type SessionCloseReason } from '../agentSessions/index.js';
20
+ import {
21
+ LoadOwnedRealtimeSession,
22
+ RealtimeSessionNotFoundError,
23
+ RealtimeSessionOwnershipError,
24
+ } from '../realtimeSessions/ownedRealtimeSession.js';
25
+
26
+ /** The `CloseReason` values a client may stamp on its own session; `Janitor` and `Shutdown` are the server's. */
27
+ const CLIENT_CLOSE_REASONS: readonly SessionCloseReason[] = ['Explicit', 'Error'];
28
+
29
+ /** Reads the mutation's optional `closeReason`: absent means `Explicit`; a server-only or unknown value is refused. */
30
+ function ParseClientCloseReason(closeReason: string | null | undefined): SessionCloseReason {
31
+ if (closeReason == null || closeReason === '') {
32
+ return 'Explicit';
33
+ }
34
+ const match = CLIENT_CLOSE_REASONS.find((r) => r === closeReason);
35
+ if (!match) {
36
+ throw new Error(`Unsupported close reason '${closeReason}': a client may close its session as ${CLIENT_CLOSE_REASONS.join(' or ')}`);
37
+ }
38
+ return match;
39
+ }
22
40
 
23
41
  /** Result of {@link AgentSessionResolver.StartAgentSession}. */
24
42
  @ObjectType()
@@ -77,15 +95,22 @@ export class AgentSessionResolver extends ResolverBase {
77
95
  /**
78
96
  * Close a session. Rejects unless the caller owns it. Returns `true` on a successful (or
79
97
  * idempotent) close, `false` if the session can't be loaded.
98
+ *
99
+ * `closeReason` is what the row records as its `CloseReason`: `Explicit` (the default, and what
100
+ * every client sent before the argument existed) when the user or host ended the call, `Error`
101
+ * when the client ended it because the start or the call failed (MJ#6013). The other reasons are
102
+ * the server's own (janitor, shutdown) and are refused from a client.
80
103
  */
81
104
  @Mutation(() => Boolean)
82
105
  async CloseAgentSession(
83
106
  @Arg('agentSessionId') agentSessionId: string,
84
107
  @Ctx() { userPayload, providers }: AppContext,
108
+ @Arg('closeReason', () => String, { nullable: true }) closeReason?: string | null,
85
109
  ): Promise<boolean> {
110
+ const reason = ParseClientCloseReason(closeReason);
86
111
  const { contextUser, provider } = this.requireUserAndProvider(userPayload, providers);
87
- await this.assertOwnership(agentSessionId, contextUser, provider);
88
- return this.sessionManager.CloseSession(agentSessionId, contextUser, provider);
112
+ await this.loadOwnedSession(agentSessionId, contextUser, provider);
113
+ return this.sessionManager.CloseSession(agentSessionId, contextUser, provider, reason);
89
114
  }
90
115
 
91
116
  /**
@@ -98,7 +123,7 @@ export class AgentSessionResolver extends ResolverBase {
98
123
  @Ctx() { userPayload, providers }: AppContext,
99
124
  ): Promise<boolean> {
100
125
  const { contextUser, provider } = this.requireUserAndProvider(userPayload, providers);
101
- await this.assertOwnership(agentSessionId, contextUser, provider);
126
+ await this.loadOwnedSession(agentSessionId, contextUser, provider);
102
127
  return this.sessionManager.Heartbeat(agentSessionId, contextUser, provider);
103
128
  }
104
129
 
@@ -117,22 +142,25 @@ export class AgentSessionResolver extends ResolverBase {
117
142
  }
118
143
 
119
144
  /**
120
- * Inbound ownership gate (the one genuinely new session-authz primitive): the session's `UserID`
121
- * must equal the caller's. Throws on mismatch or when the session can't be loaded.
145
+ * Inbound ownership gate: delegates to {@link LoadOwnedRealtimeSession} (which enforces both
146
+ * `UserID === contextUser.ID` and `AuthorizeSessionAccess` scope/visitor binding) and maps its
147
+ * typed errors to this resolver's message format.
122
148
  */
123
- private async assertOwnership(
149
+ private async loadOwnedSession(
124
150
  agentSessionId: string,
125
151
  contextUser: UserInfo,
126
152
  provider: IMetadataProvider,
127
153
  ): Promise<void> {
128
- const session = await provider.GetEntityObject<MJAIAgentSessionEntity>('MJ: AI Agent Sessions', contextUser);
129
- const loaded = await session.Load(agentSessionId);
130
- if (!loaded) {
131
- throw new Error(`Agent session ${agentSessionId} not found`);
132
- }
133
- if (!UUIDsEqual(session.UserID, contextUser.ID)) {
134
- LogError(`AgentSessionResolver: ownership check failed — user ${contextUser.ID} attempted to operate on session ${agentSessionId} owned by ${session.UserID}`);
135
- throw new Error('Not authorized: you do not own this agent session');
154
+ try {
155
+ await LoadOwnedRealtimeSession(agentSessionId, contextUser, provider);
156
+ } catch (err) {
157
+ if (err instanceof RealtimeSessionNotFoundError) {
158
+ throw new Error(`Agent session ${agentSessionId} not found`);
159
+ }
160
+ if (err instanceof RealtimeSessionOwnershipError) {
161
+ throw new Error('Not authorized: you do not own this agent session');
162
+ }
163
+ throw err;
136
164
  }
137
165
  }
138
166
  }
@@ -46,7 +46,11 @@ export class ArtifactFileResolver extends ResolverBase {
46
46
  return this.buildDownloadUrl(artifactVersion.FileID, user, p);
47
47
  }
48
48
 
49
- /** Load the File + its storage account/provider and generate a signed URL. */
49
+ /**
50
+ * Load the File (as the caller) and generate a signed URL — after the storage gate: the caller must be able to read
51
+ * the account the file's provider resolves to and every `MJ: Files` row that tracks its object
52
+ * (`FileStorageEngine.ResolveFileObject`), so an artifact cannot sign an object in an account the caller is refused.
53
+ */
50
54
  private async buildDownloadUrl(
51
55
  fileId: string,
52
56
  user: ReturnType<ResolverBase['GetUserFromPayload']>,
@@ -58,14 +62,11 @@ export class ArtifactFileResolver extends ResolverBase {
58
62
  throw new Error(`File record ${fileId} not found`);
59
63
  }
60
64
 
61
- // Find the storage account for this file's provider using cached metadata
62
- await FileStorageEngine.Instance.Config(false, user!);
63
- const matchingAccounts = FileStorageEngine.Instance.GetAccountsByProviderID(fileEntity.ProviderID);
64
- if (matchingAccounts.length === 0) {
65
+ // Resolve the storage account for this file's provider, gated for the caller (throws on refusal)
66
+ const resolved = await FileStorageEngine.Instance.ResolveFileObject(fileEntity, user!, 'Read', provider);
67
+ if (!resolved) {
65
68
  throw new Error(`No FileStorageAccount found for ProviderID ${fileEntity.ProviderID}. Cannot generate download URL.`);
66
69
  }
67
-
68
- const driver = await FileStorageEngine.Instance.GetDriver(matchingAccounts[0].ID, user!);
69
- return driver.CreatePreAuthDownloadUrl(fileEntity.ProviderKey ?? fileEntity.Name);
70
+ return resolved.Driver.CreatePreAuthDownloadUrl(resolved.ObjectKey);
70
71
  }
71
72
  }
@@ -7,7 +7,7 @@ import type { AppContext } from '../types.js';
7
7
  import { GetReadOnlyProvider } from '../util.js';
8
8
 
9
9
  /** The run columns the tail reads. */
10
- type TailRunRow = Pick<MJAIAgentRunEntity, 'ID' | 'Status' | 'Result'>;
10
+ type TailRunRow = Pick<MJAIAgentRunEntity, 'ID' | 'Status' | 'FinalPayload' | 'Result'>;
11
11
 
12
12
  /** The step columns an event carries. The large data columns are never read. */
13
13
  type TailStepRow = Pick<
@@ -15,7 +15,7 @@ type TailStepRow = Pick<
15
15
  'StepNumber' | 'StepType' | 'StepName' | 'Status' | 'Success' | 'ErrorMessage' | 'StartedAt' | 'CompletedAt'
16
16
  >;
17
17
 
18
- const RUN_FIELDS: (keyof TailRunRow)[] = ['ID', 'Status', 'Result'];
18
+ const RUN_FIELDS: (keyof TailRunRow)[] = ['ID', 'Status', 'FinalPayload', 'Result'];
19
19
  const STEP_FIELDS: (keyof TailStepRow)[] = [
20
20
  'StepNumber', 'StepType', 'StepName', 'Status', 'Success', 'ErrorMessage', 'StartedAt', 'CompletedAt',
21
21
  ];
@@ -94,10 +94,14 @@ export class ConversationRunEventsOutput {
94
94
  /**
95
95
  * The run's answer, returned only once the run is terminal.
96
96
  *
97
- * Sourced from `AIAgentRun.Result`, falling back to the conversation detail's message because
98
- * `Result` is agent-dependent and null on many successful runs. Still nullable: a caller must
99
- * decide a message is finished from {@link IsInFlight} / {@link DetailStatus}, never from the
100
- * presence of this field, or it will wait forever on an agent that writes neither.
97
+ * Sourced from `AIAgentRun.FinalPayload` (`Result` on older rows), then the conversation detail's
98
+ * message, because the run payload is agent-dependent and null on many successful runs. Still
99
+ * nullable: a caller must decide a message is finished from {@link IsInFlight} /
100
+ * {@link DetailStatus}, never from the presence of this field, or it will wait forever on an
101
+ * agent that writes neither.
102
+ *
103
+ * A run that ended without completing (for example `Cancelled`) returns whatever `FinalPayload`
104
+ * it had saved, which can be partial, so a caller should check {@link RunStatus} first.
101
105
  */
102
106
  @Field(() => String, { nullable: true })
103
107
  FinalPayload?: string;
@@ -206,11 +210,11 @@ export class ConversationRunEventsResolver {
206
210
  // Only meaningful once terminal; sending it mid-run would hand the client a
207
211
  // partial payload it could mistake for the final answer.
208
212
  //
209
- // `AIAgentRun.Result` is agent-dependent — it is null on a large share of
210
- // genuinely successful runs — so the conversation detail's own message is the
211
- // fallback. That is the text the chat renders, so it is the answer a caller
212
- // waiting on this field actually wants.
213
- FinalPayload: isInFlight ? undefined : (run.Result ?? detail.Message ?? undefined),
213
+ // `AIAgentRun.FinalPayload` (`Result` on older rows) is agent-dependent — it is
214
+ // null on a large share of genuinely successful runs — so the conversation detail's
215
+ // own message is the fallback. That is the text the chat renders, so it is the
216
+ // answer a caller waiting on this field actually wants.
217
+ FinalPayload: isInFlight ? undefined : (run.FinalPayload ?? run.Result ?? detail.Message ?? undefined),
214
218
  DetailStatus: detail.Status ?? undefined,
215
219
  };
216
220
  } catch (e) {
@@ -1,6 +1,6 @@
1
1
  import { Arg, Ctx, Field, InputType, Int, ObjectType, Query, Resolver } from 'type-graphql';
2
- import { AppContext } from '../types.js';
3
- import { LogError, Metadata } from '@memberjunction/core';
2
+ import { AppContext, UserPayload } from '../types.js';
3
+ import { DatabaseProviderBase, DatasetItemFilterType, DatasetItemResultType, LogError, Metadata, UserInfo } from '@memberjunction/core';
4
4
  import { GetReadOnlyProvider } from '../util.js';
5
5
  import { ResolverBase } from '../generic/ResolverBase.js';
6
6
 
@@ -34,9 +34,64 @@ export class DatasetItemFilterTypeGQL {
34
34
  Filter: string;
35
35
  }
36
36
 
37
+ /**
38
+ * Request handling shared by the dataset queries. Every read runs as the session's user, so the
39
+ * provider applies that user's entity read permission and row-level security per item, and every
40
+ * client ItemFilter passes the same AST screen as a RunView ExtraFilter before a provider sees it.
41
+ */
42
+ export abstract class DatasetResolverBase extends ResolverBase {
43
+ /** The session's user. A dataset read never runs without one: the provider applies no read checks then. */
44
+ protected RequireDatasetUser(userPayload: UserPayload): UserInfo {
45
+ const user = this.GetUserFromPayload(userPayload);
46
+ if (!user) {
47
+ throw new Error('Dataset request refused: the session resolves to no user');
48
+ }
49
+ return user;
50
+ }
51
+
52
+ /**
53
+ * Screens every client ItemFilter: one statement, read-only, and subqueries only over entity base
54
+ * views the user can read. Throws on the first refusal. Returns the filters without null entries.
55
+ */
56
+ protected ScreenItemFilters(
57
+ itemFilters: DatasetItemFilterTypeGQL[] | undefined,
58
+ provider: DatabaseProviderBase,
59
+ user: UserInfo,
60
+ ): DatasetItemFilterType[] | undefined {
61
+ if (!itemFilters) return undefined;
62
+ itemFilters.forEach((itemFilter, index) => {
63
+ if (itemFilter) {
64
+ this.assertClientClauseUsesEntityBaseViews(itemFilter.Filter, `ItemFilters[${index}].Filter`, provider, user);
65
+ }
66
+ });
67
+ return itemFilters.filter((itemFilter) => itemFilter != null);
68
+ }
69
+
70
+ /**
71
+ * Applies the API encryption policy to each item's rows, as every other GraphQL read path does:
72
+ * an encrypted field the entity does not allow decrypted over the API leaves as ciphertext or the
73
+ * sentinel. Works on copies, because the rows can be the server cache's own frozen objects.
74
+ */
75
+ protected async ProtectEncryptedFields(
76
+ items: DatasetItemResultType[],
77
+ provider: DatabaseProviderBase,
78
+ user: UserInfo,
79
+ ): Promise<DatasetItemResultType[]> {
80
+ return Promise.all(
81
+ items.map(async (item) => {
82
+ const entity = provider.EntityByName(item.EntityName);
83
+ if (!item.Results?.length || !entity?.EncryptedFields.some((field) => !field.AllowDecryptInAPI)) {
84
+ return item;
85
+ }
86
+ const rows = item.Results.map((row: Record<string, unknown>) => ({ ...row }));
87
+ return { ...item, Results: await this.ArrayFilterEncryptedFieldsForAPI(item.EntityName, rows, user, provider, 'Name') };
88
+ }),
89
+ );
90
+ }
91
+ }
37
92
 
38
93
  @Resolver(DatasetResultType)
39
- export class DatasetResolverExtended extends ResolverBase {
94
+ export class DatasetResolverExtended extends DatasetResolverBase {
40
95
  @Query(() => DatasetResultType)
41
96
  async GetDatasetByName(
42
97
  @Arg('DatasetName', () => String) DatasetName: string,
@@ -45,10 +100,12 @@ export class DatasetResolverExtended extends ResolverBase {
45
100
  ) {
46
101
  // Check API key scope authorization for dataset read
47
102
  await this.CheckAPIKeyScopeAuthorization('dataset:read', DatasetName, userPayload);
103
+ const md = GetReadOnlyProvider(providers, {allowFallbackToReadWrite: true});
104
+ const user = this.RequireDatasetUser(userPayload);
105
+ const itemFilters = this.ScreenItemFilters(ItemFilters, md, user);
48
106
 
49
107
  try {
50
- const md = GetReadOnlyProvider(providers, {allowFallbackToReadWrite: true});
51
- const result = await md.GetDatasetByName(DatasetName, ItemFilters);
108
+ const result = await md.GetDatasetByName(DatasetName, itemFilters, user);
52
109
  if (result) {
53
110
  return {
54
111
  DatasetID: result.DatasetID,
@@ -56,7 +113,7 @@ export class DatasetResolverExtended extends ResolverBase {
56
113
  Success: result.Success,
57
114
  Status: result.Status,
58
115
  LatestUpdateDate: result.LatestUpdateDate,
59
- Results: JSON.stringify(result.Results),
116
+ Results: JSON.stringify(await this.ProtectEncryptedFields(result.Results, md, user)),
60
117
  };
61
118
  } else {
62
119
  throw new Error('Error retrieving Dataset: ' + DatasetName);
@@ -90,7 +147,7 @@ export class DatasetStatusResultType {
90
147
  }
91
148
 
92
149
  @Resolver(DatasetStatusResultType)
93
- export class DatasetStatusResolver extends ResolverBase {
150
+ export class DatasetStatusResolver extends DatasetResolverBase {
94
151
  @Query(() => DatasetStatusResultType)
95
152
  async GetDatasetStatusByName(
96
153
  @Arg('DatasetName', () => String) DatasetName: string,
@@ -99,10 +156,12 @@ export class DatasetStatusResolver extends ResolverBase {
99
156
  ) {
100
157
  // Check API key scope authorization for dataset read
101
158
  await this.CheckAPIKeyScopeAuthorization('dataset:read', DatasetName, userPayload);
159
+ const md = GetReadOnlyProvider(providers, {allowFallbackToReadWrite: true});
160
+ const user = this.RequireDatasetUser(userPayload);
161
+ const itemFilters = this.ScreenItemFilters(ItemFilters, md, user);
102
162
 
103
163
  try {
104
- const md = GetReadOnlyProvider(providers, {allowFallbackToReadWrite: true});
105
- const result = await md.GetDatasetStatusByName(DatasetName, ItemFilters);
164
+ const result = await md.GetDatasetStatusByName(DatasetName, itemFilters, user);
106
165
  if (result) {
107
166
  return {
108
167
  DatasetID: result.DatasetID,
@@ -131,12 +190,13 @@ export class DatasetStatusResolver extends ResolverBase {
131
190
  @Ctx() { providers, userPayload }: AppContext,
132
191
  ): Promise<DatasetStatusResultType[]> {
133
192
  const md = GetReadOnlyProvider(providers, {allowFallbackToReadWrite: true});
193
+ const user = this.RequireDatasetUser(userPayload);
134
194
  const results: DatasetStatusResultType[] = [];
135
195
 
136
196
  // Execute all status checks in parallel
137
197
  const statusPromises = DatasetNames.map(async (name) => {
138
198
  await this.CheckAPIKeyScopeAuthorization('dataset:read', name, userPayload);
139
- return md.GetDatasetStatusByName(name);
199
+ return md.GetDatasetStatusByName(name, undefined, user);
140
200
  });
141
201
 
142
202
  const statuses = await Promise.all(statusPromises);
@@ -3,12 +3,14 @@ import { AppContext } from '../types.js';
3
3
  import { RunViewByIDInput } from '../generic/RunViewResolver.js';
4
4
  import { Message } from '@memberjunction/communication-types';
5
5
  import { EntityCommunicationsEngine } from '@memberjunction/entity-communications-server';
6
- import { RunViewParams } from '@memberjunction/core';
6
+ import { DatabaseProviderBase, IMetadataProvider, RunViewParams, UserInfo } from '@memberjunction/core';
7
+ import { UUIDsEqual } from '@memberjunction/global';
7
8
  import { GraphQLJSONObject } from 'graphql-type-json';
8
9
  import { TemplateEngineServer } from '@memberjunction/templates';
9
10
  import { EntityCommunicationParams } from '@memberjunction/entity-communications-base';
10
11
  import { z } from 'zod';
11
12
  import { ResolverBase } from '../generic/ResolverBase.js';
13
+ import { GetReadOnlyProvider } from '../util.js';
12
14
 
13
15
  @InputType()
14
16
  export class CommunicationProviderMessageType {
@@ -168,6 +170,11 @@ export class RunEntityCommunicationResultType {
168
170
 
169
171
  @Resolver(RunEntityCommunicationResultType)
170
172
  export class ReportResolver extends ResolverBase {
173
+ /**
174
+ * Runs a message against a view of records, as the caller. The recipient and related-entity reads
175
+ * run as the authenticated user, so a preview returns and a send merges only rows and fields that
176
+ * user may read. The view's client-supplied clauses get the same screen as a RunView request.
177
+ */
171
178
  @Query(() => RunEntityCommunicationResultType)
172
179
  async RunEntityCommunicationByViewID(
173
180
  @Arg('entityID', () => String) entityID: string,
@@ -177,25 +184,29 @@ export class ReportResolver extends ResolverBase {
177
184
  @Arg('message', () => CommunicationMessageInput) message: CommunicationMessageInput,
178
185
  @Arg('previewOnly', () => Boolean) previewOnly: boolean,
179
186
  @Arg('includeProcessedMessages', () => Boolean) includeProcessedMessages: boolean,
180
- @Ctx() { userPayload }: AppContext
187
+ @Ctx() { userPayload, providers }: AppContext
181
188
  ): Promise<RunEntityCommunicationResultType> {
182
189
  // Check API key scope authorization for communication send
183
190
  await this.CheckAPIKeyScopeAuthorization('communication:send', entityID, userPayload);
184
191
 
185
192
  try {
186
- await EntityCommunicationsEngine.Instance.Config(false, userPayload.userRecord);
187
- const newMessage = new Message(message as unknown as Message);
188
- await TemplateEngineServer.Instance.Config(false, userPayload.userRecord);
189
- // for the templates, replace the values from the input with the objects from the Template Engine we have here
190
- if (newMessage.BodyTemplate) {
191
- newMessage.BodyTemplate = TemplateEngineServer.Instance.FindTemplate(newMessage.BodyTemplate.Name);
192
- }
193
- if (newMessage.HTMLBodyTemplate) {
194
- newMessage.HTMLBodyTemplate = TemplateEngineServer.Instance.FindTemplate(newMessage.HTMLBodyTemplate.Name);
195
- }
196
- if (newMessage.SubjectTemplate) {
197
- newMessage.SubjectTemplate = TemplateEngineServer.Instance.FindTemplate(newMessage.SubjectTemplate.Name);
198
- }
193
+ const contextUser = this.GetUserFromPayload(userPayload);
194
+ if (!contextUser) throw new Error('Unable to determine the acting user for this communication');
195
+ const provider = GetReadOnlyProvider(providers, { allowFallbackToReadWrite: true });
196
+ this.screenClientViewClauses(
197
+ {
198
+ extraFilter: runViewByIDInput.ExtraFilter,
199
+ orderBy: runViewByIDInput.OrderBy,
200
+ userSearchString: runViewByIDInput.UserSearchString,
201
+ overrideExcludeFilter: runViewByIDInput.OverrideExcludeFilter,
202
+ },
203
+ provider as unknown as IMetadataProvider,
204
+ contextUser,
205
+ );
206
+ await this.assertViewBelongsToEntity(runViewByIDInput.ViewID, entityID, provider, contextUser);
207
+
208
+ await EntityCommunicationsEngine.Instance.Config(false, contextUser);
209
+ const newMessage = await this.resolveMessageTemplates(message, contextUser);
199
210
  const params: EntityCommunicationParams = {
200
211
  EntityID: entityID,
201
212
  RunViewParams: <RunViewParams>runViewByIDInput,
@@ -204,6 +215,8 @@ export class ReportResolver extends ResolverBase {
204
215
  Message: newMessage,
205
216
  PreviewOnly: previewOnly,
206
217
  IncludeProcessedMessages: includeProcessedMessages,
218
+ ContextUser: contextUser,
219
+ Provider: provider,
207
220
  };
208
221
  const result = await EntityCommunicationsEngine.Instance.RunEntityCommunication(params);
209
222
  return {
@@ -222,4 +235,32 @@ export class ReportResolver extends ResolverBase {
222
235
  };
223
236
  }
224
237
  }
238
+
239
+ /**
240
+ * Refuses a view that is not a view of `entityID`, with the same message as for a view that does
241
+ * not exist or that the caller cannot load, so the refusal does not reveal which views exist.
242
+ */
243
+ private async assertViewBelongsToEntity(viewID: string | undefined, entityID: string, provider: DatabaseProviderBase, contextUser: UserInfo): Promise<void> {
244
+ if (!viewID) return;
245
+ const view = await this.resolveUserViewByID(viewID, provider, contextUser);
246
+ if (!view?.ID || !UUIDsEqual(view.ID, viewID) || !UUIDsEqual(view.EntityID, entityID)) {
247
+ throw new Error('The requested view does not exist or you do not have access to it');
248
+ }
249
+ }
250
+
251
+ /** Builds the message, replacing each template the client named with the server's copy of it. */
252
+ private async resolveMessageTemplates(message: CommunicationMessageInput, contextUser: UserInfo): Promise<Message> {
253
+ const newMessage = new Message(message as unknown as Message);
254
+ await TemplateEngineServer.Instance.Config(false, contextUser);
255
+ if (newMessage.BodyTemplate) {
256
+ newMessage.BodyTemplate = TemplateEngineServer.Instance.FindTemplate(newMessage.BodyTemplate.Name);
257
+ }
258
+ if (newMessage.HTMLBodyTemplate) {
259
+ newMessage.HTMLBodyTemplate = TemplateEngineServer.Instance.FindTemplate(newMessage.HTMLBodyTemplate.Name);
260
+ }
261
+ if (newMessage.SubjectTemplate) {
262
+ newMessage.SubjectTemplate = TemplateEngineServer.Instance.FindTemplate(newMessage.SubjectTemplate.Name);
263
+ }
264
+ return newMessage;
265
+ }
225
266
  }
@@ -38,7 +38,8 @@ export class EntityRecordNameResult {
38
38
  *
39
39
  * Entity-level read permission is checked here ({@link ResolverBase.CheckUserReadPermissions}).
40
40
  * Field- and row-level security are applied by the provider's lookup, for the acting user passed
41
- * to it: when any field the name is built from is withheld, it answers with no name.
41
+ * to it: when any field the name is built from is withheld, it answers with no name, and it reads
42
+ * only rows the user's read row filter allows. Without an acting user there is no lookup.
42
43
  *
43
44
  * A withheld name answers `Success: false` with the same status as a record that does not exist.
44
45
  * Callers already treat "no name" as "show the primary key", and the identical answer keeps this
@@ -85,7 +86,7 @@ export class EntityRecordNameResolver extends ResolverBase {
85
86
  if (e) {
86
87
  const contextUser = userPayload ? this.GetUserFromPayload(userPayload) : undefined;
87
88
  // The acting user is what field- and row-level security are applied for.
88
- const recordName = await md.GetEntityRecordName(e.Name, pk, contextUser);
89
+ const recordName = contextUser ? await md.GetEntityRecordName(e.Name, pk, contextUser) : '';
89
90
  if (recordName) return { Success: true, Status: 'OK', CompositeKey: pk, RecordName: recordName, EntityName };
90
91
  else
91
92
  return {