@memberjunction/server 6.1.0-edge.5 → 6.1.0-edge.7

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 (250) hide show
  1. package/README.md +30 -11
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/agentSessions/SessionJanitor.js +2 -2
  4. package/dist/agentSessions/SessionJanitor.js.map +1 -1
  5. package/dist/auth/exampleNewUserSubClass.d.ts.map +1 -1
  6. package/dist/auth/exampleNewUserSubClass.js +9 -4
  7. package/dist/auth/exampleNewUserSubClass.js.map +1 -1
  8. package/dist/auth/magicLink/MagicLinkService.d.ts.map +1 -1
  9. package/dist/auth/magicLink/MagicLinkService.js +2 -8
  10. package/dist/auth/magicLink/MagicLinkService.js.map +1 -1
  11. package/dist/auth/newUsers.d.ts.map +1 -1
  12. package/dist/auth/newUsers.js +4 -12
  13. package/dist/auth/newUsers.js.map +1 -1
  14. package/dist/auth/principals.d.ts +92 -0
  15. package/dist/auth/principals.d.ts.map +1 -0
  16. package/dist/auth/principals.js +193 -0
  17. package/dist/auth/principals.js.map +1 -0
  18. package/dist/config.d.ts +106 -12
  19. package/dist/config.d.ts.map +1 -1
  20. package/dist/config.js +41 -4
  21. package/dist/config.js.map +1 -1
  22. package/dist/entitySubclasses/MJEntityPermissionEntityServer.server.d.ts +30 -0
  23. package/dist/entitySubclasses/MJEntityPermissionEntityServer.server.d.ts.map +1 -1
  24. package/dist/entitySubclasses/MJEntityPermissionEntityServer.server.js +58 -5
  25. package/dist/entitySubclasses/MJEntityPermissionEntityServer.server.js.map +1 -1
  26. package/dist/generated/graphql-schemas/__mj.d.ts +7607 -6853
  27. package/dist/generated/graphql-schemas/__mj.d.ts.map +1 -1
  28. package/dist/generated/graphql-schemas/__mj.js +25141 -21645
  29. package/dist/generated/graphql-schemas/__mj.js.map +1 -1
  30. package/dist/generic/ResolverBase.d.ts +152 -2
  31. package/dist/generic/ResolverBase.d.ts.map +1 -1
  32. package/dist/generic/ResolverBase.js +389 -10
  33. package/dist/generic/ResolverBase.js.map +1 -1
  34. package/dist/generic/RunViewResolver.d.ts.map +1 -1
  35. package/dist/generic/RunViewResolver.js +26 -2
  36. package/dist/generic/RunViewResolver.js.map +1 -1
  37. package/dist/generic/refusalExtensions.d.ts +52 -0
  38. package/dist/generic/refusalExtensions.d.ts.map +1 -0
  39. package/dist/generic/refusalExtensions.js +16 -0
  40. package/dist/generic/refusalExtensions.js.map +1 -0
  41. package/dist/index.d.ts +11 -3
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +131 -93
  44. package/dist/index.js.map +1 -1
  45. package/dist/realtimeWidget/WidgetSessionService.d.ts.map +1 -1
  46. package/dist/realtimeWidget/WidgetSessionService.js +2 -12
  47. package/dist/realtimeWidget/WidgetSessionService.js.map +1 -1
  48. package/dist/realtimeWidget/visitorIdentity.d.ts.map +1 -1
  49. package/dist/realtimeWidget/visitorIdentity.js +20 -5
  50. package/dist/realtimeWidget/visitorIdentity.js.map +1 -1
  51. package/dist/resolvers/EntityRecordNameResolver.d.ts +34 -5
  52. package/dist/resolvers/EntityRecordNameResolver.d.ts.map +1 -1
  53. package/dist/resolvers/EntityRecordNameResolver.js +64 -7
  54. package/dist/resolvers/EntityRecordNameResolver.js.map +1 -1
  55. package/dist/resolvers/FileCategoryResolver.d.ts.map +1 -1
  56. package/dist/resolvers/FileCategoryResolver.js +1 -2
  57. package/dist/resolvers/FileCategoryResolver.js.map +1 -1
  58. package/dist/resolvers/IntegrationDiscoveryResolver.d.ts.map +1 -1
  59. package/dist/resolvers/IntegrationDiscoveryResolver.js +2 -0
  60. package/dist/resolvers/IntegrationDiscoveryResolver.js.map +1 -1
  61. package/dist/resolvers/QuerySystemUserResolver.js +1 -1
  62. package/dist/resolvers/QuerySystemUserResolver.js.map +1 -1
  63. package/dist/resolvers/RealtimeClientSessionResolver.d.ts +10 -2
  64. package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
  65. package/dist/resolvers/RealtimeClientSessionResolver.js +80 -4
  66. package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
  67. package/dist/resolvers/RemoteBrowserActionResolver.d.ts +13 -8
  68. package/dist/resolvers/RemoteBrowserActionResolver.d.ts.map +1 -1
  69. package/dist/resolvers/RemoteBrowserActionResolver.js +45 -8
  70. package/dist/resolvers/RemoteBrowserActionResolver.js.map +1 -1
  71. package/dist/resolvers/SyncRolesUsersResolver.d.ts.map +1 -1
  72. package/dist/resolvers/SyncRolesUsersResolver.js +11 -2
  73. package/dist/resolvers/SyncRolesUsersResolver.js.map +1 -1
  74. package/dist/resolvers/UserViewResolver.d.ts.map +1 -1
  75. package/dist/resolvers/UserViewResolver.js +8 -4
  76. package/dist/resolvers/UserViewResolver.js.map +1 -1
  77. package/dist/rest/EntityCRUDHandler.d.ts +2 -1
  78. package/dist/rest/EntityCRUDHandler.d.ts.map +1 -1
  79. package/dist/rest/EntityCRUDHandler.js +3 -18
  80. package/dist/rest/EntityCRUDHandler.js.map +1 -1
  81. package/dist/rest/RESTEndpointHandler.d.ts +2 -1
  82. package/dist/rest/RESTEndpointHandler.d.ts.map +1 -1
  83. package/dist/rest/RESTEndpointHandler.js +3 -16
  84. package/dist/rest/RESTEndpointHandler.js.map +1 -1
  85. package/dist/rest/RealtimeSdpBrokerHandler.d.ts +23 -0
  86. package/dist/rest/RealtimeSdpBrokerHandler.d.ts.map +1 -0
  87. package/dist/rest/RealtimeSdpBrokerHandler.js +78 -0
  88. package/dist/rest/RealtimeSdpBrokerHandler.js.map +1 -0
  89. package/dist/serverExtensionReservedRoots.d.ts.map +1 -1
  90. package/dist/serverExtensionReservedRoots.js +2 -3
  91. package/dist/serverExtensionReservedRoots.js.map +1 -1
  92. package/package.json +92 -91
  93. package/src/__tests__/EntityCRUDHandler.test.ts +18 -5
  94. package/src/__tests__/EntityRecordNameResolver.fieldSecurity.test.ts +118 -0
  95. package/src/__tests__/RealtimeClientSessionResolver.test.ts +20 -0
  96. package/src/__tests__/RealtimeSdpBrokerHandler.test.ts +191 -0
  97. package/src/__tests__/RemoteBrowserAudioStream.test.ts +81 -2
  98. package/src/__tests__/ResolverBase.filterEscaping.test.ts +190 -3
  99. package/src/__tests__/ResolverBase.readableFieldsTransport.test.ts +106 -0
  100. package/src/__tests__/UserViewResolver.updateWhereClause.test.ts +114 -0
  101. package/src/__tests__/WidgetSessionService.test.ts +4 -1
  102. package/src/__tests__/generatedGraphQLSchema.structural.test.ts +46 -0
  103. package/src/__tests__/newUserRolesDefault.test.ts +81 -0
  104. package/src/__tests__/newUsers.test.ts +36 -14
  105. package/src/__tests__/principals.callSites.test.ts +112 -0
  106. package/src/__tests__/principals.logging.test.ts +160 -0
  107. package/src/__tests__/principals.test.ts +305 -0
  108. package/src/__tests__/resolverBase.fls.test.ts +483 -0
  109. package/src/__tests__/resolverBase.recordChangesFls.test.ts +358 -0
  110. package/src/__tests__/resolverBase.refusalExtensions.test.ts +101 -0
  111. package/src/__tests__/resolverBase.refusalMessage.test.ts +88 -0
  112. package/src/__tests__/serverExtensionReservedRoots.test.ts +79 -11
  113. package/src/__tests__/visitorIdentity.resolve.test.ts +61 -0
  114. package/src/agentSessions/SessionJanitor.ts +2 -2
  115. package/src/auth/exampleNewUserSubClass.ts +9 -6
  116. package/src/auth/magicLink/MagicLinkService.ts +2 -8
  117. package/src/auth/newUsers.ts +7 -15
  118. package/src/auth/principals.ts +257 -0
  119. package/src/config.ts +44 -4
  120. package/src/entitySubclasses/MJEntityPermissionEntityServer.server.ts +65 -6
  121. package/src/generated/graphql-schemas/__mj.ts +18966 -16452
  122. package/src/generic/ResolverBase.ts +467 -9
  123. package/src/generic/RunViewResolver.ts +28 -2
  124. package/src/generic/refusalExtensions.ts +59 -0
  125. package/src/index.ts +154 -102
  126. package/src/realtimeWidget/WidgetSessionService.ts +2 -14
  127. package/src/realtimeWidget/visitorIdentity.ts +21 -6
  128. package/src/resolvers/EntityRecordNameResolver.ts +74 -8
  129. package/src/resolvers/FileCategoryResolver.ts +2 -3
  130. package/src/resolvers/IntegrationDiscoveryResolver.ts +2 -0
  131. package/src/resolvers/QuerySystemUserResolver.ts +1 -1
  132. package/src/resolvers/RealtimeClientSessionResolver.ts +128 -2
  133. package/src/resolvers/RemoteBrowserActionResolver.ts +47 -8
  134. package/src/resolvers/SyncRolesUsersResolver.ts +11 -2
  135. package/src/resolvers/UserViewResolver.ts +8 -4
  136. package/src/rest/EntityCRUDHandler.ts +3 -19
  137. package/src/rest/RESTEndpointHandler.ts +3 -17
  138. package/src/rest/RealtimeSdpBrokerHandler.ts +101 -0
  139. package/src/serverExtensionReservedRoots.ts +2 -3
  140. package/dist/resolvers/RingCentralTelephonyResolver.d.ts +0 -27
  141. package/dist/resolvers/RingCentralTelephonyResolver.d.ts.map +0 -1
  142. package/dist/resolvers/RingCentralTelephonyResolver.js +0 -87
  143. package/dist/resolvers/RingCentralTelephonyResolver.js.map +0 -1
  144. package/dist/resolvers/TeamsMeetingsResolver.d.ts +0 -28
  145. package/dist/resolvers/TeamsMeetingsResolver.d.ts.map +0 -1
  146. package/dist/resolvers/TeamsMeetingsResolver.js +0 -91
  147. package/dist/resolvers/TeamsMeetingsResolver.js.map +0 -1
  148. package/dist/resolvers/TelephonyResolver.d.ts +0 -26
  149. package/dist/resolvers/TelephonyResolver.d.ts.map +0 -1
  150. package/dist/resolvers/TelephonyResolver.js +0 -86
  151. package/dist/resolvers/TelephonyResolver.js.map +0 -1
  152. package/dist/resolvers/VonageTelephonyResolver.d.ts +0 -26
  153. package/dist/resolvers/VonageTelephonyResolver.d.ts.map +0 -1
  154. package/dist/resolvers/VonageTelephonyResolver.js +0 -86
  155. package/dist/resolvers/VonageTelephonyResolver.js.map +0 -1
  156. package/dist/telephony/RingCentralTelephonyService.d.ts +0 -115
  157. package/dist/telephony/RingCentralTelephonyService.d.ts.map +0 -1
  158. package/dist/telephony/RingCentralTelephonyService.js +0 -262
  159. package/dist/telephony/RingCentralTelephonyService.js.map +0 -1
  160. package/dist/telephony/TeamsMeetingsRouter.d.ts +0 -40
  161. package/dist/telephony/TeamsMeetingsRouter.d.ts.map +0 -1
  162. package/dist/telephony/TeamsMeetingsRouter.js +0 -96
  163. package/dist/telephony/TeamsMeetingsRouter.js.map +0 -1
  164. package/dist/telephony/TeamsMeetingsService.d.ts +0 -113
  165. package/dist/telephony/TeamsMeetingsService.d.ts.map +0 -1
  166. package/dist/telephony/TeamsMeetingsService.js +0 -196
  167. package/dist/telephony/TeamsMeetingsService.js.map +0 -1
  168. package/dist/telephony/TwilioTelephonyRouter.d.ts +0 -36
  169. package/dist/telephony/TwilioTelephonyRouter.d.ts.map +0 -1
  170. package/dist/telephony/TwilioTelephonyRouter.js +0 -143
  171. package/dist/telephony/TwilioTelephonyRouter.js.map +0 -1
  172. package/dist/telephony/TwilioTelephonyService.d.ts +0 -95
  173. package/dist/telephony/TwilioTelephonyService.d.ts.map +0 -1
  174. package/dist/telephony/TwilioTelephonyService.js +0 -193
  175. package/dist/telephony/TwilioTelephonyService.js.map +0 -1
  176. package/dist/telephony/VonageTelephonyRouter.d.ts +0 -41
  177. package/dist/telephony/VonageTelephonyRouter.d.ts.map +0 -1
  178. package/dist/telephony/VonageTelephonyRouter.js +0 -201
  179. package/dist/telephony/VonageTelephonyRouter.js.map +0 -1
  180. package/dist/telephony/VonageTelephonyService.d.ts +0 -90
  181. package/dist/telephony/VonageTelephonyService.d.ts.map +0 -1
  182. package/dist/telephony/VonageTelephonyService.js +0 -191
  183. package/dist/telephony/VonageTelephonyService.js.map +0 -1
  184. package/dist/telephony/calendar-scheduler.d.ts +0 -67
  185. package/dist/telephony/calendar-scheduler.d.ts.map +0 -1
  186. package/dist/telephony/calendar-scheduler.js +0 -133
  187. package/dist/telephony/calendar-scheduler.js.map +0 -1
  188. package/dist/telephony/index.d.ts +0 -29
  189. package/dist/telephony/index.d.ts.map +0 -1
  190. package/dist/telephony/index.js +0 -38
  191. package/dist/telephony/index.js.map +0 -1
  192. package/dist/telephony/media-upgrade-router.d.ts +0 -47
  193. package/dist/telephony/media-upgrade-router.d.ts.map +0 -1
  194. package/dist/telephony/media-upgrade-router.js +0 -72
  195. package/dist/telephony/media-upgrade-router.js.map +0 -1
  196. package/dist/telephony/ringcentral-runtime.d.ts +0 -14
  197. package/dist/telephony/ringcentral-runtime.d.ts.map +0 -1
  198. package/dist/telephony/ringcentral-runtime.js +0 -18
  199. package/dist/telephony/ringcentral-runtime.js.map +0 -1
  200. package/dist/telephony/teams-meetings-runtime.d.ts +0 -16
  201. package/dist/telephony/teams-meetings-runtime.d.ts.map +0 -1
  202. package/dist/telephony/teams-meetings-runtime.js +0 -20
  203. package/dist/telephony/teams-meetings-runtime.js.map +0 -1
  204. package/dist/telephony/teamsAcsMediaRegistry.d.ts +0 -69
  205. package/dist/telephony/teamsAcsMediaRegistry.d.ts.map +0 -1
  206. package/dist/telephony/teamsAcsMediaRegistry.js +0 -118
  207. package/dist/telephony/teamsAcsMediaRegistry.js.map +0 -1
  208. package/dist/telephony/telephony-runtime.d.ts +0 -14
  209. package/dist/telephony/telephony-runtime.d.ts.map +0 -1
  210. package/dist/telephony/telephony-runtime.js +0 -18
  211. package/dist/telephony/telephony-runtime.js.map +0 -1
  212. package/dist/telephony/twilioMediaRegistry.d.ts +0 -60
  213. package/dist/telephony/twilioMediaRegistry.d.ts.map +0 -1
  214. package/dist/telephony/twilioMediaRegistry.js +0 -106
  215. package/dist/telephony/twilioMediaRegistry.js.map +0 -1
  216. package/dist/telephony/vonage-runtime.d.ts +0 -14
  217. package/dist/telephony/vonage-runtime.d.ts.map +0 -1
  218. package/dist/telephony/vonage-runtime.js +0 -18
  219. package/dist/telephony/vonage-runtime.js.map +0 -1
  220. package/dist/telephony/vonageMediaRegistry.d.ts +0 -78
  221. package/dist/telephony/vonageMediaRegistry.d.ts.map +0 -1
  222. package/dist/telephony/vonageMediaRegistry.js +0 -158
  223. package/dist/telephony/vonageMediaRegistry.js.map +0 -1
  224. package/src/__tests__/media-upgrade-router.test.ts +0 -43
  225. package/src/__tests__/teams-meetings-service.test.ts +0 -65
  226. package/src/__tests__/teamsAcsMediaRegistry.test.ts +0 -82
  227. package/src/__tests__/twilio-telephony-service.test.ts +0 -23
  228. package/src/__tests__/twilioMediaRegistry.test.ts +0 -103
  229. package/src/__tests__/vonageMediaRegistry.test.ts +0 -180
  230. package/src/resolvers/RingCentralTelephonyResolver.ts +0 -64
  231. package/src/resolvers/TeamsMeetingsResolver.ts +0 -68
  232. package/src/resolvers/TelephonyResolver.ts +0 -63
  233. package/src/resolvers/VonageTelephonyResolver.ts +0 -63
  234. package/src/telephony/RingCentralTelephonyService.ts +0 -342
  235. package/src/telephony/TeamsMeetingsRouter.ts +0 -124
  236. package/src/telephony/TeamsMeetingsService.ts +0 -268
  237. package/src/telephony/TwilioTelephonyRouter.ts +0 -184
  238. package/src/telephony/TwilioTelephonyService.ts +0 -261
  239. package/src/telephony/VonageTelephonyRouter.ts +0 -239
  240. package/src/telephony/VonageTelephonyService.ts +0 -259
  241. package/src/telephony/calendar-scheduler.ts +0 -176
  242. package/src/telephony/index.ts +0 -43
  243. package/src/telephony/media-upgrade-router.ts +0 -79
  244. package/src/telephony/ringcentral-runtime.ts +0 -22
  245. package/src/telephony/teams-meetings-runtime.ts +0 -24
  246. package/src/telephony/teamsAcsMediaRegistry.ts +0 -152
  247. package/src/telephony/telephony-runtime.ts +0 -22
  248. package/src/telephony/twilioMediaRegistry.ts +0 -137
  249. package/src/telephony/vonage-runtime.ts +0 -22
  250. package/src/telephony/vonageMediaRegistry.ts +0 -200
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ import { DatabasePlatform } from '@memberjunction/core';
2
2
  import { Application } from 'express';
