@memberjunction/server 6.2.0-edge.0 → 6.2.0-edge.1
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/dist/.tsbuildinfo +1 -1
- package/dist/agentSessions/ReturningVisitorRecap.d.ts +2 -0
- package/dist/agentSessions/ReturningVisitorRecap.d.ts.map +1 -1
- package/dist/agentSessions/ReturningVisitorRecap.js +5 -1
- package/dist/agentSessions/ReturningVisitorRecap.js.map +1 -1
- package/dist/agentSessions/SessionManager.js +2 -2
- package/dist/agentSessions/remoteBrowserGoalEngine.d.ts +8 -0
- package/dist/agentSessions/remoteBrowserGoalEngine.d.ts.map +1 -1
- package/dist/agentSessions/remoteBrowserGoalEngine.js +21 -5
- package/dist/agentSessions/remoteBrowserGoalEngine.js.map +1 -1
- package/dist/auth/AuthProviderCatalogRouter.d.ts +2 -0
- package/dist/auth/AuthProviderCatalogRouter.d.ts.map +1 -1
- package/dist/auth/AuthProviderCatalogRouter.js +5 -1
- package/dist/auth/AuthProviderCatalogRouter.js.map +1 -1
- package/dist/auth/index.d.ts +20 -1
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +20 -10
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/initializeProviders.d.ts +8 -0
- package/dist/auth/initializeProviders.d.ts.map +1 -1
- package/dist/auth/initializeProviders.js +21 -5
- package/dist/auth/initializeProviders.js.map +1 -1
- package/dist/auth/magicLink/MagicLinkRouter.d.ts +9 -0
- package/dist/auth/magicLink/MagicLinkRouter.d.ts.map +1 -1
- package/dist/auth/magicLink/MagicLinkRouter.js +22 -10
- package/dist/auth/magicLink/MagicLinkRouter.js.map +1 -1
- package/dist/auth/magicLink/MagicLinkService.d.ts +17 -15
- package/dist/auth/magicLink/MagicLinkService.d.ts.map +1 -1
- package/dist/auth/magicLink/MagicLinkService.js +65 -51
- package/dist/auth/magicLink/MagicLinkService.js.map +1 -1
- package/dist/auth/magicLink/index.d.ts +2 -2
- package/dist/auth/magicLink/index.d.ts.map +1 -1
- package/dist/auth/magicLink/index.js +2 -2
- package/dist/auth/magicLink/index.js.map +1 -1
- package/dist/auth/magicLink/magicLinkCore.d.ts +54 -33
- package/dist/auth/magicLink/magicLinkCore.d.ts.map +1 -1
- package/dist/auth/magicLink/magicLinkCore.js +61 -61
- package/dist/auth/magicLink/magicLinkCore.js.map +1 -1
- package/dist/auth/magicLink/redeemLanding.d.ts +4 -0
- package/dist/auth/magicLink/redeemLanding.d.ts.map +1 -1
- package/dist/auth/magicLink/redeemLanding.js +12 -4
- package/dist/auth/magicLink/redeemLanding.js.map +1 -1
- package/dist/auth/magicLink/types.d.ts +4 -4
- package/dist/auth/principals.d.ts +2 -0
- package/dist/auth/principals.d.ts.map +1 -1
- package/dist/auth/principals.js +6 -2
- package/dist/auth/principals.js.map +1 -1
- package/dist/cache.d.ts +2 -0
- package/dist/cache.d.ts.map +1 -1
- package/dist/cache.js +3 -1
- package/dist/cache.js.map +1 -1
- package/dist/config.d.ts +346 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +34 -4
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +20 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +27 -19
- package/dist/context.js.map +1 -1
- package/dist/directives/Public.d.ts +2 -0
- package/dist/directives/Public.d.ts.map +1 -1
- package/dist/directives/Public.js +3 -1
- package/dist/directives/Public.js.map +1 -1
- package/dist/directives/RequireSystemUser.d.ts +2 -0
- package/dist/directives/RequireSystemUser.d.ts.map +1 -1
- package/dist/directives/RequireSystemUser.js +3 -1
- package/dist/directives/RequireSystemUser.js.map +1 -1
- package/dist/generated/graphql-schemas/__mj.d.ts +11 -0
- package/dist/generated/graphql-schemas/__mj.d.ts.map +1 -1
- package/dist/generated/graphql-schemas/__mj.js +48 -0
- package/dist/generated/graphql-schemas/__mj.js.map +1 -1
- package/dist/generic/CacheInvalidationResolver.d.ts +94 -4
- package/dist/generic/CacheInvalidationResolver.d.ts.map +1 -1
- package/dist/generic/CacheInvalidationResolver.js +122 -3
- package/dist/generic/CacheInvalidationResolver.js.map +1 -1
- package/dist/generic/DeleteOptionsInput.d.ts +8 -1
- package/dist/generic/DeleteOptionsInput.d.ts.map +1 -1
- package/dist/generic/DeleteOptionsInput.js +1 -1
- package/dist/generic/DeleteOptionsInput.js.map +1 -1
- package/dist/generic/FireAndForgetHeartbeat.d.ts +3 -1
- package/dist/generic/FireAndForgetHeartbeat.d.ts.map +1 -1
- package/dist/generic/FireAndForgetHeartbeat.js +8 -4
- package/dist/generic/FireAndForgetHeartbeat.js.map +1 -1
- package/dist/generic/PushStatusResolver.d.ts +10 -1
- package/dist/generic/PushStatusResolver.d.ts.map +1 -1
- package/dist/generic/PushStatusResolver.js +11 -3
- package/dist/generic/PushStatusResolver.js.map +1 -1
- package/dist/generic/ResolverBase.d.ts +5 -1
- package/dist/generic/ResolverBase.d.ts.map +1 -1
- package/dist/generic/ResolverBase.js +15 -8
- package/dist/generic/ResolverBase.js.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30 -9
- package/dist/index.js.map +1 -1
- package/dist/integration/CustomColumnPromoter.d.ts +2 -0
- package/dist/integration/CustomColumnPromoter.d.ts.map +1 -1
- package/dist/integration/CustomColumnPromoter.js +5 -1
- package/dist/integration/CustomColumnPromoter.js.map +1 -1
- package/dist/integration/EntityMapLifecycle.d.ts +4 -0
- package/dist/integration/EntityMapLifecycle.d.ts.map +1 -1
- package/dist/integration/EntityMapLifecycle.js +10 -2
- package/dist/integration/EntityMapLifecycle.js.map +1 -1
- package/dist/logging/NoLog.d.ts +4 -0
- package/dist/logging/NoLog.d.ts.map +1 -1
- package/dist/logging/NoLog.js +10 -2
- package/dist/logging/NoLog.js.map +1 -1
- package/dist/logging/StartupLogger.d.ts +2 -0
- package/dist/logging/StartupLogger.d.ts.map +1 -1
- package/dist/logging/StartupLogger.js +5 -1
- package/dist/logging/StartupLogger.js.map +1 -1
- package/dist/logging/bootAudit.d.ts +11 -7
- package/dist/logging/bootAudit.d.ts.map +1 -1
- package/dist/logging/bootAudit.js +15 -7
- package/dist/logging/bootAudit.js.map +1 -1
- package/dist/logging/boundaryLogPayload.d.ts +4 -0
- package/dist/logging/boundaryLogPayload.d.ts.map +1 -1
- package/dist/logging/boundaryLogPayload.js +5 -1
- package/dist/logging/boundaryLogPayload.js.map +1 -1
- package/dist/logging/secretRedactor.d.ts +2 -0
- package/dist/logging/secretRedactor.d.ts.map +1 -1
- package/dist/logging/secretRedactor.js +8 -4
- package/dist/logging/secretRedactor.js.map +1 -1
- package/dist/logging/shortenForLog.d.ts +2 -0
- package/dist/logging/shortenForLog.d.ts.map +1 -1
- package/dist/logging/shortenForLog.js +7 -3
- package/dist/logging/shortenForLog.js.map +1 -1
- package/dist/logging/variablesLoggingMiddleware.d.ts +2 -0
- package/dist/logging/variablesLoggingMiddleware.d.ts.map +1 -1
- package/dist/logging/variablesLoggingMiddleware.js +8 -6
- package/dist/logging/variablesLoggingMiddleware.js.map +1 -1
- package/dist/metadataRefreshSignal.d.ts +19 -0
- package/dist/metadataRefreshSignal.d.ts.map +1 -0
- package/dist/metadataRefreshSignal.js +45 -0
- package/dist/metadataRefreshSignal.js.map +1 -0
- package/dist/middleware/MJTenantFilterMiddleware.js +4 -4
- package/dist/multiTenancy/index.d.ts +8 -0
- package/dist/multiTenancy/index.d.ts.map +1 -1
- package/dist/multiTenancy/index.js +21 -5
- package/dist/multiTenancy/index.js.map +1 -1
- package/dist/realtimeWidget/WidgetRouter.d.ts +5 -0
- package/dist/realtimeWidget/WidgetRouter.d.ts.map +1 -1
- package/dist/realtimeWidget/WidgetRouter.js +14 -10
- package/dist/realtimeWidget/WidgetRouter.js.map +1 -1
- package/dist/realtimeWidget/WidgetSessionService.d.ts +6 -6
- package/dist/realtimeWidget/WidgetSessionService.js +27 -27
- package/dist/realtimeWidget/host-identity.d.ts +5 -1
- package/dist/realtimeWidget/host-identity.d.ts.map +1 -1
- package/dist/realtimeWidget/host-identity.js +11 -3
- package/dist/realtimeWidget/host-identity.js.map +1 -1
- package/dist/realtimeWidget/index.d.ts +2 -2
- package/dist/realtimeWidget/index.d.ts.map +1 -1
- package/dist/realtimeWidget/index.js +2 -2
- package/dist/realtimeWidget/index.js.map +1 -1
- package/dist/realtimeWidget/visitorIdentity.d.ts +21 -1
- package/dist/realtimeWidget/visitorIdentity.d.ts.map +1 -1
- package/dist/realtimeWidget/visitorIdentity.js +16 -4
- package/dist/realtimeWidget/visitorIdentity.js.map +1 -1
- package/dist/realtimeWidget/widgetCore.d.ts +48 -0
- package/dist/realtimeWidget/widgetCore.d.ts.map +1 -1
- package/dist/realtimeWidget/widgetCore.js +38 -10
- package/dist/realtimeWidget/widgetCore.js.map +1 -1
- package/dist/realtimeWidget/widgetGuestElevation.d.ts +10 -6
- package/dist/realtimeWidget/widgetGuestElevation.d.ts.map +1 -1
- package/dist/realtimeWidget/widgetGuestElevation.js +14 -6
- package/dist/realtimeWidget/widgetGuestElevation.js.map +1 -1
- package/dist/resolvers/AdhocQueryResolver.js +3 -3
- package/dist/resolvers/FileResolver.js +3 -3
- package/dist/resolvers/GeoResolver.d.ts +2 -2
- package/dist/resolvers/GeoResolver.js +4 -4
- package/dist/resolvers/GetDataResolver.d.ts +14 -0
- package/dist/resolvers/GetDataResolver.d.ts.map +1 -1
- package/dist/resolvers/GetDataResolver.js +43 -15
- package/dist/resolvers/GetDataResolver.js.map +1 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.js +2 -2
- package/dist/resolvers/ListOperationsResolver.d.ts +20 -0
- package/dist/resolvers/ListOperationsResolver.d.ts.map +1 -1
- package/dist/resolvers/ListOperationsResolver.js +68 -28
- package/dist/resolvers/ListOperationsResolver.js.map +1 -1
- package/dist/resolvers/MCPResolver.d.ts +11 -1
- package/dist/resolvers/MCPResolver.d.ts.map +1 -1
- package/dist/resolvers/MCPResolver.js +7 -3
- package/dist/resolvers/MCPResolver.js.map +1 -1
- package/dist/resolvers/RealtimeBridgeResolver.js +3 -3
- package/dist/resolvers/RealtimeClientSessionResolver.js +3 -3
- package/dist/resolvers/RemoteBrowserActionResolver.js +5 -5
- package/dist/resolvers/RunAIAgentResolver.d.ts +10 -4
- package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.js +69 -38
- package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
- package/dist/resolvers/RunAIPromptResolver.d.ts +1 -1
- package/dist/resolvers/RunAIPromptResolver.js +2 -2
- package/dist/resolvers/RunTestResolver.js +5 -5
- package/dist/resolvers/SqlLoggingConfigResolver.d.ts +8 -4
- package/dist/resolvers/SqlLoggingConfigResolver.d.ts.map +1 -1
- package/dist/resolvers/SqlLoggingConfigResolver.js +5 -5
- package/dist/resolvers/TaskGraphFrameResolver.d.ts +8 -1
- package/dist/resolvers/TaskGraphFrameResolver.d.ts.map +1 -1
- package/dist/resolvers/TaskGraphFrameResolver.js +6 -2
- package/dist/resolvers/TaskGraphFrameResolver.js.map +1 -1
- package/dist/resolvers/adhoc-query-helpers.d.ts +6 -0
- package/dist/resolvers/adhoc-query-helpers.d.ts.map +1 -1
- package/dist/resolvers/adhoc-query-helpers.js +10 -2
- package/dist/resolvers/adhoc-query-helpers.js.map +1 -1
- package/dist/resolvers/artifact-routing.d.ts +8 -8
- package/dist/resolvers/artifact-routing.js +2 -2
- package/dist/resolvers/artifact-routing.js.map +1 -1
- package/dist/resolvers/meetingRecordingRegistration.d.ts +10 -2
- package/dist/resolvers/meetingRecordingRegistration.d.ts.map +1 -1
- package/dist/resolvers/meetingRecordingRegistration.js +24 -8
- package/dist/resolvers/meetingRecordingRegistration.js.map +1 -1
- package/dist/resolvers/peaksSidecar.d.ts +4 -0
- package/dist/resolvers/peaksSidecar.d.ts.map +1 -1
- package/dist/resolvers/peaksSidecar.js +10 -2
- package/dist/resolvers/peaksSidecar.js.map +1 -1
- package/dist/rest/EntityCRUDHandler.d.ts +28 -0
- package/dist/rest/EntityCRUDHandler.d.ts.map +1 -1
- package/dist/rest/EntityCRUDHandler.js +20 -4
- package/dist/rest/EntityCRUDHandler.js.map +1 -1
- package/dist/rest/MediaStreamHandler.d.ts +2 -0
- package/dist/rest/MediaStreamHandler.d.ts.map +1 -1
- package/dist/rest/MediaStreamHandler.js +10 -6
- package/dist/rest/MediaStreamHandler.js.map +1 -1
- package/dist/rest/OAuthCallbackHandler.d.ts +9 -0
- package/dist/rest/OAuthCallbackHandler.d.ts.map +1 -1
- package/dist/rest/OAuthCallbackHandler.js +15 -3
- package/dist/rest/OAuthCallbackHandler.js.map +1 -1
- package/dist/rest/RESTEndpointHandler.d.ts +6 -4
- package/dist/rest/RESTEndpointHandler.d.ts.map +1 -1
- package/dist/rest/RESTEndpointHandler.js +15 -11
- package/dist/rest/RESTEndpointHandler.js.map +1 -1
- package/dist/rest/RealtimeSdpBrokerHandler.d.ts +5 -1
- package/dist/rest/RealtimeSdpBrokerHandler.d.ts.map +1 -1
- package/dist/rest/RealtimeSdpBrokerHandler.js +12 -4
- package/dist/rest/RealtimeSdpBrokerHandler.js.map +1 -1
- package/dist/rest/SignatureWebhookHandler.d.ts +2 -0
- package/dist/rest/SignatureWebhookHandler.d.ts.map +1 -1
- package/dist/rest/SignatureWebhookHandler.js +5 -1
- package/dist/rest/SignatureWebhookHandler.js.map +1 -1
- package/dist/rest/UploadTokenManager.d.ts +24 -8
- package/dist/rest/UploadTokenManager.d.ts.map +1 -1
- package/dist/rest/UploadTokenManager.js +53 -21
- package/dist/rest/UploadTokenManager.js.map +1 -1
- package/dist/rest/ViewOperationsHandler.d.ts +20 -0
- package/dist/rest/ViewOperationsHandler.d.ts.map +1 -1
- package/dist/rest/ViewOperationsHandler.js +20 -4
- package/dist/rest/ViewOperationsHandler.js.map +1 -1
- package/dist/rest/mediaRange.d.ts +4 -0
- package/dist/rest/mediaRange.d.ts.map +1 -1
- package/dist/rest/mediaRange.js +10 -2
- package/dist/rest/mediaRange.js.map +1 -1
- package/dist/rest/setupRESTEndpoints.d.ts +4 -0
- package/dist/rest/setupRESTEndpoints.d.ts.map +1 -1
- package/dist/rest/setupRESTEndpoints.js +13 -7
- package/dist/rest/setupRESTEndpoints.js.map +1 -1
- package/dist/serverExtensionReservedRoots.d.ts +2 -0
- package/dist/serverExtensionReservedRoots.d.ts.map +1 -1
- package/dist/serverExtensionReservedRoots.js +5 -1
- package/dist/serverExtensionReservedRoots.js.map +1 -1
- package/dist/services/TaskGraphActionRunner.d.ts +13 -8
- package/dist/services/TaskGraphActionRunner.d.ts.map +1 -1
- package/dist/services/TaskGraphActionRunner.js +16 -15
- package/dist/services/TaskGraphActionRunner.js.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +7 -3
- package/dist/types.js.map +1 -1
- package/dist/util.d.ts +6 -0
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +13 -5
- package/dist/util.js.map +1 -1
- package/package.json +92 -92
- package/src/__tests__/DeleteOptionsInput.wireShape.test.ts +62 -0
- package/src/__tests__/FileResolverPeaks.test.ts +13 -13
- package/src/__tests__/ListOperationsResolver.test.ts +17 -17
- package/src/__tests__/MediaStreamHandler.test.ts +28 -28
- package/src/__tests__/NoLog.test.ts +11 -11
- package/src/__tests__/PrimaryKeyAlwaysMapped.test.ts +10 -10
- package/src/__tests__/RESTEndpointHandler.test.ts +14 -14
- package/src/__tests__/RealtimeBridgeResolver.test.ts +4 -2
- package/src/__tests__/RealtimeSdpBrokerHandler.test.ts +6 -6
- package/src/__tests__/RefreshAdoptsNewColumns.test.ts +8 -8
- package/src/__tests__/RemoteBrowserGoalEngine.test.ts +18 -18
- package/src/__tests__/RunAIAgentResolver.historyFrom.test.ts +228 -0
- package/src/__tests__/TaskGraphActionRunner.durablePayload.test.ts +129 -0
- package/src/__tests__/TaskGraphFrameResolver.test.ts +2 -2
- package/src/__tests__/WidgetSessionService.test.ts +8 -4
- package/src/__tests__/adhoc-query-helpers.test.ts +21 -21
- package/src/__tests__/bootAudit.test.ts +11 -11
- package/src/__tests__/boundaryLogPayload.test.ts +6 -6
- package/src/__tests__/cacheInvalidationRecordData.test.ts +177 -0
- package/src/__tests__/databaseAbstraction.test.ts +12 -6
- package/src/__tests__/getDataTokenRedaction.test.ts +7 -7
- package/src/__tests__/initializeProviders.refresh.test.ts +4 -4
- package/src/__tests__/magicLink.test.ts +73 -134
- package/src/__tests__/magicLinkService.consume.test.ts +224 -0
- package/src/__tests__/meetingRecordingRegistration.test.ts +12 -12
- package/src/__tests__/metadataRefreshSignal.test.ts +78 -0
- package/src/__tests__/multiTenancy.security.test.ts +40 -40
- package/src/__tests__/multiTenancy.test.ts +18 -18
- package/src/__tests__/newUsers.test.ts +24 -23
- package/src/__tests__/principals.test.ts +22 -22
- package/src/__tests__/pushStatusResolver.filter.test.ts +8 -8
- package/src/__tests__/secretRedactor.failOpen.test.ts +12 -12
- package/src/__tests__/secretRedactor.test.ts +12 -12
- package/src/__tests__/serverExtensionReservedRoots.test.ts +7 -7
- package/src/__tests__/subscriptionRedaction.test.ts +5 -5
- package/src/__tests__/unifiedAuth.test.ts +15 -9
- package/src/__tests__/visitorIdentity.resolve.test.ts +6 -6
- package/src/__tests__/widget.test.ts +45 -45
- package/src/__tests__/widgetGuestElevation.test.ts +7 -7
- package/src/__tests__/widgetHostIdentity.test.ts +14 -14
- package/src/agentSessions/ReturningVisitorRecap.ts +12 -1
- package/src/agentSessions/SessionManager.ts +2 -2
- package/src/agentSessions/remoteBrowserGoalEngine.ts +30 -5
- package/src/auth/AuthProviderCatalogRouter.ts +6 -1
- package/src/auth/__tests__/backward-compatibility.test.ts +3 -3
- package/src/auth/index.ts +43 -28
- package/src/auth/initializeProviders.ts +25 -5
- package/src/auth/magicLink/MagicLinkRouter.ts +28 -10
- package/src/auth/magicLink/MagicLinkService.ts +71 -52
- package/src/auth/magicLink/index.ts +7 -7
- package/src/auth/magicLink/magicLinkCore.ts +96 -64
- package/src/auth/magicLink/redeemLanding.ts +14 -4
- package/src/auth/magicLink/types.ts +54 -54
- package/src/auth/newUsers.ts +1 -1
- package/src/auth/principals.ts +11 -2
- package/src/cache.ts +4 -1
- package/src/config.ts +37 -4
- package/src/context.ts +37 -24
- package/src/directives/Public.ts +4 -1
- package/src/directives/RequireSystemUser.ts +4 -1
- package/src/generated/graphql-schemas/__mj.ts +37 -0
- package/src/generic/CacheInvalidationResolver.ts +148 -4
- package/src/generic/DeleteOptionsInput.ts +9 -2
- package/src/generic/FireAndForgetHeartbeat.ts +19 -14
- package/src/generic/PushStatusResolver.ts +21 -7
- package/src/generic/ResolverBase.ts +16 -8
- package/src/generic/RunViewResolver.ts +22 -22
- package/src/generic/__tests__/FireAndForgetHeartbeat.test.ts +7 -7
- package/src/index.ts +35 -9
- package/src/integration/CustomColumnPromoter.ts +6 -1
- package/src/integration/EntityMapLifecycle.ts +20 -2
- package/src/logging/NoLog.ts +16 -2
- package/src/logging/StartupLogger.ts +6 -1
- package/src/logging/bootAudit.ts +26 -16
- package/src/logging/boundaryLogPayload.ts +8 -1
- package/src/logging/secretRedactor.ts +14 -9
- package/src/logging/shortenForLog.ts +8 -3
- package/src/logging/variablesLoggingMiddleware.ts +9 -6
- package/src/metadataRefreshSignal.ts +45 -0
- package/src/middleware/MJTenantFilterMiddleware.ts +4 -4
- package/src/multiTenancy/index.ts +29 -5
- package/src/realtimeWidget/WidgetRouter.ts +15 -10
- package/src/realtimeWidget/WidgetSessionService.ts +76 -76
- package/src/realtimeWidget/host-identity.ts +24 -10
- package/src/realtimeWidget/index.ts +3 -3
- package/src/realtimeWidget/visitorIdentity.ts +39 -8
- package/src/realtimeWidget/widgetCore.ts +75 -10
- package/src/realtimeWidget/widgetGuestElevation.ts +25 -12
- package/src/resolvers/AdhocQueryResolver.ts +3 -3
- package/src/resolvers/AgentSessionResolver.ts +3 -3
- package/src/resolvers/ColorResolver.ts +6 -6
- package/src/resolvers/ComponentRegistryResolver.ts +36 -36
- package/src/resolvers/EntityCommunicationsResolver.ts +4 -4
- package/src/resolvers/ExecuteRemoteOperationResolver.ts +9 -9
- package/src/resolvers/FileResolver.ts +42 -42
- package/src/resolvers/GeoResolver.ts +4 -4
- package/src/resolvers/GetDataResolver.ts +50 -15
- package/src/resolvers/IntegrationDiscoveryResolver.ts +2 -2
- package/src/resolvers/ListOperationsResolver.ts +78 -28
- package/src/resolvers/MCPResolver.ts +30 -15
- package/src/resolvers/QueryResolver.ts +13 -13
- package/src/resolvers/RealtimeBridgeResolver.ts +3 -3
- package/src/resolvers/RealtimeClientSessionResolver.ts +3 -3
- package/src/resolvers/RemoteBrowserActionResolver.ts +5 -5
- package/src/resolvers/RunAIAgentResolver.ts +113 -72
- package/src/resolvers/RunAIPromptResolver.ts +22 -22
- package/src/resolvers/RunTemplateResolver.ts +4 -4
- package/src/resolvers/RunTestResolver.ts +25 -25
- package/src/resolvers/SqlLoggingConfigResolver.ts +56 -56
- package/src/resolvers/TaskGraphFrameResolver.ts +37 -28
- package/src/resolvers/TelemetryResolver.ts +79 -79
- package/src/resolvers/__tests__/GetDataResolver.tokens.test.ts +40 -38
- package/src/resolvers/__tests__/artifact-routing.test.ts +23 -23
- package/src/resolvers/adhoc-query-helpers.ts +19 -2
- package/src/resolvers/artifact-routing.ts +19 -19
- package/src/resolvers/meetingRecordingRegistration.ts +44 -10
- package/src/resolvers/peaksSidecar.ts +12 -2
- package/src/rest/EntityCRUDHandler.ts +24 -4
- package/src/rest/MediaStreamHandler.ts +11 -6
- package/src/rest/OAuthCallbackHandler.ts +25 -7
- package/src/rest/RESTEndpointHandler.ts +20 -15
- package/src/rest/RealtimeSdpBrokerHandler.ts +14 -4
- package/src/rest/SignatureWebhookHandler.ts +6 -1
- package/src/rest/UploadTokenManager.ts +66 -30
- package/src/rest/ViewOperationsHandler.ts +24 -4
- package/src/rest/mediaRange.ts +16 -6
- package/src/rest/setupRESTEndpoints.ts +24 -12
- package/src/serverExtensionReservedRoots.ts +6 -1
- package/src/services/TaskGraphActionRunner.ts +16 -15
- package/src/types.ts +21 -16
- package/src/util.ts +16 -6
|
@@ -10,14 +10,14 @@
|
|
|
10
10
|
*/
|
|
11
11
|
export interface MagicLinkScopeEntry {
|
|
12
12
|
/** The invite that granted this scope entry. */
|
|
13
|
-
inviteId: string;
|
|
13
|
+
inviteId: string; // case-violation-ok-legacy-back-compat: the old name is also read off a value typed `any`, where a rename would compile and silently return undefined
|
|
14
14
|
/** The Application this entry grants access to. */
|
|
15
|
-
appId: string;
|
|
15
|
+
appId: string; // case-violation-ok-legacy-back-compat: the old name is also read off a value typed `any`, where a rename would compile and silently return undefined
|
|
16
16
|
/** The role name this entry carries (email/app-session links). */
|
|
17
|
-
role?: string;
|
|
17
|
+
role?: string; // case-violation-ok-legacy-back-compat: optional, and the old name is also read off a value the checker cannot type; renaming it stays assignable and silently yields undefined
|
|
18
18
|
/** For resource-share/embed links: the shared resource's type + id. */
|
|
19
|
-
resourceType?: string;
|
|
20
|
-
resourceId?: string;
|
|
19
|
+
resourceType?: string; // case-violation-ok-legacy-back-compat: optional, and the old name is also read off a value the checker cannot type; renaming it stays assignable and silently yields undefined
|
|
20
|
+
resourceId?: string; // case-violation-ok-legacy-back-compat: optional, and the old name is also read off a value the checker cannot type; renaming it stays assignable and silently yields undefined
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
/**
|
|
@@ -27,25 +27,25 @@ export interface MagicLinkScopeEntry {
|
|
|
27
27
|
*/
|
|
28
28
|
export interface MagicLinkJWTClaims {
|
|
29
29
|
/** Issuer — MJ's public URL; resolves to the registered `magic-link` auth provider. */
|
|
30
|
-
iss: string;
|
|
30
|
+
iss: string; // case-violation-ok-legacy-back-compat: the type crosses a serialization boundary (JSON / HTTP body), so this member name is part of a wire or on-disk shape
|
|
31
31
|
/** Audience — the configured magic-link audience (default `mj-magic-link`). */
|
|
32
|
-
aud: string;
|
|
32
|
+
aud: string; // case-violation-ok-legacy-back-compat: the type crosses a serialization boundary (JSON / HTTP body), so this member name is part of a wire or on-disk shape
|
|
33
33
|
/** Subject — `magic-link|<inviteId>`. */
|
|
34
|
-
sub: string;
|
|
34
|
+
sub: string; // case-violation-ok-legacy-back-compat: the type crosses a serialization boundary (JSON / HTTP body), so this member name is part of a wire or on-disk shape
|
|
35
35
|
/** Issued-at (epoch seconds). */
|
|
36
|
-
iat: number;
|
|
36
|
+
iat: number; // case-violation-ok-legacy-back-compat: the type crosses a serialization boundary (JSON / HTTP body), so this member name is part of a wire or on-disk shape
|
|
37
37
|
/** Expiry (epoch seconds). */
|
|
38
|
-
exp: number;
|
|
39
|
-
email: string;
|
|
40
|
-
given_name?: string;
|
|
41
|
-
family_name?: string;
|
|
42
|
-
name?: string;
|
|
38
|
+
exp: number; // case-violation-ok-legacy-back-compat: the type crosses a serialization boundary (JSON / HTTP body), so this member name is part of a wire or on-disk shape
|
|
39
|
+
email: string; // case-violation-ok-legacy-back-compat: the type crosses a serialization boundary (JSON / HTTP body), so this member name is part of a wire or on-disk shape
|
|
40
|
+
given_name?: string; // case-violation-ok-legacy-back-compat: snake_case mirrors an external payload — the remote spelling is the contract, not MJ convention
|
|
41
|
+
family_name?: string; // case-violation-ok-legacy-back-compat: snake_case mirrors an external payload — the remote spelling is the contract, not MJ convention
|
|
42
|
+
name?: string; // case-violation-ok-legacy-back-compat: the type crosses a serialization boundary (JSON / HTTP body), so this member name is part of a wire or on-disk shape
|
|
43
43
|
/** The single Application this session is scoped to. */
|
|
44
|
-
mj_app_id: string;
|
|
44
|
+
mj_app_id: string; // case-violation-ok-legacy-back-compat: snake_case mirrors an external payload — the remote spelling is the contract, not MJ convention
|
|
45
45
|
/** The restricted role name assigned to this user (informational; enforcement is server-side via the role's entity permissions). */
|
|
46
|
-
mj_role: string;
|
|
46
|
+
mj_role: string; // case-violation-ok-legacy-back-compat: snake_case mirrors an external payload — the remote spelling is the contract, not MJ convention
|
|
47
47
|
/** UserID of the internal user who issued the invite (attribution/audit). Absent on links whose inviter could not be resolved. */
|
|
48
|
-
mj_invited_by?: string;
|
|
48
|
+
mj_invited_by?: string; // case-violation-ok-legacy-back-compat: snake_case mirrors an external payload — the remote spelling is the contract, not MJ convention
|
|
49
49
|
/**
|
|
50
50
|
* Per-session scope UNION (Phase 4+). Each entry is one redeemed link's grant.
|
|
51
51
|
* The server enforces anonymous sessions against THIS set (not the user's role
|
|
@@ -53,81 +53,81 @@ export interface MagicLinkJWTClaims {
|
|
|
53
53
|
* different scopes without accretion. For email sessions the singular mj_app_id/
|
|
54
54
|
* mj_role remain authoritative; this carries the union when links are stacked.
|
|
55
55
|
*/
|
|
56
|
-
mj_scopes?: MagicLinkScopeEntry[];
|
|
56
|
+
mj_scopes?: MagicLinkScopeEntry[]; // case-violation-ok-legacy-back-compat: snake_case mirrors an external payload — the remote spelling is the contract, not MJ convention
|
|
57
57
|
/** True when this session resolves to the shared Anonymous principal (claims-based enforcement). */
|
|
58
|
-
mj_anon?: boolean;
|
|
58
|
+
mj_anon?: boolean; // case-violation-ok-legacy-back-compat: snake_case mirrors an external payload — the remote spelling is the contract, not MJ convention
|
|
59
59
|
/** Opaque per-session id — correlates one anonymous session's activity across audit rows without a real user. */
|
|
60
|
-
mj_sid?: string;
|
|
60
|
+
mj_sid?: string; // case-violation-ok-legacy-back-compat: snake_case mirrors an external payload — the remote spelling is the contract, not MJ convention
|
|
61
61
|
/**
|
|
62
62
|
* Public web widget instance id (additive — set only for widget guest sessions
|
|
63
63
|
* minted by WidgetSessionService). Binds the synthesized guest principal to one
|
|
64
64
|
* widget instance so its pinned agent / guest role can be locked down. Absent on
|
|
65
65
|
* ordinary magic-link sessions.
|
|
66
66
|
*/
|
|
67
|
-
mj_widget_id?: string;
|
|
67
|
+
mj_widget_id?: string; // case-violation-ok-legacy-back-compat: snake_case mirrors an external payload — the remote spelling is the contract, not MJ convention
|
|
68
68
|
/**
|
|
69
69
|
* Host-asserted visitor email for a widget `host-identity` session (additive). The
|
|
70
70
|
* authoritative `email`/`sub` still resolve the constrained shared Anonymous principal;
|
|
71
71
|
* this carries WHO the host says the visitor is, for the agent to look up their account —
|
|
72
72
|
* without granting that account's permissions. Absent on anonymous/ordinary sessions.
|
|
73
73
|
*/
|
|
74
|
-
mj_host_email?: string;
|
|
74
|
+
mj_host_email?: string; // case-violation-ok-legacy-back-compat: snake_case mirrors an external payload — the remote spelling is the contract, not MJ convention
|
|
75
75
|
/**
|
|
76
76
|
* Returning-visitor anchor for a widget guest session (additive, RV1). Carried so the VOICE path —
|
|
77
77
|
* whose conversation is created server-side — can stamp the same Conversation.VisitorKey the text
|
|
78
78
|
* path stamps client-side. Present only when the widget remembers returning visitors.
|
|
79
79
|
*/
|
|
80
|
-
mj_visitor_key?: string;
|
|
80
|
+
mj_visitor_key?: string; // case-violation-ok-legacy-back-compat: snake_case mirrors an external payload — the remote spelling is the contract, not MJ convention
|
|
81
81
|
/** The prior conversation this visit chains from (RV2), for the voice path to stamp Conversation.LastConversationID. */
|
|
82
|
-
mj_last_conversation_id?: string;
|
|
82
|
+
mj_last_conversation_id?: string; // case-violation-ok-legacy-back-compat: snake_case mirrors an external payload — the remote spelling is the contract, not MJ convention
|
|
83
83
|
/** Resolved polymorphic identity entity id (RV4), for the voice path to stamp the existing Conversation.LinkedEntityID / AIAgentSession.LinkedEntityID. */
|
|
84
|
-
mj_linked_entity_id?: string;
|
|
84
|
+
mj_linked_entity_id?: string; // case-violation-ok-legacy-back-compat: snake_case mirrors an external payload — the remote spelling is the contract, not MJ convention
|
|
85
85
|
/** Resolved polymorphic identity record id (RV4), for the voice path to stamp the existing Conversation.LinkedRecordID / AIAgentSession.LinkedRecordID. */
|
|
86
|
-
mj_linked_record_id?: string;
|
|
86
|
+
mj_linked_record_id?: string; // case-violation-ok-legacy-back-compat: snake_case mirrors an external payload — the remote spelling is the contract, not MJ convention
|
|
87
87
|
/** Marks the session as magic-link so the Explorer can confine the UI. */
|
|
88
|
-
mj_magic_link: true;
|
|
88
|
+
mj_magic_link: true; // case-violation-ok-legacy-back-compat: snake_case mirrors an external payload — the remote spelling is the contract, not MJ convention
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
/** Parameters for creating a magic-link invite (POST /magic-link/create). */
|
|
92
92
|
export interface CreateMagicLinkInviteParams {
|
|
93
93
|
/** Recipient email — becomes the provisioned user's email. */
|
|
94
|
-
email: string;
|
|
94
|
+
email: string; // case-violation-ok-legacy-back-compat: the old name is also read off a value typed `any`, where a rename would compile and silently return undefined
|
|
95
95
|
/** The Application the invite grants access to. */
|
|
96
|
-
|
|
96
|
+
ApplicationId: string;
|
|
97
97
|
/** Restricted role to assign. Defaults to the configured `restrictedRoleName`. */
|
|
98
|
-
|
|
98
|
+
RoleId?: string;
|
|
99
99
|
/** Hours until the link expires. Defaults to config `defaultExpiresInHours`. */
|
|
100
|
-
|
|
100
|
+
ExpiresInHours?: number;
|
|
101
101
|
/** Maximum redemptions. Defaults to 1 (single-use). */
|
|
102
|
-
|
|
102
|
+
MaxUses?: number;
|
|
103
103
|
/** Optional given/family name to seed the provisioned user. */
|
|
104
|
-
firstName?: string;
|
|
105
|
-
lastName?: string;
|
|
104
|
+
firstName?: string; // case-violation-ok-legacy-back-compat: optional, and the old name is also read off a value the checker cannot type; renaming it stays assignable and silently yields undefined
|
|
105
|
+
lastName?: string; // case-violation-ok-legacy-back-compat: optional, and the old name is also read off a value the checker cannot type; renaming it stays assignable and silently yields undefined
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
/** Result of creating an invite. */
|
|
109
109
|
export interface CreateMagicLinkInviteResult {
|
|
110
|
-
success: boolean;
|
|
111
|
-
inviteId?: string;
|
|
110
|
+
success: boolean; // case-violation-ok-legacy-back-compat: the type crosses a serialization boundary (JSON / HTTP body), so this member name is part of a wire or on-disk shape
|
|
111
|
+
inviteId?: string; // case-violation-ok-legacy-back-compat: the type crosses a serialization boundary (JSON / HTTP body), so this member name is part of a wire or on-disk shape
|
|
112
112
|
/** Full redemption URL to share. */
|
|
113
|
-
redemptionUrl?: string;
|
|
113
|
+
redemptionUrl?: string; // case-violation-ok-legacy-back-compat: the type crosses a serialization boundary (JSON / HTTP body), so this member name is part of a wire or on-disk shape
|
|
114
114
|
/**
|
|
115
115
|
* The raw token, returned ONLY when no email provider is configured (so the
|
|
116
116
|
* caller can deliver the link out of band). Never returned once email send
|
|
117
117
|
* succeeds, and never persisted.
|
|
118
118
|
*/
|
|
119
|
-
rawToken?: string;
|
|
119
|
+
rawToken?: string; // case-violation-ok-legacy-back-compat: the type crosses a serialization boundary (JSON / HTTP body), so this member name is part of a wire or on-disk shape
|
|
120
120
|
/** Whether the invite email was dispatched. */
|
|
121
|
-
emailSent?: boolean;
|
|
121
|
+
emailSent?: boolean; // case-violation-ok-legacy-back-compat: the type crosses a serialization boundary (JSON / HTTP body), so this member name is part of a wire or on-disk shape
|
|
122
122
|
/** ISO expiry timestamp. */
|
|
123
|
-
expiresAt?: string;
|
|
124
|
-
error?: string;
|
|
123
|
+
expiresAt?: string; // case-violation-ok-legacy-back-compat: the type crosses a serialization boundary (JSON / HTTP body), so this member name is part of a wire or on-disk shape
|
|
124
|
+
error?: string; // case-violation-ok-legacy-back-compat: the type crosses a serialization boundary (JSON / HTTP body), so this member name is part of a wire or on-disk shape
|
|
125
125
|
/**
|
|
126
126
|
* Set when the request was rejected for authorization reasons:
|
|
127
127
|
* `forbidden` — caller may not issue invites; `invalid_role` — the requested
|
|
128
128
|
* role is not grantable via magic-link. Drives the HTTP status in the router.
|
|
129
129
|
*/
|
|
130
|
-
errorCode?: 'forbidden' | 'invalid_role';
|
|
130
|
+
errorCode?: 'forbidden' | 'invalid_role'; // case-violation-ok-legacy-back-compat: the type crosses a serialization boundary (JSON / HTTP body), so this member name is part of a wire or on-disk shape
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
/** Why a redemption failed. */
|
|
@@ -139,25 +139,25 @@ export type RedeemErrorCode = 'not_found' | 'expired' | 'consumed' | 'revoked' |
|
|
|
139
139
|
* all fields optional because the API/JSON flow may omit them.
|
|
140
140
|
*/
|
|
141
141
|
export interface RedeemAuditContext {
|
|
142
|
-
ipAddress?: string;
|
|
143
|
-
userAgent?: string;
|
|
144
|
-
origin?: string;
|
|
142
|
+
ipAddress?: string; // case-violation-ok-legacy-back-compat: optional, and the old name is also read off a value the checker cannot type; renaming it stays assignable and silently yields undefined
|
|
143
|
+
userAgent?: string; // case-violation-ok-legacy-back-compat: optional, and the old name is also read off a value the checker cannot type; renaming it stays assignable and silently yields undefined
|
|
144
|
+
origin?: string; // case-violation-ok-legacy-back-compat: optional, and the old name is also read off a value the checker cannot type; renaming it stays assignable and silently yields undefined
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
/** Result of redeeming an invite. */
|
|
148
148
|
export interface RedeemMagicLinkResult {
|
|
149
|
-
success: boolean;
|
|
149
|
+
success: boolean; // case-violation-ok-legacy-back-compat: the type crosses a serialization boundary (JSON / HTTP body), so this member name is part of a wire or on-disk shape
|
|
150
150
|
/** The minted session JWT (RS256). */
|
|
151
|
-
token?: string;
|
|
151
|
+
token?: string; // case-violation-ok-legacy-back-compat: the type crosses a serialization boundary (JSON / HTTP body), so this member name is part of a wire or on-disk shape
|
|
152
152
|
/** ISO expiry of the session token. */
|
|
153
|
-
expiresAt?: string;
|
|
153
|
+
expiresAt?: string; // case-violation-ok-legacy-back-compat: the type crosses a serialization boundary (JSON / HTTP body), so this member name is part of a wire or on-disk shape
|
|
154
154
|
/** The Application the session is scoped to. */
|
|
155
|
-
applicationId?: string;
|
|
155
|
+
applicationId?: string; // case-violation-ok-legacy-back-compat: the type crosses a serialization boundary (JSON / HTTP body), so this member name is part of a wire or on-disk shape
|
|
156
156
|
/** The Application's display name (used to deep-link the browser into that app). */
|
|
157
|
-
applicationName?: string;
|
|
157
|
+
applicationName?: string; // case-violation-ok-legacy-back-compat: the type crosses a serialization boundary (JSON / HTTP body), so this member name is part of a wire or on-disk shape
|
|
158
158
|
/** The Application's URL path slug (preferred for deep-linking; falls back to name). */
|
|
159
|
-
applicationPath?: string;
|
|
160
|
-
email?: string;
|
|
161
|
-
error?: string;
|
|
162
|
-
errorCode?: RedeemErrorCode;
|
|
159
|
+
applicationPath?: string; // case-violation-ok-legacy-back-compat: the type crosses a serialization boundary (JSON / HTTP body), so this member name is part of a wire or on-disk shape
|
|
160
|
+
email?: string; // case-violation-ok-legacy-back-compat: the type crosses a serialization boundary (JSON / HTTP body), so this member name is part of a wire or on-disk shape
|
|
161
|
+
error?: string; // case-violation-ok-legacy-back-compat: the type crosses a serialization boundary (JSON / HTTP body), so this member name is part of a wire or on-disk shape
|
|
162
|
+
errorCode?: RedeemErrorCode; // case-violation-ok-legacy-back-compat: the type crosses a serialization boundary (JSON / HTTP body), so this member name is part of a wire or on-disk shape
|
|
163
163
|
}
|
package/src/auth/newUsers.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { configInfo } from "../config.js";
|
|
|
5
5
|
import { MJUserEntity, MJUserRoleEntity, MJUserApplicationEntity, MJUserApplicationEntityEntity, MJApplicationEntityType, MJApplicationEntityEntityType, UserInfoEngine } from "@memberjunction/core-entities";
|
|
6
6
|
|
|
7
7
|
export class NewUserBase {
|
|
8
|
-
public async createNewUser(firstName: string, lastName: string, email: string, linkedRecordType: string = 'None', linkedEntityId?: string, linkedEntityRecordId?: string): Promise<MJUserEntity | null> {
|
|
8
|
+
public async createNewUser(firstName: string, lastName: string, email: string, linkedRecordType: string = 'None', linkedEntityId?: string, linkedEntityRecordId?: string): Promise<MJUserEntity | null> { // case-violation-ok-legacy-back-compat: a subclass overrides this; a stub preserves CALLING the old name but not OVERRIDING it
|
|
9
9
|
try {
|
|
10
10
|
const contextUser: UserInfo | null = ResolveConfiguredPrincipal(
|
|
11
11
|
configInfo?.userHandling?.contextUserForNewUserCreation,
|
package/src/auth/principals.ts
CHANGED
|
@@ -116,7 +116,7 @@ function lowestActiveById<T extends ResolvablePrincipal>(matches: readonly T[]):
|
|
|
116
116
|
* @param users the candidate pool, normally `UserCache.Users`
|
|
117
117
|
* @param systemUserId the deployment's system user ID (`UserCache.Instance.SYSTEM_USER_ID`)
|
|
118
118
|
*/
|
|
119
|
-
export function
|
|
119
|
+
export function ResolvePrincipalFrom<T extends ResolvablePrincipal>(
|
|
120
120
|
candidate: string | undefined,
|
|
121
121
|
users: readonly T[],
|
|
122
122
|
systemUserId: string,
|
|
@@ -156,6 +156,15 @@ export function resolvePrincipalFrom<T extends ResolvablePrincipal>(
|
|
|
156
156
|
};
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
+
/** @deprecated Use {@link ResolvePrincipalFrom}. */
|
|
160
|
+
export function resolvePrincipalFrom<T extends ResolvablePrincipal>(
|
|
161
|
+
candidate: string | undefined,
|
|
162
|
+
users: readonly T[],
|
|
163
|
+
systemUserId: string,
|
|
164
|
+
): PrincipalResolution<T> {
|
|
165
|
+
return ResolvePrincipalFrom(candidate, users, systemUserId);
|
|
166
|
+
}
|
|
167
|
+
|
|
159
168
|
/**
|
|
160
169
|
* Why a configured candidate yielded nothing. The two causes need opposite fixes, so the message
|
|
161
170
|
* has to tell them apart: "no such user" is a typo or the wrong column, while "matched, but
|
|
@@ -230,7 +239,7 @@ export function ReportedMisconfigurationCount(): number {
|
|
|
230
239
|
* handle null rather than assume a principal is always available
|
|
231
240
|
*/
|
|
232
241
|
export function ResolveConfiguredPrincipal(candidate: string | undefined, purpose: string): UserInfo | null {
|
|
233
|
-
const resolution =
|
|
242
|
+
const resolution = ResolvePrincipalFrom(candidate, UserCache.Instance.Users, UserCache.Instance.SYSTEM_USER_ID);
|
|
234
243
|
|
|
235
244
|
if (resolution.warning) {
|
|
236
245
|
const key = `${purpose} :: ${candidate ?? ''}`;
|
package/src/cache.ts
CHANGED
|
@@ -2,9 +2,12 @@ import { LRUCache } from 'lru-cache';
|
|
|
2
2
|
|
|
3
3
|
const oneHourMs = 60 * 60 * 1000;
|
|
4
4
|
|
|
5
|
-
export const
|
|
5
|
+
export const AuthCache = new LRUCache({
|
|
6
6
|
max: 50000,
|
|
7
7
|
ttl: oneHourMs,
|
|
8
8
|
ttlAutopurge: false,
|
|
9
9
|
});
|
|
10
10
|
|
|
11
|
+
/** @deprecated Use {@link AuthCache}. */
|
|
12
|
+
export const authCache = AuthCache;
|
|
13
|
+
|
package/src/config.ts
CHANGED
|
@@ -230,6 +230,29 @@ const cacheSettingsSchema = z.object({
|
|
|
230
230
|
evictionSweepIntervalSeconds: z.number().optional().default(300),
|
|
231
231
|
/** Enable verbose cache logging (hits, misses, evictions). Default: false. */
|
|
232
232
|
verboseLogging: z.boolean().optional().default(false),
|
|
233
|
+
/**
|
|
234
|
+
* Entity names whose FULL ROW may ride along with a cache-invalidation broadcast.
|
|
235
|
+
*
|
|
236
|
+
* The cache-invalidation subscription is delivered to EVERY connected client with no per-user
|
|
237
|
+
* filter (see CacheInvalidationResolver), so any row named here is disclosed to every signed-in
|
|
238
|
+
* session, whatever row-level security or tenant scoping would otherwise apply to reading it.
|
|
239
|
+
*
|
|
240
|
+
* Defaults to `[]`: invalidation still carries the entity name and primary key, which is all a
|
|
241
|
+
* client needs to evict, and the client re-fetches through the normal read path where access
|
|
242
|
+
* control applies. Listing an entity re-enables the apply-in-place optimisation for it — correct
|
|
243
|
+
* only for reference data every signed-in user is allowed to read.
|
|
244
|
+
*
|
|
245
|
+
* What the re-fetch costs depends on the consumer. `ConversationEngine` re-reads the ONE record
|
|
246
|
+
* by primary key. `BaseEngine` (every engine subclass with `AutoRefresh`, the default) applies a
|
|
247
|
+
* remote save in place only when the row is present, so without it a remote save falls through to
|
|
248
|
+
* a full reload of each matching config — a `RunView` of that entity, not a keyed read. Remote
|
|
249
|
+
* deletes still apply in place from the primary key. Engine-cached reference entities that every
|
|
250
|
+
* signed-in user may read are the ones worth listing here.
|
|
251
|
+
*
|
|
252
|
+
* `['*']` opts every entity in, restoring the previous behaviour. Only safe on a deployment where
|
|
253
|
+
* every signed-in user may read every row of every entity.
|
|
254
|
+
*/
|
|
255
|
+
recordDataBroadcastEntities: z.array(z.string()).optional().default([]),
|
|
233
256
|
});
|
|
234
257
|
|
|
235
258
|
const loggingSettingsSchema = z.object({
|
|
@@ -812,9 +835,14 @@ export const DEFAULT_SERVER_CONFIG: Partial<ConfigInfo> = {
|
|
|
812
835
|
* startup summary `Config` line. Declared before `configInfo` so the assignment
|
|
813
836
|
* inside `loadConfig()` (invoked below) is not in its temporal dead zone.
|
|
814
837
|
*/
|
|
815
|
-
export let
|
|
838
|
+
export let ConfigFilePath: string | undefined;
|
|
816
839
|
|
|
817
|
-
export
|
|
840
|
+
export {
|
|
841
|
+
/** @deprecated Use {@link ConfigFilePath} instead. */
|
|
842
|
+
ConfigFilePath as configFilePath,
|
|
843
|
+
};
|
|
844
|
+
|
|
845
|
+
export const configInfo: ConfigInfo = LoadConfig(); // case-violation-ok-legacy-back-compat: the PascalCase name is already taken in this scope
|
|
818
846
|
|
|
819
847
|
export const {
|
|
820
848
|
dbUsername,
|
|
@@ -841,7 +869,7 @@ export const {
|
|
|
841
869
|
restApiOptions: RESTApiOptions,
|
|
842
870
|
} = configInfo;
|
|
843
871
|
|
|
844
|
-
export function
|
|
872
|
+
export function LoadConfig() {
|
|
845
873
|
const configSearchResult = explorer.search(process.cwd());
|
|
846
874
|
|
|
847
875
|
// Start with DEFAULT_SERVER_CONFIG as base
|
|
@@ -851,7 +879,7 @@ export function loadConfig() {
|
|
|
851
879
|
if (configSearchResult && !configSearchResult.isEmpty) {
|
|
852
880
|
// Resolved config-file path. Surfaced in the startup summary `Config` line at standard
|
|
853
881
|
// level (see StartupLogger). Demoted to verbose-only here to avoid a duplicate inline line.
|
|
854
|
-
|
|
882
|
+
ConfigFilePath = configSearchResult.filepath;
|
|
855
883
|
LogStatusEx({ message: `Config file found at ${configSearchResult.filepath}`, verboseOnly: true });
|
|
856
884
|
|
|
857
885
|
// Merge user config with defaults (user config takes precedence)
|
|
@@ -868,3 +896,8 @@ export function loadConfig() {
|
|
|
868
896
|
}
|
|
869
897
|
return configParsing.data;
|
|
870
898
|
}
|
|
899
|
+
|
|
900
|
+
/** @deprecated Use {@link LoadConfig}. */
|
|
901
|
+
export function loadConfig() {
|
|
902
|
+
return LoadConfig();
|
|
903
|
+
}
|
package/src/context.ts
CHANGED
|
@@ -5,13 +5,13 @@ import 'reflect-metadata';
|
|
|
5
5
|
import { Subject, firstValueFrom } from 'rxjs';
|
|
6
6
|
import { AuthenticationError, AuthorizationError } from 'type-graphql';
|
|
7
7
|
import sql from 'mssql';
|
|
8
|
-
import {
|
|
8
|
+
import { GetSigningKeys, GetSystemUser, GetValidationOptions, VerifyUserRecord, ExtractUserInfoFromPayload } from './auth/index.js';
|
|
9
9
|
import { CloneUserForSessionContext } from './auth/sessionUserClone.js';
|
|
10
10
|
import { GetAPIKeyActingContextResolver } from './auth/actingContextResolver.js';
|
|
11
11
|
import { TokenExpiredError, AuthProviderFactory } from '@memberjunction/auth-providers';
|
|
12
|
-
import {
|
|
12
|
+
import { AuthCache } from './cache.js';
|
|
13
13
|
import { userEmailMap, apiKey, mj_core_schema } from './config.js';
|
|
14
|
-
import {
|
|
14
|
+
import { BuildBoundaryLogPayload } from './logging/boundaryLogPayload.js';
|
|
15
15
|
import { StartupLogger } from './logging/StartupLogger.js';
|
|
16
16
|
import { DataSourceInfo, UserPayload } from './types.js';
|
|
17
17
|
import { GetReadOnlyDataSource, GetReadWriteDataSource } from './util.js';
|
|
@@ -110,7 +110,7 @@ async function writeSessionAudit(args: {
|
|
|
110
110
|
// as them silently fails the permission check (this is exactly why the built-in
|
|
111
111
|
// CreateAuditLogRecord, which saves as `user`, drops guest session rows). We record
|
|
112
112
|
// the real session user in UserID but write the row as the system user.
|
|
113
|
-
const writer = await
|
|
113
|
+
const writer = await GetSystemUser();
|
|
114
114
|
const auditType = provider.AuditLogTypes?.find(
|
|
115
115
|
(t) => t?.Name?.trim().toLowerCase() === args.auditTypeName.trim().toLowerCase(),
|
|
116
116
|
);
|
|
@@ -170,7 +170,7 @@ async function auditLoginFailure(
|
|
|
170
170
|
return; // already logged this failing identity/token — don't let a retry loop spam
|
|
171
171
|
}
|
|
172
172
|
// No-arg: getSystemUser pulls from the process-global UserCache (no ConnectionPool needed here).
|
|
173
|
-
const systemUser = await
|
|
173
|
+
const systemUser = await GetSystemUser();
|
|
174
174
|
if (!systemUser) {
|
|
175
175
|
return;
|
|
176
176
|
}
|
|
@@ -316,7 +316,7 @@ function extractWidgetGuestContext(payload: jwt.JwtPayload): WidgetGuestContext
|
|
|
316
316
|
|
|
317
317
|
const verifyAsync = async (issuer: string, token: string): Promise<jwt.JwtPayload> =>
|
|
318
318
|
new Promise((resolve, reject) => {
|
|
319
|
-
const options =
|
|
319
|
+
const options = GetValidationOptions(issuer);
|
|
320
320
|
|
|
321
321
|
if (!options) {
|
|
322
322
|
reject(new Error(`No validation options found for issuer ${issuer}`));
|
|
@@ -336,14 +336,14 @@ const verifyAsync = async (issuer: string, token: string): Promise<jwt.JwtPayloa
|
|
|
336
336
|
verifyOptions.audience = options.audience;
|
|
337
337
|
}
|
|
338
338
|
|
|
339
|
-
jwt.verify(token,
|
|
339
|
+
jwt.verify(token, GetSigningKeys(issuer), verifyOptions, (err, jwt) => {
|
|
340
340
|
if (jwt && typeof jwt !== 'string' && !err) {
|
|
341
341
|
const payload = jwt.payload ?? jwt;
|
|
342
342
|
|
|
343
343
|
// Per-request token confirmation — debug-only (one of the worst
|
|
344
344
|
// "constantly on" offenders on an authenticated server).
|
|
345
345
|
if (isDebugLogLevel()) {
|
|
346
|
-
const userInfo =
|
|
346
|
+
const userInfo = ExtractUserInfoFromPayload(payload);
|
|
347
347
|
console.log(`Valid token: ${userInfo.fullName || 'Unknown'} (${userInfo.email || userInfo.preferredUsername || 'Unknown'})`);
|
|
348
348
|
}
|
|
349
349
|
resolve(payload);
|
|
@@ -359,18 +359,18 @@ const verifyAsync = async (issuer: string, token: string): Promise<jwt.JwtPayloa
|
|
|
359
359
|
*/
|
|
360
360
|
export interface RequestContext {
|
|
361
361
|
/** The API endpoint path (e.g., '/graphql', '/mcp') */
|
|
362
|
-
endpoint: string;
|
|
362
|
+
endpoint: string; // case-violation-ok-legacy-back-compat: the old name is also read off a value typed `any`, where a rename would compile and silently return undefined
|
|
363
363
|
/** HTTP method (e.g., 'POST', 'GET') */
|
|
364
|
-
method: string;
|
|
364
|
+
method: string; // case-violation-ok-legacy-back-compat: the old name is also read off a value typed `any`, where a rename would compile and silently return undefined
|
|
365
365
|
/** GraphQL operation name if available */
|
|
366
|
-
operationName?: string;
|
|
366
|
+
operationName?: string; // case-violation-ok-legacy-back-compat: optional, and the old name is also read off a value the checker cannot type; renaming it stays assignable and silently yields undefined
|
|
367
367
|
/** Client IP address */
|
|
368
|
-
ipAddress?: string;
|
|
368
|
+
ipAddress?: string; // case-violation-ok-legacy-back-compat: optional, and the old name is also read off a value the checker cannot type; renaming it stays assignable and silently yields undefined
|
|
369
369
|
/** User-Agent header */
|
|
370
|
-
userAgent?: string;
|
|
370
|
+
userAgent?: string; // case-violation-ok-legacy-back-compat: optional, and the old name is also read off a value the checker cannot type; renaming it stays assignable and silently yields undefined
|
|
371
371
|
}
|
|
372
372
|
|
|
373
|
-
export const
|
|
373
|
+
export const GetUserPayload = async (
|
|
374
374
|
bearerToken: string,
|
|
375
375
|
sessionId = 'default',
|
|
376
376
|
dataSources: DataSourceInfo[],
|
|
@@ -388,7 +388,7 @@ export const getUserPayload = async (
|
|
|
388
388
|
// This authenticates as the specific user who owns the API key
|
|
389
389
|
if (userApiKey && userApiKey !== String(undefined)) {
|
|
390
390
|
// Use system user as context for validation operations
|
|
391
|
-
const systemUser = await
|
|
391
|
+
const systemUser = await GetSystemUser(readOnlyDataSource);
|
|
392
392
|
const apiKeyEngine = GetAPIKeyEngine();
|
|
393
393
|
const validationResult = await apiKeyEngine.ValidateAPIKey(
|
|
394
394
|
{
|
|
@@ -463,7 +463,7 @@ export const getUserPayload = async (
|
|
|
463
463
|
const systemKeyDigest = createHash('sha256').update(String(systemApiKey)).digest();
|
|
464
464
|
const providedKeyDigest = createHash('sha256').update(String(apiKey)).digest();
|
|
465
465
|
if (timingSafeEqual(systemKeyDigest, providedKeyDigest)) {
|
|
466
|
-
const systemUser = await
|
|
466
|
+
const systemUser = await GetSystemUser(readOnlyDataSource);
|
|
467
467
|
return {
|
|
468
468
|
userRecord: systemUser,
|
|
469
469
|
email: systemUser.Email,
|
|
@@ -497,7 +497,7 @@ export const getUserPayload = async (
|
|
|
497
497
|
throw new TokenExpiredError(expiryDate);
|
|
498
498
|
}
|
|
499
499
|
|
|
500
|
-
if (!
|
|
500
|
+
if (!AuthCache.has(token)) {
|
|
501
501
|
const issuer = payload.iss;
|
|
502
502
|
if (!issuer) {
|
|
503
503
|
console.warn('No issuer claim on token');
|
|
@@ -512,14 +512,14 @@ export const getUserPayload = async (
|
|
|
512
512
|
}
|
|
513
513
|
|
|
514
514
|
await verifyAsync(issuer, token);
|
|
515
|
-
|
|
515
|
+
AuthCache.set(token, true);
|
|
516
516
|
}
|
|
517
517
|
|
|
518
518
|
// Use provider to extract user information
|
|
519
|
-
const userInfo =
|
|
519
|
+
const userInfo = ExtractUserInfoFromPayload(payload);
|
|
520
520
|
const email = userInfo.email ? ((userEmailMap ?? {})[userInfo.email] ?? userInfo.email) : userInfo.preferredUsername;
|
|
521
521
|
|
|
522
|
-
const userRecord = await
|
|
522
|
+
const userRecord = await VerifyUserRecord(
|
|
523
523
|
email,
|
|
524
524
|
userInfo.firstName,
|
|
525
525
|
userInfo.lastName,
|
|
@@ -602,6 +602,9 @@ export const getUserPayload = async (
|
|
|
602
602
|
}
|
|
603
603
|
};
|
|
604
604
|
|
|
605
|
+
/** @deprecated Use {@link GetUserPayload}. */
|
|
606
|
+
export const getUserPayload = GetUserPayload;
|
|
607
|
+
|
|
605
608
|
/**
|
|
606
609
|
* Extracts auth headers and builds a RequestContext from an Express request.
|
|
607
610
|
* Shared by both the unified auth middleware and the WebSocket context.
|
|
@@ -665,7 +668,7 @@ function extractAuthInputs(req: IncomingMessage): {
|
|
|
665
668
|
*
|
|
666
669
|
* Register OAuth callback routes BEFORE this middleware so they remain unauthenticated.
|
|
667
670
|
*/
|
|
668
|
-
export function
|
|
671
|
+
export function CreateUnifiedAuthMiddleware(
|
|
669
672
|
dataSources: DataSourceInfo[]
|
|
670
673
|
): RequestHandler {
|
|
671
674
|
return async (req: Request, res: Response, next: NextFunction): Promise<void> => {
|
|
@@ -680,7 +683,7 @@ export function createUnifiedAuthMiddleware(
|
|
|
680
683
|
const { bearerToken, sessionId, requestDomain, systemApiKey, userApiKey, requestContext } =
|
|
681
684
|
extractAuthInputs(req);
|
|
682
685
|
|
|
683
|
-
const userPayload = await
|
|
686
|
+
const userPayload = await GetUserPayload(
|
|
684
687
|
bearerToken,
|
|
685
688
|
sessionId,
|
|
686
689
|
dataSources,
|
|
@@ -730,13 +733,20 @@ export function createUnifiedAuthMiddleware(
|
|
|
730
733
|
};
|
|
731
734
|
}
|
|
732
735
|
|
|
736
|
+
/** @deprecated Use {@link CreateUnifiedAuthMiddleware}. */
|
|
737
|
+
export function createUnifiedAuthMiddleware(
|
|
738
|
+
dataSources: DataSourceInfo[]
|
|
739
|
+
): RequestHandler {
|
|
740
|
+
return CreateUnifiedAuthMiddleware(dataSources);
|
|
741
|
+
}
|
|
742
|
+
|
|
733
743
|
/**
|
|
734
744
|
* Creates the GraphQL context from an already-authenticated request.
|
|
735
745
|
*
|
|
736
746
|
* The unified auth middleware has already resolved `req.userPayload` before this runs.
|
|
737
747
|
* This function reads the payload and creates per-request database providers.
|
|
738
748
|
*/
|
|
739
|
-
export const
|
|
749
|
+
export const ContextFunction =
|
|
740
750
|
({ setupComplete$, dataSource, dataSources }: { setupComplete$: Subject<unknown>; dataSource: sql.ConnectionPool, dataSources: DataSourceInfo[] }) =>
|
|
741
751
|
async ({ req }: { req: IncomingMessage }) => {
|
|
742
752
|
await firstValueFrom(setupComplete$); // wait for setup to complete before processing the request
|
|
@@ -748,7 +758,7 @@ export const contextFunction =
|
|
|
748
758
|
// Per-request GraphQL boundary line — debug-only. Kept (not deleted) so the
|
|
749
759
|
// data is available when an operator opts into debug, but off by default.
|
|
750
760
|
if (operationName !== 'IntrospectionQuery' && isDebugLogLevel()) {
|
|
751
|
-
console.dir(
|
|
761
|
+
console.dir(BuildBoundaryLogPayload(operationName), { depth: null, breakLength: 200 });
|
|
752
762
|
}
|
|
753
763
|
|
|
754
764
|
// Auth already happened in the unified auth middleware — just read the result
|
|
@@ -773,6 +783,9 @@ export const contextFunction =
|
|
|
773
783
|
};
|
|
774
784
|
};
|
|
775
785
|
|
|
786
|
+
/** @deprecated Use {@link ContextFunction}. */
|
|
787
|
+
export const contextFunction = ContextFunction;
|
|
788
|
+
|
|
776
789
|
/**
|
|
777
790
|
* Creates per-request DatabaseProviderBase instances for the GraphQL context.
|
|
778
791
|
* Handles both SQL Server and PostgreSQL paths.
|
package/src/directives/Public.ts
CHANGED
|
@@ -11,7 +11,7 @@ export function Public(): PropertyDecorator | MethodDecorator | ClassDecorator {
|
|
|
11
11
|
Directive(`@${DIRECTIVE_NAME}`)(targetOrPrototype, propertyKey, descriptor);
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
export const
|
|
14
|
+
export const PublicDirective: DirectiveBuilder = {
|
|
15
15
|
typeDefs: `directive @${DIRECTIVE_NAME} on FIELD_DEFINITION`,
|
|
16
16
|
transformer: (schema) => {
|
|
17
17
|
const fieldMapper: FieldMapper = (fieldConfig) => {
|
|
@@ -40,3 +40,6 @@ export const publicDirective: DirectiveBuilder = {
|
|
|
40
40
|
return mapSchema(schema, { [MapperKind.OBJECT_FIELD]: fieldMapper });
|
|
41
41
|
},
|
|
42
42
|
};
|
|
43
|
+
|
|
44
|
+
/** @deprecated Use {@link PublicDirective}. */
|
|
45
|
+
export const publicDirective = PublicDirective;
|
|
@@ -9,7 +9,7 @@ export function RequireSystemUser(): PropertyDecorator | MethodDecorator | Class
|
|
|
9
9
|
return (targetOrPrototype, propertyKey, descriptor) => Directive(`@${DIRECTIVE_NAME}`)(targetOrPrototype, propertyKey, descriptor);
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
export const
|
|
12
|
+
export const RequireSystemUserDirective: DirectiveBuilder = {
|
|
13
13
|
typeDefs: `directive @${DIRECTIVE_NAME} on FIELD_DEFINITION`,
|
|
14
14
|
transformer: (schema) => {
|
|
15
15
|
const fieldMapper: FieldMapper = (fieldConfig) => {
|
|
@@ -29,3 +29,6 @@ export const requireSystemUserDirective: DirectiveBuilder = {
|
|
|
29
29
|
return mapSchema(schema, { [MapperKind.OBJECT_FIELD]: fieldMapper });
|
|
30
30
|
},
|
|
31
31
|
};
|
|
32
|
+
|
|
33
|
+
/** @deprecated Use {@link RequireSystemUserDirective}. */
|
|
34
|
+
export const requireSystemUserDirective = RequireSystemUserDirective;
|