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

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 (543) hide show
  1. package/README.md +20 -0
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/agentSessions/BridgeHostInstance.d.ts +25 -0
  4. package/dist/agentSessions/BridgeHostInstance.d.ts.map +1 -0
  5. package/dist/agentSessions/BridgeHostInstance.js +30 -0
  6. package/dist/agentSessions/BridgeHostInstance.js.map +1 -0
  7. package/dist/agentSessions/HostInstance.d.ts +75 -11
  8. package/dist/agentSessions/HostInstance.d.ts.map +1 -1
  9. package/dist/agentSessions/HostInstance.js +99 -28
  10. package/dist/agentSessions/HostInstance.js.map +1 -1
  11. package/dist/agentSessions/ReturningVisitorRecap.d.ts.map +1 -1
  12. package/dist/agentSessions/ReturningVisitorRecap.js +7 -3
  13. package/dist/agentSessions/ReturningVisitorRecap.js.map +1 -1
  14. package/dist/agentSessions/SessionJanitor.d.ts +236 -27
  15. package/dist/agentSessions/SessionJanitor.d.ts.map +1 -1
  16. package/dist/agentSessions/SessionJanitor.js +682 -54
  17. package/dist/agentSessions/SessionJanitor.js.map +1 -1
  18. package/dist/agentSessions/SessionManager.d.ts +48 -3
  19. package/dist/agentSessions/SessionManager.d.ts.map +1 -1
  20. package/dist/agentSessions/SessionManager.js +112 -9
  21. package/dist/agentSessions/SessionManager.js.map +1 -1
  22. package/dist/agentSessions/SessionRunIDVerifier.d.ts +63 -0
  23. package/dist/agentSessions/SessionRunIDVerifier.d.ts.map +1 -0
  24. package/dist/agentSessions/SessionRunIDVerifier.js +129 -0
  25. package/dist/agentSessions/SessionRunIDVerifier.js.map +1 -0
  26. package/dist/agentSessions/index.d.ts +2 -0
  27. package/dist/agentSessions/index.d.ts.map +1 -1
  28. package/dist/agentSessions/index.js +10 -3
  29. package/dist/agentSessions/index.js.map +1 -1
  30. package/dist/apiRoot.d.ts +32 -0
  31. package/dist/apiRoot.d.ts.map +1 -0
  32. package/dist/apiRoot.js +67 -0
  33. package/dist/apiRoot.js.map +1 -0
  34. package/dist/auth/AuthProviderCatalogRouter.d.ts.map +1 -1
  35. package/dist/auth/AuthProviderCatalogRouter.js +25 -0
  36. package/dist/auth/AuthProviderCatalogRouter.js.map +1 -1
  37. package/dist/auth/LoginScreenEngine.d.ts +22 -0
  38. package/dist/auth/LoginScreenEngine.d.ts.map +1 -0
  39. package/dist/auth/LoginScreenEngine.js +57 -0
  40. package/dist/auth/LoginScreenEngine.js.map +1 -0
  41. package/dist/auth/actionAuthorization.d.ts +40 -0
  42. package/dist/auth/actionAuthorization.d.ts.map +1 -0
  43. package/dist/auth/actionAuthorization.js +94 -0
  44. package/dist/auth/actionAuthorization.js.map +1 -0
  45. package/dist/auth/index.d.ts +1 -0
  46. package/dist/auth/index.d.ts.map +1 -1
  47. package/dist/auth/index.js +4 -10
  48. package/dist/auth/index.js.map +1 -1
  49. package/dist/auth/magicLink/MagicLinkRouter.d.ts.map +1 -1
  50. package/dist/auth/magicLink/MagicLinkRouter.js +3 -2
  51. package/dist/auth/magicLink/MagicLinkRouter.js.map +1 -1
  52. package/dist/auth/magicLink/MagicLinkService.d.ts.map +1 -1
  53. package/dist/auth/magicLink/MagicLinkService.js +6 -3
  54. package/dist/auth/magicLink/MagicLinkService.js.map +1 -1
  55. package/dist/auth/newUsers.d.ts +10 -0
  56. package/dist/auth/newUsers.d.ts.map +1 -1
  57. package/dist/auth/newUsers.js +80 -11
  58. package/dist/auth/newUsers.js.map +1 -1
  59. package/dist/config.d.ts +2514 -22
  60. package/dist/config.d.ts.map +1 -1
  61. package/dist/config.js +166 -4
  62. package/dist/config.js.map +1 -1
  63. package/dist/context.d.ts +8 -0
  64. package/dist/context.d.ts.map +1 -1
  65. package/dist/context.js +14 -11
  66. package/dist/context.js.map +1 -1
  67. package/dist/coreRoutes.d.ts +29 -0
  68. package/dist/coreRoutes.d.ts.map +1 -0
  69. package/dist/coreRoutes.js +142 -0
  70. package/dist/coreRoutes.js.map +1 -0
  71. package/dist/generated/graphql-schemas/__mj.d.ts +504 -3
  72. package/dist/generated/graphql-schemas/__mj.d.ts.map +1 -1
  73. package/dist/generated/graphql-schemas/__mj.js +2456 -7
  74. package/dist/generated/graphql-schemas/__mj.js.map +1 -1
  75. package/dist/generic/CacheInvalidationResolver.d.ts +43 -8
  76. package/dist/generic/CacheInvalidationResolver.d.ts.map +1 -1
  77. package/dist/generic/CacheInvalidationResolver.js +59 -19
  78. package/dist/generic/CacheInvalidationResolver.js.map +1 -1
  79. package/dist/generic/OrphanedConversationDetailReconciler.js +3 -3
  80. package/dist/generic/OrphanedConversationDetailReconciler.js.map +1 -1
  81. package/dist/generic/PushStatusResolver.js +1 -1
  82. package/dist/generic/PushStatusResolver.js.map +1 -1
  83. package/dist/generic/ResolverBase.d.ts +123 -48
  84. package/dist/generic/ResolverBase.d.ts.map +1 -1
  85. package/dist/generic/ResolverBase.js +293 -305
  86. package/dist/generic/ResolverBase.js.map +1 -1
  87. package/dist/generic/RunViewResolver.d.ts.map +1 -1
  88. package/dist/generic/RunViewResolver.js +16 -0
  89. package/dist/generic/RunViewResolver.js.map +1 -1
  90. package/dist/globalCors.d.ts +33 -0
  91. package/dist/globalCors.d.ts.map +1 -0
  92. package/dist/globalCors.js +58 -0
  93. package/dist/globalCors.js.map +1 -0
  94. package/dist/index.d.ts +17 -0
  95. package/dist/index.d.ts.map +1 -1
  96. package/dist/index.js +219 -278
  97. package/dist/index.js.map +1 -1
  98. package/dist/isolatedProvider.d.ts +20 -0
  99. package/dist/isolatedProvider.d.ts.map +1 -0
  100. package/dist/isolatedProvider.js +22 -0
  101. package/dist/isolatedProvider.js.map +1 -0
  102. package/dist/multiTenancy/index.d.ts.map +1 -1
  103. package/dist/multiTenancy/index.js +22 -2
  104. package/dist/multiTenancy/index.js.map +1 -1
  105. package/dist/realtimeProxy/RealtimeProxyServer.d.ts +44 -4
  106. package/dist/realtimeProxy/RealtimeProxyServer.d.ts.map +1 -1
  107. package/dist/realtimeProxy/RealtimeProxyServer.js +121 -16
  108. package/dist/realtimeProxy/RealtimeProxyServer.js.map +1 -1
  109. package/dist/realtimeProxy/RealtimeRelayTunnel.d.ts +171 -0
  110. package/dist/realtimeProxy/RealtimeRelayTunnel.d.ts.map +1 -0
  111. package/dist/realtimeProxy/RealtimeRelayTunnel.js +532 -0
  112. package/dist/realtimeProxy/RealtimeRelayTunnel.js.map +1 -0
  113. package/dist/realtimeSessions/RealtimeSessionEventService.d.ts +148 -0
  114. package/dist/realtimeSessions/RealtimeSessionEventService.d.ts.map +1 -0
  115. package/dist/realtimeSessions/RealtimeSessionEventService.js +191 -0
  116. package/dist/realtimeSessions/RealtimeSessionEventService.js.map +1 -0
  117. package/dist/realtimeSessions/RealtimeSessionVerificationService.d.ts +66 -0
  118. package/dist/realtimeSessions/RealtimeSessionVerificationService.d.ts.map +1 -0
  119. package/dist/realtimeSessions/RealtimeSessionVerificationService.js +139 -0
  120. package/dist/realtimeSessions/RealtimeSessionVerificationService.js.map +1 -0
  121. package/dist/realtimeSessions/RealtimeVerifyRouter.d.ts +38 -0
  122. package/dist/realtimeSessions/RealtimeVerifyRouter.d.ts.map +1 -0
  123. package/dist/realtimeSessions/RealtimeVerifyRouter.js +99 -0
  124. package/dist/realtimeSessions/RealtimeVerifyRouter.js.map +1 -0
  125. package/dist/realtimeSessions/RecordingAssemblyScheduler.d.ts +100 -0
  126. package/dist/realtimeSessions/RecordingAssemblyScheduler.d.ts.map +1 -0
  127. package/dist/realtimeSessions/RecordingAssemblyScheduler.js +173 -0
  128. package/dist/realtimeSessions/RecordingAssemblyScheduler.js.map +1 -0
  129. package/dist/realtimeSessions/SessionVerificationPortsBase.d.ts +61 -0
  130. package/dist/realtimeSessions/SessionVerificationPortsBase.d.ts.map +1 -0
  131. package/dist/realtimeSessions/SessionVerificationPortsBase.js +149 -0
  132. package/dist/realtimeSessions/SessionVerificationPortsBase.js.map +1 -0
  133. package/dist/realtimeSessions/SlidingWindowRateLimiter.d.ts +57 -0
  134. package/dist/realtimeSessions/SlidingWindowRateLimiter.d.ts.map +1 -0
  135. package/dist/realtimeSessions/SlidingWindowRateLimiter.js +69 -0
  136. package/dist/realtimeSessions/SlidingWindowRateLimiter.js.map +1 -0
  137. package/dist/realtimeSessions/index.d.ts +19 -0
  138. package/dist/realtimeSessions/index.d.ts.map +1 -0
  139. package/dist/realtimeSessions/index.js +19 -0
  140. package/dist/realtimeSessions/index.js.map +1 -0
  141. package/dist/realtimeSessions/ownedRealtimeSession.d.ts +30 -0
  142. package/dist/realtimeSessions/ownedRealtimeSession.d.ts.map +1 -0
  143. package/dist/realtimeSessions/ownedRealtimeSession.js +47 -0
  144. package/dist/realtimeSessions/ownedRealtimeSession.js.map +1 -0
  145. package/dist/realtimeSessions/sessionAccess.d.ts +92 -0
  146. package/dist/realtimeSessions/sessionAccess.d.ts.map +1 -0
  147. package/dist/realtimeSessions/sessionAccess.js +94 -0
  148. package/dist/realtimeSessions/sessionAccess.js.map +1 -0
  149. package/dist/realtimeSessions/sessionConfigStamps.d.ts +70 -0
  150. package/dist/realtimeSessions/sessionConfigStamps.d.ts.map +1 -0
  151. package/dist/realtimeSessions/sessionConfigStamps.js +93 -0
  152. package/dist/realtimeSessions/sessionConfigStamps.js.map +1 -0
  153. package/dist/realtimeSessions/subscriptionAuthorization.d.ts +65 -0
  154. package/dist/realtimeSessions/subscriptionAuthorization.d.ts.map +1 -0
  155. package/dist/realtimeSessions/subscriptionAuthorization.js +71 -0
  156. package/dist/realtimeSessions/subscriptionAuthorization.js.map +1 -0
  157. package/dist/realtimeSessions/verificationCore.d.ts +243 -0
  158. package/dist/realtimeSessions/verificationCore.d.ts.map +1 -0
  159. package/dist/realtimeSessions/verificationCore.js +356 -0
  160. package/dist/realtimeSessions/verificationCore.js.map +1 -0
  161. package/dist/realtimeSessions/verificationPages.d.ts +66 -0
  162. package/dist/realtimeSessions/verificationPages.d.ts.map +1 -0
  163. package/dist/realtimeSessions/verificationPages.js +110 -0
  164. package/dist/realtimeSessions/verificationPages.js.map +1 -0
  165. package/dist/realtimeSessions/verificationPolicy.d.ts +147 -0
  166. package/dist/realtimeSessions/verificationPolicy.d.ts.map +1 -0
  167. package/dist/realtimeSessions/verificationPolicy.js +249 -0
  168. package/dist/realtimeSessions/verificationPolicy.js.map +1 -0
  169. package/dist/realtimeSessions/verificationWorkflow.d.ts +263 -0
  170. package/dist/realtimeSessions/verificationWorkflow.d.ts.map +1 -0
  171. package/dist/realtimeSessions/verificationWorkflow.js +435 -0
  172. package/dist/realtimeSessions/verificationWorkflow.js.map +1 -0
  173. package/dist/realtimeWidget/widgetGuestElevation.d.ts +20 -2
  174. package/dist/realtimeWidget/widgetGuestElevation.d.ts.map +1 -1
  175. package/dist/realtimeWidget/widgetGuestElevation.js +31 -2
  176. package/dist/realtimeWidget/widgetGuestElevation.js.map +1 -1
  177. package/dist/resolvers/ActionResolver.d.ts +31 -5
  178. package/dist/resolvers/ActionResolver.d.ts.map +1 -1
  179. package/dist/resolvers/ActionResolver.js +75 -14
  180. package/dist/resolvers/ActionResolver.js.map +1 -1
  181. package/dist/resolvers/AdhocQueryResolver.d.ts +14 -1
  182. package/dist/resolvers/AdhocQueryResolver.d.ts.map +1 -1
  183. package/dist/resolvers/AdhocQueryResolver.js +21 -5
  184. package/dist/resolvers/AdhocQueryResolver.js.map +1 -1
  185. package/dist/resolvers/ArtifactFileResolver.d.ts +5 -1
  186. package/dist/resolvers/ArtifactFileResolver.d.ts.map +1 -1
  187. package/dist/resolvers/ArtifactFileResolver.js +9 -7
  188. package/dist/resolvers/ArtifactFileResolver.js.map +1 -1
  189. package/dist/resolvers/CacheStatsResolver.d.ts +27 -0
  190. package/dist/resolvers/CacheStatsResolver.d.ts.map +1 -1
  191. package/dist/resolvers/CacheStatsResolver.js +113 -2
  192. package/dist/resolvers/CacheStatsResolver.js.map +1 -1
  193. package/dist/resolvers/ClientToolRequestResolver.d.ts +4 -2
  194. package/dist/resolvers/ClientToolRequestResolver.d.ts.map +1 -1
  195. package/dist/resolvers/ClientToolRequestResolver.js +28 -10
  196. package/dist/resolvers/ClientToolRequestResolver.js.map +1 -1
  197. package/dist/resolvers/ConversationRunEventsResolver.d.ts +8 -4
  198. package/dist/resolvers/ConversationRunEventsResolver.d.ts.map +1 -1
  199. package/dist/resolvers/ConversationRunEventsResolver.js +6 -6
  200. package/dist/resolvers/ConversationRunEventsResolver.js.map +1 -1
  201. package/dist/resolvers/DatasetResolver.d.ts +24 -3
  202. package/dist/resolvers/DatasetResolver.d.ts.map +1 -1
  203. package/dist/resolvers/DatasetResolver.js +57 -8
  204. package/dist/resolvers/DatasetResolver.js.map +1 -1
  205. package/dist/resolvers/EntityRecordNameResolver.d.ts +2 -1
  206. package/dist/resolvers/EntityRecordNameResolver.d.ts.map +1 -1
  207. package/dist/resolvers/EntityRecordNameResolver.js +3 -2
  208. package/dist/resolvers/EntityRecordNameResolver.js.map +1 -1
  209. package/dist/resolvers/FetchEntityVectorsResolver.d.ts +27 -1
  210. package/dist/resolvers/FetchEntityVectorsResolver.d.ts.map +1 -1
  211. package/dist/resolvers/FetchEntityVectorsResolver.js +148 -2
  212. package/dist/resolvers/FetchEntityVectorsResolver.js.map +1 -1
  213. package/dist/resolvers/FileResolver.d.ts +82 -11
  214. package/dist/resolvers/FileResolver.d.ts.map +1 -1
  215. package/dist/resolvers/FileResolver.js +279 -101
  216. package/dist/resolvers/FileResolver.js.map +1 -1
  217. package/dist/resolvers/GetDataContextDataResolver.d.ts +33 -7
  218. package/dist/resolvers/GetDataContextDataResolver.d.ts.map +1 -1
  219. package/dist/resolvers/GetDataContextDataResolver.js +117 -38
  220. package/dist/resolvers/GetDataContextDataResolver.js.map +1 -1
  221. package/dist/resolvers/GetDataResolver.d.ts.map +1 -1
  222. package/dist/resolvers/GetDataResolver.js +6 -3
  223. package/dist/resolvers/GetDataResolver.js.map +1 -1
  224. package/dist/resolvers/HumanHandoffResolver.d.ts.map +1 -1
  225. package/dist/resolvers/HumanHandoffResolver.js +7 -1
  226. package/dist/resolvers/HumanHandoffResolver.js.map +1 -1
  227. package/dist/resolvers/IntegrationDiscoveryResolver.d.ts.map +1 -1
  228. package/dist/resolvers/IntegrationDiscoveryResolver.js +4 -2
  229. package/dist/resolvers/IntegrationDiscoveryResolver.js.map +1 -1
  230. package/dist/resolvers/MCPResolver.d.ts.map +1 -1
  231. package/dist/resolvers/MCPResolver.js +9 -4
  232. package/dist/resolvers/MCPResolver.js.map +1 -1
  233. package/dist/resolvers/QueryResolver.d.ts +2 -0
  234. package/dist/resolvers/QueryResolver.d.ts.map +1 -1
  235. package/dist/resolvers/QueryResolver.js +13 -0
  236. package/dist/resolvers/QueryResolver.js.map +1 -1
  237. package/dist/resolvers/RealtimeBridgeResolver.d.ts +54 -2
  238. package/dist/resolvers/RealtimeBridgeResolver.d.ts.map +1 -1
  239. package/dist/resolvers/RealtimeBridgeResolver.js +155 -10
  240. package/dist/resolvers/RealtimeBridgeResolver.js.map +1 -1
  241. package/dist/resolvers/RealtimeClientSessionResolver.d.ts +157 -33
  242. package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
  243. package/dist/resolvers/RealtimeClientSessionResolver.js +404 -116
  244. package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
  245. package/dist/resolvers/RealtimeSessionEventsResolver.d.ts +61 -0
  246. package/dist/resolvers/RealtimeSessionEventsResolver.d.ts.map +1 -0
  247. package/dist/resolvers/RealtimeSessionEventsResolver.js +130 -0
  248. package/dist/resolvers/RealtimeSessionEventsResolver.js.map +1 -0
  249. package/dist/resolvers/RealtimeSessionVerificationResolver.d.ts +85 -0
  250. package/dist/resolvers/RealtimeSessionVerificationResolver.d.ts.map +1 -0
  251. package/dist/resolvers/RealtimeSessionVerificationResolver.js +188 -0
  252. package/dist/resolvers/RealtimeSessionVerificationResolver.js.map +1 -0
  253. package/dist/resolvers/RemoteBrowserActionResolver.d.ts +2 -0
  254. package/dist/resolvers/RemoteBrowserActionResolver.d.ts.map +1 -1
  255. package/dist/resolvers/RemoteBrowserActionResolver.js +5 -1
  256. package/dist/resolvers/RemoteBrowserActionResolver.js.map +1 -1
  257. package/dist/resolvers/RunAIAgentResolver.d.ts +10 -0
  258. package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
  259. package/dist/resolvers/RunAIAgentResolver.js +100 -14
  260. package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
  261. package/dist/resolvers/RunTemplateResolver.d.ts.map +1 -1
  262. package/dist/resolvers/RunTemplateResolver.js +12 -11
  263. package/dist/resolvers/RunTemplateResolver.js.map +1 -1
  264. package/dist/resolvers/SearchKnowledgeStreamResolver.d.ts +12 -1
  265. package/dist/resolvers/SearchKnowledgeStreamResolver.d.ts.map +1 -1
  266. package/dist/resolvers/SearchKnowledgeStreamResolver.js +15 -2
  267. package/dist/resolvers/SearchKnowledgeStreamResolver.js.map +1 -1
  268. package/dist/resolvers/SqlLoggingConfigResolver.d.ts.map +1 -1
  269. package/dist/resolvers/SqlLoggingConfigResolver.js +2 -3
  270. package/dist/resolvers/SqlLoggingConfigResolver.js.map +1 -1
  271. package/dist/resolvers/SyncDataResolver.d.ts.map +1 -1
  272. package/dist/resolvers/SyncDataResolver.js +6 -2
  273. package/dist/resolvers/SyncDataResolver.js.map +1 -1
  274. package/dist/resolvers/SyncRolesUsersResolver.d.ts +2 -0
  275. package/dist/resolvers/SyncRolesUsersResolver.d.ts.map +1 -1
  276. package/dist/resolvers/SyncRolesUsersResolver.js +23 -6
  277. package/dist/resolvers/SyncRolesUsersResolver.js.map +1 -1
  278. package/dist/resolvers/TaskGraphFrameResolver.d.ts +2 -1
  279. package/dist/resolvers/TaskGraphFrameResolver.d.ts.map +1 -1
  280. package/dist/resolvers/TaskGraphFrameResolver.js +28 -1
  281. package/dist/resolvers/TaskGraphFrameResolver.js.map +1 -1
  282. package/dist/resolvers/TestQuerySQLResolver.d.ts +24 -0
  283. package/dist/resolvers/TestQuerySQLResolver.d.ts.map +1 -1
  284. package/dist/resolvers/TestQuerySQLResolver.js +65 -13
  285. package/dist/resolvers/TestQuerySQLResolver.js.map +1 -1
  286. package/dist/resolvers/TransactionGroupResolver.d.ts +19 -2
  287. package/dist/resolvers/TransactionGroupResolver.d.ts.map +1 -1
  288. package/dist/resolvers/TransactionGroupResolver.js +102 -24
  289. package/dist/resolvers/TransactionGroupResolver.js.map +1 -1
  290. package/dist/resolvers/UserAvatarResolver.d.ts +16 -0
  291. package/dist/resolvers/UserAvatarResolver.d.ts.map +1 -0
  292. package/dist/resolvers/UserAvatarResolver.js +124 -0
  293. package/dist/resolvers/UserAvatarResolver.js.map +1 -0
  294. package/dist/resolvers/UserResolver.d.ts.map +1 -1
  295. package/dist/resolvers/UserResolver.js +2 -17
  296. package/dist/resolvers/UserResolver.js.map +1 -1
  297. package/dist/resolvers/agent-run-data-guard.d.ts +31 -0
  298. package/dist/resolvers/agent-run-data-guard.d.ts.map +1 -0
  299. package/dist/resolvers/agent-run-data-guard.js +72 -0
  300. package/dist/resolvers/agent-run-data-guard.js.map +1 -0
  301. package/dist/resolvers/agentVisionConsentAudit.d.ts +37 -0
  302. package/dist/resolvers/agentVisionConsentAudit.d.ts.map +1 -0
  303. package/dist/resolvers/agentVisionConsentAudit.js +63 -0
  304. package/dist/resolvers/agentVisionConsentAudit.js.map +1 -0
  305. package/dist/resolvers/avatarInputValidation.d.ts +40 -0
  306. package/dist/resolvers/avatarInputValidation.d.ts.map +1 -0
  307. package/dist/resolvers/avatarInputValidation.js +97 -0
  308. package/dist/resolvers/avatarInputValidation.js.map +1 -0
  309. package/dist/resolvers/currentUserRoles.d.ts +29 -0
  310. package/dist/resolvers/currentUserRoles.d.ts.map +1 -1
  311. package/dist/resolvers/currentUserRoles.js +30 -0
  312. package/dist/resolvers/currentUserRoles.js.map +1 -1
  313. package/dist/resolvers/meetings/meetingMutations.d.ts +6 -0
  314. package/dist/resolvers/meetings/meetingMutations.d.ts.map +1 -1
  315. package/dist/resolvers/meetings/meetingMutations.js +21 -0
  316. package/dist/resolvers/meetings/meetingMutations.js.map +1 -1
  317. package/dist/rest/RealtimeRecordingHandler.d.ts +49 -0
  318. package/dist/rest/RealtimeRecordingHandler.d.ts.map +1 -0
  319. package/dist/rest/RealtimeRecordingHandler.js +383 -0
  320. package/dist/rest/RealtimeRecordingHandler.js.map +1 -0
  321. package/dist/rest/ViewOperationsHandler.d.ts +3 -1
  322. package/dist/rest/ViewOperationsHandler.d.ts.map +1 -1
  323. package/dist/rest/ViewOperationsHandler.js +21 -12
  324. package/dist/rest/ViewOperationsHandler.js.map +1 -1
  325. package/dist/rest/setupRESTEndpoints.d.ts +6 -0
  326. package/dist/rest/setupRESTEndpoints.d.ts.map +1 -1
  327. package/dist/rest/setupRESTEndpoints.js +6 -0
  328. package/dist/rest/setupRESTEndpoints.js.map +1 -1
  329. package/dist/serverExtensionReservedRoots.d.ts +12 -10
  330. package/dist/serverExtensionReservedRoots.d.ts.map +1 -1
  331. package/dist/serverExtensionReservedRoots.js +14 -17
  332. package/dist/serverExtensionReservedRoots.js.map +1 -1
  333. package/dist/services/MJStorageBlobStore.d.ts +8 -1
  334. package/dist/services/MJStorageBlobStore.d.ts.map +1 -1
  335. package/dist/services/MJStorageBlobStore.js +25 -19
  336. package/dist/services/MJStorageBlobStore.js.map +1 -1
  337. package/dist/services/StartTaskGraphDispatcher.js +2 -2
  338. package/dist/services/StartTaskGraphDispatcher.js.map +1 -1
  339. package/dist/services/TaskGraphActionRunner.d.ts +5 -3
  340. package/dist/services/TaskGraphActionRunner.d.ts.map +1 -1
  341. package/dist/services/TaskGraphActionRunner.js +27 -5
  342. package/dist/services/TaskGraphActionRunner.js.map +1 -1
  343. package/dist/services/TaskGraphAgentRunner.d.ts +14 -2
  344. package/dist/services/TaskGraphAgentRunner.d.ts.map +1 -1
  345. package/dist/services/TaskGraphAgentRunner.js +157 -9
  346. package/dist/services/TaskGraphAgentRunner.js.map +1 -1
  347. package/dist/services/TaskGraphContinuationDeliverer.d.ts +57 -4
  348. package/dist/services/TaskGraphContinuationDeliverer.d.ts.map +1 -1
  349. package/dist/services/TaskGraphContinuationDeliverer.js +607 -18
  350. package/dist/services/TaskGraphContinuationDeliverer.js.map +1 -1
  351. package/dist/sharedCache.d.ts +105 -0
  352. package/dist/sharedCache.d.ts.map +1 -0
  353. package/dist/sharedCache.js +279 -0
  354. package/dist/sharedCache.js.map +1 -0
  355. package/dist/types.d.ts +6 -0
  356. package/dist/types.d.ts.map +1 -1
  357. package/dist/types.js.map +1 -1
  358. package/package.json +99 -96
  359. package/src/__tests__/ActionResolver.authorization.test.ts +353 -0
  360. package/src/__tests__/AdhocQueryResolver.sqlAuthorizer.test.ts +104 -0
  361. package/src/__tests__/BridgeHostInstance.test.ts +232 -0
  362. package/src/__tests__/ClientToolRequestResolver.test.ts +116 -0
  363. package/src/__tests__/DatasetResolver.itemFilters.test.ts +201 -0
  364. package/src/__tests__/EntityRecordNameResolver.rowSecurity.test.ts +152 -0
  365. package/src/__tests__/FetchEntityVectorsResolver.test.ts +433 -0
  366. package/src/__tests__/FileResolver.storageAccess.test.ts +562 -0
  367. package/src/__tests__/GetDataContextDataResolver.sqlItems.test.ts +416 -0
  368. package/src/__tests__/HostInstance.test.ts +84 -0
  369. package/src/__tests__/HumanHandoffResolver.test.ts +17 -0
  370. package/src/__tests__/ListOperationsResolver.adhocScreen.test.ts +137 -0
  371. package/src/__tests__/LoginScreenEngine.test.ts +86 -0
  372. package/src/__tests__/MJStorageBlobStore.storageGate.test.ts +63 -0
  373. package/src/__tests__/MeetingResolver.test.ts +75 -1
  374. package/src/__tests__/RealtimeBridgeResolver.test.ts +415 -6
  375. package/src/__tests__/RealtimeClientSessionResolver.configTamper.test.ts +383 -0
  376. package/src/__tests__/RealtimeClientSessionResolver.test.ts +682 -58
  377. package/src/__tests__/RealtimeProxyServer.test.ts +16 -1
  378. package/src/__tests__/RealtimeRelay.test.ts +876 -0
  379. package/src/__tests__/RecordingAssemblyScheduler.test.ts +178 -0
  380. package/src/__tests__/RemoteBrowserActionResolver.goalRunLink.test.ts +129 -0
  381. package/src/__tests__/ResolverBase.adhocReadScope.test.ts +133 -2
  382. package/src/__tests__/ResolverBase.aggregateScreen.test.ts +174 -0
  383. package/src/__tests__/ResolverBase.balancedClause.test.ts +155 -0
  384. package/src/__tests__/ResolverBase.clauseUnscopedRead.test.ts +127 -0
  385. package/src/__tests__/ResolverBase.clientOldValues.test.ts +212 -6
  386. package/src/__tests__/ResolverBase.filterEscaping.test.ts +5 -2
  387. package/src/__tests__/ReturningVisitorRecap.test.ts +115 -0
  388. package/src/__tests__/RunAIAgentResolver.branch.test.ts +170 -0
  389. package/src/__tests__/RunAIAgentResolver.historyFrom.test.ts +6 -4
  390. package/src/__tests__/RunAIAgentResolver.runDataGuard.test.ts +258 -0
  391. package/src/__tests__/RunAIAgentResolver.stoppedPredecessor.test.ts +166 -0
  392. package/src/__tests__/RunTemplateResolver.test.ts +132 -0
  393. package/src/__tests__/RunViewResolver.cacheCheckForwarding.test.ts +63 -0
  394. package/src/__tests__/RunViewResolver.cacheCheckScreen.test.ts +165 -0
  395. package/src/__tests__/SearchKnowledgeStreamResolver.test.ts +161 -0
  396. package/src/__tests__/SessionJanitor.test.ts +1203 -21
  397. package/src/__tests__/SessionManager.test.ts +240 -17
  398. package/src/__tests__/SessionRunIDVerifier.test.ts +251 -0
  399. package/src/__tests__/SyncRolesUsersResolver.userRoles.test.ts +97 -0
  400. package/src/__tests__/TaskGraphActionRunner.durablePayload.test.ts +25 -0
  401. package/src/__tests__/TaskGraphAgentRunner.test.ts +266 -0
  402. package/src/__tests__/TaskGraphContinuationDeliverer.test.ts +403 -22
  403. package/src/__tests__/TaskGraphFrameResolver.test.ts +22 -0
  404. package/src/__tests__/TestQuerySQLResolver.test.ts +274 -0
  405. package/src/__tests__/TransactionGroupResolver.refusals.test.ts +98 -1
  406. package/src/__tests__/UpdateMJDataContextItem.oldValues.test.ts +220 -0
  407. package/src/__tests__/UserAvatarResolver.test.ts +255 -0
  408. package/src/__tests__/UserResolver.currentUser.test.ts +16 -1
  409. package/src/__tests__/ViewOperationsHandler.clauseScreen.test.ts +157 -0
  410. package/src/__tests__/actionAuthorization.test.ts +130 -0
  411. package/src/__tests__/agent-run-data-guard.test.ts +130 -0
  412. package/src/__tests__/agentVisionConsentAudit.test.ts +118 -0
  413. package/src/__tests__/apiRootBoot.test.ts +202 -0
  414. package/src/__tests__/avatarInputValidation.test.ts +160 -0
  415. package/src/__tests__/cacheInvalidationRecordData.test.ts +64 -0
  416. package/src/__tests__/conversationRunEvents.test.ts +56 -14
  417. package/src/__tests__/globalCors.test.ts +217 -0
  418. package/src/__tests__/isolatedProviderTransactions.test.ts +169 -0
  419. package/src/__tests__/magicLinkService.consume.test.ts +6 -0
  420. package/src/__tests__/magicLinkService.provisionLog.test.ts +5 -0
  421. package/src/__tests__/multiTenancy.postgresRewrite.test.ts +181 -0
  422. package/src/__tests__/multiTenancy.security.test.ts +51 -0
  423. package/src/__tests__/multiTenancy.test.ts +1 -1
  424. package/src/__tests__/newUsers.template.test.ts +151 -0
  425. package/src/__tests__/newUsers.test.ts +74 -5
  426. package/src/__tests__/orphanedConversationDetailReconciler.test.ts +17 -2
  427. package/src/__tests__/ownedRealtimeSession.test.ts +39 -0
  428. package/src/__tests__/pushStatusResolver.filter.test.ts +7 -0
  429. package/src/__tests__/realtimeRecordingHandler.test.ts +652 -0
  430. package/src/__tests__/realtimeSessions/RealtimeSessionEventService.test.ts +201 -0
  431. package/src/__tests__/realtimeSessions/RealtimeSessionEventsResolver.test.ts +215 -0
  432. package/src/__tests__/realtimeSessions/RealtimeSessionVerificationResolver.test.ts +102 -0
  433. package/src/__tests__/realtimeSessions/RealtimeSessionVerificationService.test.ts +349 -0
  434. package/src/__tests__/realtimeSessions/RealtimeVerifyRouter.test.ts +131 -0
  435. package/src/__tests__/realtimeSessions/SlidingWindowRateLimiter.test.ts +56 -0
  436. package/src/__tests__/realtimeSessions/helpers.ts +4 -0
  437. package/src/__tests__/realtimeSessions/sessionAccess.test.ts +129 -0
  438. package/src/__tests__/realtimeSessions/sessionConfigStamps.test.ts +124 -0
  439. package/src/__tests__/realtimeSessions/verificationCore.test.ts +355 -0
  440. package/src/__tests__/realtimeSessions/verificationPages.test.ts +84 -0
  441. package/src/__tests__/realtimeSessions/verificationPolicy.test.ts +226 -0
  442. package/src/__tests__/realtimeSessions/verificationWorkflow.test.ts +633 -0
  443. package/src/__tests__/resolverBase.fls.test.ts +87 -4
  444. package/src/__tests__/serverExtensionHostOverlay.test.ts +66 -0
  445. package/src/__tests__/serverExtensionReservedRoots.test.ts +11 -96
  446. package/src/__tests__/sharedCache.test.ts +312 -0
  447. package/src/__tests__/widgetGuestElevation.test.ts +44 -0
  448. package/src/agentSessions/BridgeHostInstance.ts +32 -0
  449. package/src/agentSessions/HostInstance.ts +124 -28
  450. package/src/agentSessions/ReturningVisitorRecap.ts +7 -3
  451. package/src/agentSessions/SessionJanitor.ts +821 -59
  452. package/src/agentSessions/SessionManager.ts +138 -26
  453. package/src/agentSessions/SessionRunIDVerifier.ts +171 -0
  454. package/src/agentSessions/index.ts +10 -3
  455. package/src/apiRoot.ts +78 -0
  456. package/src/auth/AuthProviderCatalogRouter.ts +26 -0
  457. package/src/auth/LoginScreenEngine.ts +50 -0
  458. package/src/auth/actionAuthorization.ts +116 -0
  459. package/src/auth/index.ts +4 -8
  460. package/src/auth/magicLink/MagicLinkRouter.ts +3 -2
  461. package/src/auth/magicLink/MagicLinkService.ts +6 -3
  462. package/src/auth/newUsers.ts +99 -11
  463. package/src/config.ts +171 -5
  464. package/src/context.ts +15 -10
  465. package/src/coreRoutes.ts +166 -0
  466. package/src/generated/graphql-schemas/__mj.ts +1815 -57
  467. package/src/generic/CacheInvalidationResolver.ts +73 -18
  468. package/src/generic/OrphanedConversationDetailReconciler.ts +3 -3
  469. package/src/generic/PushStatusResolver.ts +1 -1
  470. package/src/generic/ResolverBase.ts +335 -326
  471. package/src/generic/RunViewResolver.ts +21 -0
  472. package/src/globalCors.ts +71 -0
  473. package/src/index.ts +231 -300
  474. package/src/isolatedProvider.ts +22 -0
  475. package/src/multiTenancy/index.ts +24 -2
  476. package/src/realtimeProxy/RealtimeProxyServer.ts +148 -16
  477. package/src/realtimeProxy/RealtimeRelayTunnel.ts +645 -0
  478. package/src/realtimeSessions/README.md +179 -0
  479. package/src/realtimeSessions/RealtimeSessionEventService.ts +274 -0
  480. package/src/realtimeSessions/RealtimeSessionVerificationService.ts +168 -0
  481. package/src/realtimeSessions/RealtimeVerifyRouter.ts +109 -0
  482. package/src/realtimeSessions/RecordingAssemblyScheduler.ts +234 -0
  483. package/src/realtimeSessions/SessionVerificationPortsBase.ts +189 -0
  484. package/src/realtimeSessions/SlidingWindowRateLimiter.ts +92 -0
  485. package/src/realtimeSessions/index.ts +18 -0
  486. package/src/realtimeSessions/ownedRealtimeSession.ts +55 -0
  487. package/src/realtimeSessions/sessionAccess.ts +145 -0
  488. package/src/realtimeSessions/sessionConfigStamps.ts +123 -0
  489. package/src/realtimeSessions/subscriptionAuthorization.ts +116 -0
  490. package/src/realtimeSessions/verificationCore.ts +502 -0
  491. package/src/realtimeSessions/verificationPages.ts +149 -0
  492. package/src/realtimeSessions/verificationPolicy.ts +321 -0
  493. package/src/realtimeSessions/verificationWorkflow.ts +702 -0
  494. package/src/realtimeWidget/widgetGuestElevation.ts +34 -2
  495. package/src/resolvers/ActionResolver.ts +84 -21
  496. package/src/resolvers/AdhocQueryResolver.ts +24 -6
  497. package/src/resolvers/ArtifactFileResolver.ts +9 -8
  498. package/src/resolvers/CacheStatsResolver.ts +89 -2
  499. package/src/resolvers/ClientToolRequestResolver.ts +25 -7
  500. package/src/resolvers/ConversationRunEventsResolver.ts +15 -11
  501. package/src/resolvers/DatasetResolver.ts +70 -10
  502. package/src/resolvers/EntityRecordNameResolver.ts +3 -2
  503. package/src/resolvers/FetchEntityVectorsResolver.ts +179 -2
  504. package/src/resolvers/FileResolver.ts +321 -106
  505. package/src/resolvers/GetDataContextDataResolver.ts +139 -41
  506. package/src/resolvers/GetDataResolver.ts +6 -3
  507. package/src/resolvers/HumanHandoffResolver.ts +8 -0
  508. package/src/resolvers/IntegrationDiscoveryResolver.ts +4 -2
  509. package/src/resolvers/MCPResolver.ts +8 -5
  510. package/src/resolvers/QueryResolver.ts +11 -0
  511. package/src/resolvers/RealtimeBridgeResolver.ts +163 -11
  512. package/src/resolvers/RealtimeClientSessionResolver.ts +511 -129
  513. package/src/resolvers/RealtimeSessionEventsResolver.ts +133 -0
  514. package/src/resolvers/RealtimeSessionVerificationResolver.ts +174 -0
  515. package/src/resolvers/RemoteBrowserActionResolver.ts +11 -1
  516. package/src/resolvers/RunAIAgentResolver.ts +116 -14
  517. package/src/resolvers/RunTemplateResolver.ts +13 -12
  518. package/src/resolvers/SearchKnowledgeStreamResolver.ts +19 -3
  519. package/src/resolvers/SqlLoggingConfigResolver.ts +2 -4
  520. package/src/resolvers/SyncDataResolver.ts +6 -2
  521. package/src/resolvers/SyncRolesUsersResolver.ts +24 -6
  522. package/src/resolvers/TaskGraphFrameResolver.ts +33 -1
  523. package/src/resolvers/TestQuerySQLResolver.ts +68 -13
  524. package/src/resolvers/TransactionGroupResolver.ts +131 -27
  525. package/src/resolvers/UserAvatarResolver.ts +111 -0
  526. package/src/resolvers/UserResolver.ts +2 -16
  527. package/src/resolvers/__tests__/GetDataResolver.validation.test.ts +95 -0
  528. package/src/resolvers/agent-run-data-guard.ts +89 -0
  529. package/src/resolvers/agentVisionConsentAudit.ts +82 -0
  530. package/src/resolvers/avatarInputValidation.ts +123 -0
  531. package/src/resolvers/currentUserRoles.ts +32 -1
  532. package/src/resolvers/meetings/meetingMutations.ts +21 -0
  533. package/src/rest/RealtimeRecordingHandler.ts +464 -0
  534. package/src/rest/ViewOperationsHandler.ts +29 -13
  535. package/src/rest/setupRESTEndpoints.ts +6 -0
  536. package/src/serverExtensionReservedRoots.ts +14 -17
  537. package/src/services/MJStorageBlobStore.ts +31 -30
  538. package/src/services/StartTaskGraphDispatcher.ts +2 -2
  539. package/src/services/TaskGraphActionRunner.ts +25 -5
  540. package/src/services/TaskGraphAgentRunner.ts +188 -11
  541. package/src/services/TaskGraphContinuationDeliverer.ts +713 -17
  542. package/src/sharedCache.ts +305 -0
  543. package/src/types.ts +7 -0
