@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
@@ -12,6 +12,8 @@ import { GetHostInstanceID } from './HostInstance.js';
12
12
  import { WriteReturningVisitorRecap } from './ReturningVisitorRecap.js';
13
13
  import { SessionRunIDVerifier, SessionRunIDs } from './SessionRunIDVerifier.js';
14
14
  import { ResolveScopedAnonymousRunUser } from '../realtimeWidget/widgetGuestElevation.js';
15
+ import { RecordingAssemblyScheduler } from '../realtimeSessions/RecordingAssemblyScheduler.js';
16
+ import { ResolveSessionScopeIdentity } from '../realtimeSessions/sessionAccess.js';
15
17
 
16
18
  /** Entity names — centralised so the `MJ:`-prefix convention is applied in exactly one place. */
17
19
  const SESSION_ENTITY = 'MJ: AI Agent Sessions';
@@ -152,11 +154,13 @@ export class SessionManager {
152
154
  /**
153
155
  * Authorize and create a new session. Flow:
154
156
  * 1. `CanRun` check on the agent — denied → {@link SessionAuthorizationError}, no row written.
155
- * 2. Resolve the conversation (use the supplied one, or create+link a fresh Conversation).
157
+ * 2. Resolve the conversation (use the supplied one, or create+link a fresh Conversation). An anonymous
158
+ * caller may only supply a conversation stamped with its own scope identity.
156
159
  * 3. Persist the `AIAgentSession` as `Active`, stamped with this host and `LastActiveAt = now`.
157
160
  *
158
161
  * @returns the saved {@link MJAIAgentSessionEntity}.
159
- * @throws {SessionAuthorizationError} when the user may not run the agent.
162
+ * @throws {SessionAuthorizationError} when the user may not run the agent, or an anonymous caller supplies a
163
+ * conversation that is not its own.
160
164
  * @throws {Error} when conversation creation or session save fails.
161
165
  */
162
166
  public async CreateSession(
@@ -165,6 +169,9 @@ export class SessionManager {
165
169
  provider: IMetadataProvider,
166
170
  ): Promise<MJAIAgentSessionEntity> {
167
171
  await this.assertCanRun(input.agentID, contextUser);
172
+ if (input.conversationID && contextUser.IsMagicLinkAnonymous) {
173
+ await this.assertAnonymousOwnsConversation(input.conversationID, contextUser, provider);
174
+ }
168
175
 
169
176
  const conversationID = input.conversationID
170
177
  ?? await this.createConversation(input, contextUser, provider);
@@ -212,6 +219,13 @@ export class SessionManager {
212
219
  if (!closed) {
213
220
  return false;
214
221
  }
222
+ if (session.RecordingStartedAt) {
223
+ // A client-direct recording is assembled only after the grace period while its call is open
224
+ // (a hidden tab must not rewrite recording.wav on every switch; see RealtimeRecordingHandler).
225
+ // The call has ended now, so assemble it right away. The ledger's claim arbitrates instances,
226
+ // and a recording with nothing to assemble (none, or server-bridged) is simply not claimable.
227
+ RecordingAssemblyScheduler.Instance.ScheduleAssembly(agentSessionID, 0, false);
228
+ }
215
229
  await this.disconnectChannels(agentSessionID, contextUser, provider, preloadedChannels);
216
230
  await this.finalizeObservabilityRuns(session, contextUser, provider);
217
231
  await this.notifyChannelPluginsSessionClosed(agentSessionID, closeReason);
@@ -440,6 +454,23 @@ export class SessionManager {
440
454
 
441
455
  // ----- internals -------------------------------------------------------------------------
442
456
 
457
+ /**
458
+ * Throws {@link SessionAuthorizationError} unless the anonymous caller owns the conversation it wants to bind a
459
+ * new session to: the conversation, read as the caller, loads, and its `ExternalID` equals the caller's scope
460
+ * identity ({@link ResolveSessionScopeIdentity}). A caller with no scope identity is refused. Every anonymous
461
+ * visitor shares one Anonymous user, so row-level security alone may let one visitor read another's
462
+ * conversation; without this check the new session row and its relays would point into that conversation.
463
+ */
464
+ private async assertAnonymousOwnsConversation(conversationID: string, contextUser: UserInfo, provider: IMetadataProvider): Promise<void> {
465
+ const conversation = await provider.GetEntityObject<MJConversationEntity>(CONVERSATION_ENTITY, contextUser);
466
+ const loaded = await conversation.Load(conversationID);
467
+ const scopeIdentity = ResolveSessionScopeIdentity(contextUser);
468
+ if (!loaded || !scopeIdentity || conversation.ExternalID !== scopeIdentity) {
469
+ LogError(`SessionManager.CreateSession: refused anonymous user ${contextUser.ID} binding a session to conversation ${conversationID} (${loaded ? 'not its own' : 'not readable'}).`);
470
+ throw new SessionAuthorizationError('Not authorized to start a session on this conversation.');
471
+ }
472
+ }
473
+
443
474
  /** Throws {@link SessionAuthorizationError} unless the user has `CanRun` on the agent. */
444
475
  private async assertCanRun(agentID: string, contextUser: UserInfo): Promise<void> {
445
476
  const canRun = await AIAgentPermissionHelper.HasPermission(agentID, contextUser, 'run');
@@ -460,13 +491,13 @@ export class SessionManager {
460
491
  conversation.NewRecord();
461
492
  conversation.UserID = input.userID;
462
493
  conversation.Name = 'Agent Session';
463
- // For a magic-link-anonymous principal (e.g. a public web-widget voice guest), stamp the
464
- // session's conversation with the signed per-session scope so the Widget Guest RLS filters
465
- // ({{ScopeResourceID}}) isolate this session — and everything chained to it (AI Agent
466
- // Sessions via ConversationID, Session Channels via the session) — from other guests
467
- // sharing the Anonymous UserID. No-op for named principals (no scope → default ExternalID).
468
- if (contextUser.MagicLinkScope?.ResourceID) {
469
- conversation.ExternalID = contextUser.MagicLinkScope.ResourceID;
494
+ // Stamp the scope identity AuthorizeSessionAccess compares against (one rule, one place:
495
+ // ResolveSessionScopeIdentity) — the token's resource scope when it has one, else an anonymous
496
+ // visitor's mj_sid. This isolates anonymous visitors that share the Anonymous UserID, and keeps
497
+ // the {{ScopeResourceID}} RLS filters matching the visitor's own rows. No-op for unscoped named principals.
498
+ const scopeIdentity = ResolveSessionScopeIdentity(contextUser);
499
+ if (scopeIdentity) {
500
+ conversation.ExternalID = scopeIdentity;
470
501
  }
471
502
 
472
503
  // Returning-visitor memory (RV1/RV2/RV4) for the VOICE path: the widget guest token carries the
@@ -530,7 +561,11 @@ export class SessionManager {
530
561
  return session;
531
562
  }
532
563
 
533
- /** Loads a session entity by ID, returning null when it cannot be loaded. */
564
+ /**
565
+ * Loads a session entity by ID, returning null when it cannot be loaded. The lifecycle saves that
566
+ * follow cannot write back the recording ledger's columns: those have `AllowUpdateAPI=0`, so they are
567
+ * not parameters of `spUpdateAIAgentSession` (#5294, #6010).
568
+ */
534
569
  private async loadSession(
535
570
  agentSessionID: string,
536
571
  contextUser: UserInfo,
package/src/apiRoot.ts ADDED
@@ -0,0 +1,78 @@
1
+ /**
2
+ * MJAPI's base path: the single prefix every route MJAPI serves is mounted under (MJ #5674).
3
+ *
4
+ * MJAPI does not know where a proxy exposes it. Behind a proxy that forwards a prefix WITHOUT stripping it
5
+ * (CloudFront `/api/*` → MJAPI), MJAPI must listen under that prefix, so the host sets
6
+ * `MJAPI_BASE_PATH=/api`. Behind a stripping proxy, or with no proxy, it stays `/`. Every mount and every
7
+ * URL handed to a browser, an email or a webhook provider goes through {@link ApiRoute}, so one setting moves
8
+ * them all. CI enforces this (`check:api-root` and `__tests__/apiRootBoot.test.ts`).
9
+ *
10
+ * `GRAPHQL_ROOT_PATH` is a separate thing: only where Apollo listens. Do not derive routes from it.
11
+ *
12
+ * At the default base path `/` every value here is byte-identical to the root-mounted paths MJAPI always used.
13
+ */
14
+ import { TrimTrailingSlashes } from '@memberjunction/global';
15
+ import { configInfo } from './config.js';
16
+
17
+ /** Options for {@link ApiRoute}. */
18
+ export interface ApiRouteOptions {
19
+ /** Return the public absolute URL (`MJAPI_PUBLIC_URL` + subpath) instead of the server mount path. */
20
+ absolute?: boolean; // case-violation-ok-legacy-back-compat: the `{ absolute: true }` option shape is the documented #5674 contract
21
+ }
22
+
23
+ /**
24
+ * Normalizes a base-path value to a prefix with no trailing slash: `''` for `/`, `'/api'` for `/api/` or
25
+ * `/api`. Throws on a value that does not start with `/`, since Express would mount it nowhere.
26
+ */
27
+ export function NormalizeApiRootPath(rootPath: string | undefined): string {
28
+ const trimmed = (rootPath ?? '').trim();
29
+ if (trimmed && !trimmed.startsWith('/')) {
30
+ throw new Error(`MJAPI_BASE_PATH must start with '/', got '${trimmed}'`);
31
+ }
32
+ return TrimTrailingSlashes(trimmed);
33
+ }
34
+
35
+ function assertSubpath(subpath: string): void {
36
+ if (typeof subpath !== 'string' || !subpath.startsWith('/')) {
37
+ throw new Error(`ApiRoute subpath must start with '/', got '${String(subpath)}'`);
38
+ }
39
+ }
40
+
41
+ /** Joins a base path and a subpath relative to it. Pure, so tests can drive any base path. */
42
+ export function JoinApiRoute(apiRootPath: string, subpath: string): string {
43
+ assertSubpath(subpath);
44
+ return `${NormalizeApiRootPath(apiRootPath)}${subpath}`;
45
+ }
46
+
47
+ /** The running server's base path (`MJAPI_BASE_PATH`, no trailing slash; `''` at `/`). */
48
+ export function ApiRootPath(): string {
49
+ return NormalizeApiRootPath(configInfo.apiBasePath);
50
+ }
51
+
52
+ /**
53
+ * The server's configured public URL, derived exactly as it always has been: `MJAPI_PUBLIC_URL`, else
54
+ * `baseUrl:graphqlPort` + `graphqlRootPath`. Unchanged and untrimmed on purpose: it is the magic-link JWT
55
+ * issuer and the `publicUrl` handed to OAuth and server extensions, and changing it would invalidate issued
56
+ * tokens. Build URLs with `ApiRoute(subpath, { absolute: true })`, not from this.
57
+ */
58
+ export function ConfiguredPublicUrl(): string {
59
+ return configInfo.publicUrl || `${configInfo.baseUrl}:${configInfo.graphqlPort}${configInfo.graphqlRootPath || ''}`;
60
+ }
61
+
62
+ /**
63
+ * The path (or, with `{ absolute: true }`, the public URL) of a route under MJAPI's base path.
64
+ *
65
+ * `subpath` is relative to the base path and must start with `/`.
66
+ * - `ApiRoute('/media')` → `/media` at base `/`, `/api/media` at `MJAPI_BASE_PATH=/api`.
67
+ * - `ApiRoute('/media/abc', { absolute: true })` → `${MJAPI_PUBLIC_URL}/media/abc`. `MJAPI_PUBLIC_URL` is
68
+ * wherever the world reaches MJAPI (prefix included), so the base path is never added to it. Without it,
69
+ * the local fallback is `baseUrl:graphqlPort` + the base path.
70
+ */
71
+ export function ApiRoute(subpath: string, options?: ApiRouteOptions): string {
72
+ if (!options?.absolute) {
73
+ return JoinApiRoute(ApiRootPath(), subpath);
74
+ }
75
+ assertSubpath(subpath);
76
+ const base = configInfo.publicUrl || `${configInfo.baseUrl}:${configInfo.graphqlPort}${ApiRootPath()}`;
77
+ return `${TrimTrailingSlashes(base)}${subpath}`;
78
+ }
@@ -12,6 +12,8 @@ import { Router, type Request, type Response } from 'express';
12
12
  import { rateLimit } from 'express-rate-limit';
13
13
  import { LogError, type PublicAuthProviderCatalog } from '@memberjunction/core';
14
14
  import { AuthProviderEngine } from './AuthProviderEngine.js';
15
+ import { EMPTY_PUBLIC_LOGIN_SCREEN, LoginScreenEngine } from './LoginScreenEngine.js';
16
+ import { AttachLocalDevAuthRoutes } from './localDevAuth.js';
15
17
 
16
18
  /** Mount path for the public catalog router. */
17
19
  export const AUTH_CATALOG_MOUNT_PATH = '/auth';
@@ -72,6 +74,33 @@ export function CreateAuthProviderCatalogRouter(): Router {
72
74
  }
73
75
  });
74
76
 
77
+ /**
78
+ * `GET /auth/login-screen`: the default theme's PUBLISHED sign-in page, logos and seeds, for the login
79
+ * screen to draw before anyone signs in. Its own rate-limit budget (a 429 must answer in this route's
80
+ * shape), the catalog's cache window, and the same failure rule: empty, never an error.
81
+ */
82
+ const loginScreenLimiter = rateLimit({
83
+ windowMs: DEFAULT_RATE_LIMIT_WINDOW_MS,
84
+ limit: DEFAULT_RATE_LIMIT_MAX,
85
+ standardHeaders: 'draft-7',
86
+ legacyHeaders: false,
87
+ message: EMPTY_PUBLIC_LOGIN_SCREEN
88
+ });
89
+
90
+ router.get('/login-screen', loginScreenLimiter, (_req: Request, res: Response) => {
91
+ try {
92
+ const body = LoginScreenEngine.Instance.GetPublicLoginScreen();
93
+ res.set('Cache-Control', `public, max-age=${CACHE_MAX_AGE_SECONDS}`);
94
+ res.status(200).json(body);
95
+ } catch (error) {
96
+ const message = error instanceof Error ? error.message : String(error);
97
+ LogError(`[Auth] Failed to serve the public login screen: ${message}`);
98
+ res.status(200).json(EMPTY_PUBLIC_LOGIN_SCREEN);
99
+ }
100
+ });
101
+
102
+ AttachLocalDevAuthRoutes(router);
103
+
75
104
  return router;
76
105
  }
77
106
 
@@ -0,0 +1,50 @@
1
+ /**
2
+ * @fileoverview Caches the default theme for the public login-screen route.
3
+ *
4
+ * @module @memberjunction/server/auth
5
+ */
6
+ import { BaseEngine, BaseEnginePropertyConfig, RegisterForStartup, UserInfo, type IMetadataProvider } from '@memberjunction/core';
7
+ import { MJThemeEntity } from '@memberjunction/core-entities';
8
+ import { PublicLoginScreenFromTheme, type PublicLoginScreen } from '@memberjunction/theme-engine';
9
+
10
+ /** What the route serves when there is no default theme, or it cannot be read. */
11
+ export const EMPTY_PUBLIC_LOGIN_SCREEN: Readonly<PublicLoginScreen> = { ThemeName: null, Design: null, Seeds: null, Logos: {} };
12
+
13
+ /**
14
+ * Holds the default Active theme, so `GET /auth/login-screen` answers every anonymous page load from
15
+ * memory. Saving a theme refreshes it, so a publish in Login Studio reaches the login screen without a
16
+ * restart. Severity `warn`: a failed load must not stop the server; the route then serves the stock page.
17
+ */
18
+ @RegisterForStartup({
19
+ priority: 20,
20
+ severity: 'warn',
21
+ deferred: false,
22
+ description: 'Caches the default theme that GET /auth/login-screen serves to the login screen'
23
+ })
24
+ export class LoginScreenEngine extends BaseEngine<LoginScreenEngine> {
25
+ private _defaultThemes: MJThemeEntity[] = [];
26
+
27
+ public static get Instance(): LoginScreenEngine {
28
+ return super.getInstance<LoginScreenEngine>();
29
+ }
30
+
31
+ public async Config(forceRefresh?: boolean, contextUser?: UserInfo, provider?: IMetadataProvider): Promise<void> {
32
+ const configs: Partial<BaseEnginePropertyConfig>[] = [
33
+ {
34
+ PropertyName: '_defaultThemes',
35
+ EntityName: 'MJ: Themes',
36
+ // One default is enforced by the app, not the schema; the most recently changed one wins (as in Login Studio).
37
+ Filter: `IsDefault = 1 AND Status = 'Active'`,
38
+ OrderBy: '__mj_UpdatedAt DESC',
39
+ CacheLocal: true
40
+ }
41
+ ];
42
+ await this.Load(configs, provider, forceRefresh, contextUser);
43
+ }
44
+
45
+ /** The default theme's public projection: its PUBLISHED design (never the draft), seeds and logos made safe. */
46
+ public GetPublicLoginScreen(): PublicLoginScreen {
47
+ const theme = this.GetConfigData<MJThemeEntity>('_defaultThemes')[0];
48
+ return theme ? PublicLoginScreenFromTheme(theme) : EMPTY_PUBLIC_LOGIN_SCREEN;
49
+ }
50
+ }
package/src/auth/index.ts CHANGED
@@ -2,7 +2,7 @@ import { JwtHeader, SigningKeyCallback, JwtPayload } from 'jsonwebtoken';
2
2
  import { configInfo } from '../config.js';
3
3
  import { UserCache } from '@memberjunction/generic-database-provider';
4
4
  import sql from 'mssql';
5
- import { DatabaseProviderBase, Metadata, RoleInfo, UserInfo } from '@memberjunction/core';
5
+ import { DatabaseProviderBase, LogError, Metadata, RoleInfo, UserInfo } from '@memberjunction/core';
6
6
  import { NewUserBase } from './newUsers.js';
7
7
  import { MJGlobal } from '@memberjunction/global';
8
8
  import { MJUserEntity, MJUserEntityType } from '@memberjunction/core-entities';
@@ -13,6 +13,7 @@ export * from './APIKeyScopeAuth.js';
13
13
  export * from './scopeLimitedPrincipal.js';
14
14
  export * from './actingContextResolver.js';
15
15
  export * from './AuthProviderEngine.js';
16
+ export * from './LoginScreenEngine.js';
16
17
  export * from './AuthProviderCatalogRouter.js';
17
18
  export { InitializeAuthProviders, initializeAuthProviders, InitializeAuthProvidersFromMetadata, initializeAuthProvidersFromMetadata, RefreshAuthProviders, refreshAuthProviders, ValidateAuthProvidersRegistered, validateAuthProvidersRegistered } from './initializeProviders.js';
18
19
 
@@ -253,11 +254,63 @@ export const VerifyUserRecord = async (
253
254
  ): Promise<UserInfo | undefined> => {
254
255
  if (!email) return undefined;
255
256
 
256
- // FindUser, not Users.find: a user this process has not loaded yet (created seconds ago on
257
- // another server) is looked up in the database instead of being treated as nonexistent.
258
- let user = await UserCache.Instance.FindUser({ Email: email });
257
+ // Collect ALL matches rather than taking .find()'s first hit. Two User rows can share an email
258
+ // case-insensitively (see the duplicate-provisioning path below), and .find() then resolved to
259
+ // whichever row happened to sit earlier in UserCache.Instance.Users — i.e. database row order.
260
+ // That order changes when the cache is rebuilt, so an MJAPI restart silently moved a user onto a
261
+ // different record: their conversations, artifacts, items shared with them and their profile
262
+ // picture (UserImageURL lives on the User row) all vanished at once, and came back if the order
263
+ // flipped again. Observed in production 2026-09-15. Resolution must not depend on row order.
264
+ const emailMatches = UserCache.Instance.Users.filter((u) => {
265
+ if (!u.Email || u.Email.trim() === '') {
266
+ // this condition should never occur. If it doesn throw a console error including the user id
267
+ // DB requires non-null but this is just an extra check and we could in theory have a blank string in the DB
268
+ console.error(`SYSTEM METADATA ISSUE: User ${u.ID} has no email address`);
269
+ return false;
270
+ } else return u.Email.toLowerCase().trim() === email.toLowerCase().trim();
271
+ });
272
+
273
+ if (emailMatches.length > 1) {
274
+ // Deterministic tie-break by ID so every process and every restart agrees, and a LOUD error
275
+ // because this is a data problem an operator has to resolve — silently picking a row is what
276
+ // made it look like data loss to the customer. Sorting by ID is arbitrary but stable; the point
277
+ // is that it never changes, not that it picks the "right" one.
278
+ emailMatches.sort((a, b) => a.ID.localeCompare(b.ID));
279
+ LogError(
280
+ `AMBIGUOUS LOGIN: ${emailMatches.length} User records share the email '${email}' ` +
281
+ `(case-insensitively): ${emailMatches.map((u) => `${u.ID} (${u.Email})`).join(', ')}. ` +
282
+ `Resolving to ${emailMatches[0].ID} by stable ID order. Until the duplicates are merged, ` +
283
+ `content owned by the other records is invisible to this login. Find every affected user ` +
284
+ `with: SELECT LOWER(Email), COUNT(*) FROM __mj.[User] GROUP BY LOWER(Email) HAVING COUNT(*) > 1`
285
+ );
286
+ }
287
+
288
+ // Nothing cached: ask FindUser, which reads the database for a user this process has not loaded
289
+ // yet (created seconds ago on another server) instead of treating them as nonexistent.
290
+ let user = emailMatches[0] ?? (await UserCache.Instance.FindUser({ Email: email }));
259
291
 
260
292
  if (!user) {
293
+ // REFRESH THE CACHE BEFORE PROVISIONING. This block used to sit AFTER the auto-create below,
294
+ // gated on `!user`, so it could only ever run when creation had already failed or was not
295
+ // attempted. That made it dead code in the exact case it exists to handle: a user who IS in the
296
+ // database but is NOT yet in this process's UserCache. Users provisioned out of band (an admin,
297
+ // an invite, a direct insert) are absent from the cache until it is rebuilt, so the lookup above
298
+ // missed and auto-create minted a SECOND record for someone who already had one — which is how
299
+ // the duplicate emails that Fix 1 above has to tolerate get created in the first place.
300
+ // Observed in production: three users created 2026-09-14 18:18, a duplicate for one of them
301
+ // created 2026-09-15 01:38 on that user's next sign-in.
302
+ //
303
+ // The recursive call passes attemptCacheUpdateIfNeeded=false, so the second pass skips straight
304
+ // to auto-create if the refreshed cache still has no match. Auto-provisioning of genuinely new
305
+ // users is therefore unchanged — it just no longer runs before we have looked properly.
306
+ if (configInfo.userHandling.updateCacheWhenNotFound && dataSource && attemptCacheUpdateIfNeeded) {
307
+ console.warn(`User ${email} not found in cache. Updating cache in attempt to find the user...`);
308
+
309
+ await refreshUserCache();
310
+
311
+ return VerifyUserRecord(email, firstName, lastName, requestDomain, dataSource, false);
312
+ }
313
+
261
314
  // NOTE: `requestDomain` (parsed from the spoofable `Origin` header) is deliberately NOT part of
262
315
  // this condition. It was previously required here, which meant a non-browser client sending no
263
316
  // Origin could never auto-provision while an attacker simply forged one — it gated entry without
@@ -312,14 +365,6 @@ export const VerifyUserRecord = async (
312
365
  }
313
366
  }
314
367
 
315
- if (!user && configInfo.userHandling.updateCacheWhenNotFound && dataSource && attemptCacheUpdateIfNeeded) {
316
- // if we get here that means in the above, if we were attempting to create a new user, it did not work, or it wasn't attempted and we have a config that asks us to auto update the cache
317
- console.warn(`User ${email} not found in cache. Updating cache in attempt to find the user...`);
318
-
319
- await refreshUserCache();
320
-
321
- return VerifyUserRecord(email, firstName, lastName, requestDomain, dataSource, false); // try one more time but do not update cache next time if not found
322
- }
323
368
  }
324
369
 
325
370
  return user;
@@ -1,8 +1,35 @@
1
1
  import { configInfo } from '../config.js';
2
2
  import { AuthProviderConfig, LogError, LogStatus, LogStatusEx, UserInfo, type IMetadataProvider } from '@memberjunction/core';
3
- import { AuthProviderFactory } from '@memberjunction/auth-providers';
3
+ import { AuthProviderFactory, LocalDevProvider } from '@memberjunction/auth-providers';
4
4
  import { AuthProviderEngine } from './AuthProviderEngine.js';
5
5
 
6
+ /**
7
+ * Returns true when local development auth is enabled via `MJ_DEV_AUTH_ENABLED=true`
8
+ * or `configInfo.devAuth?.enabled === true`.
9
+ */
10
+ export function IsLocalDevAuthEnabled(env: NodeJS.ProcessEnv = process.env): boolean {
11
+ const rawEnv = env.MJ_DEV_AUTH_ENABLED?.trim().toLowerCase();
12
+ if (rawEnv === 'true' || rawEnv === '1') {
13
+ return true;
14
+ }
15
+ if (rawEnv === 'false' || rawEnv === '0') {
16
+ return false;
17
+ }
18
+ return configInfo?.devAuth?.enabled === true;
19
+ }
20
+
21
+ /**
22
+ * Enforces the production safety invariant: throws a fatal error if local dev auth
23
+ * is enabled while `NODE_ENV === 'production'`.
24
+ */
25
+ export function AssertLocalDevAuthAllowed(env: NodeJS.ProcessEnv = process.env): void {
26
+ if (IsLocalDevAuthEnabled(env) && env.NODE_ENV?.trim().toLowerCase() === 'production') {
27
+ throw new Error(
28
+ '[SECURITY] Local dev auth (MJ_DEV_AUTH_ENABLED) is strictly forbidden when NODE_ENV=production. Refusing to start.'
29
+ );
30
+ }
31
+ }
32
+
6
33
  /**
7
34
  * Initialize authentication providers from configuration.
8
35
  *
@@ -15,6 +42,8 @@ import { AuthProviderEngine } from './AuthProviderEngine.js';
15
42
  * connection and a system user exist.
16
43
  */
17
44
  export function InitializeAuthProviders(): void {
45
+ AssertLocalDevAuthAllowed();
46
+
18
47
  const factory = AuthProviderFactory.Instance;
19
48
 
20
49
  // Clear any existing providers
@@ -40,6 +69,19 @@ export function InitializeAuthProviders(): void {
40
69
  }
41
70
  }
42
71
 
72
+ if (IsLocalDevAuthEnabled()) {
73
+ configInfo.authProviders = configInfo.authProviders ?? [];
74
+ if (!configInfo.authProviders.some((p) => p.type === 'local' || p.name === 'local')) {
75
+ const localConfig = LocalDevProvider.ConfigFromEnvironment({
76
+ ...process.env,
77
+ MJ_DEV_AUTH_ENABLED: 'true',
78
+ });
79
+ if (localConfig) {
80
+ configInfo.authProviders.push(localConfig);
81
+ }
82
+ }
83
+ }
84
+
43
85
  // Initialize providers from authProviders config
44
86
  if (configInfo.authProviders && configInfo.authProviders.length > 0) {
45
87
  for (const providerConfig of configInfo.authProviders) {