@memberjunction/server 6.2.0-edge.5 → 6.2.0-edge.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +96 -1
- package/dist/.tsbuildinfo +1 -1
- package/dist/agentSessions/BridgeHostInstance.d.ts +8 -3
- package/dist/agentSessions/BridgeHostInstance.d.ts.map +1 -1
- package/dist/agentSessions/BridgeHostInstance.js +14 -4
- package/dist/agentSessions/BridgeHostInstance.js.map +1 -1
- package/dist/agentSessions/HandoffOfferExpiry.d.ts +10 -0
- package/dist/agentSessions/HandoffOfferExpiry.d.ts.map +1 -0
- package/dist/agentSessions/HandoffOfferExpiry.js +18 -0
- package/dist/agentSessions/HandoffOfferExpiry.js.map +1 -0
- package/dist/agentSessions/ReturningVisitorRecap.js +1 -0
- package/dist/agentSessions/ReturningVisitorRecap.js.map +1 -1
- package/dist/agentSessions/SessionJanitor.d.ts +34 -11
- package/dist/agentSessions/SessionJanitor.d.ts.map +1 -1
- package/dist/agentSessions/SessionJanitor.js +88 -44
- package/dist/agentSessions/SessionJanitor.js.map +1 -1
- package/dist/agentSessions/SessionManager.d.ts +29 -9
- package/dist/agentSessions/SessionManager.d.ts.map +1 -1
- package/dist/agentSessions/SessionManager.js +62 -16
- package/dist/agentSessions/SessionManager.js.map +1 -1
- package/dist/agentSessions/conversationBrowsers.d.ts +61 -0
- package/dist/agentSessions/conversationBrowsers.d.ts.map +1 -0
- package/dist/agentSessions/conversationBrowsers.js +118 -0
- package/dist/agentSessions/conversationBrowsers.js.map +1 -0
- package/dist/agentSessions/sessionDeadline.d.ts +43 -0
- package/dist/agentSessions/sessionDeadline.d.ts.map +1 -0
- package/dist/agentSessions/sessionDeadline.js +68 -0
- package/dist/agentSessions/sessionDeadline.js.map +1 -0
- package/dist/auth/APIKeyScopeAuth.d.ts.map +1 -1
- package/dist/auth/APIKeyScopeAuth.js +5 -4
- package/dist/auth/APIKeyScopeAuth.js.map +1 -1
- package/dist/auth/AuthProviderCatalogRouter.d.ts.map +1 -1
- package/dist/auth/AuthProviderCatalogRouter.js +2 -0
- package/dist/auth/AuthProviderCatalogRouter.js.map +1 -1
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +51 -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/loginEmailResolution.d.ts +41 -0
- package/dist/auth/loginEmailResolution.d.ts.map +1 -0
- package/dist/auth/loginEmailResolution.js +47 -0
- package/dist/auth/loginEmailResolution.js.map +1 -0
- package/dist/auth/magicLink/MagicLinkKeys.d.ts +51 -3
- package/dist/auth/magicLink/MagicLinkKeys.d.ts.map +1 -1
- package/dist/auth/magicLink/MagicLinkKeys.js +130 -13
- package/dist/auth/magicLink/MagicLinkKeys.js.map +1 -1
- package/dist/auth/magicLink/MagicLinkRouter.d.ts +3 -0
- package/dist/auth/magicLink/MagicLinkRouter.d.ts.map +1 -1
- package/dist/auth/magicLink/MagicLinkRouter.js +23 -5
- package/dist/auth/magicLink/MagicLinkRouter.js.map +1 -1
- package/dist/auth/magicLink/MagicLinkService.d.ts +39 -5
- package/dist/auth/magicLink/MagicLinkService.d.ts.map +1 -1
- package/dist/auth/magicLink/MagicLinkService.js +221 -9
- package/dist/auth/magicLink/MagicLinkService.js.map +1 -1
- package/dist/auth/magicLink/index.d.ts +1 -1
- package/dist/auth/magicLink/index.d.ts.map +1 -1
- package/dist/auth/magicLink/index.js +1 -1
- package/dist/auth/magicLink/index.js.map +1 -1
- package/dist/auth/magicLink/redeemLanding.d.ts +2 -2
- package/dist/auth/magicLink/redeemLanding.d.ts.map +1 -1
- package/dist/auth/magicLink/redeemLanding.js +7 -4
- package/dist/auth/magicLink/redeemLanding.js.map +1 -1
- package/dist/auth/magicLink/types.d.ts +39 -3
- package/dist/auth/magicLink/types.d.ts.map +1 -1
- package/dist/auth/magicLink/types.js +0 -4
- package/dist/auth/magicLink/types.js.map +1 -1
- package/dist/auth/newUsers.d.ts.map +1 -1
- package/dist/auth/newUsers.js +1 -0
- package/dist/auth/newUsers.js.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/backgroundSweepConfigUnits.d.ts +231 -0
- package/dist/backgroundSweepConfigUnits.d.ts.map +1 -0
- package/dist/backgroundSweepConfigUnits.js +180 -0
- package/dist/backgroundSweepConfigUnits.js.map +1 -0
- 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 +1402 -8
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +120 -0
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +5 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +64 -12
- package/dist/context.js.map +1 -1
- package/dist/coreRoutes.d.ts +3 -1
- package/dist/coreRoutes.d.ts.map +1 -1
- package/dist/coreRoutes.js +20 -4
- package/dist/coreRoutes.js.map +1 -1
- package/dist/generated/graphql-schemas/__mj.d.ts +863 -14
- package/dist/generated/graphql-schemas/__mj.d.ts.map +1 -1
- package/dist/generated/graphql-schemas/__mj.js +4167 -62
- package/dist/generated/graphql-schemas/__mj.js.map +1 -1
- package/dist/generic/CacheInvalidationResolver.d.ts +50 -30
- package/dist/generic/CacheInvalidationResolver.d.ts.map +1 -1
- package/dist/generic/CacheInvalidationResolver.js +154 -79
- package/dist/generic/CacheInvalidationResolver.js.map +1 -1
- package/dist/generic/OrphanedConversationDetailReconciler.d.ts +11 -0
- package/dist/generic/OrphanedConversationDetailReconciler.d.ts.map +1 -1
- package/dist/generic/OrphanedConversationDetailReconciler.js +29 -1
- 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 +93 -11
- package/dist/generic/PushStatusResolver.js.map +1 -1
- package/dist/generic/ResolverBase.d.ts +114 -29
- package/dist/generic/ResolverBase.d.ts.map +1 -1
- package/dist/generic/ResolverBase.js +509 -220
- package/dist/generic/ResolverBase.js.map +1 -1
- package/dist/generic/RunViewResolver.d.ts +15 -3
- package/dist/generic/RunViewResolver.d.ts.map +1 -1
- package/dist/generic/RunViewResolver.js +126 -20
- 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/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +262 -84
- package/dist/index.js.map +1 -1
- package/dist/integration/ConnectionPause.d.ts +121 -0
- package/dist/integration/ConnectionPause.d.ts.map +1 -0
- package/dist/integration/ConnectionPause.js +183 -0
- package/dist/integration/ConnectionPause.js.map +1 -0
- package/dist/integration/CustomColumnPromoter.d.ts +72 -6
- package/dist/integration/CustomColumnPromoter.d.ts.map +1 -1
- package/dist/integration/CustomColumnPromoter.js +93 -47
- package/dist/integration/CustomColumnPromoter.js.map +1 -1
- package/dist/integration/EntityMapLifecycle.d.ts +78 -4
- package/dist/integration/EntityMapLifecycle.d.ts.map +1 -1
- package/dist/integration/EntityMapLifecycle.js +199 -5
- package/dist/integration/EntityMapLifecycle.js.map +1 -1
- package/dist/integration/InactiveRowWarnings.d.ts +31 -0
- package/dist/integration/InactiveRowWarnings.d.ts.map +1 -1
- package/dist/integration/InactiveRowWarnings.js +29 -0
- package/dist/integration/InactiveRowWarnings.js.map +1 -1
- package/dist/integration/ObjectNamesByID.d.ts +28 -0
- package/dist/integration/ObjectNamesByID.d.ts.map +1 -0
- package/dist/integration/ObjectNamesByID.js +87 -0
- package/dist/integration/ObjectNamesByID.js.map +1 -0
- package/dist/integration/PostRestartIntrospect.d.ts +26 -0
- package/dist/integration/PostRestartIntrospect.d.ts.map +1 -0
- package/dist/integration/PostRestartIntrospect.js +27 -0
- package/dist/integration/PostRestartIntrospect.js.map +1 -0
- package/dist/integration/RSUPostRestartProgress.d.ts +176 -0
- package/dist/integration/RSUPostRestartProgress.d.ts.map +1 -0
- package/dist/integration/RSUPostRestartProgress.js +323 -0
- package/dist/integration/RSUPostRestartProgress.js.map +1 -0
- package/dist/integration/RSUProgressBridge.d.ts +41 -2
- package/dist/integration/RSUProgressBridge.d.ts.map +1 -1
- package/dist/integration/RSUProgressBridge.js +84 -1
- package/dist/integration/RSUProgressBridge.js.map +1 -1
- package/dist/integration/RunArtifactAuthorization.d.ts +39 -0
- package/dist/integration/RunArtifactAuthorization.d.ts.map +1 -0
- package/dist/integration/RunArtifactAuthorization.js +45 -0
- package/dist/integration/RunArtifactAuthorization.js.map +1 -0
- package/dist/integration/SchemaRefreshLaunch.d.ts +9 -0
- package/dist/integration/SchemaRefreshLaunch.d.ts.map +1 -1
- package/dist/integration/SchemaRefreshLaunch.js +3 -2
- package/dist/integration/SchemaRefreshLaunch.js.map +1 -1
- package/dist/integration/ScopedFieldsForBuild.d.ts +46 -0
- package/dist/integration/ScopedFieldsForBuild.d.ts.map +1 -0
- package/dist/integration/ScopedFieldsForBuild.js +91 -0
- package/dist/integration/ScopedFieldsForBuild.js.map +1 -0
- package/dist/integration/TargetConfigGuard.d.ts +40 -0
- package/dist/integration/TargetConfigGuard.d.ts.map +1 -0
- package/dist/integration/TargetConfigGuard.js +40 -0
- package/dist/integration/TargetConfigGuard.js.map +1 -0
- 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/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/ownedRealtimeSession.d.ts +8 -6
- package/dist/realtimeSessions/ownedRealtimeSession.d.ts.map +1 -1
- package/dist/realtimeSessions/ownedRealtimeSession.js +14 -6
- package/dist/realtimeSessions/ownedRealtimeSession.js.map +1 -1
- package/dist/realtimeSessions/sessionAccess.d.ts +103 -11
- package/dist/realtimeSessions/sessionAccess.d.ts.map +1 -1
- package/dist/realtimeSessions/sessionAccess.js +147 -22
- 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 +203 -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/visitorIdentity.d.ts.map +1 -1
- package/dist/realtimeWidget/visitorIdentity.js +1 -0
- package/dist/realtimeWidget/visitorIdentity.js.map +1 -1
- package/dist/realtimeWidget/widgetCore.d.ts +20 -1
- package/dist/realtimeWidget/widgetCore.d.ts.map +1 -1
- package/dist/realtimeWidget/widgetCore.js +21 -8
- 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 +3 -1
- package/dist/realtimeWidget/widgetGuestElevation.js.map +1 -1
- package/dist/requestOrigin.d.ts +22 -0
- package/dist/requestOrigin.d.ts.map +1 -0
- package/dist/requestOrigin.js +60 -0
- package/dist/requestOrigin.js.map +1 -0
- 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 +44 -17
- package/dist/resolvers/AgentSessionResolver.js.map +1 -1
- package/dist/resolvers/AutotagPipelineResolver.d.ts.map +1 -1
- package/dist/resolvers/AutotagPipelineResolver.js +2 -1
- package/dist/resolvers/AutotagPipelineResolver.js.map +1 -1
- package/dist/resolvers/ConversationRunEventsResolver.d.ts.map +1 -1
- package/dist/resolvers/ConversationRunEventsResolver.js +2 -0
- package/dist/resolvers/ConversationRunEventsResolver.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/ExecuteRemoteOperationResolver.d.ts +6 -0
- package/dist/resolvers/ExecuteRemoteOperationResolver.d.ts.map +1 -1
- package/dist/resolvers/ExecuteRemoteOperationResolver.js +30 -7
- package/dist/resolvers/ExecuteRemoteOperationResolver.js.map +1 -1
- package/dist/resolvers/FetchEntityVectorsResolver.d.ts +28 -0
- package/dist/resolvers/FetchEntityVectorsResolver.d.ts.map +1 -1
- package/dist/resolvers/FetchEntityVectorsResolver.js +117 -21
- 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 +5 -0
- package/dist/resolvers/FileResolver.d.ts.map +1 -1
- package/dist/resolvers/FileResolver.js +13 -4
- package/dist/resolvers/FileResolver.js.map +1 -1
- package/dist/resolvers/GetDataResolver.d.ts.map +1 -1
- package/dist/resolvers/GetDataResolver.js +34 -13
- package/dist/resolvers/GetDataResolver.js.map +1 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.d.ts +401 -11
- package/dist/resolvers/IntegrationDiscoveryResolver.d.ts.map +1 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.js +2713 -1290
- package/dist/resolvers/IntegrationDiscoveryResolver.js.map +1 -1
- package/dist/resolvers/MCPResolver.d.ts.map +1 -1
- package/dist/resolvers/MCPResolver.js +13 -2
- package/dist/resolvers/MCPResolver.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.map +1 -1
- package/dist/resolvers/QueryResolver.js +20 -6
- package/dist/resolvers/QueryResolver.js.map +1 -1
- package/dist/resolvers/QuerySystemUserResolver.d.ts +38 -0
- package/dist/resolvers/QuerySystemUserResolver.d.ts.map +1 -1
- package/dist/resolvers/QuerySystemUserResolver.js +184 -88
- 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/RealtimeBridgeResolver.d.ts.map +1 -1
- package/dist/resolvers/RealtimeBridgeResolver.js +1 -0
- package/dist/resolvers/RealtimeBridgeResolver.js.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts +22 -2
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.js +118 -33
- package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
- package/dist/resolvers/RemoteBrowserActionResolver.d.ts +62 -10
- package/dist/resolvers/RemoteBrowserActionResolver.d.ts.map +1 -1
- package/dist/resolvers/RemoteBrowserActionResolver.js +224 -39
- package/dist/resolvers/RemoteBrowserActionResolver.js.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.d.ts +80 -16
- package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.js +388 -125
- package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
- package/dist/resolvers/RunAIPromptResolver.d.ts +5 -3
- package/dist/resolvers/RunAIPromptResolver.d.ts.map +1 -1
- package/dist/resolvers/RunAIPromptResolver.js +19 -18
- package/dist/resolvers/RunAIPromptResolver.js.map +1 -1
- package/dist/resolvers/RunTemplateResolver.d.ts.map +1 -1
- package/dist/resolvers/RunTemplateResolver.js +7 -5
- 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/SyncDataResolver.d.ts.map +1 -1
- package/dist/resolvers/SyncDataResolver.js +4 -0
- package/dist/resolvers/SyncDataResolver.js.map +1 -1
- package/dist/resolvers/TestQuerySQLResolver.d.ts.map +1 -1
- package/dist/resolvers/TestQuerySQLResolver.js +1 -0
- package/dist/resolvers/TestQuerySQLResolver.js.map +1 -1
- package/dist/resolvers/TransactionGroupResolver.d.ts +17 -2
- package/dist/resolvers/TransactionGroupResolver.d.ts.map +1 -1
- package/dist/resolvers/TransactionGroupResolver.js +60 -15
- 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/meetingRecordingRegistration.d.ts.map +1 -1
- package/dist/resolvers/meetingRecordingRegistration.js +2 -0
- package/dist/resolvers/meetingRecordingRegistration.js.map +1 -1
- 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/MediaAccessKeys.d.ts.map +1 -1
- package/dist/rest/MediaAccessKeys.js +6 -2
- package/dist/rest/MediaAccessKeys.js.map +1 -1
- package/dist/rest/OAuthCallbackHandler.d.ts.map +1 -1
- package/dist/rest/OAuthCallbackHandler.js +11 -5
- package/dist/rest/OAuthCallbackHandler.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 +3 -3
- package/dist/rest/RealtimeRecordingHandler.d.ts.map +1 -1
- package/dist/rest/RealtimeRecordingHandler.js +6 -8
- package/dist/rest/RealtimeRecordingHandler.js.map +1 -1
- package/dist/rest/ViewOperationsHandler.d.ts +6 -0
- package/dist/rest/ViewOperationsHandler.d.ts.map +1 -1
- package/dist/rest/ViewOperationsHandler.js +24 -6
- package/dist/rest/ViewOperationsHandler.js.map +1 -1
- package/dist/rest/setupRESTEndpoints.d.ts +3 -1
- package/dist/rest/setupRESTEndpoints.d.ts.map +1 -1
- package/dist/rest/setupRESTEndpoints.js +11 -2
- package/dist/rest/setupRESTEndpoints.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/DurableEntityActionTaskSubmitter.d.ts.map +1 -1
- package/dist/services/DurableEntityActionTaskSubmitter.js +6 -1
- package/dist/services/DurableEntityActionTaskSubmitter.js.map +1 -1
- package/dist/services/TaskGraphActionRunner.d.ts.map +1 -1
- package/dist/services/TaskGraphActionRunner.js +2 -26
- package/dist/services/TaskGraphActionRunner.js.map +1 -1
- package/dist/services/TaskGraphAgentRunner.d.ts +6 -0
- package/dist/services/TaskGraphAgentRunner.d.ts.map +1 -1
- package/dist/services/TaskGraphAgentRunner.js +38 -0
- package/dist/services/TaskGraphAgentRunner.js.map +1 -1
- package/dist/services/TaskGraphContinuationDeliverer.d.ts +5 -0
- package/dist/services/TaskGraphContinuationDeliverer.d.ts.map +1 -1
- package/dist/services/TaskGraphContinuationDeliverer.js +43 -15
- package/dist/services/TaskGraphContinuationDeliverer.js.map +1 -1
- package/dist/services/WorkQueueHostService.d.ts +2 -1
- package/dist/services/WorkQueueHostService.d.ts.map +1 -1
- package/dist/services/WorkQueueHostService.js +19 -4
- package/dist/services/WorkQueueHostService.js.map +1 -1
- package/dist/services/workQueueConfig.d.ts +2 -2
- package/dist/services/workQueueConfig.js +5 -5
- package/dist/services/workQueueConfig.js.map +1 -1
- package/dist/sharedCache.js +1 -1
- package/dist/sharedCache.js.map +1 -1
- package/dist/types.d.ts +40 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +98 -98
- package/src/__tests__/APIKeyScopeAuth.test.ts +4 -8
- package/src/__tests__/ActionResolver.fieldSecurity.test.ts +237 -0
- package/src/__tests__/ActiveOperations.test.ts +68 -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 +150 -0
- package/src/__tests__/AssertTargetConfigs.test.ts +75 -0
- package/src/__tests__/BatchApplyParity.test.ts +109 -0
- package/src/__tests__/BridgeHostInstance.test.ts +42 -0
- package/src/__tests__/CollectInactiveRowWarnings.test.ts +115 -0
- package/src/__tests__/ConnectionPause.test.ts +192 -0
- package/src/__tests__/ConnectionPauseResolver.test.ts +166 -0
- package/src/__tests__/ConnectionPauseSave.test.ts +143 -0
- package/src/__tests__/CustomColumnPromoterCompletion.test.ts +142 -0
- package/src/__tests__/CustomColumnPromoterOnePass.test.ts +15 -1
- package/src/__tests__/DeleteConnectionRemovesPerConnectionCatalog.test.ts +51 -0
- package/src/__tests__/DetachedDiscoveryStart.test.ts +65 -0
- package/src/__tests__/DurableEntityActionTaskSubmitter.test.ts +73 -0
- package/src/__tests__/EntityCommunicationsResolver.actingUser.test.ts +151 -0
- package/src/__tests__/EntityMapLifecycle.rekey.test.ts +252 -0
- package/src/__tests__/EvolutionActsOnWhatItDetects.test.ts +113 -0
- package/src/__tests__/ExecuteRemoteOperationResolver.test.ts +213 -0
- package/src/__tests__/FetchEntityVectorsResolver.test.ts +206 -3
- package/src/__tests__/FileResolver.fieldSecurity.test.ts +82 -0
- package/src/__tests__/HandoffOfferExpiry.test.ts +40 -0
- package/src/__tests__/IntegrationRunArtifactAuthorization.test.ts +126 -0
- package/src/__tests__/MagicLinkKeys.test.ts +102 -0
- package/src/__tests__/MediaAccessKeys.test.ts +57 -10
- package/src/__tests__/NewArrivalsDefaultDisabled.test.ts +50 -0
- package/src/__tests__/ObjectNamesByID.test.ts +176 -0
- package/src/__tests__/PipelineProgressResolver.filter.test.ts +58 -0
- package/src/__tests__/PostRestartMapsInCatalogScope.test.ts +146 -0
- package/src/__tests__/QuerySystemUserResolver.childRows.test.ts +80 -0
- package/src/__tests__/QuerySystemUserResolver.collision.test.ts +200 -0
- package/src/__tests__/QuerySystemUserResolver.fieldSecurity.test.ts +49 -0
- package/src/__tests__/QuerySystemUserResolver.permissions.test.ts +132 -0
- package/src/__tests__/RESTEndpointHandler.test.ts +25 -0
- package/src/__tests__/RSUPostRestartProgress.test.ts +343 -0
- package/src/__tests__/RSUProgressBridge.test.ts +188 -5
- package/src/__tests__/RSUStartupSweepWiring.test.ts +30 -0
- package/src/__tests__/ReactivateRefreshMessage.test.ts +10 -3
- package/src/__tests__/RealtimeClientSessionResolver.configTamper.test.ts +23 -3
- package/src/__tests__/RealtimeClientSessionResolver.test.ts +346 -46
- package/src/__tests__/{RefreshAdoptsNewColumns.test.ts → RefreshReportsNewColumns.test.ts} +25 -16
- package/src/__tests__/RemoteBrowserActionRecovery.test.ts +287 -0
- package/src/__tests__/RemoteBrowserActionResolver.goalRunLink.test.ts +3 -0
- package/src/__tests__/RemoteBrowserActionResolver.ownership.test.ts +100 -0
- package/src/__tests__/RemoteBrowserAudioStream.test.ts +3 -0
- package/src/__tests__/RemoteBrowserSnapshot.test.ts +3 -0
- package/src/__tests__/ResolverBase.clientOldValues.test.ts +344 -14
- package/src/__tests__/ResolverBase.deleteReturnProjection.test.ts +52 -0
- package/src/__tests__/ResolverBase.encryptedApiZeroReencrypt.test.ts +307 -0
- package/src/__tests__/ResolverBase.entityMessageRelay.test.ts +227 -0
- package/src/__tests__/ResolverBase.includeBinaryFields.test.ts +83 -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 +72 -13
- package/src/__tests__/RunAIAgentResolver.consultPredecessor.test.ts +289 -0
- package/src/__tests__/RunAIAgentResolver.conversationWriter.test.ts +210 -0
- package/src/__tests__/RunAIAgentResolver.fireAndForgetCompletion.test.ts +209 -0
- package/src/__tests__/RunAIAgentResolver.handoff.test.ts +649 -0
- package/src/__tests__/RunAIAgentResolver.historyFrom.test.ts +19 -27
- package/src/__tests__/RunAIAgentResolver.runDataGuard.test.ts +10 -2
- package/src/__tests__/RunAIAgentResolver.serverReply.test.ts +358 -0
- package/src/__tests__/RunAIAgentResolver.stoppedPredecessor.test.ts +91 -13
- package/src/__tests__/RunTemplateResolver.test.ts +35 -2
- package/src/__tests__/RunViewResolver.cacheCheckForwarding.test.ts +11 -0
- package/src/__tests__/SchemaEvolutionCustomColumns.test.ts +119 -0
- package/src/__tests__/SchemaRefreshLaunch.test.ts +24 -2
- package/src/__tests__/ScopedFieldsForBuild.test.ts +192 -0
- package/src/__tests__/SessionJanitor.test.ts +195 -4
- package/src/__tests__/SessionManager.test.ts +164 -0
- package/src/__tests__/TaskGraphActionRunner.durablePayload.test.ts +2 -2
- package/src/__tests__/TaskGraphAgentRunner.test.ts +272 -16
- package/src/__tests__/TaskGraphContinuationDeliverer.test.ts +114 -3
- package/src/__tests__/TransactionGroupResolver.fieldSecurity.test.ts +199 -0
- package/src/__tests__/UserViewResolver.updateWhereClause.test.ts +15 -0
- package/src/__tests__/ViewOperationsHandler.test.ts +9 -7
- package/src/__tests__/WidgetSessionService.test.ts +583 -4
- package/src/__tests__/WorkQueueHostService.test.ts +25 -7
- package/src/__tests__/apiRootBoot.test.ts +1 -1
- package/src/__tests__/backgroundSweepConfigUnits.test.ts +153 -0
- package/src/__tests__/buildMagicLinkSessionUser.test.ts +96 -0
- package/src/__tests__/cacheBroadcastProviders.test.ts +403 -0
- package/src/__tests__/cacheInvalidationRecordData.test.ts +45 -0
- package/src/__tests__/contextRequestOrigin.test.ts +105 -0
- package/src/__tests__/conversationBrowsers.test.ts +62 -0
- package/src/__tests__/fieldSecurityFixtures.ts +91 -0
- package/src/__tests__/globalCors.test.ts +3 -3
- package/src/__tests__/localDevAuth.test.ts +196 -0
- package/src/__tests__/magicLinkExtensionCapabilities.test.ts +413 -0
- package/src/__tests__/orphanedConversationDetailReconciler.start.test.ts +82 -0
- package/src/__tests__/orphanedConversationDetailReconciler.test.ts +10 -0
- package/src/__tests__/ownedRealtimeSession.test.ts +14 -0
- package/src/__tests__/pushStatusResolver.filter.test.ts +57 -1
- package/src/__tests__/realtimeRecordingHandler.test.ts +24 -2
- 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 +224 -7
- package/src/__tests__/realtimeSessions/sessionConfigStamps.test.ts +1 -1
- package/src/__tests__/realtimeSessions/verificationWorkflow.test.ts +25 -4
- package/src/__tests__/requestOrigin.test.ts +104 -0
- 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__/securityHardeningPr6034.test.ts +120 -0
- package/src/__tests__/sessionDeadline.test.ts +51 -0
- package/src/__tests__/sessionUserClone.test.ts +5 -1
- package/src/__tests__/sharedCache.test.ts +11 -0
- package/src/__tests__/startupSweepOrder.test.ts +40 -0
- package/src/__tests__/unifiedAuth.test.ts +101 -1
- package/src/__tests__/widgetGuestElevation.test.ts +2 -0
- package/src/agentSessions/BridgeHostInstance.ts +20 -5
- package/src/agentSessions/HandoffOfferExpiry.ts +18 -0
- package/src/agentSessions/ReturningVisitorRecap.ts +1 -0
- package/src/agentSessions/SessionJanitor.ts +95 -45
- package/src/agentSessions/SessionManager.ts +73 -20
- package/src/agentSessions/conversationBrowsers.ts +143 -0
- package/src/agentSessions/sessionDeadline.ts +81 -0
- package/src/auth/APIKeyScopeAuth.ts +5 -4
- package/src/auth/AuthProviderCatalogRouter.ts +3 -0
- package/src/auth/__tests__/loginEmailResolution.test.ts +67 -0
- package/src/auth/index.ts +56 -12
- package/src/auth/initializeProviders.ts +43 -1
- package/src/auth/localDevAuth.ts +528 -0
- package/src/auth/loginEmailResolution.ts +67 -0
- package/src/auth/magicLink/MagicLinkKeys.ts +147 -15
- package/src/auth/magicLink/MagicLinkRouter.ts +33 -6
- package/src/auth/magicLink/MagicLinkService.ts +250 -10
- package/src/auth/magicLink/index.ts +1 -1
- package/src/auth/magicLink/redeemLanding.ts +7 -4
- package/src/auth/magicLink/types.ts +38 -3
- package/src/auth/newUsers.ts +1 -0
- package/src/auth/sessionUserClone.ts +3 -2
- package/src/backgroundSweepConfigUnits.ts +213 -0
- 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 +138 -0
- package/src/context.ts +71 -14
- package/src/coreRoutes.ts +29 -7
- package/src/generated/graphql-schemas/__mj.ts +4145 -1193
- package/src/generic/CacheInvalidationResolver.ts +135 -78
- package/src/generic/OrphanedConversationDetailReconciler.ts +36 -3
- package/src/generic/PubSubManager.ts +54 -1
- package/src/generic/PushStatusResolver.ts +108 -11
- package/src/generic/ResolverBase.ts +635 -234
- package/src/generic/RunViewResolver.ts +176 -64
- package/src/generic/actionOutputFieldSecurity.ts +75 -0
- package/src/generic/fieldSecurityTransport.ts +62 -0
- package/src/index.ts +310 -85
- package/src/integration/ConnectionPause.ts +222 -0
- package/src/integration/CustomColumnPromoter.ts +129 -54
- package/src/integration/EntityMapLifecycle.ts +229 -6
- package/src/integration/InactiveRowWarnings.ts +50 -0
- package/src/integration/ObjectNamesByID.ts +97 -0
- package/src/integration/PostRestartIntrospect.ts +49 -0
- package/src/integration/RSUPostRestartProgress.ts +359 -0
- package/src/integration/RSUProgressBridge.ts +85 -2
- package/src/integration/RunArtifactAuthorization.ts +65 -0
- package/src/integration/SchemaRefreshLaunch.ts +12 -2
- package/src/integration/ScopedFieldsForBuild.ts +113 -0
- package/src/integration/TargetConfigGuard.ts +71 -0
- package/src/logging/variablesLoggingMiddleware.ts +59 -3
- package/src/realtimeSessions/README.md +7 -3
- package/src/realtimeSessions/SessionVerificationPortsBase.ts +1 -0
- package/src/realtimeSessions/ownedRealtimeSession.ts +16 -6
- package/src/realtimeSessions/sessionAccess.ts +211 -25
- 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 +254 -17
- package/src/realtimeWidget/host-identity.ts +1 -1
- package/src/realtimeWidget/visitorIdentity.ts +1 -0
- package/src/realtimeWidget/widgetCore.ts +34 -9
- package/src/realtimeWidget/widgetGuestElevation.ts +3 -1
- package/src/requestOrigin.ts +64 -0
- 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 +50 -18
- package/src/resolvers/AutotagPipelineResolver.ts +2 -1
- package/src/resolvers/ConversationRunEventsResolver.ts +2 -0
- package/src/resolvers/EntityCommunicationsResolver.ts +56 -15
- package/src/resolvers/ExecuteRemoteOperationResolver.ts +41 -9
- package/src/resolvers/FetchEntityVectorsResolver.ts +132 -21
- package/src/resolvers/FileCategoryResolver.ts +1 -0
- package/src/resolvers/FileResolver.ts +14 -4
- package/src/resolvers/GetDataResolver.ts +35 -13
- package/src/resolvers/IntegrationDiscoveryResolver.ts +1570 -209
- package/src/resolvers/MCPResolver.ts +15 -2
- package/src/resolvers/MergeRecordsResolver.ts +23 -2
- package/src/resolvers/PipelineProgressResolver.ts +12 -3
- package/src/resolvers/QueryResolver.ts +20 -6
- package/src/resolvers/QuerySystemUserResolver.ts +207 -99
- package/src/resolvers/RSUResolver.ts +12 -0
- package/src/resolvers/RealtimeBridgeResolver.ts +1 -0
- package/src/resolvers/RealtimeClientSessionResolver.ts +144 -40
- package/src/resolvers/RemoteBrowserActionResolver.ts +252 -37
- package/src/resolvers/RunAIAgentResolver.ts +518 -163
- package/src/resolvers/RunAIPromptResolver.ts +18 -18
- package/src/resolvers/RunTemplateResolver.ts +9 -5
- package/src/resolvers/RunTestResolver.ts +3 -1
- package/src/resolvers/SyncDataResolver.ts +4 -0
- package/src/resolvers/TestQuerySQLResolver.ts +1 -0
- package/src/resolvers/TransactionGroupResolver.ts +66 -15
- package/src/resolvers/UserViewResolver.ts +2 -1
- package/src/resolvers/__tests__/GetDataResolver.tokens.test.ts +52 -0
- package/src/resolvers/__tests__/MergeRecordsResolver.test.ts +43 -0
- package/src/resolvers/meetingRecordingRegistration.ts +2 -0
- package/src/rest/EntityCRUDHandler.ts +22 -5
- package/src/rest/MediaAccessKeys.ts +6 -2
- package/src/rest/OAuthCallbackHandler.ts +13 -5
- package/src/rest/RESTEndpointHandler.ts +8 -5
- package/src/rest/RealtimeRecordingHandler.ts +9 -10
- package/src/rest/ViewOperationsHandler.ts +26 -7
- package/src/rest/setupRESTEndpoints.ts +11 -2
- package/src/serverRoleConfigUnits.ts +48 -0
- package/src/services/DurableEntityActionTaskSubmitter.ts +10 -2
- package/src/services/TaskGraphActionRunner.ts +2 -23
- package/src/services/TaskGraphAgentRunner.ts +43 -0
- package/src/services/TaskGraphContinuationDeliverer.ts +53 -20
- package/src/services/WorkQueueHostService.ts +26 -4
- package/src/services/workQueueConfig.ts +5 -5
- package/src/sharedCache.ts +1 -1
- package/src/types.ts +41 -1
- package/src/services/TaskOrchestration-Integration.md +0 -188
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { createHash, createHmac } from 'node:crypto';
|
|
2
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
3
|
+
import { UserInfo } from '@memberjunction/core';
|
|
4
|
+
import {
|
|
5
|
+
BaseCacheInvalidationBroadcastProvider,
|
|
6
|
+
CacheBroadcastNegotiationResult,
|
|
7
|
+
CacheInvalidationBroadcastTopology,
|
|
8
|
+
} from '../BaseCacheInvalidationBroadcastProvider.js';
|
|
9
|
+
import type {
|
|
10
|
+
CacheInvalidationNotification,
|
|
11
|
+
CacheInvalidationPayload,
|
|
12
|
+
} from '../../generic/CacheInvalidationResolver.js';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Envelope published to an AWS IoT Core MQTT role topic.
|
|
16
|
+
*/
|
|
17
|
+
export interface AWSIoTCoreTopicMessage {
|
|
18
|
+
Topic: string;
|
|
19
|
+
QoS: 0 | 1;
|
|
20
|
+
Event: CacheInvalidationNotification;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Transport callback used by {@link AWSIoTCoreBroadcastProvider} to publish a shaped
|
|
25
|
+
* invalidation notification to an AWS IoT Core MQTT topic.
|
|
26
|
+
*/
|
|
27
|
+
export type AWSIoTCoreTopicPublisher = (message: AWSIoTCoreTopicMessage) => Promise<void>;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Topology 3 Cloud Multiplexer Provider for **AWS IoT Core MQTT over WebSockets** (`'AWSIoTCore'`).
|
|
31
|
+
*
|
|
32
|
+
* Offloads per-client WebSocket connection management and message fan-out from MJServer
|
|
33
|
+
* to AWS IoT Core's managed MQTT message broker:
|
|
34
|
+
* - Each authenticated browser client calls `NegotiateCacheBroadcastConnection` to obtain
|
|
35
|
+
* a SigV4-presigned `wss://<endpoint>/mqtt` URL and its authorized MQTT topic list
|
|
36
|
+
* (`<topicPrefix>/roles/<RoleID>`).
|
|
37
|
+
* - When an entity mutation occurs, MJServer shapes the invalidation payload once per
|
|
38
|
+
* authorized role on the entity and publishes to `<topicPrefix>/roles/<RoleID>`.
|
|
39
|
+
*/
|
|
40
|
+
@RegisterClass(BaseCacheInvalidationBroadcastProvider, 'AWSIoTCore')
|
|
41
|
+
export class AWSIoTCoreBroadcastProvider extends BaseCacheInvalidationBroadcastProvider {
|
|
42
|
+
private _topicPublisher: AWSIoTCoreTopicPublisher | null = null;
|
|
43
|
+
|
|
44
|
+
public override get Topology(): CacheInvalidationBroadcastTopology {
|
|
45
|
+
return 'AWSIoTCore';
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Installs a custom MQTT topic publisher (e.g., AWS SDK `IoTDataPlaneClient` adapter or test spy).
|
|
50
|
+
*/
|
|
51
|
+
public SetTopicPublisher(publisher: AWSIoTCoreTopicPublisher | null): void {
|
|
52
|
+
this._topicPublisher = publisher;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Computes the MQTT topic filters (`<topicPrefix>/roles/<roleId>`) for a user's roles.
|
|
57
|
+
*/
|
|
58
|
+
public GetAuthorizedTopicsForUser(user: UserInfo): string[] {
|
|
59
|
+
const prefix = (this._config.awsIoTCore?.topicPrefix || 'mj/cache').replace(/\/+$/, '');
|
|
60
|
+
const roles = user.UserRoles ?? [];
|
|
61
|
+
const topics: string[] = [];
|
|
62
|
+
for (const r of roles) {
|
|
63
|
+
const roleId = (r.RoleID ?? '').trim().toLowerCase();
|
|
64
|
+
if (roleId.length > 0) {
|
|
65
|
+
topics.push(`${prefix}/roles/${roleId}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
topics.sort();
|
|
69
|
+
return topics;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
protected override async OnInvalidationRecorded(payload: CacheInvalidationPayload): Promise<void> {
|
|
73
|
+
const prefix = (this._config.awsIoTCore?.topicPrefix || 'mj/cache').replace(/\/+$/, '');
|
|
74
|
+
const entity = this.ResolveEntityForPayload(payload);
|
|
75
|
+
if (!entity) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
for (const perm of entity.Permissions) {
|
|
80
|
+
if (!perm.CanRead) continue;
|
|
81
|
+
const roleId = (perm.RoleID ?? '').trim().toLowerCase();
|
|
82
|
+
if (!roleId) continue;
|
|
83
|
+
|
|
84
|
+
const syntheticRoleHolder = { UserRoles: [{ RoleID: roleId }] };
|
|
85
|
+
const shaped = this.ShapeEventForSubscriber(payload, syntheticRoleHolder, entity);
|
|
86
|
+
const message: AWSIoTCoreTopicMessage = {
|
|
87
|
+
Topic: `${prefix}/roles/${roleId}`,
|
|
88
|
+
QoS: 1,
|
|
89
|
+
Event: shaped,
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
if (this._topicPublisher) {
|
|
93
|
+
await this._topicPublisher(message);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
public override async NegotiateClientConnection(
|
|
99
|
+
user: UserInfo,
|
|
100
|
+
defaultGraphQLWsUrl = '/graphql'
|
|
101
|
+
): Promise<CacheBroadcastNegotiationResult> {
|
|
102
|
+
const endpoint = (this._config.awsIoTCore?.endpoint ?? '').replace(/^https?:\/\//i, '').replace(/\/+$/, '');
|
|
103
|
+
const region = this._config.awsIoTCore?.region || 'us-east-1';
|
|
104
|
+
const ttlSeconds = this._config.awsIoTCore?.tokenTtlSeconds ?? 3600;
|
|
105
|
+
const expiresAtMs = Date.now() + ttlSeconds * 1000;
|
|
106
|
+
const topics = this.GetAuthorizedTopicsForUser(user);
|
|
107
|
+
|
|
108
|
+
if (!endpoint) {
|
|
109
|
+
return {
|
|
110
|
+
Provider: this.Topology,
|
|
111
|
+
Url: defaultGraphQLWsUrl,
|
|
112
|
+
Groups: topics,
|
|
113
|
+
ExpiresAt: new Date(expiresAtMs).toISOString(),
|
|
114
|
+
ServerProcessID: this.ServerProcessID,
|
|
115
|
+
CurrentSequence: this.CurrentSequence,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const accessKeyId = this._config.awsIoTCore?.accessKeyId;
|
|
120
|
+
const secretAccessKey = this._config.awsIoTCore?.secretAccessKey;
|
|
121
|
+
const presignedUrl =
|
|
122
|
+
accessKeyId && secretAccessKey
|
|
123
|
+
? this.buildSigV4PresignedMqttUrl(endpoint, region, accessKeyId, secretAccessKey, ttlSeconds)
|
|
124
|
+
: `wss://${endpoint}/mqtt`;
|
|
125
|
+
|
|
126
|
+
return {
|
|
127
|
+
Provider: this.Topology,
|
|
128
|
+
Url: presignedUrl,
|
|
129
|
+
Groups: topics,
|
|
130
|
+
ExpiresAt: new Date(expiresAtMs).toISOString(),
|
|
131
|
+
ServerProcessID: this.ServerProcessID,
|
|
132
|
+
CurrentSequence: this.CurrentSequence,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
private buildSigV4PresignedMqttUrl(
|
|
137
|
+
host: string,
|
|
138
|
+
region: string,
|
|
139
|
+
accessKeyId: string,
|
|
140
|
+
secretAccessKey: string,
|
|
141
|
+
expiresSeconds: number
|
|
142
|
+
): string {
|
|
143
|
+
const now = new Date();
|
|
144
|
+
const amzDate = now.toISOString().replace(/[:-]|\.\d{3}/g, '');
|
|
145
|
+
const dateStamp = amzDate.slice(0, 8);
|
|
146
|
+
const service = 'iotdevicegateway';
|
|
147
|
+
const credentialScope = `${dateStamp}/${region}/${service}/aws4_request`;
|
|
148
|
+
const queryParams = [
|
|
149
|
+
`X-Amz-Algorithm=AWS4-HMAC-SHA256`,
|
|
150
|
+
`X-Amz-Credential=${encodeURIComponent(`${accessKeyId}/${credentialScope}`)}`,
|
|
151
|
+
`X-Amz-Date=${amzDate}`,
|
|
152
|
+
`X-Amz-Expires=${expiresSeconds}`,
|
|
153
|
+
`X-Amz-SignedHeaders=host`,
|
|
154
|
+
].join('&');
|
|
155
|
+
|
|
156
|
+
const canonicalRequest = [
|
|
157
|
+
'GET',
|
|
158
|
+
'/mqtt',
|
|
159
|
+
queryParams,
|
|
160
|
+
`host:${host}\n`,
|
|
161
|
+
'host',
|
|
162
|
+
createHash('sha256').update('').digest('hex'),
|
|
163
|
+
].join('\n');
|
|
164
|
+
|
|
165
|
+
const stringToSign = [
|
|
166
|
+
'AWS4-HMAC-SHA256',
|
|
167
|
+
amzDate,
|
|
168
|
+
credentialScope,
|
|
169
|
+
createHash('sha256').update(canonicalRequest).digest('hex'),
|
|
170
|
+
].join('\n');
|
|
171
|
+
|
|
172
|
+
const kDate = createHmac('sha256', `AWS4${secretAccessKey}`).update(dateStamp).digest();
|
|
173
|
+
const kRegion = createHmac('sha256', kDate).update(region).digest();
|
|
174
|
+
const kService = createHmac('sha256', kRegion).update(service).digest();
|
|
175
|
+
const kSigning = createHmac('sha256', kService).update('aws4_request').digest();
|
|
176
|
+
const signature = createHmac('sha256', kSigning).update(stringToSign).digest('hex');
|
|
177
|
+
|
|
178
|
+
return `wss://${host}/mqtt?${queryParams}&X-Amz-Signature=${signature}`;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { createHmac } from 'node:crypto';
|
|
2
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
3
|
+
import { UserInfo } from '@memberjunction/core';
|
|
4
|
+
import {
|
|
5
|
+
BaseCacheInvalidationBroadcastProvider,
|
|
6
|
+
CacheBroadcastNegotiationResult,
|
|
7
|
+
CacheInvalidationBroadcastTopology,
|
|
8
|
+
} from '../BaseCacheInvalidationBroadcastProvider.js';
|
|
9
|
+
import type {
|
|
10
|
+
CacheInvalidationNotification,
|
|
11
|
+
CacheInvalidationPayload,
|
|
12
|
+
} from '../../generic/CacheInvalidationResolver.js';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Envelope published to an Azure Web PubSub role group.
|
|
16
|
+
*/
|
|
17
|
+
export interface AzureWebPubSubGroupMessage {
|
|
18
|
+
HubName: string;
|
|
19
|
+
GroupName: string;
|
|
20
|
+
Event: CacheInvalidationNotification;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Transport callback used by {@link AzureWebPubSubBroadcastProvider} to deliver a shaped
|
|
25
|
+
* invalidation notification to an Azure Web PubSub group.
|
|
26
|
+
*/
|
|
27
|
+
export type AzureWebPubSubGroupPublisher = (message: AzureWebPubSubGroupMessage) => Promise<void>;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Topology 3 Cloud Multiplexer Provider for **Azure Web PubSub** (`'AzureWebPubSub'`).
|
|
31
|
+
*
|
|
32
|
+
* Offloads per-client WebSocket connection management and message fan-out from MJServer
|
|
33
|
+
* to Azure Web PubSub:
|
|
34
|
+
* - Each authenticated browser client calls `NegotiateCacheBroadcastConnection` to receive
|
|
35
|
+
* a short-lived, HMAC-signed JWT access token scoped to its authorized role groups (`mj-role-<RoleID>`).
|
|
36
|
+
* - When an entity mutation occurs, MJServer shapes the invalidation payload once per
|
|
37
|
+
* authorized role group on the entity and publishes a single group broadcast to Azure Web PubSub,
|
|
38
|
+
* which fans the message out to thousands of connected browsers in C++ edge infrastructure.
|
|
39
|
+
*/
|
|
40
|
+
@RegisterClass(BaseCacheInvalidationBroadcastProvider, 'AzureWebPubSub')
|
|
41
|
+
export class AzureWebPubSubBroadcastProvider extends BaseCacheInvalidationBroadcastProvider {
|
|
42
|
+
private _groupPublisher: AzureWebPubSubGroupPublisher | null = null;
|
|
43
|
+
|
|
44
|
+
public override get Topology(): CacheInvalidationBroadcastTopology {
|
|
45
|
+
return 'AzureWebPubSub';
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Installs a custom group publisher (e.g., Azure WebPubSubServiceClient adapter or test spy).
|
|
50
|
+
* When unset and an HTTP endpoint + accessKey are configured, defaults to the Azure Web PubSub
|
|
51
|
+
* REST Data Plane API (`POST /api/hubs/{hub}/groups/{group}/:send`).
|
|
52
|
+
*/
|
|
53
|
+
public SetGroupPublisher(publisher: AzureWebPubSubGroupPublisher | null): void {
|
|
54
|
+
this._groupPublisher = publisher;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Computes the Azure Web PubSub group names (`mj-role-<roleId>`) for a user's roles.
|
|
59
|
+
*/
|
|
60
|
+
public GetAuthorizedGroupsForUser(user: UserInfo): string[] {
|
|
61
|
+
const roles = user.UserRoles ?? [];
|
|
62
|
+
const groups: string[] = [];
|
|
63
|
+
for (const r of roles) {
|
|
64
|
+
const roleId = (r.RoleID ?? '').trim().toLowerCase();
|
|
65
|
+
if (roleId.length > 0) {
|
|
66
|
+
groups.push(`mj-role-${roleId}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
groups.sort();
|
|
70
|
+
return groups;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
protected override async OnInvalidationRecorded(payload: CacheInvalidationPayload): Promise<void> {
|
|
74
|
+
const hubName = this._config.azureWebPubSub?.hubName || 'mj_cache_hub';
|
|
75
|
+
const entity = this.ResolveEntityForPayload(payload);
|
|
76
|
+
if (!entity) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Group entity permissions by RoleID and shape once per authorized role
|
|
81
|
+
for (const perm of entity.Permissions) {
|
|
82
|
+
if (!perm.CanRead) continue;
|
|
83
|
+
const roleId = (perm.RoleID ?? '').trim().toLowerCase();
|
|
84
|
+
if (!roleId) continue;
|
|
85
|
+
|
|
86
|
+
const syntheticRoleHolder = { UserRoles: [{ RoleID: roleId }] };
|
|
87
|
+
const shaped = this.ShapeEventForSubscriber(payload, syntheticRoleHolder, entity);
|
|
88
|
+
const message: AzureWebPubSubGroupMessage = {
|
|
89
|
+
HubName: hubName,
|
|
90
|
+
GroupName: `mj-role-${roleId}`,
|
|
91
|
+
Event: shaped,
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
if (this._groupPublisher) {
|
|
95
|
+
await this._groupPublisher(message);
|
|
96
|
+
} else if (this._config.azureWebPubSub?.endpoint && this._config.azureWebPubSub?.accessKey) {
|
|
97
|
+
await this.publishViaRestApi(message);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
public override async NegotiateClientConnection(
|
|
103
|
+
user: UserInfo,
|
|
104
|
+
defaultGraphQLWsUrl = '/graphql'
|
|
105
|
+
): Promise<CacheBroadcastNegotiationResult> {
|
|
106
|
+
const endpoint = (this._config.azureWebPubSub?.endpoint ?? '').replace(/\/+$/, '');
|
|
107
|
+
const hubName = this._config.azureWebPubSub?.hubName || 'mj_cache_hub';
|
|
108
|
+
const accessKey = this._config.azureWebPubSub?.accessKey || '';
|
|
109
|
+
const ttlMinutes = this._config.azureWebPubSub?.tokenTtlMinutes ?? 60;
|
|
110
|
+
const expiresAtMs = Date.now() + ttlMinutes * 60 * 1000;
|
|
111
|
+
const groups = this.GetAuthorizedGroupsForUser(user);
|
|
112
|
+
|
|
113
|
+
if (!endpoint) {
|
|
114
|
+
return {
|
|
115
|
+
Provider: this.Topology,
|
|
116
|
+
Url: defaultGraphQLWsUrl,
|
|
117
|
+
Groups: groups,
|
|
118
|
+
ExpiresAt: new Date(expiresAtMs).toISOString(),
|
|
119
|
+
ServerProcessID: this.ServerProcessID,
|
|
120
|
+
CurrentSequence: this.CurrentSequence,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const wsEndpoint = endpoint.replace(/^http:/i, 'ws:').replace(/^https:/i, 'wss:');
|
|
125
|
+
const audience = `${endpoint}/client/hubs/${hubName}`;
|
|
126
|
+
const token = accessKey
|
|
127
|
+
? this.mintJwtToken(audience, user.ID, groups, Math.floor(expiresAtMs / 1000), accessKey)
|
|
128
|
+
: undefined;
|
|
129
|
+
const url = token
|
|
130
|
+
? `${wsEndpoint}/client/hubs/${hubName}?access_token=${encodeURIComponent(token)}`
|
|
131
|
+
: `${wsEndpoint}/client/hubs/${hubName}`;
|
|
132
|
+
|
|
133
|
+
return {
|
|
134
|
+
Provider: this.Topology,
|
|
135
|
+
Url: url,
|
|
136
|
+
Token: token,
|
|
137
|
+
Groups: groups,
|
|
138
|
+
ExpiresAt: new Date(expiresAtMs).toISOString(),
|
|
139
|
+
ServerProcessID: this.ServerProcessID,
|
|
140
|
+
CurrentSequence: this.CurrentSequence,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
private mintJwtToken(
|
|
145
|
+
audience: string,
|
|
146
|
+
subject: string,
|
|
147
|
+
groups: string[],
|
|
148
|
+
expSeconds: number,
|
|
149
|
+
secret: string
|
|
150
|
+
): string {
|
|
151
|
+
const header = Buffer.from(JSON.stringify({ alg: 'HS256', typ: 'JWT' })).toString('base64url');
|
|
152
|
+
const claims = Buffer.from(
|
|
153
|
+
JSON.stringify({
|
|
154
|
+
aud: audience,
|
|
155
|
+
sub: subject,
|
|
156
|
+
iat: Math.floor(Date.now() / 1000),
|
|
157
|
+
exp: expSeconds,
|
|
158
|
+
role: groups.map((g) => `webpubsub.joinLeaveGroup.${g}`),
|
|
159
|
+
})
|
|
160
|
+
).toString('base64url');
|
|
161
|
+
const signingInput = `${header}.${claims}`;
|
|
162
|
+
const signature = createHmac('sha256', secret).update(signingInput).digest('base64url');
|
|
163
|
+
return `${signingInput}.${signature}`;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
private async publishViaRestApi(message: AzureWebPubSubGroupMessage): Promise<void> {
|
|
167
|
+
const endpoint = (this._config.azureWebPubSub?.endpoint ?? '').replace(/\/+$/, '');
|
|
168
|
+
const accessKey = this._config.azureWebPubSub?.accessKey ?? '';
|
|
169
|
+
if (!endpoint || !accessKey) return;
|
|
170
|
+
|
|
171
|
+
const targetUrl = `${endpoint}/api/hubs/${encodeURIComponent(message.HubName)}/groups/${encodeURIComponent(message.GroupName)}/:send?api-version=2024-01-01`;
|
|
172
|
+
const token = this.mintJwtToken(targetUrl, 'mj-server', [], Math.floor(Date.now() / 1000) + 300, accessKey);
|
|
173
|
+
await fetch(targetUrl, {
|
|
174
|
+
method: 'POST',
|
|
175
|
+
headers: {
|
|
176
|
+
Authorization: `Bearer ${token}`,
|
|
177
|
+
'Content-Type': 'application/json',
|
|
178
|
+
},
|
|
179
|
+
body: JSON.stringify(message.Event),
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { createHmac } from 'node:crypto';
|
|
2
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
3
|
+
import { UserInfo } from '@memberjunction/core';
|
|
4
|
+
import {
|
|
5
|
+
BaseCacheInvalidationBroadcastProvider,
|
|
6
|
+
CacheBroadcastNegotiationResult,
|
|
7
|
+
CacheInvalidationBroadcastTopology,
|
|
8
|
+
} from '../BaseCacheInvalidationBroadcastProvider.js';
|
|
9
|
+
import type {
|
|
10
|
+
CacheInvalidationNotification,
|
|
11
|
+
CacheInvalidationPayload,
|
|
12
|
+
} from '../../generic/CacheInvalidationResolver.js';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Envelope published to a Google Cloud Pub/Sub role topic.
|
|
16
|
+
*/
|
|
17
|
+
export interface GCPPubSubTopicMessage {
|
|
18
|
+
ProjectId: string;
|
|
19
|
+
TopicName: string;
|
|
20
|
+
Attributes: {
|
|
21
|
+
roleId: string;
|
|
22
|
+
entityName: string;
|
|
23
|
+
action: string;
|
|
24
|
+
sequence: string;
|
|
25
|
+
};
|
|
26
|
+
Event: CacheInvalidationNotification;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Transport callback used by {@link GCPPubSubBroadcastProvider} to publish a shaped
|
|
31
|
+
* invalidation notification to Google Cloud Pub/Sub.
|
|
32
|
+
*/
|
|
33
|
+
export type GCPPubSubTopicPublisher = (message: GCPPubSubTopicMessage) => Promise<void>;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Topology 3 Cloud Multiplexer Provider for **Google Cloud Pub/Sub + Cloud Run WebSockets** (`'GCPPubSub'`).
|
|
37
|
+
*
|
|
38
|
+
* Offloads per-client WebSocket connection management and message fan-out from MJServer
|
|
39
|
+
* to a Google Cloud Pub/Sub + Cloud Run WebSocket fan-out gateway:
|
|
40
|
+
* - Each authenticated browser client calls `NegotiateCacheBroadcastConnection` to obtain
|
|
41
|
+
* a signed gateway token and its authorized Pub/Sub role subscription attributes
|
|
42
|
+
* (`projects/<projectId>/topics/<topicPrefix>-role-<RoleID>`).
|
|
43
|
+
* - When an entity mutation occurs, MJServer shapes the invalidation payload once per
|
|
44
|
+
* authorized role on the entity and publishes a message with Pub/Sub filtering attributes.
|
|
45
|
+
*/
|
|
46
|
+
@RegisterClass(BaseCacheInvalidationBroadcastProvider, 'GCPPubSub')
|
|
47
|
+
export class GCPPubSubBroadcastProvider extends BaseCacheInvalidationBroadcastProvider {
|
|
48
|
+
private _topicPublisher: GCPPubSubTopicPublisher | null = null;
|
|
49
|
+
|
|
50
|
+
public override get Topology(): CacheInvalidationBroadcastTopology {
|
|
51
|
+
return 'GCPPubSub';
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Installs a custom Google Cloud Pub/Sub topic publisher (e.g., `@google-cloud/pubsub` adapter or test spy).
|
|
56
|
+
*/
|
|
57
|
+
public SetTopicPublisher(publisher: GCPPubSubTopicPublisher | null): void {
|
|
58
|
+
this._topicPublisher = publisher;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Computes the fully-qualified GCP Pub/Sub topic names for a user's roles.
|
|
63
|
+
*/
|
|
64
|
+
public GetAuthorizedTopicsForUser(user: UserInfo): string[] {
|
|
65
|
+
const projectId = this._config.gcpPubSub?.projectId || 'mj-default-project';
|
|
66
|
+
const prefix = this._config.gcpPubSub?.topicPrefix || 'mj-cache';
|
|
67
|
+
const roles = user.UserRoles ?? [];
|
|
68
|
+
const topics: string[] = [];
|
|
69
|
+
for (const r of roles) {
|
|
70
|
+
const roleId = (r.RoleID ?? '').trim().toLowerCase();
|
|
71
|
+
if (roleId.length > 0) {
|
|
72
|
+
topics.push(`projects/${projectId}/topics/${prefix}-role-${roleId}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
topics.sort();
|
|
76
|
+
return topics;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
protected override async OnInvalidationRecorded(payload: CacheInvalidationPayload): Promise<void> {
|
|
80
|
+
const projectId = this._config.gcpPubSub?.projectId || 'mj-default-project';
|
|
81
|
+
const prefix = this._config.gcpPubSub?.topicPrefix || 'mj-cache';
|
|
82
|
+
const entity = this.ResolveEntityForPayload(payload);
|
|
83
|
+
if (!entity) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
for (const perm of entity.Permissions) {
|
|
88
|
+
if (!perm.CanRead) continue;
|
|
89
|
+
const roleId = (perm.RoleID ?? '').trim().toLowerCase();
|
|
90
|
+
if (!roleId) continue;
|
|
91
|
+
|
|
92
|
+
const syntheticRoleHolder = { UserRoles: [{ RoleID: roleId }] };
|
|
93
|
+
const shaped = this.ShapeEventForSubscriber(payload, syntheticRoleHolder, entity);
|
|
94
|
+
const message: GCPPubSubTopicMessage = {
|
|
95
|
+
ProjectId: projectId,
|
|
96
|
+
TopicName: `projects/${projectId}/topics/${prefix}-role-${roleId}`,
|
|
97
|
+
Attributes: {
|
|
98
|
+
roleId,
|
|
99
|
+
entityName: payload.entityName,
|
|
100
|
+
action: payload.action,
|
|
101
|
+
sequence: String(payload.sequence ?? 0),
|
|
102
|
+
},
|
|
103
|
+
Event: shaped,
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
if (this._topicPublisher) {
|
|
107
|
+
await this._topicPublisher(message);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
public override async NegotiateClientConnection(
|
|
113
|
+
user: UserInfo,
|
|
114
|
+
defaultGraphQLWsUrl = '/graphql'
|
|
115
|
+
): Promise<CacheBroadcastNegotiationResult> {
|
|
116
|
+
const gatewayUrl = (this._config.gcpPubSub?.gatewayUrl ?? '').replace(/\/+$/, '');
|
|
117
|
+
const signingSecret = this._config.gcpPubSub?.signingSecret || '';
|
|
118
|
+
const ttlSeconds = this._config.gcpPubSub?.tokenTtlSeconds ?? 3600;
|
|
119
|
+
const expiresAtMs = Date.now() + ttlSeconds * 1000;
|
|
120
|
+
const topics = this.GetAuthorizedTopicsForUser(user);
|
|
121
|
+
|
|
122
|
+
if (!gatewayUrl) {
|
|
123
|
+
return {
|
|
124
|
+
Provider: this.Topology,
|
|
125
|
+
Url: defaultGraphQLWsUrl,
|
|
126
|
+
Groups: topics,
|
|
127
|
+
ExpiresAt: new Date(expiresAtMs).toISOString(),
|
|
128
|
+
ServerProcessID: this.ServerProcessID,
|
|
129
|
+
CurrentSequence: this.CurrentSequence,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const wsGatewayUrl = gatewayUrl.replace(/^http:/i, 'ws:').replace(/^https:/i, 'wss:');
|
|
134
|
+
const token = signingSecret
|
|
135
|
+
? this.mintGatewayToken(user.ID, topics, Math.floor(expiresAtMs / 1000), signingSecret)
|
|
136
|
+
: undefined;
|
|
137
|
+
const url = token ? `${wsGatewayUrl}?token=${encodeURIComponent(token)}` : wsGatewayUrl;
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
Provider: this.Topology,
|
|
141
|
+
Url: url,
|
|
142
|
+
Token: token,
|
|
143
|
+
Groups: topics,
|
|
144
|
+
ExpiresAt: new Date(expiresAtMs).toISOString(),
|
|
145
|
+
ServerProcessID: this.ServerProcessID,
|
|
146
|
+
CurrentSequence: this.CurrentSequence,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
private mintGatewayToken(
|
|
151
|
+
subject: string,
|
|
152
|
+
topics: string[],
|
|
153
|
+
expSeconds: number,
|
|
154
|
+
secret: string
|
|
155
|
+
): string {
|
|
156
|
+
const header = Buffer.from(JSON.stringify({ alg: 'HS256', typ: 'JWT' })).toString('base64url');
|
|
157
|
+
const claims = Buffer.from(
|
|
158
|
+
JSON.stringify({
|
|
159
|
+
sub: subject,
|
|
160
|
+
iat: Math.floor(Date.now() / 1000),
|
|
161
|
+
exp: expSeconds,
|
|
162
|
+
topics,
|
|
163
|
+
})
|
|
164
|
+
).toString('base64url');
|
|
165
|
+
const signingInput = `${header}.${claims}`;
|
|
166
|
+
const signature = createHmac('sha256', secret).update(signingInput).digest('base64url');
|
|
167
|
+
return `${signingInput}.${signature}`;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
2
|
+
import { UserInfo } from '@memberjunction/core';
|
|
3
|
+
import {
|
|
4
|
+
BaseCacheInvalidationBroadcastProvider,
|
|
5
|
+
CacheBroadcastNegotiationResult,
|
|
6
|
+
CacheInvalidationBroadcastManager,
|
|
7
|
+
CacheInvalidationBroadcastTopology,
|
|
8
|
+
} from '../BaseCacheInvalidationBroadcastProvider.js';
|
|
9
|
+
import type { CacheInvalidationPayload } from '../../generic/CacheInvalidationResolver.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Default MemberJunction cache invalidation broadcast provider (`'SequencedRoleBucket'`).
|
|
13
|
+
*
|
|
14
|
+
* Combines:
|
|
15
|
+
* - **Topology 1 (Monotonic Sequence Ring Buffer + HTTP Header Piggybacking)**:
|
|
16
|
+
* Every mutation assigns a monotonic `Sequence` integer, stores the event in a bounded ring buffer,
|
|
17
|
+
* and piggybacks `X-MJ-Cache-Seq` and `X-MJ-Server-ID` onto GraphQL HTTP responses so clients can
|
|
18
|
+
* detect and recover missed invalidations via `GetCacheInvalidationsSince` in a single delta query.
|
|
19
|
+
* - **Topology 2 (Role-Fingerprint $O(\text{Roles})$ Evaluation & Shaping Memoizer)**:
|
|
20
|
+
* Memoizes entity-level read permission (`CanRead`) and row-level security key-withholding
|
|
21
|
+
* (`ReadIsRowFiltered`) once per unique role fingerprint (`RoleID` set) per event instead of
|
|
22
|
+
* re-evaluating permissions $N$ times across all connected WebSocket clients.
|
|
23
|
+
*
|
|
24
|
+
* Zero external cloud infrastructure is required.
|
|
25
|
+
*/
|
|
26
|
+
@RegisterClass(BaseCacheInvalidationBroadcastProvider, 'SequencedRoleBucket')
|
|
27
|
+
export class SequencedRoleBucketBroadcastProvider extends BaseCacheInvalidationBroadcastProvider {
|
|
28
|
+
public override get Topology(): CacheInvalidationBroadcastTopology {
|
|
29
|
+
return 'SequencedRoleBucket';
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
protected override async OnInvalidationRecorded(_payload: CacheInvalidationPayload): Promise<void> {
|
|
33
|
+
// In-process GraphQL WebSocket subscriptions read directly from PubSub + role-bucket memoizer;
|
|
34
|
+
// no external cloud multiplexer dispatch is needed in SequencedRoleBucket mode.
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
public override async NegotiateClientConnection(
|
|
38
|
+
user: UserInfo,
|
|
39
|
+
defaultGraphQLWsUrl = '/graphql'
|
|
40
|
+
): Promise<CacheBroadcastNegotiationResult> {
|
|
41
|
+
const fingerprint = this.GetRoleFingerprint(user);
|
|
42
|
+
const expiresAt = new Date(Date.now() + 60 * 60 * 1000).toISOString();
|
|
43
|
+
return {
|
|
44
|
+
Provider: this.Topology,
|
|
45
|
+
Url: defaultGraphQLWsUrl,
|
|
46
|
+
Groups: [fingerprint],
|
|
47
|
+
ExpiresAt: expiresAt,
|
|
48
|
+
ServerProcessID: this.ServerProcessID,
|
|
49
|
+
CurrentSequence: this.CurrentSequence,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Ensure the default provider factory is always registered even if ClassFactory lookup happens early.
|
|
55
|
+
CacheInvalidationBroadcastManager.Instance.RegisterDefaultProviderFactory(
|
|
56
|
+
() => new SequencedRoleBucketBroadcastProvider()
|
|
57
|
+
);
|
package/src/cache.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { LRUCache } from 'lru-cache';
|
|
2
|
+
import type jwt from 'jsonwebtoken';
|
|
2
3
|
|
|
3
4
|
const oneHourMs = 60 * 60 * 1000;
|
|
4
5
|
|
|
5
|
-
export const AuthCache = new LRUCache({
|
|
6
|
+
export const AuthCache = new LRUCache<string, jwt.JwtPayload | boolean>({
|
|
6
7
|
max: 50000,
|
|
7
8
|
ttl: oneHourMs,
|
|
8
9
|
ttlAutopurge: false,
|