@memberjunction/server 5.43.0 → 5.45.0

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 (309) hide show
  1. package/dist/agentSessions/ReturningVisitorRecap.d.ts +39 -0
  2. package/dist/agentSessions/ReturningVisitorRecap.d.ts.map +1 -0
  3. package/dist/agentSessions/ReturningVisitorRecap.js +198 -0
  4. package/dist/agentSessions/ReturningVisitorRecap.js.map +1 -0
  5. package/dist/agentSessions/SessionJanitor.d.ts +13 -0
  6. package/dist/agentSessions/SessionJanitor.d.ts.map +1 -1
  7. package/dist/agentSessions/SessionJanitor.js +65 -7
  8. package/dist/agentSessions/SessionJanitor.js.map +1 -1
  9. package/dist/agentSessions/SessionManager.d.ts.map +1 -1
  10. package/dist/agentSessions/SessionManager.js +40 -0
  11. package/dist/agentSessions/SessionManager.js.map +1 -1
  12. package/dist/agentSessions/index.d.ts.map +1 -1
  13. package/dist/agentSessions/index.js +3 -1
  14. package/dist/agentSessions/index.js.map +1 -1
  15. package/dist/auth/magicLink/MagicLinkRouter.d.ts +10 -0
  16. package/dist/auth/magicLink/MagicLinkRouter.d.ts.map +1 -1
  17. package/dist/auth/magicLink/MagicLinkRouter.js +16 -0
  18. package/dist/auth/magicLink/MagicLinkRouter.js.map +1 -1
  19. package/dist/auth/magicLink/index.d.ts +1 -1
  20. package/dist/auth/magicLink/index.d.ts.map +1 -1
  21. package/dist/auth/magicLink/index.js +1 -1
  22. package/dist/auth/magicLink/index.js.map +1 -1
  23. package/dist/auth/magicLink/types.d.ts +26 -0
  24. package/dist/auth/magicLink/types.d.ts.map +1 -1
  25. package/dist/config.d.ts +1883 -144
  26. package/dist/config.d.ts.map +1 -1
  27. package/dist/config.js +160 -36
  28. package/dist/config.js.map +1 -1
  29. package/dist/context.d.ts.map +1 -1
  30. package/dist/context.js +45 -2
  31. package/dist/context.js.map +1 -1
  32. package/dist/generated/generated.d.ts +1684 -54
  33. package/dist/generated/generated.d.ts.map +1 -1
  34. package/dist/generated/generated.js +57105 -48029
  35. package/dist/generated/generated.js.map +1 -1
  36. package/dist/generic/ResolverBase.d.ts +13 -0
  37. package/dist/generic/ResolverBase.d.ts.map +1 -1
  38. package/dist/generic/ResolverBase.js +22 -0
  39. package/dist/generic/ResolverBase.js.map +1 -1
  40. package/dist/generic/RunViewResolver.d.ts.map +1 -1
  41. package/dist/generic/RunViewResolver.js +4 -0
  42. package/dist/generic/RunViewResolver.js.map +1 -1
  43. package/dist/index.d.ts +2 -2
  44. package/dist/index.d.ts.map +1 -1
  45. package/dist/index.js +110 -3
  46. package/dist/index.js.map +1 -1
  47. package/dist/integration/CustomColumnPromoter.d.ts.map +1 -1
  48. package/dist/integration/CustomColumnPromoter.js +6 -0
  49. package/dist/integration/CustomColumnPromoter.js.map +1 -1
  50. package/dist/realtimeWidget/WidgetRouter.d.ts +26 -0
  51. package/dist/realtimeWidget/WidgetRouter.d.ts.map +1 -0
  52. package/dist/realtimeWidget/WidgetRouter.js +182 -0
  53. package/dist/realtimeWidget/WidgetRouter.js.map +1 -0
  54. package/dist/realtimeWidget/WidgetSessionService.d.ts +265 -0
  55. package/dist/realtimeWidget/WidgetSessionService.d.ts.map +1 -0
  56. package/dist/realtimeWidget/WidgetSessionService.js +477 -0
  57. package/dist/realtimeWidget/WidgetSessionService.js.map +1 -0
  58. package/dist/realtimeWidget/host-identity.d.ts +40 -0
  59. package/dist/realtimeWidget/host-identity.d.ts.map +1 -0
  60. package/dist/realtimeWidget/host-identity.js +58 -0
  61. package/dist/realtimeWidget/host-identity.js.map +1 -0
  62. package/dist/realtimeWidget/index.d.ts +10 -0
  63. package/dist/realtimeWidget/index.d.ts.map +1 -0
  64. package/dist/realtimeWidget/index.js +9 -0
  65. package/dist/realtimeWidget/index.js.map +1 -0
  66. package/dist/realtimeWidget/visitorIdentity.d.ts +76 -0
  67. package/dist/realtimeWidget/visitorIdentity.d.ts.map +1 -0
  68. package/dist/realtimeWidget/visitorIdentity.js +202 -0
  69. package/dist/realtimeWidget/visitorIdentity.js.map +1 -0
  70. package/dist/realtimeWidget/widgetCore.d.ts +106 -0
  71. package/dist/realtimeWidget/widgetCore.d.ts.map +1 -0
  72. package/dist/realtimeWidget/widgetCore.js +173 -0
  73. package/dist/realtimeWidget/widgetCore.js.map +1 -0
  74. package/dist/realtimeWidget/widgetGuestElevation.d.ts +51 -0
  75. package/dist/realtimeWidget/widgetGuestElevation.d.ts.map +1 -0
  76. package/dist/realtimeWidget/widgetGuestElevation.js +79 -0
  77. package/dist/realtimeWidget/widgetGuestElevation.js.map +1 -0
  78. package/dist/resolvers/ComponentRegistryResolver.d.ts +7 -0
  79. package/dist/resolvers/ComponentRegistryResolver.d.ts.map +1 -1
  80. package/dist/resolvers/ComponentRegistryResolver.js +31 -8
  81. package/dist/resolvers/ComponentRegistryResolver.js.map +1 -1
  82. package/dist/resolvers/EntityPermissionResolver.d.ts.map +1 -1
  83. package/dist/resolvers/EntityPermissionResolver.js +1 -2
  84. package/dist/resolvers/EntityPermissionResolver.js.map +1 -1
  85. package/dist/resolvers/FileResolver.d.ts +74 -0
  86. package/dist/resolvers/FileResolver.d.ts.map +1 -1
  87. package/dist/resolvers/FileResolver.js +211 -2
  88. package/dist/resolvers/FileResolver.js.map +1 -1
  89. package/dist/resolvers/QueryResolver.d.ts +6 -4
  90. package/dist/resolvers/QueryResolver.d.ts.map +1 -1
  91. package/dist/resolvers/QueryResolver.js +29 -14
  92. package/dist/resolvers/QueryResolver.js.map +1 -1
  93. package/dist/resolvers/QuerySystemUserResolver.d.ts +9 -6
  94. package/dist/resolvers/QuerySystemUserResolver.d.ts.map +1 -1
  95. package/dist/resolvers/QuerySystemUserResolver.js +15 -13
  96. package/dist/resolvers/QuerySystemUserResolver.js.map +1 -1
  97. package/dist/resolvers/RealtimeBridgeResolver.d.ts +8 -1
  98. package/dist/resolvers/RealtimeBridgeResolver.d.ts.map +1 -1
  99. package/dist/resolvers/RealtimeBridgeResolver.js +28 -4
  100. package/dist/resolvers/RealtimeBridgeResolver.js.map +1 -1
  101. package/dist/resolvers/RealtimeClientSessionResolver.d.ts +91 -2
  102. package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
  103. package/dist/resolvers/RealtimeClientSessionResolver.js +337 -17
  104. package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
  105. package/dist/resolvers/RemoteBrowserActionResolver.d.ts.map +1 -1
  106. package/dist/resolvers/RemoteBrowserActionResolver.js +17 -2
  107. package/dist/resolvers/RemoteBrowserActionResolver.js.map +1 -1
  108. package/dist/resolvers/RingCentralTelephonyResolver.d.ts +27 -0
  109. package/dist/resolvers/RingCentralTelephonyResolver.d.ts.map +1 -0
  110. package/dist/resolvers/RingCentralTelephonyResolver.js +87 -0
  111. package/dist/resolvers/RingCentralTelephonyResolver.js.map +1 -0
  112. package/dist/resolvers/RunAIAgentResolver.d.ts +12 -3
  113. package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
  114. package/dist/resolvers/RunAIAgentResolver.js +50 -17
  115. package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
  116. package/dist/resolvers/SearchKnowledgeResolver.d.ts.map +1 -1
  117. package/dist/resolvers/SearchKnowledgeResolver.js +2 -0
  118. package/dist/resolvers/SearchKnowledgeResolver.js.map +1 -1
  119. package/dist/resolvers/TeamsMeetingsResolver.d.ts +28 -0
  120. package/dist/resolvers/TeamsMeetingsResolver.d.ts.map +1 -0
  121. package/dist/resolvers/TeamsMeetingsResolver.js +91 -0
  122. package/dist/resolvers/TeamsMeetingsResolver.js.map +1 -0
  123. package/dist/resolvers/TelephonyResolver.d.ts +26 -0
  124. package/dist/resolvers/TelephonyResolver.d.ts.map +1 -0
  125. package/dist/resolvers/TelephonyResolver.js +86 -0
  126. package/dist/resolvers/TelephonyResolver.js.map +1 -0
  127. package/dist/resolvers/TestQuerySQLResolver.d.ts +1 -1
  128. package/dist/resolvers/TestQuerySQLResolver.d.ts.map +1 -1
  129. package/dist/resolvers/TestQuerySQLResolver.js +2 -3
  130. package/dist/resolvers/TestQuerySQLResolver.js.map +1 -1
  131. package/dist/resolvers/VonageTelephonyResolver.d.ts +26 -0
  132. package/dist/resolvers/VonageTelephonyResolver.d.ts.map +1 -0
  133. package/dist/resolvers/VonageTelephonyResolver.js +86 -0
  134. package/dist/resolvers/VonageTelephonyResolver.js.map +1 -0
  135. package/dist/resolvers/meetingRecordingRegistration.d.ts +124 -0
  136. package/dist/resolvers/meetingRecordingRegistration.d.ts.map +1 -0
  137. package/dist/resolvers/meetingRecordingRegistration.js +311 -0
  138. package/dist/resolvers/meetingRecordingRegistration.js.map +1 -0
  139. package/dist/resolvers/peaksSidecar.d.ts +30 -0
  140. package/dist/resolvers/peaksSidecar.d.ts.map +1 -0
  141. package/dist/resolvers/peaksSidecar.js +51 -0
  142. package/dist/resolvers/peaksSidecar.js.map +1 -0
  143. package/dist/rest/MediaAccessKeys.d.ts +68 -0
  144. package/dist/rest/MediaAccessKeys.d.ts.map +1 -0
  145. package/dist/rest/MediaAccessKeys.js +96 -0
  146. package/dist/rest/MediaAccessKeys.js.map +1 -0
  147. package/dist/rest/MediaStreamHandler.d.ts +26 -0
  148. package/dist/rest/MediaStreamHandler.d.ts.map +1 -0
  149. package/dist/rest/MediaStreamHandler.js +195 -0
  150. package/dist/rest/MediaStreamHandler.js.map +1 -0
  151. package/dist/rest/mediaRange.d.ts +41 -0
  152. package/dist/rest/mediaRange.d.ts.map +1 -0
  153. package/dist/rest/mediaRange.js +60 -0
  154. package/dist/rest/mediaRange.js.map +1 -0
  155. package/dist/telephony/RingCentralTelephonyService.d.ts +115 -0
  156. package/dist/telephony/RingCentralTelephonyService.d.ts.map +1 -0
  157. package/dist/telephony/RingCentralTelephonyService.js +262 -0
  158. package/dist/telephony/RingCentralTelephonyService.js.map +1 -0
  159. package/dist/telephony/TeamsMeetingsRouter.d.ts +40 -0
  160. package/dist/telephony/TeamsMeetingsRouter.d.ts.map +1 -0
  161. package/dist/telephony/TeamsMeetingsRouter.js +96 -0
  162. package/dist/telephony/TeamsMeetingsRouter.js.map +1 -0
  163. package/dist/telephony/TeamsMeetingsService.d.ts +113 -0
  164. package/dist/telephony/TeamsMeetingsService.d.ts.map +1 -0
  165. package/dist/telephony/TeamsMeetingsService.js +196 -0
  166. package/dist/telephony/TeamsMeetingsService.js.map +1 -0
  167. package/dist/telephony/TwilioTelephonyRouter.d.ts +36 -0
  168. package/dist/telephony/TwilioTelephonyRouter.d.ts.map +1 -0
  169. package/dist/telephony/TwilioTelephonyRouter.js +143 -0
  170. package/dist/telephony/TwilioTelephonyRouter.js.map +1 -0
  171. package/dist/telephony/TwilioTelephonyService.d.ts +95 -0
  172. package/dist/telephony/TwilioTelephonyService.d.ts.map +1 -0
  173. package/dist/telephony/TwilioTelephonyService.js +193 -0
  174. package/dist/telephony/TwilioTelephonyService.js.map +1 -0
  175. package/dist/telephony/VonageTelephonyRouter.d.ts +41 -0
  176. package/dist/telephony/VonageTelephonyRouter.d.ts.map +1 -0
  177. package/dist/telephony/VonageTelephonyRouter.js +201 -0
  178. package/dist/telephony/VonageTelephonyRouter.js.map +1 -0
  179. package/dist/telephony/VonageTelephonyService.d.ts +90 -0
  180. package/dist/telephony/VonageTelephonyService.d.ts.map +1 -0
  181. package/dist/telephony/VonageTelephonyService.js +191 -0
  182. package/dist/telephony/VonageTelephonyService.js.map +1 -0
  183. package/dist/telephony/calendar-scheduler.d.ts +67 -0
  184. package/dist/telephony/calendar-scheduler.d.ts.map +1 -0
  185. package/dist/telephony/calendar-scheduler.js +133 -0
  186. package/dist/telephony/calendar-scheduler.js.map +1 -0
  187. package/dist/telephony/index.d.ts +29 -0
  188. package/dist/telephony/index.d.ts.map +1 -0
  189. package/dist/telephony/index.js +38 -0
  190. package/dist/telephony/index.js.map +1 -0
  191. package/dist/telephony/media-upgrade-router.d.ts +33 -0
  192. package/dist/telephony/media-upgrade-router.d.ts.map +1 -0
  193. package/dist/telephony/media-upgrade-router.js +56 -0
  194. package/dist/telephony/media-upgrade-router.js.map +1 -0
  195. package/dist/telephony/ringcentral-runtime.d.ts +14 -0
  196. package/dist/telephony/ringcentral-runtime.d.ts.map +1 -0
  197. package/dist/telephony/ringcentral-runtime.js +18 -0
  198. package/dist/telephony/ringcentral-runtime.js.map +1 -0
  199. package/dist/telephony/teams-meetings-runtime.d.ts +16 -0
  200. package/dist/telephony/teams-meetings-runtime.d.ts.map +1 -0
  201. package/dist/telephony/teams-meetings-runtime.js +20 -0
  202. package/dist/telephony/teams-meetings-runtime.js.map +1 -0
  203. package/dist/telephony/teamsAcsMediaRegistry.d.ts +69 -0
  204. package/dist/telephony/teamsAcsMediaRegistry.d.ts.map +1 -0
  205. package/dist/telephony/teamsAcsMediaRegistry.js +118 -0
  206. package/dist/telephony/teamsAcsMediaRegistry.js.map +1 -0
  207. package/dist/telephony/telephony-runtime.d.ts +14 -0
  208. package/dist/telephony/telephony-runtime.d.ts.map +1 -0
  209. package/dist/telephony/telephony-runtime.js +18 -0
  210. package/dist/telephony/telephony-runtime.js.map +1 -0
  211. package/dist/telephony/twilioMediaRegistry.d.ts +60 -0
  212. package/dist/telephony/twilioMediaRegistry.d.ts.map +1 -0
  213. package/dist/telephony/twilioMediaRegistry.js +106 -0
  214. package/dist/telephony/twilioMediaRegistry.js.map +1 -0
  215. package/dist/telephony/vonage-runtime.d.ts +14 -0
  216. package/dist/telephony/vonage-runtime.d.ts.map +1 -0
  217. package/dist/telephony/vonage-runtime.js +18 -0
  218. package/dist/telephony/vonage-runtime.js.map +1 -0
  219. package/dist/telephony/vonageMediaRegistry.d.ts +78 -0
  220. package/dist/telephony/vonageMediaRegistry.d.ts.map +1 -0
  221. package/dist/telephony/vonageMediaRegistry.js +158 -0
  222. package/dist/telephony/vonageMediaRegistry.js.map +1 -0
  223. package/package.json +88 -82
  224. package/src/__tests__/FileResolverPeaks.test.ts +64 -0
  225. package/src/__tests__/MediaAccessKeys.test.ts +68 -0
  226. package/src/__tests__/MediaStreamHandler.test.ts +91 -0
  227. package/src/__tests__/RealtimeBridgeResolver.test.ts +10 -1
  228. package/src/__tests__/RealtimeClientSessionResolver.test.ts +69 -0
  229. package/src/__tests__/RealtimeCoAgentAppAwareness.integration.test.ts +191 -0
  230. package/src/__tests__/RemoteBrowserSnapshot.test.ts +123 -0
  231. package/src/__tests__/SessionManager.test.ts +2 -0
  232. package/src/__tests__/meetingRecordingRegistration.test.ts +248 -0
  233. package/src/__tests__/search-knowledge-tags.test.ts +9 -9
  234. package/src/__tests__/teams-meetings-service.test.ts +65 -0
  235. package/src/__tests__/teamsAcsMediaRegistry.test.ts +82 -0
  236. package/src/__tests__/twilio-telephony-service.test.ts +23 -0
  237. package/src/__tests__/twilioMediaRegistry.test.ts +103 -0
  238. package/src/__tests__/vonageMediaRegistry.test.ts +180 -0
  239. package/src/__tests__/widget.test.ts +204 -0
  240. package/src/__tests__/widgetGuestElevation.test.ts +57 -0
  241. package/src/__tests__/widgetHostIdentity.test.ts +117 -0
  242. package/src/agentSessions/ReturningVisitorRecap.ts +242 -0
  243. package/src/agentSessions/SessionJanitor.ts +66 -6
  244. package/src/agentSessions/SessionManager.ts +41 -0
  245. package/src/agentSessions/index.ts +3 -1
  246. package/src/auth/magicLink/MagicLinkRouter.ts +17 -0
  247. package/src/auth/magicLink/index.ts +1 -0
  248. package/src/auth/magicLink/types.ts +26 -0
  249. package/src/config.ts +172 -38
  250. package/src/context.ts +50 -3
  251. package/src/generated/generated.ts +26726 -20464
  252. package/src/generic/ResolverBase.ts +28 -0
  253. package/src/generic/RunViewResolver.ts +4 -0
  254. package/src/index.ts +119 -3
  255. package/src/integration/CustomColumnPromoter.ts +6 -0
  256. package/src/realtimeWidget/WidgetRouter.ts +204 -0
  257. package/src/realtimeWidget/WidgetSessionService.ts +714 -0
  258. package/src/realtimeWidget/host-identity.ts +84 -0
  259. package/src/realtimeWidget/index.ts +15 -0
  260. package/src/realtimeWidget/visitorIdentity.ts +258 -0
  261. package/src/realtimeWidget/widgetCore.ts +231 -0
  262. package/src/realtimeWidget/widgetGuestElevation.ts +115 -0
  263. package/src/resolvers/ComponentRegistryResolver.ts +36 -10
  264. package/src/resolvers/EntityPermissionResolver.ts +1 -2
  265. package/src/resolvers/FileResolver.ts +199 -1
  266. package/src/resolvers/QueryResolver.ts +33 -19
  267. package/src/resolvers/QuerySystemUserResolver.ts +14 -10
  268. package/src/resolvers/RealtimeBridgeResolver.ts +36 -4
  269. package/src/resolvers/RealtimeClientSessionResolver.ts +383 -9
  270. package/src/resolvers/RemoteBrowserActionResolver.ts +18 -2
  271. package/src/resolvers/RingCentralTelephonyResolver.ts +64 -0
  272. package/src/resolvers/RunAIAgentResolver.ts +60 -15
  273. package/src/resolvers/SearchKnowledgeResolver.ts +2 -0
  274. package/src/resolvers/TeamsMeetingsResolver.ts +68 -0
  275. package/src/resolvers/TelephonyResolver.ts +63 -0
  276. package/src/resolvers/TestQuerySQLResolver.ts +2 -3
  277. package/src/resolvers/VonageTelephonyResolver.ts +63 -0
  278. package/src/resolvers/meetingRecordingRegistration.ts +432 -0
  279. package/src/resolvers/peaksSidecar.ts +52 -0
  280. package/src/rest/MediaAccessKeys.ts +121 -0
  281. package/src/rest/MediaStreamHandler.ts +223 -0
  282. package/src/rest/mediaRange.ts +76 -0
  283. package/src/telephony/RingCentralTelephonyService.ts +342 -0
  284. package/src/telephony/TeamsMeetingsRouter.ts +124 -0
  285. package/src/telephony/TeamsMeetingsService.ts +268 -0
  286. package/src/telephony/TwilioTelephonyRouter.ts +184 -0
  287. package/src/telephony/TwilioTelephonyService.ts +261 -0
  288. package/src/telephony/VonageTelephonyRouter.ts +239 -0
  289. package/src/telephony/VonageTelephonyService.ts +259 -0
  290. package/src/telephony/calendar-scheduler.ts +176 -0
  291. package/src/telephony/index.ts +43 -0
  292. package/src/telephony/media-upgrade-router.ts +62 -0
  293. package/src/telephony/ringcentral-runtime.ts +22 -0
  294. package/src/telephony/teams-meetings-runtime.ts +24 -0
  295. package/src/telephony/teamsAcsMediaRegistry.ts +152 -0
  296. package/src/telephony/telephony-runtime.ts +22 -0
  297. package/src/telephony/twilioMediaRegistry.ts +137 -0
  298. package/src/telephony/vonage-runtime.ts +22 -0
  299. package/src/telephony/vonageMediaRegistry.ts +200 -0
  300. package/dist/agents/skip-agent.d.ts +0 -111
  301. package/dist/agents/skip-agent.d.ts.map +0 -1
  302. package/dist/agents/skip-agent.js +0 -1487
  303. package/dist/agents/skip-agent.js.map +0 -1
  304. package/dist/agents/skip-sdk.d.ts +0 -261
  305. package/dist/agents/skip-sdk.d.ts.map +0 -1
  306. package/dist/agents/skip-sdk.js +0 -909
  307. package/dist/agents/skip-sdk.js.map +0 -1
  308. package/src/agents/skip-agent.ts +0 -1594
  309. package/src/agents/skip-sdk.ts +0 -1210