package/src/index.ts CHANGED
@@ -4,7 +4,7 @@ dotenv.config({ quiet: true });
4
4
 
5
5
  import { expressMiddleware } from '@as-integrations/express5';
6
6
  import { mergeSchemas } from '@graphql-tools/schema';
7
- import { Metadata, DatabasePlatform, SetProvider, StartupManager as StartupManagerImport, BaseEntity, BaseEntityEvent, RunView, DatabaseProviderBase, ResolveStartupMode } from '@memberjunction/core';
7
+ import { Metadata, DatabasePlatform, SetProvider, StartupManager as StartupManagerImport, BaseEntity, BaseEntityEvent, RunView, DatabaseProviderBase, ProviderBase, ResolveStartupMode, UserInfo } from '@memberjunction/core';
8
8
  import { UserCache, resolveDbPlatformFromEnv } from '@memberjunction/generic-database-provider';
9
9
  import { MJGlobal, MJEventType, UUIDsEqual, ShutdownRegistry } from '@memberjunction/global';
10
10
  import { setupSQLServerClient, SQLServerDataProvider, SQLServerProviderConfigData } from '@memberjunction/sqlserver-dataprovider';
@@ -19,9 +19,10 @@ import { default as fg } from 'fast-glob';
19
19
  import { useServer } from 'graphql-ws/lib/use/ws';
