@memberjunction/server 6.2.0-edge.4 → 6.2.0-edge.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -1
- package/dist/.tsbuildinfo +1 -1
- package/dist/agentSessions/SessionJanitor.d.ts +91 -30
- package/dist/agentSessions/SessionJanitor.d.ts.map +1 -1
- package/dist/agentSessions/SessionJanitor.js +311 -81
- package/dist/agentSessions/SessionJanitor.js.map +1 -1
- package/dist/agentSessions/SessionManager.d.ts +17 -3
- package/dist/agentSessions/SessionManager.d.ts.map +1 -1
- package/dist/agentSessions/SessionManager.js +44 -10
- package/dist/agentSessions/SessionManager.js.map +1 -1
- package/dist/apiRoot.d.ts +32 -0
- package/dist/apiRoot.d.ts.map +1 -0
- package/dist/apiRoot.js +67 -0
- package/dist/apiRoot.js.map +1 -0
- package/dist/auth/AuthProviderCatalogRouter.d.ts.map +1 -1
- package/dist/auth/AuthProviderCatalogRouter.js +27 -0
- package/dist/auth/AuthProviderCatalogRouter.js.map +1 -1
- package/dist/auth/LoginScreenEngine.d.ts +22 -0
- package/dist/auth/LoginScreenEngine.d.ts.map +1 -0
- package/dist/auth/LoginScreenEngine.js +57 -0
- package/dist/auth/LoginScreenEngine.js.map +1 -0
- package/dist/auth/index.d.ts +1 -0
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +52 -10
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/initializeProviders.d.ts +10 -0
- package/dist/auth/initializeProviders.d.ts.map +1 -1
- package/dist/auth/initializeProviders.js +37 -1
- package/dist/auth/initializeProviders.js.map +1 -1
- package/dist/auth/localDevAuth.d.ts +79 -0
- package/dist/auth/localDevAuth.d.ts.map +1 -0
- package/dist/auth/localDevAuth.js +439 -0
- package/dist/auth/localDevAuth.js.map +1 -0
- package/dist/auth/magicLink/MagicLinkKeys.d.ts +2 -2
- package/dist/auth/magicLink/MagicLinkKeys.d.ts.map +1 -1
- package/dist/auth/magicLink/MagicLinkKeys.js +1 -1
- package/dist/auth/magicLink/MagicLinkKeys.js.map +1 -1
- package/dist/auth/magicLink/MagicLinkRouter.d.ts.map +1 -1
- package/dist/auth/magicLink/MagicLinkRouter.js +3 -2
- package/dist/auth/magicLink/MagicLinkRouter.js.map +1 -1
- package/dist/auth/magicLink/types.d.ts +12 -0
- package/dist/auth/magicLink/types.d.ts.map +1 -1
- package/dist/auth/sessionUserClone.d.ts +1 -1
- package/dist/auth/sessionUserClone.d.ts.map +1 -1
- package/dist/auth/sessionUserClone.js +3 -2
- package/dist/auth/sessionUserClone.js.map +1 -1
- package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.d.ts +292 -0
- package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.d.ts.map +1 -0
- package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.js +442 -0
- package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.js.map +1 -0
- package/dist/broadcast/index.d.ts +6 -0
- package/dist/broadcast/index.d.ts.map +1 -0
- package/dist/broadcast/index.js +6 -0
- package/dist/broadcast/index.js.map +1 -0
- package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.d.ts +43 -0
- package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.d.ts.map +1 -0
- package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.js +144 -0
- package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.js.map +1 -0
- package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.d.ts +46 -0
- package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.d.ts.map +1 -0
- package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.js +149 -0
- package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.js.map +1 -0
- package/dist/broadcast/providers/GCPPubSubBroadcastProvider.d.ts +49 -0
- package/dist/broadcast/providers/GCPPubSubBroadcastProvider.d.ts.map +1 -0
- package/dist/broadcast/providers/GCPPubSubBroadcastProvider.js +131 -0
- package/dist/broadcast/providers/GCPPubSubBroadcastProvider.js.map +1 -0
- package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.d.ts +24 -0
- package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.d.ts.map +1 -0
- package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.js +51 -0
- package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.js.map +1 -0
- package/dist/cache.d.ts +3 -2
- package/dist/cache.d.ts.map +1 -1
- package/dist/cache.js.map +1 -1
- package/dist/config.d.ts +632 -22
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +104 -4
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +3 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +29 -8
- package/dist/context.js.map +1 -1
- package/dist/coreRoutes.d.ts +29 -0
- package/dist/coreRoutes.d.ts.map +1 -0
- package/dist/coreRoutes.js +156 -0
- package/dist/coreRoutes.js.map +1 -0
- package/dist/generated/graphql-schemas/__mj.d.ts +1016 -29
- package/dist/generated/graphql-schemas/__mj.d.ts.map +1 -1
- package/dist/generated/graphql-schemas/__mj.js +5125 -434
- package/dist/generated/graphql-schemas/__mj.js.map +1 -1
- package/dist/generic/CacheInvalidationResolver.d.ts +85 -30
- package/dist/generic/CacheInvalidationResolver.d.ts.map +1 -1
- package/dist/generic/CacheInvalidationResolver.js +175 -60
- package/dist/generic/CacheInvalidationResolver.js.map +1 -1
- package/dist/generic/OrphanedConversationDetailReconciler.d.ts.map +1 -1
- package/dist/generic/OrphanedConversationDetailReconciler.js +2 -0
- package/dist/generic/OrphanedConversationDetailReconciler.js.map +1 -1
- package/dist/generic/PubSubManager.d.ts +10 -0
- package/dist/generic/PubSubManager.d.ts.map +1 -1
- package/dist/generic/PubSubManager.js +44 -1
- package/dist/generic/PubSubManager.js.map +1 -1
- package/dist/generic/PushStatusResolver.d.ts +39 -6
- package/dist/generic/PushStatusResolver.d.ts.map +1 -1
- package/dist/generic/PushStatusResolver.js +94 -12
- package/dist/generic/PushStatusResolver.js.map +1 -1
- package/dist/generic/ResolverBase.d.ts +168 -69
- package/dist/generic/ResolverBase.d.ts.map +1 -1
- package/dist/generic/ResolverBase.js +464 -405
- package/dist/generic/ResolverBase.js.map +1 -1
- package/dist/generic/RunViewResolver.d.ts +11 -3
- package/dist/generic/RunViewResolver.d.ts.map +1 -1
- package/dist/generic/RunViewResolver.js +91 -13
- package/dist/generic/RunViewResolver.js.map +1 -1
- package/dist/generic/actionOutputFieldSecurity.d.ts +26 -0
- package/dist/generic/actionOutputFieldSecurity.d.ts.map +1 -0
- package/dist/generic/actionOutputFieldSecurity.js +47 -0
- package/dist/generic/actionOutputFieldSecurity.js.map +1 -0
- package/dist/generic/fieldSecurityTransport.d.ts +30 -0
- package/dist/generic/fieldSecurityTransport.d.ts.map +1 -0
- package/dist/generic/fieldSecurityTransport.js +30 -0
- package/dist/generic/fieldSecurityTransport.js.map +1 -0
- package/dist/globalCors.d.ts +33 -0
- package/dist/globalCors.d.ts.map +1 -0
- package/dist/globalCors.js +58 -0
- package/dist/globalCors.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +230 -222
- package/dist/index.js.map +1 -1
- package/dist/integration/CustomColumnPromoter.d.ts.map +1 -1
- package/dist/integration/CustomColumnPromoter.js +6 -1
- package/dist/integration/CustomColumnPromoter.js.map +1 -1
- package/dist/logging/variablesLoggingMiddleware.d.ts +12 -0
- package/dist/logging/variablesLoggingMiddleware.d.ts.map +1 -1
- package/dist/logging/variablesLoggingMiddleware.js +50 -1
- package/dist/logging/variablesLoggingMiddleware.js.map +1 -1
- package/dist/multiTenancy/index.d.ts.map +1 -1
- package/dist/multiTenancy/index.js +22 -2
- package/dist/multiTenancy/index.js.map +1 -1
- package/dist/realtimeSessions/RealtimeSessionVerificationService.d.ts.map +1 -1
- package/dist/realtimeSessions/RealtimeSessionVerificationService.js +2 -1
- package/dist/realtimeSessions/RealtimeSessionVerificationService.js.map +1 -1
- package/dist/realtimeSessions/RealtimeVerifyRouter.d.ts.map +1 -1
- package/dist/realtimeSessions/RealtimeVerifyRouter.js +2 -1
- package/dist/realtimeSessions/RealtimeVerifyRouter.js.map +1 -1
- package/dist/realtimeSessions/RecordingAssemblyScheduler.d.ts +100 -0
- package/dist/realtimeSessions/RecordingAssemblyScheduler.d.ts.map +1 -0
- package/dist/realtimeSessions/RecordingAssemblyScheduler.js +173 -0
- package/dist/realtimeSessions/RecordingAssemblyScheduler.js.map +1 -0
- package/dist/realtimeSessions/SessionVerificationPortsBase.d.ts.map +1 -1
- package/dist/realtimeSessions/SessionVerificationPortsBase.js +1 -0
- package/dist/realtimeSessions/SessionVerificationPortsBase.js.map +1 -1
- package/dist/realtimeSessions/index.d.ts +2 -0
- package/dist/realtimeSessions/index.d.ts.map +1 -1
- package/dist/realtimeSessions/index.js +2 -0
- package/dist/realtimeSessions/index.js.map +1 -1
- package/dist/realtimeSessions/ownedRealtimeSession.d.ts +32 -0
- package/dist/realtimeSessions/ownedRealtimeSession.d.ts.map +1 -0
- package/dist/realtimeSessions/ownedRealtimeSession.js +56 -0
- package/dist/realtimeSessions/ownedRealtimeSession.js.map +1 -0
- package/dist/realtimeSessions/sessionAccess.d.ts +91 -8
- package/dist/realtimeSessions/sessionAccess.d.ts.map +1 -1
- package/dist/realtimeSessions/sessionAccess.js +127 -20
- package/dist/realtimeSessions/sessionAccess.js.map +1 -1
- package/dist/realtimeSessions/sessionConfigStamps.js +1 -1
- package/dist/realtimeSessions/sessionConfigStamps.js.map +1 -1
- package/dist/realtimeSessions/subscriptionAuthorization.d.ts.map +1 -1
- package/dist/realtimeSessions/subscriptionAuthorization.js +5 -2
- package/dist/realtimeSessions/subscriptionAuthorization.js.map +1 -1
- package/dist/realtimeSessions/verificationWorkflow.d.ts +2 -0
- package/dist/realtimeSessions/verificationWorkflow.d.ts.map +1 -1
- package/dist/realtimeSessions/verificationWorkflow.js +1 -1
- package/dist/realtimeSessions/verificationWorkflow.js.map +1 -1
- package/dist/realtimeWidget/WidgetRouter.d.ts.map +1 -1
- package/dist/realtimeWidget/WidgetRouter.js +19 -3
- package/dist/realtimeWidget/WidgetRouter.js.map +1 -1
- package/dist/realtimeWidget/WidgetSessionService.d.ts +67 -7
- package/dist/realtimeWidget/WidgetSessionService.d.ts.map +1 -1
- package/dist/realtimeWidget/WidgetSessionService.js +201 -19
- package/dist/realtimeWidget/WidgetSessionService.js.map +1 -1
- package/dist/realtimeWidget/host-identity.d.ts +1 -1
- package/dist/realtimeWidget/host-identity.js +1 -1
- package/dist/realtimeWidget/widgetCore.d.ts +20 -1
- package/dist/realtimeWidget/widgetCore.d.ts.map +1 -1
- package/dist/realtimeWidget/widgetCore.js +17 -1
- package/dist/realtimeWidget/widgetCore.js.map +1 -1
- package/dist/realtimeWidget/widgetGuestElevation.d.ts +1 -1
- package/dist/realtimeWidget/widgetGuestElevation.d.ts.map +1 -1
- package/dist/realtimeWidget/widgetGuestElevation.js +2 -1
- package/dist/realtimeWidget/widgetGuestElevation.js.map +1 -1
- package/dist/resolvers/ActionResolver.d.ts +19 -1
- package/dist/resolvers/ActionResolver.d.ts.map +1 -1
- package/dist/resolvers/ActionResolver.js +63 -12
- package/dist/resolvers/ActionResolver.js.map +1 -1
- package/dist/resolvers/AdhocQueryResolver.d.ts.map +1 -1
- package/dist/resolvers/AdhocQueryResolver.js +1 -0
- package/dist/resolvers/AdhocQueryResolver.js.map +1 -1
- package/dist/resolvers/AgentRunStatusPublisher.d.ts +18 -4
- package/dist/resolvers/AgentRunStatusPublisher.d.ts.map +1 -1
- package/dist/resolvers/AgentRunStatusPublisher.js +32 -8
- package/dist/resolvers/AgentRunStatusPublisher.js.map +1 -1
- package/dist/resolvers/AgentSessionResolver.d.ts +10 -4
- package/dist/resolvers/AgentSessionResolver.d.ts.map +1 -1
- package/dist/resolvers/AgentSessionResolver.js +40 -17
- package/dist/resolvers/AgentSessionResolver.js.map +1 -1
- package/dist/resolvers/ArtifactFileResolver.d.ts +5 -1
- package/dist/resolvers/ArtifactFileResolver.d.ts.map +1 -1
- package/dist/resolvers/ArtifactFileResolver.js +9 -7
- package/dist/resolvers/ArtifactFileResolver.js.map +1 -1
- package/dist/resolvers/ConversationRunEventsResolver.d.ts +8 -4
- package/dist/resolvers/ConversationRunEventsResolver.d.ts.map +1 -1
- package/dist/resolvers/ConversationRunEventsResolver.js +6 -6
- package/dist/resolvers/ConversationRunEventsResolver.js.map +1 -1
- package/dist/resolvers/DatasetResolver.d.ts +24 -3
- package/dist/resolvers/DatasetResolver.d.ts.map +1 -1
- package/dist/resolvers/DatasetResolver.js +57 -8
- package/dist/resolvers/DatasetResolver.js.map +1 -1
- package/dist/resolvers/EntityCommunicationsResolver.d.ts +13 -1
- package/dist/resolvers/EntityCommunicationsResolver.d.ts.map +1 -1
- package/dist/resolvers/EntityCommunicationsResolver.js +50 -14
- package/dist/resolvers/EntityCommunicationsResolver.js.map +1 -1
- package/dist/resolvers/EntityRecordNameResolver.d.ts +2 -1
- package/dist/resolvers/EntityRecordNameResolver.d.ts.map +1 -1
- package/dist/resolvers/EntityRecordNameResolver.js +3 -2
- package/dist/resolvers/EntityRecordNameResolver.js.map +1 -1
- package/dist/resolvers/FetchEntityVectorsResolver.d.ts +46 -3
- package/dist/resolvers/FetchEntityVectorsResolver.d.ts.map +1 -1
- package/dist/resolvers/FetchEntityVectorsResolver.js +211 -50
- package/dist/resolvers/FetchEntityVectorsResolver.js.map +1 -1
- package/dist/resolvers/FileCategoryResolver.d.ts.map +1 -1
- package/dist/resolvers/FileCategoryResolver.js +1 -0
- package/dist/resolvers/FileCategoryResolver.js.map +1 -1
- package/dist/resolvers/FileResolver.d.ts +87 -11
- package/dist/resolvers/FileResolver.d.ts.map +1 -1
- package/dist/resolvers/FileResolver.js +292 -105
- package/dist/resolvers/FileResolver.js.map +1 -1
- package/dist/resolvers/GetDataContextDataResolver.d.ts +33 -7
- package/dist/resolvers/GetDataContextDataResolver.d.ts.map +1 -1
- package/dist/resolvers/GetDataContextDataResolver.js +117 -38
- package/dist/resolvers/GetDataContextDataResolver.js.map +1 -1
- package/dist/resolvers/GetDataResolver.d.ts.map +1 -1
- package/dist/resolvers/GetDataResolver.js +6 -3
- package/dist/resolvers/GetDataResolver.js.map +1 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.d.ts.map +1 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.js +49 -9
- package/dist/resolvers/IntegrationDiscoveryResolver.js.map +1 -1
- package/dist/resolvers/MergeRecordsResolver.d.ts +8 -1
- package/dist/resolvers/MergeRecordsResolver.d.ts.map +1 -1
- package/dist/resolvers/MergeRecordsResolver.js +31 -3
- package/dist/resolvers/MergeRecordsResolver.js.map +1 -1
- package/dist/resolvers/PipelineProgressResolver.d.ts +6 -0
- package/dist/resolvers/PipelineProgressResolver.d.ts.map +1 -1
- package/dist/resolvers/PipelineProgressResolver.js +5 -3
- package/dist/resolvers/PipelineProgressResolver.js.map +1 -1
- package/dist/resolvers/QueryResolver.d.ts +2 -0
- package/dist/resolvers/QueryResolver.d.ts.map +1 -1
- package/dist/resolvers/QueryResolver.js +33 -6
- package/dist/resolvers/QueryResolver.js.map +1 -1
- package/dist/resolvers/QuerySystemUserResolver.d.ts +2 -0
- package/dist/resolvers/QuerySystemUserResolver.d.ts.map +1 -1
- package/dist/resolvers/QuerySystemUserResolver.js +15 -6
- package/dist/resolvers/QuerySystemUserResolver.js.map +1 -1
- package/dist/resolvers/RSUResolver.d.ts.map +1 -1
- package/dist/resolvers/RSUResolver.js +12 -0
- package/dist/resolvers/RSUResolver.js.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts +18 -10
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.js +92 -54
- package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
- package/dist/resolvers/RemoteBrowserActionResolver.d.ts.map +1 -1
- package/dist/resolvers/RemoteBrowserActionResolver.js +11 -9
- package/dist/resolvers/RemoteBrowserActionResolver.js.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.d.ts +56 -8
- package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.js +241 -67
- package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
- package/dist/resolvers/RunTemplateResolver.d.ts.map +1 -1
- package/dist/resolvers/RunTemplateResolver.js +4 -4
- package/dist/resolvers/RunTemplateResolver.js.map +1 -1
- package/dist/resolvers/RunTestResolver.d.ts.map +1 -1
- package/dist/resolvers/RunTestResolver.js +3 -1
- package/dist/resolvers/RunTestResolver.js.map +1 -1
- package/dist/resolvers/SearchKnowledgeStreamResolver.d.ts +12 -1
- package/dist/resolvers/SearchKnowledgeStreamResolver.d.ts.map +1 -1
- package/dist/resolvers/SearchKnowledgeStreamResolver.js +15 -2
- package/dist/resolvers/SearchKnowledgeStreamResolver.js.map +1 -1
- package/dist/resolvers/SqlLoggingConfigResolver.d.ts.map +1 -1
- package/dist/resolvers/SqlLoggingConfigResolver.js +2 -3
- package/dist/resolvers/SqlLoggingConfigResolver.js.map +1 -1
- package/dist/resolvers/SyncDataResolver.d.ts.map +1 -1
- package/dist/resolvers/SyncDataResolver.js +4 -0
- package/dist/resolvers/SyncDataResolver.js.map +1 -1
- package/dist/resolvers/TaskGraphFrameResolver.d.ts +2 -1
- package/dist/resolvers/TaskGraphFrameResolver.d.ts.map +1 -1
- package/dist/resolvers/TaskGraphFrameResolver.js +28 -1
- package/dist/resolvers/TaskGraphFrameResolver.js.map +1 -1
- package/dist/resolvers/TestQuerySQLResolver.d.ts +24 -0
- package/dist/resolvers/TestQuerySQLResolver.d.ts.map +1 -1
- package/dist/resolvers/TestQuerySQLResolver.js +66 -13
- package/dist/resolvers/TestQuerySQLResolver.js.map +1 -1
- package/dist/resolvers/TransactionGroupResolver.d.ts +34 -2
- package/dist/resolvers/TransactionGroupResolver.d.ts.map +1 -1
- package/dist/resolvers/TransactionGroupResolver.js +150 -27
- package/dist/resolvers/TransactionGroupResolver.js.map +1 -1
- package/dist/resolvers/UserViewResolver.d.ts +1 -1
- package/dist/resolvers/UserViewResolver.d.ts.map +1 -1
- package/dist/resolvers/UserViewResolver.js +2 -1
- package/dist/resolvers/UserViewResolver.js.map +1 -1
- package/dist/resolvers/agent-run-data-guard.d.ts +31 -0
- package/dist/resolvers/agent-run-data-guard.d.ts.map +1 -0
- package/dist/resolvers/agent-run-data-guard.js +72 -0
- package/dist/resolvers/agent-run-data-guard.js.map +1 -0
- package/dist/rest/EntityCRUDHandler.d.ts +6 -0
- package/dist/rest/EntityCRUDHandler.d.ts.map +1 -1
- package/dist/rest/EntityCRUDHandler.js +19 -5
- package/dist/rest/EntityCRUDHandler.js.map +1 -1
- package/dist/rest/RESTEndpointHandler.d.ts.map +1 -1
- package/dist/rest/RESTEndpointHandler.js +8 -5
- package/dist/rest/RESTEndpointHandler.js.map +1 -1
- package/dist/rest/RealtimeRecordingHandler.d.ts +49 -0
- package/dist/rest/RealtimeRecordingHandler.d.ts.map +1 -0
- package/dist/rest/RealtimeRecordingHandler.js +383 -0
- package/dist/rest/RealtimeRecordingHandler.js.map +1 -0
- package/dist/rest/ViewOperationsHandler.d.ts +9 -1
- package/dist/rest/ViewOperationsHandler.d.ts.map +1 -1
- package/dist/rest/ViewOperationsHandler.js +43 -17
- package/dist/rest/ViewOperationsHandler.js.map +1 -1
- package/dist/rest/setupRESTEndpoints.d.ts +6 -0
- package/dist/rest/setupRESTEndpoints.d.ts.map +1 -1
- package/dist/rest/setupRESTEndpoints.js +6 -0
- package/dist/rest/setupRESTEndpoints.js.map +1 -1
- package/dist/serverExtensionReservedRoots.d.ts +12 -10
- package/dist/serverExtensionReservedRoots.d.ts.map +1 -1
- package/dist/serverExtensionReservedRoots.js +14 -17
- package/dist/serverExtensionReservedRoots.js.map +1 -1
- package/dist/serverRoleConfigUnits.d.ts +29 -0
- package/dist/serverRoleConfigUnits.d.ts.map +1 -0
- package/dist/serverRoleConfigUnits.js +33 -0
- package/dist/serverRoleConfigUnits.js.map +1 -0
- package/dist/services/MJStorageBlobStore.d.ts +8 -1
- package/dist/services/MJStorageBlobStore.d.ts.map +1 -1
- package/dist/services/MJStorageBlobStore.js +25 -19
- package/dist/services/MJStorageBlobStore.js.map +1 -1
- package/dist/services/StartTaskGraphDispatcher.js +2 -2
- package/dist/services/StartTaskGraphDispatcher.js.map +1 -1
- package/dist/services/TaskGraphActionRunner.d.ts +5 -3
- package/dist/services/TaskGraphActionRunner.d.ts.map +1 -1
- package/dist/services/TaskGraphActionRunner.js +27 -5
- package/dist/services/TaskGraphActionRunner.js.map +1 -1
- package/dist/services/TaskGraphAgentRunner.d.ts +14 -2
- package/dist/services/TaskGraphAgentRunner.d.ts.map +1 -1
- package/dist/services/TaskGraphAgentRunner.js +157 -9
- package/dist/services/TaskGraphAgentRunner.js.map +1 -1
- package/dist/services/TaskGraphContinuationDeliverer.d.ts +59 -2
- package/dist/services/TaskGraphContinuationDeliverer.d.ts.map +1 -1
- package/dist/services/TaskGraphContinuationDeliverer.js +626 -16
- package/dist/services/TaskGraphContinuationDeliverer.js.map +1 -1
- package/dist/sharedCache.d.ts.map +1 -1
- package/dist/sharedCache.js +3 -0
- package/dist/sharedCache.js.map +1 -1
- package/dist/types.d.ts +23 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +99 -98
- package/src/__tests__/ActionResolver.fieldSecurity.test.ts +237 -0
- package/src/__tests__/AdhocQueryResolver.dialect.test.ts +137 -0
- package/src/__tests__/AgentRunStatusPublisher.test.ts +49 -0
- package/src/__tests__/AgentSessionResolver.ownership.test.ts +137 -0
- package/src/__tests__/CustomColumnPromoterOnePass.test.ts +15 -1
- package/src/__tests__/DatasetResolver.itemFilters.test.ts +201 -0
- package/src/__tests__/EntityCommunicationsResolver.actingUser.test.ts +151 -0
- package/src/__tests__/EntityRecordNameResolver.rowSecurity.test.ts +152 -0
- package/src/__tests__/EvolutionActsOnWhatItDetects.test.ts +113 -0
- package/src/__tests__/FetchEntityVectorsResolver.test.ts +369 -18
- package/src/__tests__/FileResolver.fieldSecurity.test.ts +82 -0
- package/src/__tests__/FileResolver.storageAccess.test.ts +562 -0
- package/src/__tests__/GetDataContextDataResolver.sqlItems.test.ts +416 -0
- package/src/__tests__/ListOperationsResolver.adhocScreen.test.ts +137 -0
- package/src/__tests__/LoginScreenEngine.test.ts +86 -0
- package/src/__tests__/MJStorageBlobStore.storageGate.test.ts +63 -0
- package/src/__tests__/PipelineProgressResolver.filter.test.ts +58 -0
- package/src/__tests__/QuerySystemUserResolver.fieldSecurity.test.ts +49 -0
- package/src/__tests__/RESTEndpointHandler.test.ts +25 -0
- package/src/__tests__/RealtimeClientSessionResolver.configTamper.test.ts +23 -3
- package/src/__tests__/RealtimeClientSessionResolver.test.ts +324 -46
- package/src/__tests__/RecordingAssemblyScheduler.test.ts +178 -0
- package/src/__tests__/RemoteBrowserActionResolver.ownership.test.ts +98 -0
- package/src/__tests__/ResolverBase.adhocReadScope.test.ts +133 -2
- package/src/__tests__/ResolverBase.balancedClause.test.ts +155 -0
- package/src/__tests__/ResolverBase.clauseUnscopedRead.test.ts +127 -0
- package/src/__tests__/ResolverBase.clientOldValues.test.ts +243 -7
- package/src/__tests__/ResolverBase.deleteReturnProjection.test.ts +52 -0
- package/src/__tests__/ResolverBase.entityMessageRelay.test.ts +176 -0
- package/src/__tests__/ResolverBase.filterEscaping.test.ts +5 -2
- package/src/__tests__/ResolverBase.includeBinaryFields.test.ts +23 -1
- package/src/__tests__/ResolverBase.publishStatusUpdate.test.ts +68 -0
- package/src/__tests__/ResolverBase.userViewCacheAndDedup.test.ts +130 -0
- package/src/__tests__/RunAIAgentResolver.branch.test.ts +69 -13
- package/src/__tests__/RunAIAgentResolver.conversationWriter.test.ts +210 -0
- package/src/__tests__/RunAIAgentResolver.fireAndForgetCompletion.test.ts +209 -0
- package/src/__tests__/RunAIAgentResolver.historyFrom.test.ts +20 -28
- package/src/__tests__/RunAIAgentResolver.runDataGuard.test.ts +264 -0
- package/src/__tests__/RunAIAgentResolver.serverReply.test.ts +358 -0
- package/src/__tests__/RunAIAgentResolver.stoppedPredecessor.test.ts +4 -1
- package/src/__tests__/RunTemplateResolver.test.ts +35 -2
- package/src/__tests__/RunViewResolver.cacheCheckForwarding.test.ts +11 -0
- package/src/__tests__/RunViewResolver.cacheCheckScreen.test.ts +165 -0
- package/src/__tests__/SearchKnowledgeStreamResolver.test.ts +161 -0
- package/src/__tests__/SessionJanitor.test.ts +365 -10
- package/src/__tests__/SessionManager.test.ts +122 -0
- package/src/__tests__/TaskGraphActionRunner.durablePayload.test.ts +25 -0
- package/src/__tests__/TaskGraphAgentRunner.test.ts +266 -0
- package/src/__tests__/TaskGraphContinuationDeliverer.test.ts +468 -23
- package/src/__tests__/TaskGraphFrameResolver.test.ts +22 -0
- package/src/__tests__/TestQuerySQLResolver.test.ts +274 -0
- package/src/__tests__/TransactionGroupResolver.fieldSecurity.test.ts +199 -0
- package/src/__tests__/TransactionGroupResolver.refusals.test.ts +98 -1
- package/src/__tests__/UpdateMJDataContextItem.oldValues.test.ts +220 -0
- package/src/__tests__/UserViewResolver.updateWhereClause.test.ts +15 -0
- package/src/__tests__/ViewOperationsHandler.clauseScreen.test.ts +157 -0
- package/src/__tests__/ViewOperationsHandler.test.ts +7 -2
- package/src/__tests__/WidgetSessionService.test.ts +583 -4
- package/src/__tests__/agent-run-data-guard.test.ts +130 -0
- package/src/__tests__/apiRootBoot.test.ts +202 -0
- package/src/__tests__/buildMagicLinkSessionUser.test.ts +96 -0
- package/src/__tests__/cacheBroadcastProviders.test.ts +403 -0
- package/src/__tests__/cacheInvalidationRecordData.test.ts +109 -0
- package/src/__tests__/conversationRunEvents.test.ts +56 -14
- package/src/__tests__/fieldSecurityFixtures.ts +91 -0
- package/src/__tests__/globalCors.test.ts +217 -0
- package/src/__tests__/localDevAuth.test.ts +196 -0
- package/src/__tests__/multiTenancy.postgresRewrite.test.ts +181 -0
- package/src/__tests__/multiTenancy.security.test.ts +51 -0
- package/src/__tests__/multiTenancy.test.ts +1 -1
- package/src/__tests__/orphanedConversationDetailReconciler.test.ts +10 -0
- package/src/__tests__/ownedRealtimeSession.test.ts +39 -0
- package/src/__tests__/pushStatusResolver.filter.test.ts +64 -1
- package/src/__tests__/realtimeRecordingHandler.test.ts +669 -0
- package/src/__tests__/realtimeSessions/RealtimeSessionEventsResolver.test.ts +29 -1
- package/src/__tests__/realtimeSessions/ownedRealtimeSession.anonymous.test.ts +31 -0
- package/src/__tests__/realtimeSessions/ownedRealtimeSession.namedScoped.test.ts +37 -0
- package/src/__tests__/realtimeSessions/sessionAccess.test.ts +146 -7
- package/src/__tests__/realtimeSessions/sessionConfigStamps.test.ts +1 -1
- package/src/__tests__/realtimeSessions/verificationWorkflow.test.ts +25 -4
- package/src/__tests__/resolverBase.cloudEventChangedFields.test.ts +157 -0
- package/src/__tests__/resolverBase.fieldSecurityTransport.test.ts +222 -0
- package/src/__tests__/resolverBase.fls.test.ts +146 -97
- package/src/__tests__/restTransport.fieldSecurity.test.ts +148 -0
- package/src/__tests__/runParamsTimeZone.test.ts +179 -0
- package/src/__tests__/runStreams.fieldSecurity.test.ts +100 -0
- package/src/__tests__/runViewProperties.test.ts +114 -0
- package/src/__tests__/scalabilityBenchmarks.test.ts +765 -0
- package/src/__tests__/scalabilityDatabaseIntegration.test.ts +207 -0
- package/src/__tests__/serverExtensionHostOverlay.test.ts +66 -0
- package/src/__tests__/serverExtensionReservedRoots.test.ts +11 -98
- package/src/__tests__/sessionUserClone.test.ts +5 -1
- package/src/__tests__/sharedCache.test.ts +5 -3
- package/src/__tests__/startupSweepOrder.test.ts +40 -0
- package/src/__tests__/unifiedAuth.test.ts +28 -0
- package/src/__tests__/widgetGuestElevation.test.ts +2 -0
- package/src/agentSessions/SessionJanitor.ts +369 -93
- package/src/agentSessions/SessionManager.ts +45 -10
- package/src/apiRoot.ts +78 -0
- package/src/auth/AuthProviderCatalogRouter.ts +29 -0
- package/src/auth/LoginScreenEngine.ts +50 -0
- package/src/auth/index.ts +57 -12
- package/src/auth/initializeProviders.ts +43 -1
- package/src/auth/localDevAuth.ts +528 -0
- package/src/auth/magicLink/MagicLinkKeys.ts +2 -2
- package/src/auth/magicLink/MagicLinkRouter.ts +3 -2
- package/src/auth/magicLink/types.ts +10 -0
- package/src/auth/sessionUserClone.ts +3 -2
- package/src/broadcast/BaseCacheInvalidationBroadcastProvider.ts +674 -0
- package/src/broadcast/index.ts +5 -0
- package/src/broadcast/providers/AWSIoTCoreBroadcastProvider.ts +180 -0
- package/src/broadcast/providers/AzureWebPubSubBroadcastProvider.ts +182 -0
- package/src/broadcast/providers/GCPPubSubBroadcastProvider.ts +169 -0
- package/src/broadcast/providers/SequencedRoleBucketBroadcastProvider.ts +57 -0
- package/src/cache.ts +2 -1
- package/src/config.ts +115 -5
- package/src/context.ts +32 -8
- package/src/coreRoutes.ts +181 -0
- package/src/generated/graphql-schemas/__mj.ts +3684 -284
- package/src/generic/CacheInvalidationResolver.ts +172 -60
- package/src/generic/OrphanedConversationDetailReconciler.ts +4 -2
- package/src/generic/PubSubManager.ts +54 -1
- package/src/generic/PushStatusResolver.ts +109 -12
- package/src/generic/ResolverBase.ts +540 -431
- package/src/generic/RunViewResolver.ts +97 -15
- package/src/generic/actionOutputFieldSecurity.ts +75 -0
- package/src/generic/fieldSecurityTransport.ts +62 -0
- package/src/globalCors.ts +71 -0
- package/src/index.ts +239 -238
- package/src/integration/CustomColumnPromoter.ts +6 -1
- package/src/logging/variablesLoggingMiddleware.ts +59 -3
- package/src/multiTenancy/index.ts +24 -2
- package/src/realtimeSessions/README.md +7 -3
- package/src/realtimeSessions/RealtimeSessionVerificationService.ts +2 -1
- package/src/realtimeSessions/RealtimeVerifyRouter.ts +2 -1
- package/src/realtimeSessions/RecordingAssemblyScheduler.ts +234 -0
- package/src/realtimeSessions/SessionVerificationPortsBase.ts +1 -0
- package/src/realtimeSessions/index.ts +2 -0
- package/src/realtimeSessions/ownedRealtimeSession.ts +69 -0
- package/src/realtimeSessions/sessionAccess.ts +183 -23
- package/src/realtimeSessions/sessionConfigStamps.ts +1 -1
- package/src/realtimeSessions/subscriptionAuthorization.ts +4 -2
- package/src/realtimeSessions/verificationWorkflow.ts +3 -1
- package/src/realtimeWidget/WidgetRouter.ts +22 -4
- package/src/realtimeWidget/WidgetSessionService.ts +252 -17
- package/src/realtimeWidget/host-identity.ts +1 -1
- package/src/realtimeWidget/widgetCore.ts +30 -1
- package/src/realtimeWidget/widgetGuestElevation.ts +2 -1
- package/src/resolvers/ActionResolver.ts +78 -15
- package/src/resolvers/AdhocQueryResolver.ts +1 -0
- package/src/resolvers/AgentRunStatusPublisher.ts +36 -8
- package/src/resolvers/AgentSessionResolver.ts +46 -18
- package/src/resolvers/ArtifactFileResolver.ts +9 -8
- package/src/resolvers/ConversationRunEventsResolver.ts +15 -11
- package/src/resolvers/DatasetResolver.ts +70 -10
- package/src/resolvers/EntityCommunicationsResolver.ts +56 -15
- package/src/resolvers/EntityRecordNameResolver.ts +3 -2
- package/src/resolvers/FetchEntityVectorsResolver.ts +248 -55
- package/src/resolvers/FileCategoryResolver.ts +1 -0
- package/src/resolvers/FileResolver.ts +334 -109
- package/src/resolvers/GetDataContextDataResolver.ts +139 -41
- package/src/resolvers/GetDataResolver.ts +6 -3
- package/src/resolvers/IntegrationDiscoveryResolver.ts +53 -9
- package/src/resolvers/MergeRecordsResolver.ts +23 -2
- package/src/resolvers/PipelineProgressResolver.ts +12 -3
- package/src/resolvers/QueryResolver.ts +31 -6
- package/src/resolvers/QuerySystemUserResolver.ts +15 -6
- package/src/resolvers/RSUResolver.ts +12 -0
- package/src/resolvers/RealtimeClientSessionResolver.ts +114 -66
- package/src/resolvers/RemoteBrowserActionResolver.ts +15 -10
- package/src/resolvers/RunAIAgentResolver.ts +296 -85
- package/src/resolvers/RunTemplateResolver.ts +6 -4
- package/src/resolvers/RunTestResolver.ts +3 -1
- package/src/resolvers/SearchKnowledgeStreamResolver.ts +19 -3
- package/src/resolvers/SqlLoggingConfigResolver.ts +2 -4
- package/src/resolvers/SyncDataResolver.ts +4 -0
- package/src/resolvers/TaskGraphFrameResolver.ts +33 -1
- package/src/resolvers/TestQuerySQLResolver.ts +69 -13
- package/src/resolvers/TransactionGroupResolver.ts +185 -30
- package/src/resolvers/UserViewResolver.ts +2 -1
- package/src/resolvers/__tests__/GetDataResolver.validation.test.ts +95 -0
- package/src/resolvers/__tests__/MergeRecordsResolver.test.ts +43 -0
- package/src/resolvers/agent-run-data-guard.ts +89 -0
- package/src/rest/EntityCRUDHandler.ts +22 -5
- package/src/rest/RESTEndpointHandler.ts +8 -5
- package/src/rest/RealtimeRecordingHandler.ts +467 -0
- package/src/rest/ViewOperationsHandler.ts +52 -18
- package/src/rest/setupRESTEndpoints.ts +6 -0
- package/src/serverExtensionReservedRoots.ts +14 -17
- package/src/serverRoleConfigUnits.ts +48 -0
- package/src/services/MJStorageBlobStore.ts +31 -30
- package/src/services/StartTaskGraphDispatcher.ts +2 -2
- package/src/services/TaskGraphActionRunner.ts +25 -5
- package/src/services/TaskGraphAgentRunner.ts +188 -11
- package/src/services/TaskGraphContinuationDeliverer.ts +738 -16
- package/src/sharedCache.ts +3 -0
- package/src/types.ts +23 -1
package/src/config.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { LogError, LogStatus, LogStatusEx } from '@memberjunction/core';
|
|
|
5
5
|
import { mergeConfigs, parseBooleanEnv } from '@memberjunction/config';
|
|
6
6
|
import { TelemetryEnabledDefault } from './telemetryConfigUnits.js';
|
|
7
7
|
import { RealtimeEnabledDefault } from './realtimeConfigUnits.js';
|
|
8
|
+
import { ResolveServerRole, type ServerRole } from './serverRoleConfigUnits.js';
|
|
8
9
|
|
|
9
10
|
const explorer = cosmiconfigSync('mj', { searchStrategy: 'global' });
|
|
10
11
|
|
|
@@ -226,10 +227,19 @@ const telemetrySchema = z.object({
|
|
|
226
227
|
level: z.enum(['minimal', 'standard', 'verbose', 'debug']).optional().default('standard'),
|
|
227
228
|
});
|
|
228
229
|
|
|
229
|
-
|
|
230
|
-
|
|
230
|
+
/**
|
|
231
|
+
* A host `mj.config.cjs` `serverExtensions[]` entry. Only `DriverClass` is required: an entry whose
|
|
232
|
+
* DriverClass an Open App package already publishes is an OVERLAY (MergeServerExtensionConfigs) and
|
|
233
|
+
* may set just the fields it overrides — `{ DriverClass: 'X', OwnsCORS: false }` — without repeating
|
|
234
|
+
* `RootPath`. `Enabled` has no schema default for the same reason: a defaulted `true` would silently
|
|
235
|
+
* re-enable an extension the package ships disabled. Whether the MERGED entry is complete (a valid
|
|
236
|
+
* `RootPath`; `Enabled` defaults to true) is validated after the merge, by prepareServerExtensionConfigs,
|
|
237
|
+
* which reports an incomplete host-only entry instead of mounting it.
|
|
238
|
+
*/
|
|
239
|
+
export const ServerExtensionSchema = z.object({
|
|
240
|
+
Enabled: z.boolean().optional(),
|
|
231
241
|
DriverClass: z.string(),
|
|
232
|
-
RootPath: z.string(),
|
|
242
|
+
RootPath: z.string().optional(),
|
|
233
243
|
Settings: z.record(z.unknown()).default({})
|
|
234
244
|
}).passthrough();
|
|
235
245
|
|
|
@@ -238,6 +248,14 @@ const cacheSettingsSchema = z.object({
|
|
|
238
248
|
maxMemoryMB: z.number().optional().default(150),
|
|
239
249
|
/** Maximum percentage of total cache memory that any single entity can occupy. Default: 50. Set to 0 to disable. */
|
|
240
250
|
maxPercentOfCachePerEntity: z.number().optional().default(50),
|
|
251
|
+
/**
|
|
252
|
+
* Ceiling on any ONE cache entry. 'auto' (the default) derives it from maxMemoryMB, so the
|
|
253
|
+
* largest entity the server caches scales with the memory the cache was given; a number is an
|
|
254
|
+
* explicit stricter percentage of maxMemoryMB; 0 removes the ceiling. Leave it on 'auto' unless
|
|
255
|
+
* a specific entry must be kept out of the cache — an entry declined by the ceiling is re-read
|
|
256
|
+
* from the database on every call, and the server logs which maxMemoryMB would admit it.
|
|
257
|
+
*/
|
|
258
|
+
maxEntryPercentOfCache: z.union([z.number(), z.literal('auto')]).optional().default('auto'),
|
|
241
259
|
/** Default TTL in seconds. 0 = no TTL, rely on event-based invalidation. Default: 0. */
|
|
242
260
|
defaultTTLSeconds: z.number().optional().default(0),
|
|
243
261
|
/** Interval in seconds for periodic eviction sweep. 0 = disabled. Default: 300 (5 minutes). */
|
|
@@ -299,6 +317,45 @@ const cacheSettingsSchema = z.object({
|
|
|
299
317
|
* for it. 0 disables the turn-taking. Default: 30.
|
|
300
318
|
*/
|
|
301
319
|
startupWarmupLeaseSeconds: z.number().int().nonnegative().optional().default(30),
|
|
320
|
+
/**
|
|
321
|
+
* Pluggable cache invalidation broadcast topology configuration.
|
|
322
|
+
* Defaults to `'SequencedRoleBucket'` (Topology 1 Monotonic Sequence Ring Buffer + Topology 2
|
|
323
|
+
* Role-Fingerprint $O(\text{Roles})$ evaluation & shaping memoizer).
|
|
324
|
+
*/
|
|
325
|
+
broadcast: z
|
|
326
|
+
.object({
|
|
327
|
+
provider: z.string().optional().default('SequencedRoleBucket'),
|
|
328
|
+
ringBufferSize: z.number().int().positive().optional().default(5000),
|
|
329
|
+
excludedEntities: z.array(z.string()).optional().default([]),
|
|
330
|
+
azureWebPubSub: z
|
|
331
|
+
.object({
|
|
332
|
+
endpoint: z.string().optional(),
|
|
333
|
+
hubName: z.string().optional(),
|
|
334
|
+
accessKey: z.string().optional(),
|
|
335
|
+
tokenTtlMinutes: z.number().positive().optional(),
|
|
336
|
+
})
|
|
337
|
+
.optional(),
|
|
338
|
+
awsIoTCore: z
|
|
339
|
+
.object({
|
|
340
|
+
endpoint: z.string().optional(),
|
|
341
|
+
region: z.string().optional(),
|
|
342
|
+
topicPrefix: z.string().optional(),
|
|
343
|
+
accessKeyId: z.string().optional(),
|
|
344
|
+
secretAccessKey: z.string().optional(),
|
|
345
|
+
tokenTtlSeconds: z.number().positive().optional(),
|
|
346
|
+
})
|
|
347
|
+
.optional(),
|
|
348
|
+
gcpPubSub: z
|
|
349
|
+
.object({
|
|
350
|
+
projectId: z.string().optional(),
|
|
351
|
+
topicPrefix: z.string().optional(),
|
|
352
|
+
gatewayUrl: z.string().optional(),
|
|
353
|
+
signingSecret: z.string().optional(),
|
|
354
|
+
tokenTtlSeconds: z.number().positive().optional(),
|
|
355
|
+
})
|
|
356
|
+
.optional(),
|
|
357
|
+
})
|
|
358
|
+
.optional(),
|
|
302
359
|
});
|
|
303
360
|
|
|
304
361
|
const loggingSettingsSchema = z.object({
|
|
@@ -316,6 +373,15 @@ const loggingSettingsSchema = z.object({
|
|
|
316
373
|
}).optional().default({}),
|
|
317
374
|
});
|
|
318
375
|
|
|
376
|
+
const aiPromptRunsSchema = z.object({
|
|
377
|
+
/**
|
|
378
|
+
* Server default for which template inputs prompt runs store in AIPromptRun.Messages:
|
|
379
|
+
* 'None' (key sizes only), 'Referenced' (keys the templates read) or 'Full'.
|
|
380
|
+
* AIPrompt.TemplateDataCapture and AIPromptParams.TemplateDataCapture override it.
|
|
381
|
+
*/
|
|
382
|
+
templateDataCapture: z.enum(['None', 'Referenced', 'Full']).optional(),
|
|
383
|
+
});
|
|
384
|
+
|
|
319
385
|
const corsSchema = z.object({
|
|
320
386
|
/** Allowed origins for CORS. Default ['*'] preserves backward-compatible "allow all" behavior. */
|
|
321
387
|
allowedOrigins: z.array(z.string()).default(['*']),
|
|
@@ -810,11 +876,24 @@ const realtimeSchema = z.object({
|
|
|
810
876
|
enabled: zodBooleanWithTransforms().default(true),
|
|
811
877
|
/** Mid-session identity verification (off by default). */
|
|
812
878
|
identityVerification: identityVerificationSchema.optional().default({}),
|
|
879
|
+
/**
|
|
880
|
+
* Seconds a client-direct call's recording waits for missing shards after its terminal signal before it
|
|
881
|
+
* is assembled anyway as `Partial` (gaps become silence). Defaults to 90.
|
|
882
|
+
*/
|
|
883
|
+
recordingAssemblyGraceSeconds: z.coerce.number().positive().optional().default(90),
|
|
884
|
+
}).passthrough();
|
|
885
|
+
|
|
886
|
+
const devAuthSchema = z.object({
|
|
887
|
+
/** Master switch for local-only development JWT auth (`MJ_DEV_AUTH_ENABLED=true`). Forbidden when NODE_ENV=production. */
|
|
888
|
+
enabled: zodBooleanWithTransforms().default(false),
|
|
889
|
+
/** Optional default email for `/auth/dev-login` when no email is specified in the request body. */
|
|
890
|
+
defaultEmail: z.string().optional(),
|
|
813
891
|
}).passthrough();
|
|
814
892
|
|
|
815
893
|
const configInfoSchema = z.object({
|
|
816
894
|
userHandling: userHandlingInfoSchema,
|
|
817
895
|
magicLink: magicLinkSchema.optional().default({}),
|
|
896
|
+
devAuth: devAuthSchema.optional().default({}),
|
|
818
897
|
widget: widgetSchema.optional().default({}),
|
|
819
898
|
telephony: telephonySchema.optional().default({}),
|
|
820
899
|
realtime: realtimeSchema.optional().default({}),
|
|
@@ -830,9 +909,10 @@ const configInfoSchema = z.object({
|
|
|
830
909
|
telemetry: telemetrySchema.optional().default({}),
|
|
831
910
|
queryDialects: queryDialectSchema.optional().default({}),
|
|
832
911
|
multiTenancy: multiTenancySchema.optional().default({}),
|
|
833
|
-
serverExtensions: z.array(
|
|
912
|
+
serverExtensions: z.array(ServerExtensionSchema).optional().default([]),
|
|
834
913
|
cacheSettings: cacheSettingsSchema.optional().default({}),
|
|
835
914
|
loggingSettings: loggingSettingsSchema.optional().default({}),
|
|
915
|
+
aiPromptRuns: aiPromptRunsSchema.optional(),
|
|
836
916
|
feedbackSettings: feedbackSettingsSchema.optional().default({}),
|
|
837
917
|
cors: corsSchema.optional().default({}),
|
|
838
918
|
rateLimiting: rateLimitSchema.optional().default({}),
|
|
@@ -860,6 +940,12 @@ const configInfoSchema = z.object({
|
|
|
860
940
|
___codeGenAPIPort: z.coerce.number().optional().default(3999),
|
|
861
941
|
___codeGenAPISubmissionDelay: z.coerce.number().optional().default(5000),
|
|
862
942
|
graphqlRootPath: z.string().optional().default('/'),
|
|
943
|
+
/**
|
|
944
|
+
* Path prefix MJAPI mounts every route it serves under (core routes and server extensions), on its own
|
|
945
|
+
* listener. `/` unless a proxy forwards a prefix WITHOUT stripping it (e.g. CloudFront `/api/*` → MJAPI):
|
|
946
|
+
* then set `MJAPI_BASE_PATH=/api`. Independent of `graphqlRootPath`, which is only Apollo's path. MJ #5674.
|
|
947
|
+
*/
|
|
948
|
+
apiBasePath: z.string().optional().default('/'),
|
|
863
949
|
enableIntrospection: z.coerce.boolean().optional().default(false),
|
|
864
950
|
websiteRunFromPackage: z.coerce.number().optional(),
|
|
865
951
|
userEmailMap: z
|
|
@@ -867,8 +953,18 @@ const configInfoSchema = z.object({
|
|
|
867
953
|
.transform((val) => z.record(z.string()).parse(JSON.parse(val)))
|
|
868
954
|
.optional(),
|
|
869
955
|
mjCoreSchema: z.string(),
|
|
956
|
+
/**
|
|
957
|
+
* Server execution role for horizontal scaling:
|
|
958
|
+
* - `'all'` (default): runs both interactive HTTP/GraphQL/WebSocket handlers and background worker loops.
|
|
959
|
+
* - `'api'`: runs interactive HTTP/GraphQL/WebSocket handlers only; background worker loops are skipped.
|
|
960
|
+
* - `'worker'`: runs background worker loops (`ScheduledJobsService`, `IntegrationSyncWorkerService`,
|
|
961
|
+
* `StartTaskGraphDispatcher`, `StartWorkQueueHost`, `SessionJanitor`, reconcilers).
|
|
962
|
+
*/
|
|
963
|
+
serverRole: z.enum(['all', 'api', 'worker']).optional().default('all'),
|
|
870
964
|
});
|
|
871
965
|
|
|
966
|
+
export type { ServerRole };
|
|
967
|
+
|
|
872
968
|
export type UserHandlingInfo = z.infer<typeof userHandlingInfoSchema>;
|
|
873
969
|
export type MagicLinkConfig = z.infer<typeof magicLinkSchema>;
|
|
874
970
|
export type WidgetConfig = z.infer<typeof widgetSchema>;
|
|
@@ -893,9 +989,10 @@ export type { WorkQueueConfig } from './services/workQueueConfig.js';
|
|
|
893
989
|
export type TelemetryConfig = z.infer<typeof telemetrySchema>;
|
|
894
990
|
export type QueryDialectConfig = z.infer<typeof queryDialectSchema>;
|
|
895
991
|
export type MultiTenancyConfig = z.infer<typeof multiTenancySchema>;
|
|
896
|
-
export type ServerExtensionConfig = z.infer<typeof
|
|
992
|
+
export type ServerExtensionConfig = z.infer<typeof ServerExtensionSchema>;
|
|
897
993
|
export type CacheSettingsConfig = z.infer<typeof cacheSettingsSchema>;
|
|
898
994
|
export type LoggingSettingsConfig = z.infer<typeof loggingSettingsSchema>;
|
|
995
|
+
export type AIPromptRunsConfig = z.infer<typeof aiPromptRunsSchema>;
|
|
899
996
|
export type FeedbackGithubSettingsConfig = z.infer<typeof feedbackGithubSettingsSchema>;
|
|
900
997
|
export type FeedbackSettingsConfig = z.infer<typeof feedbackSettingsSchema>;
|
|
901
998
|
export type CorsConfig = z.infer<typeof corsSchema>;
|
|
@@ -931,11 +1028,13 @@ export const DEFAULT_SERVER_CONFIG: Partial<ConfigInfo> = {
|
|
|
931
1028
|
// GraphQL server settings (environment-driven with defaults)
|
|
932
1029
|
graphqlPort: process.env.GRAPHQL_PORT ? parseInt(process.env.GRAPHQL_PORT, 10) : 4000,
|
|
933
1030
|
graphqlRootPath: process.env.GRAPHQL_ROOT_PATH ?? '/',
|
|
1031
|
+
apiBasePath: process.env.MJAPI_BASE_PATH ?? '/',
|
|
934
1032
|
baseUrl: process.env.GRAPHQL_BASE_URL ?? 'http://localhost',
|
|
935
1033
|
publicUrl: process.env.MJAPI_PUBLIC_URL,
|
|
936
1034
|
enableIntrospection: process.env.ENABLE_INTROSPECTION === 'true',
|
|
937
1035
|
apiKey: process.env.MJ_API_KEY,
|
|
938
1036
|
websiteRunFromPackage: process.env.WEBSITE_RUN_FROM_PACKAGE ? parseInt(process.env.WEBSITE_RUN_FROM_PACKAGE, 10) : undefined,
|
|
1037
|
+
serverRole: ResolveServerRole(process.env.MJ_SERVER_ROLE),
|
|
939
1038
|
|
|
940
1039
|
// User handling defaults
|
|
941
1040
|
userHandling: {
|
|
@@ -1047,6 +1146,7 @@ export const DEFAULT_SERVER_CONFIG: Partial<ConfigInfo> = {
|
|
|
1047
1146
|
cacheSettings: {
|
|
1048
1147
|
maxMemoryMB: 150,
|
|
1049
1148
|
maxPercentOfCachePerEntity: 50,
|
|
1149
|
+
maxEntryPercentOfCache: 'auto',
|
|
1050
1150
|
defaultTTLSeconds: 0,
|
|
1051
1151
|
evictionSweepIntervalSeconds: 300,
|
|
1052
1152
|
verboseLogging: false,
|
|
@@ -1146,6 +1246,16 @@ export function LoadConfig() {
|
|
|
1146
1246
|
LogError('Error parsing config file', null, JSON.stringify(configParsing.error.issues, null, 2));
|
|
1147
1247
|
throw new Error('Configuration validation failed');
|
|
1148
1248
|
}
|
|
1249
|
+
|
|
1250
|
+
const rawDevAuthEnv = process.env.MJ_DEV_AUTH_ENABLED?.trim().toLowerCase();
|
|
1251
|
+
const isDevAuthEnabled =
|
|
1252
|
+
rawDevAuthEnv === 'true' || rawDevAuthEnv === '1' || configParsing.data.devAuth?.enabled === true;
|
|
1253
|
+
if (isDevAuthEnabled && process.env.NODE_ENV?.trim().toLowerCase() === 'production') {
|
|
1254
|
+
throw new Error(
|
|
1255
|
+
'[SECURITY] Local dev auth (MJ_DEV_AUTH_ENABLED) is strictly forbidden when NODE_ENV=production. Refusing to start.'
|
|
1256
|
+
);
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1149
1259
|
return configParsing.data;
|
|
1150
1260
|
}
|
|
1151
1261
|
|
package/src/context.ts
CHANGED
|
@@ -21,7 +21,7 @@ import e from 'express';
|
|
|
21
21
|
import type { RequestHandler, Request, Response, NextFunction } from 'express';
|
|
22
22
|
import { DatabaseProviderBase, UserInfo, type IMetadataProvider, type MagicLinkScope, type ReturningVisitorContext, type WidgetGuestContext } from '@memberjunction/core';
|
|
23
23
|
import { SQLServerDataProvider, SQLServerProviderConfigData } from '@memberjunction/sqlserver-dataprovider';
|
|
24
|
-
import { Metadata } from '@memberjunction/core';
|
|
24
|
+
import { Metadata, IsValidTimeZone, TIME_ZONE_HEADER } from '@memberjunction/core';
|
|
25
25
|
import { IdentityClaimEngineServer } from '@memberjunction/core-entities-server';
|
|
26
26
|
import { UUIDsEqual } from '@memberjunction/global';
|
|
27
27
|
import { UserCache, resolveDbPlatformFromEnv } from '@memberjunction/generic-database-provider';
|
|
@@ -204,12 +204,17 @@ async function auditLoginFailure(
|
|
|
204
204
|
// userRecord may be a SHARED cached instance (e.g. multiple recruiters on one per-company
|
|
205
205
|
// link) — mutating it would leak one session's scope to another. Non-magic-link sessions,
|
|
206
206
|
// and named sessions with no resource scope, are returned untouched.
|
|
207
|
-
function
|
|
207
|
+
export function BuildMagicLinkSessionUser(userRecord: UserInfo, payload: jwt.JwtPayload): UserInfo {
|
|
208
208
|
if (payload['mj_magic_link'] !== true) {
|
|
209
209
|
return userRecord;
|
|
210
210
|
}
|
|
211
211
|
const md = Metadata.Provider; // global-provider-ok: server-side magic-link session built under the server's single default provider
|
|
212
212
|
const isAnon = payload['mj_anon'] === true;
|
|
213
|
+
const rawSid = payload['mj_sid'];
|
|
214
|
+
const mjSid = typeof rawSid === 'string' ? rawSid.trim() : '';
|
|
215
|
+
if (isAnon && !mjSid) {
|
|
216
|
+
throw new AuthenticationError('Anonymous magic-link session token is missing required mj_sid claim');
|
|
217
|
+
}
|
|
213
218
|
const scopes = payload['mj_scopes'];
|
|
214
219
|
|
|
215
220
|
// Per-session resource scope (single-resource share; multi-resource union is a follow-on).
|
|
@@ -279,6 +284,7 @@ function buildMagicLinkSessionUser(userRecord: UserInfo, payload: jwt.JwtPayload
|
|
|
279
284
|
// Mark the session so the CurrentUser field resolver serves these synthesized roles
|
|
280
285
|
// (the shared Anonymous principal holds none in the DB). See UserInfo.IsMagicLinkAnonymous.
|
|
281
286
|
sessionUser.IsMagicLinkAnonymous = true;
|
|
287
|
+
sessionUser.AnonymousVisitorID = mjSid;
|
|
282
288
|
}
|
|
283
289
|
return sessionUser;
|
|
284
290
|
}
|
|
@@ -420,7 +426,7 @@ export const GetUserPayload = async (
|
|
|
420
426
|
// very often the SHARED UserCache instance, and stamping it in place
|
|
421
427
|
// leaks one session's row-filter bindings / acting context to every
|
|
422
428
|
// concurrent session of the same user (same pattern as
|
|
423
|
-
//
|
|
429
|
+
// BuildMagicLinkSessionUser — see sessionUserClone.ts).
|
|
424
430
|
const userRecord = CloneUserForSessionContext(resolvedUser);
|
|
425
431
|
|
|
426
432
|
// Row-filter bindings for this key, rebuilt PER REQUEST from the
|
|
@@ -486,7 +492,11 @@ export const GetUserPayload = async (
|
|
|
486
492
|
throw new AuthenticationError('Missing token');
|
|
487
493
|
}
|
|
488
494
|
|
|
489
|
-
const
|
|
495
|
+
const cachedAuth = AuthCache.get(token);
|
|
496
|
+
const payload =
|
|
497
|
+
cachedAuth && typeof cachedAuth === 'object'
|
|
498
|
+
? cachedAuth
|
|
499
|
+
: jwt.decode(token);
|
|
490
500
|
if (!payload || typeof payload === 'string') {
|
|
491
501
|
throw new AuthenticationError('Invalid token payload');
|
|
492
502
|
}
|
|
@@ -498,7 +508,7 @@ export const GetUserPayload = async (
|
|
|
498
508
|
throw new TokenExpiredError(expiryDate);
|
|
499
509
|
}
|
|
500
510
|
|
|
501
|
-
if (!
|
|
511
|
+
if (!cachedAuth) {
|
|
502
512
|
const issuer = payload.iss;
|
|
503
513
|
if (!issuer) {
|
|
504
514
|
console.warn('No issuer claim on token');
|
|
@@ -513,7 +523,7 @@ export const GetUserPayload = async (
|
|
|
513
523
|
}
|
|
514
524
|
|
|
515
525
|
await verifyAsync(issuer, token);
|
|
516
|
-
AuthCache.set(token,
|
|
526
|
+
AuthCache.set(token, payload);
|
|
517
527
|
}
|
|
518
528
|
|
|
519
529
|
// Use provider to extract user information
|
|
@@ -540,7 +550,7 @@ export const GetUserPayload = async (
|
|
|
540
550
|
// Anonymous principal with an in-memory UserInfo carrying the claimed role(s), so
|
|
541
551
|
// the session enforces exactly the link's granted scope (no DB accretion). No-op
|
|
542
552
|
// for everything else.
|
|
543
|
-
const sessionUser =
|
|
553
|
+
const sessionUser = BuildMagicLinkSessionUser(userRecord, payload);
|
|
544
554
|
|
|
545
555
|
// Session-established audit — once per issued token (deduped), fire-and-forget so
|
|
546
556
|
// it never adds latency to the request. The dedup mark is set synchronously here.
|
|
@@ -626,6 +636,15 @@ function parseRequestHostname(origin: string | undefined): string | undefined {
|
|
|
626
636
|
}
|
|
627
637
|
}
|
|
628
638
|
|
|
639
|
+
/**
|
|
640
|
+
* The caller's IANA time zone from the `x-mj-timezone` header, or undefined when the header is
|
|
641
|
+
* absent, repeated, or names no zone this runtime knows (callers then use UTC).
|
|
642
|
+
*/
|
|
643
|
+
function readTimeZoneHeader(req: IncomingMessage): string | undefined {
|
|
644
|
+
const value = req.headers[TIME_ZONE_HEADER];
|
|
645
|
+
return typeof value === 'string' && IsValidTimeZone(value) ? value : undefined;
|
|
646
|
+
}
|
|
647
|
+
|
|
629
648
|
function extractAuthInputs(req: IncomingMessage): {
|
|
630
649
|
bearerToken: string;
|
|
631
650
|
sessionId: string;
|
|
@@ -633,6 +652,7 @@ function extractAuthInputs(req: IncomingMessage): {
|
|
|
633
652
|
systemApiKey: string;
|
|
634
653
|
userApiKey: string;
|
|
635
654
|
requestContext: RequestContext;
|
|
655
|
+
timeZone: string | undefined;
|
|
636
656
|
} {
|
|
637
657
|
const sessionIdRaw = req.headers['x-session-id'];
|
|
638
658
|
const requestDomain = parseRequestHostname(req.headers.origin);
|
|
@@ -657,6 +677,7 @@ function extractAuthInputs(req: IncomingMessage): {
|
|
|
657
677
|
systemApiKey,
|
|
658
678
|
userApiKey,
|
|
659
679
|
requestContext,
|
|
680
|
+
timeZone: readTimeZoneHeader(req),
|
|
660
681
|
};
|
|
661
682
|
}
|
|
662
683
|
|
|
@@ -681,7 +702,7 @@ export function CreateUnifiedAuthMiddleware(
|
|
|
681
702
|
}
|
|
682
703
|
|
|
683
704
|
try {
|
|
684
|
-
const { bearerToken, sessionId, requestDomain, systemApiKey, userApiKey, requestContext } =
|
|
705
|
+
const { bearerToken, sessionId, requestDomain, systemApiKey, userApiKey, requestContext, timeZone } =
|
|
685
706
|
extractAuthInputs(req);
|
|
686
707
|
|
|
687
708
|
const userPayload = await GetUserPayload(
|
|
@@ -699,6 +720,9 @@ export function CreateUnifiedAuthMiddleware(
|
|
|
699
720
|
res.status(401).json({ error: 'Invalid token' });
|
|
700
721
|
return;
|
|
701
722
|
}
|
|
723
|
+
if (timeZone) {
|
|
724
|
+
userPayload.TimeZone = timeZone;
|
|
725
|
+
}
|
|
702
726
|
|
|
703
727
|
// Attach to request for downstream consumers
|
|
704
728
|
req.userPayload = userPayload;
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core HTTP routes MJServer mounts itself, every one under MJAPI's base path (`MJAPI_BASE_PATH`) via {@link ApiRoute}.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from `serve()` so `__tests__/apiRootBoot.test.ts` can mount them on a bare Express app with
|
|
5
|
+
* `MJAPI_BASE_PATH=/api` and check every registered path. `serve()` still decides the ORDER (relative
|
|
6
|
+
* to compression, the auth middleware, server extensions and Apollo); these functions only mount.
|
|
7
|
+
*
|
|
8
|
+
* ALL new custom routes, webhooks and integrations belong in Server Extensions
|
|
9
|
+
* (guides/SERVER_EXTENSIONS_GUIDE.md), not here.
|
|
10
|
+
*/
|
|
11
|
+
import cors from 'cors';
|
|
12
|
+
import { default as BodyParser } from 'body-parser';
|
|
13
|
+
import type { Application, Router } from 'express';
|
|
14
|
+
import { REALTIME_SDP_EXCHANGE_PATH } from '@memberjunction/ai';
|
|
15
|
+
import type { ServerExtensionLoader } from '@memberjunction/server-extensions-core';
|
|
16
|
+
import { configInfo } from './config.js';
|
|
17
|
+
import { ApiRoute } from './apiRoot.js';
|
|
18
|
+
import { CreateOAuthCallbackHandler } from './rest/OAuthCallbackHandler.js';
|
|
19
|
+
import { CreateSignatureWebhookHandler } from './rest/SignatureWebhookHandler.js';
|
|
20
|
+
import { CreateMediaStreamRouter } from './rest/MediaStreamHandler.js';
|
|
21
|
+
import { CreateRealtimeSdpBrokerRouter } from './rest/RealtimeSdpBrokerHandler.js';
|
|
22
|
+
import { CreateMagicLinkHandler, CreateMagicLinkJwksRouter, RegisterMagicLinkAuthProvider, MAGIC_LINK_MOUNT_PATH } from './auth/magicLink/index.js';
|
|
23
|
+
import { CreateWidgetHandler, WIDGET_MOUNT_PATH } from './realtimeWidget/index.js';
|
|
24
|
+
import { CreateRealtimeVerifyRouter, REALTIME_VERIFY_MOUNT_PATH, RealtimeSessionVerificationService } from './realtimeSessions/index.js';
|
|
25
|
+
import { CreateAuthProviderCatalogRouter, AUTH_CATALOG_MOUNT_PATH } from './auth/AuthProviderCatalogRouter.js';
|
|
26
|
+
import { AssertLocalDevAuthAllowed, IsLocalDevAuthEnabled, RegisterLocalDevAuthProvider } from './auth/localDevAuth.js';
|
|
27
|
+
import type { StartupLogger } from './logging/StartupLogger.js';
|
|
28
|
+
|
|
29
|
+
type RouteLog = Pick<StartupLogger, 'LogIf'>;
|
|
30
|
+
|
|
31
|
+
/** Routers the public mounts create that must be mounted again after the auth middleware. */
|
|
32
|
+
export interface CoreAuthenticatedRouters {
|
|
33
|
+
OAuth?: Router;
|
|
34
|
+
MagicLink?: Router;
|
|
35
|
+
Widget?: Router;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** `/healthcheck` — mounted first so platform probes never meet the auth middleware. */
|
|
39
|
+
export function MountHealthcheckRoute(app: Application): void {
|
|
40
|
+
app.get(ApiRoute('/healthcheck'), cors<cors.CorsRequest>(), (_req, res) => {
|
|
41
|
+
res.status(200).json({ status: 'ok' });
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* The unauthenticated core routes (OAuth callback, eSignature webhook, media streaming, realtime SDP
|
|
47
|
+
* broker, magic-link, widget, realtime verify). Each verifies its own capability (signature, token,
|
|
48
|
+
* ticket), so they mount BEFORE the auth middleware. Returns the routers that belong after it.
|
|
49
|
+
*/
|
|
50
|
+
export function MountPublicCoreRoutes(app: Application, publicUrl: string, log: RouteLog): CoreAuthenticatedRouters {
|
|
51
|
+
const routers: CoreAuthenticatedRouters = { OAuth: mountOAuthCallback(app, publicUrl, log) };
|
|
52
|
+
|
|
53
|
+
app.use(ApiRoute('/esignature'), cors<cors.CorsRequest>(), CreateSignatureWebhookHandler());
|
|
54
|
+
log.LogIf('verbose', `[eSignature] Webhook route registered at ${ApiRoute('/esignature')}/webhook/:driverKey`);
|
|
55
|
+
|
|
56
|
+
// The `?token=` query param is the capability; an <audio>/<video> element can't send Authorization headers.
|
|
57
|
+
app.use(ApiRoute('/media'), cors<cors.CorsRequest>(), CreateMediaStreamRouter());
|
|
58
|
+
log.LogIf('verbose', `[Media] Streaming route registered at ${ApiRoute('/media')}/:fileId`);
|
|
59
|
+
|
|
60
|
+
if (configInfo.realtime?.enabled) {
|
|
61
|
+
app.use(ApiRoute(REALTIME_SDP_EXCHANGE_PATH), cors<cors.CorsRequest>(), CreateRealtimeSdpBrokerRouter());
|
|
62
|
+
log.LogIf('verbose', `[Realtime] WebRTC SDP broker registered at ${ApiRoute(REALTIME_SDP_EXCHANGE_PATH)}`);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
routers.MagicLink = mountMagicLinkPublic(app, publicUrl, log);
|
|
66
|
+
routers.Widget = mountWidgetPublic(app, publicUrl, log);
|
|
67
|
+
mountLocalDevAuthPublic(app, publicUrl, log);
|
|
68
|
+
mountRealtimeVerify(app, log);
|
|
69
|
+
return routers;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function mountLocalDevAuthPublic(app: Application, publicUrl: string, log: RouteLog): void {
|
|
73
|
+
AssertLocalDevAuthAllowed();
|
|
74
|
+
if (!IsLocalDevAuthEnabled()) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
RegisterLocalDevAuthProvider(publicUrl);
|
|
78
|
+
if (!configInfo.magicLink?.enabled && !configInfo.widget?.enabled) {
|
|
79
|
+
app.use(ApiRoute(MAGIC_LINK_MOUNT_PATH), cors<cors.CorsRequest>(), CreateMagicLinkJwksRouter());
|
|
80
|
+
log.LogIf('verbose', `[LocalDevAuth] Published RS256 signing key at ${ApiRoute(MAGIC_LINK_MOUNT_PATH)}/jwks.json`);
|
|
81
|
+
}
|
|
82
|
+
log.LogIf('verbose', `[LocalDevAuth] Local dev auth routes enabled at ${ApiRoute(AUTH_CATALOG_MOUNT_PATH)}/dev-login (localhost only)`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function mountOAuthCallback(app: Application, publicUrl: string, log: RouteLog): Router | undefined {
|
|
86
|
+
if (!publicUrl) {
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
const { callbackRouter, authenticatedRouter } = CreateOAuthCallbackHandler({
|
|
90
|
+
publicUrl,
|
|
91
|
+
successRedirectUrl: ApiRoute('/oauth/success', { absolute: true }),
|
|
92
|
+
errorRedirectUrl: ApiRoute('/oauth/error', { absolute: true }),
|
|
93
|
+
// Constrains where a caller-supplied frontendReturnUrl may point (open-redirect guard).
|
|
94
|
+
allowedFrontendOrigins: configInfo.cors?.allowedOrigins ?? ['*'],
|
|
95
|
+
});
|
|
96
|
+
// The callback is unauthenticated (called by the external auth server).
|
|
97
|
+
app.use(ApiRoute('/oauth'), cors<cors.CorsRequest>(), callbackRouter);
|
|
98
|
+
log.LogIf('verbose', `[OAuth] Callback route registered at ${ApiRoute('/oauth')}/callback`);
|
|
99
|
+
return authenticatedRouter;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** Public magic-link router (JWKS + redeem). The invite-creation router is returned for after auth. */
|
|
103
|
+
function mountMagicLinkPublic(app: Application, publicUrl: string, log: RouteLog): Router | undefined {
|
|
104
|
+
if (!configInfo.magicLink?.enabled) {
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
|
107
|
+
const { publicRouter, authenticatedRouter } = CreateMagicLinkHandler(publicUrl, configInfo.magicLink);
|
|
108
|
+
RegisterMagicLinkAuthProvider(publicUrl, configInfo.magicLink);
|
|
109
|
+
app.use(ApiRoute(MAGIC_LINK_MOUNT_PATH), cors<cors.CorsRequest>(), publicRouter);
|
|
110
|
+
log.LogIf('verbose', `[MagicLink] Public routes registered at ${ApiRoute(MAGIC_LINK_MOUNT_PATH)}/redeem and ${ApiRoute(MAGIC_LINK_MOUNT_PATH)}/jwks.json`);
|
|
111
|
+
return authenticatedRouter;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Public widget guest-session mint. It reuses the magic-link RS256 key, so when magic-link itself is
|
|
116
|
+
* disabled the JWKS is published here — otherwise every guest token fails validation and the widget 401s.
|
|
117
|
+
*/
|
|
118
|
+
function mountWidgetPublic(app: Application, publicUrl: string, log: RouteLog): Router | undefined {
|
|
119
|
+
if (!configInfo.widget?.enabled) {
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
122
|
+
const { publicRouter, authenticatedRouter } = CreateWidgetHandler(publicUrl, configInfo.widget);
|
|
123
|
+
app.use(ApiRoute(WIDGET_MOUNT_PATH), cors<cors.CorsRequest>(), publicRouter);
|
|
124
|
+
if (!configInfo.magicLink?.enabled) {
|
|
125
|
+
app.use(ApiRoute(MAGIC_LINK_MOUNT_PATH), cors<cors.CorsRequest>(), CreateMagicLinkJwksRouter());
|
|
126
|
+
log.LogIf('verbose', `[Widget] Published reused signing key at ${ApiRoute(MAGIC_LINK_MOUNT_PATH)}/jwks.json (magic-link flow disabled)`);
|
|
127
|
+
}
|
|
128
|
+
log.LogIf('verbose', `[Widget] Public routes registered at ${ApiRoute(WIDGET_MOUNT_PATH)}/session and ${ApiRoute(WIDGET_MOUNT_PATH)}/session/refresh`);
|
|
129
|
+
return authenticatedRouter;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Realtime identity-verification links. The emailed single-use token is the capability. Mounted only when
|
|
134
|
+
* verification can send mail AND protect its codes (realtime.identityVerification config).
|
|
135
|
+
*/
|
|
136
|
+
function mountRealtimeVerify(app: Application, log: RouteLog): void {
|
|
137
|
+
const verification = RealtimeSessionVerificationService.Instance;
|
|
138
|
+
if (configInfo.realtime?.identityVerification?.enabled && !verification.IsEnabled) {
|
|
139
|
+
console.warn('[RealtimeVerify] realtime.identityVerification.enabled is true but verification is unavailable: it needs a communicationProvider and an hmacSecret of at least 16 characters.');
|
|
140
|
+
}
|
|
141
|
+
if (!verification.IsEnabled) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
app.use(ApiRoute(REALTIME_VERIFY_MOUNT_PATH), cors<cors.CorsRequest>(), CreateRealtimeVerifyRouter());
|
|
145
|
+
log.LogIf('verbose', `[RealtimeVerify] Public routes registered at ${ApiRoute(REALTIME_VERIFY_MOUNT_PATH)}/:token (GET) and ${ApiRoute(REALTIME_VERIFY_MOUNT_PATH)} (POST)`);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/** `/health/extensions` — always mounted; an empty array when no extensions loaded. */
|
|
149
|
+
export function MountExtensionHealthRoute(app: Application, loader: ServerExtensionLoader): void {
|
|
150
|
+
app.get(ApiRoute('/health/extensions'), async (_req, res) => {
|
|
151
|
+
const results = await loader.HealthCheckAll();
|
|
152
|
+
const allHealthy = results.length === 0 || results.every((r) => r.Healthy);
|
|
153
|
+
res.status(allHealthy ? 200 : 503).json({ extensions: results });
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Public authentication-provider catalog. The browser needs it BEFORE it holds a token; it publishes only
|
|
159
|
+
* the non-secret allow-list (AuthProviderEngine.GetPublicCatalog).
|
|
160
|
+
*/
|
|
161
|
+
export function MountAuthCatalogRoute(app: Application, log: RouteLog): void {
|
|
162
|
+
app.use(ApiRoute(AUTH_CATALOG_MOUNT_PATH), cors<cors.CorsRequest>(), CreateAuthProviderCatalogRouter());
|
|
163
|
+
log.LogIf('verbose', `[Auth] Public provider catalog and login screen registered at ${ApiRoute(AUTH_CATALOG_MOUNT_PATH)}/providers and ${ApiRoute(AUTH_CATALOG_MOUNT_PATH)}/login-screen`);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** The routers {@link MountPublicCoreRoutes} returned, mounted AFTER the unified auth middleware. */
|
|
167
|
+
export function MountAuthenticatedCoreRoutes(app: Application, routers: CoreAuthenticatedRouters, log: RouteLog): void {
|
|
168
|
+
if (routers.OAuth) {
|
|
169
|
+
app.use(ApiRoute('/oauth'), cors<cors.CorsRequest>(), BodyParser.json(), routers.OAuth);
|
|
170
|
+
log.LogIf('verbose', `[OAuth] Authenticated routes registered at ${ApiRoute('/oauth')}/status, /initiate and /exchange`);
|
|
171
|
+
}
|
|
172
|
+
if (routers.MagicLink) {
|
|
173
|
+
app.use(ApiRoute(MAGIC_LINK_MOUNT_PATH), cors<cors.CorsRequest>(), routers.MagicLink);
|
|
174
|
+
log.LogIf('verbose', `[MagicLink] Authenticated route registered at ${ApiRoute(MAGIC_LINK_MOUNT_PATH)}/create`);
|
|
175
|
+
}
|
|
176
|
+
// A verified visitor (post magic-link upgrade) promotes their anonymous trail here.
|
|
177
|
+
if (routers.Widget) {
|
|
178
|
+
app.use(ApiRoute(WIDGET_MOUNT_PATH), cors<cors.CorsRequest>(), routers.Widget);
|
|
179
|
+
log.LogIf('verbose', `[Widget] Authenticated route registered at ${ApiRoute(WIDGET_MOUNT_PATH)}/resolve-identity`);
|
|
180
|
+
}
|
|
181
|
+
}
|