@@ -0,0 +1,182 @@
1
+ /**
2
+ * @fileoverview Express wiring for the public web widget guest-session endpoints.
3
+ *
4
+ * Mirrors the magic-link public-router pattern: a single PUBLIC router
5
+ * (unauthenticated) mounted BEFORE the unified auth middleware. The widget reuses
6
+ * the magic-link RS256 key + the registered `magic-link` auth provider for token
7
+ * validation, so this module ensures both are initialized (idempotently) even when
8
+ * `magicLink.enabled` is false — the widget can stand on its own.
9
+ *
10
+ * @module @memberjunction/server/widget
11
+ */
12
+ import { Router, json } from 'express';
13
+ import { rateLimit } from 'express-rate-limit';
14
+ import { LogStatus } from '@memberjunction/core';
15
+ import { configInfo } from '../config.js';
16
+ import { MagicLinkKeyManager } from '../auth/magicLink/MagicLinkKeys.js';
17
+ import { registerMagicLinkAuthProvider } from '../auth/magicLink/MagicLinkRouter.js';
18
+ import { WidgetSessionService } from './WidgetSessionService.js';
19
+ import { looksLikeBot } from './widgetCore.js';
20
+ /** The mount path for the widget public router (`/widget`). */
21
+ export const WIDGET_MOUNT_PATH = '/widget';
22
+ /**
23
+ * Ensures the magic-link signing key is initialized and the `magic-link` auth
24
+ * provider is registered, so widget tokens (signed with that key) validate. Safe to
25
+ * call when magic-link is already enabled — both operations are idempotent.
26
+ */
27
+ function ensureWidgetSigning(publicUrl, widgetConfig) {
28
+ const mlConfig = configInfo.magicLink;
29
+ // The widget shares the magic-link audience so the same provider validates its
30
+ // tokens; surface a clear log if a deployment diverged them.
31
+ if (mlConfig?.audience && mlConfig.audience !== widgetConfig.audience) {
32
+ LogStatus(`[Widget] WARNING: widget.audience ('${widgetConfig.audience}') != magicLink.audience ('${mlConfig.audience}'). ` +
33
+ `Widget tokens will not validate unless an auth provider is registered for the widget audience.`);
34
+ }
35
+ MagicLinkKeyManager.Instance.Initialize(mlConfig?.rsaPrivateKey);
36
+ // Register the magic-link provider against the magic-link config (its audience),
37
+ // which is what validates widget tokens. No-op if already registered.
38
+ if (mlConfig) {
39
+ registerMagicLinkAuthProvider(publicUrl, mlConfig);
40
+ }
41
+ }
42
+ /**
43
+ * Builds the widget routers. Mount `publicRouter` at WIDGET_MOUNT_PATH BEFORE the unified auth
44
+ * middleware (the mint/forget endpoints are public — visitors have no MJ JWT yet) and
45
+ * `authenticatedRouter` at the same path AFTER it (the RV4 resolve-identity endpoint needs the
46
+ * verified principal from `req.userPayload`).
47
+ */
48
+ export function createWidgetHandler(publicUrl, config) {
49
+ ensureWidgetSigning(publicUrl, config);
50
+ const service = new WidgetSessionService(publicUrl, config);
51
+ // Per-instance DYNAMIC mint limiter (W6 hardening): keyed by (widgetKey + IP) so each widget
52
+ // deployment gets its own bucket and one abusive IP can't exhaust a shared instance's budget for
53
+ // everyone. The per-request `limit` is the widget instance's stored `RateLimitPerMinute` (cached,
54
+ // resolved from the parsed body), falling back to the deployment-wide default for an unknown key.
55
+ // `json()` runs FIRST so the key generator + limit can read `req.body.widgetKey`.
56
+ const mintLimiter = rateLimit({
57
+ windowMs: config.rateLimitWindowMs,
58
+ standardHeaders: 'draft-7',
59
+ legacyHeaders: false,
60
+ keyGenerator: (req) => `${readWidgetKey(req)}:${req.ip ?? 'noip'}`,
61
+ limit: async (req) => service.ResolvePerInstanceRateLimit(readWidgetKey(req)),
62
+ message: { success: false, errorCode: 'rate_limited', error: 'Too many widget session requests. Try again later.' },
63
+ });
64
+ const publicRouter = Router();
65
+ publicRouter.post('/session', json(), mintLimiter, async (req, res) => {
66
+ await handleMint(service, req, res, false);
67
+ });
68
+ publicRouter.post('/session/refresh', json(), mintLimiter, async (req, res) => {
69
+ await handleMint(service, req, res, true);
70
+ });
71
+ // W5 magic-link upgrade ("Verify it's you"): emails a verification link scoped to the widget's app.
72
+ // Same dynamic limiter as mint — it issues an email invite, a comparable cost/abuse surface.
73
+ publicRouter.post('/upgrade', json(), mintLimiter, async (req, res) => {
74
+ await handleUpgrade(service, req, res);
75
+ });
76
+ // RV5 "forget me": archive the visitor's memory + clear the VisitorKey linkage. Public — the visitor
77
+ // proves possession of the durable key (not an identity). Same dynamic limiter as mint.
78
+ publicRouter.post('/forget', json(), mintLimiter, async (req, res) => {
79
+ await handleForget(service, req, res);
80
+ });
81
+ // RV4 resolve-identity: promote the visitor's anonymous trail to the verified record. AUTHENTICATED —
82
+ // it reads the verified principal's email from req.userPayload, so it mounts after the auth middleware.
83
+ const authenticatedRouter = Router();
84
+ authenticatedRouter.post('/resolve-identity', json(), mintLimiter, async (req, res) => {
85
+ await handleResolveIdentity(service, req, res);
86
+ });
87
+ return { publicRouter, authenticatedRouter };
88
+ }
89
+ /** Reads the `widgetKey` from a parsed JSON body, or '' when absent (used to key the dynamic limiter). */
90
+ function readWidgetKey(req) {
91
+ const body = (req.body ?? {});
92
+ return typeof body.widgetKey === 'string' ? body.widgetKey.trim() : '';
93
+ }
94
+ /** Handles "forget me" (RV5) — parses the body, calls the service, maps the status. */
95
+ async function handleForget(service, req, res) {
96
+ const body = (req.body ?? {});
97
+ const widgetKey = typeof body.widgetKey === 'string' ? body.widgetKey : '';
98
+ const visitorKey = typeof body.visitorKey === 'string' ? body.visitorKey : '';
99
+ if (!widgetKey) {
100
+ res.status(400).json({ success: false, errorCode: 'not_found', error: 'widgetKey is required.' });
101
+ return;
102
+ }
103
+ const result = await service.ForgetVisitor({ widgetKey, visitorKey, origin: req.get('origin') ?? undefined });
104
+ res.status(result.success ? 200 : result.errorCode === 'server_error' ? 500 : 403).json(result);
105
+ }
106
+ /**
107
+ * Handles RV4 resolve-identity — reads the verified email from the authenticated principal
108
+ * (`req.userPayload.userRecord`), parses the body, calls the service, maps the status.
109
+ */
110
+ async function handleResolveIdentity(service, req, res) {
111
+ const verifiedUser = req.userPayload?.userRecord;
112
+ if (!verifiedUser?.Email) {
113
+ res.status(401).json({ success: false, errorCode: 'server_error', error: 'Authentication required.' });
114
+ return;
115
+ }
116
+ const body = (req.body ?? {});
117
+ const widgetKey = typeof body.widgetKey === 'string' ? body.widgetKey : '';
118
+ const visitorKey = typeof body.visitorKey === 'string' ? body.visitorKey : '';
119
+ if (!widgetKey) {
120
+ res.status(400).json({ success: false, errorCode: 'not_found', error: 'widgetKey is required.' });
121
+ return;
122
+ }
123
+ const result = await service.ResolveVisitorIdentity({
124
+ widgetKey,
125
+ visitorKey,
126
+ verifiedEmail: verifiedUser.Email,
127
+ origin: req.get('origin') ?? undefined,
128
+ });
129
+ res.status(result.success ? 200 : result.errorCode === 'server_error' ? 500 : 403).json(result);
130
+ }
131
+ /** Handles the magic-link upgrade request — parses the body, calls the service, maps the status. */
132
+ async function handleUpgrade(service, req, res) {
133
+ const body = (req.body ?? {});
134
+ const widgetKey = typeof body.widgetKey === 'string' ? body.widgetKey : '';
135
+ const email = typeof body.email === 'string' ? body.email : '';
136
+ if (!widgetKey) {
137
+ res.status(400).json({ success: false, errorCode: 'not_found', error: 'widgetKey is required.' });
138
+ return;
139
+ }
140
+ const result = await service.RequestUpgrade({ widgetKey, email, origin: req.get('origin') ?? undefined });
141
+ // 400 for a bad email (client can fix it); 403 for any policy rejection (uniform, non-enumerable); 500 for faults.
142
+ const status = result.success ? 200 : result.errorCode === 'invalid_email' ? 400 : result.errorCode === 'server_error' ? 500 : 403;
143
+ res.status(status).json(result);
144
+ }
145
+ /** Shared mint/refresh handler — parses the request, calls the service, maps the status. */
146
+ async function handleMint(service, req, res, refresh) {
147
+ const body = (req.body ?? {});
148
+ const widgetKey = typeof body.widgetKey === 'string' ? body.widgetKey : '';
149
+ if (!widgetKey) {
150
+ res.status(400).json({ success: false, errorCode: 'not_found', error: 'widgetKey is required.' });
151
+ return;
152
+ }
153
+ // W6 hardening: coarse bot/automation rejection before any DB lookup or token mint. Returns the same
154
+ // 403 as a policy rejection so a probe can't distinguish "bot-blocked" from "bad key/origin".
155
+ if (looksLikeBot(req.get('user-agent'))) {
156
+ res.status(403).json({ success: false, errorCode: 'origin_not_allowed', error: 'Widget mint rejected.' });
157
+ return;
158
+ }
159
+ const origin = req.get('origin') ?? undefined;
160
+ const input = {
161
+ widgetKey,
162
+ origin,
163
+ hostAssertion: typeof body.hostAssertion === 'string' ? body.hostAssertion : undefined,
164
+ visitorKey: typeof body.visitorKey === 'string' ? body.visitorKey : undefined,
165
+ audit: { ipAddress: req.ip, userAgent: req.get('user-agent') ?? undefined, origin },
166
+ };
167
+ const result = refresh ? await service.RefreshGuestSession(input) : await service.MintGuestSession(input);
168
+ res.status(statusForResult(result)).json(result);
169
+ }
170
+ /**
171
+ * Maps a mint result to an HTTP status. All client-side rejections (unknown key,
172
+ * disabled widget, disallowed origin, modality off) return 403 — deliberately
173
+ * uniform so a probe cannot distinguish "no such widget" from "wrong origin" and
174
+ * enumerate valid keys. Only true server faults return 500.
175
+ */
176
+ function statusForResult(result) {
177
+ if (result.success) {
178
+ return 200;
179
+ }
180
+ return result.errorCode === 'server_error' ? 500 : 403;
181
+ }
182
+ //# sourceMappingURL=WidgetRouter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WidgetRouter.js","sourceRoot":"","sources":["../../src/realtimeWidget/WidgetRouter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,MAAM,EAAE,IAAI,EAA+B,MAAM,SAAS,CAAC;AACpE,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAqB,MAAM,cAAc,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,EAAE,6BAA6B,EAAE,MAAM,sCAAsC,CAAC;AACrF,OAAO,EAAE,oBAAoB,EAA+B,MAAM,2BAA2B,CAAC;AAC9F,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,+DAA+D;AAC/D,MAAM,CAAC,MAAM,iBAAiB,GAAG,SAAS,CAAC;AAE3C;;;;GAIG;AACH,SAAS,mBAAmB,CAAC,SAAiB,EAAE,YAA0B;IACxE,MAAM,QAAQ,GAAG,UAAU,CAAC,SAAS,CAAC;IACtC,+EAA+E;IAC/E,6DAA6D;IAC7D,IAAI,QAAQ,EAAE,QAAQ,IAAI,QAAQ,CAAC,QAAQ,KAAK,YAAY,CAAC,QAAQ,EAAE,CAAC;QACtE,SAAS,CACP,uCAAuC,YAAY,CAAC,QAAQ,8BAA8B,QAAQ,CAAC,QAAQ,MAAM;YACjH,gGAAgG,CACjG,CAAC;IACJ,CAAC;IACD,mBAAmB,CAAC,QAAQ,CAAC,UAAU,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IACjE,iFAAiF;IACjF,sEAAsE;IACtE,IAAI,QAAQ,EAAE,CAAC;QACb,6BAA6B,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACrD,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,SAAiB,EAAE,MAAoB;IACzE,mBAAmB,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAEvC,MAAM,OAAO,GAAG,IAAI,oBAAoB,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAE5D,6FAA6F;IAC7F,iGAAiG;IACjG,kGAAkG;IAClG,kGAAkG;IAClG,kFAAkF;IAClF,MAAM,WAAW,GAAG,SAAS,CAAC;QAC5B,QAAQ,EAAE,MAAM,CAAC,iBAAiB;QAClC,eAAe,EAAE,SAAS;QAC1B,aAAa,EAAE,KAAK;QACpB,YAAY,EAAE,CAAC,GAAY,EAAE,EAAE,CAAC,GAAG,aAAa,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,EAAE,IAAI,MAAM,EAAE;QAC3E,KAAK,EAAE,KAAK,EAAE,GAAY,EAAE,EAAE,CAAC,OAAO,CAAC,2BAA2B,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QACtF,OAAO,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,KAAK,EAAE,oDAAoD,EAAE;KACpH,CAAC,CAAC;IAEH,MAAM,YAAY,GAAG,MAAM,EAAE,CAAC;IAE9B,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QACvF,MAAM,UAAU,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,YAAY,CAAC,IAAI,CAAC,kBAAkB,EAAE,IAAI,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QAC/F,MAAM,UAAU,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,oGAAoG;IACpG,6FAA6F;IAC7F,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QACvF,MAAM,aAAa,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,qGAAqG;IACrG,wFAAwF;IACxF,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QACtF,MAAM,YAAY,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,sGAAsG;IACtG,wGAAwG;IACxG,MAAM,mBAAmB,GAAG,MAAM,EAAE,CAAC;IACrC,mBAAmB,CAAC,IAAI,CAAC,mBAAmB,EAAE,IAAI,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QACvG,MAAM,qBAAqB,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,CAAC;AAC/C,CAAC;AAED,0GAA0G;AAC1G,SAAS,aAAa,CAAC,GAAY;IACjC,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAA2B,CAAC;IACxD,OAAO,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACzE,CAAC;AAED,uFAAuF;AACvF,KAAK,UAAU,YAAY,CAAC,OAA6B,EAAE,GAAY,EAAE,GAAa;IACpF,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAgD,CAAC;IAC7E,MAAM,SAAS,GAAG,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3E,MAAM,UAAU,GAAG,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9E,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC,CAAC;QAClG,OAAO;IACT,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,SAAS,EAAE,CAAC,CAAC;IAC9G,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,KAAK,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAClG,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,qBAAqB,CAAC,OAA6B,EAAE,GAAY,EAAE,GAAa;IAC7F,MAAM,YAAY,GAAG,GAAG,CAAC,WAAW,EAAE,UAAU,CAAC;IACjD,IAAI,CAAC,YAAY,EAAE,KAAK,EAAE,CAAC;QACzB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,KAAK,EAAE,0BAA0B,EAAE,CAAC,CAAC;QACvG,OAAO;IACT,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAgD,CAAC;IAC7E,MAAM,SAAS,GAAG,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3E,MAAM,UAAU,GAAG,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9E,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC,CAAC;QAClG,OAAO;IACT,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,sBAAsB,CAAC;QAClD,SAAS;QACT,UAAU;QACV,aAAa,EAAE,YAAY,CAAC,KAAK;QACjC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,SAAS;KACvC,CAAC,CAAC;IACH,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,KAAK,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAClG,CAAC;AAED,oGAAoG;AACpG,KAAK,UAAU,aAAa,CAAC,OAA6B,EAAE,GAAY,EAAE,GAAa;IACrF,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAA2C,CAAC;IACxE,MAAM,SAAS,GAAG,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3E,MAAM,KAAK,GAAG,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/D,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC,CAAC;QAClG,OAAO;IACT,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,cAAc,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,SAAS,EAAE,CAAC,CAAC;IAC1G,mHAAmH;IACnH,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,KAAK,eAAe,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,KAAK,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IACnI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAClC,CAAC;AAED,4FAA4F;AAC5F,KAAK,UAAU,UAAU,CAAC,OAA6B,EAAE,GAAY,EAAE,GAAa,EAAE,OAAgB;IACpG,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAwE,CAAC;IACrG,MAAM,SAAS,GAAG,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3E,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC,CAAC;QAClG,OAAO;IACT,CAAC;IAED,qGAAqG;IACrG,8FAA8F;IAC9F,IAAI,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC;QACxC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,oBAAoB,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC,CAAC;QAC1G,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,SAAS,CAAC;IAC9C,MAAM,KAAK,GAAG;QACZ,SAAS;QACT,MAAM;QACN,aAAa,EAAE,OAAO,IAAI,CAAC,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS;QACtF,UAAU,EAAE,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS;QAC7E,KAAK,EAAE,EAAE,SAAS,EAAE,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,SAAS,EAAE,MAAM,EAAE;KACpF,CAAC;IACF,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;IAC1G,GAAG,CAAC,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACnD,CAAC;AAED;;;;;GAKG;AACH,SAAS,eAAe,CAAC,MAA8B;IACrD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,GAAG,CAAC;IACb,CAAC;IACD,OAAO,MAAM,CAAC,SAAS,KAAK,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;AACzD,CAAC"}
@@ -0,0 +1,265 @@
1
+ /**
2
+ * @fileoverview Imperative shell for public web widget guest sessions: resolves a
3
+ * widget instance by its public key, enforces the origin allowlist + status, and
4
+ * mints a short-lived anonymous guest session JWT by reusing the magic-link RS256
5
+ * key + `anonymous-embed` synthesis. The pure logic lives in `widgetCore.ts`.
6
+ *
7
+ * Design (per public-web-widget.md W1 + open-Q #1): DIRECT-MINT for anonymous
8
+ * guests — no MagicLinkInvite row is created (those model single-use invites; a
9
+ * widget guest is ephemeral). Forensics ride the opaque per-session id (`mj_sid`)
10
+ * carried in the token, plus best-effort structured audit logging. The minted
11
+ * token is validated by the SAME `magic-link` auth provider (same issuer/audience/
12
+ * JWKS) and synthesized into a constrained guest principal by `buildMagicLinkSessionUser`.
13
+ *
14
+ * @module @memberjunction/server/widget
15
+ */
16
+ import { type WidgetConfig } from '../config.js';
17
+ import { type WidgetMintErrorCode } from './widgetCore.js';
18
+ import { type ResolvedVisitorIdentity } from './visitorIdentity.js';
19
+ /** Per-request forensic context captured for audit (sourced from the HTTP request). */
20
+ export interface WidgetMintAuditContext {
21
+ ipAddress?: string;
22
+ userAgent?: string;
23
+ origin?: string;
24
+ }
25
+ /** Input to mint a guest session. */
26
+ export interface MintGuestSessionInput {
27
+ /** The widget's public embed key (pk_live_…). */
28
+ widgetKey: string;
29
+ /** The request's Origin header — enforced against the instance allowlist. */
30
+ origin?: string;
31
+ /**
32
+ * A host-signed RS256 identity assertion (D1 `host-identity` strategy). Required when the
33
+ * resolved widget's AuthStrategy is `HostIdentity`; ignored otherwise. Verified against the
34
+ * host's registered public key; its identity is carried as informational claims only.
35
+ */
36
+ hostAssertion?: string;
37
+ /**
38
+ * The durable returning-visitor anchor (RV1) the client presents from its first-party cookie.
39
+ * Honored only when the widget's `RememberReturningVisitors` toggle is on: a valid presented key
40
+ * chains this visit to the visitor's prior conversation; absent/invalid on a first visit, the
41
+ * server mints a fresh one. Ignored entirely when remembering is off.
42
+ */
43
+ visitorKey?: string;
44
+ audit?: WidgetMintAuditContext;
45
+ }
46
+ /** Result of a guest-session mint. */
47
+ export interface MintGuestSessionResult {
48
+ success: boolean;
49
+ /** The minted session JWT (RS256), held by the widget in memory and refreshed before expiry. */
50
+ token?: string;
51
+ /** ISO expiry of the session token. */
52
+ expiresAt?: string;
53
+ /** The widget instance id (also carried as the `mj_widget_id` claim). */
54
+ widgetId?: string;
55
+ /** The Application the session is scoped to. */
56
+ applicationId?: string;
57
+ /** The pinned support agent the widget passes as explicitAgentId for every turn (D5). */
58
+ pinnedAgentId?: string;
59
+ /** Which modalities this widget exposes (drives the widget UI). */
60
+ modality?: string;
61
+ /**
62
+ * The opaque per-session id (also the signed scope resourceId). The widget stamps
63
+ * Conversation.ExternalID with this so the Widget Guest RLS filters isolate this guest's rows.
64
+ */
65
+ sessionId?: string;
66
+ /**
67
+ * Optional hard ceiling (minutes) on a voice session for this widget. Surfaced so the client
68
+ * voice-abuse guard uses the deployment-configured limit; also enforced server-side at mint.
69
+ */
70
+ voiceMaxSessionMinutes?: number;
71
+ /** Whether returning-visitor memory is enabled for this widget (gates the cookie + chaining). */
72
+ rememberReturningVisitors?: boolean;
73
+ /**
74
+ * The durable visitor anchor to persist as a cookie (RV1). Set only when remembering is on:
75
+ * the validated key the client presented, or a freshly minted one on a first visit.
76
+ */
77
+ visitorKey?: string;
78
+ /** The visitor's prior conversation for this anchor (RV2 chain); set only on a returning visit. */
79
+ lastConversationId?: string;
80
+ /**
81
+ * The resolved polymorphic identity entity id (RV4), set only when a host-identity widget asserted a
82
+ * resolvable identity at mint. The client stamps it (with {@link MintGuestSessionResult.linkedRecordId})
83
+ * onto the new conversation so memory injection (RV3) keys off the resolved record, not the cookie.
84
+ */
85
+ linkedEntityId?: string;
86
+ /** The resolved polymorphic identity record id (RV4); paired with {@link MintGuestSessionResult.linkedEntityId}. */
87
+ linkedRecordId?: string;
88
+ /**
89
+ * Interactive channels (by name, e.g. `["Whiteboard"]`) this widget may attach when voice is active
90
+ * (Phase 2). Mirrors the widget instance's `EnabledChannels`; empty (the default) = no channels.
91
+ */
92
+ enabledChannels?: string[];
93
+ error?: string;
94
+ errorCode?: WidgetMintErrorCode;
95
+ }
96
+ /** Input to resolve a returning visitor's identity after they verify (RV4, magic-link upgrade path). */
97
+ export interface ResolveVisitorIdentityInput {
98
+ /** The widget's public embed key. */
99
+ widgetKey: string;
100
+ /** The durable returning-visitor anchor whose trail should be promoted to the verified identity. */
101
+ visitorKey: string;
102
+ /** The verified visitor's email (from the authenticated session) — resolved to a record via config. */
103
+ verifiedEmail: string;
104
+ /** The request's Origin header — enforced against the instance allowlist. */
105
+ origin?: string;
106
+ }
107
+ /** Result of an RV4 identity resolve+merge. */
108
+ export interface ResolveVisitorIdentityResult {
109
+ success: boolean;
110
+ /** The resolved polymorphic pair, when a record matched the verified email. */
111
+ resolved?: ResolvedVisitorIdentity;
112
+ /** How many conversations were stamped with the resolved identity. */
113
+ mergedConversations?: number;
114
+ error?: string;
115
+ errorCode?: WidgetMintErrorCode;
116
+ }
117
+ /** Input to a "forget me" request (RV5). */
118
+ export interface ForgetVisitorInput {
119
+ /** The widget's public embed key. */
120
+ widgetKey: string;
121
+ /** The durable returning-visitor anchor to forget. */
122
+ visitorKey: string;
123
+ /** The request's Origin header — enforced against the instance allowlist. */
124
+ origin?: string;
125
+ }
126
+ /** Result of a "forget me" request (RV5). */
127
+ export interface ForgetVisitorResult {
128
+ success: boolean;
129
+ /** Count of memory notes archived. */
130
+ notesArchived?: number;
131
+ /** Count of conversations whose VisitorKey linkage was cleared. */
132
+ conversationsCleared?: number;
133
+ error?: string;
134
+ errorCode?: WidgetMintErrorCode;
135
+ }
136
+ /** Input to request a magic-link identity upgrade for a live guest session (W5). */
137
+ export interface UpgradeGuestSessionInput {
138
+ /** The widget's public embed key. */
139
+ widgetKey: string;
140
+ /** The email to send the verification link to (becomes the provisioned user's email). */
141
+ email: string;
142
+ /** The request's Origin header — enforced against the instance allowlist. */
143
+ origin?: string;
144
+ }
145
+ /** Result of a magic-link upgrade request. Never carries the token (delivered by email, out-of-band). */
146
+ export interface UpgradeGuestSessionResult {
147
+ success: boolean;
148
+ /** Whether the verification email was dispatched (false when no comms provider is configured). */
149
+ emailSent?: boolean;
150
+ error?: string;
151
+ errorCode?: WidgetMintErrorCode;
152
+ }
153
+ /**
154
+ * Mints constrained, short-lived guest sessions for the public web widget.
155
+ * Stateless; constructed once at server startup alongside the magic-link service.
156
+ */
157
+ export declare class WidgetSessionService {
158
+ private readonly publicUrl;
159
+ private readonly config;
160
+ constructor(publicUrl: string, config: WidgetConfig);
161
+ /**
162
+ * Resolves the widget instance, enforces guardrails, and mints a guest JWT.
163
+ * Never throws for business failures — returns `{ success: false, errorCode }`.
164
+ */
165
+ MintGuestSession(input: MintGuestSessionInput): Promise<MintGuestSessionResult>;
166
+ /**
167
+ * Refreshes a live guest session. The widget always holds its public key, so a
168
+ * refresh is a fresh mint by the same key + origin — short-TTL tokens with no
169
+ * refresh-token machinery (mirrors magic-link's no-refresh-token stance).
170
+ */
171
+ RefreshGuestSession(input: MintGuestSessionInput): Promise<MintGuestSessionResult>;
172
+ /** Short-TTL cache of resolved per-instance rate limits, so the limiter doesn't hit the DB per request. */
173
+ private readonly rateLimitCache;
174
+ private static readonly RATE_LIMIT_CACHE_TTL_MS;
175
+ /**
176
+ * Resolves the per-instance `RateLimitPerMinute` for a widget key (W6 hardening), falling back to the
177
+ * deployment-wide `defaultRateLimitPerMinute` for an unknown/invalid key (so an enumeration probe is
178
+ * still bounded by the coarse default). Cached for a short TTL so the dynamic limiter — which runs on
179
+ * EVERY mint request — does not issue a DB read per request. Never throws.
180
+ */
181
+ ResolvePerInstanceRateLimit(widgetKey: string): Promise<number>;
182
+ /**
183
+ * W5 magic-link upgrade — "Verify it's you". For a widget whose AuthStrategy is `MagicLinkUpgrade`,
184
+ * a guest supplies their email and we issue a single-use **email-mode** magic-link invite scoped to
185
+ * the widget's Application (under the server principal — `CreateInvite` is Owner-gated). The visitor
186
+ * clicks the emailed link → the existing public `POST /magic-link/redeem` mints a VERIFIED session
187
+ * JWT → the widget swaps it in via `transport.UpdateToken`, preserving the live conversationId.
188
+ *
189
+ * This converges on the SAME `AuthProviderFactory` + `buildMagicLinkSessionUser` path as the guest
190
+ * mint (D1), so the verified session is just a more-privileged principal on the one pathway. Never
191
+ * throws for business failures — returns a structured result.
192
+ */
193
+ RequestUpgrade(input: UpgradeGuestSessionInput): Promise<UpgradeGuestSessionResult>;
194
+ /**
195
+ * Verifies a host-identity assertion for a HostIdentity widget against the host's
196
+ * registered public key (config interim store, keyed by widget PublicKey). Fails closed
197
+ * when the key is absent or the assertion is missing/invalid.
198
+ */
199
+ private verifyHost;
200
+ /** Builds + signs the guest JWT for an eligible widget instance. */
201
+ private mintToken;
202
+ /**
203
+ * RV4 (host-identity path): when a `HostIdentity` widget asserts a resolvable identity AND remembering
204
+ * is on, resolve the asserted email to a polymorphic record and merge the visitor's prior anonymous
205
+ * trail onto it. Returns the resolved pair (so the client stamps the new conversation), or undefined
206
+ * when not applicable or no record matched. Best-effort — never blocks the mint.
207
+ */
208
+ private resolveHostIdentityIfApplicable;
209
+ /**
210
+ * RV4 (magic-link upgrade path): after a visitor verifies their identity, promote their anonymous
211
+ * trail to the verified record. Called from the AUTHENTICATED route with the verified session's email,
212
+ * so the resolved record is the deployment-configured target for that email (default: the MJ User).
213
+ * Validates the widget + origin + opt-in + key, then resolves and merges. Never throws.
214
+ */
215
+ ResolveVisitorIdentity(input: ResolveVisitorIdentityInput): Promise<ResolveVisitorIdentityResult>;
216
+ /**
217
+ * RV5 "forget me": archives the visitor's auto-generated memory and clears the VisitorKey linkage for
218
+ * this anchor in the widget's application. Public (the visitor proves possession of the durable key,
219
+ * not an identity). Validates the widget + origin + opt-in + key, then delegates to {@link forgetVisitor}.
220
+ */
221
+ ForgetVisitor(input: ForgetVisitorInput): Promise<ForgetVisitorResult>;
222
+ /**
223
+ * Shared guard for the RV4/RV5 visitor-privacy endpoints: resolves the lookup user, loads + validates
224
+ * the widget (status/origin), requires returning-visitor memory to be ON, and validates the presented
225
+ * VisitorKey shape. Returns the resolved widget + context user on success, or a structured failure.
226
+ */
227
+ private gateVisitorPrivacyRequest;
228
+ /**
229
+ * Resolves the returning-visitor anchor for a mint (RV1). Returns undefined when the widget does NOT
230
+ * opt in (RememberReturningVisitors off) — the default, fully-off path: no cookie, no chaining.
231
+ * When on: validates the presented key (else mints a fresh one) and, for a returning key, finds the
232
+ * visitor's most-recent prior conversation in this widget's application to chain from. Best-effort:
233
+ * a lookup failure degrades to "no prior conversation" rather than blocking the session.
234
+ */
235
+ private resolveReturningVisitor;
236
+ /**
237
+ * Recaps the visitor's prior conversation when they return (RV2, text path). No-op unless this is a
238
+ * returning visit (a resolved `lastConversationId`). Delegates to the shared, idempotent,
239
+ * best-effort {@link writeReturningVisitorRecap}, attributing the recap to the widget's pinned agent
240
+ * and stamping the widget's `VisitorMemoryRetentionDays` as the note's expiry. Awaited so the recap
241
+ * note exists before the new session's memory injection (RV3) runs; the recap's own idempotency
242
+ * bounds the LLM cost to the first return after each prior conversation.
243
+ */
244
+ private recapPriorConversationIfNeeded;
245
+ /**
246
+ * Finds the visitor's most-recent prior conversation for a VisitorKey, scoped to the widget's
247
+ * application so a key can never resolve a conversation from a different deployment. Returns the
248
+ * id or undefined (first visit, or read failure — never throws).
249
+ */
250
+ private findPreviousConversationByVisitorKey;
251
+ /** Loads a single widget instance by its public key (read-only, simple result). */
252
+ private loadWidgetByKey;
253
+ /** Resolves the guest role's NAME from its id (claims carry the name, not the id). */
254
+ private resolveGuestRoleName;
255
+ /** Resolves the server-side context user used to READ widget config (not the guest principal). */
256
+ private resolveLookupUser;
257
+ /**
258
+ * Best-effort structured audit of a mint attempt. Never alters the result — losing
259
+ * an audit line must not change whether a visitor got (or was denied) a session.
260
+ * (A dedicated `MJ: Widget Session` audit entity is a follow-on; for now this is a
261
+ * structured log line carrying the same forensics as the magic-link redemption row.)
262
+ */
263
+ private audited;
264
+ }
265
+ //# sourceMappingURL=WidgetSessionService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WidgetSessionService.d.ts","sourceRoot":"","sources":["../../src/realtimeWidget/WidgetSessionService.ts"],"names":[],"mappings":"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"}