fix calendar events and messages post hooks (#12034)
Context workspaceMemberId is not always present in AuthContext. Solution implemented here is to fetch workspaceMemberId via userId. QRQC coming ... Tested - FindManyCalendarEvents / FindOneCalendarEvent - FindManyMessages / FindOneMessage closes https://github.com/twentyhq/twenty/issues/12027
This commit is contained in:
@ -1,9 +1,11 @@
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { WorkspacePostQueryHookInstance } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/interfaces/workspace-query-hook.interface';
|
||||
|
||||
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
|
||||
import { WorkspaceQueryHookType } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/types/workspace-query-hook.type';
|
||||
import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
|
||||
import { UserInputError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||
import { ForbiddenError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||
import { ApplyCalendarEventsVisibilityRestrictionsService } from 'src/modules/calendar/common/query-hooks/calendar-event/services/apply-calendar-events-visibility-restrictions.service';
|
||||
import { CalendarEventWorkspaceEntity } from 'src/modules/calendar/common/standard-objects/calendar-event.workspace-entity';
|
||||
|
||||
@ -23,13 +25,15 @@ export class CalendarEventFindManyPostQueryHook
|
||||
_objectName: string,
|
||||
payload: CalendarEventWorkspaceEntity[],
|
||||
): Promise<void> {
|
||||
if (!authContext.workspaceMemberId) {
|
||||
throw new UserInputError('Workspace member id is required');
|
||||
const { user, apiKey } = authContext;
|
||||
|
||||
if (!isDefined(user) && !isDefined(apiKey)) {
|
||||
throw new ForbiddenError('User is required');
|
||||
}
|
||||
|
||||
await this.applyCalendarEventsVisibilityRestrictionsService.applyCalendarEventsVisibilityRestrictions(
|
||||
authContext.workspaceMemberId,
|
||||
payload,
|
||||
user?.id,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { WorkspacePostQueryHookInstance } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/interfaces/workspace-query-hook.interface';
|
||||
|
||||
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
|
||||
import { WorkspaceQueryHookType } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/types/workspace-query-hook.type';
|
||||
import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
|
||||
import { UserInputError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||
import { ForbiddenError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||
import { ApplyCalendarEventsVisibilityRestrictionsService } from 'src/modules/calendar/common/query-hooks/calendar-event/services/apply-calendar-events-visibility-restrictions.service';
|
||||
import { CalendarEventWorkspaceEntity } from 'src/modules/calendar/common/standard-objects/calendar-event.workspace-entity';
|
||||
|
||||
@ -23,13 +25,15 @@ export class CalendarEventFindOnePostQueryHook
|
||||
_objectName: string,
|
||||
payload: CalendarEventWorkspaceEntity[],
|
||||
): Promise<void> {
|
||||
if (!authContext.workspaceMemberId) {
|
||||
throw new UserInputError('Workspace member id is required');
|
||||
const { user, apiKey } = authContext;
|
||||
|
||||
if (!isDefined(user) && !isDefined(apiKey)) {
|
||||
throw new ForbiddenError('User is required');
|
||||
}
|
||||
|
||||
await this.applyCalendarEventsVisibilityRestrictionsService.applyCalendarEventsVisibilityRestrictions(
|
||||
authContext.workspaceMemberId,
|
||||
payload,
|
||||
user?.id,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,6 +48,10 @@ describe('ApplyCalendarEventsVisibilityRestrictionsService', () => {
|
||||
find: jest.fn(),
|
||||
};
|
||||
|
||||
const mockWorkspaceMemberRepository = {
|
||||
findOneByOrFail: jest.fn(),
|
||||
};
|
||||
|
||||
const mockTwentyORMManager = {
|
||||
getRepository: jest.fn().mockImplementation((name) => {
|
||||
if (name === 'calendarChannelEventAssociation') {
|
||||
@ -56,6 +60,9 @@ describe('ApplyCalendarEventsVisibilityRestrictionsService', () => {
|
||||
if (name === 'connectedAccount') {
|
||||
return mockConnectedAccountRepository;
|
||||
}
|
||||
if (name === 'workspaceMember') {
|
||||
return mockWorkspaceMemberRepository;
|
||||
}
|
||||
}),
|
||||
};
|
||||
|
||||
@ -83,6 +90,10 @@ describe('ApplyCalendarEventsVisibilityRestrictionsService', () => {
|
||||
createMockCalendarEvent('1', 'Test Event', 'Test Description'),
|
||||
];
|
||||
|
||||
mockWorkspaceMemberRepository.findOneByOrFail.mockResolvedValue({
|
||||
id: 'workspace-member-id',
|
||||
});
|
||||
|
||||
mockCalendarEventAssociationRepository.find.mockResolvedValue([
|
||||
{
|
||||
calendarEventId: '1',
|
||||
@ -94,8 +105,8 @@ describe('ApplyCalendarEventsVisibilityRestrictionsService', () => {
|
||||
]);
|
||||
|
||||
const result = await service.applyCalendarEventsVisibilityRestrictions(
|
||||
'workspace-member-id',
|
||||
calendarEvents,
|
||||
'user-id',
|
||||
);
|
||||
|
||||
expect(result).toEqual(calendarEvents);
|
||||
@ -124,11 +135,15 @@ describe('ApplyCalendarEventsVisibilityRestrictionsService', () => {
|
||||
},
|
||||
]);
|
||||
|
||||
mockWorkspaceMemberRepository.findOneByOrFail.mockResolvedValue({
|
||||
id: 'workspace-member-id',
|
||||
});
|
||||
|
||||
mockConnectedAccountRepository.find.mockResolvedValue([]);
|
||||
|
||||
const result = await service.applyCalendarEventsVisibilityRestrictions(
|
||||
'workspace-member-id',
|
||||
calendarEvents,
|
||||
'user-id',
|
||||
);
|
||||
|
||||
expect(result).toEqual([
|
||||
@ -155,11 +170,15 @@ describe('ApplyCalendarEventsVisibilityRestrictionsService', () => {
|
||||
},
|
||||
]);
|
||||
|
||||
mockWorkspaceMemberRepository.findOneByOrFail.mockResolvedValue({
|
||||
id: 'workspace-member-account-owner-id',
|
||||
});
|
||||
|
||||
mockConnectedAccountRepository.find.mockResolvedValue([{ id: '1' }]);
|
||||
|
||||
const result = await service.applyCalendarEventsVisibilityRestrictions(
|
||||
'workspace-member-id',
|
||||
calendarEvents,
|
||||
'user-id',
|
||||
);
|
||||
|
||||
expect(result).toEqual(calendarEvents);
|
||||
@ -186,11 +205,15 @@ describe('ApplyCalendarEventsVisibilityRestrictionsService', () => {
|
||||
},
|
||||
]);
|
||||
|
||||
mockWorkspaceMemberRepository.findOneByOrFail.mockResolvedValue({
|
||||
id: 'workspace-member-not-account-owner-id',
|
||||
});
|
||||
|
||||
mockConnectedAccountRepository.find.mockResolvedValue([]);
|
||||
|
||||
const result = await service.applyCalendarEventsVisibilityRestrictions(
|
||||
'workspace-member-id',
|
||||
calendarEvents,
|
||||
'user-id',
|
||||
);
|
||||
|
||||
expect(result).toEqual([]);
|
||||
@ -203,6 +226,10 @@ describe('ApplyCalendarEventsVisibilityRestrictionsService', () => {
|
||||
createMockCalendarEvent('3', 'Event 3', 'Description 3'),
|
||||
];
|
||||
|
||||
mockWorkspaceMemberRepository.findOneByOrFail.mockResolvedValue({
|
||||
id: 'workspace-member-id',
|
||||
});
|
||||
|
||||
mockCalendarEventAssociationRepository.find.mockResolvedValue([
|
||||
{
|
||||
calendarEventId: '1',
|
||||
@ -232,8 +259,63 @@ describe('ApplyCalendarEventsVisibilityRestrictionsService', () => {
|
||||
.mockResolvedValueOnce([{ id: '1' }]); // request for calendar event 2
|
||||
|
||||
const result = await service.applyCalendarEventsVisibilityRestrictions(
|
||||
'workspace-member-id',
|
||||
calendarEvents,
|
||||
'user-id',
|
||||
);
|
||||
|
||||
expect(result).toEqual([
|
||||
calendarEvents[0],
|
||||
calendarEvents[1],
|
||||
{
|
||||
...calendarEvents[2],
|
||||
title: FIELD_RESTRICTED_ADDITIONAL_PERMISSIONS_REQUIRED,
|
||||
description: FIELD_RESTRICTED_ADDITIONAL_PERMISSIONS_REQUIRED,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should return all calendar events with the right visibility when userId is undefined (api key request)', async () => {
|
||||
const calendarEvents = [
|
||||
createMockCalendarEvent('1', 'Event 1', 'Description 1'),
|
||||
createMockCalendarEvent('2', 'Event 2', 'Description 2'),
|
||||
createMockCalendarEvent('3', 'Event 3', 'Description 3'),
|
||||
];
|
||||
|
||||
mockWorkspaceMemberRepository.findOneByOrFail.mockResolvedValue({
|
||||
id: 'workspace-member-id',
|
||||
});
|
||||
|
||||
mockCalendarEventAssociationRepository.find.mockResolvedValue([
|
||||
{
|
||||
calendarEventId: '1',
|
||||
calendarChannel: {
|
||||
id: '1',
|
||||
visibility: CalendarChannelVisibility.SHARE_EVERYTHING,
|
||||
},
|
||||
},
|
||||
{
|
||||
calendarEventId: '2',
|
||||
calendarChannel: {
|
||||
id: '2',
|
||||
visibility: CalendarChannelVisibility.METADATA,
|
||||
},
|
||||
},
|
||||
{
|
||||
calendarEventId: '3',
|
||||
calendarChannel: {
|
||||
id: '3',
|
||||
visibility: CalendarChannelVisibility.METADATA,
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
mockConnectedAccountRepository.find
|
||||
.mockResolvedValueOnce([]) // request for calendar event 3
|
||||
.mockResolvedValueOnce([{ id: '1' }]); // request for calendar event 2
|
||||
|
||||
const result = await service.applyCalendarEventsVisibilityRestrictions(
|
||||
calendarEvents,
|
||||
undefined,
|
||||
);
|
||||
|
||||
expect(result).toEqual([
|
||||
|
||||
@ -2,6 +2,7 @@ import { Injectable } from '@nestjs/common';
|
||||
|
||||
import groupBy from 'lodash.groupby';
|
||||
import { FIELD_RESTRICTED_ADDITIONAL_PERMISSIONS_REQUIRED } from 'twenty-shared/constants';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { In } from 'typeorm';
|
||||
|
||||
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||
@ -9,14 +10,15 @@ import { CalendarChannelEventAssociationWorkspaceEntity } from 'src/modules/cale
|
||||
import { CalendarChannelVisibility } from 'src/modules/calendar/common/standard-objects/calendar-channel.workspace-entity';
|
||||
import { CalendarEventWorkspaceEntity } from 'src/modules/calendar/common/standard-objects/calendar-event.workspace-entity';
|
||||
import { ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity';
|
||||
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
|
||||
|
||||
@Injectable()
|
||||
export class ApplyCalendarEventsVisibilityRestrictionsService {
|
||||
constructor(private readonly twentyORMManager: TwentyORMManager) {}
|
||||
|
||||
public async applyCalendarEventsVisibilityRestrictions(
|
||||
workspaceMemberId: string,
|
||||
calendarEvents: CalendarEventWorkspaceEntity[],
|
||||
userId?: string, // undefined when request is made with api key
|
||||
) {
|
||||
const calendarChannelEventAssociationRepository =
|
||||
await this.twentyORMManager.getRepository<CalendarChannelEventAssociationWorkspaceEntity>(
|
||||
@ -36,6 +38,11 @@ export class ApplyCalendarEventsVisibilityRestrictionsService {
|
||||
'connectedAccount',
|
||||
);
|
||||
|
||||
const workspaceMemberRepository =
|
||||
await this.twentyORMManager.getRepository<WorkspaceMemberWorkspaceEntity>(
|
||||
'workspaceMember',
|
||||
);
|
||||
|
||||
for (let i = calendarEvents.length - 1; i >= 0; i--) {
|
||||
const calendarChannelCalendarEventAssociations =
|
||||
calendarChannelCalendarEventsAssociations.filter(
|
||||
@ -59,18 +66,26 @@ export class ApplyCalendarEventsVisibilityRestrictionsService {
|
||||
continue;
|
||||
}
|
||||
|
||||
const connectedAccounts = await connectedAccountRepository.find({
|
||||
select: ['id'],
|
||||
where: {
|
||||
calendarChannels: {
|
||||
id: In(calendarChannels.map((channel) => channel.id)),
|
||||
if (isDefined(userId)) {
|
||||
const workspaceMember = await workspaceMemberRepository.findOneByOrFail(
|
||||
{
|
||||
userId: userId,
|
||||
},
|
||||
accountOwnerId: workspaceMemberId,
|
||||
},
|
||||
});
|
||||
);
|
||||
|
||||
if (connectedAccounts.length > 0) {
|
||||
continue;
|
||||
const connectedAccounts = await connectedAccountRepository.find({
|
||||
select: ['id'],
|
||||
where: {
|
||||
calendarChannels: {
|
||||
id: In(calendarChannels.map((channel) => channel.id)),
|
||||
},
|
||||
accountOwnerId: workspaceMember.id,
|
||||
},
|
||||
});
|
||||
|
||||
if (connectedAccounts.length > 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
|
||||
@ -38,6 +38,10 @@ describe('ApplyMessagesVisibilityRestrictionsService', () => {
|
||||
find: jest.fn(),
|
||||
};
|
||||
|
||||
const mockWorkspaceMemberRepository = {
|
||||
findOneByOrFail: jest.fn(),
|
||||
};
|
||||
|
||||
const mockTwentyORMManager = {
|
||||
getRepository: jest.fn().mockImplementation((name) => {
|
||||
if (name === 'messageChannelMessageAssociation') {
|
||||
@ -46,6 +50,9 @@ describe('ApplyMessagesVisibilityRestrictionsService', () => {
|
||||
if (name === 'connectedAccount') {
|
||||
return mockConnectedAccountRepository;
|
||||
}
|
||||
if (name === 'workspaceMember') {
|
||||
return mockWorkspaceMemberRepository;
|
||||
}
|
||||
}),
|
||||
};
|
||||
|
||||
@ -83,8 +90,8 @@ describe('ApplyMessagesVisibilityRestrictionsService', () => {
|
||||
]);
|
||||
|
||||
const result = await service.applyMessagesVisibilityRestrictions(
|
||||
'workspace-member-id',
|
||||
messages,
|
||||
'user-id',
|
||||
);
|
||||
|
||||
expect(result).toEqual(messages);
|
||||
@ -114,9 +121,13 @@ describe('ApplyMessagesVisibilityRestrictionsService', () => {
|
||||
|
||||
mockConnectedAccountRepository.find.mockResolvedValue([]);
|
||||
|
||||
mockWorkspaceMemberRepository.findOneByOrFail.mockResolvedValue({
|
||||
id: 'workspace-member-id',
|
||||
});
|
||||
|
||||
const result = await service.applyMessagesVisibilityRestrictions(
|
||||
'workspace-member-id',
|
||||
messages,
|
||||
'user-id',
|
||||
);
|
||||
|
||||
expect(result).toEqual([
|
||||
@ -144,9 +155,13 @@ describe('ApplyMessagesVisibilityRestrictionsService', () => {
|
||||
|
||||
mockConnectedAccountRepository.find.mockResolvedValue([]);
|
||||
|
||||
mockWorkspaceMemberRepository.findOneByOrFail.mockResolvedValue({
|
||||
id: 'workspace-member-id',
|
||||
});
|
||||
|
||||
const result = await service.applyMessagesVisibilityRestrictions(
|
||||
'workspace-member-id',
|
||||
messages,
|
||||
'user-id',
|
||||
);
|
||||
|
||||
expect(result).toEqual([
|
||||
@ -173,11 +188,15 @@ describe('ApplyMessagesVisibilityRestrictionsService', () => {
|
||||
},
|
||||
]);
|
||||
|
||||
mockWorkspaceMemberRepository.findOneByOrFail.mockResolvedValue({
|
||||
id: 'workspace-member-account-owner-id',
|
||||
});
|
||||
|
||||
mockConnectedAccountRepository.find.mockResolvedValue([{ id: '1' }]);
|
||||
|
||||
const result = await service.applyMessagesVisibilityRestrictions(
|
||||
'workspace-member-id',
|
||||
messages,
|
||||
'user-id',
|
||||
);
|
||||
|
||||
expect(result).toEqual(messages);
|
||||
@ -203,11 +222,15 @@ describe('ApplyMessagesVisibilityRestrictionsService', () => {
|
||||
},
|
||||
]);
|
||||
|
||||
mockWorkspaceMemberRepository.findOneByOrFail.mockResolvedValue({
|
||||
id: 'workspace-member-not-account-owner-id',
|
||||
});
|
||||
|
||||
mockConnectedAccountRepository.find.mockResolvedValue([]);
|
||||
|
||||
const result = await service.applyMessagesVisibilityRestrictions(
|
||||
'workspace-member-id',
|
||||
messages,
|
||||
'user-id',
|
||||
);
|
||||
|
||||
expect(result).toEqual([]);
|
||||
@ -244,13 +267,75 @@ describe('ApplyMessagesVisibilityRestrictionsService', () => {
|
||||
},
|
||||
]);
|
||||
|
||||
mockWorkspaceMemberRepository.findOneByOrFail.mockResolvedValue({
|
||||
id: 'workspace-member-id',
|
||||
});
|
||||
|
||||
mockConnectedAccountRepository.find
|
||||
.mockResolvedValueOnce([]) // request for message 3
|
||||
.mockResolvedValueOnce([]); // request for message 2
|
||||
|
||||
const result = await service.applyMessagesVisibilityRestrictions(
|
||||
'workspace-member-id',
|
||||
messages,
|
||||
'user-id',
|
||||
);
|
||||
|
||||
expect(result).toEqual([
|
||||
messages[0],
|
||||
{
|
||||
...messages[1],
|
||||
text: FIELD_RESTRICTED_ADDITIONAL_PERMISSIONS_REQUIRED,
|
||||
},
|
||||
{
|
||||
...messages[2],
|
||||
subject: FIELD_RESTRICTED_ADDITIONAL_PERMISSIONS_REQUIRED,
|
||||
text: FIELD_RESTRICTED_ADDITIONAL_PERMISSIONS_REQUIRED,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should return all messages with the right visibility when userId is undefined (api key request)', async () => {
|
||||
const messages = [
|
||||
createMockMessage('1', 'Subject 1', 'Message 1'),
|
||||
createMockMessage('2', 'Subject 2', 'Message 2'),
|
||||
createMockMessage('3', 'Subject 3', 'Message 3'),
|
||||
];
|
||||
|
||||
mockMessageChannelMessageAssociationRepository.find.mockResolvedValue([
|
||||
{
|
||||
messageId: '1',
|
||||
messageChannel: {
|
||||
id: '1',
|
||||
visibility: MessageChannelVisibility.SHARE_EVERYTHING,
|
||||
},
|
||||
},
|
||||
{
|
||||
messageId: '2',
|
||||
messageChannel: {
|
||||
id: '2',
|
||||
visibility: MessageChannelVisibility.SUBJECT,
|
||||
},
|
||||
},
|
||||
{
|
||||
messageId: '3',
|
||||
messageChannel: {
|
||||
id: '3',
|
||||
visibility: MessageChannelVisibility.METADATA,
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
mockWorkspaceMemberRepository.findOneByOrFail.mockResolvedValue({
|
||||
id: 'workspace-member-id',
|
||||
});
|
||||
|
||||
mockConnectedAccountRepository.find
|
||||
.mockResolvedValueOnce([]) // request for message 3
|
||||
.mockResolvedValueOnce([]); // request for message 2
|
||||
|
||||
const result = await service.applyMessagesVisibilityRestrictions(
|
||||
messages,
|
||||
undefined,
|
||||
);
|
||||
|
||||
expect(result).toEqual([
|
||||
|
||||
@ -2,6 +2,7 @@ import { Injectable } from '@nestjs/common';
|
||||
|
||||
import groupBy from 'lodash.groupby';
|
||||
import { FIELD_RESTRICTED_ADDITIONAL_PERMISSIONS_REQUIRED } from 'twenty-shared/constants';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { In } from 'typeorm';
|
||||
|
||||
import { NotFoundError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||
@ -10,14 +11,15 @@ import { ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/s
|
||||
import { MessageChannelMessageAssociationWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-channel-message-association.workspace-entity';
|
||||
import { MessageChannelVisibility } from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
|
||||
import { MessageWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message.workspace-entity';
|
||||
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
|
||||
|
||||
@Injectable()
|
||||
export class ApplyMessagesVisibilityRestrictionsService {
|
||||
constructor(private readonly twentyORMManager: TwentyORMManager) {}
|
||||
|
||||
public async applyMessagesVisibilityRestrictions(
|
||||
workspaceMemberId: string,
|
||||
messages: MessageWorkspaceEntity[],
|
||||
userId?: string, // undefined when request is made with api key
|
||||
) {
|
||||
const messageChannelMessageAssociationRepository =
|
||||
await this.twentyORMManager.getRepository<MessageChannelMessageAssociationWorkspaceEntity>(
|
||||
@ -37,6 +39,11 @@ export class ApplyMessagesVisibilityRestrictionsService {
|
||||
'connectedAccount',
|
||||
);
|
||||
|
||||
const workspaceMemberRepository =
|
||||
await this.twentyORMManager.getRepository<WorkspaceMemberWorkspaceEntity>(
|
||||
'workspaceMember',
|
||||
);
|
||||
|
||||
for (let i = messages.length - 1; i >= 0; i--) {
|
||||
const messageChannelMessageAssociations =
|
||||
messageChannelMessagesAssociations.filter(
|
||||
@ -66,19 +73,28 @@ export class ApplyMessagesVisibilityRestrictionsService {
|
||||
continue;
|
||||
}
|
||||
|
||||
const connectedAccounts = await connectedAccountRepository.find({
|
||||
select: ['id'],
|
||||
where: {
|
||||
messageChannels: {
|
||||
id: In(messageChannels.map((channel) => channel.id)),
|
||||
if (isDefined(userId)) {
|
||||
const workspaceMember = await workspaceMemberRepository.findOneByOrFail(
|
||||
{
|
||||
userId,
|
||||
},
|
||||
accountOwnerId: workspaceMemberId,
|
||||
},
|
||||
});
|
||||
);
|
||||
|
||||
if (connectedAccounts.length > 0) {
|
||||
continue;
|
||||
const connectedAccounts = await connectedAccountRepository.find({
|
||||
select: ['id'],
|
||||
where: {
|
||||
messageChannels: {
|
||||
id: In(messageChannels.map((channel) => channel.id)),
|
||||
},
|
||||
accountOwnerId: workspaceMember.id,
|
||||
},
|
||||
});
|
||||
|
||||
if (connectedAccounts.length > 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (messageChannelsGroupByVisibility[MessageChannelVisibility.SUBJECT]) {
|
||||
messages[i].text = FIELD_RESTRICTED_ADDITIONAL_PERMISSIONS_REQUIRED;
|
||||
continue;
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { WorkspacePostQueryHookInstance } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/interfaces/workspace-query-hook.interface';
|
||||
|
||||
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
|
||||
import { WorkspaceQueryHookType } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/types/workspace-query-hook.type';
|
||||
import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
|
||||
import { UserInputError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||
import { ForbiddenError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||
import { ApplyMessagesVisibilityRestrictionsService } from 'src/modules/messaging/common/query-hooks/message/apply-messages-visibility-restrictions.service';
|
||||
import { MessageWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message.workspace-entity';
|
||||
|
||||
@ -23,13 +25,15 @@ export class MessageFindManyPostQueryHook
|
||||
_objectName: string,
|
||||
payload: MessageWorkspaceEntity[],
|
||||
): Promise<void> {
|
||||
if (!authContext.workspaceMemberId) {
|
||||
throw new UserInputError('Workspace member id is required');
|
||||
const { user, apiKey } = authContext;
|
||||
|
||||
if (!isDefined(user) && !isDefined(apiKey)) {
|
||||
throw new ForbiddenError('User is required');
|
||||
}
|
||||
|
||||
await this.applyMessagesVisibilityRestrictionsService.applyMessagesVisibilityRestrictions(
|
||||
authContext.workspaceMemberId,
|
||||
payload,
|
||||
user?.id,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { WorkspacePostQueryHookInstance } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/interfaces/workspace-query-hook.interface';
|
||||
|
||||
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
|
||||
import { WorkspaceQueryHookType } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/types/workspace-query-hook.type';
|
||||
import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
|
||||
import { UserInputError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||
import { ForbiddenError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||
import { ApplyMessagesVisibilityRestrictionsService } from 'src/modules/messaging/common/query-hooks/message/apply-messages-visibility-restrictions.service';
|
||||
import { MessageWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message.workspace-entity';
|
||||
|
||||
@ -23,13 +25,15 @@ export class MessageFindOnePostQueryHook
|
||||
_objectName: string,
|
||||
payload: MessageWorkspaceEntity[],
|
||||
): Promise<void> {
|
||||
if (!authContext.workspaceMemberId) {
|
||||
throw new UserInputError('Workspace member id is required');
|
||||
const { user, apiKey } = authContext;
|
||||
|
||||
if (!isDefined(user) && !isDefined(apiKey)) {
|
||||
throw new ForbiddenError('User is required');
|
||||
}
|
||||
|
||||
await this.applyMessagesVisibilityRestrictionsService.applyMessagesVisibilityRestrictions(
|
||||
authContext.workspaceMemberId,
|
||||
payload,
|
||||
user?.id,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user