import { BadRequestException, ForbiddenException, Injectable, NotFoundException, } from '@nestjs/common'; import { groupBy } from 'lodash'; import { WorkspacePreQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/interfaces/workspace-pre-query-hook.interface'; import { FindManyResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; import { MessageChannelMessageAssociationService } from 'src/modules/messaging/repositories/message-channel-message-association/message-channel-message-association.service'; import { MessageChannelService } from 'src/modules/messaging/repositories/message-channel/message-channel.service'; import { ConnectedAccountService } from 'src/modules/connected-account/repositories/connected-account/connected-account.service'; import { WorkspaceMemberService } from 'src/modules/workspace-member/repositories/workspace-member/workspace-member.service'; @Injectable() export class MessageFindManyPreQueryHook implements WorkspacePreQueryHook { constructor( private readonly messageChannelMessageAssociationService: MessageChannelMessageAssociationService, private readonly messageChannelService: MessageChannelService, private readonly connectedAccountService: ConnectedAccountService, private readonly workspaceMemberService: WorkspaceMemberService, ) {} async execute( userId: string, workspaceId: string, payload: FindManyResolverArgs, ): Promise { if (!payload?.filter?.messageThreadId?.eq) { throw new BadRequestException('messageThreadId filter is required'); } const messageChannelMessageAssociations = await this.messageChannelMessageAssociationService.getByMessageThreadId( payload?.filter?.messageThreadId?.eq, workspaceId, ); if (messageChannelMessageAssociations.length === 0) { throw new NotFoundException(); } await this.canAccessMessageThread( userId, workspaceId, messageChannelMessageAssociations, ); } private async canAccessMessageThread( userId: string, workspaceId: string, messageChannelMessageAssociations: any[], ) { const messageChannels = await this.messageChannelService.getByIds( messageChannelMessageAssociations.map( (association) => association.messageChannelId, ), workspaceId, ); const messageChannelsGroupByVisibility = groupBy( messageChannels, (channel) => channel.visibility, ); if (messageChannelsGroupByVisibility.share_everything) { return; } const currentWorkspaceMember = await this.workspaceMemberService.getByIdOrFail(userId, workspaceId); const messageChannelsConnectedAccounts = await this.connectedAccountService.getByIds( messageChannels.map((channel) => channel.connectedAccountId), workspaceId, ); const messageChannelsWorkspaceMemberIds = messageChannelsConnectedAccounts.map( (connectedAccount) => connectedAccount.accountOwnerId, ); if (messageChannelsWorkspaceMemberIds.includes(currentWorkspaceMember.id)) { return; } throw new ForbiddenException(); } }