diff --git a/src/authentication/authentication.guard.spec.ts b/src/authentication/authentication.guard.spec.ts index 8edac59..0aa983e 100644 --- a/src/authentication/authentication.guard.spec.ts +++ b/src/authentication/authentication.guard.spec.ts @@ -11,7 +11,7 @@ import { Authenticated, RequireAllPermissions, RequireSomePermission, -} from './authentication.decorator'; +} from '../decorators/authentication.decorator'; import { AuthenticationGuard } from './authentication.guard'; import { PERMISSIONS_GROUPS } from './permissions.enum'; import { AuthClientService } from '../modules/auth/auth.service'; diff --git a/src/authentication/authentication.guard.ts b/src/authentication/authentication.guard.ts index 07125b1..f97bdfe 100644 --- a/src/authentication/authentication.guard.ts +++ b/src/authentication/authentication.guard.ts @@ -13,8 +13,8 @@ import { AuthClientService } from '../modules/auth/auth.service'; import { AuthenticationFunction, AUTH_FUNCTION_KEY, -} from './authentication.decorator'; -import { RequestUser } from './user.decorator'; +} from '../decorators/authentication.decorator'; +import { RequestUser } from '../decorators/user.decorator'; import ErrorBuilder from '../utils/ErrorBuilder'; import ErrorCodes from '../utils/errorCodes'; diff --git a/src/authentication/authentication.decorator.ts b/src/decorators/authentication.decorator.ts similarity index 50% rename from src/authentication/authentication.decorator.ts rename to src/decorators/authentication.decorator.ts index 2016872..385ced0 100644 --- a/src/authentication/authentication.decorator.ts +++ b/src/decorators/authentication.decorator.ts @@ -1,44 +1,14 @@ -import { Request } from 'express'; -import { applyDecorators, CustomDecorator } from '@nestjs/common'; -import { PermissionsObjectPermission } from './permissions.enum'; -import { RequestUser } from './user.decorator'; +import { applyDecorators } from '@nestjs/common'; import { ApiSecurity } from '@nestjs/swagger'; +import { type Request } from 'express'; +import { type PermissionsObjectPermission } from '../authentication/permissions.enum'; +import { type RequestUser } from './user.decorator'; +import { SetMultipleMetadata } from './shared'; export const AUTH_FUNCTION_KEY = '__AUTH_FUNCTION__'; export type AuthenticationFunction = (req: Request, user: any) => boolean; -// implementation copied from SetMetadata, but tweaked to get existing values -// of the metadataKey and accumulate it with the new metadataValue -function SetMultipleMetadata(metadataKey, metadataValue): CustomDecorator { - const decoratorFactory: CustomDecorator = (target, key?, descriptor?) => { - // .start: tweak - // descriptor?.value = function decorator; target = class decorator - const accumulatedVal = - Reflect.getMetadata(metadataKey, descriptor?.value ?? target) ?? []; - accumulatedVal.push(metadataValue); - // .end: tweak - - if (descriptor) { - Reflect.defineMetadata(metadataKey, accumulatedVal, descriptor.value); - return descriptor; - } - - Reflect.defineMetadata(metadataKey, accumulatedVal, target); - return target; - }; - - decoratorFactory.KEY = metadataKey; - return decoratorFactory; -} - -function createAuthenticatedDecorator(metadataValue: AuthenticationFunction) { - return applyDecorators( - ApiSecurity('access-token'), - SetMultipleMetadata(AUTH_FUNCTION_KEY, metadataValue), - ); -} - export function RequireAllPermissions( ...permissions: PermissionsObjectPermission[] ) { @@ -62,3 +32,10 @@ export function AuthenticateCondition(func: AuthenticationFunction) { export function Authenticated() { return createAuthenticatedDecorator(() => true); } + +function createAuthenticatedDecorator(metadataValue: AuthenticationFunction) { + return applyDecorators( + ApiSecurity('access-token'), + SetMultipleMetadata(AUTH_FUNCTION_KEY, metadataValue), + ); +} diff --git a/src/decorators/shared.ts b/src/decorators/shared.ts new file mode 100644 index 0000000..9d4f659 --- /dev/null +++ b/src/decorators/shared.ts @@ -0,0 +1,28 @@ +import { type CustomDecorator } from '@nestjs/common'; + +// implementation copied from SetMetadata, but tweaked to get existing values +// of the metadataKey and accumulate it with the new metadataValue +export function SetMultipleMetadata( + metadataKey, + metadataValue, +): CustomDecorator { + const decoratorFactory: CustomDecorator = (target, key?, descriptor?) => { + // .start: tweak + // descriptor?.value = function decorator; target = class decorator + const accumulatedVal = + Reflect.getMetadata(metadataKey, descriptor?.value ?? target) ?? []; + accumulatedVal.push(metadataValue); + // .end: tweak + + if (descriptor) { + Reflect.defineMetadata(metadataKey, accumulatedVal, descriptor.value); + return descriptor; + } + + Reflect.defineMetadata(metadataKey, accumulatedVal, target); + return target; + }; + + decoratorFactory.KEY = metadataKey; + return decoratorFactory; +} diff --git a/src/authentication/user.decorator.spec.ts b/src/decorators/user.decorator.spec.ts similarity index 95% rename from src/authentication/user.decorator.spec.ts rename to src/decorators/user.decorator.spec.ts index c1a041a..90488f3 100644 --- a/src/authentication/user.decorator.spec.ts +++ b/src/decorators/user.decorator.spec.ts @@ -1,17 +1,14 @@ -import request from 'supertest'; -import { Test } from '@nestjs/testing'; -import { HttpStatus, INestApplication } from '@nestjs/common'; -import { APP_GUARD } from '@nestjs/core'; -import jwt from 'jsonwebtoken'; - -import { Controller, Get } from '@nestjs/common'; import { DadosferaLogger } from '@dadosfera/dadosfera-logs'; -import { AuthenticationGuard } from './authentication.guard'; +import { Controller, Get, HttpStatus, INestApplication } from '@nestjs/common'; +import { APP_GUARD } from '@nestjs/core'; +import { Test } from '@nestjs/testing'; +import jwt from 'jsonwebtoken'; +import request from 'supertest'; +import { AuthenticationGuard } from '../authentication/authentication.guard'; +import { PERMISSIONS_GROUPS } from '../authentication/permissions.enum'; import { AuthClientService } from '../modules/auth/auth.service'; - import ErrorCodes from '../utils/errorCodes'; import { User } from './user.decorator'; -import { PERMISSIONS_GROUPS } from './permissions.enum'; const logger = { info: (...args) => args, diff --git a/src/authentication/user.decorator.ts b/src/decorators/user.decorator.ts similarity index 89% rename from src/authentication/user.decorator.ts rename to src/decorators/user.decorator.ts index bdec568..94b6045 100644 --- a/src/authentication/user.decorator.ts +++ b/src/decorators/user.decorator.ts @@ -1,4 +1,4 @@ -import { createParamDecorator, ExecutionContext } from '@nestjs/common'; +import { createParamDecorator, type ExecutionContext } from '@nestjs/common'; import ErrorBuilder from '../utils/ErrorBuilder'; import ErrorCodes from '../utils/errorCodes'; diff --git a/src/modules/auth/auth.controller.ts b/src/modules/auth/auth.controller.ts index 9739012..1fb66e7 100644 --- a/src/modules/auth/auth.controller.ts +++ b/src/modules/auth/auth.controller.ts @@ -24,11 +24,11 @@ import { PERMISSIONS_GROUPS } from 'src/authentication/permissions.enum'; import { Authenticated, RequireAllPermissions, -} from 'src/authentication/authentication.decorator'; +} from 'src/decorators/authentication.decorator'; import { AuthClientService } from './auth.service'; import { DadosferaLogger } from '@dadosfera/dadosfera-logs'; import { GrpcToHttpExceptionFilter } from '../../error/grpc-to-http-exception.filter'; -import { RequestUser, User } from 'src/authentication/user.decorator'; +import { RequestUser, User } from 'src/decorators/user.decorator'; import { AuthRefreshAccessTokenReq, AuthSignInReq, diff --git a/src/modules/catalog/catalog.controller.ts b/src/modules/catalog/catalog.controller.ts index d9ba418..1dc4b55 100644 --- a/src/modules/catalog/catalog.controller.ts +++ b/src/modules/catalog/catalog.controller.ts @@ -18,12 +18,12 @@ import { ApiTags } from '@nestjs/swagger'; import { Authenticated, RequireSomePermission, -} from '../../authentication/authentication.decorator'; +} from '../../decorators/authentication.decorator'; import { PERMISSIONS_GROUPS } from '../../authentication/permissions.enum'; import { CatalogService } from './catalog.service'; import { DadosferaLogger } from '@dadosfera/dadosfera-logs'; import { PackTheMetadata } from 'src/utils/ PackTheMetadata'; -import { RequestUser, User } from 'src/authentication/user.decorator'; +import { RequestUser, User } from 'src/decorators/user.decorator'; import { ICatalogAllResponse, IColumnsMetadataResponse, diff --git a/src/modules/connection-test/connection-test.controller.ts b/src/modules/connection-test/connection-test.controller.ts index c3a86f8..cc5c6c8 100644 --- a/src/modules/connection-test/connection-test.controller.ts +++ b/src/modules/connection-test/connection-test.controller.ts @@ -9,7 +9,7 @@ import { ValidationPipe, } from '@nestjs/common'; import { ApiOkResponse, ApiTags } from '@nestjs/swagger'; -import { User, RequestUser } from 'src/authentication/user.decorator'; +import { User, RequestUser } from 'src/decorators/user.decorator'; import { ConnectionTestService } from './connection-test.service'; import { ConnectionTestPingRes, @@ -24,7 +24,7 @@ import { GetTableMetadataReq, } from './dto/connection-test'; import { DadosferaLogger } from '@dadosfera/dadosfera-logs'; -import { Authenticated } from 'src/authentication/authentication.decorator'; +import { Authenticated } from 'src/decorators/authentication.decorator'; import { GrpcToHttpExceptionFilter } from 'src/error/grpc-to-http-exception.filter'; @ApiTags('Connection Test') diff --git a/src/modules/connection-test/connection-test.service.ts b/src/modules/connection-test/connection-test.service.ts index 6e78443..310555a 100644 --- a/src/modules/connection-test/connection-test.service.ts +++ b/src/modules/connection-test/connection-test.service.ts @@ -19,7 +19,7 @@ import { CreateConnectionDto, DatabaseConnectionPropertiesDto, } from '../connection/dtos/connection'; -import { RequestUser } from 'src/authentication/user.decorator'; +import { RequestUser } from 'src/decorators/user.decorator'; import { PackTheMetadata } from 'src/utils/ PackTheMetadata'; @Injectable() diff --git a/src/modules/connection/connection.controller.ts b/src/modules/connection/connection.controller.ts index 4ea8897..c986617 100644 --- a/src/modules/connection/connection.controller.ts +++ b/src/modules/connection/connection.controller.ts @@ -17,9 +17,9 @@ import { DadosferaLogger } from '@dadosfera/dadosfera-logs'; import { Authenticated, RequireAllPermissions, -} from 'src/authentication/authentication.decorator'; +} from 'src/decorators/authentication.decorator'; import { PERMISSIONS_GROUPS } from 'src/authentication/permissions.enum'; -import { RequestUser, User } from 'src/authentication/user.decorator'; +import { RequestUser, User } from 'src/decorators/user.decorator'; import { ValidationPipe } from '../../pipes/object-validation.pipe'; import { ConnectionDetailsRes, diff --git a/src/modules/connector/connector.controller.ts b/src/modules/connector/connector.controller.ts index ba2116f..badf102 100644 --- a/src/modules/connector/connector.controller.ts +++ b/src/modules/connector/connector.controller.ts @@ -27,7 +27,7 @@ import { Authenticated, RequireAllPermissions, RequireSomePermission, -} from 'src/authentication/authentication.decorator'; +} from 'src/decorators/authentication.decorator'; import { PERMISSIONS_GROUPS } from 'src/authentication/permissions.enum'; @ApiTags('connectors') diff --git a/src/modules/inputs/inputs.controller.ts b/src/modules/inputs/inputs.controller.ts index 4ce5dc6..d7670bf 100644 --- a/src/modules/inputs/inputs.controller.ts +++ b/src/modules/inputs/inputs.controller.ts @@ -12,7 +12,7 @@ import { import { InputsService } from './inputs.service'; import { DadosferaLogger } from '@dadosfera/dadosfera-logs'; import { PERMISSIONS_GROUPS } from '../../authentication/permissions.enum'; -import { AuthenticateCondition } from 'src/authentication/authentication.decorator'; +import { AuthenticateCondition } from 'src/decorators/authentication.decorator'; import { ApiOkResponse, ApiTags } from '@nestjs/swagger'; import { CreateInputReq, @@ -21,7 +21,7 @@ import { Input, } from './dtos/input.model'; import { UpdateInputRequest } from './dtos/old_interfaces'; -import { RequestUser, User } from 'src/authentication/user.decorator'; +import { RequestUser, User } from 'src/decorators/user.decorator'; import { Info } from '@dadosfera/protospack-v2/dist/lib/Input/interfaces/entities'; import { GrpcToHttpExceptionFilter } from 'src/error/grpc-to-http-exception.filter'; diff --git a/src/modules/mixpanel/mixpanel.controller.ts b/src/modules/mixpanel/mixpanel.controller.ts index bf04196..cb1b641 100644 --- a/src/modules/mixpanel/mixpanel.controller.ts +++ b/src/modules/mixpanel/mixpanel.controller.ts @@ -1,7 +1,7 @@ import { Body, Controller, Inject, Param, Post } from '@nestjs/common'; import { init } from 'mixpanel'; -import { Authenticated } from 'src/authentication/authentication.decorator'; -import { RequestUser, User } from 'src/authentication/user.decorator'; +import { Authenticated } from 'src/decorators/authentication.decorator'; +import { RequestUser, User } from 'src/decorators/user.decorator'; @Authenticated() @Controller('trackEvent') diff --git a/src/modules/network-config/network-config.controller.ts b/src/modules/network-config/network-config.controller.ts index f65ecbb..3e1291c 100644 --- a/src/modules/network-config/network-config.controller.ts +++ b/src/modules/network-config/network-config.controller.ts @@ -15,7 +15,7 @@ import { import { NetworkConfigService } from './network-config.service'; import { DadosferaLogger } from '@dadosfera/dadosfera-logs'; import { ApiConsumes, ApiOkResponse, ApiTags } from '@nestjs/swagger'; -import { RequestUser, User } from 'src/authentication/user.decorator'; +import { RequestUser, User } from 'src/decorators/user.decorator'; import { CreateNetworkConfigReq, CreateNetworkConfigRes, @@ -26,7 +26,7 @@ import { PERMISSIONS_GROUPS } from 'src/authentication/permissions.enum'; import { Authenticated, RequireAllPermissions, -} from 'src/authentication/authentication.decorator'; +} from 'src/decorators/authentication.decorator'; const networkConfigPermissions = PERMISSIONS_GROUPS.NETWORK_CONFIG.permissions; @ApiTags('Network Config') diff --git a/src/modules/permissions/permissions.controller.ts b/src/modules/permissions/permissions.controller.ts index 0383d9f..ad51354 100644 --- a/src/modules/permissions/permissions.controller.ts +++ b/src/modules/permissions/permissions.controller.ts @@ -1,9 +1,9 @@ import { Controller, Get, Headers, Inject } from '@nestjs/common'; import { ApiHeader, ApiOkResponse, ApiTags } from '@nestjs/swagger'; import { DadosferaLogger } from '@dadosfera/dadosfera-logs'; -import { Authenticated } from 'src/authentication/authentication.decorator'; +import { Authenticated } from 'src/decorators/authentication.decorator'; import { PermissionUsages } from 'src/authentication/permissions.enum'; -import { RequestUser, User } from 'src/authentication/user.decorator'; +import { RequestUser, User } from 'src/decorators/user.decorator'; import { LanguageEnum } from 'src/utils/languages.enum'; import { GetPublicPermissionsRes } from './dto/entities'; import { PermissionsService } from './permissions.service'; diff --git a/src/modules/pipelines/pipelines.controller.ts b/src/modules/pipelines/pipelines.controller.ts index 3eb334b..ea094b8 100644 --- a/src/modules/pipelines/pipelines.controller.ts +++ b/src/modules/pipelines/pipelines.controller.ts @@ -3,7 +3,7 @@ import { ApiOperation, ApiTags } from '@nestjs/swagger'; import { AuthenticateCondition, Authenticated, -} from 'src/authentication/authentication.decorator'; +} from 'src/decorators/authentication.decorator'; import { PERMISSIONS_GROUPS } from '../../authentication/permissions.enum'; import { PipelinesService } from './pipelines.service'; import { DadosferaLogger } from '@dadosfera/dadosfera-logs'; diff --git a/src/modules/pipelinesV2/pipelines.controller.ts b/src/modules/pipelinesV2/pipelines.controller.ts index 521251b..ab3093e 100644 --- a/src/modules/pipelinesV2/pipelines.controller.ts +++ b/src/modules/pipelinesV2/pipelines.controller.ts @@ -25,12 +25,12 @@ import { import { AuthenticateCondition, RequireAllPermissions, -} from 'src/authentication/authentication.decorator'; +} from 'src/decorators/authentication.decorator'; import { PERMISSIONS_GROUPS } from '../../authentication/permissions.enum'; import { PipelinesService } from './pipelines.service'; import { DadosferaLogger } from '@dadosfera/dadosfera-logs'; import { Messages } from '@dadosfera/protospack-v2/dist/lib/PipelineV2'; -import { RequestUser, User } from 'src/authentication/user.decorator'; +import { RequestUser, User } from 'src/decorators/user.decorator'; import { PackTheMetadata } from 'src/utils/ PackTheMetadata'; import { PipelinesService as OldPipelineService } from 'src/modules/pipelines/pipelines.service'; diff --git a/src/modules/pipelinesV2/pipelines.service.ts b/src/modules/pipelinesV2/pipelines.service.ts index de62496..dcf740b 100644 --- a/src/modules/pipelinesV2/pipelines.service.ts +++ b/src/modules/pipelinesV2/pipelines.service.ts @@ -21,7 +21,7 @@ import { PipelineV2CreateRequest } from '@dadosfera/protospack-v2/dist/lib/Pipel import { Metadata } from '@grpc/grpc-js'; import { ConnectorClientService } from '../connector/client.service'; import { InputsService } from '../inputs/inputs.service'; -import { RequestUser } from 'src/authentication/user.decorator'; +import { RequestUser } from 'src/decorators/user.decorator'; import { TransformationsService } from '../transformations/transformations.service'; import { getObjValueFromPath } from 'src/utils/ObjValueFromPath'; import ErrorCodes from 'src/utils/errorCodes'; diff --git a/src/modules/productboard/productboard.controller.ts b/src/modules/productboard/productboard.controller.ts index 16e47c3..481b6f1 100644 --- a/src/modules/productboard/productboard.controller.ts +++ b/src/modules/productboard/productboard.controller.ts @@ -1,8 +1,8 @@ import { Body, Controller, HttpException, Post } from '@nestjs/common'; import { ApiTags } from '@nestjs/swagger'; import axios from 'axios'; -import { Authenticated } from 'src/authentication/authentication.decorator'; -import { User, RequestUser } from 'src/authentication/user.decorator'; +import { Authenticated } from 'src/decorators/authentication.decorator'; +import { User, RequestUser } from 'src/decorators/user.decorator'; import { getSecretFromSecretsManager } from 'src/utils/SecretManager'; import { INote } from './dtos'; diff --git a/src/modules/roles/roles.controller.ts b/src/modules/roles/roles.controller.ts index ca5ab99..038245c 100644 --- a/src/modules/roles/roles.controller.ts +++ b/src/modules/roles/roles.controller.ts @@ -18,7 +18,7 @@ import { ApiOkResponse, ApiTags, } from '@nestjs/swagger'; -import { RequestUser, User } from 'src/authentication/user.decorator'; +import { RequestUser, User } from 'src/decorators/user.decorator'; import { DadosferaLogger } from '@dadosfera/dadosfera-logs'; import { RolesService } from './roles.service'; import { @@ -43,7 +43,7 @@ import { PERMISSIONS_GROUPS } from 'src/authentication/permissions.enum'; import { Authenticated, RequireAllPermissions, -} from 'src/authentication/authentication.decorator'; +} from 'src/decorators/authentication.decorator'; import { LanguageEnum } from 'src/utils/languages.enum'; @ApiTags('Roles') diff --git a/src/modules/roles/roles.service.ts b/src/modules/roles/roles.service.ts index da12c7b..bd41ca5 100644 --- a/src/modules/roles/roles.service.ts +++ b/src/modules/roles/roles.service.ts @@ -18,7 +18,7 @@ import { Permission } from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces/ent import { lastValueFrom } from 'rxjs'; import { PermissionsService } from '../permissions/permissions.service'; import { LanguageEnum } from 'src/utils/languages.enum'; -import { RequestUser } from 'src/authentication/user.decorator'; +import { RequestUser } from 'src/decorators/user.decorator'; import { DucClient } from '../duc/client.config'; interface GetRolesPermissionsName { diff --git a/src/modules/termsOfUse/termsOfUse.controller.ts b/src/modules/termsOfUse/termsOfUse.controller.ts index e003367..55279ff 100644 --- a/src/modules/termsOfUse/termsOfUse.controller.ts +++ b/src/modules/termsOfUse/termsOfUse.controller.ts @@ -16,7 +16,7 @@ import { TermsOfUseClientService } from './termsOfUse.service'; import { DadosferaLogger } from '@dadosfera/dadosfera-logs'; import { GrpcToHttpExceptionFilter } from '../../error/grpc-to-http-exception.filter'; -import { RequestUser, User } from '../../authentication/user.decorator'; +import { RequestUser, User } from '../../decorators/user.decorator'; import { Metadata } from '@grpc/grpc-js'; @ApiTags('TermsOfUse') diff --git a/src/modules/transformations/transformations.controller.ts b/src/modules/transformations/transformations.controller.ts index 6c8def6..df66c44 100644 --- a/src/modules/transformations/transformations.controller.ts +++ b/src/modules/transformations/transformations.controller.ts @@ -12,14 +12,13 @@ import { ApiTags } from '@nestjs/swagger'; import { TransformationsClientService } from './client.service'; import { IIdRequest } from './interfaces'; import { - AuthenticateCondition, Authenticated, RequireSomePermission, -} from 'src/authentication/authentication.decorator'; +} from 'src/decorators/authentication.decorator'; import { PERMISSIONS_GROUPS } from '../../authentication/permissions.enum'; import { TransformationsService } from './transformations.service'; import { DadosferaLogger } from '@dadosfera/dadosfera-logs'; -import { RequestUser, User } from 'src/authentication/user.decorator'; +import { RequestUser, User } from 'src/decorators/user.decorator'; const pipelinePermissions = PERMISSIONS_GROUPS.PIPELINE.permissions; @ApiTags('Transformations') @Controller('transformations') diff --git a/src/modules/users/users.controller.ts b/src/modules/users/users.controller.ts index 8a0c17e..c05fb27 100644 --- a/src/modules/users/users.controller.ts +++ b/src/modules/users/users.controller.ts @@ -1,3 +1,4 @@ +import { DadosferaLogger } from '@dadosfera/dadosfera-logs'; import { Body, Controller, @@ -20,14 +21,16 @@ import { ApiOkResponse, ApiTags, } from '@nestjs/swagger'; -import { DadosferaLogger } from '@dadosfera/dadosfera-logs'; +import { PERMISSIONS_GROUPS } from 'src/authentication/permissions.enum'; import { Authenticated, RequireAllPermissions, -} from 'src/authentication/authentication.decorator'; -import { PERMISSIONS_GROUPS } from 'src/authentication/permissions.enum'; -import { RequestUser, User } from 'src/authentication/user.decorator'; +} from 'src/decorators/authentication.decorator'; +import { RequestUser, User } from 'src/decorators/user.decorator'; import { GrpcToHttpExceptionFilter } from 'src/error/grpc-to-http-exception.filter'; +import { PackTheMetadata } from 'src/utils/ PackTheMetadata'; +import ErrorBuilder from 'src/utils/ErrorBuilder'; +import ErrorCodes from 'src/utils/errorCodes'; import { LanguageEnum } from 'src/utils/languages.enum'; import { AssignRoleToUserReq, @@ -40,17 +43,14 @@ import { GetAllHierarchiesRes, GetAllJobTitlesRes, GetAllUsersByCustomerIdRes, + IUserByCustomer, SetUserRolesReq, SetUserRolesRes, UnassignRoleToUserReq, UpdateUserReq, UpdateUserRes, - IUserByCustomer, } from './dtos/entities'; import { UsersService } from './users.service'; -import ErrorBuilder from 'src/utils/ErrorBuilder'; -import ErrorCodes from 'src/utils/errorCodes'; -import { PackTheMetadata } from 'src/utils/ PackTheMetadata'; @ApiTags('Users') @Controller('users')