3
3
  import 'reflect-metadata';
4
4
  import { RESTApiOptions } from './config.js';
5
- import { ServerExtensionConfig } from '@memberjunction/server-extensions-core';
5
+ import { ServerExtensionLoader, ServerExtensionConfig } from '@memberjunction/server-extensions-core';
6
6
  export { MetadataCacheRefreshIntervalSeconds } from './providerConfigUnits.js';
7
7
  /**
8
8
  * Returns the configured database platform from the `DB_PLATFORM` environment
@@ -22,8 +22,8 @@ export * from 'type-graphql';
22
22
  export { Int, Float, ID } from 'type-graphql';
23
23
  export { NewUserBase } from './auth/newUsers.js';
24
24
  export { configInfo, DEFAULT_SERVER_CONFIG } from './config.js';
25
- export { ServerExtensionLoader, BaseServerExtension } from '@memberjunction/server-extensions-core';
26
- export type { ServerExtensionConfig, ExtensionInitResult, ExtensionHealthResult } from '@memberjunction/server-extensions-core';
25
+ export { ServerExtensionLoader, BaseServerExtension, DefaultServerExtensionServiceRegistry } from '@memberjunction/server-extensions-core';
26
+ export type { ServerExtensionConfig, ServerExtensionPhase, ServerExtensionServiceRegistry, ServerExtensionInitContext, ExtensionInitResult, ExtensionHealthResult, LoadExtensionsOptions, } from '@memberjunction/server-extensions-core';
27
27
  export * from './directives/index.js';
28
28
  export { NoLog, hasNoLogParameter, getNoLogFields } from './logging/NoLog.js';
29
29
  export * from './entitySubclasses/MJEntityPermissionEntityServer.server.js';
@@ -31,11 +31,19 @@ export * from './types.js';
31
31
  export { getSystemUser, getSigningKeys, extractUserInfoFromPayload, verifyUserRecord, } from './auth/index.js';
32
32
  export * from './auth/APIKeyScopeAuth.js';
33
33
  export * from './auth/actingContextResolver.js';
34
+ export { ResolveConfiguredPrincipal, resolvePrincipalFrom } from './auth/principals.js';
35
+ export type { ResolvablePrincipal, PrincipalResolution, PrincipalResolutionReason } from './auth/principals.js';
34
36
  export { CloneUserForSessionContext } from './auth/sessionUserClone.js';
37
+ /**
38
+ * Returns the active ServerExtensionLoader instance for the running server.
39
+ * Returns null if the server has not been started yet.
40
+ */
41
+ export declare function GetServerExtensionLoader(): ServerExtensionLoader | null;
35
42
  export * from './generic/PushStatusResolver.js';