20
20
  import { createServer } from 'node:http';
21
21
  import { fileURLToPath } from 'node:url';
22
- import { readFileSync, writeFileSync } from 'node:fs';
22
+ import { mkdtempSync, readFileSync, writeFileSync } from 'node:fs';
23
+ import { tmpdir } from 'node:os';
23
24
  import { Session as InspectorSession } from 'node:inspector';
24
- import { sep } from 'node:path';
25
+ import { join, sep } from 'node:path';
25
26
  import 'reflect-metadata';
26
27
  import { ReplaySubject } from 'rxjs';
27
28
  import { BuildSchemaOptions, buildSchemaSync, getMetadataStorage, GraphQLTimestamp, PubSubEngine } from 'type-graphql';
@@ -34,7 +35,7 @@ import { configInfo, configFilePath, dbDatabase, dbHost, dbPort, dbUsername, gra
34
35
  import { TranslateBracketsToPG } from './postgresqlCompat.js';
35
36
  import { BuildPostgreSQLConnectionConfig, DescribeReadOnlyLoginOverreach, PostgreSQLReadOnlyPool, ResolvePostgreSQLEndpoint, ResolvePostgreSQLReadOnlyCredentials, ToPGPoolConfig } from './postgresqlPoolSettings.js';
36
37
  import { default as jwt } from 'jsonwebtoken';
37
- import { contextFunction, CreateUnifiedAuthMiddleware, getUserPayload } from './context.js';
38
+ import { contextFunction, CreateReadOnlyProvider, CreateUnifiedAuthMiddleware, getUserPayload } from './context.js';
38
39
  import { UserPayload } from './types.js';
39
40
  import { requireSystemUserDirective, publicDirective } from './directives/index.js';
40
41
  import { variablesLoggingMiddleware } from './logging/variablesLoggingMiddleware.js';
@@ -43,13 +44,15 @@ import { StartupLogger } from './logging/StartupLogger.js';
43
44
  import { AuthProviderFactory } from '@memberjunction/auth-providers';
44
45
  import createMSSQLConfig from './orm.js';
45
46
  import { setupRESTEndpoints } from './rest/setupRESTEndpoints.js';
46
- import { createOAuthCallbackHandler } from './rest/OAuthCallbackHandler.js';
47
- import { createSignatureWebhookHandler } from './rest/SignatureWebhookHandler.js';
48
- import { createMediaStreamRouter } from './rest/MediaStreamHandler.js';
49
- import { createRealtimeSdpBrokerRouter } from './rest/RealtimeSdpBrokerHandler.js';
50
- import { REALTIME_SDP_EXCHANGE_PATH } from '@memberjunction/ai';
51
- import { createMagicLinkHandler, createMagicLinkJwksRouter, registerMagicLinkAuthProvider, MAGIC_LINK_MOUNT_PATH } from './auth/magicLink/index.js';
52
- import { createWidgetHandler, WIDGET_MOUNT_PATH } from './realtimeWidget/index.js';
47
+ import { CreateRealtimeRecordingRouter, REALTIME_RECORDING_MOUNT_PATH } from './rest/RealtimeRecordingHandler.js';
48
+ import { LoadOwnedRealtimeSession } from './realtimeSessions/ownedRealtimeSession.js';
49
+ import { LoadSessionConversationExternalID } from './realtimeSessions/sessionAccess.js';
50
+ import { RecordingAssemblyScheduler } from './realtimeSessions/RecordingAssemblyScheduler.js';
51
+ import {
52
+ RealtimeSessionEventService,
53
+ ParseReplicatedRealtimeSessionEvent,
54
+ type RealtimeSessionEventTopicPayload,
55
+ } from './realtimeSessions/index.js';
53
56
  import { resolve } from 'node:path';
54
57
  import { DataSourceInfo, raiseEvent } from './types.js';
55
58
 
@@ -58,17 +61,12 @@ import { ScheduledJobsService } from './services/ScheduledJobsService.js';
58
61
  import { IntegrationSyncWorkerService } from './services/IntegrationSyncWorkerService.js';
59
62
  import { LocalCacheManager, StartupManager, TelemetryManager, TelemetryLevel, LogStatus, LogError, SetVerboseLogging } from '@memberjunction/core';
60
63
  import { getSystemUser, validateAuthProvidersRegistered } from './auth/index.js';
61
- import { createAuthProviderCatalogRouter, AUTH_CATALOG_MOUNT_PATH } from './auth/AuthProviderCatalogRouter.js';
62
64
  import { GetAPIKeyEngine } from '@memberjunction/api-keys';
63
- import { RedisLocalStorageProvider } from '@memberjunction/redis-provider';
64
- import { GenericDatabaseProvider } from '@memberjunction/generic-database-provider';
65
+ import { ActionEngineServer } from '@memberjunction/actions';
66
+ import { CreateAdhocSQLAuthorizer } from './resolvers/AdhocQueryResolver.js';
67
+ import { CacheManagerConfigFromSettings, CreateSharedCacheFromEnvironment, StartEngineSweeper, StartMetadataSweep, StartUserCacheChecks, WarmupLeaseMsFromSettings, WirePushStatusFanOut, WireSharedCacheEvents } from './sharedCache.js';
65
68
  import { PubSubManager } from './generic/PubSubManager.js';
66
69
  import { ReconcileOrphanedConversationDetails } from './generic/OrphanedConversationDetailReconciler.js';
67
- import {
68
- PUSH_STATUS_UPDATES_TOPIC,
69
- SetPushStatusPublishHook,
70
- ParseReplicatedStatusUpdate,
71
- } from './generic/PushStatusResolver.js';
72
70
  import {
73
71
  HANDOFF_OFFER_FANOUT_CHANNEL,
74
72
  HANDOFF_OFFER_TOPIC,
@@ -76,11 +74,14 @@ import {
76
74
  ParseReplicatedHandoffOfferUpdate,
77
75
  } from './resolvers/HumanHandoffResolver.js';
78
76
  import { RoomHandoffEngine } from '@memberjunction/livekit-room-server';
77
+ // Type-only: the provider is built in ./sharedCache.ts. Still needed here because the handoff-offer
78
+ // fan-out below stays in this file — see the note at its call site.
79
+ import type { RedisLocalStorageProvider } from '@memberjunction/redis-provider';
79
80
  import { IntegrationProgressEmitter } from '@memberjunction/integration-progress-artifacts';
80
81
  import { PublishIntegrationProgress } from './resolvers/IntegrationProgressResolver.js';
81
82
  import { RegisterRSUProgressBridge } from './integration/RSUProgressBridge.js';
82
- import { ClientToolRequestManager, AgentRunWatchdog } from '@memberjunction/ai-agents';
83
- import { SessionJanitor } from './agentSessions/index.js';
83
+ import { ClientToolRequestManager, AgentRunWatchdog, SqlRealtimeRecordingLedger } from '@memberjunction/ai-agents';
84
+ import { BindBridgeEngineHostInstance, SessionJanitor, SetHostInstancePort, StartBridgeOrphanReconciliation } from './agentSessions/index.js';
84
85
  import { StartTaskGraphDispatcher } from './services/StartTaskGraphDispatcher.js';
85
86
  import { MJServerWorkQueueProviderSource, StartWorkQueueHost } from './services/WorkQueueHostService.js';
86
87
  import { GetAttachmentService } from '@memberjunction/aiengine';
@@ -95,8 +96,11 @@ import {
95
96
  MJCompanyIntegrationFieldMapEntity,
96
97
  MJScheduledJobEntity,
97
98
  } from '@memberjunction/core-entities';
98
- import { ServerExtensionLoader, ServerExtensionConfig, mergeServerExtensionConfigs, prepareServerExtensionConfigs, describeServerExtensionMount, InstallMediaUpgradeDispatcher, IsGraphQLWsPath } from '@memberjunction/server-extensions-core';
99
- import { coreReservedServerExtensionRoots } from './serverExtensionReservedRoots.js';
99
+ import { ServerExtensionLoader, ServerExtensionConfig, mergeServerExtensionConfigs, prepareServerExtensionConfigs, describeServerExtensionMount, InstallMediaUpgradeDispatcher, IsGraphQLWsPath, GetCorsOwningServerExtensionRoots } from '@memberjunction/server-extensions-core';
100
+ import { CreateExtensionOwnedPreflightFallback, CreateGlobalCorsMiddleware } from './globalCors.js';
101
+ import { CoreReservedServerExtensionRoots } from './serverExtensionReservedRoots.js';
102
+ import { ApiRoute, ApiRootPath, ConfiguredPublicUrl } from './apiRoot.js';
103
+ import { MountHealthcheckRoute, MountPublicCoreRoutes, MountExtensionHealthRoute, MountAuthCatalogRoute, MountAuthenticatedCoreRoutes } from './coreRoutes.js';
100
104
  import { MetadataCacheRefreshIntervalSeconds } from './providerConfigUnits.js';
101
105
  import { CreateMetadataRefreshSignalHandler, METADATA_REFRESH_SIGNAL } from './metadataRefreshSignal.js';
102
106
 
@@ -132,7 +136,9 @@ export * from 'type-graphql';
132
136
  // later importers, which makes schema build fail on ViewResult.RowCount.
133
137
  export { Int, Float, ID } from 'type-graphql';
134
138
  export { NewUserBase } from './auth/newUsers.js';
139
+ export { CreateIsolatedProvider } from './isolatedProvider.js';
135
140
  export { configInfo, DEFAULT_SERVER_CONFIG } from './config.js';
141
+ export { ApiRoute, ApiRootPath, ConfiguredPublicUrl, JoinApiRoute, NormalizeApiRootPath, type ApiRouteOptions } from './apiRoot.js';
136
142
  export { ServerExtensionLoader, BaseServerExtension, DefaultServerExtensionServiceRegistry } from '@memberjunction/server-extensions-core';
137
143
  export type {
138
144
  ServerExtensionConfig,
@@ -196,6 +202,8 @@ export * from './resolvers/GenerateSeedTaxonomyResolver.js';
196
202
  export * from './resolvers/PipelineProgressResolver.js';
197
203
  export * from './resolvers/IntegrationProgressResolver.js';
198
204
  export * from './resolvers/IdentityClaimRedemptionResolver.js';
205
+ export * from './resolvers/UserAvatarResolver.js';
206
+ export * from './resolvers/avatarInputValidation.js';
199
207
  export * from './resolvers/ClientToolRequestResolver.js';
200
208
  export * from './resolvers/AutotagPipelineResolver.js';
201
209
  export * from './resolvers/TagGovernanceResolver.js';
@@ -240,6 +248,7 @@ export * from './resolvers/FileCategoryResolver.js';
240
248
  export * from './resolvers/FileResolver.js';
241
249
  export * from './rest/MediaAccessKeys.js';
242
250
  export * from './rest/MediaStreamHandler.js';
251
+ export * from './rest/RealtimeRecordingHandler.js';
243
252
  export * from './resolvers/InfoResolver.js';
244
253
  export * from './resolvers/PotentialDuplicateRecordResolver.js';
245
254
  export * from './resolvers/DuplicateEntryCheckResolver.js';
@@ -253,6 +262,9 @@ export * from './resolvers/CurrentUserContextResolver.js';
253
262
  export * from './resolvers/RSUResolver.js';
254
263
  export * from './resolvers/AgentSessionResolver.js';
255
264
  export * from './resolvers/RealtimeClientSessionResolver.js';
265
+ export * from './resolvers/RealtimeSessionEventsResolver.js';
266
+ export * from './resolvers/RealtimeSessionVerificationResolver.js';
267
+ export * from './realtimeSessions/index.js';
256
268
  export * from './resolvers/MeetingResolver.js';
257
269
  export * from './resolvers/RemoteBrowserActionResolver.js';
258
270
  export * from './agentSessions/index.js';
@@ -289,7 +301,15 @@ const localPath = (p: string) => {
289
301
  return resolvedPath;
290
302
  };
291
303
 
292
- export const CreateApp = (): Application => express();
304
+ /**
305
+ * Creates the Express application MJServer serves on. `X-Powered-By` is disabled: it only
306
+ * advertises the framework to scanners. {@link Serve} disables it again on a host-supplied app.
307
+ */
308
+ export const CreateApp = (): Application => {
309
+ const app = express();
310
+ app.disable('x-powered-by');
311
+ return app;
312
+ };
293
313
 
294
314
  /** @deprecated Use {@link CreateApp}. */
295
315
  export const createApp = CreateApp;
@@ -316,59 +336,6 @@ function resolveServerVersion(): string | undefined {
316
336
  /** How often to re-check for conversation details left behind by finished runs. */
317
337
  const ORPHAN_DETAIL_SWEEP_INTERVAL_MS = 5 * 60_000;
318
338
 
319
- /** Redis channel carrying replicated push-status updates between server instances. */
320
- const PUSH_STATUS_FANOUT_CHANNEL = 'push-status-updates';
321
-
322
- /**
323
- * Replicate push-status updates across server instances over Redis (MJ #4222).
324
- *
325
- * Outbound: every locally-published update is forwarded on a shared channel. Inbound: a message
326
- * from another instance is republished onto THIS instance's local topic, where the normal
327
- * subscription filter decides who receives it — so the identity gate (`ownerUserId` vs. the
328
- * connection's authenticated user) still applies to a replicated message exactly as it does to a
329
- * local one. The replica has no say in who sees what.
330
- *
331
- * Republishing goes straight to `PubSubManager`, never back through `publishStatusUpdate`, so an
332
- * inbound message cannot be re-broadcast and loop. `SourceServerId` guards the remaining case: a
333
- * publisher also receives its own message from Redis.
334
- */
335
- async function wirePushStatusFanOut(redisProvider: RedisLocalStorageProvider, startupLog: StartupLogger): Promise<void> {
336
- try {
337
- await redisProvider.SubscribeToChannel(PUSH_STATUS_FANOUT_CHANNEL, (raw: string) => {
338
- try {
339
- const payload = ParseReplicatedStatusUpdate(raw, MJGlobal.Instance.ProcessUUID);
340
- if (!payload) {
341
- return;
342
- }
343
- // Rebuilt as a plain record: the topic's publish signature takes an index-signature type,
344
- // and listing the fields keeps the wire shape explicit at the one place it crosses hosts.
345
- PubSubManager.Instance.Publish(PUSH_STATUS_UPDATES_TOPIC, {
346
- sessionId: payload.sessionId,
347
- ownerUserId: payload.ownerUserId,
348
- message: payload.message,
349
- SourceServerId: payload.SourceServerId,
350
- });
351
- } catch (err) {
352
- // A malformed message on a shared channel must not take down the subscriber.
353
- LogError('Error processing push-status fan-out message', undefined, err);
354
- }
355
- });
356
-
357
- SetPushStatusPublishHook((payload) => {
358
- redisProvider.PublishMessage(PUSH_STATUS_FANOUT_CHANNEL, JSON.stringify(payload));
359
- });
360
-
361
- // Printed unconditionally, not verbose-gated. "Is fan-out actually on?" is the first question
362
- // anyone debugging a hung conversation behind a load balancer asks, and a silent default left
363
- // no way to answer it.
364
- console.log('[MJAPI] Push-status updates: cross-instance fan-out enabled via Redis');
365
- } catch (err) {
366
- // Single-instance delivery still works, and the durable tail query covers the rest. Degraded,
367
- // not broken — so this must not stop the server from starting.
368
- console.warn(`Push-status fan-out unavailable: ${(err as Error).message}`);
369
- }
370
- }
371
-
372
339
  /**
373
340
  * Replicate handoff-offer updates across server instances over Redis.
374
341
  *
@@ -408,6 +375,43 @@ async function wireHandoffOfferFanOut(redisProvider: RedisLocalStorageProvider,
408
375
  }
409
376
  }
410
377
 
378
+ /** Redis channel carrying replicated realtime session events between server instances. */
379
+ const REALTIME_SESSION_EVENTS_FANOUT_CHANNEL = 'realtime-session-events';
380
+
381
+ /**
382
+ * Replicate realtime session events across server instances over Redis.
383
+ *
384
+ * Behind a load balancer the browser's WebSocket (the `RealtimeSessionEvents` subscription) lives on one
385
+ * replica while the request that raises the event — typically the public verify-link redemption — can be
386
+ * handled by another. The session-events topic is an in-process PubSub, so without this an
387
+ * `identity.verified` published on replica B never reaches the subscriber on replica A.
388
+ *
389
+ * Inbound messages are republished onto THIS instance's local topic only (never back through the
390
+ * replication hook, so there is no loop) and are still judged by the subscription filter against the
391
+ * connection's identity — a replica has no say in who sees what. The durable
392
+ * `RealtimeSessionVerificationStatus` query remains the backstop if Redis is down.
393
+ */
394
+ async function wireRealtimeSessionEventFanOut(redisProvider: RedisLocalStorageProvider): Promise<void> {
395
+ try {
396
+ await redisProvider.SubscribeToChannel(REALTIME_SESSION_EVENTS_FANOUT_CHANNEL, (raw: string) => {
397
+ try {
398
+ const payload = ParseReplicatedRealtimeSessionEvent(raw, MJGlobal.Instance.ProcessUUID);
399
+ if (payload) {
400
+ RealtimeSessionEventService.Instance.PublishReplicated(payload);
401
+ }
402
+ } catch (err) {
403
+ LogError(`Realtime session event fan-out: dropping a malformed replicated event: ${(err as Error).message}`);
404
+ }
405
+ });
406
+ RealtimeSessionEventService.Instance.SetReplicationHook((payload: RealtimeSessionEventTopicPayload) => {
407
+ redisProvider.PublishMessage(REALTIME_SESSION_EVENTS_FANOUT_CHANNEL, JSON.stringify(payload));
408
+ });
409
+ console.log('[MJAPI] Realtime session events: cross-instance fan-out enabled via Redis');
410
+ } catch (err) {
411
+ // Single-instance delivery still works and the status query covers the rest: degraded, not broken.
412
+ console.warn(`Realtime session event fan-out unavailable: ${(err as Error).message}`);
413
+ }
414
+ }
411
415
 
412
416
  // Bind MJStorage as the conversation-attachment blob store. The attachment service itself no longer
413
417
  // imports `@memberjunction/storage` — that dependency made it unusable from any browser or React
@@ -422,6 +426,12 @@ GetAttachmentService().BlobStore = new MJStorageBlobStore();
422
426
 
423
427
  export const Serve = async (resolverPaths: Array<string>, app: Application = CreateApp(), options?: MJServerOptions): Promise<void> => {
424
428
  const t0 = performance.now();
429
+ // Name this MJAPI instance by its port before anything stamps a session row with its identity, so the janitor's
430
+ // startup recovery closes only the sessions an earlier boot of this instance left, never those of another MJAPI on
431
+ // the same host (#5309).
432
+ SetHostInstancePort(graphqlPort);
433
+ // The realtime bridge engine stamps its bridge rows with the same identity and reconciles orphans by it (#5310).
434
+ BindBridgeEngineHostInstance();
425
435
  // Level-gated startup logger. Resolves verbosity from telemetry.level (single
426
436
  // operator knob). At `standard` (default), per-phase timings are collapsed into
427
437
  // the one-line summary; at `verbose`+ each phase prints inline as before.
@@ -450,6 +460,25 @@ const setupComplete$ = new ReplaySubject(1);
450
460
  const dbType = GetDbType();
451
461
  const dataSources: DataSourceInfo[] = [];
452
462
 
463
+ // Shared cache first: the database provider loads metadata and startup engines through
464
+ // it, so the first server to start fills it and later servers read it instead of each querying
465
+ // the database and broadcasting what they loaded. Subscribed before engines load so they hear
466
+ // other servers while they start.
467
+ const sharedCache = CreateSharedCacheFromEnvironment(configInfo.cacheSettings);
468
+ if (sharedCache) {
469
+ await WireSharedCacheEvents(sharedCache, () => (Metadata.Provider instanceof ProviderBase ? Metadata.Provider : undefined)); // global-provider-ok: bootstrap
470
+ // The cross-instance fan-outs ride this connection. Push-status moved into sharedCache.ts
471
+ // with the rest of the Redis wiring; the handoff and realtime-session ones stay here deliberately —
472
+ // they reach into RoomHandoffEngine and RealtimeSessionEventService, and the cache module should not
473
+ // acquire a dependency on either.
474
+ await WirePushStatusFanOut(sharedCache);
475
+ await wireHandoffOfferFanOut(sharedCache, startupLog);
476
+ await wireRealtimeSessionEventFanOut(sharedCache);
477
+ startupLog.LogIf('verbose', `Redis cache provider connected: ${process.env.REDIS_URL}`);
478
+ }
479
+ const cacheManagerConfig = CacheManagerConfigFromSettings(configInfo.cacheSettings);
480
+ const warmupLeaseMs = WarmupLeaseMsFromSettings(configInfo.cacheSettings);
481
+
453
482
  if (dbType === 'postgresql') {
454
483
  // ─── PostgreSQL Path ───────────────────────────────────────────
455
484
  startupLog.BeginPhase('Connecting to database');
@@ -509,6 +538,7 @@ const setupComplete$ = new ReplaySubject(1);
509
538
  mj_core_schema,
510
539
  cacheRefreshInterval / 1000, // convert ms to seconds
511
540
  );
541
+ pgConfigData.LocalStorageProvider = sharedCache ?? undefined;
512
542
  const provider = new PostgreSQLDataProvider();
513
543
  await provider.Config(pgConfigData);
514
544
  SetProvider(provider);
@@ -520,7 +550,7 @@ const setupComplete$ = new ReplaySubject(1);
520
550
  const sysUser = UserCache.Instance.GetSystemUser();
521
551
  const backupSysUser = UserCache.Instance.Users.find(u => u.IsActive && u.Type === 'Owner');
522
552
  const pgStartupMode = ResolveStartupMode({ configValue: configInfo.startup?.mode, defaultMode: 'full' });
523
- await StartupManagerImport.Instance.Startup(false, sysUser || backupSysUser, provider, { mode: pgStartupMode.mode });
553
+ await StartupManagerImport.Instance.Startup(false, sysUser || backupSysUser, provider, { mode: pgStartupMode.mode, cacheManagerConfig, warmupLeaseMs });
524
554
 
525
555
  // Both provider sources have now had their turn — config/env at module load, metadata via
526
556
  // AuthProviderEngine's startup hook — so "no providers at all" is finally a meaningful check.
@@ -678,10 +708,11 @@ const setupComplete$ = new ReplaySubject(1);
678
708
 
679
709
  // cacheRefreshInterval is configured in ms; checkRefreshIntervalSeconds declares seconds — see providerConfigUnits.ts
680
710
  const config = new SQLServerProviderConfigData(pool, mj_core_schema, MetadataCacheRefreshIntervalSeconds(cacheRefreshInterval));
711
+ config.LocalStorageProvider = sharedCache ?? undefined;
681
712
  // MJAPI is a long-running server, so entry-point default is 'full' engine pre-warm;
682
713
  // MJ_STARTUP_MODE / mj.config.cjs startup.mode can override per the shared precedence chain
683
714
  const startupMode = ResolveStartupMode({ configValue: configInfo.startup?.mode, defaultMode: 'full' });
684
- await setupSQLServerClient(config, { mode: startupMode.mode });
715
+ await setupSQLServerClient(config, { mode: startupMode.mode, cacheManagerConfig, warmupLeaseMs });
685
716
 
686
717
  // See the note on the PostgreSQL path above: this is the first point at which both the
687
718
  // config/env providers and the metadata catalog have been registered.
@@ -806,84 +837,33 @@ const setupComplete$ = new ReplaySubject(1);
806
837
  startupLog.LogIf('verbose', 'Server telemetry disabled');
807
838
  }
808
839
 
809
- // Optionally inject Redis as the shared storage provider for cross-server cache invalidation
810
- if (process.env.REDIS_URL) {
811
- const redisProvider = new RedisLocalStorageProvider({
812
- url: process.env.REDIS_URL,
813
- keyPrefix: process.env.REDIS_KEY_PREFIX || 'mj',
814
- enablePubSub: true,
815
- enableLogging: configInfo.cacheSettings?.verboseLogging ?? false,
816
- });
817
- (Metadata.Provider as GenericDatabaseProvider).SetLocalStorageProvider(redisProvider); // global-provider-ok: bootstrap (Redis cache wiring)
818
- await redisProvider.StartListening();
819
-
820
- // Connect Redis pub/sub events to LocalCacheManager callback dispatch
821
- // so cross-server cache invalidation messages are routed to registered callbacks
822
- redisProvider.OnCacheChanged((event) => {
823
- const sourceShort = event.SourceServerId ? event.SourceServerId.substring(0, 8) : 'unknown';
824
- console.log(`[MJAPI] Redis pub/sub → DispatchCacheChange: ${event.Action} for "${event.CacheKey}" from server ${sourceShort}`);
825
- LocalCacheManager.Instance.DispatchCacheChange(event);
826
-
827
- // Also broadcast to connected browser clients via GraphQL subscription
828
- // Extract entity name from the cache key (format: EntityName|Filter|OrderBy|...)
829
- const entityName = event.CacheKey ? event.CacheKey.split('|')[0] : '';
830
- if (entityName) {
831
- PubSubManager.Instance.Publish(CACHE_INVALIDATION_TOPIC, {
832
- entityName,
833
- primaryKeyValues: null, // entity-level invalidation
834
- action: event.Action || 'save',
835
- sourceServerId: event.SourceServerId || 'unknown',
836
- timestamp: new Date(),
837
- });
838
- }
839
- });
840
-
841
- // Fan push-status updates across server instances (MJ #4222).
842
- //
843
- // Behind a load balancer the browser's WebSocket lives on one replica while the mutation that
844
- // drives the agent can be handled by another. The push topic is an in-process PubSub, so a
845
- // completion published on replica B never reaches a subscriber on replica A — the browser waits
846
- // forever for an event that was delivered to nobody. Replicating progress and completion over
847
- // Redis closes that, and the durable tail query remains the backstop if Redis is down.
848
- await wirePushStatusFanOut(redisProvider, startupLog);
849
- await wireHandoffOfferFanOut(redisProvider, startupLog);
850
-
851
- startupLog.LogIf('verbose', `Redis cache provider connected: ${process.env.REDIS_URL}`);
852
- }
853
-
854
- // If Redis is available, swap LocalCacheManager's storage provider to Redis.
855
- // LocalCacheManager may have already been initialized (with in-memory provider)
856
- // during engine loading. SetStorageProvider migrates cached data to Redis.
857
- if (process.env.REDIS_URL) {
858
- await LocalCacheManager.Instance.SetStorageProvider(Metadata.Provider.LocalStorageProvider); // global-provider-ok: bootstrap
859
- startupLog.LogIf('verbose', 'LocalCacheManager: storage provider swapped to Redis');
860
- }
861
- // Ensure LocalCacheManager is initialized (no-op if already done during engine loading)
862
- if (!LocalCacheManager.Instance.IsInitialized) {
863
- // Build cache config from mj.config.cjs cacheSettings
864
- const cs = configInfo.cacheSettings;
865
- const cacheConfig = {
866
- maxSizeBytes: (cs.maxMemoryMB ?? 150) * 1024 * 1024,
867
- maxPercentOfCachePerEntity: cs.maxPercentOfCachePerEntity ?? 50,
868
- defaultTTLMs: (cs.defaultTTLSeconds ?? 0) * 1000,
869
- evictionSweepIntervalMs: (cs.evictionSweepIntervalSeconds ?? 300) * 1000,
870
- verboseLogging: cs.verboseLogging ?? false,
871
- };
872
- await LocalCacheManager.Instance.Initialize(Metadata.Provider.LocalStorageProvider, cacheConfig); // global-provider-ok: bootstrap
873
- if (startupLog.IsAtLeast('verbose')) {
874
- // eslint-disable-next-line no-console
875
- console.log('LocalCacheManager initialized with cache config:', JSON.stringify({
876
- maxMemoryMB: cs.maxMemoryMB ?? 150,
877
- maxPercentOfCachePerEntity: cs.maxPercentOfCachePerEntity ?? 50,
878
- evictionSweepIntervalSeconds: cs.evictionSweepIntervalSeconds ?? 300,
879
- }));
880
- }
840
+ // The database provider already initialized LocalCacheManager from inside its own Config(), with
841
+ // no settings — this call is what makes `cacheSettings` take effect (Initialize merges a config
842
+ // handed to it later). Unconditional on purpose: the guard that used to sit here
843
+ // skipped exactly the case that needed it.
844
+ await LocalCacheManager.Instance.Initialize(Metadata.Provider.LocalStorageProvider, cacheManagerConfig); // global-provider-ok: bootstrap
845
+ if (sharedCache) {
846
+ await LocalCacheManager.Instance.SetStorageProvider(sharedCache);
881
847
  }
848
+ // The derived per-entry ceiling, so the boot log says what the largest cacheable entry actually is.
849
+ startupLog.LogIf('verbose', `LocalCacheManager: largest cacheable entry ${Math.floor(LocalCacheManager.Instance.MaxEntrySizeBytes / 1024 / 1024)} MB (maxEntryPercentOfCache: ${configInfo.cacheSettings?.maxEntryPercentOfCache ?? 'auto'})`);
850
+ const engineSweepMs = StartEngineSweeper(configInfo.cacheSettings);
851
+ startupLog.LogIf('verbose', engineSweepMs > 0 ? `Engine/database sweep every ${engineSweepMs / 1000}s` : 'Engine/database sweep disabled');
852
+ const userCacheCheckMs = StartUserCacheChecks(configInfo.cacheSettings);
853
+ startupLog.LogIf('verbose', userCacheCheckMs > 0 ? `User cache staleness check every ${userCacheCheckMs / 1000}s` : 'User cache staleness check disabled');
854
+ // Costs nothing unless a metadata entity declares TrustServerCacheCompletely = false.
855
+ const metadataSweepMs = StartMetadataSweep(configInfo.cacheSettings, () => (Metadata.Provider instanceof ProviderBase ? Metadata.Provider : undefined)); // global-provider-ok: bootstrap (this process's one provider)
856
+ startupLog.LogIf('verbose', metadataSweepMs > 0 ? `Metadata/database sweep every ${metadataSweepMs / 1000}s (only for entities declaring drift)` : 'Metadata/database sweep disabled');
882
857
 
883
858
  // Initialize APIKeyEngine singleton — reads apiKeyGeneration from mj.config.cjs automatically
884
859
  // This must happen before any request handler calls GetAPIKeyEngine()
885
860
  GetAPIKeyEngine();
886
861
 
862
+ // Actions that run caller-supplied SQL (Run Ad-hoc Query) run only on the read-only login, with
863
+ // ExecuteAdhocQuery's table check and timeout limit.
864
+ ActionEngineServer.Instance.SetReadOnlyProviderFactory(() => CreateReadOnlyProvider(dataSources));
865
+ ActionEngineServer.Instance.SetAdhocSQLAuthorizer(CreateAdhocSQLAuthorizer(configInfo.databaseSettings.requestTimeout));
866
+
887
867
  setupComplete$.next(true);
888
868
  raiseEvent('setupComplete', dataSources, null, this);
889
869
 
@@ -1131,7 +1111,7 @@ const setupComplete$ = new ReplaySubject(1);
1131
1111
  const profile = await new Promise<unknown>((res, rej) =>
1132
1112
  profSession!.post('Profiler.stop', (e, r) => (e ? rej(e) : res((r as { profile: unknown }).profile)))
1133
1113
  );
1134
- const outPath = `/tmp/mjapi_schema_build_${process.pid}.cpuprofile`;
1114
+ const outPath = join(mkdtempSync(join(tmpdir(), 'mjapi-schema-')), `mjapi_schema_build_${process.pid}.cpuprofile`);
1135
1115
  writeFileSync(outPath, JSON.stringify(profile));
1136
1116
  profSession.disconnect();
1137
1117
  // eslint-disable-next-line no-console
@@ -1298,6 +1278,9 @@ const setupComplete$ = new ReplaySubject(1);
1298
1278
  await apolloServer.start();
1299
1279
 
1300
1280
  // Fix #8: Add compression for better throughput performance
1281
+ // Never advertise the framework (`X-Powered-By: Express`) — the host may have passed its own app.
1282
+ app.disable('x-powered-by');
1283
+
1301
1284
  app.use(compression({
1302
1285
  // Don't compress responses smaller than 1KB
1303
1286
  threshold: 1024,
@@ -1318,101 +1301,23 @@ const setupComplete$ = new ReplaySubject(1);
1318
1301
  level: 6
1319
1302
  }));
1320
1303
 
1321
- // Health check endpoint - registered before auth middleware so cloud
1322
- // platform probes (Azure App Service, AWS ALB, k8s, etc.) don't
1323
- // generate noisy auth errors in the logs. CORS is enabled so browser-based
1324
- // clients (e.g. MJExplorer's connectivity poller) can read the response.
1325
- app.get('/healthcheck', cors<cors.CorsRequest>(), (_req, res) => {
1326
- res.status(200).json({ status: 'ok' });
1327
- });
1304
+ // Health check — before every middleware contribution and the auth middleware, so cloud platform
1305
+ // probes never generate auth noise. Every core route mounts under MJAPI_BASE_PATH (see apiRoot.ts).
1306
+ MountHealthcheckRoute(app);
1328
1307
 
1329
1308
  // Apply middleware-contributed pre-auth handlers (after compression, before routes)
1330
1309
  for (const mw of mwPreAuth) {
1331
1310
  app.use(mw);
1332
1311
  }
1333
1312
 
1334
- // ─── OAuth callback routes (unauthenticated, registered BEFORE auth) ─────
1335
- const oauthPublicUrl = configInfo.publicUrl || `${configInfo.baseUrl}:${configInfo.graphqlPort}${configInfo.graphqlRootPath || ''}`;
1313
+ // ─── Public core routes (unauthenticated, registered BEFORE auth) ─────
1314
+ // OAuth callback, eSignature, media, realtime SDP broker, magic-link, widget, realtime verify — see
1315
+ // coreRoutes.ts. New custom routes belong in Server Extensions, never in serve().
1316
+ // oauthPublicUrl is the configured public URL, derived as it always was; it is also the magic-link JWT
1317
+ // issuer, so it stays untrimmed. Outward links use ApiRoute(…, { absolute: true }) instead.
1318
+ const oauthPublicUrl = ConfiguredPublicUrl();
1336
1319
  startupLog.LogIf('verbose', `[OAuth] publicUrl: ${oauthPublicUrl}`);
1337
-
1338
- let oauthAuthenticatedRouter: ReturnType<typeof createOAuthCallbackHandler>['authenticatedRouter'] | undefined;
1339
- if (oauthPublicUrl) {
1340
- const { callbackRouter, authenticatedRouter } = createOAuthCallbackHandler({
1341
- publicUrl: oauthPublicUrl,
1342
- successRedirectUrl: `${oauthPublicUrl}/oauth/success`,
1343
- errorRedirectUrl: `${oauthPublicUrl}/oauth/error`,
1344
- // Constrains where a caller-supplied frontendReturnUrl may point (open-redirect guard).
1345
- allowedFrontendOrigins: configInfo.cors?.allowedOrigins ?? ['*']
1346
- });
1347
- oauthAuthenticatedRouter = authenticatedRouter;
1348
-
1349
- const oauthCors = cors<cors.CorsRequest>();
1350
-
1351
- // OAuth callback is unauthenticated (called by external auth server)
1352
- app.use('/oauth', oauthCors, callbackRouter);
1353
- startupLog.LogIf('verbose', '[OAuth] Callback route registered at /oauth/callback');
1354
- }
1355
-
1356
- // ─── Core HTTP Routes (Static Core Infrastructure) ─────────────────────────
1357
- // IMPORTANT ARCHITECTURAL NOTE:
1358
- // The route mounts below are strictly reserved for core framework infrastructure (OAuth, eSignature,
1359
- // media streaming, realtime WebRTC broker, magic-link, widgets).
1360
- // ALL new custom routes, external webhooks, vendor adapters, and application integrations MUST be
1361
- // implemented as Server Extensions (subclasses of BaseServerExtension in @memberjunction/server-extensions-core)
1362
- // mounted via ServerExtensionLoader — NEVER hardcoded as ad-hoc app.use() in serve().
1363
- // See guides/SERVER_EXTENSIONS_GUIDE.md for complete patterns and best practices.
1364
-
1365
- // ─── eSignature webhook (unauthenticated, registered BEFORE auth) ─────
1366
- // Called by external signature providers (DocuSign Connect, etc.) without an MJ bearer token.
1367
- // The provider DRIVER verifies the payload signature/HMAC; MJ auth does not apply here.
1368
- app.use('/esignature', cors<cors.CorsRequest>(), createSignatureWebhookHandler());
1369
- startupLog.LogIf('verbose', '[eSignature] Webhook route registered at /esignature/webhook/:driverKey');
1370
-
1371
- // ─── Authenticated media streaming (token-gated, registered BEFORE auth) ─────
1372
- // The `?token=` query param (minted by CreateMediaAccessToken after a per-user permission
1373
- // check) is the capability — the route verifies it itself, so it does NOT use the MJ bearer
1374
- // auth middleware (an <audio>/<video> element can't send Authorization headers).
1375
- app.use('/media', cors<cors.CorsRequest>(), createMediaStreamRouter());
1376
- startupLog.LogIf('verbose', '[Media] Streaming route registered at /media/:fileId');
1377
-
1378
- // ─── Realtime WebRTC SDP broker (ticket-gated, registered BEFORE auth) ───────
1379
- if (configInfo.realtime?.enabled) {
1380
- app.use(REALTIME_SDP_EXCHANGE_PATH, cors<cors.CorsRequest>(), createRealtimeSdpBrokerRouter());
1381
- startupLog.LogIf('verbose', `[Realtime] WebRTC SDP broker registered at ${REALTIME_SDP_EXCHANGE_PATH}`);
1382
- }
1383
-
1384
- // ─── Magic-link routes (MJ-issued, app-scoped external access) ───────────
1385
- // Public router (JWKS + redeem) mounts BEFORE the auth middleware; the
1386
- // authenticated invite-creation router mounts AFTER it (see below).
1387
- let widgetAuthenticatedRouter: ReturnType<typeof createWidgetHandler>['authenticatedRouter'] | undefined;
1388
- let magicLinkAuthenticatedRouter: ReturnType<typeof createMagicLinkHandler>['authenticatedRouter'] | undefined;
1389
- if (configInfo.magicLink?.enabled) {
1390
- const { publicRouter, authenticatedRouter } = createMagicLinkHandler(oauthPublicUrl, configInfo.magicLink);
1391
- magicLinkAuthenticatedRouter = authenticatedRouter;
1392
- registerMagicLinkAuthProvider(oauthPublicUrl, configInfo.magicLink);
1393
- app.use(MAGIC_LINK_MOUNT_PATH, cors<cors.CorsRequest>(), publicRouter);
1394
- startupLog.LogIf('verbose', `[MagicLink] Public routes registered at ${MAGIC_LINK_MOUNT_PATH}/redeem and ${MAGIC_LINK_MOUNT_PATH}/jwks.json`);
1395
- }
1396
-
1397
- // ─── Public web widget: guest-session mint (PUBLIC, before auth mw) ───────
1398
- // Visitors hold no MJ JWT yet, so POST /widget/session is public. It reuses the
1399
- // magic-link RS256 key + `magic-link` auth provider (ensured idempotently inside
1400
- // createWidgetHandler), so it stands on its own even if magicLink.enabled is false.
1401
- if (configInfo.widget?.enabled) {
1402
- const { publicRouter: widgetRouter, authenticatedRouter: widgetAuthRouter } = createWidgetHandler(oauthPublicUrl, configInfo.widget);
1403
- widgetAuthenticatedRouter = widgetAuthRouter;
1404
- app.use(WIDGET_MOUNT_PATH, cors<cors.CorsRequest>(), widgetRouter);
1405
- // The widget reuses the magic-link RS256 key + auth provider to validate guest
1406
- // tokens, which validates by fetching the JWKS at MAGIC_LINK_MOUNT_PATH/jwks.json.
1407
- // When magic-link itself is disabled its public router (which serves JWKS) never
1408
- // mounts, so publish the key here — otherwise every guest token fails validation
1409
- // (the auth middleware can't fetch the public key) and the widget 401s.
1410
- if (!configInfo.magicLink?.enabled) {
1411
- app.use(MAGIC_LINK_MOUNT_PATH, cors<cors.CorsRequest>(), createMagicLinkJwksRouter());
1412
- startupLog.LogIf('verbose', `[Widget] Published reused signing key at ${MAGIC_LINK_MOUNT_PATH}/jwks.json (magic-link flow disabled)`);
1413
- }
1414
- startupLog.LogIf('verbose', `[Widget] Public routes registered at ${WIDGET_MOUNT_PATH}/session and ${WIDGET_MOUNT_PATH}/session/refresh`);
1415
- }
1320
+ const coreAuthenticatedRouters = MountPublicCoreRoutes(app, oauthPublicUrl, startupLog);
1416
1321
 
1417
1322
  // ─── Server extensions loader & shared service registry ───────────────────
1418
1323
  const extensionLoader = new ServerExtensionLoader();
@@ -1483,9 +1388,9 @@ const setupComplete$ = new ReplaySubject(1);
1483
1388
 
1484
1389
  // Open App packages publish their extensions; host mj.config.cjs overlays by DriverClass
1485
1390
  // (and remains the only source for host-only extensions such as Slack/Teams).
1486
- // extraReservedRoots is derived from the mounts registered above plus graphqlRootPath
1487
- // so a new pre-auth app.use(...) in serve() must also be added to
1488
- // coreReservedServerExtensionRoots() — otherwise an Open App can claim it.
1391
+ // Every RootPath is relative to MJAPI_BASE_PATH: apiRootPath composes the real mount path, and
1392
+ // extraReservedRoots (also relative) must list every core mount in coreRoutes.ts, otherwise an
1393
+ // Open App can claim it.
1489
1394
  const extensionConfigs = prepareServerExtensionConfigs(
1490
1395
  mergeServerExtensionConfigs(
1491
1396
  options?.serverExtensions ?? [],
@@ -1494,7 +1399,8 @@ const setupComplete$ = new ReplaySubject(1);
1494
1399
  {
1495
1400
  onInvalid: (message) => LogError(message),
1496
1401
  onOverlap: (message) => LogStatus(message),
1497
- extraReservedRoots: coreReservedServerExtensionRoots(graphqlRootPath),
1402
+ extraReservedRoots: CoreReservedServerExtensionRoots(),
1403
+ apiRootPath: ApiRootPath(),
1498
1404
  },
1499
1405
  );
1500
1406
  for (const cfg of extensionConfigs) {
@@ -1505,27 +1411,14 @@ const setupComplete$ = new ReplaySubject(1);
1505
1411
  // Without this, the browser blocks 401 responses from the auth middleware
1506
1412
  // because they lack Access-Control-Allow-Origin headers, preventing the
1507
1413
  // client from reading the error code and triggering token refresh.
1508
- const corsAllowed = configInfo.cors?.allowedOrigins ?? ['*'];
1509
- const corsWildcard = corsAllowed.includes('*');
1510
- // SECURITY: never combine credentials with a wildcard/reflect-any-origin policy. When
1511
- // allowedOrigins is ['*'] the origin callback reflects the caller's Origin, and pairing that
1512
- // with Access-Control-Allow-Credentials: true lets any site a signed-in user visits make
1513
- // credentialed cross-origin reads. MJ's primary auth is a Bearer token (not auto-sent
1514
- // cross-origin), so dropping credentials under the wildcard default is safe; deployments that
1515
- // genuinely need credentialed CORS must configure an explicit allowedOrigins list.
1516
- app.use(cors<cors.CorsRequest>({
1517
- origin: (origin, callback) => {
1518
- // Allow all origins when ['*'] (default/backward-compatible),
1519
- // or when no Origin header (server-to-server calls).
1520
- if (corsWildcard || !origin || corsAllowed.includes(origin)) {
1521
- callback(null, true);
1522
- } else {
1523
- callback(new Error(`Origin ${origin} not allowed by CORS`));
1524
- }
1525
- },
1526
- credentials: corsWildcard ? false : (configInfo.cors?.allowCredentials ?? true),
1527
- maxAge: configInfo.cors?.maxAge ?? 86400,
1528
- }));
1414
+ // Extensions that declare `OwnsCORS: true` (ServerExtensionConfig) are exempt: the global
1415
+ // middleware skips their RootPaths so it neither reflects an origin onto their responses nor
1416
+ // answers their preflights — the extension's own OPTIONS handling and origin policy run instead.
1417
+ const corsOwnedExtensionRoots = GetCorsOwningServerExtensionRoots(extensionConfigs);
1418
+ if (corsOwnedExtensionRoots.length > 0) {
1419
+ LogStatus(`Global CORS skips extension-owned roots: ${corsOwnedExtensionRoots.join(', ')}`);
1420
+ }
1421
+ app.use(CreateGlobalCorsMiddleware(configInfo.cors, corsOwnedExtensionRoots));
1529
1422
 
1530
1423
  // ─── Pre-auth server extensions (before auth — extensions handle their own auth) ─────
1531
1424
  // Slack uses HMAC signature verification, Teams uses Bot Framework JWT validation.
@@ -1536,23 +1429,12 @@ const setupComplete$ = new ReplaySubject(1);
1536
1429
  phase: 'pre-auth',
1537
1430
  httpServer,
1538
1431
  publicUrl: oauthPublicUrl,
1432
+ apiRootPath: ApiRootPath(),
1539
1433
  });
1540
1434
  }
1541
1435
 
1542
- // Extension health endpoint (always available, returns empty array if no extensions)
1543
- app.get('/health/extensions', async (_req, res) => {
1544
- const results = await extensionLoader.HealthCheckAll();
1545
- const allHealthy = results.length === 0 || results.every(r => r.Healthy);
1546
- res.status(allHealthy ? 200 : 503).json({ extensions: results });
1547
- });
1548
-
1549
- // ─── Public authentication-provider catalog (PUBLIC, before auth mw) ──────
1550
- // The browser needs the provider list BEFORE it holds a token, so this is necessarily
1551
- // unauthenticated and must mount ahead of the auth middleware. It publishes only the
1552
- // non-secret allow-list (see AuthProviderEngine.GetPublicCatalog) — the same values a
1553
- // single-provider SPA already compiled into its bundle.
1554
- app.use(AUTH_CATALOG_MOUNT_PATH, cors<cors.CorsRequest>(), createAuthProviderCatalogRouter());
1555
- startupLog.LogIf('verbose', `[Auth] Public provider catalog registered at ${AUTH_CATALOG_MOUNT_PATH}/providers`);
1436
+ MountExtensionHealthRoute(app, extensionLoader);
1437
+ MountAuthCatalogRoute(app, startupLog);
1556
1438
 
1557
1439
  // ─── Unified auth middleware (replaces both REST authMiddleware and contextFunction auth) ─────
1558
1440
  app.use(CreateUnifiedAuthMiddleware(dataSources));
@@ -1565,25 +1447,16 @@ const setupComplete$ = new ReplaySubject(1);
1565
1447
  app.use(mw);
1566
1448
  }
1567
1449
 
1568
- // ─── OAuth authenticated routes (auth already handled by unified middleware) ─────
1569
- if (oauthAuthenticatedRouter) {
1570
- const oauthCors = cors<cors.CorsRequest>();
1571
- app.use('/oauth', oauthCors, BodyParser.json(), oauthAuthenticatedRouter);
1572
- startupLog.LogIf('verbose', '[OAuth] Authenticated routes registered at /oauth/status, /oauth/initiate, and /oauth/exchange');
1573
- }
1574
-
1575
- // ─── Magic-link authenticated route (invite creation) ─────────────────────
1576
- if (magicLinkAuthenticatedRouter) {
1577
- app.use(MAGIC_LINK_MOUNT_PATH, cors<cors.CorsRequest>(), magicLinkAuthenticatedRouter);
1578
- startupLog.LogIf('verbose', `[MagicLink] Authenticated route registered at ${MAGIC_LINK_MOUNT_PATH}/create`);
1579
- }
1450
+ // ─── Authenticated core routes: OAuth status/initiate/exchange, magic-link create, widget resolve-identity ─────
1451
+ MountAuthenticatedCoreRoutes(app, coreAuthenticatedRouters, startupLog);
1580
1452
 
1581
- // ─── Widget authenticated route (RV4 resolve-identity) ────────────────────
1582
- // Mounts after the unified auth middleware so a verified visitor (post magic-link upgrade) can
1583
- // promote their anonymous returning-visitor trail to the verified record.
1584
- if (widgetAuthenticatedRouter) {
1585
- app.use(WIDGET_MOUNT_PATH, cors<cors.CorsRequest>(), widgetAuthenticatedRouter);
1586
- startupLog.LogIf('verbose', `[Widget] Authenticated route registered at ${WIDGET_MOUNT_PATH}/resolve-identity`);
1453
+ // ─── Realtime recording shards + terminal signal (authenticated, owner-gated) ─────
1454
+ // The browser uploads a client-direct call's recording as Opus shards and a keepalive terminal request;
1455
+ // assembly runs off the request path on the scheduler. Needs a SQL provider: the ledger calls procs.
1456
+ if (configInfo.realtime?.enabled) {
1457
+ if (mountRealtimeRecordingRoutes(app)) {
1458
+ startupLog.LogIf('verbose', `[Realtime] Recording routes registered at ${ApiRoute(REALTIME_RECORDING_MOUNT_PATH)}/:agentSessionId/shard/:index and /end`);
1459
+ }
1587
1460
  }
1588
1461
 
1589
1462
  // ─── Post-auth server extensions ──────────────────────────────────────────
@@ -1594,15 +1467,24 @@ const setupComplete$ = new ReplaySubject(1);
1594
1467
  phase: 'post-auth',
1595
1468
  httpServer,
1596
1469
  publicUrl: oauthPublicUrl,
1470
+ apiRootPath: ApiRootPath(),
1597
1471
  });
1598
1472
  }
1599
1473
 
1474
+ // Every extension has now had its chance at the request: a preflight under an extension-owned
1475
+ // root that none of them answered is refused here, instead of falling through to the GraphQL
1476
+ // mount's cors(), which would approve it for every origin.
1477
+ if (corsOwnedExtensionRoots.length > 0) {
1478
+ app.use(CreateExtensionOwnedPreflightFallback(corsOwnedExtensionRoots));
1479
+ }
1480
+
1600
1481
  // ─── Cross-extension lifecycle hook: OnAllExtensionsMounted ───────────────
1601
1482
  // Called after all extensions across both pre-auth and post-auth phases are mounted.
1602
1483
  // Extensions can wire themselves to services registered by other extensions or core.
1603
1484
  await extensionLoader.NotifyAllExtensionsMounted({
1604
1485
  httpServer,
1605
1486
  publicUrl: oauthPublicUrl,
1487
+ apiRootPath: ApiRootPath(),
1606
1488
  });
1607
1489
 
1608
1490
  // Install the single path-routing WebSocket-upgrade dispatcher AFTER all extensions across both
@@ -1757,12 +1639,16 @@ const setupComplete$ = new ReplaySubject(1);
1757
1639
  });
