@memberjunction/server 6.2.0-edge.5 → 6.2.0-edge.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -1
- package/dist/.tsbuildinfo +1 -1
- package/dist/agentSessions/SessionJanitor.d.ts +3 -3
- package/dist/agentSessions/SessionJanitor.js +3 -3
- package/dist/agentSessions/SessionManager.d.ts +15 -5
- package/dist/agentSessions/SessionManager.d.ts.map +1 -1
- package/dist/agentSessions/SessionManager.js +34 -12
- package/dist/agentSessions/SessionManager.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/magicLink/MagicLinkKeys.d.ts +2 -2
- package/dist/auth/magicLink/MagicLinkKeys.d.ts.map +1 -1
- package/dist/auth/magicLink/MagicLinkKeys.js +1 -1
- package/dist/auth/magicLink/MagicLinkKeys.js.map +1 -1
- package/dist/auth/magicLink/types.d.ts +12 -0
- package/dist/auth/magicLink/types.d.ts.map +1 -1
- package/dist/auth/sessionUserClone.d.ts +1 -1
- package/dist/auth/sessionUserClone.d.ts.map +1 -1
- package/dist/auth/sessionUserClone.js +3 -2
- package/dist/auth/sessionUserClone.js.map +1 -1
- package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.d.ts +292 -0
- package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.d.ts.map +1 -0
- package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.js +442 -0
- package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.js.map +1 -0
- package/dist/broadcast/index.d.ts +6 -0
- package/dist/broadcast/index.d.ts.map +1 -0
- package/dist/broadcast/index.js +6 -0
- package/dist/broadcast/index.js.map +1 -0
- package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.d.ts +43 -0
- package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.d.ts.map +1 -0
- package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.js +144 -0
- package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.js.map +1 -0
- package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.d.ts +46 -0
- package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.d.ts.map +1 -0
- package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.js +149 -0
- package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.js.map +1 -0
- package/dist/broadcast/providers/GCPPubSubBroadcastProvider.d.ts +49 -0
- package/dist/broadcast/providers/GCPPubSubBroadcastProvider.d.ts.map +1 -0
- package/dist/broadcast/providers/GCPPubSubBroadcastProvider.js +131 -0
- package/dist/broadcast/providers/GCPPubSubBroadcastProvider.js.map +1 -0
- package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.d.ts +24 -0
- package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.d.ts.map +1 -0
- package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.js +51 -0
- package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.js.map +1 -0
- package/dist/cache.d.ts +3 -2
- package/dist/cache.d.ts.map +1 -1
- package/dist/cache.js.map +1 -1
- package/dist/config.d.ts +496 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +61 -0
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +3 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +29 -8
- package/dist/context.js.map +1 -1
- package/dist/coreRoutes.d.ts.map +1 -1
- package/dist/coreRoutes.js +14 -0
- package/dist/coreRoutes.js.map +1 -1
- package/dist/generated/graphql-schemas/__mj.d.ts +635 -14
- package/dist/generated/graphql-schemas/__mj.d.ts.map +1 -1
- package/dist/generated/graphql-schemas/__mj.js +3366 -418
- 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.map +1 -1
- package/dist/generic/OrphanedConversationDetailReconciler.js +2 -0
- package/dist/generic/OrphanedConversationDetailReconciler.js.map +1 -1
- package/dist/generic/PubSubManager.d.ts +10 -0
- package/dist/generic/PubSubManager.d.ts.map +1 -1
- package/dist/generic/PubSubManager.js +44 -1
- package/dist/generic/PubSubManager.js.map +1 -1
- package/dist/generic/PushStatusResolver.d.ts +39 -6
- package/dist/generic/PushStatusResolver.d.ts.map +1 -1
- package/dist/generic/PushStatusResolver.js +93 -11
- package/dist/generic/PushStatusResolver.js.map +1 -1
- package/dist/generic/ResolverBase.d.ts +65 -25
- package/dist/generic/ResolverBase.d.ts.map +1 -1
- package/dist/generic/ResolverBase.js +201 -101
- package/dist/generic/ResolverBase.js.map +1 -1
- package/dist/generic/RunViewResolver.d.ts +11 -3
- package/dist/generic/RunViewResolver.d.ts.map +1 -1
- package/dist/generic/RunViewResolver.js +79 -13
- package/dist/generic/RunViewResolver.js.map +1 -1
- package/dist/generic/actionOutputFieldSecurity.d.ts +26 -0
- package/dist/generic/actionOutputFieldSecurity.d.ts.map +1 -0
- package/dist/generic/actionOutputFieldSecurity.js +47 -0
- package/dist/generic/actionOutputFieldSecurity.js.map +1 -0
- package/dist/generic/fieldSecurityTransport.d.ts +30 -0
- package/dist/generic/fieldSecurityTransport.d.ts.map +1 -0
- package/dist/generic/fieldSecurityTransport.js +30 -0
- package/dist/generic/fieldSecurityTransport.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +122 -66
- package/dist/index.js.map +1 -1
- package/dist/integration/CustomColumnPromoter.d.ts.map +1 -1
- package/dist/integration/CustomColumnPromoter.js +6 -1
- package/dist/integration/CustomColumnPromoter.js.map +1 -1
- package/dist/logging/variablesLoggingMiddleware.d.ts +12 -0
- package/dist/logging/variablesLoggingMiddleware.d.ts.map +1 -1
- package/dist/logging/variablesLoggingMiddleware.js +50 -1
- package/dist/logging/variablesLoggingMiddleware.js.map +1 -1
- package/dist/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 +15 -6
- package/dist/realtimeSessions/ownedRealtimeSession.js.map +1 -1
- package/dist/realtimeSessions/sessionAccess.d.ts +88 -11
- package/dist/realtimeSessions/sessionAccess.d.ts.map +1 -1
- package/dist/realtimeSessions/sessionAccess.js +125 -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 +201 -19
- package/dist/realtimeWidget/WidgetSessionService.js.map +1 -1
- package/dist/realtimeWidget/host-identity.d.ts +1 -1
- package/dist/realtimeWidget/host-identity.js +1 -1
- package/dist/realtimeWidget/widgetCore.d.ts +20 -1
- package/dist/realtimeWidget/widgetCore.d.ts.map +1 -1
- package/dist/realtimeWidget/widgetCore.js +17 -1
- package/dist/realtimeWidget/widgetCore.js.map +1 -1
- package/dist/realtimeWidget/widgetGuestElevation.d.ts +1 -1
- package/dist/realtimeWidget/widgetGuestElevation.d.ts.map +1 -1
- package/dist/realtimeWidget/widgetGuestElevation.js +2 -1
- package/dist/realtimeWidget/widgetGuestElevation.js.map +1 -1
- package/dist/resolvers/ActionResolver.d.ts +19 -1
- package/dist/resolvers/ActionResolver.d.ts.map +1 -1
- package/dist/resolvers/ActionResolver.js +63 -12
- package/dist/resolvers/ActionResolver.js.map +1 -1
- package/dist/resolvers/AdhocQueryResolver.d.ts.map +1 -1
- package/dist/resolvers/AdhocQueryResolver.js +1 -0
- package/dist/resolvers/AdhocQueryResolver.js.map +1 -1
- package/dist/resolvers/AgentRunStatusPublisher.d.ts +18 -4
- package/dist/resolvers/AgentRunStatusPublisher.d.ts.map +1 -1
- package/dist/resolvers/AgentRunStatusPublisher.js +32 -8
- package/dist/resolvers/AgentRunStatusPublisher.js.map +1 -1
- package/dist/resolvers/AgentSessionResolver.d.ts +10 -4
- package/dist/resolvers/AgentSessionResolver.d.ts.map +1 -1
- package/dist/resolvers/AgentSessionResolver.js +40 -17
- package/dist/resolvers/AgentSessionResolver.js.map +1 -1
- package/dist/resolvers/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/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/IntegrationDiscoveryResolver.d.ts.map +1 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.js +45 -7
- package/dist/resolvers/IntegrationDiscoveryResolver.js.map +1 -1
- package/dist/resolvers/MergeRecordsResolver.d.ts +8 -1
- package/dist/resolvers/MergeRecordsResolver.d.ts.map +1 -1
- package/dist/resolvers/MergeRecordsResolver.js +31 -3
- package/dist/resolvers/MergeRecordsResolver.js.map +1 -1
- package/dist/resolvers/PipelineProgressResolver.d.ts +6 -0
- package/dist/resolvers/PipelineProgressResolver.d.ts.map +1 -1
- package/dist/resolvers/PipelineProgressResolver.js +5 -3
- package/dist/resolvers/PipelineProgressResolver.js.map +1 -1
- package/dist/resolvers/QueryResolver.d.ts.map +1 -1
- package/dist/resolvers/QueryResolver.js +20 -6
- package/dist/resolvers/QueryResolver.js.map +1 -1
- package/dist/resolvers/QuerySystemUserResolver.d.ts +2 -0
- package/dist/resolvers/QuerySystemUserResolver.d.ts.map +1 -1
- package/dist/resolvers/QuerySystemUserResolver.js +15 -6
- package/dist/resolvers/QuerySystemUserResolver.js.map +1 -1
- package/dist/resolvers/RSUResolver.d.ts.map +1 -1
- package/dist/resolvers/RSUResolver.js +12 -0
- package/dist/resolvers/RSUResolver.js.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts +16 -2
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.js +82 -28
- package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
- package/dist/resolvers/RemoteBrowserActionResolver.d.ts.map +1 -1
- package/dist/resolvers/RemoteBrowserActionResolver.js +11 -9
- package/dist/resolvers/RemoteBrowserActionResolver.js.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.d.ts +56 -8
- package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.js +209 -64
- package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
- package/dist/resolvers/RunTemplateResolver.d.ts.map +1 -1
- package/dist/resolvers/RunTemplateResolver.js +4 -4
- package/dist/resolvers/RunTemplateResolver.js.map +1 -1
- package/dist/resolvers/RunTestResolver.d.ts.map +1 -1
- package/dist/resolvers/RunTestResolver.js +3 -1
- package/dist/resolvers/RunTestResolver.js.map +1 -1
- package/dist/resolvers/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/rest/EntityCRUDHandler.d.ts +6 -0
- package/dist/rest/EntityCRUDHandler.d.ts.map +1 -1
- package/dist/rest/EntityCRUDHandler.js +19 -5
- package/dist/rest/EntityCRUDHandler.js.map +1 -1
- package/dist/rest/RESTEndpointHandler.d.ts.map +1 -1
- package/dist/rest/RESTEndpointHandler.js +8 -5
- package/dist/rest/RESTEndpointHandler.js.map +1 -1
- package/dist/rest/RealtimeRecordingHandler.d.ts +3 -3
- package/dist/rest/RealtimeRecordingHandler.d.ts.map +1 -1
- package/dist/rest/RealtimeRecordingHandler.js +7 -7
- 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 +22 -5
- package/dist/rest/ViewOperationsHandler.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/TaskGraphContinuationDeliverer.d.ts +5 -0
- package/dist/services/TaskGraphContinuationDeliverer.d.ts.map +1 -1
- package/dist/services/TaskGraphContinuationDeliverer.js +42 -15
- package/dist/services/TaskGraphContinuationDeliverer.js.map +1 -1
- package/dist/types.d.ts +23 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +98 -98
- package/src/__tests__/ActionResolver.fieldSecurity.test.ts +237 -0
- package/src/__tests__/AdhocQueryResolver.dialect.test.ts +137 -0
- package/src/__tests__/AgentRunStatusPublisher.test.ts +49 -0
- package/src/__tests__/AgentSessionResolver.ownership.test.ts +137 -0
- package/src/__tests__/CustomColumnPromoterOnePass.test.ts +15 -1
- package/src/__tests__/EntityCommunicationsResolver.actingUser.test.ts +151 -0
- package/src/__tests__/EvolutionActsOnWhatItDetects.test.ts +113 -0
- package/src/__tests__/FetchEntityVectorsResolver.test.ts +206 -3
- package/src/__tests__/FileResolver.fieldSecurity.test.ts +82 -0
- package/src/__tests__/PipelineProgressResolver.filter.test.ts +58 -0
- package/src/__tests__/QuerySystemUserResolver.fieldSecurity.test.ts +49 -0
- package/src/__tests__/RESTEndpointHandler.test.ts +25 -0
- package/src/__tests__/RealtimeClientSessionResolver.configTamper.test.ts +23 -3
- package/src/__tests__/RealtimeClientSessionResolver.test.ts +324 -46
- package/src/__tests__/RemoteBrowserActionResolver.ownership.test.ts +98 -0
- package/src/__tests__/ResolverBase.clientOldValues.test.ts +37 -4
- package/src/__tests__/ResolverBase.deleteReturnProjection.test.ts +52 -0
- package/src/__tests__/ResolverBase.entityMessageRelay.test.ts +176 -0
- package/src/__tests__/ResolverBase.includeBinaryFields.test.ts +23 -1
- package/src/__tests__/ResolverBase.publishStatusUpdate.test.ts +68 -0
- package/src/__tests__/ResolverBase.userViewCacheAndDedup.test.ts +130 -0
- package/src/__tests__/RunAIAgentResolver.branch.test.ts +68 -13
- package/src/__tests__/RunAIAgentResolver.conversationWriter.test.ts +210 -0
- package/src/__tests__/RunAIAgentResolver.fireAndForgetCompletion.test.ts +209 -0
- package/src/__tests__/RunAIAgentResolver.historyFrom.test.ts +17 -27
- package/src/__tests__/RunAIAgentResolver.runDataGuard.test.ts +8 -2
- package/src/__tests__/RunAIAgentResolver.serverReply.test.ts +358 -0
- package/src/__tests__/RunAIAgentResolver.stoppedPredecessor.test.ts +4 -1
- package/src/__tests__/RunTemplateResolver.test.ts +35 -2
- package/src/__tests__/RunViewResolver.cacheCheckForwarding.test.ts +11 -0
- package/src/__tests__/SessionManager.test.ts +95 -0
- 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 +7 -2
- package/src/__tests__/WidgetSessionService.test.ts +583 -4
- package/src/__tests__/apiRootBoot.test.ts +1 -1
- 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__/fieldSecurityFixtures.ts +91 -0
- package/src/__tests__/globalCors.test.ts +3 -3
- package/src/__tests__/localDevAuth.test.ts +196 -0
- package/src/__tests__/orphanedConversationDetailReconciler.test.ts +10 -0
- package/src/__tests__/pushStatusResolver.filter.test.ts +57 -1
- package/src/__tests__/realtimeRecordingHandler.test.ts +19 -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 +146 -7
- package/src/__tests__/realtimeSessions/sessionConfigStamps.test.ts +1 -1
- package/src/__tests__/realtimeSessions/verificationWorkflow.test.ts +25 -4
- package/src/__tests__/resolverBase.cloudEventChangedFields.test.ts +157 -0
- package/src/__tests__/resolverBase.fieldSecurityTransport.test.ts +222 -0
- package/src/__tests__/resolverBase.fls.test.ts +146 -97
- package/src/__tests__/restTransport.fieldSecurity.test.ts +148 -0
- package/src/__tests__/runParamsTimeZone.test.ts +179 -0
- package/src/__tests__/runStreams.fieldSecurity.test.ts +100 -0
- package/src/__tests__/runViewProperties.test.ts +114 -0
- package/src/__tests__/scalabilityBenchmarks.test.ts +765 -0
- package/src/__tests__/scalabilityDatabaseIntegration.test.ts +207 -0
- package/src/__tests__/sessionUserClone.test.ts +5 -1
- package/src/__tests__/startupSweepOrder.test.ts +40 -0
- package/src/__tests__/unifiedAuth.test.ts +28 -0
- package/src/__tests__/widgetGuestElevation.test.ts +2 -0
- package/src/agentSessions/SessionJanitor.ts +3 -3
- package/src/agentSessions/SessionManager.ts +35 -12
- package/src/auth/AuthProviderCatalogRouter.ts +3 -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/magicLink/MagicLinkKeys.ts +2 -2
- package/src/auth/magicLink/types.ts +10 -0
- package/src/auth/sessionUserClone.ts +3 -2
- package/src/broadcast/BaseCacheInvalidationBroadcastProvider.ts +674 -0
- package/src/broadcast/index.ts +5 -0
- package/src/broadcast/providers/AWSIoTCoreBroadcastProvider.ts +180 -0
- package/src/broadcast/providers/AzureWebPubSubBroadcastProvider.ts +182 -0
- package/src/broadcast/providers/GCPPubSubBroadcastProvider.ts +169 -0
- package/src/broadcast/providers/SequencedRoleBucketBroadcastProvider.ts +57 -0
- package/src/cache.ts +2 -1
- package/src/config.ts +69 -0
- package/src/context.ts +32 -8
- package/src/coreRoutes.ts +15 -0
- package/src/generated/graphql-schemas/__mj.ts +2239 -102
- package/src/generic/CacheInvalidationResolver.ts +135 -78
- package/src/generic/OrphanedConversationDetailReconciler.ts +4 -2
- package/src/generic/PubSubManager.ts +54 -1
- package/src/generic/PushStatusResolver.ts +108 -11
- package/src/generic/ResolverBase.ts +237 -107
- package/src/generic/RunViewResolver.ts +80 -15
- package/src/generic/actionOutputFieldSecurity.ts +75 -0
- package/src/generic/fieldSecurityTransport.ts +62 -0
- package/src/index.ts +127 -68
- package/src/integration/CustomColumnPromoter.ts +6 -1
- 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 +20 -6
- package/src/realtimeSessions/sessionAccess.ts +181 -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 +252 -17
- package/src/realtimeWidget/host-identity.ts +1 -1
- package/src/realtimeWidget/widgetCore.ts +30 -1
- package/src/realtimeWidget/widgetGuestElevation.ts +2 -1
- package/src/resolvers/ActionResolver.ts +78 -15
- package/src/resolvers/AdhocQueryResolver.ts +1 -0
- package/src/resolvers/AgentRunStatusPublisher.ts +36 -8
- package/src/resolvers/AgentSessionResolver.ts +46 -18
- package/src/resolvers/EntityCommunicationsResolver.ts +56 -15
- package/src/resolvers/FetchEntityVectorsResolver.ts +132 -21
- package/src/resolvers/FileCategoryResolver.ts +1 -0
- package/src/resolvers/FileResolver.ts +14 -4
- package/src/resolvers/IntegrationDiscoveryResolver.ts +49 -7
- 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 +15 -6
- package/src/resolvers/RSUResolver.ts +12 -0
- package/src/resolvers/RealtimeClientSessionResolver.ts +104 -33
- package/src/resolvers/RemoteBrowserActionResolver.ts +15 -10
- package/src/resolvers/RunAIAgentResolver.ts +258 -82
- package/src/resolvers/RunTemplateResolver.ts +6 -4
- 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__/MergeRecordsResolver.test.ts +43 -0
- package/src/rest/EntityCRUDHandler.ts +22 -5
- package/src/rest/RESTEndpointHandler.ts +8 -5
- package/src/rest/RealtimeRecordingHandler.ts +13 -10
- package/src/rest/ViewOperationsHandler.ts +24 -6
- package/src/serverRoleConfigUnits.ts +48 -0
- package/src/services/TaskGraphContinuationDeliverer.ts +52 -20
- package/src/types.ts +23 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EntityPermissionType, FieldValueCollection, EntitySaveOptions, IMetadataProvider, LogError, UserInfo } from '@memberjunction/core';
|
|
1
|
+
import { AssertClientInputWritableForUser, EntityPermissionType, FieldValueCollection, EntitySaveOptions, IMetadataProvider, LogError, UserInfo } from '@memberjunction/core';
|
|
2
2
|
import { NormalizeUUID } from '@memberjunction/global';
|
|
3
3
|
import { MJFileEntity, MJFileStorageProviderEntity, MJFileStorageAccountEntity } from '@memberjunction/core-entities';
|
|
4
4
|
import {
|
|
@@ -47,6 +47,7 @@ import {
|
|
|
47
47
|
import { CreateMJFileInput, MJFileResolver as FileResolverBase, MJFile_, UpdateMJFileInput } from '../generated/generated.js';
|
|
48
48
|
import { FieldMapper } from '@memberjunction/graphql-dataprovider';
|
|
49
49
|
import { GetReadOnlyProvider } from '../util.js';
|
|
50
|
+
import { ProjectEntityObjectForCaller, ProjectableEntityObject } from '../generic/fieldSecurityTransport.js';
|
|
50
51
|
import { MediaAccessKeyManager } from '../rest/MediaAccessKeys.js';
|
|
51
52
|
import { UploadTokenManager } from '../rest/UploadTokenManager.js';
|
|
52
53
|
import { DeriveSidecarPath, ParsePeaksSidecar } from './peaksSidecar.js';
|
|
@@ -666,6 +667,8 @@ export class FileResolver extends FileResolverBase {
|
|
|
666
667
|
const fileEntity = await provider.GetEntityObject<MJFileEntity>('MJ: Files', user);
|
|
667
668
|
const providerEntity = await provider.GetEntityObject<MJFileStorageProviderEntity>('MJ: File Storage Providers', user);
|
|
668
669
|
fileEntity.CheckPermissions(EntityPermissionType.Create, true);
|
|
670
|
+
// Field-level security: refuse a key the caller may not read, or that names no field, before anything else
|
|
671
|
+
AssertClientInputWritableForUser(fileEntity.EntityInfo, { ...input }, user);
|
|
669
672
|
|
|
670
673
|
// The upload URL signs an overwrite of `Name` (and the row will point at `ProviderKey`): Write on the account the
|
|
671
674
|
// provider resolves to, and the tracked-file rule on both keys, as for every other route that writes an object.
|
|
@@ -693,7 +696,7 @@ export class FileResolver extends FileResolverBase {
|
|
|
693
696
|
if (!saved) {
|
|
694
697
|
console.error('[CreateFile] File save failed:', fileEntity.LatestResult?.CompleteMessage);
|
|
695
698
|
}
|
|
696
|
-
const File =
|
|
699
|
+
const File = this.fileResponse(fileEntity, user, provider);
|
|
697
700
|
|
|
698
701
|
return { File, UploadUrl, NameExists };
|
|
699
702
|
}
|
|
@@ -760,8 +763,7 @@ export class FileResolver extends FileResolverBase {
|
|
|
760
763
|
});
|
|
761
764
|
|
|
762
765
|
const loaded = await fileEntity.Load(uploadResult.FileID);
|
|
763
|
-
const
|
|
764
|
-
const File = loaded ? (mapper.MapFields({ ...fileEntity.GetAll() }) as unknown as MJFile_) : undefined;
|
|
766
|
+
const File = loaded ? (this.fileResponse(fileEntity, user, provider) as unknown as MJFile_) : undefined;
|
|
765
767
|
|
|
766
768
|
return {
|
|
767
769
|
Success: true,
|
|
@@ -778,6 +780,14 @@ export class FileResolver extends FileResolverBase {
|
|
|
778
780
|
}
|
|
779
781
|
}
|
|
780
782
|
|
|
783
|
+
/**
|
|
784
|
+
* The file record for a response: its field values as the caller may read them, in GraphQL field
|
|
785
|
+
* names. The record was just saved or reloaded, and a save re-reads the whole row.
|
|
786
|
+
*/
|
|
787
|
+
private fileResponse(fileEntity: ProjectableEntityObject, user: UserInfo, provider: IMetadataProvider): Record<string, unknown> {
|
|
788
|
+
return new FieldMapper().MapFields({ ...ProjectEntityObjectForCaller(fileEntity, user, provider) });
|
|
789
|
+
}
|
|
790
|
+
|
|
781
791
|
/**
|
|
782
792
|
* The account an upload will land in: the requested one, else the engine's default (the first active account) —
|
|
783
793
|
* returned as an explicit ID so the account the gate checks is the account `UploadFile` uses. A requested ID is
|
|
@@ -33,7 +33,8 @@ import {
|
|
|
33
33
|
IntegrationSchemaSync,
|
|
34
34
|
decideSchemaLimitViolations,
|
|
35
35
|
IntegrationConnectorCreationPipeline,
|
|
36
|
-
IntegrationActionGenerator
|
|
36
|
+
IntegrationActionGenerator,
|
|
37
|
+
ObjectsWithWatermarkFieldChange
|
|
37
38
|
} from "@memberjunction/integration-engine";
|
|
38
39
|
import type {
|
|
39
40
|
IntegrationActionVerb,
|
|
@@ -1624,7 +1625,7 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
1624
1625
|
Platform: validatedPlatform,
|
|
1625
1626
|
MJVersion: process.env.MJ_VERSION ?? '5.11.0',
|
|
1626
1627
|
SourceType: companyIntegration.Integration,
|
|
1627
|
-
AdditionalSchemaInfoPath:
|
|
1628
|
+
AdditionalSchemaInfoPath: RuntimeSchemaManager.Instance.AdditionalSchemaInfoPath,
|
|
1628
1629
|
MigrationsDir: process.env.RSU_MIGRATIONS_PATH ?? 'migrations/rsu',
|
|
1629
1630
|
MetadataDir: process.env.RSU_METADATA_DIR ?? 'metadata',
|
|
1630
1631
|
ExistingTables: this.buildExistingTables(targetConfigs, provider),
|
|
@@ -3431,7 +3432,7 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
3431
3432
|
Platform: validatedPlatform,
|
|
3432
3433
|
MJVersion: process.env.MJ_VERSION ?? '5.11.0',
|
|
3433
3434
|
SourceType: companyIntegration.Integration,
|
|
3434
|
-
AdditionalSchemaInfoPath:
|
|
3435
|
+
AdditionalSchemaInfoPath: RuntimeSchemaManager.Instance.AdditionalSchemaInfoPath,
|
|
3435
3436
|
MigrationsDir: process.env.RSU_MIGRATIONS_PATH ?? 'migrations/rsu',
|
|
3436
3437
|
MetadataDir: process.env.RSU_METADATA_DIR ?? 'metadata',
|
|
3437
3438
|
ExistingTables: this.buildExistingTables(targetConfigs, provider),
|
|
@@ -3516,8 +3517,14 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
3516
3517
|
return { Success: false, Message: 'No valid schema inputs to process', Items: itemResults };
|
|
3517
3518
|
}
|
|
3518
3519
|
|
|
3520
|
+
// Retrying variant, matching `IntegrationApplySchema` (which retries via
|
|
3521
|
+
// SchemaBuilder.RunSchemaPipeline). This is the same install path over the same
|
|
3522
|
+
// SchemaBuilder-generated DDL, and its expensive middle steps — ExecuteMigration,
|
|
3523
|
+
// RunCodeGen, CompileTypeScript, RestartMJAPI — fail transiently. The wrapper replays
|
|
3524
|
+
// only those four, and only while NOTHING in the batch has been applied, so a partially
|
|
3525
|
+
// succeeded batch is still reported as-is rather than double-applied.
|
|
3519
3526
|
const rsm = RuntimeSchemaManager.Instance;
|
|
3520
|
-
const batchResult = await rsm.
|
|
3527
|
+
const batchResult = await rsm.RunPipelineBatchWithRetry(pipelineInputs);
|
|
3521
3528
|
|
|
3522
3529
|
return {
|
|
3523
3530
|
Success: batchResult.SuccessCount > 0,
|
|
@@ -4205,7 +4212,7 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
4205
4212
|
Platform: platform,
|
|
4206
4213
|
MJVersion: process.env.MJ_VERSION ?? '5.11.0',
|
|
4207
4214
|
SourceType: companyIntegration.Integration,
|
|
4208
|
-
AdditionalSchemaInfoPath:
|
|
4215
|
+
AdditionalSchemaInfoPath: RuntimeSchemaManager.Instance.AdditionalSchemaInfoPath,
|
|
4209
4216
|
MigrationsDir: process.env.RSU_MIGRATIONS_PATH ?? 'migrations/rsu',
|
|
4210
4217
|
MetadataDir: process.env.RSU_METADATA_DIR ?? 'metadata',
|
|
4211
4218
|
ExistingTables: this.buildExistingTables(targetConfigs, provider),
|
|
@@ -6186,7 +6193,7 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
6186
6193
|
Platform: validatedPlatform,
|
|
6187
6194
|
MJVersion: process.env.MJ_VERSION ?? '5.11.0',
|
|
6188
6195
|
SourceType: companyIntegration.Integration,
|
|
6189
|
-
AdditionalSchemaInfoPath:
|
|
6196
|
+
AdditionalSchemaInfoPath: RuntimeSchemaManager.Instance.AdditionalSchemaInfoPath,
|
|
6190
6197
|
MigrationsDir: process.env.RSU_MIGRATIONS_PATH ?? 'migrations/rsu',
|
|
6191
6198
|
MetadataDir: process.env.RSU_METADATA_DIR ?? 'metadata',
|
|
6192
6199
|
ExistingTables: existingTables,
|
|
@@ -6227,6 +6234,36 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
6227
6234
|
}
|
|
6228
6235
|
}
|
|
6229
6236
|
|
|
6237
|
+
// ── Phase 5b — MJ-RUN-37: a WATERMARK-FIELD swap is a change the DDL diff cannot see ──
|
|
6238
|
+
//
|
|
6239
|
+
// A connector upgrade can move an object's incremental cursor to a different source
|
|
6240
|
+
// column (`modified_at` → `last_updated`). Phase 1's persist already DETECTS that — the
|
|
6241
|
+
// overlay rewrites `IntegrationObject.IncrementalWatermarkField` and records it in the
|
|
6242
|
+
// merge log's `ChangedAttributes`. Nothing consumed it, and no other source of
|
|
6243
|
+
// `changedObjects` can: a cursor swap adds no column (so `diff.AddedColumns` and
|
|
6244
|
+
// `ModifiedColumns` are both empty) and touches no field map (so Phase 6 stays quiet).
|
|
6245
|
+
//
|
|
6246
|
+
// The object was therefore treated as unchanged, its Pull watermark survived, and the
|
|
6247
|
+
// next incremental sync applied the OLD column's stored value as a lower bound on the
|
|
6248
|
+
// NEW one. Where the new column sorts later, every row below that value is filtered out
|
|
6249
|
+
// AT THE SOURCE — permanently, and with no artifact: the source reports a total
|
|
6250
|
+
// consistent with the filter it was given, so fetched equals expected and the run
|
|
6251
|
+
// closes clean. Absence, not duplication, is what this produces.
|
|
6252
|
+
//
|
|
6253
|
+
// Scoped to CONTINUING maps deliberately. A new object has no watermark to invalidate
|
|
6254
|
+
// and a removed one has no sync left to protect; widening this to every persisted object
|
|
6255
|
+
// would inflate `ChangedObjects` (and `hasChanges`) with names Phase 7 cannot act on.
|
|
6256
|
+
const watermarkFieldChanged = ObjectsWithWatermarkFieldChange(
|
|
6257
|
+
refresh.PersistResult?.ObjectMergeLog ?? [],
|
|
6258
|
+
continuingMaps.map(m => m.ExternalObjectName ?? ''),
|
|
6259
|
+
);
|
|
6260
|
+
for (const name of watermarkFieldChanged) {
|
|
6261
|
+
if (!changedObjects.some(n => n.toLowerCase() === name.toLowerCase())) changedObjects.push(name);
|
|
6262
|
+
}
|
|
6263
|
+
if (watermarkFieldChanged.length > 0) {
|
|
6264
|
+
LogStatus(`[SchemaEvolution] IncrementalWatermarkField changed on ${watermarkFieldChanged.length} object(s) — resetting their Pull watermarks: ${watermarkFieldChanged.join(', ')}`);
|
|
6265
|
+
}
|
|
6266
|
+
|
|
6230
6267
|
// ── Phase 6 — reconcile CONTINUING maps' field maps to the resolution ──
|
|
6231
6268
|
// Added source fields get field maps (Active on enabled maps, Disabled on disabled
|
|
6232
6269
|
// maps); field maps whose source field vanished from the resolution are disabled.
|
|
@@ -6301,8 +6338,13 @@ export class IntegrationDiscoveryResolver extends ResolverBase {
|
|
|
6301
6338
|
rsuInput.ContextUser = user;
|
|
6302
6339
|
}
|
|
6303
6340
|
|
|
6341
|
+
// Retrying variant, for the same reason every other install path uses it: a refresh
|
|
6342
|
+
// is unattended and long, and a transient ExecuteMigration / RunCodeGen /
|
|
6343
|
+
// CompileTypeScript / RestartMJAPI failure would otherwise abandon it with the
|
|
6344
|
+
// metadata already re-resolved and the DDL not applied — the half-state an operator
|
|
6345
|
+
// then has to diagnose. Replay happens only while nothing was applied.
|
|
6304
6346
|
const rsm = RuntimeSchemaManager.Instance;
|
|
6305
|
-
const batchResult = await rsm.
|
|
6347
|
+
const batchResult = await rsm.RunPipelineBatchWithRetry([rsuInput]);
|
|
6306
6348
|
const pipelineResult = batchResult.Results[0];
|
|
6307
6349
|
pipelineSteps = pipelineResult?.Steps.map((s: RSUPipelineStep) => ({
|
|
6308
6350
|
Name: s.Name, Status: s.Status, DurationMs: s.DurationMs, Message: s.Message, StepIndex: s.StepIndex, StepTotal: s.StepTotal,
|
|
@@ -38,6 +38,18 @@ export class EntityDependencyResolver {
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
@InputType()
|
|
42
|
+
export class RecordDependencyOptionsInput {
|
|
43
|
+
@Field(() => String, { nullable: true })
|
|
44
|
+
LinkType?: 'both' | 'hard' | 'soft';
|
|
45
|
+
|
|
46
|
+
@Field(() => Boolean, { nullable: true })
|
|
47
|
+
IncludeSystemEntities?: boolean;
|
|
48
|
+
|
|
49
|
+
@Field(() => [String], { nullable: true })
|
|
50
|
+
EntityNames?: string[];
|
|
51
|
+
}
|
|
52
|
+
|
|
41
53
|
@ObjectType()
|
|
42
54
|
export class RecordDependencyResult {
|
|
43
55
|
@Field(() => String)
|
|
@@ -49,6 +61,9 @@ export class RecordDependencyResult {
|
|
|
49
61
|
@Field(() => String)
|
|
50
62
|
FieldName: string; // required
|
|
51
63
|
|
|
64
|
+
@Field(() => String, { nullable: true })
|
|
65
|
+
FieldDisplayName?: string;
|
|
66
|
+
|
|
52
67
|
@Field(() => CompositeKeyOutputType)
|
|
53
68
|
PrimaryKey: CompositeKey;
|
|
54
69
|
|
|
@@ -70,17 +85,23 @@ export class RecordDependencyResolver {
|
|
|
70
85
|
@Arg('entityName', () => String) entityName: string,
|
|
71
86
|
@Arg('CompositeKey', () => CompositeKeyInputType) ckInput: CompositeKeyInputType,
|
|
72
87
|
@Ctx() { dataSource, userPayload, providers }: AppContext,
|
|
73
|
-
@PubSub() pubSub: PubSubEngine
|
|
88
|
+
@PubSub() pubSub: PubSubEngine,
|
|
89
|
+
@Arg('options', () => RecordDependencyOptionsInput, { nullable: true }) options?: RecordDependencyOptionsInput
|
|
74
90
|
) {
|
|
75
91
|
try {
|
|
76
92
|
const md = GetReadOnlyProvider(providers);
|
|
77
93
|
const ck = new CompositeKey(ckInput.KeyValuePairs);
|
|
78
|
-
const
|
|
94
|
+
const contextUser = userPayload?.userRecord;
|
|
95
|
+
const result =
|
|
96
|
+
options !== undefined || contextUser !== undefined
|
|
97
|
+
? await md.GetRecordDependencies(entityName, ck, contextUser, options)
|
|
98
|
+
: await md.GetRecordDependencies(entityName, ck);
|
|
79
99
|
|
|
80
100
|
return result.map(dep => ({
|
|
81
101
|
EntityName: dep.EntityName,
|
|
82
102
|
RelatedEntityName: dep.RelatedEntityName,
|
|
83
103
|
FieldName: dep.FieldName,
|
|
104
|
+
FieldDisplayName: dep.FieldDisplayName,
|
|
84
105
|
PrimaryKey: dep.PrimaryKey,
|
|
85
106
|
CompositeKey: dep.PrimaryKey,
|
|
86
107
|
IsSoftLink: dep.IsSoftLink,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Resolver, Subscription, Root, ObjectType, Field, Float, Mutation, Arg, Ctx, PubSub, PubSubEngine } from 'type-graphql';
|
|
2
2
|
import { AppContext } from '../types.js';
|
|
3
3
|
import { LogStatus, LogError } from '@memberjunction/core';
|
|
4
|
+
import { UUIDsEqual } from '@memberjunction/global';
|
|
4
5
|
import { ResolverBase } from '../generic/ResolverBase.js';
|
|
5
6
|
|
|
6
7
|
const PIPELINE_PROGRESS_TOPIC = 'PIPELINE_PROGRESS';
|
|
@@ -49,6 +50,16 @@ export class PipelineStartResult {
|
|
|
49
50
|
ErrorMessage?: string;
|
|
50
51
|
}
|
|
51
52
|
|
|
53
|
+
export function PipelineProgressFilter({
|
|
54
|
+
payload,
|
|
55
|
+
args,
|
|
56
|
+
}: {
|
|
57
|
+
payload: PipelineProgressNotification;
|
|
58
|
+
args: { pipelineRunID: string };
|
|
59
|
+
}): boolean {
|
|
60
|
+
return UUIDsEqual(payload.PipelineRunID, args.pipelineRunID) || payload.PipelineRunID === args.pipelineRunID;
|
|
61
|
+
}
|
|
62
|
+
|
|
52
63
|
@Resolver()
|
|
53
64
|
export class PipelineProgressResolver extends ResolverBase {
|
|
54
65
|
/**
|
|
@@ -56,9 +67,7 @@ export class PipelineProgressResolver extends ResolverBase {
|
|
|
56
67
|
*/
|
|
57
68
|
@Subscription(() => PipelineProgressNotification, {
|
|
58
69
|
topics: PIPELINE_PROGRESS_TOPIC,
|
|
59
|
-
filter:
|
|
60
|
-
return payload.PipelineRunID === args.pipelineRunID;
|
|
61
|
-
},
|
|
70
|
+
filter: PipelineProgressFilter,
|
|
62
71
|
})
|
|
63
72
|
PipelineProgress(
|
|
64
73
|
@Root() notification: PipelineProgressNotification,
|
|
@@ -226,7 +226,8 @@ export class RunQueryResolver extends ResolverBase {
|
|
|
226
226
|
ForceAuditLog: ForceAuditLog,
|
|
227
227
|
AuditLogDescription: AuditLogDescription,
|
|
228
228
|
Enrichment: Enrichment,
|
|
229
|
-
DataSource: DataSource
|
|
229
|
+
DataSource: DataSource,
|
|
230
|
+
TimeZone: context.userPayload.TimeZone
|
|
230
231
|
},
|
|
231
232
|
context.userPayload.userRecord);
|
|
232
233
|
|
|
@@ -247,6 +248,7 @@ export class RunQueryResolver extends ResolverBase {
|
|
|
247
248
|
QueryID: QueryID,
|
|
248
249
|
QueryName: queryName || 'Unknown Query',
|
|
249
250
|
Success: result.Success ?? false,
|
|
251
|
+
// fls-guard: saved-query rows. Its SQL is refused before it runs if it reads a field the caller is denied, unless the query has `MJ: Query Permissions` rows, which authorize it by role alone
|
|
250
252
|
Results: JSON.stringify(result.Results ?? null),
|
|
251
253
|
RowCount: result.RowCount ?? 0,
|
|
252
254
|
TotalRowCount: result.TotalRowCount ?? 0,
|
|
@@ -288,7 +290,8 @@ export class RunQueryResolver extends ResolverBase {
|
|
|
288
290
|
ForceAuditLog: ForceAuditLog,
|
|
289
291
|
AuditLogDescription: AuditLogDescription,
|
|
290
292
|
Enrichment: Enrichment,
|
|
291
|
-
DataSource: DataSource
|
|
293
|
+
DataSource: DataSource,
|
|
294
|
+
TimeZone: context.userPayload.TimeZone
|
|
292
295
|
},
|
|
293
296
|
context.userPayload.userRecord);
|
|
294
297
|
|
|
@@ -296,6 +299,7 @@ export class RunQueryResolver extends ResolverBase {
|
|
|
296
299
|
QueryID: result.QueryID || '',
|
|
297
300
|
QueryName: QueryName,
|
|
298
301
|
Success: result.Success ?? false,
|
|
302
|
+
// fls-guard: saved-query rows. Its SQL is refused before it runs if it reads a field the caller is denied, unless the query has `MJ: Query Permissions` rows, which authorize it by role alone
|
|
299
303
|
Results: JSON.stringify(result.Results ?? null),
|
|
300
304
|
RowCount: result.RowCount ?? 0,
|
|
301
305
|
TotalRowCount: result.TotalRowCount ?? 0,
|
|
@@ -337,7 +341,8 @@ export class RunQueryResolver extends ResolverBase {
|
|
|
337
341
|
ForceAuditLog: ForceAuditLog,
|
|
338
342
|
AuditLogDescription: AuditLogDescription,
|
|
339
343
|
Enrichment: Enrichment,
|
|
340
|
-
DataSource: DataSource
|
|
344
|
+
DataSource: DataSource,
|
|
345
|
+
TimeZone: context.userPayload.TimeZone
|
|
341
346
|
},
|
|
342
347
|
context.userPayload.userRecord);
|
|
343
348
|
|
|
@@ -358,6 +363,7 @@ export class RunQueryResolver extends ResolverBase {
|
|
|
358
363
|
QueryID: QueryID,
|
|
359
364
|
QueryName: queryName || 'Unknown Query',
|
|
360
365
|
Success: result.Success ?? false,
|
|
366
|
+
// fls-guard: saved-query rows. Its SQL is refused before it runs if it reads a field the caller is denied, unless the query has `MJ: Query Permissions` rows, which authorize it by role alone
|
|
361
367
|
Results: JSON.stringify(result.Results ?? null),
|
|
362
368
|
RowCount: result.RowCount ?? 0,
|
|
363
369
|
TotalRowCount: result.TotalRowCount ?? 0,
|
|
@@ -398,7 +404,8 @@ export class RunQueryResolver extends ResolverBase {
|
|
|
398
404
|
ForceAuditLog: ForceAuditLog,
|
|
399
405
|
AuditLogDescription: AuditLogDescription,
|
|
400
406
|
Enrichment: Enrichment,
|
|
401
|
-
DataSource: DataSource
|
|
407
|
+
DataSource: DataSource,
|
|
408
|
+
TimeZone: context.userPayload.TimeZone
|
|
402
409
|
},
|
|
403
410
|
context.userPayload.userRecord);
|
|
404
411
|
|
|
@@ -406,6 +413,7 @@ export class RunQueryResolver extends ResolverBase {
|
|
|
406
413
|
QueryID: result.QueryID || '',
|
|
407
414
|
QueryName: QueryName,
|
|
408
415
|
Success: result.Success ?? false,
|
|
416
|
+
// fls-guard: saved-query rows. Its SQL is refused before it runs if it reads a field the caller is denied, unless the query has `MJ: Query Permissions` rows, which authorize it by role alone
|
|
409
417
|
Results: JSON.stringify(result.Results ?? null),
|
|
410
418
|
RowCount: result.RowCount ?? 0,
|
|
411
419
|
TotalRowCount: result.TotalRowCount ?? 0,
|
|
@@ -447,7 +455,8 @@ export class RunQueryResolver extends ResolverBase {
|
|
|
447
455
|
ForceAuditLog: i.ForceAuditLog,
|
|
448
456
|
AuditLogDescription: i.AuditLogDescription,
|
|
449
457
|
Enrichment: i.Enrichment,
|
|
450
|
-
DataSource: i.DataSource
|
|
458
|
+
DataSource: i.DataSource,
|
|
459
|
+
TimeZone: context.userPayload.TimeZone
|
|
451
460
|
}));
|
|
452
461
|
|
|
453
462
|
// Execute all queries in parallel using the batch method
|
|
@@ -460,6 +469,7 @@ export class RunQueryResolver extends ResolverBase {
|
|
|
460
469
|
QueryID: result.QueryID || inputItem.QueryID || '',
|
|
461
470
|
QueryName: result.QueryName || inputItem.QueryName || 'Unknown Query',
|
|
462
471
|
Success: result.Success ?? false,
|
|
472
|
+
// fls-guard: saved-query rows. Its SQL is refused before it runs if it reads a field the caller is denied, unless the query has `MJ: Query Permissions` rows, which authorize it by role alone
|
|
463
473
|
Results: JSON.stringify(result.Results ?? null),
|
|
464
474
|
RowCount: result.RowCount ?? 0,
|
|
465
475
|
TotalRowCount: result.TotalRowCount ?? 0,
|
|
@@ -498,7 +508,8 @@ export class RunQueryResolver extends ResolverBase {
|
|
|
498
508
|
ForceAuditLog: i.ForceAuditLog,
|
|
499
509
|
AuditLogDescription: i.AuditLogDescription,
|
|
500
510
|
Enrichment: i.Enrichment,
|
|
501
|
-
DataSource: i.DataSource
|
|
511
|
+
DataSource: i.DataSource,
|
|
512
|
+
TimeZone: context.userPayload.TimeZone
|
|
502
513
|
}));
|
|
503
514
|
|
|
504
515
|
// Execute all queries in parallel using the batch method
|
|
@@ -511,6 +522,7 @@ export class RunQueryResolver extends ResolverBase {
|
|
|
511
522
|
QueryID: result.QueryID || inputItem.QueryID || '',
|
|
512
523
|
QueryName: result.QueryName || inputItem.QueryName || 'Unknown Query',
|
|
513
524
|
Success: result.Success ?? false,
|
|
525
|
+
// fls-guard: saved-query rows. Its SQL is refused before it runs if it reads a field the caller is denied, unless the query has `MJ: Query Permissions` rows, which authorize it by role alone
|
|
514
526
|
Results: JSON.stringify(result.Results ?? null),
|
|
515
527
|
RowCount: result.RowCount ?? 0,
|
|
516
528
|
TotalRowCount: result.TotalRowCount ?? 0,
|
|
@@ -563,6 +575,7 @@ export class RunQueryResolver extends ResolverBase {
|
|
|
563
575
|
AuditLogDescription: item.params.AuditLogDescription,
|
|
564
576
|
Enrichment: item.params.Enrichment,
|
|
565
577
|
DataSource: item.params.DataSource,
|
|
578
|
+
TimeZone: context.userPayload.TimeZone,
|
|
566
579
|
},
|
|
567
580
|
cacheStatus: item.cacheStatus ? {
|
|
568
581
|
maxUpdatedAt: item.cacheStatus.maxUpdatedAt,
|
|
@@ -578,6 +591,7 @@ export class RunQueryResolver extends ResolverBase {
|
|
|
578
591
|
queryIndex: result.queryIndex,
|
|
579
592
|
queryId: result.queryId,
|
|
580
593
|
status: result.status,
|
|
594
|
+
// fls-guard: saved-query rows. Its SQL is refused before it runs if it reads a field the caller is denied, unless the query has `MJ: Query Permissions` rows, which authorize it by role alone
|
|
581
595
|
Results: result.results ? JSON.stringify(result.results) : undefined,
|
|
582
596
|
maxUpdatedAt: result.maxUpdatedAt,
|
|
583
597
|
rowCount: result.rowCount,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Arg, Ctx, Field, InputType, Mutation, ObjectType, registerEnumType, Resolver, PubSub, PubSubEngine } from 'type-graphql';
|
|
2
2
|
import { AppContext } from '../types.js';
|
|
3
|
-
import { LogError, UserInfo, CompositeKey, DatabaseProviderBase, LogStatus } from '@memberjunction/core';
|
|
3
|
+
import { AssertClientInputWritableForUser, LogError, UserInfo, CompositeKey, DatabaseProviderBase, LogStatus } from '@memberjunction/core';
|
|
4
4
|
import { MJQueryCategoryEntity, MJQueryPermissionEntity, MJQueryFieldEntity, MJQueryParameterEntity, MJQueryEntityEntity, QueryEngine } from '@memberjunction/core-entities';
|
|
5
5
|
import { MJQueryResolver, MJQuery_, MJQueryField_, MJQueryParameter_, MJQueryEntity_, MJQueryPermission_ } from '../generated/generated.js';
|
|
6
6
|
import { GetReadWriteProvider } from '../util.js';
|
|
@@ -301,6 +301,8 @@ export class MJQueryResolverExtended extends MJQueryResolver {
|
|
|
301
301
|
CacheMaxSize: input.CacheMaxSize || null
|
|
302
302
|
};
|
|
303
303
|
|
|
304
|
+
// Field-level security: refuse a key the caller may not read, or that names no field
|
|
305
|
+
AssertClientInputWritableForUser(record.EntityInfo, fieldsToSet, context.userPayload.userRecord);
|
|
304
306
|
record.SetMany(fieldsToSet, true);
|
|
305
307
|
|
|
306
308
|
// Pass caller-provided parameter sample values to override LLM guesses
|
|
@@ -324,7 +326,7 @@ export class MJQueryResolverExtended extends MJQueryResolver {
|
|
|
324
326
|
}
|
|
325
327
|
|
|
326
328
|
|
|
327
|
-
return await this.buildSuccessResult(record);
|
|
329
|
+
return await this.buildSuccessResult(record, context.userPayload.userRecord, provider);
|
|
328
330
|
}
|
|
329
331
|
else {
|
|
330
332
|
// Save failed - check if another request created the same query (race condition)
|
|
@@ -337,7 +339,7 @@ export class MJQueryResolverExtended extends MJQueryResolver {
|
|
|
337
339
|
LogStatus(`[CreateQuery] Unique constraint detected for query '${input.Name}'. Using existing query (ID: ${existingQuery.ID}) created by concurrent request.`);
|
|
338
340
|
const existingEntity = await provider.GetEntityObject<MJQueryEntityServer>('MJ: Queries', context.userPayload.userRecord);
|
|
339
341
|
if (await existingEntity.Load(existingQuery.ID)) {
|
|
340
|
-
return await this.buildSuccessResult(existingEntity);
|
|
342
|
+
return await this.buildSuccessResult(existingEntity, context.userPayload.userRecord, provider);
|
|
341
343
|
}
|
|
342
344
|
// Entity load failed after confirming the row exists — extremely rare
|
|
343
345
|
return {
|
|
@@ -367,11 +369,16 @@ export class MJQueryResolverExtended extends MJQueryResolver {
|
|
|
367
369
|
* Maps an MJQueryEntityServer (with loaded related metadata) to a QueryMutationResultType.
|
|
368
370
|
* Uses entity.GetAll() for scalar fields so that new CodeGen-generated fields are included
|
|
369
371
|
* automatically without manual updates. Related entity arrays are mapped explicitly.
|
|
372
|
+
*
|
|
373
|
+
* @param contextUser The caller the result is for. Field security projects the record for them.
|
|
370
374
|
*/
|
|
371
|
-
private async buildSuccessResult(entity: MJQueryEntityServer): Promise<QueryMutationResultType> {
|
|
375
|
+
private async buildSuccessResult(entity: MJQueryEntityServer, contextUser: UserInfo, provider: DatabaseProviderBase): Promise<QueryMutationResultType> {
|
|
372
376
|
return {
|
|
373
377
|
Success: true,
|
|
374
|
-
|
|
378
|
+
// Mapped for the caller, so the field-security projection applies: the record was just
|
|
379
|
+
// saved, and a save re-reads the whole row.
|
|
380
|
+
// fls-guard: projected for contextUser by MapFieldNamesToCodeNames
|
|
381
|
+
Query: await this.MapFieldNamesToCodeNames('MJ: Queries', entity.GetAll(), contextUser, provider) as MJQuery_,
|
|
375
382
|
Fields: this.mapFields(entity.QueryFields),
|
|
376
383
|
Parameters: this.mapParameters(entity.QueryParameters),
|
|
377
384
|
Entities: this.mapEntities(entity.QueryEntities),
|
|
@@ -523,6 +530,8 @@ export class MJQueryResolverExtended extends MJQueryResolver {
|
|
|
523
530
|
if (input.CacheTTLMinutes !== undefined) updateFields.CacheTTLMinutes = input.CacheTTLMinutes;
|
|
524
531
|
if (input.CacheMaxSize !== undefined) updateFields.CacheMaxSize = input.CacheMaxSize;
|
|
525
532
|
|
|
533
|
+
// Field-level security: refuse a key the caller may not read
|
|
534
|
+
AssertClientInputWritableForUser(queryEntity.EntityInfo, updateFields, context.userPayload.userRecord);
|
|
526
535
|
// Use SetMany to update all fields at once
|
|
527
536
|
queryEntity.SetMany(updateFields);
|
|
528
537
|
|
|
@@ -554,7 +563,7 @@ export class MJQueryResolverExtended extends MJQueryResolver {
|
|
|
554
563
|
await this.createPermissions(provider, input.Permissions, queryID, context.userPayload.userRecord);
|
|
555
564
|
}
|
|
556
565
|
|
|
557
|
-
return await this.buildSuccessResult(queryEntity);
|
|
566
|
+
return await this.buildSuccessResult(queryEntity, context.userPayload.userRecord, provider);
|
|
558
567
|
|
|
559
568
|
} catch (err) {
|
|
560
569
|
LogError(err);
|
|
@@ -318,6 +318,18 @@ export class RSUResolver {
|
|
|
318
318
|
SkipRestart: input.SkipRestart ?? undefined,
|
|
319
319
|
}));
|
|
320
320
|
|
|
321
|
+
// MJ-APPLY-6 — deliberately the BARE call, not RunPipelineBatchWithRetry. Everywhere else
|
|
322
|
+
// the MigrationSQL was generated by SchemaBuilder, so the manager knows what a replay would
|
|
323
|
+
// re-execute. Here it is arbitrary SQL handed in by the caller, and `executeMigration` is
|
|
324
|
+
// NOT transactional: it splits on GO/statement boundaries and issues one ExecuteSQL per
|
|
325
|
+
// chunk, so a migration that fails on chunk 3 leaves chunks 1-2 committed while the step is
|
|
326
|
+
// recorded `failed` — which is exactly the state `canSafelyRetry` reads as "nothing was
|
|
327
|
+
// applied, safe to replay". The replay then re-runs the committed chunks and reports THEIR
|
|
328
|
+
// "already exists" error in place of the real one. For generated DDL that risk is accepted
|
|
329
|
+
// upstream (SchemaBuilder.RunSchemaPipeline); for caller-authored DDL it is not ours to
|
|
330
|
+
// take. This is also an attended operator mutation with no in-repo caller — the human on
|
|
331
|
+
// the other end sees the failure and decides. Keep it in step with the singular
|
|
332
|
+
// RunRuntimeSchemaUpdate above, which uses bare RunPipeline for the same reason.
|
|
321
333
|
const batchResult = await rsm.RunPipelineBatch(pipelineInputs);
|
|
322
334
|
|
|
323
335
|
return {
|