36
43
  export * from './generic/PubSubManager.js';
37
44
  export * from './generic/CacheInvalidationResolver.js';
38
45
  export * from './generic/ResolverBase.js';
46
+ export * from './generic/refusalExtensions.js';
39
47
  export * from './generic/RunViewResolver.js';
40
48
  export * from './resolvers/RunTemplateResolver.js';
41
49
  export * from './resolvers/RunAIPromptResolver.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -41,13 +41,10 @@ import { setupRESTEndpoints } from './rest/setupRESTEndpoints.js';
41
41
  import { createOAuthCallbackHandler } from './rest/OAuthCallbackHandler.js';
42
42
  import { createSignatureWebhookHandler } from './rest/SignatureWebhookHandler.js';
43
43
  import { createMediaStreamRouter } from './rest/MediaStreamHandler.js';
44
+ import { createRealtimeSdpBrokerRouter } from './rest/RealtimeSdpBrokerHandler.js';
45
+ import { REALTIME_SDP_EXCHANGE_PATH } from '@memberjunction/ai';
44
46
  import { createMagicLinkHandler, createMagicLinkJwksRouter, registerMagicLinkAuthProvider, MAGIC_LINK_MOUNT_PATH } from './auth/magicLink/index.js';
45
47
  import { createWidgetHandler, WIDGET_MOUNT_PATH } from './realtimeWidget/index.js';
