Stop rejecting application token on calendar and message events requests (#20440)

fixes https://github.com/twentyhq/twenty/issues/20423 by authorizing
application token to perform calendarEvents and message queries
This commit is contained in:
martmull
2026-05-11 15:24:24 +02:00
committed by GitHub
parent 8909badc59
commit e72a907baa
5 changed files with 35 additions and 40 deletions
@@ -118,6 +118,7 @@ export const validateOperationIsPermittedOrThrow = ({
objectMetadata.universalIdentifier ===
WORKSPACE_MEMBER_OBJECT_UNIVERSAL_IDENTIFIER;
// TODO: this should be improved, we may have more complex permission configuration for is system objects
if (objectMetadataIsSystem && !isWorkspaceMemberObject) {
return;
}
@@ -5,9 +5,10 @@ import { WorkspaceQueryHookType } from 'src/engine/api/graphql/workspace-query-r
import { isUserAuthContext } from 'src/engine/core-modules/auth/guards/is-user-auth-context.guard';
import { type WorkspaceAuthContext } from 'src/engine/core-modules/auth/types/workspace-auth-context.type';
import { ForbiddenError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
import { TWENTY_STANDARD_APPLICATION } from 'src/engine/workspace-manager/twenty-standard-application/constants/twenty-standard-applications';
import { ApplyCalendarEventsVisibilityRestrictionsService } from 'src/modules/calendar/common/query-hooks/calendar-event/services/apply-calendar-events-visibility-restrictions.service';
import { type CalendarEventWorkspaceEntity } from 'src/modules/calendar/common/standard-objects/calendar-event.workspace-entity';
import { isApiKeyAuthContext } from 'src/engine/core-modules/auth/guards/is-api-key-auth-context.guard';
import { isApplicationAuthContext } from 'src/engine/core-modules/auth/guards/is-application-auth-context.guard';
@WorkspaceQueryHook({
key: `calendarEvent.findMany`,
@@ -28,17 +29,15 @@ export class CalendarEventFindManyPostQueryHook
const isUserContext = isUserAuthContext(authContext);
const userId = isUserContext ? authContext.user.id : undefined;
const isTwentyStandardApplication =
authContext.type === 'application' &&
authContext.application.universalIdentifier ===
TWENTY_STANDARD_APPLICATION.universalIdentifier;
// TODO: this check should be removed
if (
!isUserContext &&
authContext.type !== 'apiKey' &&
!isTwentyStandardApplication
!isUserAuthContext(authContext) &&
!isApiKeyAuthContext(authContext) &&
!isApplicationAuthContext(authContext)
) {
throw new ForbiddenError('Authentication is required');
throw new ForbiddenError(
'Authentication error, auth context should be user, apiKey or application',
);
}
const workspace = authContext.workspace;
@@ -5,9 +5,10 @@ import { WorkspaceQueryHookType } from 'src/engine/api/graphql/workspace-query-r
import { isUserAuthContext } from 'src/engine/core-modules/auth/guards/is-user-auth-context.guard';
import { type WorkspaceAuthContext } from 'src/engine/core-modules/auth/types/workspace-auth-context.type';
import { ForbiddenError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
import { TWENTY_STANDARD_APPLICATION } from 'src/engine/workspace-manager/twenty-standard-application/constants/twenty-standard-applications';
import { ApplyCalendarEventsVisibilityRestrictionsService } from 'src/modules/calendar/common/query-hooks/calendar-event/services/apply-calendar-events-visibility-restrictions.service';
import { type CalendarEventWorkspaceEntity } from 'src/modules/calendar/common/standard-objects/calendar-event.workspace-entity';
import { isApiKeyAuthContext } from 'src/engine/core-modules/auth/guards/is-api-key-auth-context.guard';
import { isApplicationAuthContext } from 'src/engine/core-modules/auth/guards/is-application-auth-context.guard';
@WorkspaceQueryHook({
key: `calendarEvent.findOne`,
@@ -28,17 +29,15 @@ export class CalendarEventFindOnePostQueryHook
const isUserContext = isUserAuthContext(authContext);
const userId = isUserContext ? authContext.user.id : undefined;
const isTwentyStandardApplication =
authContext.type === 'application' &&
authContext.application.universalIdentifier ===
TWENTY_STANDARD_APPLICATION.universalIdentifier;
// TODO: this check should be removed
if (
!isUserContext &&
authContext.type !== 'apiKey' &&
!isTwentyStandardApplication
!isUserAuthContext(authContext) &&
!isApiKeyAuthContext(authContext) &&
!isApplicationAuthContext(authContext)
) {
throw new ForbiddenError('Authentication is required');
throw new ForbiddenError(
'Authentication error, auth context should be user, apiKey or application',
);
}
const workspace = authContext.workspace;
@@ -5,9 +5,10 @@ import { WorkspaceQueryHookType } from 'src/engine/api/graphql/workspace-query-r
import { isUserAuthContext } from 'src/engine/core-modules/auth/guards/is-user-auth-context.guard';
import { type WorkspaceAuthContext } from 'src/engine/core-modules/auth/types/workspace-auth-context.type';
import { ForbiddenError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
import { TWENTY_STANDARD_APPLICATION } from 'src/engine/workspace-manager/twenty-standard-application/constants/twenty-standard-applications';
import { ApplyMessagesVisibilityRestrictionsService } from 'src/modules/messaging/common/query-hooks/message/apply-messages-visibility-restrictions.service';
import { type MessageWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message.workspace-entity';
import { isApiKeyAuthContext } from 'src/engine/core-modules/auth/guards/is-api-key-auth-context.guard';
import { isApplicationAuthContext } from 'src/engine/core-modules/auth/guards/is-application-auth-context.guard';
@WorkspaceQueryHook({
key: `message.findMany`,
@@ -25,17 +26,15 @@ export class MessageFindManyPostQueryHook
_objectName: string,
payload: MessageWorkspaceEntity[],
): Promise<void> {
const isTwentyStandardApplication =
authContext.type === 'application' &&
authContext.application.universalIdentifier ===
TWENTY_STANDARD_APPLICATION.universalIdentifier;
// TODO: this check should be removed
if (
authContext.type !== 'user' &&
authContext.type !== 'apiKey' &&
!isTwentyStandardApplication
!isUserAuthContext(authContext) &&
!isApiKeyAuthContext(authContext) &&
!isApplicationAuthContext(authContext)
) {
throw new ForbiddenError('Authentication is required');
throw new ForbiddenError(
'Authentication error, auth context should be user, apiKey or application',
);
}
const workspace = authContext.workspace;
@@ -2,14 +2,13 @@ import { type WorkspacePostQueryHookInstance } from 'src/engine/api/graphql/work
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 { isApiKeyAuthContext } from 'src/engine/core-modules/auth/guards/is-api-key-auth-context.guard';
import { isApplicationAuthContext } from 'src/engine/core-modules/auth/guards/is-application-auth-context.guard';
import { isUserAuthContext } from 'src/engine/core-modules/auth/guards/is-user-auth-context.guard';
import { type WorkspaceAuthContext } from 'src/engine/core-modules/auth/types/workspace-auth-context.type';
import { ForbiddenError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
import { TWENTY_STANDARD_APPLICATION } from 'src/engine/workspace-manager/twenty-standard-application/constants/twenty-standard-applications';
import { ApplyMessagesVisibilityRestrictionsService } from 'src/modules/messaging/common/query-hooks/message/apply-messages-visibility-restrictions.service';
import { type MessageWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message.workspace-entity';
import { isApiKeyAuthContext } from 'src/engine/core-modules/auth/guards/is-api-key-auth-context.guard';
import { isApplicationAuthContext } from 'src/engine/core-modules/auth/guards/is-application-auth-context.guard';
@WorkspaceQueryHook({
key: `message.findOne`,
@@ -27,17 +26,15 @@ export class MessageFindOnePostQueryHook
_objectName: string,
payload: MessageWorkspaceEntity[],
): Promise<void> {
const isTwentyStandardApplication =
isApplicationAuthContext(authContext) &&
authContext.application.universalIdentifier ===
TWENTY_STANDARD_APPLICATION.universalIdentifier;
// TODO: this check should be removed
if (
!isUserAuthContext(authContext) &&
!isApiKeyAuthContext(authContext) &&
!isTwentyStandardApplication
!isApplicationAuthContext(authContext)
) {
throw new ForbiddenError('Authentication is required');
throw new ForbiddenError(
'Authentication error, auth context should be user, apiKey or application',
);
}
const workspace = authContext.workspace;