@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
@@ -0,0 +1,274 @@
1
+ // type-graphql decorators call `Reflect.getMetadata`, which only exists once this polyfill is
2
+ // loaded. MUST precede any import that pulls in the resolver file.
3
+ import 'reflect-metadata';
4
+
5
+ import { describe, it, expect, vi } from 'vitest';
6
+ import { readFileSync } from 'fs';
7
+ import { resolve } from 'path';
8
+
9
+ vi.mock('type-graphql', () => {
10
+ const noopDecorator = () => () => undefined;
11
+ return {
12
+ Resolver: noopDecorator, Mutation: noopDecorator, Query: noopDecorator, Subscription: noopDecorator,
13
+ ObjectType: noopDecorator, InputType: noopDecorator, Field: noopDecorator, Arg: noopDecorator,
14
+ Args: noopDecorator, Ctx: noopDecorator, PubSub: noopDecorator, Root: noopDecorator,
15
+ Directive: noopDecorator, Authorized: noopDecorator, UseMiddleware: noopDecorator,
16
+ createUnionType: () => class {},
17
+ AuthorizationError: class AuthorizationError extends Error {},
18
+ Float: class {}, Int: class {}, ID: class {},
19
+ };
20
+ });
21
+
22
+ vi.mock('../config.js', () => ({ configInfo: { databaseSettings: { requestTimeout: 120_000 } } }));
23
+
24
+ import { UserInfo } from '@memberjunction/core';
25
+ import type { DatabaseProviderBase } from '@memberjunction/core';
26
+ import { TestQuerySQLResolver, TestQuerySQLInput } from '../resolvers/TestQuerySQLResolver.js';
27
+ import type { AppContext } from '../types.js';
28
+
29
+ interface EntityFixture {
30
+ Name: string;
31
+ SchemaName: string;
32
+ BaseView: string;
33
+ canRead?: boolean;
34
+ rowFilter?: string;
35
+ deniedFields?: string[];
36
+ }
37
+
38
+ function createReadOnlyProvider(entities: EntityFixture[]): DatabaseProviderBase {
39
+ return {
40
+ PlatformKey: 'sqlserver',
41
+ Entities: entities.map((e) => ({
42
+ Name: e.Name,
43
+ SchemaName: e.SchemaName,
44
+ BaseView: e.BaseView,
45
+ GetUserPermisions: () => ({ CanRead: e.canRead ?? true }),
46
+ GetEffectiveRowFilterWhereClause: () => e.rowFilter ?? '',
47
+ GetDeniedReadFields: () => new Set<string>(e.deniedFields ?? []),
48
+ })),
49
+ } as unknown as DatabaseProviderBase;
50
+ }
51
+
52
+ function createPlainUser(): UserInfo {
53
+ const u = new UserInfo();
54
+ u.ID = 'D1F1A0C4-0000-4000-8000-000000000001';
55
+ u.Email = 'user@example.com';
56
+ return u;
57
+ }
58
+
59
+ const RUBRIC_EVALUATIONS: EntityFixture = {
60
+ Name: 'MJ: Rubric Evaluations',
61
+ SchemaName: '__mj',
62
+ BaseView: 'vwRubricEvaluations',
63
+ };
64
+
65
+ const AI_MODELS: EntityFixture = {
66
+ Name: 'MJ: AI Models',
67
+ SchemaName: '__mj',
68
+ BaseView: 'vwAIModels',
69
+ };
70
+
71
+ describe('TestQuerySQLResolver scope-limited principal guard', () => {
72
+ const resolverSrc = readFileSync(resolve(__dirname, '../resolvers/TestQuerySQLResolver.ts'), 'utf8');
73
+
74
+ it('checks IsScopeLimitedPrincipal before acquiring the read-only provider or authorizing SQL', () => {
75
+ const scopeGuardIdx = resolverSrc.indexOf('IsScopeLimitedPrincipal(');
76
+ const providerIdx = resolverSrc.indexOf('GetReadOnlyProvider(');
77
+ const authorizeIdx = resolverSrc.indexOf('this.AuthorizeRenderedTestSQL(');
78
+
79
+ expect(scopeGuardIdx).toBeGreaterThan(-1);
80
+ expect(providerIdx).toBeGreaterThan(-1);
81
+ expect(authorizeIdx).toBeGreaterThan(-1);
82
+ expect(scopeGuardIdx).toBeLessThan(providerIdx);
83
+ expect(providerIdx).toBeLessThan(authorizeIdx);
84
+ });
85
+
86
+ it('refuses anonymous magic-link guests, resource-scoped sessions, and missing principals', async () => {
87
+ const resolver = new TestQuerySQLResolver();
88
+ const input: TestQuerySQLInput = { SQL: 'SELECT ID FROM [__mj].[vwRubricEvaluations]' };
89
+
90
+ const anonGuest = createPlainUser();
91
+ anonGuest.IsMagicLinkAnonymous = true;
92
+
93
+ const scopedUser = createPlainUser();
94
+ scopedUser.MagicLinkScope = { ResourceID: 'A0000000-0000-4000-8000-000000000009' };
95
+
96
+ for (const userRecord of [anonGuest, scopedUser, undefined]) {
97
+ const context = {
98
+ userPayload: { userRecord, email: 'guest@example.com', sessionId: 'sess-1' },
99
+ providers: [],
100
+ } as unknown as AppContext;
101
+
102
+ const result = await resolver.TestQuerySQL(input, context);
103
+ expect(result.Success).toBe(false);
104
+ expect(result.RowCount).toBe(0);
105
+ expect(result.ErrorMessage).toBe('Ad-hoc SQL execution is not permitted for scope-limited sessions.');
106
+ }
107
+ });
108
+ });
109
+
110
+ describe('TestQuerySQLResolver.AuthorizeRenderedTestSQL', () => {
111
+ const resolver = new TestQuerySQLResolver();
112
+ const user = createPlainUser();
113
+
114
+ it('admits a read query referencing only unscoped readable entity base views', () => {
115
+ const provider = createReadOnlyProvider([RUBRIC_EVALUATIONS, AI_MODELS]);
116
+ const refusal = resolver.AuthorizeRenderedTestSQL(
117
+ { SQL: 'SELECT r.ID, m.Name FROM [__mj].[vwRubricEvaluations] r INNER JOIN [__mj].[vwAIModels] m ON r.ID = m.ID' },
118
+ provider,
119
+ user,
120
+ );
121
+ expect(refusal).toBeNull();
122
+ });
123
+
124
+ it('allows a table-free query that reads niladic user functions (CURRENT_USER, SESSION_USER, SYSTEM_USER)', () => {
125
+ const provider = createReadOnlyProvider([RUBRIC_EVALUATIONS]);
126
+ const refusal = resolver.AuthorizeRenderedTestSQL(
127
+ { SQL: 'SELECT CURRENT_USER AS UserName, SESSION_USER AS SessionUser, SYSTEM_USER AS SystemUser' },
128
+ provider,
129
+ user,
130
+ );
131
+ expect(refusal).toBeNull();
132
+ });
133
+
134
+ it('refuses a query that reads a base table instead of an entity base view', () => {
135
+ const provider = createReadOnlyProvider([RUBRIC_EVALUATIONS]);
136
+ const refusal = resolver.AuthorizeRenderedTestSQL(
137
+ { SQL: 'SELECT * FROM [__mj].[User]' },
138
+ provider,
139
+ user,
140
+ );
141
+ expect(refusal).toMatch(/entity base view/);
142
+ });
143
+
144
+ it('refuses a query that reads an entity the caller does not have CanRead permission for', () => {
145
+ const provider = createReadOnlyProvider([{ ...RUBRIC_EVALUATIONS, canRead: false }]);
146
+ const refusal = resolver.AuthorizeRenderedTestSQL(
147
+ { SQL: 'SELECT ID FROM [__mj].[vwRubricEvaluations]' },
148
+ provider,
149
+ user,
150
+ );
151
+ expect(refusal).toMatch(/not permitted to read|permission/i);
152
+ });
153
+
154
+ it('refuses a query that reads a row-level-security filtered entity', () => {
155
+ const provider = createReadOnlyProvider([
156
+ { ...RUBRIC_EVALUATIONS, rowFilter: "EvaluatorUserID = 'user-1'" },
157
+ ]);
158
+ const refusal = resolver.AuthorizeRenderedTestSQL(
159
+ { SQL: 'SELECT ID FROM [__mj].[vwRubricEvaluations]' },
160
+ provider,
161
+ user,
162
+ );
163
+ expect(refusal).toMatch(/row-level-security filtered/);
164
+ });
165
+
166
+ it('refuses a query that reads an entity with denied read fields for the caller', () => {
167
+ const provider = createReadOnlyProvider([
168
+ { ...RUBRIC_EVALUATIONS, deniedFields: ['SecretScore'] },
169
+ ]);
170
+ const refusal = resolver.AuthorizeRenderedTestSQL(
171
+ { SQL: 'SELECT ID FROM [__mj].[vwRubricEvaluations]' },
172
+ provider,
173
+ user,
174
+ );
175
+ expect(refusal).toMatch(/fields you are not permitted to read/);
176
+ });
177
+
178
+ it('refuses write statements and stacked SQL batches at render time', () => {
179
+ const provider = createReadOnlyProvider([RUBRIC_EVALUATIONS]);
180
+
181
+ const deleteRefusal = resolver.AuthorizeRenderedTestSQL(
182
+ { SQL: 'DELETE FROM [__mj].[vwRubricEvaluations]' },
183
+ provider,
184
+ user,
185
+ );
186
+ expect(deleteRefusal).toMatch(/single read query/i);
187
+
188
+ const stackedRefusal = resolver.AuthorizeRenderedTestSQL(
189
+ { SQL: 'SELECT ID FROM [__mj].[vwRubricEvaluations]; SELECT * FROM [__mj].[User]' },
190
+ provider,
191
+ user,
192
+ );
193
+ expect(stackedRefusal).toMatch(/single read query/i);
194
+ });
195
+
196
+ it('screens the rendered SQL after Nunjucks template expansion', () => {
197
+ const provider = createReadOnlyProvider([RUBRIC_EVALUATIONS]);
198
+
199
+ // Safe parameter substitution on an allowed view passes
200
+ const safeRefusal = resolver.AuthorizeRenderedTestSQL(
201
+ {
202
+ SQL: 'SELECT ID FROM [__mj].[vwRubricEvaluations] WHERE Name = {{ targetName | sqlString }}',
203
+ UsesTemplate: true,
204
+ Parameters: { targetName: 'Q1 Eval' },
205
+ },
206
+ provider,
207
+ user,
208
+ );
209
+ expect(safeRefusal).toBeNull();
210
+
211
+ // Template expansion that introduces a base table reference is refused
212
+ const injectedTableRefusal = resolver.AuthorizeRenderedTestSQL(
213
+ {
214
+ SQL: 'SELECT * FROM {{ targetTable }}',
215
+ UsesTemplate: true,
216
+ Parameters: { targetTable: '[__mj].[User]' },
217
+ },
218
+ provider,
219
+ user,
220
+ );
221
+ expect(injectedTableRefusal).toMatch(/entity base view/);
222
+ });
223
+
224
+ it('screens the rendered SQL after inline Dependencies ({{query:"..."}}) composition', () => {
225
+ const provider = createReadOnlyProvider([RUBRIC_EVALUATIONS, AI_MODELS]);
226
+
227
+ // Inline dependency reading an unscoped readable entity base view is admitted
228
+ const allowedDepRefusal = resolver.AuthorizeRenderedTestSQL(
229
+ {
230
+ SQL: 'SELECT sub.ID FROM {{query:"Analytics/Evals/Base"}} sub',
231
+ Dependencies: [
232
+ {
233
+ Name: 'Base',
234
+ CategoryPath: '/Analytics/Evals/',
235
+ SQL: 'SELECT ID FROM [__mj].[vwRubricEvaluations]',
236
+ },
237
+ ],
238
+ },
239
+ provider,
240
+ user,
241
+ );
242
+ expect(allowedDepRefusal).toBeNull();
243
+
244
+ // Inline dependency reading a base table is refused when composed into the outer query
245
+ const forbiddenDepRefusal = resolver.AuthorizeRenderedTestSQL(
246
+ {
247
+ SQL: 'SELECT sub.ID FROM {{query:"Analytics/Evals/LeakedUsers"}} sub',
248
+ Dependencies: [
249
+ {
250
+ Name: 'LeakedUsers',
251
+ CategoryPath: '/Analytics/Evals/',
252
+ SQL: 'SELECT ID FROM [__mj].[User]',
253
+ },
254
+ ],
255
+ },
256
+ provider,
257
+ user,
258
+ );
259
+ expect(forbiddenDepRefusal).toMatch(/entity base view/);
260
+ });
261
+ });
262
+
263
+ describe('IntegrationDiscoveryResolver webhook SSRF guard', () => {
264
+ const discoverySrc = readFileSync(resolve(__dirname, '../resolvers/IntegrationDiscoveryResolver.ts'), 'utf8');
265
+
266
+ it('routes sendWebhook through SafeFetch from @memberjunction/network-utils instead of bare fetch', () => {
267
+ expect(discoverySrc).toMatch(/import\s*\{[^}]*\bSafeFetch\b[^}]*\}\s*from\s*['"]@memberjunction\/network-utils['"]/);
268
+ const sendWebhookStart = discoverySrc.indexOf('private async sendWebhook(');
269
+ expect(sendWebhookStart).toBeGreaterThan(-1);
270
+ const sendWebhookBody = discoverySrc.slice(sendWebhookStart, sendWebhookStart + 800);
271
+ expect(sendWebhookBody).toContain('await SafeFetch(url,');
272
+ expect(sendWebhookBody).not.toMatch(/(?<![A-Za-z])fetch\s*\(/);
273
+ });
274
+ });
@@ -0,0 +1,199 @@
1
+ /**
2
+ * Field-level security on the transaction-group transport.
3
+ *
4
+ * Output: every `ResultsJSON` entry is projected for the caller. The update entry is a DELTA,
5
+ * computed by comparing the post-save row with a pre-save snapshot. When the snapshot came from a
6
+ * load narrowed for the caller and the post-save row is full width, every non-null denied value
7
+ * differs from its (absent) snapshot and counts as "changed", so the delta itself carried the
8
+ * values the caller may not read. The entity objects here deliberately return full-width rows
9
+ * to stand in for any object not narrowed at its source.
10
+ *
11
+ * Input: a restricted caller's item payload, and the field a transaction variable names, are
12
+ * refused when they carry a key the caller may not read or a key that names no field, with the
13
+ * same message for both, so the refusal does not reveal which columns exist.
14
+ */
15
+ import 'reflect-metadata';
16
+ import { describe, it, expect, vi } from 'vitest';
17
+ import { BaseEntityResult, EntityInfo, UserInfo } from '@memberjunction/core';
18
+
19
+ vi.mock('@memberjunction/core', async (importOriginal) => {
20
+ const actual = await importOriginal<typeof import('@memberjunction/core')>();
21
+ return { ...actual, LogError: () => undefined };
22
+ });
23
+
24
+ import {
25
+ TransactionResolver,
26
+ TransactionInputType,
27
+ TransactionOperationType,
28
+ TransactionVariableType,
29
+ } from '../resolvers/TransactionGroupResolver.js';
30
+ import type { AppContext } from '../types.js';
31
+ import { EmployeeEntity, FullWidthEmployeeRow, HRUser, Intern, RefusalFor, SECRET_SALARY } from './fieldSecurityFixtures.js';
32
+
33
+ class FakeTransactionGroup {
34
+ public Enrolled = 0;
35
+ public AddTransaction(): void { this.Enrolled++; }
36
+ public AddVariable(): void { /* variables are not under test here */ }
37
+ public async Submit(): Promise<boolean> { return true; }
38
+ }
39
+
40
+ /**
41
+ * An entity object that is NOT narrowed at its source: its load returns `loaded`, and after the
42
+ * save it reports the full-width row, as a save's re-read does.
43
+ */
44
+ class FullWidthEntity {
45
+ public TransactionGroup: FakeTransactionGroup | null = null;
46
+ public LatestResult: BaseEntityResult | null = null;
47
+ public PrimaryKeys = [{ Name: 'ID' }];
48
+ public SetManyCalls: Array<Record<string, unknown>> = [];
49
+ private values: Record<string, unknown>;
50
+ private saved = false;
51
+
52
+ constructor(public readonly EntityInfo: EntityInfo, private readonly loaded: Record<string, unknown>) {
53
+ this.values = { ...loaded };
54
+ }
55
+ public SetMany(values: Record<string, unknown>): void {
56
+ this.SetManyCalls.push(values);
57
+ this.values = { ...this.values, ...values };
58
+ }
59
+ public async InnerLoad(): Promise<boolean> { this.values = { ...this.loaded }; return true; }
60
+ public async GetDataObject(): Promise<Record<string, unknown>> {
61
+ return this.saved ? { ...FullWidthEmployeeRow(), ...this.values, Salary: SECRET_SALARY } : { ...this.values };
62
+ }
63
+ public async GetDataObjectJSON(): Promise<string> { return JSON.stringify(await this.GetDataObject()); }
64
+ public async Save(): Promise<boolean> { return this.write(); }
65
+ public async Delete(): Promise<boolean> { return this.write(); }
66
+ private write(): boolean {
67
+ this.TransactionGroup?.AddTransaction();
68
+ this.saved = true;
69
+ const result = new BaseEntityResult();
70
+ result.Success = true;
71
+ this.LatestResult = result;
72
+ return true;
73
+ }
74
+ }
75
+
76
+ /** What a load narrowed for an intern holds: no salary keys at all. */
77
+ const NARROW_ROW = { ID: 'emp-1', Name: 'Ada', Notes: 'n' };
78
+
79
+ function buildContext(entities: FullWidthEntity[], user: UserInfo): AppContext {
80
+ let next = 0;
81
+ const provider = {
82
+ CreateTransactionGroup: async () => new FakeTransactionGroup(),
83
+ GetEntityObject: async () => entities[next++],
84
+ Entities: [] as EntityInfo[],
85
+ EntityByID: () => undefined,
86
+ };
87
+ return {
88
+ providers: [{ type: 'Read-Write', provider }],
89
+ userPayload: { userRecord: user, email: user.Email },
90
+ } as unknown as AppContext;
91
+ }
92
+
93
+ function group(operation: TransactionOperationType, payload: Record<string, unknown>): TransactionInputType {
94
+ return { Items: [{ EntityName: 'Employees', EntityObjectJSON: JSON.stringify(payload), OperationType: operation }], Variables: [] };
95
+ }
96
+
97
+ describe('ExecuteTransactionGroup: output is projected for the caller', () => {
98
+ it('REGRESSION: the update delta never carries a denied value, though the post-save row is full width', async () => {
99
+ const entity = new FullWidthEntity(EmployeeEntity(), NARROW_ROW);
100
+ const result = await new TransactionResolver().ExecuteTransactionGroup(
101
+ group(TransactionOperationType.Update, { ID: 'emp-1', Notes: 'edited' }),
102
+ buildContext([entity], Intern())
103
+ );
104
+
105
+ expect(result.Success).toBe(true);
106
+ const delta = JSON.parse(result.ResultsJSON[0]);
107
+ expect(delta).toMatchObject({ ID: 'emp-1', Notes: 'edited' });
108
+ expect(delta).not.toHaveProperty('Salary');
109
+ expect(delta).not.toHaveProperty('Base Salary');
110
+ expect(result.ResultsJSON[0]).not.toContain(String(SECRET_SALARY));
111
+ });
112
+
113
+ it('REGRESSION: the create result never carries a denied value', async () => {
114
+ const entity = new FullWidthEntity(EmployeeEntity(), {});
115
+ const result = await new TransactionResolver().ExecuteTransactionGroup(
116
+ group(TransactionOperationType.Create, { ID: 'emp-1', Name: 'Ada' }),
117
+ buildContext([entity], Intern())
118
+ );
119
+
120
+ expect(result.ResultsJSON[0]).not.toContain(String(SECRET_SALARY));
121
+ expect(JSON.parse(result.ResultsJSON[0])).toMatchObject({ ID: 'emp-1', Name: 'Ada' });
122
+ });
123
+
124
+ it('REGRESSION: the delete result never carries a denied value', async () => {
125
+ const entity = new FullWidthEntity(EmployeeEntity(), FullWidthEmployeeRow());
126
+ const result = await new TransactionResolver().ExecuteTransactionGroup(
127
+ group(TransactionOperationType.Delete, { ID: 'emp-1' }),
128
+ buildContext([entity], Intern())
129
+ );
130
+
131
+ expect(result.ResultsJSON[0]).not.toContain(String(SECRET_SALARY));
132
+ expect(JSON.parse(result.ResultsJSON[0])).toMatchObject({ ID: 'emp-1', Name: 'Ada' });
133
+ });
134
+
135
+ it('a caller who may read the salary still gets it back', async () => {
136
+ const entity = new FullWidthEntity(EmployeeEntity(), {});
137
+ const result = await new TransactionResolver().ExecuteTransactionGroup(
138
+ group(TransactionOperationType.Create, { ID: 'emp-1', Name: 'Ada', Salary: 1 }),
139
+ buildContext([entity], HRUser())
140
+ );
141
+
142
+ expect(JSON.parse(result.ResultsJSON[0]).Salary).toBe(SECRET_SALARY);
143
+ });
144
+ });
145
+
146
+ describe('ExecuteTransactionGroup: client input is gated for a restricted caller', () => {
147
+ it.each([
148
+ ['a denied field', 'Salary'],
149
+ ['a key that names no field', 'Bogus'],
150
+ ])('REGRESSION: refuses %s with the same message, before anything is applied', async (_label, key) => {
151
+ const entity = new FullWidthEntity(EmployeeEntity(), NARROW_ROW);
152
+ const run = new TransactionResolver().ExecuteTransactionGroup(
153
+ group(TransactionOperationType.Update, { ID: 'emp-1', Notes: 'edited', [key]: 1 }),
154
+ buildContext([entity], Intern())
155
+ );
156
+
157
+ await expect(run).rejects.toThrow(RefusalFor(key));
158
+ expect(entity.SetManyCalls).toHaveLength(0);
159
+ });
160
+
161
+ it('REGRESSION: refuses a transaction variable that names a denied field (it would copy the value elsewhere)', async () => {
162
+ const source = new FullWidthEntity(EmployeeEntity(), NARROW_ROW);
163
+ const target = new FullWidthEntity(EmployeeEntity(), NARROW_ROW);
164
+ const input: TransactionInputType = {
165
+ Items: [
166
+ { EntityName: 'Employees', EntityObjectJSON: JSON.stringify({ ID: 'emp-1', Notes: 'a' }), OperationType: TransactionOperationType.Update },
167
+ { EntityName: 'Employees', EntityObjectJSON: JSON.stringify({ ID: 'emp-2', Notes: 'b' }), OperationType: TransactionOperationType.Update },
168
+ ],
169
+ Variables: [
170
+ { Name: 'leak', ItemIndex: 0, FieldName: 'Salary', Type: TransactionVariableType.Define },
171
+ { Name: 'leak', ItemIndex: 1, FieldName: 'Notes', Type: TransactionVariableType.Use },
172
+ ],
173
+ };
174
+
175
+ await expect(new TransactionResolver().ExecuteTransactionGroup(input, buildContext([source, target], Intern())))
176
+ .rejects.toThrow(RefusalFor('Salary'));
177
+ });
178
+
179
+ it('accepts the keys a well-behaved client sends, plus transport keys', async () => {
180
+ const entity = new FullWidthEntity(EmployeeEntity(), NARROW_ROW);
181
+ const result = await new TransactionResolver().ExecuteTransactionGroup(
182
+ group(TransactionOperationType.Update, { ID: 'emp-1', Notes: 'edited', __typename: 'Employee_' }),
183
+ buildContext([entity], Intern())
184
+ );
185
+
186
+ expect(result.Success).toBe(true);
187
+ expect(entity.SetManyCalls).toHaveLength(1);
188
+ });
189
+
190
+ it('does not gate a caller who is denied nothing', async () => {
191
+ const entity = new FullWidthEntity(EmployeeEntity(), FullWidthEmployeeRow());
192
+ const result = await new TransactionResolver().ExecuteTransactionGroup(
193
+ group(TransactionOperationType.Update, { ID: 'emp-1', Salary: 5 }),
194
+ buildContext([entity], HRUser())
195
+ );
196
+
197
+ expect(result.Success).toBe(true);
198
+ });
199
+ });
@@ -41,6 +41,7 @@ import {
41
41
  TransactionInputType,
42
42
  TransactionItemInputType,
43
43
  TransactionOperationType,
44
+ TransactionVariableType,
44
45
  } from '../resolvers/TransactionGroupResolver.js';
45
46
  import type { AppContext } from '../types.js';
46
47
 
@@ -57,7 +58,10 @@ class FakeTransactionGroup {
57
58
  public AddTransaction(label: string): void {
58
59
  this.Enrolled.push(label);
59
60
  }
60
- public AddVariable(): void { /* no variables in these tests */ }
61
+ public Variables: unknown[] = [];
62
+ public AddVariable(variable: unknown): void {
63
+ this.Variables.push(variable);
64
+ }
61
65
  public async Submit(): Promise<boolean> {
62
66
  this.SubmitCalled = true;
63
67
  // TransactionGroupBase.Submit(): an empty group is "nothing to do" and returns true.
@@ -287,4 +291,97 @@ describe('ExecuteTransactionGroup — rows refused server-side (issue #4309)', (
287
291
  expect(result.Success).toBe(true);
288
292
  expect(group.Enrolled).toHaveLength(0);
289
293
  });
294
+
295
+ it("registers the group's variables before any row's Save(), so a server-side check can see them", async () => {
296
+ // A 'Use' variable sets its field at Submit(), after every Save()-time check has passed. A check
297
+ // that depends on a field's final value (who a conversation message is from) can refuse such a
298
+ // row only if the variable is already on the group when its Save() runs.
299
+ const variablesAtSave: number[] = [];
300
+ class RecordingEntity extends FakeEntity {
301
+ public override async Save(): Promise<boolean> {
302
+ variablesAtSave.push(this.TransactionGroup?.Variables.length ?? -1);
303
+ return super.Save();
304
+ }
305
+ }
306
+ const entities = [
307
+ new RecordingEntity('MJ: User Roles', { accepts: true }),
308
+ new RecordingEntity('MJ: User Roles', { accepts: true }),
309
+ ];
310
+ const { context } = buildContext(entities);
311
+ const input = buildGroupInput(2);
312
+ input.Variables = [
313
+ { Name: 'v', ItemIndex: 0, FieldName: 'ID', Type: TransactionVariableType.Define },
314
+ { Name: 'v', ItemIndex: 1, FieldName: 'UserID', Type: TransactionVariableType.Use },
315
+ ];
316
+
317
+ const result = await new TransactionResolver().ExecuteTransactionGroup(input, context);
318
+
319
+ expect(result.Success).toBe(true);
320
+ expect(variablesAtSave).toEqual([2, 2]);
321
+ });
322
+
323
+ it('returns delta-only ResultsJSON on Update (PK, client-sent fields, datestamps, and server-changed fields), omitting unchanged columns', async () => {
324
+ const preLoadedRow: Record<string, unknown> = {
325
+ ID: 'a0000000-0000-0000-0000-000000000099',
326
+ Name: 'Action One',
327
+ Description: 'Initial description',
328
+ DriverClass: 'OriginalDriver',
329
+ Category: 'Utilities',
330
+ __mj_CreatedAt: '2026-01-01T00:00:00.000Z',
331
+ __mj_UpdatedAt: '2026-02-01T00:00:00.000Z',
332
+ };
333
+ for (let i = 1; i <= 15; i++) {
334
+ preLoadedRow[`UnchangedField${i}`] = `Constant-${i}`;
335
+ }
336
+
337
+ class ServerMutatingEntity extends FakeEntity {
338
+ public override async Save(): Promise<boolean> {
339
+ const ok = await super.Save();
340
+ if (ok) {
341
+ // Simulate server-side DB update refreshing __mj_UpdatedAt and a computed/trigger column
342
+ this.SetMany({
343
+ __mj_UpdatedAt: '2026-03-01T00:00:00.000Z',
344
+ Category: 'Automation (Server Refreshed)',
345
+ });
346
+ }
347
+ return ok;
348
+ }
349
+ }
350
+
351
+ const entity = new ServerMutatingEntity('MJ: Actions', {
352
+ accepts: true,
353
+ loadedValues: preLoadedRow,
354
+ });
355
+ const { context } = buildContext([entity]);
356
+ const input: TransactionInputType = {
357
+ Items: [
358
+ {
359
+ EntityName: 'MJ: Actions',
360
+ EntityObjectJSON: JSON.stringify({
361
+ ID: 'a0000000-0000-0000-0000-000000000099',
362
+ Description: 'Updated description',
363
+ }),
364
+ OperationType: TransactionOperationType.Update,
365
+ },
366
+ ],
367
+ Variables: [],
368
+ };
369
+
370
+ const result = await new TransactionResolver().ExecuteTransactionGroup(input, context);
371
+
372
+ expect(result.Success).toBe(true);
373
+ const returnedObj = JSON.parse(result.ResultsJSON[0]) as Record<string, unknown>;
374
+ expect(returnedObj).toEqual({
375
+ ID: 'a0000000-0000-0000-0000-000000000099',
376
+ Description: 'Updated description',
377
+ Category: 'Automation (Server Refreshed)',
378
+ __mj_CreatedAt: '2026-01-01T00:00:00.000Z',
379
+ __mj_UpdatedAt: '2026-03-01T00:00:00.000Z',
380
+ });
381
+ expect(returnedObj).not.toHaveProperty('Name');
382
+ expect(returnedObj).not.toHaveProperty('DriverClass');
383
+ for (let i = 1; i <= 15; i++) {
384
+ expect(returnedObj).not.toHaveProperty(`UnchangedField${i}`);
385
+ }
386
+ });
290
387
  });