46
- import { createTwilioTelephonyHandler, TWILIO_TELEPHONY_MOUNT_PATH, SetTwilioTelephonyService } from './telephony/index.js';
47
- import { createVonageTelephonyHandler, VONAGE_TELEPHONY_MOUNT_PATH, SetVonageTelephonyService } from './telephony/index.js';
48
- import { RingCentralTelephonyService, SetRingCentralTelephonyService } from './telephony/index.js';
49
- import { createTeamsMeetingsHandler, TEAMS_MEETINGS_MOUNT_PATH, SetTeamsMeetingsService, GetTeamsMeetingsService, StartCalendarScheduler } from './telephony/index.js';
50
- import { InstallMediaUpgradeDispatcher, IsGraphQLWsPath } from './telephony/index.js';
51
48
  import { resolve } from 'node:path';
52
49
  import { DataSourceInfo, raiseEvent } from './types.js';
53
50
  import { ScheduledJobsService } from './services/ScheduledJobsService.js';
@@ -67,7 +64,7 @@ import { StartTaskGraphDispatcher } from './services/StartTaskGraphDispatcher.js
67
64
  import { CACHE_INVALIDATION_TOPIC } from './generic/CacheInvalidationResolver.js';
68
65
  import { ConnectorFactory, IntegrationEngine } from '@memberjunction/integration-engine';
