Fix subscription cross tenant issue (#16670)

As title
This commit is contained in:
martmull
2025-12-18 15:22:17 +01:00
committed by GitHub
parent c36bb8f3a1
commit 52cf3775b3
13 changed files with 178 additions and 105 deletions
@@ -1 +0,0 @@
export const SERVERLESS_FUNCTION_LOGS_TRIGGER = 'serverlessFunctionLogs';
@@ -1,10 +1,9 @@
import { Inject, UseFilters, UseGuards, UsePipes } from '@nestjs/common';
import { UseFilters, UseGuards, UsePipes } from '@nestjs/common';
import { Args, Mutation, Query, Resolver, Subscription } from '@nestjs/graphql';
import { InjectRepository } from '@nestjs/typeorm';
import graphqlTypeJson from 'graphql-type-json';
import { Repository } from 'typeorm';
import { RedisPubSub } from 'graphql-redis-subscriptions';
import { isDefined } from 'twenty-shared/utils';
import { PermissionFlagType } from 'twenty-shared/constants';
@@ -28,7 +27,8 @@ import { ServerlessFunctionService } from 'src/engine/metadata-modules/serverles
import { serverlessFunctionGraphQLApiExceptionHandler } from 'src/engine/metadata-modules/serverless-function/utils/serverless-function-graphql-api-exception-handler.utils';
import { ServerlessFunctionLogsDTO } from 'src/engine/metadata-modules/serverless-function/dtos/serverless-function-logs.dto';
import { ServerlessFunctionLogsInput } from 'src/engine/metadata-modules/serverless-function/dtos/serverless-function-logs.input';
import { SERVERLESS_FUNCTION_LOGS_TRIGGER } from 'src/engine/metadata-modules/serverless-function/constants/serverless-function-logs-trigger';
import { SubscriptionChannel } from 'src/engine/subscriptions/enums/subscription-channel.enum';
import { SubscriptionService } from 'src/engine/subscriptions/subscription.service';
@UseGuards(
WorkspaceAuthGuard,
@@ -43,8 +43,7 @@ export class ServerlessFunctionResolver {
private readonly serverlessFunctionService: ServerlessFunctionService,
@InjectRepository(ServerlessFunctionEntity)
private readonly serverlessFunctionRepository: Repository<ServerlessFunctionEntity>,
@Inject('PUB_SUB')
private readonly pubSub: RedisPubSub,
private readonly subscriptionService: SubscriptionService,
) {}
@Query(() => ServerlessFunctionDTO)
@@ -226,7 +225,13 @@ export class ServerlessFunctionResolver {
);
},
})
serverlessFunctionLogs(@Args('input') _: ServerlessFunctionLogsInput) {
return this.pubSub.asyncIterator(SERVERLESS_FUNCTION_LOGS_TRIGGER);
serverlessFunctionLogs(
@Args('input') _: ServerlessFunctionLogsInput,
@AuthWorkspace() workspace: WorkspaceEntity,
) {
return this.subscriptionService.subscribe({
channel: SubscriptionChannel.SERVERLESS_FUNCTION_LOGS_CHANNEL,
workspaceId: workspace.id,
});
}
}
@@ -1,4 +1,4 @@
import { Inject, Injectable } from '@nestjs/common';
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { join } from 'path';
@@ -6,11 +6,10 @@ import { join } from 'path';
import deepEqual from 'deep-equal';
import { isDefined } from 'twenty-shared/utils';
import { IsNull, Not, Repository } from 'typeorm';
import { RedisPubSub } from 'graphql-redis-subscriptions';
import { Sources } from 'twenty-shared/types';
import {
DEFAULT_API_URL_NAME,
DEFAULT_API_KEY_NAME,
DEFAULT_API_URL_NAME,
} from 'twenty-shared/application';
import { FileStorageExceptionCode } from 'src/engine/core-modules/file-storage/interfaces/file-storage-exception';
@@ -36,11 +35,11 @@ import {
WorkflowVersionStepException,
WorkflowVersionStepExceptionCode,
} from 'src/modules/workflow/common/exceptions/workflow-version-step.exception';
import { SERVERLESS_FUNCTION_LOGS_TRIGGER } from 'src/engine/metadata-modules/serverless-function/constants/serverless-function-logs-trigger';
import { ApplicationTokenService } from 'src/engine/core-modules/auth/token/services/application-token.service';
import { buildEnvVar } from 'src/engine/core-modules/serverless/drivers/utils/build-env-var';
import { AccessTokenService } from 'src/engine/core-modules/auth/token/services/access-token.service';
import { cleanServerUrl } from 'src/utils/clean-server-url';
import { SubscriptionService } from 'src/engine/subscriptions/subscription.service';
import { SubscriptionChannel } from 'src/engine/subscriptions/enums/subscription-channel.enum';
const MIN_TOKEN_EXPIRATION_IN_SECONDS = 5;
@@ -55,10 +54,8 @@ export class ServerlessFunctionService {
private readonly throttlerService: ThrottlerService,
private readonly twentyConfigService: TwentyConfigService,
private readonly auditService: AuditService,
private readonly accessTokenService: AccessTokenService,
private readonly applicationTokenService: ApplicationTokenService,
@Inject('PUB_SUB')
private readonly pubSub: RedisPubSub,
private readonly subscriptionService: SubscriptionService,
) {}
async hasServerlessFunctionPublishedVersion(serverlessFunctionId: string) {
@@ -166,15 +163,19 @@ export class ServerlessFunctionService {
console.log(resultServerlessFunction.logs);
}
await this.pubSub.publish(SERVERLESS_FUNCTION_LOGS_TRIGGER, {
serverlessFunctionLogs: {
logs: resultServerlessFunction.logs,
id: functionToExecute.id,
name: functionToExecute.name,
universalIdentifier: functionToExecute.universalIdentifier,
applicationId: functionToExecute.applicationId,
applicationUniversalIdentifier:
functionToExecute.application?.universalIdentifier,
await this.subscriptionService.publish({
channel: SubscriptionChannel.SERVERLESS_FUNCTION_LOGS_CHANNEL,
workspaceId,
payload: {
serverlessFunctionLogs: {
logs: resultServerlessFunction.logs,
id: functionToExecute.id,
name: functionToExecute.name,
universalIdentifier: functionToExecute.universalIdentifier,
applicationId: functionToExecute.applicationId,
applicationUniversalIdentifier:
functionToExecute.application?.universalIdentifier,
},
},
});