1758
1640
  }
1759
1641
 
1760
- // Launch the AI Agent Session janitor: run own-host orphan recovery once at boot, then keep a
1761
- // periodic staleness sweep running. Self-registers with ShutdownRegistry, so its timer is cleared
1762
- // by the gracefulShutdown drain below (no explicit Stop() wiring needed here).
1642
+ // Launch the AI Agent Session janitor: run own-host orphan recovery once at boot, then a periodic tick
1643
+ // that closes stale and over-deadline sessions and rebuilds lost realtime recordings from their
1644
+ // crash-recovery shards (storage reads and writes). Self-registers with ShutdownRegistry, so its timer
1645
+ // is cleared by the gracefulShutdown drain below (no explicit Stop() wiring needed here).
1763
1646
  if (resumeUser && Metadata.Provider instanceof DatabaseProviderBase) { // global-provider-ok: server startup recovery — boot-time session janitor uses the server's own provider
1764
1647
  SessionJanitor.Instance.Start(Metadata.Provider, resumeUser) // global-provider-ok: server-owned background reconciler runs under the server's provider + system user
1765
1648
  .catch(err => console.warn(`[SessionJanitor] Startup failed: ${err}`));
1649
+ // The bridge engine's orphan reconcile likewise starts only now that this process holds its port, so it can't
1650
+ // take the live bridges of another MJAPI still serving that port for its own orphans (#5310).
1651
+ StartBridgeOrphanReconciliation(Metadata.Provider, resumeUser); // global-provider-ok: server-owned background reconciler runs under the server's provider + system user
1766
1652
  }