69
66
  import { CronExpressionHelper } from '@memberjunction/scheduling-engine';
70
- import { ServerExtensionLoader, mergeServerExtensionConfigs, prepareServerExtensionConfigs, describeServerExtensionMount } from '@memberjunction/server-extensions-core';
67
+ import { ServerExtensionLoader, mergeServerExtensionConfigs, prepareServerExtensionConfigs, describeServerExtensionMount, InstallMediaUpgradeDispatcher, IsGraphQLWsPath } from '@memberjunction/server-extensions-core';
71
68
  import { coreReservedServerExtensionRoots } from './serverExtensionReservedRoots.js';
72
69
  import { MetadataCacheRefreshIntervalSeconds } from './providerConfigUnits.js';
73
70
  const cacheRefreshInterval = configInfo.databaseSettings.metadataCacheRefreshInterval;
@@ -95,7 +92,7 @@ export * from 'type-graphql';
95
92
  export { Int, Float, ID } from 'type-graphql';
96
93
  export { NewUserBase } from './auth/newUsers.js';
97
94
  export { configInfo, DEFAULT_SERVER_CONFIG } from './config.js';
98
- export { ServerExtensionLoader, BaseServerExtension } from '@memberjunction/server-extensions-core';
95
+ export { ServerExtensionLoader, BaseServerExtension, DefaultServerExtensionServiceRegistry } from '@memberjunction/server-extensions-core';
99
96
  export * from './directives/index.js';
100
97
  export { NoLog, hasNoLogParameter, getNoLogFields } from './logging/NoLog.js';
101
98
  export * from './entitySubclasses/MJEntityPermissionEntityServer.server.js';
@@ -103,11 +100,27 @@ export * from './types.js';
103
100
  export { getSystemUser, getSigningKeys, extractUserInfoFromPayload, verifyUserRecord, } from './auth/index.js';
104
101
  export * from './auth/APIKeyScopeAuth.js';
105
102
  export * from './auth/actingContextResolver.js';
103
+ // The context-user ladder (#4209). Public because `auth/exampleNewUserSubClass.ts` — the template
104
+ // integrators are told to copy into their OWN package — resolves through it, and `package.json`
105
+ // publishes only "."; without this the example compiles here and cannot be reused anywhere else.
106
+ // `ReportedMisconfigurationCount` / `MAX_REPORTED_MISCONFIGURATIONS` are deliberately NOT here:
107
+ // they exist so the LRU's bound is assertable, the tests import them from the module directly, and
108
+ // a published export is a maintenance commitment no caller asked for.
109
+ export { ResolveConfiguredPrincipal, resolvePrincipalFrom } from './auth/principals.js';
106
110
  export { CloneUserForSessionContext } from './auth/sessionUserClone.js';
111
+ let _currentExtensionLoader = null;
112
+ /**
113
+ * Returns the active ServerExtensionLoader instance for the running server.
114
+ * Returns null if the server has not been started yet.
115
+ */
116
+ export function GetServerExtensionLoader() {
117
+ return _currentExtensionLoader;
118
+ }
107
119
  export * from './generic/PushStatusResolver.js';
108
120
  export * from './generic/PubSubManager.js';
109
121
  export * from './generic/CacheInvalidationResolver.js';
110
122
  export * from './generic/ResolverBase.js';
123
+ export * from './generic/refusalExtensions.js';
111
124
  export * from './generic/RunViewResolver.js';
112
125
  export * from './resolvers/RunTemplateResolver.js';
113
126
  export * from './resolvers/RunAIPromptResolver.js';
@@ -989,6 +1002,14 @@ export const serve = async (resolverPaths, app = createApp(), options) => {
989
1002
  app.use('/oauth', oauthCors, callbackRouter);
990
1003
  startupLog.LogIf('verbose', '[OAuth] Callback route registered at /oauth/callback');
991
1004
  }
1005
+ // ─── Core HTTP Routes (Static Core Infrastructure) ─────────────────────────
1006
+ // IMPORTANT ARCHITECTURAL NOTE:
1007
+ // The route mounts below are strictly reserved for core framework infrastructure (OAuth, eSignature,
1008
+ // media streaming, realtime WebRTC broker, magic-link, widgets).
1009
+ // ALL new custom routes, external webhooks, vendor adapters, and application integrations MUST be
1010
+ // implemented as Server Extensions (subclasses of BaseServerExtension in @memberjunction/server-extensions-core)
1011
+ // mounted via ServerExtensionLoader — NEVER hardcoded as ad-hoc app.use() in serve().
1012
+ // See guides/SERVER_EXTENSIONS_GUIDE.md for complete patterns and best practices.
992
1013
  // ─── eSignature webhook (unauthenticated, registered BEFORE auth) ─────
993
1014
  // Called by external signature providers (DocuSign Connect, etc.) without an MJ bearer token.
994
1015
  // The provider DRIVER verifies the payload signature/HMAC; MJ auth does not apply here.
