fix(server): map PermissionsException to proper HTTP status on REST API (#20739)
## Summary `PermissionsException` thrown by `SettingsPermissionGuard` (and other permission code paths) was bubbling up through every typed REST exception filter and landing in the global `UnhandledExceptionFilter`, which falls back to **500** for anything that isn't an `HttpException`. So a forbidden user (e.g. an API key whose role doesn't have `DATA_MODEL`) calling `GET /rest/metadata/objects` got: ``` HTTP/1.1 500 Internal Server Error "Entity performing the request does not have permission" ``` GraphQL already had the right plumbing via `permissionGraphqlApiExceptionHandler` (`ForbiddenError` → 403, `UserInputError` → 400, `NotFoundError` → 404). This PR mirrors it on the REST side. ## What - New util `permissionRestApiExceptionCodeToHttpStatus` mapping every `PermissionsExceptionCode` → HTTP status, with `assertUnreachable` to force explicit handling of future codes. - New filter `PermissionsRestApiExceptionFilter` (`@Catch(PermissionsException)`) that delegates to `HttpExceptionHandlerService.handleError(...)` with the resolved status. - Wired `PermissionsRestApiExceptionFilter` (placed first, so the typed filter wins over any sibling catch-all) into `@UseFilters(...)` of every REST controller that uses `SettingsPermissionGuard` or whose service can throw `PermissionsException`: - `object-metadata`, `field-metadata`, `webhook`, `api-key` - `view`, `view-sort`, `view-group`, `view-filter`, `view-filter-group`, `view-field` - `page-layout`, `page-layout-widget`, `page-layout-tab` - `front-component`, `ai-generate-text` - Unit tests covering 403 / 400 / 404 / 500 mappings. ## Mapping | Code | Status | |------|--------| | `PERMISSION_DENIED`, `NO_AUTHENTICATION_CONTEXT`, `ROLE_LABEL_ALREADY_EXISTS`, `CANNOT_UNASSIGN_LAST_ADMIN`, `CANNOT_UPDATE_SELF_ROLE`, `CANNOT_DELETE_LAST_ADMIN_USER`, `ROLE_NOT_EDITABLE`, `CANNOT_ADD_OBJECT_PERMISSION_ON_SYSTEM_OBJECT`, `CANNOT_ADD_FIELD_PERMISSION_ON_SYSTEM_OBJECT` | **403** | | `INVALID_ARG`, `INVALID_SETTING`, `CANNOT_GIVE_WRITING_PERMISSION_ON_NON_READABLE_OBJECT`, `CANNOT_GIVE_WRITING_PERMISSION_WITHOUT_READING_PERMISSION`, `ONLY_FIELD_RESTRICTION_ALLOWED`, `FIELD_RESTRICTION_ONLY_ALLOWED_ON_READABLE_OBJECT`, `FIELD_RESTRICTION_ON_UPDATE_ONLY_ALLOWED_ON_UPDATABLE_OBJECT`, `EMPTY_FIELD_PERMISSION_NOT_ALLOWED`, `ROLE_MUST_HAVE_AT_LEAST_ONE_TARGET`, `ROLE_CANNOT_BE_ASSIGNED_TO_USERS` | **400** | | `ROLE_NOT_FOUND`, `OBJECT_METADATA_NOT_FOUND`, `FIELD_METADATA_NOT_FOUND`, `FIELD_PERMISSION_NOT_FOUND`, `PERMISSION_NOT_FOUND` | **404** | | All remaining "internal" codes (rethrown as-is in GraphQL) | **500** | ## Before <img width="507" height="216" alt="Screenshot 2026-05-19 at 19 26 07" src="https://github.com/user-attachments/assets/21d633aa-7ee8-4923-94e4-7ad57258a29e" /> ## After <img width="610" height="385" alt="Screenshot 2026-05-19 at 19 26 01" src="https://github.com/user-attachments/assets/0103b7ee-7df7-4aef-999a-73c22901afd2" />
This commit is contained in:
+2
-1
@@ -23,6 +23,7 @@ import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorat
|
||||
import { JwtAuthGuard } from 'src/engine/guards/jwt-auth.guard';
|
||||
import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard';
|
||||
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
|
||||
import { PermissionsRestApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-rest-api-exception.filter';
|
||||
|
||||
/**
|
||||
* rest/apiKeys is deprecated, use rest/metadata/apiKeys instead
|
||||
@@ -34,7 +35,7 @@ import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
|
||||
WorkspaceAuthGuard,
|
||||
SettingsPermissionGuard(PermissionFlagType.API_KEYS_AND_WEBHOOKS),
|
||||
)
|
||||
@UseFilters(RestApiExceptionFilter)
|
||||
@UseFilters(PermissionsRestApiExceptionFilter, RestApiExceptionFilter)
|
||||
export class ApiKeyController {
|
||||
constructor(private readonly apiKeyService: ApiKeyService) {}
|
||||
|
||||
|
||||
+6
-1
@@ -20,10 +20,15 @@ import { AiBillingService } from 'src/engine/metadata-modules/ai/ai-billing/serv
|
||||
import { AiRestApiExceptionFilter } from 'src/engine/metadata-modules/ai/filters/ai-api-exception.filter';
|
||||
import { GenerateTextInput } from 'src/engine/metadata-modules/ai/ai-generate-text/dtos/generate-text.input';
|
||||
import { AiModelRegistryService } from 'src/engine/metadata-modules/ai/ai-models/services/ai-model-registry.service';
|
||||
import { PermissionsRestApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-rest-api-exception.filter';
|
||||
|
||||
@Controller('rest/ai')
|
||||
@UseGuards(JwtAuthGuard, WorkspaceAuthGuard)
|
||||
@UseFilters(AiRestApiExceptionFilter, RestApiExceptionFilter)
|
||||
@UseFilters(
|
||||
PermissionsRestApiExceptionFilter,
|
||||
AiRestApiExceptionFilter,
|
||||
RestApiExceptionFilter,
|
||||
)
|
||||
export class AiGenerateTextController {
|
||||
constructor(
|
||||
private readonly aiModelRegistryService: AiModelRegistryService,
|
||||
|
||||
+5
-1
@@ -53,6 +53,7 @@ import {
|
||||
toLegacyFieldMetadataUpdateResponse,
|
||||
} from 'src/engine/metadata-modules/field-metadata/utils/to-legacy-field-metadata-response.util';
|
||||
import { fromFlatFieldMetadataToFieldMetadataDto } from 'src/engine/metadata-modules/flat-field-metadata/utils/from-flat-field-metadata-to-field-metadata-dto.util';
|
||||
import { PermissionsRestApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-rest-api-exception.filter';
|
||||
|
||||
@Controller('rest/metadata/fields')
|
||||
@UseGuards(
|
||||
@@ -60,7 +61,10 @@ import { fromFlatFieldMetadataToFieldMetadataDto } from 'src/engine/metadata-mod
|
||||
WorkspaceAuthGuard,
|
||||
SettingsPermissionGuard(PermissionFlagType.DATA_MODEL),
|
||||
)
|
||||
@UseFilters(FieldMetadataRestApiExceptionFilter)
|
||||
@UseFilters(
|
||||
PermissionsRestApiExceptionFilter,
|
||||
FieldMetadataRestApiExceptionFilter,
|
||||
)
|
||||
@UsePipes(new ValidationPipe())
|
||||
export class FieldMetadataController {
|
||||
constructor(
|
||||
|
||||
+2
@@ -27,11 +27,13 @@ import {
|
||||
FrontComponentExceptionCode,
|
||||
} from 'src/engine/metadata-modules/front-component/front-component.exception';
|
||||
import { FrontComponentService } from 'src/engine/metadata-modules/front-component/front-component.service';
|
||||
import { PermissionsRestApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-rest-api-exception.filter';
|
||||
import { WorkspaceMigrationRunnerRestApiExceptionFilter } from 'src/engine/workspace-manager/workspace-migration/filters/workspace-migration-runner-rest-api-exception.filter';
|
||||
|
||||
@Controller('rest/front-components')
|
||||
@UseGuards(WorkspaceAuthGuard)
|
||||
@UseFilters(
|
||||
PermissionsRestApiExceptionFilter,
|
||||
FrontComponentRestApiExceptionFilter,
|
||||
FlatEntityMapsRestApiExceptionFilter,
|
||||
WorkspaceMigrationRunnerRestApiExceptionFilter,
|
||||
|
||||
+5
-1
@@ -55,6 +55,7 @@ import {
|
||||
toLegacyObjectMetadataListResponse,
|
||||
toLegacyObjectMetadataUpdateResponse,
|
||||
} from 'src/engine/metadata-modules/object-metadata/utils/to-legacy-object-metadata-response.util';
|
||||
import { PermissionsRestApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-rest-api-exception.filter';
|
||||
|
||||
@Controller('rest/metadata/objects')
|
||||
@UseGuards(
|
||||
@@ -62,7 +63,10 @@ import {
|
||||
WorkspaceAuthGuard,
|
||||
SettingsPermissionGuard(PermissionFlagType.DATA_MODEL),
|
||||
)
|
||||
@UseFilters(ObjectMetadataRestApiExceptionFilter)
|
||||
@UseFilters(
|
||||
PermissionsRestApiExceptionFilter,
|
||||
ObjectMetadataRestApiExceptionFilter,
|
||||
)
|
||||
@UsePipes(new ValidationPipe())
|
||||
export class ObjectMetadataController {
|
||||
constructor(
|
||||
|
||||
+2
@@ -31,11 +31,13 @@ import {
|
||||
} from 'src/engine/metadata-modules/page-layout-tab/exceptions/page-layout-tab.exception';
|
||||
import { PageLayoutTabRestApiExceptionFilter } from 'src/engine/metadata-modules/page-layout-tab/filters/page-layout-tab-rest-api-exception.filter';
|
||||
import { PageLayoutTabService } from 'src/engine/metadata-modules/page-layout-tab/services/page-layout-tab.service';
|
||||
import { PermissionsRestApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-rest-api-exception.filter';
|
||||
import { WorkspaceMigrationRunnerRestApiExceptionFilter } from 'src/engine/workspace-manager/workspace-migration/filters/workspace-migration-runner-rest-api-exception.filter';
|
||||
|
||||
@Controller('rest/metadata/pageLayoutTabs')
|
||||
@UseGuards(WorkspaceAuthGuard)
|
||||
@UseFilters(
|
||||
PermissionsRestApiExceptionFilter,
|
||||
PageLayoutTabRestApiExceptionFilter,
|
||||
FlatEntityMapsRestApiExceptionFilter,
|
||||
WorkspaceMigrationRunnerRestApiExceptionFilter,
|
||||
|
||||
+2
@@ -31,11 +31,13 @@ import {
|
||||
} from 'src/engine/metadata-modules/page-layout-widget/exceptions/page-layout-widget.exception';
|
||||
import { PageLayoutWidgetRestApiExceptionFilter } from 'src/engine/metadata-modules/page-layout-widget/filters/page-layout-widget-rest-api-exception.filter';
|
||||
import { PageLayoutWidgetService } from 'src/engine/metadata-modules/page-layout-widget/services/page-layout-widget.service';
|
||||
import { PermissionsRestApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-rest-api-exception.filter';
|
||||
import { WorkspaceMigrationRunnerRestApiExceptionFilter } from 'src/engine/workspace-manager/workspace-migration/filters/workspace-migration-runner-rest-api-exception.filter';
|
||||
|
||||
@Controller('rest/metadata/pageLayoutWidgets')
|
||||
@UseGuards(WorkspaceAuthGuard)
|
||||
@UseFilters(
|
||||
PermissionsRestApiExceptionFilter,
|
||||
PageLayoutWidgetRestApiExceptionFilter,
|
||||
FlatEntityMapsRestApiExceptionFilter,
|
||||
WorkspaceMigrationRunnerRestApiExceptionFilter,
|
||||
|
||||
+2
@@ -26,11 +26,13 @@ import { type PageLayoutDTO } from 'src/engine/metadata-modules/page-layout/dtos
|
||||
import { PageLayoutType } from 'src/engine/metadata-modules/page-layout/enums/page-layout-type.enum';
|
||||
import { PageLayoutRestApiExceptionFilter } from 'src/engine/metadata-modules/page-layout/filters/page-layout-rest-api-exception.filter';
|
||||
import { PageLayoutService } from 'src/engine/metadata-modules/page-layout/services/page-layout.service';
|
||||
import { PermissionsRestApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-rest-api-exception.filter';
|
||||
import { WorkspaceMigrationRunnerRestApiExceptionFilter } from 'src/engine/workspace-manager/workspace-migration/filters/workspace-migration-runner-rest-api-exception.filter';
|
||||
|
||||
@Controller('rest/metadata/pageLayouts')
|
||||
@UseGuards(WorkspaceAuthGuard)
|
||||
@UseFilters(
|
||||
PermissionsRestApiExceptionFilter,
|
||||
PageLayoutRestApiExceptionFilter,
|
||||
FlatEntityMapsRestApiExceptionFilter,
|
||||
WorkspaceMigrationRunnerRestApiExceptionFilter,
|
||||
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
import { PermissionsExceptionCode } from 'src/engine/metadata-modules/permissions/permissions.exception';
|
||||
import { permissionRestApiExceptionCodeToHttpStatus } from 'src/engine/metadata-modules/permissions/utils/permission-rest-api-exception-code-to-http-status.util';
|
||||
|
||||
describe('permissionRestApiExceptionCodeToHttpStatus', () => {
|
||||
it('should return 403 for PERMISSION_DENIED', () => {
|
||||
expect(
|
||||
permissionRestApiExceptionCodeToHttpStatus(
|
||||
PermissionsExceptionCode.PERMISSION_DENIED,
|
||||
),
|
||||
).toBe(403);
|
||||
});
|
||||
|
||||
it('should return 403 for role-related forbidden cases', () => {
|
||||
expect(
|
||||
permissionRestApiExceptionCodeToHttpStatus(
|
||||
PermissionsExceptionCode.CANNOT_UPDATE_SELF_ROLE,
|
||||
),
|
||||
).toBe(403);
|
||||
});
|
||||
|
||||
it('should return 403 for NO_AUTHENTICATION_CONTEXT', () => {
|
||||
expect(
|
||||
permissionRestApiExceptionCodeToHttpStatus(
|
||||
PermissionsExceptionCode.NO_AUTHENTICATION_CONTEXT,
|
||||
),
|
||||
).toBe(403);
|
||||
});
|
||||
|
||||
it('should return 400 for INVALID_ARG', () => {
|
||||
expect(
|
||||
permissionRestApiExceptionCodeToHttpStatus(
|
||||
PermissionsExceptionCode.INVALID_ARG,
|
||||
),
|
||||
).toBe(400);
|
||||
});
|
||||
|
||||
it('should return 400 for permission validation errors', () => {
|
||||
expect(
|
||||
permissionRestApiExceptionCodeToHttpStatus(
|
||||
PermissionsExceptionCode.EMPTY_FIELD_PERMISSION_NOT_ALLOWED,
|
||||
),
|
||||
).toBe(400);
|
||||
});
|
||||
|
||||
it('should return 404 for ROLE_NOT_FOUND', () => {
|
||||
expect(
|
||||
permissionRestApiExceptionCodeToHttpStatus(
|
||||
PermissionsExceptionCode.ROLE_NOT_FOUND,
|
||||
),
|
||||
).toBe(404);
|
||||
});
|
||||
|
||||
it('should return 404 for metadata not found cases', () => {
|
||||
expect(
|
||||
permissionRestApiExceptionCodeToHttpStatus(
|
||||
PermissionsExceptionCode.OBJECT_METADATA_NOT_FOUND,
|
||||
),
|
||||
).toBe(404);
|
||||
});
|
||||
|
||||
it('should return 500 for METHOD_NOT_ALLOWED', () => {
|
||||
expect(
|
||||
permissionRestApiExceptionCodeToHttpStatus(
|
||||
PermissionsExceptionCode.METHOD_NOT_ALLOWED,
|
||||
),
|
||||
).toBe(500);
|
||||
});
|
||||
|
||||
it('should return 500 for internal error codes', () => {
|
||||
expect(
|
||||
permissionRestApiExceptionCodeToHttpStatus(
|
||||
PermissionsExceptionCode.DEFAULT_ROLE_NOT_FOUND,
|
||||
),
|
||||
).toBe(500);
|
||||
});
|
||||
});
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
import { assertUnreachable } from 'twenty-shared/utils';
|
||||
|
||||
import { PermissionsExceptionCode } from 'src/engine/metadata-modules/permissions/permissions.exception';
|
||||
|
||||
export const permissionRestApiExceptionCodeToHttpStatus = (
|
||||
code: PermissionsExceptionCode,
|
||||
): number => {
|
||||
switch (code) {
|
||||
case PermissionsExceptionCode.PERMISSION_DENIED:
|
||||
case PermissionsExceptionCode.NO_AUTHENTICATION_CONTEXT:
|
||||
case PermissionsExceptionCode.ROLE_LABEL_ALREADY_EXISTS:
|
||||
case PermissionsExceptionCode.CANNOT_UNASSIGN_LAST_ADMIN:
|
||||
case PermissionsExceptionCode.CANNOT_UPDATE_SELF_ROLE:
|
||||
case PermissionsExceptionCode.CANNOT_DELETE_LAST_ADMIN_USER:
|
||||
case PermissionsExceptionCode.ROLE_NOT_EDITABLE:
|
||||
case PermissionsExceptionCode.CANNOT_ADD_OBJECT_PERMISSION_ON_SYSTEM_OBJECT:
|
||||
case PermissionsExceptionCode.CANNOT_ADD_FIELD_PERMISSION_ON_SYSTEM_OBJECT:
|
||||
return 403;
|
||||
case PermissionsExceptionCode.INVALID_ARG:
|
||||
case PermissionsExceptionCode.INVALID_SETTING:
|
||||
case PermissionsExceptionCode.CANNOT_GIVE_WRITING_PERMISSION_ON_NON_READABLE_OBJECT:
|
||||
case PermissionsExceptionCode.CANNOT_GIVE_WRITING_PERMISSION_WITHOUT_READING_PERMISSION:
|
||||
case PermissionsExceptionCode.ONLY_FIELD_RESTRICTION_ALLOWED:
|
||||
case PermissionsExceptionCode.FIELD_RESTRICTION_ONLY_ALLOWED_ON_READABLE_OBJECT:
|
||||
case PermissionsExceptionCode.FIELD_RESTRICTION_ON_UPDATE_ONLY_ALLOWED_ON_UPDATABLE_OBJECT:
|
||||
case PermissionsExceptionCode.EMPTY_FIELD_PERMISSION_NOT_ALLOWED:
|
||||
case PermissionsExceptionCode.ROLE_MUST_HAVE_AT_LEAST_ONE_TARGET:
|
||||
case PermissionsExceptionCode.ROLE_CANNOT_BE_ASSIGNED_TO_USERS:
|
||||
return 400;
|
||||
case PermissionsExceptionCode.ROLE_NOT_FOUND:
|
||||
case PermissionsExceptionCode.OBJECT_METADATA_NOT_FOUND:
|
||||
case PermissionsExceptionCode.FIELD_METADATA_NOT_FOUND:
|
||||
case PermissionsExceptionCode.FIELD_PERMISSION_NOT_FOUND:
|
||||
case PermissionsExceptionCode.PERMISSION_NOT_FOUND:
|
||||
return 404;
|
||||
case PermissionsExceptionCode.UPSERT_FIELD_PERMISSION_FAILED:
|
||||
case PermissionsExceptionCode.DEFAULT_ROLE_NOT_FOUND:
|
||||
case PermissionsExceptionCode.WORKSPACE_ID_ROLE_USER_WORKSPACE_MISMATCH:
|
||||
case PermissionsExceptionCode.TOO_MANY_ADMIN_CANDIDATES:
|
||||
case PermissionsExceptionCode.USER_WORKSPACE_ALREADY_HAS_ROLE:
|
||||
case PermissionsExceptionCode.ADMIN_ROLE_NOT_FOUND:
|
||||
case PermissionsExceptionCode.DEFAULT_ROLE_CANNOT_BE_DELETED:
|
||||
case PermissionsExceptionCode.WORKSPACE_MEMBER_NOT_FOUND:
|
||||
case PermissionsExceptionCode.UNKNOWN_OPERATION_NAME:
|
||||
case PermissionsExceptionCode.UNKNOWN_REQUIRED_PERMISSION:
|
||||
case PermissionsExceptionCode.NO_ROLE_FOUND_FOR_USER_WORKSPACE:
|
||||
case PermissionsExceptionCode.NO_PERMISSIONS_FOUND_IN_DATASOURCE:
|
||||
case PermissionsExceptionCode.METHOD_NOT_ALLOWED:
|
||||
case PermissionsExceptionCode.RAW_SQL_NOT_ALLOWED:
|
||||
case PermissionsExceptionCode.OBJECT_PERMISSION_NOT_FOUND:
|
||||
case PermissionsExceptionCode.API_KEY_ROLE_NOT_FOUND:
|
||||
case PermissionsExceptionCode.JOIN_COLUMN_NAME_REQUIRED:
|
||||
case PermissionsExceptionCode.COMPOSITE_TYPE_NOT_FOUND:
|
||||
case PermissionsExceptionCode.USER_WORKSPACE_NOT_FOUND:
|
||||
case PermissionsExceptionCode.APPLICATION_ROLE_NOT_FOUND:
|
||||
case PermissionsExceptionCode.ROLE_BELONGS_TO_ANOTHER_APPLICATION:
|
||||
return 500;
|
||||
default:
|
||||
return assertUnreachable(code);
|
||||
}
|
||||
};
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
import {
|
||||
type ArgumentsHost,
|
||||
Catch,
|
||||
type ExceptionFilter,
|
||||
Injectable,
|
||||
} from '@nestjs/common';
|
||||
|
||||
import { type Response } from 'express';
|
||||
|
||||
import { HttpExceptionHandlerService } from 'src/engine/core-modules/exception-handler/http-exception-handler.service';
|
||||
import { PermissionsException } from 'src/engine/metadata-modules/permissions/permissions.exception';
|
||||
import { permissionRestApiExceptionCodeToHttpStatus } from 'src/engine/metadata-modules/permissions/utils/permission-rest-api-exception-code-to-http-status.util';
|
||||
import { type CustomException } from 'src/utils/custom-exception';
|
||||
|
||||
@Injectable()
|
||||
@Catch(PermissionsException)
|
||||
export class PermissionsRestApiExceptionFilter implements ExceptionFilter {
|
||||
constructor(
|
||||
private readonly httpExceptionHandlerService: HttpExceptionHandlerService,
|
||||
) {}
|
||||
|
||||
catch(exception: PermissionsException, host: ArgumentsHost) {
|
||||
const response = host.switchToHttp().getResponse<Response>();
|
||||
|
||||
return this.httpExceptionHandlerService.handleError(
|
||||
exception as CustomException,
|
||||
response,
|
||||
permissionRestApiExceptionCodeToHttpStatus(exception.code),
|
||||
);
|
||||
}
|
||||
}
|
||||
+2
@@ -18,6 +18,7 @@ import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorat
|
||||
import { NoPermissionGuard } from 'src/engine/guards/no-permission.guard';
|
||||
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
|
||||
import { FlatEntityMapsRestApiExceptionFilter } from 'src/engine/metadata-modules/flat-entity/filters/flat-entity-maps-rest-api-exception.filter';
|
||||
import { PermissionsRestApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-rest-api-exception.filter';
|
||||
import { CreateViewFieldInput } from 'src/engine/metadata-modules/view-field/dtos/inputs/create-view-field.input';
|
||||
import { UpdateViewFieldInput } from 'src/engine/metadata-modules/view-field/dtos/inputs/update-view-field.input';
|
||||
import { ViewFieldDTO } from 'src/engine/metadata-modules/view-field/dtos/view-field.dto';
|
||||
@@ -38,6 +39,7 @@ import { WorkspaceMigrationRunnerRestApiExceptionFilter } from 'src/engine/works
|
||||
@Controller('rest/metadata/viewFields')
|
||||
@UseGuards(WorkspaceAuthGuard)
|
||||
@UseFilters(
|
||||
PermissionsRestApiExceptionFilter,
|
||||
ViewFieldRestApiExceptionFilter,
|
||||
FlatEntityMapsRestApiExceptionFilter,
|
||||
WorkspaceMigrationRunnerRestApiExceptionFilter,
|
||||
|
||||
+2
@@ -18,6 +18,7 @@ import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorat
|
||||
import { NoPermissionGuard } from 'src/engine/guards/no-permission.guard';
|
||||
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
|
||||
import { FlatEntityMapsRestApiExceptionFilter } from 'src/engine/metadata-modules/flat-entity/filters/flat-entity-maps-rest-api-exception.filter';
|
||||
import { PermissionsRestApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-rest-api-exception.filter';
|
||||
import { type CreateViewFilterGroupInput } from 'src/engine/metadata-modules/view-filter-group/dtos/inputs/create-view-filter-group.input';
|
||||
import { type UpdateViewFilterGroupInput } from 'src/engine/metadata-modules/view-filter-group/dtos/inputs/update-view-filter-group.input';
|
||||
import { type ViewFilterGroupDTO } from 'src/engine/metadata-modules/view-filter-group/dtos/view-filter-group.dto';
|
||||
@@ -38,6 +39,7 @@ import { WorkspaceMigrationRunnerRestApiExceptionFilter } from 'src/engine/works
|
||||
@Controller('rest/metadata/viewFilterGroups')
|
||||
@UseGuards(WorkspaceAuthGuard)
|
||||
@UseFilters(
|
||||
PermissionsRestApiExceptionFilter,
|
||||
ViewFilterGroupRestApiExceptionFilter,
|
||||
FlatEntityMapsRestApiExceptionFilter,
|
||||
WorkspaceMigrationRunnerRestApiExceptionFilter,
|
||||
|
||||
+2
@@ -18,6 +18,7 @@ import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorat
|
||||
import { NoPermissionGuard } from 'src/engine/guards/no-permission.guard';
|
||||
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
|
||||
import { FlatEntityMapsRestApiExceptionFilter } from 'src/engine/metadata-modules/flat-entity/filters/flat-entity-maps-rest-api-exception.filter';
|
||||
import { PermissionsRestApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-rest-api-exception.filter';
|
||||
import { CreateViewFilterInput } from 'src/engine/metadata-modules/view-filter/dtos/inputs/create-view-filter.input';
|
||||
import { UpdateViewFilterInput } from 'src/engine/metadata-modules/view-filter/dtos/inputs/update-view-filter.input';
|
||||
import { ViewFilterDTO } from 'src/engine/metadata-modules/view-filter/dtos/view-filter.dto';
|
||||
@@ -38,6 +39,7 @@ import { WorkspaceMigrationRunnerRestApiExceptionFilter } from 'src/engine/works
|
||||
@Controller('rest/metadata/viewFilters')
|
||||
@UseGuards(WorkspaceAuthGuard)
|
||||
@UseFilters(
|
||||
PermissionsRestApiExceptionFilter,
|
||||
ViewFilterRestApiExceptionFilter,
|
||||
FlatEntityMapsRestApiExceptionFilter,
|
||||
WorkspaceMigrationRunnerRestApiExceptionFilter,
|
||||
|
||||
+2
@@ -18,6 +18,7 @@ import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorat
|
||||
import { NoPermissionGuard } from 'src/engine/guards/no-permission.guard';
|
||||
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
|
||||
import { FlatEntityMapsRestApiExceptionFilter } from 'src/engine/metadata-modules/flat-entity/filters/flat-entity-maps-rest-api-exception.filter';
|
||||
import { PermissionsRestApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-rest-api-exception.filter';
|
||||
import { CreateViewGroupInput } from 'src/engine/metadata-modules/view-group/dtos/inputs/create-view-group.input';
|
||||
import { UpdateViewGroupInput } from 'src/engine/metadata-modules/view-group/dtos/inputs/update-view-group.input';
|
||||
import { type ViewGroupDTO } from 'src/engine/metadata-modules/view-group/dtos/view-group.dto';
|
||||
@@ -38,6 +39,7 @@ import { WorkspaceMigrationRunnerRestApiExceptionFilter } from 'src/engine/works
|
||||
@Controller('rest/metadata/viewGroups')
|
||||
@UseGuards(WorkspaceAuthGuard)
|
||||
@UseFilters(
|
||||
PermissionsRestApiExceptionFilter,
|
||||
ViewGroupRestApiExceptionFilter,
|
||||
FlatEntityMapsRestApiExceptionFilter,
|
||||
WorkspaceMigrationRunnerRestApiExceptionFilter,
|
||||
|
||||
+2
@@ -18,6 +18,7 @@ import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorat
|
||||
import { NoPermissionGuard } from 'src/engine/guards/no-permission.guard';
|
||||
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
|
||||
import { FlatEntityMapsRestApiExceptionFilter } from 'src/engine/metadata-modules/flat-entity/filters/flat-entity-maps-rest-api-exception.filter';
|
||||
import { PermissionsRestApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-rest-api-exception.filter';
|
||||
import { CreateViewSortPermissionGuard } from 'src/engine/metadata-modules/view-permissions/guards/create-view-sort-permission.guard';
|
||||
import { DeleteViewSortPermissionGuard } from 'src/engine/metadata-modules/view-permissions/guards/delete-view-sort-permission.guard';
|
||||
import { UpdateViewSortPermissionGuard } from 'src/engine/metadata-modules/view-permissions/guards/update-view-sort-permission.guard';
|
||||
@@ -38,6 +39,7 @@ import { ViewSortDirection } from 'twenty-shared/types';
|
||||
@Controller('rest/metadata/viewSorts')
|
||||
@UseGuards(WorkspaceAuthGuard)
|
||||
@UseFilters(
|
||||
PermissionsRestApiExceptionFilter,
|
||||
ViewSortRestApiExceptionFilter,
|
||||
FlatEntityMapsRestApiExceptionFilter,
|
||||
WorkspaceMigrationRunnerRestApiExceptionFilter,
|
||||
|
||||
@@ -41,11 +41,13 @@ import {
|
||||
import { ViewRestApiExceptionFilter } from 'src/engine/metadata-modules/view/filters/view-rest-api-exception.filter';
|
||||
import { ViewService } from 'src/engine/metadata-modules/view/services/view.service';
|
||||
import { FlatEntityMapsRestApiExceptionFilter } from 'src/engine/metadata-modules/flat-entity/filters/flat-entity-maps-rest-api-exception.filter';
|
||||
import { PermissionsRestApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-rest-api-exception.filter';
|
||||
import { WorkspaceMigrationRunnerRestApiExceptionFilter } from 'src/engine/workspace-manager/workspace-migration/filters/workspace-migration-runner-rest-api-exception.filter';
|
||||
|
||||
@Controller('rest/metadata/views')
|
||||
@UseGuards(WorkspaceAuthGuard)
|
||||
@UseFilters(
|
||||
PermissionsRestApiExceptionFilter,
|
||||
ViewRestApiExceptionFilter,
|
||||
FlatEntityMapsRestApiExceptionFilter,
|
||||
WorkspaceMigrationRunnerRestApiExceptionFilter,
|
||||
|
||||
+2
@@ -19,6 +19,7 @@ import { JwtAuthGuard } from 'src/engine/guards/jwt-auth.guard';
|
||||
import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard';
|
||||
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
|
||||
import { FlatEntityMapsRestApiExceptionFilter } from 'src/engine/metadata-modules/flat-entity/filters/flat-entity-maps-rest-api-exception.filter';
|
||||
import { PermissionsRestApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-rest-api-exception.filter';
|
||||
import { CreateWebhookInput } from 'src/engine/metadata-modules/webhook/dtos/create-webhook.input';
|
||||
import { UpdateWebhookInput } from 'src/engine/metadata-modules/webhook/dtos/update-webhook.input';
|
||||
import { type WebhookDTO } from 'src/engine/metadata-modules/webhook/dtos/webhook.dto';
|
||||
@@ -32,6 +33,7 @@ import { WorkspaceMigrationRunnerRestApiExceptionFilter } from 'src/engine/works
|
||||
SettingsPermissionGuard(PermissionFlagType.API_KEYS_AND_WEBHOOKS),
|
||||
)
|
||||
@UseFilters(
|
||||
PermissionsRestApiExceptionFilter,
|
||||
RestApiExceptionFilter,
|
||||
FlatEntityMapsRestApiExceptionFilter,
|
||||
WorkspaceMigrationRunnerRestApiExceptionFilter,
|
||||
|
||||
Reference in New Issue
Block a user