1767
1653
 
1768
1654
  // Launch the durable task-graph dispatcher: claim Pending tasks, execute them with a fresh
@@ -2291,3 +2177,48 @@ function createMSSQLCompatPool(pgPool: import('pg').Pool): sql.ConnectionPool {
2291
2177
  return wrapper as unknown as sql.ConnectionPool;
2292
2178
  }
2293
2179
 
2180
+ // Defined below serve() on purpose: serverExtensionReservedRoots.test.ts treats every app.use() that appears
2181
+ // textually before the unified auth middleware as a pre-auth mount, and these routes are mounted post-auth.
2182
+ /**
2183
+ * Mounts the realtime recording shard/terminal routes (post-auth) and starts the assembly scheduler they
2184
+ * hand work to. Skipped, with a warning, when the server's provider is not a SQL provider (the ledger calls
2185
+ * stored procedures). Without a system user the routes still store shards, and the janitor assembles them.
2186
+ * Returns whether the routes were mounted.
2187
+ */
2188
+ function mountRealtimeRecordingRoutes(app: Application): boolean {
2189
+ const provider = Metadata.Provider; // global-provider-ok: REST endpoint — no per-request provider injection in REST middleware yet; the ledger's procs run as the server's SQL login either way
2190
+ if (!(provider instanceof DatabaseProviderBase)) {
2191
+ console.warn('[Realtime] Recording routes not mounted: the server provider is not a DatabaseProviderBase');
2192
+ return false;
2193
+ }
2194
+ const graceMs = (): number => configInfo.realtime.recordingAssemblyGraceSeconds * 1000;
2195
+ const systemUser = UserCache.Instance.GetSystemUser();
2196
+ if (systemUser) {
2197
+ RecordingAssemblyScheduler.Instance.Start({ Provider: provider, SystemUser: systemUser, GraceMs: graceMs });
2198
+ } else {
2199
+ LogError('[Realtime] Recording assembly scheduler not started: no system user; the session janitor assembles recordings instead');
2200
+ }
2201
+ app.use(ApiRoute(REALTIME_RECORDING_MOUNT_PATH), cors<cors.CorsRequest>(), CreateRealtimeRecordingRouter({
2202
+ ResolveCaller: req => {
2203
+ const user: UserInfo | undefined = req.userPayload?.userRecord;
2204
+ return user ? { ContextUser: user, Provider: provider } : null;
2205
+ },
2206
+ LoadOwnedSession: LoadOwnedRealtimeSession,
2207
+ LoadConversationExternalID: LoadSessionConversationExternalID,
2208
+ CreateLedger: (ledgerProvider, contextUser) => new SqlRealtimeRecordingLedger(ledgerProvider, contextUser),
2209
+ Scheduler: RecordingAssemblyScheduler.Instance,
2210
+ GraceMs: graceMs,
2211
+ SystemUser: () => UserCache.Instance.GetSystemUser() ?? null,
2212
+ }));
2213
+ return true;
2214
+ }
2215
+
2216
+ // Public-edge building blocks for Open Apps that run their own pre-auth edge and mint
2217
+ // scope-limited guest sessions (e.g. a ballot edge: verify a credential, then mint a short-lived
2218
+ // session scoped to one resource). They are the same pieces WidgetSessionService uses; a generic
2219
+ // public-widget session mint remains the long-term replacement.
2220
+ export { BuildSessionClaims, MagicLinkKeyManager, MagicLinkService, HashToken, GenerateRawToken } from './auth/magicLink/index.js';
2221
+ export type { MagicLinkJWTClaims } from './auth/magicLink/index.js';
2222
+ export { VerifyHostAssertion } from './realtimeWidget/host-identity.js';
2223
+ export type { HostAssertedIdentity, HostAssertionResult } from './realtimeWidget/host-identity.js';
2224
+ export { IsScopeLimitedPrincipal } from './auth/scopeLimitedPrincipal.js';