@@ -1000,6 +1021,11 @@ export const serve = async (resolverPaths, app = createApp(), options) => {
1000
1021
  // auth middleware (an <audio>/<video> element can't send Authorization headers).
1001
1022
  app.use('/media', cors(), createMediaStreamRouter());
1002
1023
  startupLog.LogIf('verbose', '[Media] Streaming route registered at /media/:fileId');
1024
+ // ─── Realtime WebRTC SDP broker (ticket-gated, registered BEFORE auth) ───────
1025
+ if (configInfo.realtime?.enabled) {
1026
+ app.use(REALTIME_SDP_EXCHANGE_PATH, cors(), createRealtimeSdpBrokerRouter());
1027
+ startupLog.LogIf('verbose', `[Realtime] WebRTC SDP broker registered at ${REALTIME_SDP_EXCHANGE_PATH}`);
1028
+ }
1003
1029
  // ─── Magic-link routes (MJ-issued, app-scoped external access) ───────────
1004
1030
  // Public router (JWKS + redeem) mounts BEFORE the auth middleware; the
1005
1031
  // authenticated invite-creation router mounts AFTER it (see below).
@@ -1031,99 +1057,101 @@ export const serve = async (resolverPaths, app = createApp(), options) => {
1031
1057
  }
1032
1058
  startupLog.LogIf('verbose', `[Widget] Public routes registered at ${WIDGET_MOUNT_PATH}/session and ${WIDGET_MOUNT_PATH}/session/refresh`);
1033
1059
  }
1034
- // ─── Telephony (Twilio) ingress: inbound voice webhook + Media-Streams WSS (PUBLIC) ──
1035
- // Carriers cannot present an MJ JWT — the X-Twilio-Signature HMAC is the gate. The
1036
- // public webhook router mounts BEFORE the auth middleware; the Media-Streams WSS attaches
1037
- // to the shared HTTP server. The outbound PlaceTwilioCall mutation reuses the same service.
1038
- if (configInfo.telephony?.enabled && configInfo.telephony.twilio) {
1039
- const twilioHandler = createTwilioTelephonyHandler(oauthPublicUrl, configInfo.telephony.twilio);
1040
- app.use(TWILIO_TELEPHONY_MOUNT_PATH, cors(), twilioHandler.publicRouter);
1041
- twilioHandler.attachMediaStreamServer();
1042
- SetTwilioTelephonyService(twilioHandler.service);
1043
- startupLog.LogIf('verbose', `[Telephony] Twilio routes registered at ${TWILIO_TELEPHONY_MOUNT_PATH}/voice + Media-Streams WSS`);
1044
- }
1045
- // ─── Telephony (Vonage) ingress: inbound answer/event webhooks + media WSS (PUBLIC) ──
1046
- // Carriers cannot present an MJ JWT — the Vonage signed-request HMAC / webhook JWT is the gate.
1047
- // The public router mounts BEFORE the auth middleware; the media WSS attaches to the shared
1048
- // HTTP server. The outbound PlaceVonageCall mutation reuses the same service.
1049
- if (configInfo.telephony?.enabled && configInfo.telephony.vonage) {
1050
- const vonageHandler = createVonageTelephonyHandler(oauthPublicUrl, configInfo.telephony.vonage);
1051
- app.use(VONAGE_TELEPHONY_MOUNT_PATH, cors(), vonageHandler.publicRouter);
1052
- vonageHandler.attachMediaStreamServer();
1053
- SetVonageTelephonyService(vonageHandler.service);
1054
- startupLog.LogIf('verbose', `[Telephony] Vonage routes registered at ${VONAGE_TELEPHONY_MOUNT_PATH}/answer + /event + media WSS`);
1055
- }
1056
- // ─── Telephony (RingCentral) ingress: SIP softphone registration (no HTTP webhook / media WSS) ──
1057
- // RingCentral's only bidirectional-audio transport is a registered SIP softphone — inbound calls arrive
1058
- // as SIP INVITEs on its own SIP/TLS connection, so there is no public webhook or media WSS to mount.
1059
- // start() registers the softphone fire-and-forget so SIP registration never blocks boot; the outbound
1060
- // PlaceRingCentralCall mutation reuses the same service via the runtime holder.
1061
- if (configInfo.telephony?.enabled && configInfo.telephony.ringcentral) {
1062
- const ringCentralService = new RingCentralTelephonyService(configInfo.telephony.ringcentral);
1063
- SetRingCentralTelephonyService(ringCentralService);
1064
- void ringCentralService.start();
1065
- startupLog.LogIf('verbose', `[Telephony] RingCentral SIP softphone starting (codec ${configInfo.telephony.ringcentral.codec ?? 'OPUS/16000'})`);
1060
+ // ─── Server extensions loader & shared service registry ───────────────────
1061
+ const extensionLoader = new ServerExtensionLoader();
1062
+ _currentExtensionLoader = extensionLoader;
1063
+ // Open App packages publish their extensions; host mj.config.cjs overlays by DriverClass
1064
+ // Backwards-compatibility shim: synthesize ServerExtensionConfig entries from legacy configInfo.telephony
1065
+ const telephonyExtensionConfigs = [];
1066
+ if (configInfo.telephony?.enabled) {
1067
+ if (configInfo.telephony.twilio) {
1068
+ telephonyExtensionConfigs.push({
1069
+ Enabled: true,
1070
+ DriverClass: 'TwilioTelephonyExtension',
1071
+ RootPath: '/telephony/twilio',
1072
+ Phase: 'pre-auth',
1073
+ Settings: configInfo.telephony.twilio,
1074
+ });
1075
+ }
1076
+ if (configInfo.telephony.vonage) {
1077
+ telephonyExtensionConfigs.push({
1078
+ Enabled: true,
1079
+ DriverClass: 'VonageTelephonyExtension',
1080
+ RootPath: '/telephony/vonage',
1081
+ Phase: 'pre-auth',
1082
+ Settings: configInfo.telephony.vonage,
1083
+ });
1084
+ }
1085
+ if (configInfo.telephony.ringcentral) {
1086
+ telephonyExtensionConfigs.push({
1087
+ Enabled: true,
1088
+ DriverClass: 'RingCentralTelephonyExtension',
1089
+ RootPath: '/telephony/ringcentral',
1090
+ Phase: 'pre-auth',
1091
+ Settings: configInfo.telephony.ringcentral,
1092
+ });
1093
+ }
1094
+ if (configInfo.telephony.teams?.enabled) {
1095
+ telephonyExtensionConfigs.push({
1096
+ Enabled: true,
1097
+ DriverClass: 'TeamsMeetingsExtension',
1098
+ RootPath: '/meetings/teams',
1099
+ Phase: 'pre-auth',
1100
+ Settings: configInfo.telephony.teams,
1101
+ });
1102
+ }
1066
1103
  }
1067
- // ─── Teams meetings ingress: Graph change-notification webhook (PUBLIC) ──────────────
1068
- // Graph cannot present an MJ JWT — the subscription validationToken handshake + the per-
1069
- // notification clientState shared secret are the gate. The public webhook router mounts
1070
- // BEFORE the auth middleware. The ACS application-hosted-media audio plane is owned by the
1071
- // server's native ACS media adapter, which attaches transports to the shared registry
1072
- // (a media WSS is not needed here). The StartTeamsMeetingSession mutation reuses the same
1073
- // service via the runtime holder.
1074
- if (configInfo.telephony?.enabled && configInfo.telephony.teams?.enabled) {
1075
- const teamsHandler = createTeamsMeetingsHandler(configInfo.telephony.teams);
1076
- app.use(TEAMS_MEETINGS_MOUNT_PATH, cors(), teamsHandler.publicRouter);
1077
- SetTeamsMeetingsService(teamsHandler.service);
1078
- startupLog.LogIf('verbose', `[Meetings] Teams routes registered at ${TEAMS_MEETINGS_MOUNT_PATH}/notifications`);
1104
+ const rawHostExtensions = (configInfo.serverExtensions ?? []);
1105
+ const mergedHostExtensions = mergeServerExtensionConfigs(telephonyExtensionConfigs, rawHostExtensions);
1106
+ // Open App packages publish their extensions; host mj.config.cjs overlays by DriverClass
1107
+ // (and remains the only source for host-only extensions such as Slack/Teams).
1108
+ // extraReservedRoots is derived from the mounts registered above plus graphqlRootPath
1109
+ // so a new pre-auth app.use(...) in serve() must also be added to
1110
+ // coreReservedServerExtensionRoots() — otherwise an Open App can claim it.
1111
+ const extensionConfigs = prepareServerExtensionConfigs(mergeServerExtensionConfigs(options?.serverExtensions ?? [], mergedHostExtensions), {
1112
+ onInvalid: (message) => LogError(message),
1113
+ onOverlap: (message) => LogStatus(message),
1114
+ extraReservedRoots: coreReservedServerExtensionRoots(graphqlRootPath),
1115
+ });
1116
+ for (const cfg of extensionConfigs) {
1117
+ LogStatus(`Server extension ${describeServerExtensionMount(cfg)}`);
1079
1118
  }
1080
- // Install the single path-routing WebSocket-upgrade dispatcher AFTER all media WSS routes have
1081
- // registered. ws 8.x has each {server}-bound WebSocketServer 400 paths it doesn't own, so the GraphQL
1082
- // socket and the telephony media sockets cannot coexist as separate {server} servers — this strips the
1083
- // auto-listeners and routes upgrades by path. No-op when no media routes registered (telephony off).
1084
- InstallMediaUpgradeDispatcher(httpServer, webSocketServer, graphqlRootPath);
1085
1119
  // ─── Global CORS (before auth so 401 responses include CORS headers) ─────
1086
1120
  // Without this, the browser blocks 401 responses from the auth middleware
1087
1121
  // because they lack Access-Control-Allow-Origin headers, preventing the
1088
1122
  // client from reading the error code and triggering token refresh.
1089
1123
  const corsAllowed = configInfo.cors?.allowedOrigins ?? ['*'];
1124
+ const corsWildcard = corsAllowed.includes('*');
1125
+ // SECURITY: never combine credentials with a wildcard/reflect-any-origin policy. When
1126
+ // allowedOrigins is ['*'] the origin callback reflects the caller's Origin, and pairing that
1127
+ // with Access-Control-Allow-Credentials: true lets any site a signed-in user visits make
1128
+ // credentialed cross-origin reads. MJ's primary auth is a Bearer token (not auto-sent
1129
+ // cross-origin), so dropping credentials under the wildcard default is safe; deployments that
1130
+ // genuinely need credentialed CORS must configure an explicit allowedOrigins list.
1090
1131
  app.use(cors({
1091
1132
  origin: (origin, callback) => {
1092
1133
  // Allow all origins when ['*'] (default/backward-compatible),
1093
1134
  // or when no Origin header (server-to-server calls).
1094
- if (corsAllowed.includes('*') || !origin || corsAllowed.includes(origin)) {
1135
+ if (corsWildcard || !origin || corsAllowed.includes(origin)) {
1095
1136
  callback(null, true);
1096
1137
  }
1097
1138
  else {
1098
1139
  callback(new Error(`Origin ${origin} not allowed by CORS`));
1099
1140
  }
1100
1141
  },
1101
- credentials: configInfo.cors?.allowCredentials ?? true,
1142
+ credentials: corsWildcard ? false : (configInfo.cors?.allowCredentials ?? true),
1102
1143
  maxAge: configInfo.cors?.maxAge ?? 86400,
1103
1144
  }));
1104
- // ─── Server extensions (before auth — extensions handle their own auth) ─────
1145
+ // ─── Pre-auth server extensions (before auth — extensions handle their own auth) ─────
1105
1146
  // Slack uses HMAC signature verification, Teams uses Bot Framework JWT validation.
1106
1147
  // These must be registered before the unified auth middleware so webhook
1107
1148
  // requests aren't rejected for lacking an MJ bearer token.
1108
- const extensionLoader = new ServerExtensionLoader();
1109
- // Open App packages publish their extensions; host mj.config.cjs overlays by DriverClass
1110
- // (and remains the only source for host-only extensions such as Slack/Teams).
1111
- // extraReservedRoots is derived from the mounts registered above plus graphqlRootPath
1112
- // so a new pre-auth app.use(...) in serve() must also be added to
1113
- // coreReservedServerExtensionRoots() — otherwise an Open App can claim it.
1114
- const extensionConfigs = prepareServerExtensionConfigs(mergeServerExtensionConfigs(options?.serverExtensions ?? [], (configInfo.serverExtensions ?? [])), {
1115
- onInvalid: (message) => LogError(message),
1116
- onOverlap: (message) => LogStatus(message),
1117
- extraReservedRoots: coreReservedServerExtensionRoots(graphqlRootPath),
1118
- });
1119
- // These routes mount BEFORE createUnifiedAuthMiddleware. Name every one so an
1120
- // operator who installed an Open App for its entities can see the pre-auth HTTP
1121
- // surface and suppress it with host serverExtensions[].Enabled = false.
1122
- for (const cfg of extensionConfigs) {
1123
- LogStatus(`Server extension ${describeServerExtensionMount(cfg)}`);
1124
- }
1125
1149
  if (extensionConfigs.length > 0) {
1126
- await extensionLoader.LoadExtensions(app, extensionConfigs);
1150
+ await extensionLoader.LoadExtensions(app, extensionConfigs, {
1151
+ phase: 'pre-auth',
1152
+ httpServer,
1153
+ publicUrl: oauthPublicUrl,
1154
+ });
1127
1155
  }
1128
1156
  // Extension health endpoint (always available, returns empty array if no extensions)
1129
1157
  app.get('/health/extensions', async (_req, res) => {
@@ -1165,6 +1193,31 @@ export const serve = async (resolverPaths, app = createApp(), options) => {
1165
1193
  app.use(WIDGET_MOUNT_PATH, cors(), widgetAuthenticatedRouter);
1166
1194
  startupLog.LogIf('verbose', `[Widget] Authenticated route registered at ${WIDGET_MOUNT_PATH}/resolve-identity`);
1167
1195
  }
1196
+ // ─── Post-auth server extensions ──────────────────────────────────────────
1197
+ // Extensions declaring Phase: 'post-auth' mount after the unified auth middleware
1198
+ // and are protected by JWT authentication by default.
1199
+ if (extensionConfigs.length > 0) {
1200
+ await extensionLoader.LoadExtensions(app, extensionConfigs, {
1201
+ phase: 'post-auth',
1202
+ httpServer,
1203
+ publicUrl: oauthPublicUrl,
1204
+ });
1205
+ }
1206
+ // ─── Cross-extension lifecycle hook: OnAllExtensionsMounted ───────────────
1207
+ // Called after all extensions across both pre-auth and post-auth phases are mounted.
1208
+ // Extensions can wire themselves to services registered by other extensions or core.
1209
+ await extensionLoader.NotifyAllExtensionsMounted({
1210
+ httpServer,
1211
+ publicUrl: oauthPublicUrl,
1212
+ });
1213
+ // Install the single path-routing WebSocket-upgrade dispatcher AFTER all extensions across both
1214
+ // pre-auth and post-auth phases have mounted and registered their media WSS routes. ws 8.x has each
1215
+ // {server}-bound WebSocketServer 400 paths it doesn't own, so the GraphQL socket and the telephony
1216
+ // media sockets cannot coexist as separate {server} servers — this strips the auto-listeners and
1217
+ // routes upgrades by path. No-op when no media routes registered (telephony off).
1218
+ InstallMediaUpgradeDispatcher(httpServer, webSocketServer, graphqlRootPath, (req, socket, head) => {
1219
+ return RealtimeProxyServer.Instance.TryHandleUpgrade(req, socket, head);
1220
+ });
1168
1221
  // ─── REST API endpoints (auth already handled by unified middleware) ─────
1169
1222
  const restApiConfig = {
1170
1223
  enabled: configInfo.restApiOptions?.enabled ?? false,
@@ -1310,22 +1363,6 @@ export const serve = async (resolverPaths, app = createApp(), options) => {
1310
1363
  StartTaskGraphDispatcher(taskGraphPool, resumeUser)
1311
1364
  .catch(err => console.warn(`[TaskGraphDispatcher] Startup failed: ${err}`));
1312
1365
  }
1313
- // Launch the calendar / scheduled-bridge loop (M2): poll agent calendars for meeting invites and
1314
- // start due meeting bridges. Mirrors the SessionJanitor lifecycle (run-once + interval, timer
1315
- // unref'd). Gated on Teams meetings being enabled (the provider whose scheduled-join is wired) and
1316
- // reuses the SAME meetings service as the ingress; identities without configured calendar creds are
1317
- // skipped, so this is a harmless no-op until a Graph-backed identity + token are configured.
1318
- if (resumeUser && configInfo.telephony?.teams?.enabled) { // global-provider-ok: server-owned background poller under the server's provider + system user
1319
- const teamsMeetingsService = GetTeamsMeetingsService();
1320
- if (teamsMeetingsService) {
1321
- StartCalendarScheduler({
1322
- Provider: Metadata.Provider, // global-provider-ok: server-owned background poller under the server's single default provider + system user
1323
- ContextUser: resumeUser,
1324
- TeamsService: teamsMeetingsService,
1325
- TeamsConfig: configInfo.telephony.teams,
1326
- });
1327
- }
1328
- }
1329
1366
  // Set up graceful shutdown handlers
1330
1367
  const gracefulShutdown = async (signal) => {
1331
1368
  console.log(`\n${signal} received, shutting down gracefully...`);
@@ -1333,6 +1370,7 @@ export const serve = async (resolverPaths, app = createApp(), options) => {
1333
1370
  if (extensionLoader.ExtensionCount > 0) {
1334
1371
  try {
1335
1372
  await extensionLoader.ShutdownAll();
1373
+ _currentExtensionLoader = null;
1336
1374
  console.log('✅ Server extensions shut down');
1337
1375
  }
1338
1376
  catch (error) {