From 46ad3c377d7b0397ab62cc3dcda0bdbea202e705 Mon Sep 17 00:00:00 2001 From: Ihar Date: Thu, 25 Apr 2024 15:00:02 +0500 Subject: [PATCH 01/16] feat:basic fastify solution --- analytics-service/src/app.ts | 3 ++- api-gateway/package.json | 3 ++- api-gateway/src/app.ts | 4 +++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/analytics-service/src/app.ts b/analytics-service/src/app.ts index d8bd3805df..81a85dea74 100644 --- a/analytics-service/src/app.ts +++ b/analytics-service/src/app.ts @@ -18,6 +18,7 @@ import { AppModule } from './app.module.js'; import { SwaggerModule } from '@nestjs/swagger'; import { SwaggerConfig } from './helpers/swagger-config.js'; import { AnalyticsUtils } from './helpers/utils.js'; +import { FastifyAdapter } from '@nestjs/platform-fastify'; const PORT = process.env.PORT || 3020; Promise.all([ @@ -34,7 +35,7 @@ Promise.all([ }, [ 'v2-21-0' ]), - NestFactory.create(AppModule, { + NestFactory.create(AppModule, new FastifyAdapter(), { rawBody: true, bodyParser: false }), diff --git a/api-gateway/package.json b/api-gateway/package.json index aec735f371..5ac1bae7ff 100644 --- a/api-gateway/package.json +++ b/api-gateway/package.json @@ -8,11 +8,12 @@ "dependencies": { "@guardian/common": "^2.24.0", "@guardian/interfaces": "^2.24.0", + "@fastify/static": "^7.0.0", "@nestjs/common": "^9.4.1", "@nestjs/core": "^9.4.1", "@nestjs/jwt": "^10.0.3", "@nestjs/microservices": "^9.4.1", - "@nestjs/platform-express": "^9.4.2", + "@nestjs/platform-fastify": "^9.4.1", "@nestjs/swagger": "^6.3.0", "@types/express-fileupload": "^1.4.1", "async-mutex": "^0.4.0", diff --git a/api-gateway/src/app.ts b/api-gateway/src/app.ts index b2a861e06f..a59913789b 100644 --- a/api-gateway/src/app.ts +++ b/api-gateway/src/app.ts @@ -19,6 +19,8 @@ import { MeecoAuth } from './helpers/meeco.js'; import * as extraModels from './middlewares/validation/schemas/index.js' import { ProjectService } from './helpers/projects.js'; import { AISuggestions } from './helpers/ai-suggestions.js'; +import { FastifyAdapter } from '@nestjs/platform-fastify'; + const PORT = process.env.PORT || 3002; @@ -30,7 +32,7 @@ const PORT = process.env.PORT || 3002; // }); Promise.all([ - NestFactory.create(AppModule, { + NestFactory.create(AppModule, new FastifyAdapter(), { rawBody: true, bodyParser: false }), From a04ac5309a361bdcc406116f47f91d3bce8b4da3 Mon Sep 17 00:00:00 2001 From: Ihar Date: Tue, 30 Apr 2024 15:28:05 +0500 Subject: [PATCH 02/16] feat: add body parser for json and binary/octet-stream and send method --- api-gateway/package.json | 6 +- api-gateway/src/api/service/account.ts | 2 - api-gateway/src/api/service/analytics.ts | 22 +-- api-gateway/src/api/service/artifact.ts | 10 +- api-gateway/src/api/service/contract.ts | 138 ++++++++---------- api-gateway/src/api/service/logger.ts | 6 +- api-gateway/src/api/service/module.ts | 56 +++---- api-gateway/src/api/service/notifications.ts | 17 ++- api-gateway/src/api/service/policy.ts | 127 ++++++++-------- api-gateway/src/api/service/record.ts | 4 +- api-gateway/src/api/service/schema.ts | 100 ++++++------- api-gateway/src/api/service/settings.ts | 15 +- api-gateway/src/api/service/suggestions.ts | 8 +- api-gateway/src/api/service/tags.ts | 41 +++--- api-gateway/src/api/service/task.ts | 5 +- api-gateway/src/api/service/themes.ts | 18 ++- api-gateway/src/api/service/tokens.ts | 97 ++++++------ api-gateway/src/api/service/tool.ts | 58 ++++---- api-gateway/src/api/service/trust-chains.ts | 8 +- api-gateway/src/api/service/wizard.ts | 12 +- api-gateway/src/app.module.ts | 72 ++++----- api-gateway/src/app.ts | 50 ++++++- api-gateway/src/auth/authorization-helper.ts | 50 ++++++- api-gateway/src/helpers/interceptors/cache.ts | 2 +- .../src/middlewares/validation/index.ts | 2 +- 25 files changed, 511 insertions(+), 415 deletions(-) diff --git a/api-gateway/package.json b/api-gateway/package.json index 5ac1bae7ff..fb64e798e8 100644 --- a/api-gateway/package.json +++ b/api-gateway/package.json @@ -8,12 +8,15 @@ "dependencies": { "@guardian/common": "^2.24.0", "@guardian/interfaces": "^2.24.0", + "@fastify/formbody": "^7.4.0", + "@fastify/multipart": "^8.2.0", "@fastify/static": "^7.0.0", "@nestjs/common": "^9.4.1", "@nestjs/core": "^9.4.1", "@nestjs/jwt": "^10.0.3", "@nestjs/microservices": "^9.4.1", - "@nestjs/platform-fastify": "^9.4.1", + "@nestjs/platform-express": "^9.4.2", + "@nestjs/platform-fastify": "^9.4.2", "@nestjs/swagger": "^6.3.0", "@types/express-fileupload": "^1.4.1", "async-mutex": "^0.4.0", @@ -23,6 +26,7 @@ "dotenv": "^16.0.0", "express": "^4.17.1", "express-fileupload": "^1.4.0", + "fastify-raw-body": "4.0.0", "gulp": "^4.0.2", "gulp-copy": "^4.0.1", "gulp-rename": "^2.0.0", diff --git a/api-gateway/src/api/service/account.ts b/api-gateway/src/api/service/account.ts index b7da1f3d82..af73fbd735 100644 --- a/api-gateway/src/api/service/account.ts +++ b/api-gateway/src/api/service/account.ts @@ -222,12 +222,10 @@ export class AccountApi { $ref: getSchemaPath(InternalServerErrorDTO) } }) - // @UseGuards(AuthGuard) @HttpCode(HttpStatus.OK) @Get() @UseCache() async getAllAccounts(@Req() req): Promise { - // await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const authHeader = req.headers.authorization; const token = authHeader?.split(' ')[1]; const users = new Users(); diff --git a/api-gateway/src/api/service/analytics.ts b/api-gateway/src/api/service/analytics.ts index 7aee58253f..406414bfd1 100644 --- a/api-gateway/src/api/service/analytics.ts +++ b/api-gateway/src/api/service/analytics.ts @@ -10,7 +10,6 @@ import { ApiSecurity, ApiTags } from '@nestjs/swagger'; -import { checkPermission } from '../../auth/authorization-helper.js'; import { UserRole } from '@guardian/interfaces'; import { FilterDocumentsDTO, @@ -27,6 +26,7 @@ import { FilterToolsDTO, CompareToolsDTO } from '../../middlewares/validation/schemas/index.js'; +import { Auth } from '../../auth/auth.decorator.js'; const ONLY_SR = ' Only users with the Standard Registry role are allowed to make the request.' @@ -69,8 +69,8 @@ export class AnalyticsApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async searchPolicies(@Body() body, @Req() req): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const guardians = new Guardians(); const policyId = body ? body.policyId : null; const user = req.user; @@ -140,8 +140,8 @@ export class AnalyticsApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async comparePolicies(@Body() body, @Req() req): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const guardians = new Guardians(); const policyId1 = body ? body.policyId1 : null; const policyId2 = body ? body.policyId2 : null; @@ -220,8 +220,8 @@ export class AnalyticsApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async compareModules(@Body() body, @Req() req): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const guardians = new Guardians(); const moduleId1 = body ? body.moduleId1 : null; const moduleId2 = body ? body.moduleId2 : null; @@ -290,8 +290,8 @@ export class AnalyticsApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async compareSchemas(@Body() body, @Req() req): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const guardians = new Guardians(); const schemaId1 = body ? body.schemaId1 : null; const schemaId2 = body ? body.schemaId2 : null; @@ -352,6 +352,7 @@ export class AnalyticsApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER) async compareDocuments(@Body() body, @Req() req): Promise { const guardians = new Guardians(); const documentId1 = body ? body.documentId1 : null; @@ -436,6 +437,7 @@ export class AnalyticsApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER) async compareTools(@Body() body, @Req() req): Promise { const guardians = new Guardians(); const toolId1 = body ? body.toolId1 : null; @@ -524,8 +526,8 @@ export class AnalyticsApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async comparePoliciesExport(@Body() body, @Req() req): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const guardians = new Guardians(); const type = req.query ? req.query.type : null; const policyId1 = body ? body.policyId1 : null; @@ -603,8 +605,8 @@ export class AnalyticsApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async compareModulesExport(@Body() body, @Req() req): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const guardians = new Guardians(); const type = req.query ? req.query.type : null; const moduleId1 = body ? body.moduleId1 : null; @@ -674,8 +676,8 @@ export class AnalyticsApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async compareSchemasExport(@Body() body, @Req() req): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const guardians = new Guardians(); const type = req.query ? req.query.type : null; const schemaId1 = body ? body.schemaId1 : null; @@ -737,6 +739,7 @@ export class AnalyticsApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER) async compareDocumentsExport(@Body() body, @Req() req): Promise { const guardians = new Guardians(); const type = req.query ? req.query.type : null; @@ -821,6 +824,7 @@ export class AnalyticsApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER) async compareToolsExport(@Body() body, @Req() req): Promise { const guardians = new Guardians(); const type = req.query ? req.query.type : null; @@ -896,8 +900,8 @@ export class AnalyticsApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async searchBlocks(@Body() body, @Req() req): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const guardians = new Guardians(); const id = body ? body.id : null; const config = body ? body.config : null; diff --git a/api-gateway/src/api/service/artifact.ts b/api-gateway/src/api/service/artifact.ts index 118a2b6344..697eb679f1 100644 --- a/api-gateway/src/api/service/artifact.ts +++ b/api-gateway/src/api/service/artifact.ts @@ -14,7 +14,6 @@ import { UploadedFiles, UseInterceptors, } from '@nestjs/common'; -import { checkPermission } from '../../auth/authorization-helper.js'; import { ApiExtraModels, ApiInternalServerErrorResponse, @@ -33,6 +32,7 @@ import { ApiImplicitQuery } from '@nestjs/swagger/dist/decorators/api-implicit-q import { ArtifactDTOItem } from '../../middlewares/validation/schemas/artifacts.js'; import { ApiImplicitParam } from '@nestjs/swagger/dist/decorators/api-implicit-param.decorator.js'; import { FilesInterceptor } from '@nestjs/platform-express'; +import { Auth } from '../../auth/auth.decorator.js'; @Controller('artifacts') @ApiTags('artifacts') @@ -101,8 +101,8 @@ export class ArtifactApi { }) @ApiExtraModels(ArtifactDTOItem, InternalServerErrorDTO) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async getArtifacts(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const guardians = new Guardians(); const options: any = { @@ -119,7 +119,7 @@ export class ArtifactApi { options.pageSize = req.query.pageSize; } const { artifacts, count } = await guardians.getArtifacts(options); - return res.setHeader('X-Total-Count', count).json(artifacts); + return res.header('X-Total-Count', count).send(artifacts); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw error; @@ -183,8 +183,8 @@ export class ArtifactApi { @ApiExtraModels(ArtifactDTOItem, InternalServerErrorDTO) @UseInterceptors(FilesInterceptor('artifacts')) @HttpCode(HttpStatus.CREATED) + @Auth(UserRole.STANDARD_REGISTRY) async uploadArtifacts(@Req() req, @UploadedFiles() files): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { if (!files) { throw new HttpException('There are no files to upload', HttpStatus.UNPROCESSABLE_ENTITY) @@ -245,8 +245,8 @@ export class ArtifactApi { }) @ApiExtraModels(ArtifactDTOItem, InternalServerErrorDTO) @HttpCode(HttpStatus.NO_CONTENT) + @Auth(UserRole.STANDARD_REGISTRY) async deleteArtifact(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const guardian = new Guardians(); await guardian.deleteArtifact(req.params.artifactId, req.user.did) diff --git a/api-gateway/src/api/service/contract.ts b/api-gateway/src/api/service/contract.ts index e5317b459f..f2a8da6fe9 100644 --- a/api-gateway/src/api/service/contract.ts +++ b/api-gateway/src/api/service/contract.ts @@ -12,7 +12,6 @@ import { Req, Response, } from '@nestjs/common'; -import { checkPermission } from '../../auth/authorization-helper.js'; import { ApiInternalServerErrorResponse, ApiOkResponse, @@ -37,6 +36,7 @@ import { WiperRequestDTO, } from '../../middlewares/validation/schemas/contracts.js'; import { UseCache } from '../../helpers/decorators/cache.js'; +import { Auth } from '../../auth/auth.decorator.js'; /** * Contracts api @@ -98,11 +98,8 @@ export class ContractsApi { type: InternalServerErrorDTO, }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.USER) async getContracts(@Req() req, @Response() res): Promise { - await checkPermission( - UserRole.STANDARD_REGISTRY, - UserRole.USER - )(req.user); try { const user = req.user; const guardians = new Guardians(); @@ -112,7 +109,7 @@ export class ContractsApi { req.query.pageIndex as any, req.query.pageSize as any ); - return res.setHeader('X-Total-Count', count).json(contracts); + return res.header('X-Total-Count', count).send(contracts); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException( @@ -155,8 +152,8 @@ export class ContractsApi { type: InternalServerErrorDTO, }) @HttpCode(HttpStatus.CREATED) + @Auth(UserRole.STANDARD_REGISTRY) async createContract(@Req() req): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const { description, type } = req.body; @@ -210,8 +207,8 @@ export class ContractsApi { type: InternalServerErrorDTO, }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async importContract(@Req() req): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const { contractId, description } = req.body; @@ -264,8 +261,8 @@ export class ContractsApi { }) @HttpCode(HttpStatus.OK) @UseCache() + @Auth(UserRole.STANDARD_REGISTRY) async contractPermissions(@Req() req): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const guardians = new Guardians(); @@ -312,12 +309,12 @@ export class ContractsApi { type: InternalServerErrorDTO, }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async removeContract(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const guardians = new Guardians(); - return res.json( + return res.send( await guardians.removeContract( user?.did, req.params?.contractId as string @@ -393,8 +390,8 @@ export class ContractsApi { }) @HttpCode(HttpStatus.OK) // @UseCache({ isExpress: true }) + @Auth(UserRole.STANDARD_REGISTRY) async getWipeRequests(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const guardians = new Guardians(); @@ -405,7 +402,7 @@ export class ContractsApi { req.query.pageSize as any ); res.locals.data = contracts - return res.setHeader('X-Total-Count', count).json(contracts); + return res.header('X-Total-Count', count).send(contracts); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException( @@ -444,12 +441,12 @@ export class ContractsApi { type: InternalServerErrorDTO, }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async enableWipeRequests(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const guardians = new Guardians(); - return res.json( + return res.send( await guardians.enableWipeRequests( user.did, req.params.contractId @@ -493,12 +490,12 @@ export class ContractsApi { type: InternalServerErrorDTO, }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async disableWipeRequests(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const guardians = new Guardians(); - return res.json( + return res.send( await guardians.disableWipeRequests( user.did, req.params.contractId @@ -542,12 +539,12 @@ export class ContractsApi { type: InternalServerErrorDTO, }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async approveWipeRequest(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const guardians = new Guardians(); - return res.json( + return res.send( await guardians.approveWipeRequest( user.did, req.params.requestId @@ -597,12 +594,12 @@ export class ContractsApi { type: InternalServerErrorDTO, }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async rejectWipeRequest(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const guardians = new Guardians(); - return res.json( + return res.send( await guardians.rejectWipeRequest( user.did, req.params.requestId, @@ -647,12 +644,12 @@ export class ContractsApi { type: InternalServerErrorDTO, }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async clearWipeRequests(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const guardians = new Guardians(); - return res.json( + return res.send( await guardians.clearWipeRequests( user.did, req.params.contractId @@ -703,12 +700,12 @@ export class ContractsApi { type: InternalServerErrorDTO, }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async wipeAddAdmin(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const guardians = new Guardians(); - return res.json( + return res.send( await guardians.addWipeAdmin( user.did, req.params.contractId, @@ -760,12 +757,12 @@ export class ContractsApi { type: InternalServerErrorDTO, }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async wipeRemoveAdmin(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const guardians = new Guardians(); - return res.json( + return res.send( await guardians.removeWipeAdmin( user.did, req.params.contractId, @@ -817,12 +814,12 @@ export class ContractsApi { type: InternalServerErrorDTO, }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async wipeAddManager(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const guardians = new Guardians(); - return res.json( + return res.send( await guardians.addWipeManager( user.did, req.params.contractId, @@ -874,12 +871,12 @@ export class ContractsApi { type: InternalServerErrorDTO, }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async wipeRemoveManager(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const guardians = new Guardians(); - return res.json( + return res.send( await guardians.removeWipeManager( user.did, req.params.contractId, @@ -931,12 +928,12 @@ export class ContractsApi { type: InternalServerErrorDTO, }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async wipeAddWiper(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const guardians = new Guardians(); - return res.json( + return res.send( await guardians.addWipeWiper( user.did, req.params.contractId, @@ -988,12 +985,12 @@ export class ContractsApi { type: InternalServerErrorDTO, }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async wipeRemoveWiper(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const guardians = new Guardians(); - return res.json( + return res.send( await guardians.removeWipeWiper( user.did, req.params.contractId, @@ -1042,12 +1039,12 @@ export class ContractsApi { type: InternalServerErrorDTO, }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async retireSyncPools(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const guardians = new Guardians(); - return res.json( + return res.send( await guardians.syncRetirePools(user.did, req.params.contractId) ); } catch (error) { @@ -1117,11 +1114,8 @@ export class ContractsApi { }) @HttpCode(HttpStatus.OK) // @UseCache({ isExpress: true }) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.USER) async getRetireRequests(@Req() req, @Response() res): Promise { - await checkPermission( - UserRole.STANDARD_REGISTRY, - UserRole.USER - )(req.user); try { const user = req.user; const guardians = new Guardians(); @@ -1132,7 +1126,7 @@ export class ContractsApi { req.query.pageSize as any ); res.locals.data = contracts - return res.setHeader('X-Total-Count', count).json(contracts); + return res.header('X-Total-Count', count).send(contracts); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException( @@ -1207,11 +1201,8 @@ export class ContractsApi { }) @HttpCode(HttpStatus.OK) // @UseCache({ isExpress: true }) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.USER) async getRetirePools(@Req() req, @Response() res): Promise { - await checkPermission( - UserRole.STANDARD_REGISTRY, - UserRole.USER - )(req.user); try { const user = req.user; const guardians = new Guardians(); @@ -1223,7 +1214,7 @@ export class ContractsApi { req.query.pageSize as any ); res.locals.data = contracts - return res.setHeader('X-Total-Count', count).json(contracts); + return res.header('X-Total-Count', count).send(contracts); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException( @@ -1263,12 +1254,12 @@ export class ContractsApi { type: InternalServerErrorDTO, }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async clearRetireRequests(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const guardians = new Guardians(); - return res.json( + return res.send( await guardians.clearRetireRequests( user.did, req.params.contractId @@ -1313,12 +1304,12 @@ export class ContractsApi { type: InternalServerErrorDTO, }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async clearRetirePools(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const guardians = new Guardians(); - return res.json( + return res.send( await guardians.clearRetirePools( user.did, req.params.contractId @@ -1366,12 +1357,12 @@ export class ContractsApi { type: InternalServerErrorDTO, }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async setRetirePool(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const guardians = new Guardians(); - return res.json( + return res.send( await guardians.setRetirePool( user.did, req.params.contractId, @@ -1417,12 +1408,12 @@ export class ContractsApi { type: InternalServerErrorDTO, }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async unsetRetirePool(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const guardians = new Guardians(); - return res.json( + return res.send( await guardians.unsetRetirePool(user.did, req.params.poolId) ); } catch (error) { @@ -1464,12 +1455,12 @@ export class ContractsApi { type: InternalServerErrorDTO, }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async unsetRetireRequest(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const guardians = new Guardians(); - return res.json( + return res.send( await guardians.unsetRetireRequest( user.did, req.params.requestId @@ -1516,15 +1507,12 @@ export class ContractsApi { type: InternalServerErrorDTO, }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.USER) async retire(@Req() req, @Response() res): Promise { - await checkPermission( - UserRole.STANDARD_REGISTRY, - UserRole.USER - )(req.user); try { const user = req.user; const guardians = new Guardians(); - return res.json( + return res.send( await guardians.retire(user.did, req.params.poolId, req.body) ); } catch (error) { @@ -1565,12 +1553,12 @@ export class ContractsApi { type: InternalServerErrorDTO, }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async approveRetire(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const guardians = new Guardians(); - return res.json( + return res.send( await guardians.approveRetire(user.did, req.params.requestId) ); } catch (error) { @@ -1610,15 +1598,12 @@ export class ContractsApi { type: InternalServerErrorDTO, }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.USER) async cancelRetireRequest(@Req() req, @Response() res): Promise { - await checkPermission( - UserRole.STANDARD_REGISTRY, - UserRole.USER - )(req.user); try { const user = req.user; const guardians = new Guardians(); - return res.json( + return res.send( await guardians.cancelRetire(user.did, req.params.requestId) ); } catch (error) { @@ -1666,12 +1651,12 @@ export class ContractsApi { type: InternalServerErrorDTO, }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async retireAddAdmin(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const guardians = new Guardians(); - return res.json( + return res.send( await guardians.addRetireAdmin( user.did, req.params.contractId, @@ -1723,12 +1708,12 @@ export class ContractsApi { type: InternalServerErrorDTO, }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async retireRemoveAdmin(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const guardians = new Guardians(); - return res.json( + return res.send( await guardians.removeRetireAdmin( user.did, req.params.contractId, @@ -1795,11 +1780,8 @@ export class ContractsApi { }) @HttpCode(HttpStatus.OK) // @UseCache({ isExpress: true }) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.USER) async getRetireVCs(@Req() req, @Response() res): Promise { - await checkPermission( - UserRole.STANDARD_REGISTRY, - UserRole.USER - )(req.user); try { const user = req.user; const guardians = new Guardians(); @@ -1809,7 +1791,7 @@ export class ContractsApi { req.query.pageSize as any ); res.locals.data = vcs - return res.setHeader('X-Total-Count', count).json(vcs); + return res.header('X-Total-Count', count).send(vcs); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException( diff --git a/api-gateway/src/api/service/logger.ts b/api-gateway/src/api/service/logger.ts index 3b13125e9a..515b06308b 100644 --- a/api-gateway/src/api/service/logger.ts +++ b/api-gateway/src/api/service/logger.ts @@ -2,10 +2,10 @@ import { IPageParameters, MessageAPI, UserRole } from '@guardian/interfaces'; import { Logger } from '@guardian/common'; import { Controller, Get, HttpCode, HttpStatus, Inject, Injectable, Post, Req, Response } from '@nestjs/common'; import { ClientProxy } from '@nestjs/microservices'; -import { checkPermission } from '../../auth/authorization-helper.js'; import { ApiTags } from '@nestjs/swagger'; import axios from 'axios'; import { UseCache } from '../../helpers/decorators/cache.js'; +import { Auth } from '../../auth/auth.decorator.js'; @Injectable() export class LoggerService { @@ -35,8 +35,8 @@ export class LoggerApi { @Post('/') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async getLogs(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const filters: any = {}; const pageParameters: IPageParameters = {}; @@ -85,8 +85,8 @@ export class LoggerApi { @Get('attributes') @HttpCode(HttpStatus.OK) @UseCache() + @Auth(UserRole.STANDARD_REGISTRY) async getAttributes(@Req() req): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { if (req.query.existingAttributes && !Array.isArray(req.query.existingAttributes)) { req.query.existingAttributes = [req.query.existingAttributes as string]; diff --git a/api-gateway/src/api/service/module.ts b/api-gateway/src/api/service/module.ts index 2b416f440d..b66a61e6c2 100644 --- a/api-gateway/src/api/service/module.ts +++ b/api-gateway/src/api/service/module.ts @@ -1,13 +1,13 @@ import { Logger } from '@guardian/common'; import { Guardians } from '../../helpers/guardians.js'; import { Controller, Delete, Get, HttpCode, HttpException, HttpStatus, Post, Put, Query, Req, Res, Response } from '@nestjs/common'; -import { checkPermission } from '../../auth/authorization-helper.js'; import { SchemaCategory, SchemaHelper, UserRole } from '@guardian/interfaces'; import { ApiForbiddenResponse, ApiInternalServerErrorResponse, ApiOkResponse, ApiOperation, ApiSecurity, ApiTags, ApiUnauthorizedResponse, getSchemaPath } from '@nestjs/swagger'; import { InternalServerErrorDTO } from '../../middlewares/validation/schemas/errors.js'; import { ApiImplicitQuery } from '@nestjs/swagger/dist/decorators/api-implicit-query.decorator.js'; import { SchemaUtils } from '../../helpers/schema-utils.js'; import { UseCache } from '../../helpers/decorators/cache.js'; +import { Auth } from '../../auth/auth.decorator.js'; @Controller('modules') @ApiTags('modules') @@ -28,8 +28,8 @@ export class ModulesApi { }) @Post('/') @HttpCode(HttpStatus.CREATED) + @Auth(UserRole.STANDARD_REGISTRY) async postModules(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const guardian = new Guardians(); const module = req.body; @@ -37,7 +37,7 @@ export class ModulesApi { throw new HttpException('Invalid module config', HttpStatus.UNPROCESSABLE_ENTITY); } const item = await guardian.createModule(module, req.user.did); - return res.status(201).json(item); + return res.status(201).send(item); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -122,8 +122,8 @@ export class ModulesApi { }) @Get('/') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async getModules(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const guardians = new Guardians(); @@ -138,7 +138,7 @@ export class ModulesApi { pageIndex, pageSize }); - return res.setHeader('X-Total-Count', count).json(items); + return res.header('X-Total-Count', count).send(items); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -155,6 +155,7 @@ export class ModulesApi { @Get('/schemas') @HttpCode(HttpStatus.OK) @UseCache({ isExpress: true }) + @Auth(UserRole.STANDARD_REGISTRY) async getModuleSchemas( @Req() req, @Res() res, @@ -162,7 +163,6 @@ export class ModulesApi { @Query('pageSize') pageSize, @Query('topicId') topicId ): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const guardians = new Guardians(); @@ -180,8 +180,8 @@ export class ModulesApi { }); res.locals.data = SchemaUtils.toOld(items) return res - .setHeader('X-Total-Count', count) - .json(SchemaUtils.toOld(items)); + .header('X-Total-Count', count) + .send(SchemaUtils.toOld(items)); } catch (error) { await (new Logger()).error(error, ['API_GATEWAY']); throw error; @@ -190,8 +190,8 @@ export class ModulesApi { @Post('/schemas') @HttpCode(HttpStatus.CREATED) + @Auth(UserRole.STANDARD_REGISTRY) async postSchemas(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const newSchema = req.body; @@ -214,7 +214,7 @@ export class ModulesApi { SchemaHelper.updateOwner(newSchema, owner); const schema = await guardians.createSchema(newSchema); - return res.status(201).json(SchemaUtils.toOld(schema)); + return res.status(201).send(SchemaUtils.toOld(schema)); } catch (error) { await (new Logger()).error(error, ['API_GATEWAY']); throw error; @@ -228,15 +228,15 @@ export class ModulesApi { @ApiSecurity('bearerAuth') @Delete('/:uuid') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async deleteModule(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const guardian = new Guardians(); if (!req.params.uuid) { throw new Error('Invalid uuid') } const result = await guardian.deleteModule(req.params.uuid, req.user.did); - return res.status(200).json(result); + return res.status(200).send(result); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -271,8 +271,8 @@ export class ModulesApi { @Get('/menu') @HttpCode(HttpStatus.OK) @UseCache() + @Auth(UserRole.STANDARD_REGISTRY) async getMenu(@Req() req): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const guardians = new Guardians(); return await guardians.getMenuModule(req.user.did); @@ -310,15 +310,15 @@ export class ModulesApi { }) @Get('/:uuid') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async getModule(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const guardian = new Guardians(); if (!req.params.uuid) { throw new HttpException('Invalid uuid', HttpStatus.UNPROCESSABLE_ENTITY) } const item = await guardian.getModuleById(req.params.uuid, req.user.did); - return res.json(item); + return res.send(item); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -349,8 +349,8 @@ export class ModulesApi { }) @Put('/:uuid') @HttpCode(HttpStatus.CREATED) + @Auth(UserRole.STANDARD_REGISTRY) async putModule(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); if (!req.params.uuid) { throw new HttpException('Invalid uuid', HttpStatus.UNPROCESSABLE_ENTITY); } @@ -361,7 +361,7 @@ export class ModulesApi { } try { const result = await guardian.updateModule(req.params.uuid, module, req.user.did); - return res.status(201).json(result); + return res.status(201).send(result); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -392,13 +392,13 @@ export class ModulesApi { }) @Get('/:uuid/export/file') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async moduleExportFile(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const guardian = new Guardians(); try { const file: any = await guardian.exportModuleFile(req.params.uuid, req.user.did); - res.setHeader('Content-disposition', `attachment; filename=module_${Date.now()}`); - res.setHeader('Content-type', 'application/zip'); + res.header('Content-disposition', `attachment; filename=module_${Date.now()}`); + res.header('Content-type', 'application/zip'); return res.send(file); } catch (error) { new Logger().error(error, ['API_GATEWAY']); @@ -430,8 +430,8 @@ export class ModulesApi { }) @Get('/:uuid/export/message') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async moduleExportMessage(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const guardian = new Guardians(); try { return res.send(await guardian.exportModuleMessage(req.params.uuid, req.user.did)); @@ -465,8 +465,8 @@ export class ModulesApi { }) @Post('/import/message') @HttpCode(HttpStatus.CREATED) + @Auth(UserRole.STANDARD_REGISTRY) async moduleImportMessage(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const guardian = new Guardians(); try { const module = await guardian.importModuleMessage(req.body.messageId, req.user.did); @@ -501,8 +501,8 @@ export class ModulesApi { }) @Post('/import/file') @HttpCode(HttpStatus.CREATED) + @Auth(UserRole.STANDARD_REGISTRY) async moduleImportFile(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const guardian = new Guardians(); try { const module = await guardian.importModuleFile(req.body, req.user.did); @@ -537,8 +537,8 @@ export class ModulesApi { }) @Post('/import/message/preview') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async moduleImportMessagePreview(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const guardian = new Guardians(); try { const module = await guardian.previewModuleMessage(req.body.messageId, req.user.did); @@ -573,8 +573,8 @@ export class ModulesApi { }) @Post('/import/file/preview') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async moduleImportFilePreview(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const guardian = new Guardians(); try { const module = await guardian.previewModuleFile(req.body, req.user.did); @@ -609,12 +609,12 @@ export class ModulesApi { }) @Put('/:uuid/publish') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async publishModule(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const guardian = new Guardians(); try { const module = await guardian.publishModule(req.params.uuid, req.user.did, req.body); - return res.json(module); + return res.send(module); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -645,8 +645,8 @@ export class ModulesApi { }) @Post('/validate') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async validateModule(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const guardian = new Guardians(); try { return res.send(await guardian.validateModule(req.user.did, req.body)); diff --git a/api-gateway/src/api/service/notifications.ts b/api-gateway/src/api/service/notifications.ts index 1ffa720cc7..f3229cc187 100644 --- a/api-gateway/src/api/service/notifications.ts +++ b/api-gateway/src/api/service/notifications.ts @@ -4,6 +4,8 @@ import { InternalServerErrorDTO } from '../../middlewares/validation/schemas/err import { NotificationDTO, ProgressDTO, } from '../../middlewares/validation/schemas/notifications.js'; import { Controller, Delete, Get, HttpCode, HttpStatus, Post, Req, Response, UseGuards, } from '@nestjs/common'; import { ApiBearerAuth, ApiExtraModels, ApiInternalServerErrorResponse, ApiOkResponse, ApiOperation, ApiParam, ApiSecurity, ApiTags, ApiUnauthorizedResponse, getSchemaPath, } from '@nestjs/swagger'; +import { Auth } from '../../auth/auth.decorator.js'; +import { UserRole } from '@guardian/interfaces'; @Controller('notifications') @ApiTags('notifications') @@ -44,6 +46,7 @@ export class NotificationsApi { @UseGuards(AuthGuard) @Get('/') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER) async getAllNotifications(@Req() req, @Response() res) { try { let pageIndex: number; @@ -57,7 +60,7 @@ export class NotificationsApi { pageIndex, pageSize ); - return res.setHeader('X-Total-Count', count).json(notifications); + return res.header('X-Total-Count', count).send(notifications); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw error; @@ -93,12 +96,13 @@ export class NotificationsApi { @UseGuards(AuthGuard) @Get('/new') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER) async getNewNotifications(@Req() req, @Response() res): Promise { try { if (!req.user.id) { throw Error('User is not registered'); } - return res.json( + return res.send( await this.notifier.getNewNotifications(req.user.id) ); } catch (error) { @@ -136,12 +140,13 @@ export class NotificationsApi { @UseGuards(AuthGuard) @Get('/progresses') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER) async getProgresses(@Req() req, @Response() res): Promise { try { if (!req.user.id) { throw Error('User is not registered'); } - return res.json(await this.notifier.getProgresses(req.user.id)); + return res.send(await this.notifier.getProgresses(req.user.id)); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw error; @@ -177,12 +182,13 @@ export class NotificationsApi { @UseGuards(AuthGuard) @Post('/read/all') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER) async readAll(@Req() req, @Response() res): Promise { try { if (!req.user.id) { throw Error('User is not registered'); } - return res.json(await this.notifier.readAll(req.user.id)); + return res.send(await this.notifier.readAll(req.user.id)); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw error; @@ -219,9 +225,10 @@ export class NotificationsApi { @UseGuards(AuthGuard) @Delete('/delete/:notificationId') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER) async delete(@Req() req, @Response() res) { try { - return res.json( + return res.send( await this.notifier.deleteUpTo( req.user.id, req.params.notificationId diff --git a/api-gateway/src/api/service/policy.ts b/api-gateway/src/api/service/policy.ts index 78a9706595..c381a39886 100644 --- a/api-gateway/src/api/service/policy.ts +++ b/api-gateway/src/api/service/policy.ts @@ -1,5 +1,5 @@ import { Auth } from '../../auth/auth.decorator.js'; -import { AuthUser, checkPermission } from '../../auth/authorization-helper.js'; +import { AuthUser } from '../../auth/authorization-helper.js'; import { IAuthUser, Logger, RunFunctionAsync } from '@guardian/common'; import { DocumentType, PolicyType, TaskAction, UserRole } from '@guardian/interfaces'; import { PolicyEngine } from '../../helpers/policy-engine.js'; @@ -54,14 +54,14 @@ export class PolicyApi { @ApiSecurity('bearerAuth') @Get('/') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.USER, UserRole.AUDITOR) async getPolicies(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY, UserRole.USER, UserRole.AUDITOR)(req.user); const users = new Users(); const engineService = new PolicyEngine(); try { const user = await users.getUser(req.user.username); if (!user.did && user.role !== UserRole.AUDITOR) { - return res.setHeader('X-Total-Count', 0).json([]); + return res.header('X-Total-Count', 0).send([]); } let pageIndex: any; let pageSize: any; @@ -104,7 +104,7 @@ export class PolicyApi { }); } const { policies, count } = result; - return res.setHeader('X-Total-Count', count).json(policies); + return res.header('X-Total-Count', count).send(policies); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -131,12 +131,12 @@ export class PolicyApi { @ApiSecurity('bearerAuth') @Post('/') @HttpCode(HttpStatus.CREATED) + @Auth(UserRole.STANDARD_REGISTRY) async createPolicy(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const engineService = new PolicyEngine(); try { const policies = await engineService.createPolicy(req.body, req.user) - return res.status(201).json(policies); + return res.status(201).send(policies); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -180,8 +180,8 @@ export class PolicyApi { @ApiSecurity('bearerAuth') @Post('/migrate-data') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async migrateData(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const engineService = new PolicyEngine(); try { return res.send(await engineService.migrateData( @@ -220,8 +220,8 @@ export class PolicyApi { @ApiSecurity('bearerAuth') @Post('/push/migrate-data') @HttpCode(HttpStatus.ACCEPTED) + @Auth(UserRole.STANDARD_REGISTRY) async migrateDataAsync(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const user = req.user; const taskManager = new TaskManager(); const task = taskManager.start(TaskAction.MIGRATE_DATA, user.id); @@ -255,8 +255,8 @@ export class PolicyApi { @ApiSecurity('bearerAuth') @Post('/push') @HttpCode(HttpStatus.ACCEPTED) + @Auth(UserRole.STANDARD_REGISTRY) async createPolicyAsync(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const model = req.body; const user = req.user; const taskManager = new TaskManager(); @@ -288,8 +288,8 @@ export class PolicyApi { @ApiSecurity('bearerAuth') @Post('/push/:policyId') @HttpCode(HttpStatus.ACCEPTED) + @Auth(UserRole.STANDARD_REGISTRY) async updatePolicyAsync(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const policyId = req.params.policyId; const model = req.body; const user = req.user; @@ -308,8 +308,8 @@ export class PolicyApi { @ApiSecurity('bearerAuth') @Delete('/push/:policyId') @HttpCode(HttpStatus.ACCEPTED) + @Auth(UserRole.STANDARD_REGISTRY) async deletePolicyAsync(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const policyId = req.params.policyId; const user = req.user; const taskManager = new TaskManager(); @@ -344,8 +344,8 @@ export class PolicyApi { @ApiSecurity('bearerAuth') @Get('/:policyId') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.USER, UserRole.AUDITOR) async getPolicy(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY, UserRole.USER, UserRole.AUDITOR)(req.user); const users = new Users(); const engineService = new PolicyEngine(); try { @@ -381,8 +381,8 @@ export class PolicyApi { @ApiSecurity('bearerAuth') @Put('/:policyId') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async updatePolicy(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const engineService = new PolicyEngine(); let model: any; try { @@ -409,7 +409,7 @@ export class PolicyApi { model.categories = policy.categories; model.projectSchema = policy.projectSchema; const result = await engineService.savePolicy(model, req.user, req.params.policyId); - return res.json(result); + return res.send(result); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -436,11 +436,11 @@ export class PolicyApi { @ApiSecurity('bearerAuth') @Put('/:policyId/publish') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async publishPolicy(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const engineService = new PolicyEngine(); try { - return res.json(await engineService.publishPolicy(req.body, req.user, req.params.policyId)); + return res.send(await engineService.publishPolicy(req.body, req.user, req.params.policyId)); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -467,8 +467,8 @@ export class PolicyApi { @ApiSecurity('bearerAuth') @Put('/push/:policyId/publish') @HttpCode(HttpStatus.ACCEPTED) + @Auth(UserRole.STANDARD_REGISTRY) async publishPolicyAsync(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const model = req.body; const user = req.user; const policyId = req.params.policyId; @@ -505,11 +505,11 @@ export class PolicyApi { @ApiSecurity('bearerAuth') @Put('/:policyId/dry-run') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async dryRunPolicy(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const engineService = new PolicyEngine(); try { - return res.json(await engineService.dryRunPolicy(req.user, req.params.policyId)); + return res.send(await engineService.dryRunPolicy(req.user, req.params.policyId)); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -556,11 +556,11 @@ export class PolicyApi { @ApiSecurity('bearerAuth') @Put('/:policyId/discontinue') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async discontinuePolicy(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const engineService = new PolicyEngine(); try { - return res.json(await engineService.discontinuePolicy(req.user, req.params.policyId, req.body?.date)); + return res.send(await engineService.discontinuePolicy(req.user, req.params.policyId, req.body?.date)); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -587,11 +587,11 @@ export class PolicyApi { @ApiSecurity('bearerAuth') @Put('/:policyId/draft') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async draftPolicy(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const engineService = new PolicyEngine(); try { - return res.json(await engineService.draft(req.user, req.params.policyId)); + return res.send(await engineService.draft(req.user, req.params.policyId)); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -618,8 +618,8 @@ export class PolicyApi { @ApiSecurity('bearerAuth') @Post('/validate') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async validatePolicy(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const engineService = new PolicyEngine(); try { return res.send(await engineService.validatePolicy(req.body, req.user)); @@ -654,8 +654,8 @@ export class PolicyApi { @Get('/:policyId/navigation') @HttpCode(HttpStatus.OK) // @UseCache() + @Auth(UserRole.STANDARD_REGISTRY, UserRole.USER) async getPolicyNavigation(@Req() req): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY, UserRole.USER)(req.user); const engineService = new PolicyEngine(); try { return await engineService.getNavigation(req.user, req.params.policyId); @@ -690,8 +690,8 @@ export class PolicyApi { @Get('/:policyId/groups') @HttpCode(HttpStatus.OK) // @UseCache() + @Auth(UserRole.STANDARD_REGISTRY, UserRole.USER) async getPolicyGroups(@Req() req): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY, UserRole.USER)(req.user); const engineService = new PolicyEngine(); try { return await engineService.getGroups(req.user, req.params.policyId); @@ -755,8 +755,8 @@ export class PolicyApi { @ApiSecurity('bearerAuth') @Get('/:policyId/documents') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async getPolicyDocuments(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const engineService = new PolicyEngine(); try { const [documents, count] = await engineService.getDocuments( @@ -767,7 +767,7 @@ export class PolicyApi { req.query?.pageIndex, req.query?.pageSize, ); - return res.setHeader('X-Total-Count', count).json(documents); + return res.header('X-Total-Count', count).send(documents); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -801,8 +801,8 @@ export class PolicyApi { @ApiSecurity('bearerAuth') @Get('/:policyId/data') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async downloadPolicyData(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const engineService = new PolicyEngine(); try { const policy = await engineService.getPolicy({ @@ -859,8 +859,8 @@ export class PolicyApi { @ApiSecurity('bearerAuth') @Post('/data') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async uploadPolicyData(@Req() req): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const engineService = new PolicyEngine(); try { return await engineService.uploadPolicyData(req.user.did, req.body); @@ -899,8 +899,8 @@ export class PolicyApi { @ApiSecurity('bearerAuth') @Get('/:policyId/tag-block-map') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async getTagBlockMap(@Req() req): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const engineService = new PolicyEngine(); try { return await engineService.getTagBlockMap( @@ -943,8 +943,8 @@ export class PolicyApi { @ApiSecurity('bearerAuth') @Get('/:policyId/virtual-keys') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async downloadVirtualKeys(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const engineService = new PolicyEngine(); try { const policy = await engineService.getPolicy({ @@ -1003,8 +1003,8 @@ export class PolicyApi { @ApiSecurity('bearerAuth') @Post('/:policyId/virtual-keys') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async uploadVirtualKeys(@Req() req): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const engineService = new PolicyEngine(); try { return await engineService.uploadVirtualKeys( @@ -1041,8 +1041,8 @@ export class PolicyApi { @ApiSecurity('bearerAuth') @Post('/:policyId/groups') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.USER) async setPolicyGroups(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY, UserRole.USER)(req.user); const engineService = new PolicyEngine(); try { return res.send(await engineService.selectGroup(req.user, req.params.policyId, req.body.uuid)); @@ -1076,8 +1076,8 @@ export class PolicyApi { @ApiSecurity('bearerAuth') @Get('/:policyId/blocks') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.USER) async getPolicyBlocks(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY, UserRole.USER)(req.user); const engineService = new PolicyEngine(); try { return res.send(await engineService.getPolicyBlocks(req.user, req.params.policyId)); @@ -1107,8 +1107,8 @@ export class PolicyApi { @ApiSecurity('bearerAuth') @Get('/:policyId/blocks/:uuid') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.USER) async getBlockData(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY, UserRole.USER)(req.user); const engineService = new PolicyEngine(); try { return res.send(await engineService.getBlockData(req.user, req.params.policyId, req.params.uuid)); @@ -1138,8 +1138,8 @@ export class PolicyApi { @ApiSecurity('bearerAuth') @Post('/:policyId/blocks/:uuid') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.USER) async setBlockData(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY, UserRole.USER)(req.user); const engineService = new PolicyEngine(); try { return res.send( @@ -1171,8 +1171,8 @@ export class PolicyApi { @ApiSecurity('bearerAuth') @Post('/:policyId/tag/:tagName/blocks') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.USER) async setBlocksByTagName(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY, UserRole.USER)(req.user); const engineService = new PolicyEngine(); try { return res.send(await engineService.setBlockDataByTag(req.user, req.params.policyId, req.params.tagName, req.body)); @@ -1202,8 +1202,8 @@ export class PolicyApi { @ApiSecurity('bearerAuth') @Get('/:policyId/tag/:tagName') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.USER) async getBlockByTagName(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY, UserRole.USER)(req.user); const engineService = new PolicyEngine(); try { return res.send(await engineService.getBlockByTagName(req.user, req.params.policyId, req.params.tagName)); @@ -1233,8 +1233,8 @@ export class PolicyApi { @ApiSecurity('bearerAuth') @Get('/:policyId/tag/:tagName/blocks') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.USER) async getBlocksByTagName(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY, UserRole.USER)(req.user); const engineService = new PolicyEngine(); try { return res.send(await engineService.getBlockDataByTag(req.user, req.params.policyId, req.params.tagName)); @@ -1246,8 +1246,8 @@ export class PolicyApi { @Get('/:policyId/blocks/:uuid/parents') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.USER) async getBlockParents(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY, UserRole.USER)(req.user); const engineService = new PolicyEngine(); try { return res.send(await engineService.getBlockParents(req.user, req.params.policyId, req.params.uuid)); @@ -1303,8 +1303,8 @@ export class PolicyApi { const engineService = new PolicyEngine(); const policyFile: any = await engineService.exportFile(user, policyId); const policy: any = await engineService.getPolicy({ filters: policyId }); - res.setHeader('Content-disposition', `attachment; filename=${policy.name}`); - res.setHeader('Content-type', 'application/zip'); + res.header('Content-disposition', `attachment; filename=${policy.name}`); + res.header('Content-type', 'application/zip'); return res.send(policyFile); } catch (error) { new Logger().error(error, ['API_GATEWAY']); @@ -1408,8 +1408,8 @@ export class PolicyApi { const engineService = new PolicyEngine(); const policyFile: any = await engineService.exportXlsx(user, policyId); const policy: any = await engineService.getPolicy({ filters: policyId }); - res.setHeader('Content-disposition', `attachment; filename=${policy.name}`); - res.setHeader('Content-type', 'application/zip'); + res.header('Content-disposition', `attachment; filename=${policy.name}`); + res.header('Content-type', 'application/zip'); return res.send(policyFile); } catch (error) { new Logger().error(error, ['API_GATEWAY']); @@ -1437,8 +1437,8 @@ export class PolicyApi { @ApiSecurity('bearerAuth') @Post('/import/message') @HttpCode(HttpStatus.CREATED) + @Auth(UserRole.STANDARD_REGISTRY) async importPolicyFromMessage(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const engineService = new PolicyEngine(); const versionOfTopicId = req.query ? req.query.versionOfTopicId : null; try { @@ -1478,8 +1478,8 @@ export class PolicyApi { @ApiSecurity('bearerAuth') @Post('/push/import/message') @HttpCode(HttpStatus.ACCEPTED) + @Auth(UserRole.STANDARD_REGISTRY) async importPolicyFromMessageAsync(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const user = req.user; const messageId = req.body.messageId; const versionOfTopicId = req.query ? req.query.versionOfTopicId : null; @@ -1530,8 +1530,8 @@ export class PolicyApi { @ApiSecurity('bearerAuth') @Post('/import/message/preview') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async importMessage(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const engineService = new PolicyEngine(); try { return res.send(await engineService.importMessagePreview(req.user, req.body.messageId)); @@ -1561,8 +1561,8 @@ export class PolicyApi { @ApiSecurity('bearerAuth') @Post('/push/import/message/preview') @HttpCode(HttpStatus.ACCEPTED) + @Auth(UserRole.STANDARD_REGISTRY) async importFromMessagePreview(@Req() req, @Response() res) { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const user = req.user; const messageId = req.body.messageId; const taskManager = new TaskManager(); @@ -1693,6 +1693,7 @@ export class PolicyApi { @UploadedFiles() files: any, @Query('versionOfTopicId') versionOfTopicId, ): Promise { + console.log('multipart/form-data'); try { const policyFile = files.find( (item) => item.fieldname === 'policyFile' @@ -2094,8 +2095,8 @@ export class PolicyApi { @Get('/blocks/about') @HttpCode(HttpStatus.OK) @UseCache({ ttl: CACHE.LONG_TTL }) + @Auth(UserRole.STANDARD_REGISTRY) async getBlockAbout(@Req() req) { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const engineService = new PolicyEngine(); try { return await engineService.blockAbout(); @@ -2107,8 +2108,8 @@ export class PolicyApi { @Get('/:policyId/dry-run/users') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async getDryRunUsers(@Req() req, @Response() res) { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const engineService = new PolicyEngine(); let policy; try { @@ -2136,8 +2137,8 @@ export class PolicyApi { @Post('/:policyId/dry-run/user') @HttpCode(HttpStatus.CREATED) + @Auth(UserRole.STANDARD_REGISTRY) async setDryRunUser(@Req() req, @Response() res) { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const engineService = new PolicyEngine(); let policy; try { @@ -2165,8 +2166,8 @@ export class PolicyApi { @Post('/:policyId/dry-run/login') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async loginDryRunUser(@Req() req, @Response() res) { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const engineService = new PolicyEngine(); let policy; try { @@ -2194,8 +2195,8 @@ export class PolicyApi { @Post('/:policyId/dry-run/restart') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async restartDryRun(@Req() req, @Response() res) { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const engineService = new PolicyEngine(); let policy; try { @@ -2214,7 +2215,7 @@ export class PolicyApi { throw new HttpException('Invalid status.', HttpStatus.FORBIDDEN) } try { - return res.json(await engineService.restartDryRun(req.body, req.user, req.params.policyId)); + return res.send(await engineService.restartDryRun(req.body, req.user, req.params.policyId)); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -2223,8 +2224,8 @@ export class PolicyApi { @Get('/:policyId/dry-run/transactions') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async getDryRunTransactions(@Req() req, @Response() res) { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const engineService = new PolicyEngine(); let policy; try { @@ -2247,7 +2248,7 @@ export class PolicyApi { pageSize = req.query.pageSize; } const [data, count] = await engineService.getVirtualDocuments(req.params.policyId, 'transactions', pageIndex, pageSize) - return res.setHeader('X-Total-Count', count).json(data); + return res.setHeader('X-Total-Count', count).send(data); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -2256,8 +2257,8 @@ export class PolicyApi { @Get('/:policyId/dry-run/artifacts') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async getDryRunArtifacts(@Req() req, @Response() res) { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const engineService = new PolicyEngine(); let policy; try { @@ -2281,7 +2282,7 @@ export class PolicyApi { pageSize = req.query.pageSize; } const [data, count] = await engineService.getVirtualDocuments(req.params.policyId, 'artifacts', pageIndex, pageSize); - return res.setHeader('X-Total-Count', count).json(data); + return res.setHeader('X-Total-Count', count).send(data); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -2290,8 +2291,8 @@ export class PolicyApi { @Get('/:policyId/dry-run/ipfs') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async getDryRunIpfs(@Req() req, @Response() res) { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const engineService = new PolicyEngine(); let policy; try { @@ -2314,7 +2315,7 @@ export class PolicyApi { pageSize = req.query.pageSize; } const [data, count] = await engineService.getVirtualDocuments(req.params.policyId, 'ipfs', pageIndex, pageSize) - return res.setHeader('X-Total-Count', count).json(data); + return res.setHeader('X-Total-Count', count).send(data); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -2323,8 +2324,8 @@ export class PolicyApi { @Get('/:policyId/multiple') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.USER) async getMultiplePolicies(@Req() req, @Response() res) { - await checkPermission(UserRole.STANDARD_REGISTRY, UserRole.USER)(req.user); const engineService = new PolicyEngine(); try { return res.send(await engineService.getMultiPolicy(req.user, req.params.policyId)); @@ -2336,8 +2337,8 @@ export class PolicyApi { @Post('/:policyId/multiple/') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.USER) async setMultiplePolicies(@Req() req, @Response() res) { - await checkPermission(UserRole.STANDARD_REGISTRY, UserRole.USER)(req.user); const engineService = new PolicyEngine(); try { return res.send(await engineService.setMultiPolicy(req.user, req.params.policyId, req.body)); diff --git a/api-gateway/src/api/service/record.ts b/api-gateway/src/api/service/record.ts index c0d186a390..db11cea3b5 100644 --- a/api-gateway/src/api/service/record.ts +++ b/api-gateway/src/api/service/record.ts @@ -195,8 +195,8 @@ export class RecordApi { try { const guardians = new Guardians(); const result = await guardians.stopRecording(policyId, user.did, options); - res.setHeader('Content-disposition', `attachment; filename=${Date.now()}`); - res.setHeader('Content-type', 'application/zip'); + res.header('Content-disposition', `attachment; filename=${Date.now()}`); + res.header('Content-type', 'application/zip'); return res.send(result); } catch (error) { new Logger().error(error, ['API_GATEWAY']); diff --git a/api-gateway/src/api/service/schema.ts b/api-gateway/src/api/service/schema.ts index 6ac7934b06..3427cf52b6 100644 --- a/api-gateway/src/api/service/schema.ts +++ b/api-gateway/src/api/service/schema.ts @@ -4,7 +4,7 @@ import { IAuthUser, Logger, RunFunctionAsync, SchemaImportExport } from '@guardi import { ApiBody, ApiExtraModels, ApiForbiddenResponse, ApiInternalServerErrorResponse, ApiOkResponse, ApiOperation, ApiSecurity, ApiTags, ApiUnauthorizedResponse } from '@nestjs/swagger'; import { Body, Controller, Delete, Get, HttpCode, HttpException, HttpStatus, Param, Post, Put, Req, Response } from '@nestjs/common'; import process from 'process'; -import { AuthUser, checkPermission } from '../../auth/authorization-helper.js'; +import { AuthUser } from '../../auth/authorization-helper.js'; import { Client, ClientProxy, Transport } from '@nestjs/microservices'; import { TaskManager } from '../../helpers/task-manager.js'; import { ServiceError } from '../../helpers/service-requests-base.js'; @@ -134,8 +134,8 @@ export class SingleSchemaApi { @Get('/:schemaId') @HttpCode(HttpStatus.OK) @UseCache({ ttl: CACHE.SHORT_TTL }) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER) async getSchema(@Req() req): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER)(req.user); try { const user = req.user; const schemaId = req.params.schemaId; @@ -193,8 +193,8 @@ export class SingleSchemaApi { description: 'Internal server error.', type: InternalServerErrorDTO }) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER) async getSchemaParents(@Req() req): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER)(req.user); try { const user = req.user; const schemaId = req.params.schemaId; @@ -251,8 +251,8 @@ export class SingleSchemaApi { description: 'Internal server error.', type: InternalServerErrorDTO }) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER) async getSchemaTree(@Req() req): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER)(req.user); try { const user = req.user; const schemaId = req.params.schemaId; @@ -363,15 +363,15 @@ export class SchemaApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER) async getSchemasPage(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER)(req.user); try { const guardians = new Guardians(); const user = req.user; const options: any = prepareSchemaPagination(req, user); const { items, count } = await guardians.getSchemasByOwner(options); SchemaHelper.updatePermission(items, user.did); - return res.setHeader('X-Total-Count', count).json(SchemaUtils.toOld(items)); + return res.header('X-Total-Count', count).send(SchemaUtils.toOld(items)); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -439,8 +439,8 @@ export class SchemaApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER) async getSchemasPageByTopicId(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY, UserRole.USER, UserRole.AUDITOR)(req.user); try { const guardians = new Guardians(); const user = req.user; @@ -448,7 +448,7 @@ export class SchemaApi { const options = prepareSchemaPagination(req, user, topicId); const { items, count } = await guardians.getSchemasByOwner(options); SchemaHelper.updatePermission(items, user.did); - return res.setHeader('X-Total-Count', count).json(SchemaUtils.toOld(items)); + return res.header('X-Total-Count', count).send(SchemaUtils.toOld(items)); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -485,8 +485,8 @@ export class SchemaApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER) async getSchemaByType(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY, UserRole.USER, UserRole.AUDITOR)(req.user) let schema: any; try { const guardians = new Guardians(); @@ -541,8 +541,8 @@ export class SchemaApi { }) @HttpCode(HttpStatus.OK) @UseCache() + @Auth(UserRole.STANDARD_REGISTRY) async getAll(@Req() req): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const guardians = new Guardians(); @@ -596,8 +596,8 @@ export class SchemaApi { }) @HttpCode(HttpStatus.OK) @UseCache() + @Auth(UserRole.STANDARD_REGISTRY) async getSub(@Req() req): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const guardians = new Guardians(); if (!req.user.did) { @@ -651,8 +651,8 @@ export class SchemaApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.CREATED) + @Auth(UserRole.STANDARD_REGISTRY) async createNewSchema(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const newSchema = req.body; @@ -663,7 +663,7 @@ export class SchemaApi { user.did, topicId, ); - return res.status(201).json(SchemaUtils.toOld(schemas)); + return res.status(201).send(SchemaUtils.toOld(schemas)); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw error; @@ -749,8 +749,8 @@ export class SchemaApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.ACCEPTED) + @Auth(UserRole.STANDARD_REGISTRY) async createNewSchemaAsync(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const user = req.user; const newSchema = req.body; const topicId = (req.params.topicId === null || req.params.topicId === undefined) ? undefined : req.params.topicId; @@ -802,8 +802,8 @@ export class SchemaApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async setSchema(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const newSchema = req.body; @@ -821,7 +821,7 @@ export class SchemaApi { } SchemaUtils.fromOld(newSchema); const schemas = await updateSchema(newSchema, user.did); - return res.json(SchemaUtils.toOld(schemas)); + return res.send(SchemaUtils.toOld(schemas)); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw error; @@ -860,8 +860,8 @@ export class SchemaApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async deleteSchema(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const user = req.user; const guardians = new Guardians(); const schemaId = req.params.schemaId; @@ -885,7 +885,7 @@ export class SchemaApi { try { const schemas = (await guardians.deleteSchema(schemaId, user?.did, true) as ISchema[]); SchemaHelper.updatePermission(schemas, user.did); - return res.json(SchemaUtils.toOld(schemas)); + return res.send(SchemaUtils.toOld(schemas)); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -944,8 +944,8 @@ export class SchemaApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async publishSchema(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const user = req.user; const guardians = new Guardians(); const schemaId = req.params.schemaId; @@ -984,7 +984,7 @@ export class SchemaApi { owner: user.did }); SchemaHelper.updatePermission(items, user.did); - return res.setHeader('X-Total-Count', count).json(SchemaUtils.toOld(items)); + return res.header('X-Total-Count', count).send(SchemaUtils.toOld(items)); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -1034,8 +1034,8 @@ export class SchemaApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.ACCEPTED) + @Auth(UserRole.STANDARD_REGISTRY) async publishSchemaAsync(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const user = req.user; const schemaId = req.params.schemaId; const guardians = new Guardians(); @@ -1107,13 +1107,13 @@ export class SchemaApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async importFromMessagePreview(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const messageId = req.body.messageId; const guardians = new Guardians(); const schemaToPreview = await guardians.previewSchemasByMessages([messageId]); - return res.json(schemaToPreview); + return res.send(schemaToPreview); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -1156,8 +1156,8 @@ export class SchemaApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.ACCEPTED) + @Auth(UserRole.STANDARD_REGISTRY) async importFromMessagePreviewAsync(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const user = req.user; const messageId = req.body.messageId; if (!messageId) { @@ -1206,8 +1206,8 @@ export class SchemaApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async importFromFilePreview(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const zip = req.body; if (!zip) { throw new HttpException('File in body is empty', HttpStatus.UNPROCESSABLE_ENTITY) @@ -1216,7 +1216,7 @@ export class SchemaApi { const guardians = new Guardians(); const { schemas } = await SchemaImportExport.parseZipFile(zip); const schemaToPreview = await guardians.previewSchemasByFile(schemas); - return res.json(schemaToPreview); + return res.send(schemaToPreview); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -1275,8 +1275,8 @@ export class SchemaApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.CREATED) + @Auth(UserRole.STANDARD_REGISTRY) async importFromMessage(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const user = req.user; const topicId = req.params.topicId; const guardians = new Guardians(); @@ -1291,7 +1291,7 @@ export class SchemaApi { owner: user.did }); SchemaHelper.updatePermission(items, user.did); - return res.status(201).setHeader('X-Total-Count', count).json(SchemaUtils.toOld(items)); + return res.status(201).header('X-Total-Count', count).send(SchemaUtils.toOld(items)); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -1341,8 +1341,8 @@ export class SchemaApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.ACCEPTED) + @Auth(UserRole.STANDARD_REGISTRY) async importFromMessageAsync(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const user = req.user; const topicId = req.params.topicId; const messageId = req.body.messageId; @@ -1406,8 +1406,8 @@ export class SchemaApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.CREATED) + @Auth(UserRole.STANDARD_REGISTRY) async importToTopicFromFile(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const user = req.user; const guardians = new Guardians(); const zip = req.body; @@ -1423,7 +1423,7 @@ export class SchemaApi { owner: user.did }); SchemaHelper.updatePermission(items, user.did); - return res.status(201).setHeader('X-Total-Count', count).json(SchemaUtils.toOld(items)); + return res.status(201).header('X-Total-Count', count).send(SchemaUtils.toOld(items)); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -1465,8 +1465,8 @@ export class SchemaApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.ACCEPTED) + @Auth(UserRole.STANDARD_REGISTRY) async importToTopicFromFileAsync(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const user = req.user; const zip = req.body; if (!zip) { @@ -1515,8 +1515,8 @@ export class SchemaApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async exportMessage(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const guardians = new Guardians(); const id = req.params.schemaId; @@ -1566,8 +1566,8 @@ export class SchemaApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async exportToFile(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const guardians = new Guardians(); const id = req.params.schemaId; @@ -1586,8 +1586,8 @@ export class SchemaApi { level: 3 } }); - res.setHeader('Content-disposition', `attachment; filename=${name}`); - res.setHeader('Content-type', 'application/zip'); + res.header('Content-disposition', `attachment; filename=${name}`); + res.header('Content-type', 'application/zip'); arcStream.pipe(res); return res; } catch (error) { @@ -1627,8 +1627,8 @@ export class SchemaApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.CREATED) + @Auth(UserRole.STANDARD_REGISTRY) async postSystemSchema(@Body() body: SystemSchemaDTO, @Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const newSchema = body as any; @@ -1651,7 +1651,7 @@ export class SchemaApi { SchemaHelper.updateOwner(newSchema, owner); const schema = await guardians.createSystemSchema(newSchema); - return res.status(201).json(SchemaUtils.toOld(schema)); + return res.status(201).send(SchemaUtils.toOld(schema)); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw error; @@ -1712,8 +1712,8 @@ export class SchemaApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async getSystemSchema(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const guardians = new Guardians(); @@ -1726,7 +1726,7 @@ export class SchemaApi { } const { items, count } = await guardians.getSystemSchemas(owner, pageIndex, pageSize); items.forEach((s) => { s.readonly = s.readonly || s.owner !== owner }); - return res.setHeader('X-Total-Count', count).json(SchemaUtils.toOld(items)); + return res.header('X-Total-Count', count).send(SchemaUtils.toOld(items)); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw error; @@ -1763,8 +1763,8 @@ export class SchemaApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.NO_CONTENT) + @Auth(UserRole.STANDARD_REGISTRY) async deleteSystemSchema(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const guardians = new Guardians(); @@ -1825,8 +1825,8 @@ export class SchemaApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async setSystemSchema(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const newSchema = req.body; @@ -1844,7 +1844,7 @@ export class SchemaApi { } SchemaUtils.fromOld(newSchema); const schemas = await updateSchema(newSchema, user.username); - return res.json(SchemaUtils.toOld(schemas)); + return res.send(SchemaUtils.toOld(schemas)); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw error; @@ -1881,8 +1881,8 @@ export class SchemaApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async activeSystemSchema(@Req() req: any): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const guardians = new Guardians(); const schemaId = req.params.schemaId; @@ -1935,8 +1935,8 @@ export class SchemaApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER) async getSchemaEntity(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY, UserRole.USER, UserRole.AUDITOR)(req.user) try { const guardians = new Guardians(); const schema = await guardians.getSchemaByEntity(req.params.schemaEntity); @@ -2005,8 +2005,8 @@ export class SchemaApi { const guardians = new Guardians(); const file: any = await guardians.exportSchemasXlsx(user, [schemaId]); const schema: any = await guardians.getSchemaById(schemaId); - res.setHeader('Content-disposition', `attachment; filename=${schema.name}`); - res.setHeader('Content-type', 'application/zip'); + res.header('Content-disposition', `attachment; filename=${schema.name}`); + res.header('Content-type', 'application/zip'); return res.send(file); } catch (error) { new Logger().error(error, ['API_GATEWAY']); @@ -2072,7 +2072,7 @@ export class SchemaApi { owner: user.did }); SchemaHelper.updatePermission(items, user.did); - return res.status(201).setHeader('X-Total-Count', count).json(SchemaUtils.toOld(items)); + return res.status(201).header('X-Total-Count', count).send(SchemaUtils.toOld(items)); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -2231,8 +2231,8 @@ export class SchemaApi { const guardians = new Guardians(); const file = await guardians.getFileTemplate(filename); const fileBuffer = Buffer.from(file, 'base64'); - res.setHeader('Content-disposition', `attachment; filename=` + filename); - res.setHeader('Content-type', 'application/zip'); + res.header('Content-disposition', `attachment; filename=` + filename); + res.header('Content-type', 'application/zip'); res.locals.data = fileBuffer return res.send(fileBuffer); } catch (error) { diff --git a/api-gateway/src/api/service/settings.ts b/api-gateway/src/api/service/settings.ts index 6da3bc5546..28a22493c1 100644 --- a/api-gateway/src/api/service/settings.ts +++ b/api-gateway/src/api/service/settings.ts @@ -2,11 +2,11 @@ import { Guardians } from '../../helpers/guardians.js'; import { AboutInterface, CommonSettings, UserRole } from '@guardian/interfaces'; import { Logger } from '@guardian/common'; import { Body, Controller, Get, HttpCode, HttpException, HttpStatus, Post, Req, Response } from '@nestjs/common'; -import { checkPermission } from '../../auth/authorization-helper.js'; import { ApiInternalServerErrorResponse, ApiOkResponse, ApiOperation, ApiTags, getSchemaPath } from '@nestjs/swagger'; import { InternalServerErrorDTO } from '../../middlewares/validation/schemas/errors.js'; import { SettingsDTO } from '../../middlewares/validation/schemas/settings.js'; import process from 'process'; +import { Auth } from '../../auth/auth.decorator.js'; @Controller('settings') @ApiTags('settings') @@ -26,15 +26,15 @@ export class SettingsApi { }) @Post('/') @HttpCode(HttpStatus.CREATED) + @Auth(UserRole.STANDARD_REGISTRY) async updateSettings(@Body() body: SettingsDTO, @Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const settings = body as CommonSettings; const guardians = new Guardians(); await Promise.all([ guardians.updateSettings(settings) ]); - return res.status(201).json(null); + return res.status(201).send(null); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -56,14 +56,14 @@ export class SettingsApi { }) @Get('/') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async getSettings(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const guardians = new Guardians(); const [guardiansSettings] = await Promise.all([ guardians.getSettings() ]); - res.json({ + res.send({ ...guardiansSettings }); } catch (error) { @@ -74,8 +74,8 @@ export class SettingsApi { @Get('/environment') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER) async getEnvironment(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY, UserRole.USER, UserRole.AUDITOR)(req.user); try { const guardians = new Guardians(); const environment = await guardians.getEnvironment(); @@ -88,9 +88,8 @@ export class SettingsApi { @Get('/about') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async getAbout(@Req() req): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); - return { version: process.env.npm_package_version } diff --git a/api-gateway/src/api/service/suggestions.ts b/api-gateway/src/api/service/suggestions.ts index eec6c3b9bf..e58653afd0 100644 --- a/api-gateway/src/api/service/suggestions.ts +++ b/api-gateway/src/api/service/suggestions.ts @@ -1,11 +1,11 @@ import { UserRole } from '@guardian/interfaces'; import { Body, Controller, Get, HttpCode, HttpStatus, Post, Req, UseGuards, } from '@nestjs/common'; -import { checkPermission } from '../../auth/authorization-helper.js'; import { Guardians } from '../../helpers/guardians.js'; import { ApiBearerAuth, ApiCreatedResponse, ApiExtraModels, ApiForbiddenResponse, ApiInternalServerErrorResponse, ApiOkResponse, ApiOperation, ApiSecurity, ApiTags, ApiUnauthorizedResponse, getSchemaPath, } from '@nestjs/swagger'; import { InternalServerErrorDTO } from '../../middlewares/validation/schemas/errors.js'; import { SuggestionsConfigDTO, SuggestionsConfigItemDTO, SuggestionsInputDTO, SuggestionsOutputDTO, } from '../../middlewares/validation/schemas/suggestions.js'; import { AuthGuard } from '../../auth/auth-guard.js'; +import { Auth } from '../../auth/auth.decorator.js'; @Controller('suggestions') @ApiTags('suggestions') @@ -44,11 +44,11 @@ export class SuggestionsApi { @UseGuards(AuthGuard) @Post('/') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async policySuggestions( @Req() req, @Body() body: SuggestionsInputDTO ): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const user = req.user; const guardians = new Guardians(); return await guardians.policySuggestions(body, user); @@ -85,11 +85,11 @@ export class SuggestionsApi { @UseGuards(AuthGuard) @Post('/config') @HttpCode(HttpStatus.CREATED) + @Auth(UserRole.STANDARD_REGISTRY) async setPolicySuggestionsConfig( @Req() req, @Body() body: SuggestionsConfigDTO ): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const guardians = new Guardians(); const user = req.user; return { @@ -127,10 +127,10 @@ export class SuggestionsApi { @UseGuards(AuthGuard) @Get('/config') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async getPolicySuggestionsConfig( @Req() req ): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const user = req.user; const guardians = new Guardians(); return { items: await guardians.getPolicySuggestionsConfig(user) }; diff --git a/api-gateway/src/api/service/tags.ts b/api-gateway/src/api/service/tags.ts index 8c33665032..4bf59bad78 100644 --- a/api-gateway/src/api/service/tags.ts +++ b/api-gateway/src/api/service/tags.ts @@ -3,23 +3,24 @@ import { Guardians } from '../../helpers/guardians.js'; import { SchemaCategory, SchemaHelper, UserRole } from '@guardian/interfaces'; import { SchemaUtils } from '../../helpers/schema-utils.js'; import { Controller, Delete, Get, HttpCode, HttpException, HttpStatus, Post, Put, Req, Response } from '@nestjs/common'; -import { checkPermission } from '../../auth/authorization-helper.js'; import { ApiTags } from '@nestjs/swagger'; +import { Auth } from '../../auth/auth.decorator.js'; @Controller('tags') @ApiTags('tags') +@Auth(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER) export class TagsApi { @Post('/') @HttpCode(HttpStatus.CREATED) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.USER) async setTags(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY, UserRole.USER)(req.user); try { if (!req.headers.authorization || !req.user || !req.user.did) { throw new HttpException('Unauthorized', HttpStatus.UNAUTHORIZED) } const guardian = new Guardians(); const item = await guardian.createTag(req.body, req.user.did); - return res.status(201).json(item); + return res.status(201).send(item); } catch (error) { await (new Logger()).error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -28,6 +29,7 @@ export class TagsApi { @Post('/search') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER) async searchTags(@Req() req, @Response() res): Promise { try { const guardians = new Guardians(); @@ -76,7 +78,7 @@ export class TagsApi { } } } - return res.json(tagMap); + return res.send(tagMap); } catch (error) { await (new Logger()).error(error, ['API_GATEWAY']); throw error @@ -85,6 +87,7 @@ export class TagsApi { @Delete('/:uuid') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER) async deleteTag(@Req() req, @Response() res): Promise { if (!req.user) { throw new HttpException('Unauthorized', HttpStatus.UNAUTHORIZED) @@ -95,7 +98,7 @@ export class TagsApi { throw new HttpException('Invalid uuid', HttpStatus.UNPROCESSABLE_ENTITY) } const result = await guardian.deleteTag(req.params.uuid, req.user.did); - return res.json(result); + return res.send(result); } catch (error) { await (new Logger()).error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -105,8 +108,8 @@ export class TagsApi { @Post('/synchronization') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.USER) async synchronizationTags(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY, UserRole.USER)(req.user); if (!req.headers.authorization || !req.user || !req.user.did) { throw new HttpException('Unauthorized', HttpStatus.UNAUTHORIZED) } @@ -130,7 +133,7 @@ export class TagsApi { tags, refreshDate: (new Date()).toISOString(), } - return res.json(result); + return res.send(result); } catch (error) { await (new Logger()).error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -144,8 +147,8 @@ export class TagsApi { @Get('/schemas') @HttpCode(HttpStatus.OK) // @UseCache({ isExpress: true }) + @Auth(UserRole.STANDARD_REGISTRY) async getSchemas(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const guardians = new Guardians(); @@ -160,8 +163,8 @@ export class TagsApi { items.forEach((s) => { s.readonly = s.readonly || s.owner !== owner }); res.locals.data = SchemaUtils.toOld(items) return res - .setHeader('X-Total-Count', count) - .json(SchemaUtils.toOld(items)); + .header('X-Total-Count', count) + .send(SchemaUtils.toOld(items)); } catch (error) { await (new Logger()).error(error, ['API_GATEWAY']); throw error; @@ -170,8 +173,8 @@ export class TagsApi { @Post('/schemas') @HttpCode(HttpStatus.CREATED) + @Auth(UserRole.STANDARD_REGISTRY) async postSchemas(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const newSchema = req.body; @@ -193,7 +196,7 @@ export class TagsApi { SchemaHelper.updateOwner(newSchema, owner); const schema = await guardians.createTagSchema(newSchema); - return res.status(201).json(SchemaUtils.toOld(schema)); + return res.status(201).send(SchemaUtils.toOld(schema)); } catch (error) { await (new Logger()).error(error, ['API_GATEWAY']); throw error; @@ -202,8 +205,8 @@ export class TagsApi { @Delete('/schemas/:schemaId') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async deleteSchema(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const guardians = new Guardians(); @@ -214,7 +217,7 @@ export class TagsApi { throw new HttpException(error, HttpStatus.FORBIDDEN) } await guardians.deleteSchema(schemaId, user?.did); - return res.json(true); + return res.send(true); } catch (error) { await (new Logger()).error(error, ['API_GATEWAY']); throw error; @@ -223,8 +226,8 @@ export class TagsApi { @Put('/schemas/:schemaId') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async setTag(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const newSchema = req.body; @@ -239,7 +242,7 @@ export class TagsApi { SchemaHelper.checkSchemaKey(newSchema); SchemaHelper.updateOwner(newSchema, owner); await guardians.updateSchema(newSchema); - return res.json(newSchema); + return res.send(newSchema); } catch (error) { await (new Logger()).error(error, ['API_GATEWAY']); throw error; @@ -248,8 +251,8 @@ export class TagsApi { @Put('/schemas/:schemaId/publish') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async publishTag(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const user = req.user; const guardians = new Guardians(); const schemaId = req.params.schemaId; @@ -267,7 +270,7 @@ export class TagsApi { } try { const result = await guardians.publishTagSchema(schemaId, version, user.did); - return res.json(result); + return res.send(result); } catch (error) { await (new Logger()).error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -276,8 +279,8 @@ export class TagsApi { @Get('/schemas/published') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.USER) async getPublished(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY, UserRole.USER)(req.user); try { const guardians = new Guardians(); const schemas = await guardians.getPublishedTagSchemas(); diff --git a/api-gateway/src/api/service/task.ts b/api-gateway/src/api/service/task.ts index 72ffdc57d8..293d943747 100644 --- a/api-gateway/src/api/service/task.ts +++ b/api-gateway/src/api/service/task.ts @@ -2,18 +2,21 @@ import { Logger } from '@guardian/common'; import { TaskManager } from '../../helpers/task-manager.js'; import { Controller, Get, HttpCode, HttpStatus, Req, Response } from '@nestjs/common'; import { ApiTags } from '@nestjs/swagger'; +import { Auth } from '../../auth/auth.decorator.js'; +import { UserRole } from '@guardian/interfaces'; @Controller('tasks') @ApiTags('tasks') export class TaskApi { @Get('/:taskId') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER) async getTask(@Req() req, @Response() res): Promise { const taskManager = new TaskManager(); try { const taskId = req.params.taskId; const taskState = taskManager.getState(req.user.id, taskId); - return res.json(taskState); + return res.send(taskState); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw error; diff --git a/api-gateway/src/api/service/themes.ts b/api-gateway/src/api/service/themes.ts index e48051ea78..b3fbf86abd 100644 --- a/api-gateway/src/api/service/themes.ts +++ b/api-gateway/src/api/service/themes.ts @@ -2,9 +2,12 @@ import { Logger } from '@guardian/common'; import { Guardians } from '../../helpers/guardians.js'; import { Controller, Delete, Get, HttpCode, HttpException, HttpStatus, Post, Put, Req, Response } from '@nestjs/common'; import { ApiTags } from '@nestjs/swagger'; +import { Auth } from '../../auth/auth.decorator.js'; +import { UserRole } from '@guardian/interfaces'; @Controller('themes') @ApiTags('themes') +@Auth(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER) export class ThemesApi { @Post('/') @HttpCode(HttpStatus.CREATED) @@ -12,7 +15,7 @@ export class ThemesApi { try { const guardians = new Guardians(); const item = await guardians.createTheme(req.body, req.user.did); - return res.status(201).json(item); + return res.status(201).send(item); } catch (error) { await (new Logger()).error(error, ['API_GATEWAY']); throw error; @@ -21,6 +24,7 @@ export class ThemesApi { @Put('/:themeId') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER) async updateTheme(@Req() req, @Response() res): Promise { try { const user = req.user; @@ -34,7 +38,7 @@ export class ThemesApi { throw new HttpException('Theme not found.', HttpStatus.NOT_FOUND) } const theme = await guardians.updateTheme(req.params.themeId, newTheme, user.did); - return res.json(theme); + return res.send(theme); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw error; @@ -43,6 +47,7 @@ export class ThemesApi { @Delete('/:themeId') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER) async deleteTheme(@Req() req, @Response() res): Promise { try { const guardians = new Guardians(); @@ -50,7 +55,7 @@ export class ThemesApi { throw new HttpException('Invalid theme id', HttpStatus.UNPROCESSABLE_ENTITY) } const result = await guardians.deleteTheme(req.params.themeId, req.user.did); - return res.json(result); + return res.send(result); } catch (error) { await (new Logger()).error(error, ['API_GATEWAY']); throw error; @@ -59,6 +64,7 @@ export class ThemesApi { @Get('/') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER) async getThemes(@Req() req, @Response() res): Promise { try { const user = req.user; @@ -76,6 +82,7 @@ export class ThemesApi { @Post('/import/file') @HttpCode(HttpStatus.CREATED) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER) async importTheme(@Req() req, @Response() res): Promise { const guardian = new Guardians(); try { @@ -89,12 +96,13 @@ export class ThemesApi { @Get('/:themeId/export/file') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER) async exportTheme(@Req() req, @Response() res): Promise { const guardian = new Guardians(); try { const file: any = await guardian.exportThemeFile(req.params.themeId, req.user.did); - res.setHeader('Content-disposition', `attachment; filename=theme_${Date.now()}`); - res.setHeader('Content-type', 'application/zip'); + res.header('Content-disposition', `attachment; filename=theme_${Date.now()}`); + res.header('Content-type', 'application/zip'); return res.send(file); } catch (error) { new Logger().error(error, ['API_GATEWAY']); diff --git a/api-gateway/src/api/service/tokens.ts b/api-gateway/src/api/service/tokens.ts index 38d66b39aa..4bc2c2764d 100644 --- a/api-gateway/src/api/service/tokens.ts +++ b/api-gateway/src/api/service/tokens.ts @@ -17,7 +17,6 @@ import { Req, Response, } from '@nestjs/common'; -import { checkPermission } from '../../auth/authorization-helper.js'; import { ApiInternalServerErrorResponse, ApiOkResponse, @@ -102,8 +101,8 @@ async function setDynamicTokenPolicy(tokens: any[], engineService?: PolicyEngine export class TokensApi { @Get('/') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.USER) async getTokens(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY, UserRole.USER)(req.user); try { const guardians = new Guardians(); const engineService = new PolicyEngine(); @@ -135,8 +134,8 @@ export class TokensApi { tokensAndCount.items = setTokensPolicies(tokensAndCount.items, map, policyId, true); } return res - .setHeader('X-Total-Count', tokensAndCount.count) - .json(tokensAndCount.items); + .header('X-Total-Count', tokensAndCount.count) + .send(tokensAndCount.items); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw error; @@ -145,15 +144,15 @@ export class TokensApi { @Post('/') @HttpCode(HttpStatus.CREATED) + @Auth(UserRole.STANDARD_REGISTRY) async newToken(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const guardians = new Guardians(); const engineService = new PolicyEngine(); const user = req.user; if (!user.did) { - return res.status(422).json(prepareValidationResponse('User not registered')); + return res.status(422).send(prepareValidationResponse('User not registered')); } let tokens = await guardians.setToken({ @@ -165,7 +164,7 @@ export class TokensApi { const map = await engineService.getTokensMap(user.did); tokens = setTokensPolicies(tokens, map); - return res.status(201).json(tokens); + return res.status(201).send(tokens); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -174,11 +173,11 @@ export class TokensApi { @Post('/push') @HttpCode(HttpStatus.ACCEPTED) + @Auth(UserRole.STANDARD_REGISTRY) async pushTokenAsync(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const user = req.user; if (!user.did) { - return res.status(422).json(prepareValidationResponse('User not registered')); + return res.status(422).send(prepareValidationResponse('User not registered')); } const token = req.body; const taskManager = new TaskManager(); @@ -227,8 +226,8 @@ export class TokensApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.CREATED) + @Auth(UserRole.STANDARD_REGISTRY) async updateToken(@Req() req): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const user = req.user; const token = req.body; @@ -256,18 +255,18 @@ export class TokensApi { @Put('/push') @HttpCode(HttpStatus.ACCEPTED) + @Auth(UserRole.STANDARD_REGISTRY) async updateTokenAsync(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const token = req.body; if (!user.did) { - return res.status(422).json(prepareValidationResponse('User not registered')); + return res.status(422).send(prepareValidationResponse('User not registered')); } if (!token.tokenId) { - return res.status(422).json(prepareValidationResponse('The field tokenId is required')); + return res.status(422).send(prepareValidationResponse('The field tokenId is required')); } const guardians = new Guardians(); @@ -299,14 +298,14 @@ export class TokensApi { @Delete('/push/:tokenId') @HttpCode(HttpStatus.ACCEPTED) + @Auth(UserRole.STANDARD_REGISTRY) async deleteTokenAsync(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const tokenId = req.params.tokenId; if (!user.did) { - return res.status(422).json(prepareValidationResponse('User not registered')); + return res.status(422).send(prepareValidationResponse('User not registered')); } const guardians = new Guardians(); @@ -346,17 +345,17 @@ export class TokensApi { @Put('/:tokenId/associate') @HttpCode(HttpStatus.OK) + @Auth(UserRole.USER) async associateToken(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.USER)(req.user); try { const guardians = new Guardians(); const tokenId = req.params.tokenId; const userDid = req.user.did; if (!userDid) { - return res.status(422).json(prepareValidationResponse('User not registered')); + return res.status(422).send(prepareValidationResponse('User not registered')); } const status = await guardians.associateToken(tokenId, userDid); - return res.json(status); + return res.send(status); } catch (error) { new Logger().error(error, ['API_GATEWAY']); if (error?.message?.toLowerCase().includes('user not found')) { @@ -371,12 +370,12 @@ export class TokensApi { @Put('/push/:tokenId/associate') @HttpCode(HttpStatus.ACCEPTED) + @Auth(UserRole.USER) async associateTokenAsync(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.USER)(req.user); const tokenId = req.params.tokenId; const user = req.user; if (!user.did) { - return res.status(422).json(prepareValidationResponse('User not registered')); + return res.status(422).send(prepareValidationResponse('User not registered')); } const taskManager = new TaskManager(); @@ -394,17 +393,17 @@ export class TokensApi { @Put('/:tokenId/dissociate') @HttpCode(HttpStatus.OK) + @Auth(UserRole.USER) async dissociateToken(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.USER)(req.user); try { const guardians = new Guardians(); const tokenId = req.params.tokenId; const userDid = req.user.did; if (!userDid) { - return res.status(422).json(prepareValidationResponse('User not registered')); + return res.status(422).send(prepareValidationResponse('User not registered')); } const status = await guardians.dissociateToken(tokenId, userDid); - return res.json(status); + return res.send(status); } catch (error) { new Logger().error(error, ['API_GATEWAY']); if (error?.message?.toLowerCase().includes('user not found')) { @@ -419,12 +418,12 @@ export class TokensApi { @Put('/push/:tokenId/dissociate') @HttpCode(HttpStatus.ACCEPTED) + @Auth(UserRole.USER) async dissociateTokenAsync(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.USER)(req.user); const tokenId = req.params.tokenId; const user = req.user; if (!user.did) { - return res.status(422).json(prepareValidationResponse('User not registered')); + return res.status(422).send(prepareValidationResponse('User not registered')); } const taskManager = new TaskManager(); const task = taskManager.start(TaskAction.DISSOCIATE_TOKEN, user.id); @@ -441,17 +440,17 @@ export class TokensApi { @Put('/:tokenId/:username/grant-kyc') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async grantKyc(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const guardians = new Guardians(); const tokenId = req.params.tokenId; const username = req.params.username; const userDid = req.user.did; if (!userDid) { - return res.status(422).json(prepareValidationResponse('User not registered')); + return res.status(422).send(prepareValidationResponse('User not registered')); } - return res.json(await guardians.grantKycToken(tokenId, username, userDid)); + return res.send(await guardians.grantKycToken(tokenId, username, userDid)); } catch (error) { new Logger().error(error, ['API_GATEWAY']); if (error?.message?.toLowerCase().includes('user not found')) { @@ -466,13 +465,13 @@ export class TokensApi { @Put('/push/:tokenId/:username/grant-kyc') @HttpCode(HttpStatus.ACCEPTED) + @Auth(UserRole.STANDARD_REGISTRY) async grantKycAsync(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const tokenId = req.params.tokenId; const username = req.params.username; const user = req.user; if (!user.did) { - return res.status(422).json(prepareValidationResponse('User not registered')); + return res.status(422).send(prepareValidationResponse('User not registered')); } const taskManager = new TaskManager(); const task = taskManager.start(TaskAction.GRANT_KYC, user.id); @@ -489,18 +488,18 @@ export class TokensApi { @Put('/:tokenId/:username/revoke-kyc') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async revokeKyc(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const guardians = new Guardians(); const tokenId = req.params.tokenId; const username = req.params.username; const userDid = req.user.did; if (!userDid) { - return res.status(422).json(prepareValidationResponse('User not registered')); + return res.status(422).send(prepareValidationResponse('User not registered')); } const result = await guardians.revokeKycToken(tokenId, username, userDid); - return res.json(result); + return res.send(result); } catch (error) { new Logger().error(error, ['API_GATEWAY']); if (error?.message?.toLowerCase().includes('user not found')) { @@ -515,8 +514,8 @@ export class TokensApi { @Put('/push/:tokenId/:username/revoke-kyc') @HttpCode(HttpStatus.ACCEPTED) + @Auth(UserRole.STANDARD_REGISTRY) async revokeKycAsync(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const tokenId = req.params.tokenId; const username = req.params.username; const user = req.user; @@ -538,18 +537,18 @@ export class TokensApi { @Put('/:tokenId/:username/freeze') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async freezeToken(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const guardians = new Guardians(); const tokenId = req.params.tokenId; const username = req.params.username; const userDid = req.user.did; if (!userDid) { - return res.status(422).json(prepareValidationResponse('User not registered')); + return res.status(422).send(prepareValidationResponse('User not registered')); } const result = await guardians.freezeToken(tokenId, username, userDid); - return res.json(result); + return res.send(result); } catch (error) { new Logger().error(error, ['API_GATEWAY']); if (error?.message?.toLowerCase().includes('user not found')) { @@ -564,18 +563,18 @@ export class TokensApi { @Put('/:tokenId/:username/unfreeze') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async unfreezeToken(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const guardians = new Guardians(); const tokenId = req.params.tokenId; const username = req.params.username; const userDid = req.user.did; if (!userDid) { - return res.status(422).json(prepareValidationResponse('User not registered')); + return res.status(422).send(prepareValidationResponse('User not registered')); } const result = await guardians.unfreezeToken(tokenId, username, userDid); - return res.json(result); + return res.send(result); } catch (error) { new Logger().error(error, ['API_GATEWAY']); if (error?.message?.toLowerCase().includes('user not found')) { @@ -590,13 +589,13 @@ export class TokensApi { @Put('/push/:tokenId/:username/freeze') @HttpCode(HttpStatus.ACCEPTED) + @Auth(UserRole.STANDARD_REGISTRY) async freezeTokenAsync(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const tokenId = req.params.tokenId; const username = req.params.username; const user = req.user; if (!user.did) { - return res.status(422).json(prepareValidationResponse('User not registered')); + return res.status(422).send(prepareValidationResponse('User not registered')); } const taskManager = new TaskManager(); const task = taskManager.start(TaskAction.FREEZE_TOKEN, user.id); @@ -613,13 +612,13 @@ export class TokensApi { @Put('/push/:tokenId/:username/unfreeze') @HttpCode(HttpStatus.ACCEPTED) + @Auth(UserRole.STANDARD_REGISTRY) async unfreezeTokenAsync(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const tokenId = req.params.tokenId; const username = req.params.username; const user = req.user; if (!user.did) { - return res.status(422).json(prepareValidationResponse('User not registered')); + return res.status(422).send(prepareValidationResponse('User not registered')); } const taskManager = new TaskManager(); const task = taskManager.start(TaskAction.UNFREEZE_TOKEN, user.id); @@ -640,18 +639,18 @@ export class TokensApi { */ @Get('/:tokenId/:username/info') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async getTokenInfo(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const guardians = new Guardians(); const tokenId = req.params.tokenId; const username = req.params.username; const userDid = req.user.did; if (!userDid) { - return res.status(422).json(prepareValidationResponse('User not registered')); + return res.status(422).send(prepareValidationResponse('User not registered')); } const result = await guardians.getInfoToken(tokenId, username, userDid); - return res.json(result as ITokenInfo); + return res.send(result as ITokenInfo); } catch (error) { new Logger().error(error, ['API_GATEWAY']); if (error?.message?.toLowerCase().includes('user not found')) { @@ -698,14 +697,14 @@ export class TokensApi { type: InternalServerErrorDTO, }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.USER) async getTokenSerials(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY, UserRole.USER)(req.user); try { const guardians = new Guardians(); const tokenId = req.params.tokenId; const userDid = req.user.did; const result = await guardians.getTokenSerials(tokenId, userDid); - return res.json(result); + return res.send(result); } catch (error) { new Logger().error(error, ['API_GATEWAY']); if (error?.message?.toLowerCase().includes('user not found')) { diff --git a/api-gateway/src/api/service/tool.ts b/api-gateway/src/api/service/tool.ts index cc3ca567bc..90f6d5feff 100644 --- a/api-gateway/src/api/service/tool.ts +++ b/api-gateway/src/api/service/tool.ts @@ -14,7 +14,6 @@ import { UploadedFiles, UseInterceptors, } from '@nestjs/common'; -import { checkPermission } from '../../auth/authorization-helper.js'; import { TaskAction, UserRole } from '@guardian/interfaces'; import { ApiBody, @@ -35,6 +34,7 @@ import { InternalServerErrorDTO, TaskDTO, ToolDTO } from '../../middlewares/vali import { ApiImplicitParam } from '@nestjs/swagger/dist/decorators/api-implicit-param.decorator.js'; import { AnyFilesInterceptor } from '@nestjs/platform-express'; import { UseCache } from '../../helpers/decorators/cache.js'; +import { Auth } from '../../auth/auth.decorator.js'; const ONLY_SR = ' Only users with the Standard Registry role are allowed to make the request.' @@ -63,8 +63,8 @@ export class ToolsApi { } }) @HttpCode(HttpStatus.CREATED) + @Auth(UserRole.STANDARD_REGISTRY) async createNewTool(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const tool = req.body; if (!tool.config || tool.config.blockType !== 'tool') { @@ -72,7 +72,7 @@ export class ToolsApi { } const guardian = new Guardians(); const item = await guardian.createTool(tool, req.user.did); - return res.status(201).json(item); + return res.status(201).send(item); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw error @@ -101,8 +101,8 @@ export class ToolsApi { } }) @HttpCode(HttpStatus.ACCEPTED) + @Auth(UserRole.STANDARD_REGISTRY) async createNewToolAsync(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const tool = req.body; const user = req.user; @@ -162,8 +162,8 @@ export class ToolsApi { } }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async getTools(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const guardians = new Guardians(); let pageIndex: any; @@ -177,7 +177,7 @@ export class ToolsApi { pageIndex, pageSize }); - return res.setHeader('X-Total-Count', count).json(items); + return res.header('X-Total-Count', count).send(items); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -210,15 +210,15 @@ export class ToolsApi { } }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async deleteTool(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const guardian = new Guardians(); if (!req.params.id) { throw new Error('Invalid id') } const result = await guardian.deleteTool(req.params.id, req.user.did); - return res.status(200).json(result); + return res.status(200).send(result); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -260,15 +260,15 @@ export class ToolsApi { } }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async getToolById(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const guardian = new Guardians(); if (!req.params.id) { throw new HttpException('Invalid id', HttpStatus.UNPROCESSABLE_ENTITY) } const item = await guardian.getToolById(req.params.id, req.user.did); - return res.json(item); + return res.send(item); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -310,8 +310,8 @@ export class ToolsApi { } }) @HttpCode(HttpStatus.CREATED) + @Auth(UserRole.STANDARD_REGISTRY) async updateTool(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); if (!req.params.id) { throw new HttpException('Invalid id', HttpStatus.UNPROCESSABLE_ENTITY); } @@ -322,7 +322,7 @@ export class ToolsApi { } try { const result = await guardian.updateTool(req.params.id, tool, req.user.did); - return res.status(201).json(result); + return res.status(201).send(result); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -364,12 +364,12 @@ export class ToolsApi { } }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async publishTool(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const guardian = new Guardians(); try { const tool = await guardian.publishTool(req.params.id, req.user.did, req.body); - return res.json(tool); + return res.send(tool); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -411,8 +411,8 @@ export class ToolsApi { } }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async publishToolAsync(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const user = req.user; const taskManager = new TaskManager(); const task = taskManager.start(TaskAction.PUBLISH_TOOL, user.id); @@ -453,8 +453,8 @@ export class ToolsApi { } }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async validateTool(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const guardian = new Guardians(); try { return res.send(await guardian.validateTool(req.user.did, req.body)); @@ -496,13 +496,13 @@ export class ToolsApi { } }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async toolExportFile(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const guardian = new Guardians(); try { const file: any = await guardian.exportToolFile(req.params.id, req.user.did); - res.setHeader('Content-disposition', `attachment; filename=tool_${Date.now()}`); - res.setHeader('Content-type', 'application/zip'); + res.header('Content-disposition', `attachment; filename=tool_${Date.now()}`); + res.header('Content-type', 'application/zip'); return res.send(file); } catch (error) { new Logger().error(error, ['API_GATEWAY']); @@ -545,8 +545,8 @@ export class ToolsApi { } }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async toolExportMessage(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const guardian = new Guardians(); try { return res.send(await guardian.exportToolMessage(req.params.id, req.user.did)); @@ -584,8 +584,8 @@ export class ToolsApi { } }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async toolImportMessagePreview(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const guardian = new Guardians(); try { const tool = await guardian.previewToolMessage(req.body.messageId, req.user.did); @@ -624,8 +624,8 @@ export class ToolsApi { } }) @HttpCode(HttpStatus.CREATED) + @Auth(UserRole.STANDARD_REGISTRY) async toolImportMessage(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const guardian = new Guardians(); try { const tool = await guardian.importToolMessage(req.body.messageId, req.user.did); @@ -664,8 +664,8 @@ export class ToolsApi { } }) @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async toolImportFilePreview(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const guardian = new Guardians(); try { const tool = await guardian.previewToolFile(req.body, req.user.did); @@ -704,8 +704,8 @@ export class ToolsApi { } }) @HttpCode(HttpStatus.CREATED) + @Auth(UserRole.STANDARD_REGISTRY) async toolImportFile(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const guardian = new Guardians(); try { const tool = await guardian.importToolFile(req.body, req.user.did); @@ -763,11 +763,11 @@ export class ToolsApi { }) @UseInterceptors(AnyFilesInterceptor()) @HttpCode(HttpStatus.CREATED) + @Auth(UserRole.STANDARD_REGISTRY) async toolImportFileWithMetadata( @Req() req, @UploadedFiles() files: any ): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const guardian = new Guardians(); try { const file = files.find((item) => item.fieldname === 'file'); @@ -820,8 +820,8 @@ export class ToolsApi { } }) @HttpCode(HttpStatus.ACCEPTED) + @Auth(UserRole.STANDARD_REGISTRY) async toolImportFileAsync(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const owner = req.user.did; @@ -891,11 +891,11 @@ export class ToolsApi { }) @UseInterceptors(AnyFilesInterceptor()) @HttpCode(HttpStatus.ACCEPTED) + @Auth(UserRole.STANDARD_REGISTRY) async toolImportFileWithMetadataAsync( @Req() req, @UploadedFiles() files: any ): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const file = files.find(item => item.fieldname === 'file'); if (!file) { @@ -965,8 +965,8 @@ export class ToolsApi { } }) @HttpCode(HttpStatus.ACCEPTED) + @Auth(UserRole.STANDARD_REGISTRY) async toolImportMessageAsync(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const user = req.user; const owner = req.user.did; @@ -1015,8 +1015,8 @@ export class ToolsApi { }) @HttpCode(HttpStatus.OK) @UseCache() + @Auth(UserRole.STANDARD_REGISTRY) async getMenu(@Req() req): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const guardians = new Guardians(); return await guardians.getMenuTool(req.user.did); diff --git a/api-gateway/src/api/service/trust-chains.ts b/api-gateway/src/api/service/trust-chains.ts index 55d79d7ba5..a4e09072fe 100644 --- a/api-gateway/src/api/service/trust-chains.ts +++ b/api-gateway/src/api/service/trust-chains.ts @@ -2,18 +2,18 @@ import { Guardians } from '../../helpers/guardians.js'; import { Users } from '../../helpers/users.js'; import { IAuthUser, Logger } from '@guardian/common'; import { Controller, Get, HttpCode, HttpStatus, Req, Response } from '@nestjs/common'; -import { checkPermission } from '../../auth/authorization-helper.js'; import { UserRole } from '@guardian/interfaces'; import { ApiTags } from '@nestjs/swagger'; import { UseCache } from '../../helpers/decorators/cache.js'; +import { Auth } from '../../auth/auth.decorator.js'; @Controller('trust-chains') @ApiTags('trust-chains') export class TrustChainsApi { @Get('/') @HttpCode(HttpStatus.OK) + @Auth(UserRole.AUDITOR) async getTrustChains(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.AUDITOR)(req.user); try { const guardians = new Guardians(); let pageIndex: any; @@ -39,7 +39,7 @@ export class TrustChainsApi { pageIndex, pageSize }); - return res.setHeader('X-Total-Count', count).json(items); + return res.header('X-Total-Count', count).send(items); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw error; @@ -52,8 +52,8 @@ export class TrustChainsApi { @Get('/:hash') @HttpCode(HttpStatus.OK) @UseCache() + @Auth(UserRole.AUDITOR) async getTrustChainByHash(@Req() req): Promise { - await checkPermission(UserRole.AUDITOR)(req.user); try { const guardians = new Guardians(); const hash = req.params.hash; diff --git a/api-gateway/src/api/service/wizard.ts b/api-gateway/src/api/service/wizard.ts index d8bfc6128e..65f5f55410 100644 --- a/api-gateway/src/api/service/wizard.ts +++ b/api-gateway/src/api/service/wizard.ts @@ -3,10 +3,10 @@ import { Logger, RunFunctionAsync, } from '@guardian/common'; import { TaskManager } from '../../helpers/task-manager.js'; import { ServiceError } from '../../helpers/service-requests-base.js'; import { Controller, HttpCode, HttpStatus, Post, Req, Response } from '@nestjs/common'; -import { checkPermission } from '../../auth/authorization-helper.js'; import { TaskAction, UserRole } from '@guardian/interfaces'; import { ApiBody, ApiInternalServerErrorResponse, ApiOkResponse, ApiOperation, ApiTags, getSchemaPath } from '@nestjs/swagger'; import { InternalServerErrorDTO } from '../../middlewares/validation/schemas/errors.js'; +import { Auth } from '../../auth/auth.decorator.js'; @Controller('wizard') @ApiTags('wizard') @@ -156,13 +156,13 @@ export class WizardApi { }) @Post('/policy') @HttpCode(HttpStatus.CREATED) + @Auth(UserRole.STANDARD_REGISTRY) async setPolicy(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const wizardConfig = req.body; const user = req.user; const guardians = new Guardians(); - return res.status(201).json( + return res.status(201).send( await guardians.wizardPolicyCreate(wizardConfig, user.did) ); } catch (error) { @@ -319,8 +319,8 @@ export class WizardApi { }) @Post('/push/policy') @HttpCode(HttpStatus.ACCEPTED) + @Auth(UserRole.STANDARD_REGISTRY) async setPolicyAsync(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); const { wizardConfig, saveState } = req.body; const user = req.user; const taskManager = new TaskManager(); @@ -491,14 +491,14 @@ export class WizardApi { }) @Post('/:policyId/config') @HttpCode(HttpStatus.OK) + @Auth(UserRole.STANDARD_REGISTRY) async setPolicyConfig(@Req() req, @Response() res): Promise { - await checkPermission(UserRole.STANDARD_REGISTRY)(req.user); try { const wizardConfig = req.body; const user = req.user; const {policyId} = req.params; const guardians = new Guardians(); - return res.json( + return res.send( await guardians.wizardGetPolicyConfig( policyId, wizardConfig, diff --git a/api-gateway/src/app.module.ts b/api-gateway/src/app.module.ts index c453e66604..efee7035d8 100644 --- a/api-gateway/src/app.module.ts +++ b/api-gateway/src/app.module.ts @@ -1,4 +1,4 @@ -import { MiddlewareConsumer, Module } from '@nestjs/common'; +import { MiddlewareConsumer, Module, RequestMethod } from '@nestjs/common'; import { AccountApi } from './api/service/account.js'; import { AnalyticsApi } from './api/service/analytics.js'; import { ArtifactApi } from './api/service/artifact.js'; @@ -13,7 +13,7 @@ import { MetricsApi } from './api/service/metrics.js'; import { ModulesApi } from './api/service/module.js'; import { ToolsApi } from './api/service/tool.js'; import { ProfileApi } from './api/service/profile.js'; -import { authorizationHelper } from './auth/authorization-helper.js'; +import { AppMiddleware, authorizationHelper, LoggerMiddleware, nextHelper } from './auth/authorization-helper.js'; import { PolicyApi } from './api/service/policy.js'; import { SchemaApi, SingleSchemaApi } from './api/service/schema.js'; import { SettingsApi } from './api/service/settings.js'; @@ -40,6 +40,7 @@ import { ProjectsAPI } from './api/service/project.js'; import { AISuggestionsAPI } from './api/service/ai-suggestions.js'; import { cacheProvider } from './helpers/cache-provider.js'; import { CacheService } from './helpers/cache-service.js'; +import fastifyRawBody from 'fastify-raw-body'; const JSON_REQUEST_LIMIT = process.env.JSON_REQUEST_LIMIT || '1mb'; const RAW_REQUEST_LIMIT = process.env.RAW_REQUEST_LIMIT || '1gb'; @@ -116,39 +117,44 @@ const RAW_REQUEST_LIMIT = process.env.RAW_REQUEST_LIMIT || '1gb'; }) export class AppModule { configure(consumer: MiddlewareConsumer) { - // consumer.apply(authorizationHelper).forRoutes(AccountApi); - consumer.apply(authorizationHelper).forRoutes(ProfileApi); - consumer.apply(authorizationHelper).forRoutes(PolicyApi); - consumer.apply(authorizationHelper).forRoutes(SettingsApi); - consumer.apply(authorizationHelper).forRoutes(SingleSchemaApi); - consumer.apply(authorizationHelper).forRoutes(SchemaApi); - consumer.apply(authorizationHelper).forRoutes(ArtifactApi); - consumer.apply(authorizationHelper).forRoutes(IpfsApi); - consumer.apply(authorizationHelper).forRoutes(LoggerApi); - consumer.apply(authorizationHelper).forRoutes(AnalyticsApi); - consumer.apply(authorizationHelper).forRoutes(ContractsApi); - consumer.apply(authorizationHelper).forRoutes(ModulesApi); - consumer.apply(authorizationHelper).forRoutes(ToolsApi); - consumer.apply(authorizationHelper).forRoutes(TagsApi); - consumer.apply(authorizationHelper).forRoutes(ThemesApi); - consumer.apply(authorizationHelper).forRoutes(TokensApi); - consumer.apply(authorizationHelper).forRoutes(TrustChainsApi); - consumer.apply(authorizationHelper).forRoutes(WizardApi); + // consumer.apply(LoggerMiddleware).forRoutes(AccountApi); + // console.log('AppModule1'); + // consumer.apply(authorizationHelper).forRoutes(ProfileApi); + // consumer.apply(authorizationHelper).forRoutes(PolicyApi); + // consumer.apply(authorizationHelper).forRoutes(SettingsApi); + // consumer.apply(authorizationHelper).forRoutes(SingleSchemaApi); + // consumer.apply(AppMiddleware).forRoutes(SchemaApi); + // consumer.apply(authorizationHelper).forRoutes(ArtifactApi); + // consumer.apply(authorizationHelper).forRoutes(IpfsApi); + // consumer.apply(authorizationHelper).forRoutes(LoggerApi); + // consumer.apply(authorizationHelper).forRoutes(AnalyticsApi); + // consumer.apply(authorizationHelper).forRoutes(ContractsApi); + // consumer.apply(authorizationHelper).forRoutes(ModulesApi); + // consumer.apply(authorizationHelper).forRoutes(ToolsApi); + // consumer.apply(authorizationHelper).forRoutes(TagsApi); + // consumer.apply(authorizationHelper).forRoutes(ThemesApi); + // consumer.apply(authorizationHelper).forRoutes(TokensApi); + // consumer.apply(authorizationHelper).forRoutes(TrustChainsApi); + // consumer.apply(authorizationHelper).forRoutes(WizardApi); // consumer.apply(authorizationHelper).forRoutes(BrandingApi); - consumer.apply(authorizationHelper).forRoutes(SuggestionsApi); - consumer.apply(authorizationHelper).forRoutes(NotificationsApi); - consumer.apply(authorizationHelper).forRoutes(TaskApi); - consumer.apply(authorizationHelper).forRoutes(RecordApi); - consumer.apply(authorizationHelper).forRoutes(AISuggestionsAPI); + // consumer.apply(authorizationHelper).forRoutes(SuggestionsApi); + // consumer.apply(authorizationHelper).forRoutes(NotificationsApi); + // consumer.apply(authorizationHelper).forRoutes(TaskApi); + // consumer.apply(authorizationHelper).forRoutes(RecordApi); + // consumer.apply(authorizationHelper).forRoutes(AISuggestionsAPI); - consumer.apply(express.json({ - limit: JSON_REQUEST_LIMIT - })).forRoutes('*'); - consumer.apply(express.raw({ - inflate: true, - limit: RAW_REQUEST_LIMIT, - type: 'binary/octet-stream' - })).forRoutes('*'); + // consumer.apply(express.json({ + // limit: JSON_REQUEST_LIMIT + // })).forRoutes('*'); + // consumer + // .apply(AppMiddleware) + // .forRoutes({ path: '*', method: RequestMethod.ALL }); + // consumer.apply(express.raw({ + // inflate: true, + // limit: RAW_REQUEST_LIMIT, + // type: 'binary/octet-stream' + // })).forRoutes('*'); + // consumer.apply(fastifyRawBody).forRoutes('*'); consumer.apply(hpp()).forRoutes('*'); } } diff --git a/api-gateway/src/app.ts b/api-gateway/src/app.ts index a59913789b..568badab8a 100644 --- a/api-gateway/src/app.ts +++ b/api-gateway/src/app.ts @@ -11,7 +11,7 @@ import { NestFactory } from '@nestjs/core'; import { MicroserviceOptions, Transport } from '@nestjs/microservices'; import process from 'process'; import { HttpStatus, ValidationPipe } from '@nestjs/common'; -import { json } from 'express'; +import express, { json } from 'express'; import { SwaggerModule } from '@nestjs/swagger'; import { SwaggerConfig } from './helpers/swagger-config.js'; import { SwaggerModels, SwaggerPaths } from './old-descriptions.js'; @@ -19,8 +19,10 @@ import { MeecoAuth } from './helpers/meeco.js'; import * as extraModels from './middlewares/validation/schemas/index.js' import { ProjectService } from './helpers/projects.js'; import { AISuggestions } from './helpers/ai-suggestions.js'; -import { FastifyAdapter } from '@nestjs/platform-fastify'; - +import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify'; +import fastify from 'fastify'; +// import fastifyFormbody from '@fastify/formbody' +// import fastifyMultipart from '@fastify/multipart'; const PORT = process.env.PORT || 3002; @@ -31,14 +33,42 @@ const PORT = process.env.PORT || 3002; // buckets: [0.1, 5, 15, 50, 100, 500], // }); +export const fastifyInstance = fastify({}); + +// fastifyInstance.addHook('onRoute', (opts) => { +// opts.config = { rawBody: true }; +// }); + +// fastifyInstance.addContentTypeParser( +// ['multipart/form-data'], +// { parseAs: 'string' }, +// fastifyInstance.getDefaultJsonParser('ignore', 'ignore'), +// ); + +fastifyInstance.addContentTypeParser('multipart/form-data', async function (req) { + var res = await new Promise((resolve, reject) => resolve(req)) + return res +}) + +// export const rowBodyConfig = { +// field: 'rawBody', // change the default request.rawBody property name +// global: true, // add the rawBody to every request. *Default true* +// encoding: 'utf8', // set it in false to set rawBody as a Buffer *Default utf8* +// runFirst: true, // get the body before any preParsing hook change/uncompress it. *Default false* +// }; + Promise.all([ - NestFactory.create(AppModule, new FastifyAdapter(), { + NestFactory.create(AppModule, new FastifyAdapter(fastifyInstance), { + // bufferLogs: true, + // logger: ['error', 'warn'], rawBody: true, - bodyParser: false + bodyParser: false, }), MessageBrokerChannel.connect('API_GATEWAY'), ]).then(async ([app, cn]) => { try { + // await app.register(rawBody, rowBodyConfig) + app.connectMicroservice({ transport: Transport.NATS, options: { @@ -52,7 +82,15 @@ Promise.all([ errorHttpStatusCode: HttpStatus.UNPROCESSABLE_ENTITY })); - app.use(json({ limit: '10mb' })); + // await app.register(fastifyFormbody); + // await app.register(fastifyMultipart); + + const bodyLimit = 10_485_760; + app.useBodyParser('json', { bodyLimit }); + app.useBodyParser('binary/octet-stream', { bodyLimit: 1024 * 1024 * 1024 }); + // app.useBodyParser('multipart/form-data', { bodyLimit: 1024 * 1024 * 1024 }); + // app.use(json({ limit: '10mb' })); + new Logger().setConnection(cn); await new Guardians().setConnection(cn).init(); diff --git a/api-gateway/src/auth/authorization-helper.ts b/api-gateway/src/auth/authorization-helper.ts index 301a4d830a..fb7cf94562 100644 --- a/api-gateway/src/auth/authorization-helper.ts +++ b/api-gateway/src/auth/authorization-helper.ts @@ -2,6 +2,9 @@ import { NextFunction, Response } from 'express'; import { Users } from '../helpers/users.js'; import { AuthenticatedRequest, IAuthUser, Logger } from '@guardian/common'; import { createParamDecorator, ExecutionContext, HttpException, HttpStatus, Injectable, NestMiddleware } from '@nestjs/common'; +import { ServerResponse, IncomingMessage } from 'http'; + +import { FastifyRequest, FastifyReply } from 'fastify'; export const AuthUser = createParamDecorator((data: string = 'user', ctx: ExecutionContext) => { const req = ctx.switchToHttp().getRequest(); @@ -48,7 +51,7 @@ export async function authorizationHelper(req: AuthenticatedRequest, res: Respon new Logger().warn(error.message, ['API_GATEWAY']); } } - res.sendStatus(401); + throw new HttpException('Unauthorized', HttpStatus.UNAUTHORIZED) } /** @@ -83,9 +86,50 @@ export function permissionHelper(...roles: string[]) { return; } } - res.sendStatus(403); + throw new HttpException('Forbidden', HttpStatus.FORBIDDEN) } else { - res.sendStatus(401); + throw new HttpException('Unauthorized', HttpStatus.UNAUTHORIZED); } } } + +/** + */ +export async function nextHelper(req: AuthenticatedRequest, res: Response, next: Function): Promise { + console.log("nextHelper"); + next(); +} + +@Injectable() +export class LoggerMiddleware implements NestMiddleware { + use(req: FastifyRequest['raw'], res: FastifyReply['raw'], next: () => void) { + console.log('Request...'); + next(); + } +} + +@Injectable() +export class AppMiddleware implements NestMiddleware { + async use(req: any, res: any, next: Function) { + const authHeader = req.headers.authorization; + if (!authHeader) { + next(); + return; + } + const users = new Users(); + const token = authHeader.split(' ')[1]; + if (authHeader) { + try { + req.user = await users.getUserByToken(token) as IAuthUser; + next(); + return; + } catch (error) { + await new Logger().warn(error.message, ['API_GATEWAY']); + } + } + throw new HttpException('Unauthorized', HttpStatus.UNAUTHORIZED) + } +} + +const RAW_REQUEST_LIMIT = process.env.RAW_REQUEST_LIMIT || '1gb'; + diff --git a/api-gateway/src/helpers/interceptors/cache.ts b/api-gateway/src/helpers/interceptors/cache.ts index 2d7caf4bba..c2e16f5f89 100644 --- a/api-gateway/src/helpers/interceptors/cache.ts +++ b/api-gateway/src/helpers/interceptors/cache.ts @@ -47,7 +47,7 @@ export class CacheInterceptor implements NestInterceptor { switchMap(resultResponse => { if (resultResponse) { if (isExpress) { - return of(responseContext.json(resultResponse)); + return of(responseContext.send(resultResponse)); } return of(resultResponse); diff --git a/api-gateway/src/middlewares/validation/index.ts b/api-gateway/src/middlewares/validation/index.ts index d196aa60b4..651f746e1b 100644 --- a/api-gateway/src/middlewares/validation/index.ts +++ b/api-gateway/src/middlewares/validation/index.ts @@ -34,7 +34,7 @@ const validate = (schema) => async (req, res, next) => { }, { abortEarly: false }); return next(); } catch (err) { - return res.status(422).json(prepareValidationResponse(err, err.name)); + return res.status(422).send(prepareValidationResponse(err, err.name)); } }; From deda97a5e9fad9de4b570b224f54eb63b7fb2bd9 Mon Sep 17 00:00:00 2001 From: Ihar Date: Thu, 2 May 2024 15:23:50 +0500 Subject: [PATCH 03/16] feat: implement interceptor for multipart formdata --- api-gateway/src/api/service/policy.ts | 13 ++--- api-gateway/src/app.ts | 18 +++---- api-gateway/src/helpers/decorators/file.ts | 11 +++++ .../src/helpers/interceptors/multipart.ts | 48 +++++++++++++++++++ .../src/helpers/interceptors/types/index.ts | 1 + .../helpers/interceptors/types/multipart.ts | 21 ++++++++ .../src/helpers/interceptors/utils/index.ts | 1 + .../helpers/interceptors/utils/multipart.ts | 37 ++++++++++++++ 8 files changed, 135 insertions(+), 15 deletions(-) create mode 100644 api-gateway/src/helpers/decorators/file.ts create mode 100644 api-gateway/src/helpers/interceptors/multipart.ts create mode 100644 api-gateway/src/helpers/interceptors/types/index.ts create mode 100644 api-gateway/src/helpers/interceptors/types/multipart.ts create mode 100644 api-gateway/src/helpers/interceptors/utils/index.ts create mode 100644 api-gateway/src/helpers/interceptors/utils/multipart.ts diff --git a/api-gateway/src/api/service/policy.ts b/api-gateway/src/api/service/policy.ts index c381a39886..cdae5f2edc 100644 --- a/api-gateway/src/api/service/policy.ts +++ b/api-gateway/src/api/service/policy.ts @@ -9,13 +9,15 @@ import { TaskManager } from '../../helpers/task-manager.js'; import { Users } from '../../helpers/users.js'; import { InternalServerErrorDTO } from '../../middlewares/validation/schemas/errors.js'; import { MigrationConfigDTO, PolicyCategoryDTO, } from '../../middlewares/validation/schemas/policies.js'; -import { Body, Controller, Delete, Get, HttpCode, HttpException, HttpStatus, Param, Post, Put, Query, Req, Response, UploadedFiles, UseInterceptors, } from '@nestjs/common'; -import { AnyFilesInterceptor } from '@nestjs/platform-express'; +import { Body, Controller, Delete, Get, HttpCode, HttpException, HttpStatus, Param, Post, Put, Query, Req, Response, UseInterceptors, } from '@nestjs/common'; import { ApiAcceptedResponse, ApiBody, ApiConsumes, ApiExtraModels, ApiForbiddenResponse, ApiInternalServerErrorResponse, ApiOkResponse, ApiOperation, ApiParam, ApiQuery, ApiSecurity, ApiTags, ApiUnauthorizedResponse, getSchemaPath, } from '@nestjs/swagger'; import { ApiImplicitParam } from '@nestjs/swagger/dist/decorators/api-implicit-param.decorator.js'; import { ApiImplicitQuery } from '@nestjs/swagger/dist/decorators/api-implicit-query.decorator.js'; import { CACHE } from '../../constants/index.js'; import { UseCache } from '../../helpers/decorators/cache.js'; +import { MultipartFile } from '../../helpers/interceptors/types/index.js'; +import { UploadedFiles } from '../../helpers/decorators/file.js'; +import { FilesInterceptor } from '../../helpers/interceptors/multipart.js'; const ONLY_SR = ' Only users with the Standard Registry role are allowed to make the request.' @@ -1687,13 +1689,12 @@ export class PolicyApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.CREATED) - @UseInterceptors(AnyFilesInterceptor()) + @UseInterceptors(FilesInterceptor()) async importPolicyFromFileWithMetadata( @AuthUser() user: IAuthUser, @UploadedFiles() files: any, @Query('versionOfTopicId') versionOfTopicId, ): Promise { - console.log('multipart/form-data'); try { const policyFile = files.find( (item) => item.fieldname === 'policyFile' @@ -1831,10 +1832,10 @@ export class PolicyApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.ACCEPTED) - @UseInterceptors(AnyFilesInterceptor()) + @UseInterceptors(FilesInterceptor()) async importPolicyFromFileWithMetadataAsync( @AuthUser() user: IAuthUser, - @UploadedFiles() files: any, + @UploadedFiles() files: MultipartFile[], @Query('versionOfTopicId') versionOfTopicId, ): Promise { const taskManager = new TaskManager(); diff --git a/api-gateway/src/app.ts b/api-gateway/src/app.ts index 568badab8a..61e6233e38 100644 --- a/api-gateway/src/app.ts +++ b/api-gateway/src/app.ts @@ -21,8 +21,8 @@ import { ProjectService } from './helpers/projects.js'; import { AISuggestions } from './helpers/ai-suggestions.js'; import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify'; import fastify from 'fastify'; -// import fastifyFormbody from '@fastify/formbody' -// import fastifyMultipart from '@fastify/multipart'; +import fastifyFormbody from '@fastify/formbody' +import fastifyMultipart from '@fastify/multipart'; const PORT = process.env.PORT || 3002; @@ -45,10 +45,10 @@ export const fastifyInstance = fastify({}); // fastifyInstance.getDefaultJsonParser('ignore', 'ignore'), // ); -fastifyInstance.addContentTypeParser('multipart/form-data', async function (req) { - var res = await new Promise((resolve, reject) => resolve(req)) - return res -}) +// fastifyInstance.addContentTypeParser('multipart/form-data', async function (req) { +// var res = await new Promise((resolve, reject) => resolve(req)) +// return res +// }) // export const rowBodyConfig = { // field: 'rawBody', // change the default request.rawBody property name @@ -58,7 +58,7 @@ fastifyInstance.addContentTypeParser('multipart/form-data', async function (req) // }; Promise.all([ - NestFactory.create(AppModule, new FastifyAdapter(fastifyInstance), { + NestFactory.create(AppModule, new FastifyAdapter(), { // bufferLogs: true, // logger: ['error', 'warn'], rawBody: true, @@ -82,8 +82,8 @@ Promise.all([ errorHttpStatusCode: HttpStatus.UNPROCESSABLE_ENTITY })); - // await app.register(fastifyFormbody); - // await app.register(fastifyMultipart); + await app.register(fastifyFormbody); + await app.register(fastifyMultipart); const bodyLimit = 10_485_760; app.useBodyParser('json', { bodyLimit }); diff --git a/api-gateway/src/helpers/decorators/file.ts b/api-gateway/src/helpers/decorators/file.ts new file mode 100644 index 0000000000..f4fa397fd1 --- /dev/null +++ b/api-gateway/src/helpers/decorators/file.ts @@ -0,0 +1,11 @@ +import { createParamDecorator, ExecutionContext } from '@nestjs/common'; + +//types and interfaces +import { FastifyRequest, MultipartFile } from '../interceptors/types/index.js'; + +export const UploadedFiles = createParamDecorator( + async (_data: unknown, ctx: ExecutionContext): Promise => { + const req = ctx.switchToHttp().getRequest() as FastifyRequest; + return req.storedFiles; + }, +); \ No newline at end of file diff --git a/api-gateway/src/helpers/interceptors/multipart.ts b/api-gateway/src/helpers/interceptors/multipart.ts new file mode 100644 index 0000000000..eb00e38445 --- /dev/null +++ b/api-gateway/src/helpers/interceptors/multipart.ts @@ -0,0 +1,48 @@ +import { CallHandler, ExecutionContext, HttpException, HttpStatus, mixin, NestInterceptor, Type } from '@nestjs/common'; + +import { MultipartValue } from '@fastify/multipart'; +import { Observable } from 'rxjs'; + +//utils +import { getFileFromPart } from './utils/index.js'; + +//types and interfaces +import { FastifyRequest, MultipartFile, MultipartOptions } from './types/index.js'; + + +export function FilesInterceptor(options: MultipartOptions = {}): Type { + class MixinInterceptor implements NestInterceptor { + async intercept(context: ExecutionContext, next: CallHandler): Promise> { + const req = context.switchToHttp().getRequest() as FastifyRequest; + + if (!req.isMultipart()) { + throw new HttpException('The request should be a form-data', HttpStatus.BAD_REQUEST) + } + + const files: MultipartFile[] = []; + const body = {}; + + for await (const part of req.parts()) { + if (part.type !== 'file') { + body[part.fieldname] = (part as MultipartValue).value; + continue; + } + + const file: MultipartFile = await getFileFromPart(part); + // const validationResult = validateFile(file, options); + + // if (validationResult) throw new HttpException(validationResult, HttpStatus.UNPROCESSABLE_ENTITY); + + files[part.fieldname] = files[part.fieldname] || []; + files.push(file); + } + + req.storedFiles = files; + req.body = body; + + return next.handle(); + } + } + + return mixin(MixinInterceptor); +} \ No newline at end of file diff --git a/api-gateway/src/helpers/interceptors/types/index.ts b/api-gateway/src/helpers/interceptors/types/index.ts new file mode 100644 index 0000000000..df348d04ea --- /dev/null +++ b/api-gateway/src/helpers/interceptors/types/index.ts @@ -0,0 +1 @@ +export { MultipartFile, MultipartOptions, FastifyRequest } from './multipart.js'; \ No newline at end of file diff --git a/api-gateway/src/helpers/interceptors/types/multipart.ts b/api-gateway/src/helpers/interceptors/types/multipart.ts new file mode 100644 index 0000000000..370948c4df --- /dev/null +++ b/api-gateway/src/helpers/interceptors/types/multipart.ts @@ -0,0 +1,21 @@ +import * as fastify from 'fastify' + +export interface FastifyRequest extends fastify.FastifyRequest { + storedFiles: MultipartFile[]; + body: unknown; +} + +export interface MultipartFile { + buffer: Buffer; + filename: string; + size: number; + mimetype: string; + fieldname: string; +} + +export class MultipartOptions { + constructor( + public maxFileSize?: number, + public fileType?: string | RegExp, + ) {} +} \ No newline at end of file diff --git a/api-gateway/src/helpers/interceptors/utils/index.ts b/api-gateway/src/helpers/interceptors/utils/index.ts new file mode 100644 index 0000000000..7aa65a3a50 --- /dev/null +++ b/api-gateway/src/helpers/interceptors/utils/index.ts @@ -0,0 +1 @@ +export { getFileFromPart } from './multipart.js'; \ No newline at end of file diff --git a/api-gateway/src/helpers/interceptors/utils/multipart.ts b/api-gateway/src/helpers/interceptors/utils/multipart.ts new file mode 100644 index 0000000000..dcf5c12492 --- /dev/null +++ b/api-gateway/src/helpers/interceptors/utils/multipart.ts @@ -0,0 +1,37 @@ +import { FileValidator } from '@nestjs/common/pipes/file/file-validator.interface'; +import { FileTypeValidator, MaxFileSizeValidator } from '@nestjs/common'; + +import { MultipartFile as MultipartFileFastify} from '@fastify/multipart'; + +//types and interfaces +import { MultipartFile, MultipartOptions } from '../types/index.js'; + + +export const getFileFromPart = async (part: MultipartFileFastify): Promise => { + const buffer: Buffer = await part.toBuffer() + return { + buffer, + size: buffer.byteLength, + filename: part.filename, + mimetype: part.mimetype, + fieldname: part.fieldname, + }; +}; + +export const validateFile = (file: MultipartFile, options: MultipartOptions): string | void => { + const validators: FileValidator[] = []; + + if (options.maxFileSize) { + validators.push(new MaxFileSizeValidator({ maxSize: options.maxFileSize })); + } + + if (options.fileType) { + validators.push(new FileTypeValidator({ fileType: options.fileType })); + } + + for (const validator of validators) { + if (validator.isValid(file)) continue; + + return validator.buildErrorMessage(file); + } +}; \ No newline at end of file From 7ff59cbb9d6aa718182fac4a8c50ca44c845e997 Mon Sep 17 00:00:00 2001 From: Ihar Date: Fri, 3 May 2024 20:05:30 +0500 Subject: [PATCH 04/16] refactor: put same names as base nest --- analytics-service/src/app.ts | 3 +- api-gateway/package.json | 1 - api-gateway/src/api/service/policy.ts | 10 ++-- api-gateway/src/api/service/tags.ts | 1 - api-gateway/src/api/service/themes.ts | 2 +- api-gateway/src/api/service/tool.ts | 9 ++-- api-gateway/src/app.module.ts | 52 ++----------------- api-gateway/src/app.ts | 37 ------------- api-gateway/src/auth/authorization-helper.ts | 44 ---------------- .../src/helpers/interceptors/multipart.ts | 2 +- 10 files changed, 16 insertions(+), 145 deletions(-) diff --git a/analytics-service/src/app.ts b/analytics-service/src/app.ts index 81a85dea74..d8bd3805df 100644 --- a/analytics-service/src/app.ts +++ b/analytics-service/src/app.ts @@ -18,7 +18,6 @@ import { AppModule } from './app.module.js'; import { SwaggerModule } from '@nestjs/swagger'; import { SwaggerConfig } from './helpers/swagger-config.js'; import { AnalyticsUtils } from './helpers/utils.js'; -import { FastifyAdapter } from '@nestjs/platform-fastify'; const PORT = process.env.PORT || 3020; Promise.all([ @@ -35,7 +34,7 @@ Promise.all([ }, [ 'v2-21-0' ]), - NestFactory.create(AppModule, new FastifyAdapter(), { + NestFactory.create(AppModule, { rawBody: true, bodyParser: false }), diff --git a/api-gateway/package.json b/api-gateway/package.json index fb64e798e8..03d953a86a 100644 --- a/api-gateway/package.json +++ b/api-gateway/package.json @@ -26,7 +26,6 @@ "dotenv": "^16.0.0", "express": "^4.17.1", "express-fileupload": "^1.4.0", - "fastify-raw-body": "4.0.0", "gulp": "^4.0.2", "gulp-copy": "^4.0.1", "gulp-rename": "^2.0.0", diff --git a/api-gateway/src/api/service/policy.ts b/api-gateway/src/api/service/policy.ts index cdae5f2edc..ec496668b5 100644 --- a/api-gateway/src/api/service/policy.ts +++ b/api-gateway/src/api/service/policy.ts @@ -15,9 +15,9 @@ import { ApiImplicitParam } from '@nestjs/swagger/dist/decorators/api-implicit-p import { ApiImplicitQuery } from '@nestjs/swagger/dist/decorators/api-implicit-query.decorator.js'; import { CACHE } from '../../constants/index.js'; import { UseCache } from '../../helpers/decorators/cache.js'; -import { MultipartFile } from '../../helpers/interceptors/types/index.js'; +import { AnyFilesInterceptor } from '../../helpers/interceptors/multipart.js'; import { UploadedFiles } from '../../helpers/decorators/file.js'; -import { FilesInterceptor } from '../../helpers/interceptors/multipart.js'; +import { MultipartFile } from '../../helpers/interceptors/types/index.js'; const ONLY_SR = ' Only users with the Standard Registry role are allowed to make the request.' @@ -1689,10 +1689,10 @@ export class PolicyApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.CREATED) - @UseInterceptors(FilesInterceptor()) + @UseInterceptors(AnyFilesInterceptor()) async importPolicyFromFileWithMetadata( @AuthUser() user: IAuthUser, - @UploadedFiles() files: any, + @UploadedFiles() files: MultipartFile[], @Query('versionOfTopicId') versionOfTopicId, ): Promise { try { @@ -1832,7 +1832,7 @@ export class PolicyApi { type: InternalServerErrorDTO }) @HttpCode(HttpStatus.ACCEPTED) - @UseInterceptors(FilesInterceptor()) + @UseInterceptors(AnyFilesInterceptor()) async importPolicyFromFileWithMetadataAsync( @AuthUser() user: IAuthUser, @UploadedFiles() files: MultipartFile[], diff --git a/api-gateway/src/api/service/tags.ts b/api-gateway/src/api/service/tags.ts index 4bf59bad78..21af33f91e 100644 --- a/api-gateway/src/api/service/tags.ts +++ b/api-gateway/src/api/service/tags.ts @@ -8,7 +8,6 @@ import { Auth } from '../../auth/auth.decorator.js'; @Controller('tags') @ApiTags('tags') -@Auth(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER) export class TagsApi { @Post('/') @HttpCode(HttpStatus.CREATED) diff --git a/api-gateway/src/api/service/themes.ts b/api-gateway/src/api/service/themes.ts index b3fbf86abd..415ba819e9 100644 --- a/api-gateway/src/api/service/themes.ts +++ b/api-gateway/src/api/service/themes.ts @@ -7,10 +7,10 @@ import { UserRole } from '@guardian/interfaces'; @Controller('themes') @ApiTags('themes') -@Auth(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER) export class ThemesApi { @Post('/') @HttpCode(HttpStatus.CREATED) + @Auth(UserRole.STANDARD_REGISTRY, UserRole.AUDITOR, UserRole.USER) async setThemes(@Req() req, @Response() res): Promise { try { const guardians = new Guardians(); diff --git a/api-gateway/src/api/service/tool.ts b/api-gateway/src/api/service/tool.ts index 90f6d5feff..35cfb071eb 100644 --- a/api-gateway/src/api/service/tool.ts +++ b/api-gateway/src/api/service/tool.ts @@ -11,7 +11,6 @@ import { Put, Req, Response, - UploadedFiles, UseInterceptors, } from '@nestjs/common'; import { TaskAction, UserRole } from '@guardian/interfaces'; @@ -32,9 +31,11 @@ import { TaskManager } from '../../helpers/task-manager.js'; import { ServiceError } from '../../helpers/service-requests-base.js'; import { InternalServerErrorDTO, TaskDTO, ToolDTO } from '../../middlewares/validation/schemas/index.js'; import { ApiImplicitParam } from '@nestjs/swagger/dist/decorators/api-implicit-param.decorator.js'; -import { AnyFilesInterceptor } from '@nestjs/platform-express'; import { UseCache } from '../../helpers/decorators/cache.js'; import { Auth } from '../../auth/auth.decorator.js'; +import { AnyFilesInterceptor } from '../../helpers/interceptors/multipart.js'; +import { UploadedFiles } from '../../helpers/decorators/file.js'; +import { MultipartFile } from '../../helpers/interceptors/types/index.js';; const ONLY_SR = ' Only users with the Standard Registry role are allowed to make the request.' @@ -766,7 +767,7 @@ export class ToolsApi { @Auth(UserRole.STANDARD_REGISTRY) async toolImportFileWithMetadata( @Req() req, - @UploadedFiles() files: any + @UploadedFiles() files: MultipartFile[] ): Promise { const guardian = new Guardians(); try { @@ -894,7 +895,7 @@ export class ToolsApi { @Auth(UserRole.STANDARD_REGISTRY) async toolImportFileWithMetadataAsync( @Req() req, - @UploadedFiles() files: any + @UploadedFiles() files: MultipartFile[] ): Promise { try { const file = files.find(item => item.fieldname === 'file'); diff --git a/api-gateway/src/app.module.ts b/api-gateway/src/app.module.ts index efee7035d8..73ce1cdccd 100644 --- a/api-gateway/src/app.module.ts +++ b/api-gateway/src/app.module.ts @@ -1,4 +1,4 @@ -import { MiddlewareConsumer, Module, RequestMethod } from '@nestjs/common'; +import { MiddlewareConsumer, Module } from '@nestjs/common'; import { AccountApi } from './api/service/account.js'; import { AnalyticsApi } from './api/service/analytics.js'; import { ArtifactApi } from './api/service/artifact.js'; @@ -13,7 +13,6 @@ import { MetricsApi } from './api/service/metrics.js'; import { ModulesApi } from './api/service/module.js'; import { ToolsApi } from './api/service/tool.js'; import { ProfileApi } from './api/service/profile.js'; -import { AppMiddleware, authorizationHelper, LoggerMiddleware, nextHelper } from './auth/authorization-helper.js'; import { PolicyApi } from './api/service/policy.js'; import { SchemaApi, SingleSchemaApi } from './api/service/schema.js'; import { SettingsApi } from './api/service/settings.js'; @@ -23,7 +22,6 @@ import { TokensApi } from './api/service/tokens.js'; import { TrustChainsApi } from './api/service/trust-chains.js'; import { WizardApi } from './api/service/wizard.js'; import process from 'process'; -import express from 'express'; import hpp from 'hpp'; import { ThemesApi } from './api/service/themes.js'; import { BrandingApi } from './api/service/branding.js'; @@ -40,23 +38,9 @@ import { ProjectsAPI } from './api/service/project.js'; import { AISuggestionsAPI } from './api/service/ai-suggestions.js'; import { cacheProvider } from './helpers/cache-provider.js'; import { CacheService } from './helpers/cache-service.js'; -import fastifyRawBody from 'fastify-raw-body'; -const JSON_REQUEST_LIMIT = process.env.JSON_REQUEST_LIMIT || '1mb'; -const RAW_REQUEST_LIMIT = process.env.RAW_REQUEST_LIMIT || '1gb'; - -// class LogClientSerializer implements Serializer { -// serialize(value: any, options?: Record): any { -// value.data = Buffer.from(JSON.stringify(value), 'utf-8') -// return value; -// } -// } -// -// class LogClientDeserializer implements Deserializer { -// deserialize(value: any, options?: Record): any { -// return JSON.parse(value.toString()) -// } -// } +// const JSON_REQUEST_LIMIT = process.env.JSON_REQUEST_LIMIT || '1mb'; +// const RAW_REQUEST_LIMIT = process.env.RAW_REQUEST_LIMIT || '1gb'; @Module({ imports: [ @@ -117,44 +101,14 @@ const RAW_REQUEST_LIMIT = process.env.RAW_REQUEST_LIMIT || '1gb'; }) export class AppModule { configure(consumer: MiddlewareConsumer) { - // consumer.apply(LoggerMiddleware).forRoutes(AccountApi); - // console.log('AppModule1'); - // consumer.apply(authorizationHelper).forRoutes(ProfileApi); - // consumer.apply(authorizationHelper).forRoutes(PolicyApi); - // consumer.apply(authorizationHelper).forRoutes(SettingsApi); - // consumer.apply(authorizationHelper).forRoutes(SingleSchemaApi); - // consumer.apply(AppMiddleware).forRoutes(SchemaApi); - // consumer.apply(authorizationHelper).forRoutes(ArtifactApi); - // consumer.apply(authorizationHelper).forRoutes(IpfsApi); - // consumer.apply(authorizationHelper).forRoutes(LoggerApi); - // consumer.apply(authorizationHelper).forRoutes(AnalyticsApi); - // consumer.apply(authorizationHelper).forRoutes(ContractsApi); - // consumer.apply(authorizationHelper).forRoutes(ModulesApi); - // consumer.apply(authorizationHelper).forRoutes(ToolsApi); - // consumer.apply(authorizationHelper).forRoutes(TagsApi); - // consumer.apply(authorizationHelper).forRoutes(ThemesApi); - // consumer.apply(authorizationHelper).forRoutes(TokensApi); - // consumer.apply(authorizationHelper).forRoutes(TrustChainsApi); - // consumer.apply(authorizationHelper).forRoutes(WizardApi); - // consumer.apply(authorizationHelper).forRoutes(BrandingApi); - // consumer.apply(authorizationHelper).forRoutes(SuggestionsApi); - // consumer.apply(authorizationHelper).forRoutes(NotificationsApi); - // consumer.apply(authorizationHelper).forRoutes(TaskApi); - // consumer.apply(authorizationHelper).forRoutes(RecordApi); - // consumer.apply(authorizationHelper).forRoutes(AISuggestionsAPI); - // consumer.apply(express.json({ // limit: JSON_REQUEST_LIMIT // })).forRoutes('*'); - // consumer - // .apply(AppMiddleware) - // .forRoutes({ path: '*', method: RequestMethod.ALL }); // consumer.apply(express.raw({ // inflate: true, // limit: RAW_REQUEST_LIMIT, // type: 'binary/octet-stream' // })).forRoutes('*'); - // consumer.apply(fastifyRawBody).forRoutes('*'); consumer.apply(hpp()).forRoutes('*'); } } diff --git a/api-gateway/src/app.ts b/api-gateway/src/app.ts index 61e6233e38..75c07e3873 100644 --- a/api-gateway/src/app.ts +++ b/api-gateway/src/app.ts @@ -11,7 +11,6 @@ import { NestFactory } from '@nestjs/core'; import { MicroserviceOptions, Transport } from '@nestjs/microservices'; import process from 'process'; import { HttpStatus, ValidationPipe } from '@nestjs/common'; -import express, { json } from 'express'; import { SwaggerModule } from '@nestjs/swagger'; import { SwaggerConfig } from './helpers/swagger-config.js'; import { SwaggerModels, SwaggerPaths } from './old-descriptions.js'; @@ -20,55 +19,19 @@ import * as extraModels from './middlewares/validation/schemas/index.js' import { ProjectService } from './helpers/projects.js'; import { AISuggestions } from './helpers/ai-suggestions.js'; import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify'; -import fastify from 'fastify'; import fastifyFormbody from '@fastify/formbody' import fastifyMultipart from '@fastify/multipart'; const PORT = process.env.PORT || 3002; -// const restResponseTimeHistogram = new client.Histogram({ -// name: 'api_gateway_rest_response_time_duration_seconds', -// help: 'api-gateway a histogram metric', -// labelNames: ['method', 'route', 'statusCode'], -// buckets: [0.1, 5, 15, 50, 100, 500], -// }); - -export const fastifyInstance = fastify({}); - -// fastifyInstance.addHook('onRoute', (opts) => { -// opts.config = { rawBody: true }; -// }); - -// fastifyInstance.addContentTypeParser( -// ['multipart/form-data'], -// { parseAs: 'string' }, -// fastifyInstance.getDefaultJsonParser('ignore', 'ignore'), -// ); - -// fastifyInstance.addContentTypeParser('multipart/form-data', async function (req) { -// var res = await new Promise((resolve, reject) => resolve(req)) -// return res -// }) - -// export const rowBodyConfig = { -// field: 'rawBody', // change the default request.rawBody property name -// global: true, // add the rawBody to every request. *Default true* -// encoding: 'utf8', // set it in false to set rawBody as a Buffer *Default utf8* -// runFirst: true, // get the body before any preParsing hook change/uncompress it. *Default false* -// }; - Promise.all([ NestFactory.create(AppModule, new FastifyAdapter(), { - // bufferLogs: true, - // logger: ['error', 'warn'], rawBody: true, bodyParser: false, }), MessageBrokerChannel.connect('API_GATEWAY'), ]).then(async ([app, cn]) => { try { - // await app.register(rawBody, rowBodyConfig) - app.connectMicroservice({ transport: Transport.NATS, options: { diff --git a/api-gateway/src/auth/authorization-helper.ts b/api-gateway/src/auth/authorization-helper.ts index fb7cf94562..f61b8a2dde 100644 --- a/api-gateway/src/auth/authorization-helper.ts +++ b/api-gateway/src/auth/authorization-helper.ts @@ -2,9 +2,6 @@ import { NextFunction, Response } from 'express'; import { Users } from '../helpers/users.js'; import { AuthenticatedRequest, IAuthUser, Logger } from '@guardian/common'; import { createParamDecorator, ExecutionContext, HttpException, HttpStatus, Injectable, NestMiddleware } from '@nestjs/common'; -import { ServerResponse, IncomingMessage } from 'http'; - -import { FastifyRequest, FastifyReply } from 'fastify'; export const AuthUser = createParamDecorator((data: string = 'user', ctx: ExecutionContext) => { const req = ctx.switchToHttp().getRequest(); @@ -92,44 +89,3 @@ export function permissionHelper(...roles: string[]) { } } } - -/** - */ -export async function nextHelper(req: AuthenticatedRequest, res: Response, next: Function): Promise { - console.log("nextHelper"); - next(); -} - -@Injectable() -export class LoggerMiddleware implements NestMiddleware { - use(req: FastifyRequest['raw'], res: FastifyReply['raw'], next: () => void) { - console.log('Request...'); - next(); - } -} - -@Injectable() -export class AppMiddleware implements NestMiddleware { - async use(req: any, res: any, next: Function) { - const authHeader = req.headers.authorization; - if (!authHeader) { - next(); - return; - } - const users = new Users(); - const token = authHeader.split(' ')[1]; - if (authHeader) { - try { - req.user = await users.getUserByToken(token) as IAuthUser; - next(); - return; - } catch (error) { - await new Logger().warn(error.message, ['API_GATEWAY']); - } - } - throw new HttpException('Unauthorized', HttpStatus.UNAUTHORIZED) - } -} - -const RAW_REQUEST_LIMIT = process.env.RAW_REQUEST_LIMIT || '1gb'; - diff --git a/api-gateway/src/helpers/interceptors/multipart.ts b/api-gateway/src/helpers/interceptors/multipart.ts index eb00e38445..c71fb39ae0 100644 --- a/api-gateway/src/helpers/interceptors/multipart.ts +++ b/api-gateway/src/helpers/interceptors/multipart.ts @@ -10,7 +10,7 @@ import { getFileFromPart } from './utils/index.js'; import { FastifyRequest, MultipartFile, MultipartOptions } from './types/index.js'; -export function FilesInterceptor(options: MultipartOptions = {}): Type { +export function AnyFilesInterceptor(options: MultipartOptions = {}): Type { class MixinInterceptor implements NestInterceptor { async intercept(context: ExecutionContext, next: CallHandler): Promise> { const req = context.switchToHttp().getRequest() as FastifyRequest; From 136410a13a73e7804ff7628d27c5f22cb9c90a60 Mon Sep 17 00:00:00 2001 From: Ihar Date: Tue, 7 May 2024 20:49:33 +0500 Subject: [PATCH 05/16] fix: size of limit json to 1gb --- api-gateway/src/app.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api-gateway/src/app.ts b/api-gateway/src/app.ts index 75c07e3873..ccf0f215e7 100644 --- a/api-gateway/src/app.ts +++ b/api-gateway/src/app.ts @@ -49,7 +49,7 @@ Promise.all([ await app.register(fastifyMultipart); const bodyLimit = 10_485_760; - app.useBodyParser('json', { bodyLimit }); + app.useBodyParser('json', { bodyLimit: 1024 * 1024 * 1024 }); app.useBodyParser('binary/octet-stream', { bodyLimit: 1024 * 1024 * 1024 }); // app.useBodyParser('multipart/form-data', { bodyLimit: 1024 * 1024 * 1024 }); // app.use(json({ limit: '10mb' })); From ac07103b5b27f1020059e293903afe745fb7b4e2 Mon Sep 17 00:00:00 2001 From: Ihar Date: Wed, 8 May 2024 15:41:43 +0500 Subject: [PATCH 06/16] fix: auth accross decorator in get account --- api-gateway/src/api/service/account.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api-gateway/src/api/service/account.ts b/api-gateway/src/api/service/account.ts index af73fbd735..e51285fde2 100644 --- a/api-gateway/src/api/service/account.ts +++ b/api-gateway/src/api/service/account.ts @@ -14,6 +14,7 @@ import { InternalServerErrorDTO } from '../../middlewares/validation/schemas/err import { ApplicationEnvironment } from '../../environment.js'; import { CACHE } from '../../constants/index.js'; import { UseCache } from '../../helpers/decorators/cache.js'; +import { Auth } from '../../auth/auth.decorator.js'; /** * User account route @@ -225,6 +226,7 @@ export class AccountApi { @HttpCode(HttpStatus.OK) @Get() @UseCache() + @Auth(UserRole.STANDARD_REGISTRY) async getAllAccounts(@Req() req): Promise { const authHeader = req.headers.authorization; const token = authHeader?.split(' ')[1]; @@ -240,7 +242,6 @@ export class AccountApi { throw new HttpException('UNAUTHORIZED', HttpStatus.UNAUTHORIZED); } try { - await checkPermission(UserRole.STANDARD_REGISTRY)(user); return await users.getAllUserAccounts() as any[]; } catch (error) { new Logger().error(error, ['API_GATEWAY']); From 84bbfd2fb9506b565ed9ae78ad624108a1ac9699 Mon Sep 17 00:00:00 2001 From: Ihar Date: Wed, 8 May 2024 16:47:23 +0500 Subject: [PATCH 07/16] feat: add option ignoreTrailingSlash in fastify adapter --- api-gateway/src/app.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api-gateway/src/app.ts b/api-gateway/src/app.ts index ccf0f215e7..22fa490fed 100644 --- a/api-gateway/src/app.ts +++ b/api-gateway/src/app.ts @@ -25,7 +25,7 @@ import fastifyMultipart from '@fastify/multipart'; const PORT = process.env.PORT || 3002; Promise.all([ - NestFactory.create(AppModule, new FastifyAdapter(), { + NestFactory.create(AppModule, new FastifyAdapter({ ignoreTrailingSlash: true }), { rawBody: true, bodyParser: false, }), From e66b0dc0e55ca6cd82f61600d45cc61a21839a59 Mon Sep 17 00:00:00 2001 From: envision-ci-agent Date: Wed, 8 May 2024 11:50:09 +0000 Subject: [PATCH 08/16] [skip ci] Add swagger.yaml --- swagger.yaml | 180 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 164 insertions(+), 16 deletions(-) diff --git a/swagger.yaml b/swagger.yaml index 99f00a4d5d..b3e043c920 100644 --- a/swagger.yaml +++ b/swagger.yaml @@ -112,6 +112,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_0 security: + - bearer: [] - bearerAuth: [] /accounts/standard-registries: get: @@ -232,6 +233,7 @@ paths: tags: &ref_1 - analytics security: + - bearer: [] - bearerAuth: [] /analytics/compare/policies: post: @@ -285,6 +287,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_1 security: + - bearer: [] - bearerAuth: [] /analytics/compare/modules: post: @@ -328,6 +331,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_1 security: + - bearer: [] - bearerAuth: [] /analytics/compare/schemas: post: @@ -369,6 +373,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_1 security: + - bearer: [] - bearerAuth: [] /analytics/compare/documents: post: @@ -414,6 +419,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_1 security: + - bearer: [] - bearerAuth: [] /analytics/compare/tools: post: @@ -459,6 +465,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_1 security: + - bearer: [] - bearerAuth: [] /analytics/compare/policies/export: post: @@ -512,6 +519,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_1 security: + - bearer: [] - bearerAuth: [] /analytics/compare/modules/export: post: @@ -555,6 +563,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_1 security: + - bearer: [] - bearerAuth: [] /analytics/compare/schemas/export: post: @@ -596,6 +605,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_1 security: + - bearer: [] - bearerAuth: [] /analytics/compare/documents/export: post: @@ -641,6 +651,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_1 security: + - bearer: [] - bearerAuth: [] /analytics/compare/tools/export: post: @@ -686,6 +697,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_1 security: + - bearer: [] - bearerAuth: [] /analytics/search/blocks: post: @@ -726,6 +738,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_1 security: + - bearer: [] - bearerAuth: [] /artifacts: get: @@ -832,6 +845,7 @@ paths: tags: - artifacts security: + - bearer: [] - bearerAuth: [] /artifacts/{artifactId}: delete: @@ -925,6 +939,7 @@ paths: - contracts security: - bearer: [] + - bearer: [] post: operationId: ContractsApi_createContract summary: Create contract. @@ -961,6 +976,7 @@ paths: tags: *ref_2 security: - bearer: [] + - bearer: [] /contracts/import: post: operationId: ContractsApi_importContract @@ -1004,6 +1020,7 @@ paths: tags: *ref_2 security: - bearer: [] + - bearer: [] /contracts/{contractId}/permissions: get: operationId: ContractsApi_contractPermissions @@ -1039,6 +1056,7 @@ paths: tags: *ref_2 security: - bearer: [] + - bearer: [] /contracts/{contractId}: delete: operationId: ContractsApi_removeContract @@ -1074,6 +1092,7 @@ paths: tags: *ref_2 security: - bearer: [] + - bearer: [] /contracts/wipe/requests: get: operationId: ContractsApi_getWipeRequests @@ -1132,6 +1151,7 @@ paths: tags: *ref_2 security: - bearer: [] + - bearer: [] /contracts/wipe/{contractId}/requests/enable: post: operationId: ContractsApi_enableWipeRequests @@ -1163,6 +1183,7 @@ paths: tags: *ref_2 security: - bearer: [] + - bearer: [] /contracts/wipe/{contractId}/requests/disable: post: operationId: ContractsApi_disableWipeRequests @@ -1194,6 +1215,7 @@ paths: tags: *ref_2 security: - bearer: [] + - bearer: [] /contracts/wipe/requests/{requestId}/approve: post: operationId: ContractsApi_approveWipeRequest @@ -1225,6 +1247,7 @@ paths: tags: *ref_2 security: - bearer: [] + - bearer: [] /contracts/wipe/requests/{requestId}/reject: delete: operationId: ContractsApi_rejectWipeRequest @@ -1262,6 +1285,7 @@ paths: tags: *ref_2 security: - bearer: [] + - bearer: [] /contracts/wipe/{contractId}/requests: delete: operationId: ContractsApi_clearWipeRequests @@ -1293,6 +1317,7 @@ paths: tags: *ref_2 security: - bearer: [] + - bearer: [] /contracts/wipe/{contractId}/admin/{hederaId}: post: operationId: ContractsApi_wipeAddAdmin @@ -1331,6 +1356,7 @@ paths: tags: *ref_2 security: - bearer: [] + - bearer: [] delete: operationId: ContractsApi_wipeRemoveAdmin summary: Remove wipe admin. @@ -1368,6 +1394,7 @@ paths: tags: *ref_2 security: - bearer: [] + - bearer: [] /contracts/wipe/{contractId}/manager/{hederaId}: post: operationId: ContractsApi_wipeAddManager @@ -1406,6 +1433,7 @@ paths: tags: *ref_2 security: - bearer: [] + - bearer: [] delete: operationId: ContractsApi_wipeRemoveManager summary: Remove wipe manager. @@ -1443,6 +1471,7 @@ paths: tags: *ref_2 security: - bearer: [] + - bearer: [] /contracts/wipe/{contractId}/wiper/{hederaId}: post: operationId: ContractsApi_wipeAddWiper @@ -1481,6 +1510,7 @@ paths: tags: *ref_2 security: - bearer: [] + - bearer: [] delete: operationId: ContractsApi_wipeRemoveWiper summary: Remove wipe wiper. @@ -1518,6 +1548,7 @@ paths: tags: *ref_2 security: - bearer: [] + - bearer: [] /contracts/retire/{contractId}/pools/sync: post: operationId: ContractsApi_retireSyncPools @@ -1553,6 +1584,7 @@ paths: tags: *ref_2 security: - bearer: [] + - bearer: [] /contracts/retire/requests: get: operationId: ContractsApi_getRetireRequests @@ -1609,6 +1641,7 @@ paths: tags: *ref_2 security: - bearer: [] + - bearer: [] /contracts/retire/pools: get: operationId: ContractsApi_getRetirePools @@ -1672,6 +1705,7 @@ paths: tags: *ref_2 security: - bearer: [] + - bearer: [] /contracts/retire/{contractId}/requests: delete: operationId: ContractsApi_clearRetireRequests @@ -1707,6 +1741,7 @@ paths: tags: *ref_2 security: - bearer: [] + - bearer: [] /contracts/retire/{contractId}/pools: delete: operationId: ContractsApi_clearRetirePools @@ -1742,6 +1777,7 @@ paths: tags: *ref_2 security: - bearer: [] + - bearer: [] post: operationId: ContractsApi_setRetirePool summary: Set retire pool. @@ -1782,6 +1818,7 @@ paths: tags: *ref_2 security: - bearer: [] + - bearer: [] /contracts/retire/pools/{poolId}: delete: operationId: ContractsApi_unsetRetirePool @@ -1817,6 +1854,7 @@ paths: tags: *ref_2 security: - bearer: [] + - bearer: [] /contracts/retire/requests/{requestId}: delete: operationId: ContractsApi_unsetRetireRequest @@ -1852,6 +1890,7 @@ paths: tags: *ref_2 security: - bearer: [] + - bearer: [] /contracts/retire/pools/{poolId}/retire: post: operationId: ContractsApi_retire @@ -1891,6 +1930,7 @@ paths: tags: *ref_2 security: - bearer: [] + - bearer: [] /contracts/retire/requests/{requestId}/approve: post: operationId: ContractsApi_approveRetire @@ -1922,6 +1962,7 @@ paths: tags: *ref_2 security: - bearer: [] + - bearer: [] /contracts/retire/requests/{requestId}/cancel: delete: operationId: ContractsApi_cancelRetireRequest @@ -1951,6 +1992,7 @@ paths: tags: *ref_2 security: - bearer: [] + - bearer: [] /contracts/retire/{contractId}/admin/{hederaId}: post: operationId: ContractsApi_retireAddAdmin @@ -1989,6 +2031,7 @@ paths: tags: *ref_2 security: - bearer: [] + - bearer: [] delete: operationId: ContractsApi_retireRemoveAdmin summary: Remove wipe admin. @@ -2026,6 +2069,7 @@ paths: tags: *ref_2 security: - bearer: [] + - bearer: [] /contracts/retire: get: operationId: ContractsApi_getRetireVCs @@ -2075,6 +2119,7 @@ paths: tags: *ref_2 security: - bearer: [] + - bearer: [] /demo/registered-users: get: operationId: DemoApi_registeredUsers @@ -2438,17 +2483,21 @@ paths: operationId: ModulesApi_getModuleSchemas parameters: [] responses: - '200': - description: '' + '401': + description: Unauthorized tags: &ref_4 - modules + security: + - bearer: [] post: operationId: ModulesApi_postSchemas parameters: [] responses: - '201': - description: '' + '401': + description: Unauthorized tags: *ref_4 + security: + - bearer: [] /modules/{uuid}: get: tags: @@ -2893,6 +2942,8 @@ paths: application/json: schema: $ref: '#/components/schemas/ToolDTO' + '401': + description: Unauthorized '500': description: Internal server error. content: @@ -2902,6 +2953,7 @@ paths: tags: &ref_5 - tools security: + - bearer: [] - bearerAuth: [] get: operationId: ToolsApi_getTools @@ -2931,6 +2983,8 @@ paths: application/json: schema: $ref: '#/components/schemas/ToolDTO' + '401': + description: Unauthorized '500': description: Internal server error. content: @@ -2939,6 +2993,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_5 security: + - bearer: [] - bearerAuth: [] /tools/push: post: @@ -2955,6 +3010,8 @@ paths: application/json: schema: $ref: '#/components/schemas/TaskDTO' + '401': + description: Unauthorized '500': description: Internal server error. content: @@ -2963,6 +3020,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_5 security: + - bearer: [] - bearerAuth: [] /tools/{id}: delete: @@ -2981,6 +3039,8 @@ paths: responses: '200': description: Successful operation. + '401': + description: Unauthorized '500': description: Internal server error. content: @@ -2989,6 +3049,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_5 security: + - bearer: [] - bearerAuth: [] get: operationId: ToolsApi_getToolById @@ -3022,6 +3083,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_5 security: + - bearer: [] - bearerAuth: [] put: operationId: ToolsApi_updateTool @@ -3055,6 +3117,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_5 security: + - bearer: [] - bearerAuth: [] /tools/{id}/publish: put: @@ -3091,6 +3154,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_5 security: + - bearer: [] - bearerAuth: [] /tools/{id}/push/publish: put: @@ -3127,6 +3191,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_5 security: + - bearer: [] - bearerAuth: [] /tools/validate: post: @@ -3155,6 +3220,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_5 security: + - bearer: [] - bearerAuth: [] /tools/{id}/export/file: get: @@ -3188,6 +3254,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_5 security: + - bearer: [] - bearerAuth: [] /tools/{id}/export/message: get: @@ -3223,6 +3290,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_5 security: + - bearer: [] - bearerAuth: [] /tools/import/message/preview: post: @@ -3252,6 +3320,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_5 security: + - bearer: [] - bearerAuth: [] /tools/import/message: post: @@ -3281,6 +3350,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_5 security: + - bearer: [] - bearerAuth: [] /tools/import/file/preview: post: @@ -3310,6 +3380,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_5 security: + - bearer: [] - bearerAuth: [] /tools/import/file: post: @@ -3339,6 +3410,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_5 security: + - bearer: [] - bearerAuth: [] /tools/import/file-metadata: post: @@ -3382,6 +3454,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_5 security: + - bearer: [] - bearerAuth: [] /tools/push/import/file: post: @@ -3411,6 +3484,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_5 security: + - bearer: [] - bearerAuth: [] /tools/push/import/file-metadata: post: @@ -3454,6 +3528,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_5 security: + - bearer: [] - bearerAuth: [] /tools/push/import/message: post: @@ -3483,6 +3558,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_5 security: + - bearer: [] - bearerAuth: [] /tools/menu/all: get: @@ -3511,6 +3587,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_5 security: + - bearer: [] - bearerAuth: [] /profiles/{username}: get: @@ -3930,6 +4007,8 @@ paths: type: string id: type: string + '401': + description: Unauthorized '500': description: Internal server error. content: @@ -3939,6 +4018,7 @@ paths: tags: &ref_7 - policies security: + - bearer: [] - bearerAuth: [] /policies/push/migrate-data: post: @@ -3962,6 +4042,8 @@ paths: application/json: schema: type: object + '401': + description: Unauthorized '500': description: Internal server error. content: @@ -3970,6 +4052,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_7 security: + - bearer: [] - bearerAuth: [] /policies/push: post: @@ -4017,6 +4100,8 @@ paths: application/json: schema: type: object + '401': + description: Unauthorized '500': description: Internal server error. content: @@ -4025,16 +4110,18 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_7 security: + - bearer: [] - bearerAuth: [] - bearerAuth: [] delete: operationId: PolicyApi_deletePolicyAsync parameters: [] responses: - '202': - description: '' + '401': + description: Unauthorized tags: *ref_7 security: + - bearer: [] - bearerAuth: [] /policies/{policyId}: get: @@ -4279,6 +4366,8 @@ paths: type: array items: type: object + '401': + description: Unauthorized '500': description: Internal server error. content: @@ -4287,6 +4376,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_7 security: + - bearer: [] - bearerAuth: [] - bearerAuth: [] /policies/{policyId}/draft: @@ -4370,6 +4460,8 @@ paths: application/json: schema: type: object + '401': + description: Unauthorized '500': description: Internal server error. content: @@ -4378,6 +4470,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_7 security: + - bearer: [] - bearerAuth: [] - bearerAuth: [] /policies/{policyId}/groups: @@ -4518,6 +4611,8 @@ paths: type: array items: type: object + '401': + description: Unauthorized '500': description: Internal server error. content: @@ -4526,6 +4621,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_7 security: + - bearer: [] - bearerAuth: [] - bearerAuth: [] /policies/{policyId}/data: @@ -4549,6 +4645,8 @@ paths: schema: type: string format: binary + '401': + description: Unauthorized '500': description: Internal server error. content: @@ -4557,6 +4655,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_7 security: + - bearer: [] - bearerAuth: [] - bearerAuth: [] /policies/data: @@ -4582,6 +4681,8 @@ paths: application/json: schema: type: object + '401': + description: Unauthorized '500': description: Internal server error. content: @@ -4590,6 +4691,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_7 security: + - bearer: [] - bearerAuth: [] - bearerAuth: [] /policies/{policyId}/tag-block-map: @@ -4612,6 +4714,8 @@ paths: application/json: schema: type: object + '401': + description: Unauthorized '500': description: Internal server error. content: @@ -4620,6 +4724,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_7 security: + - bearer: [] - bearerAuth: [] - bearerAuth: [] /policies/{policyId}/virtual-keys: @@ -4643,6 +4748,8 @@ paths: schema: type: string format: binary + '401': + description: Unauthorized '500': description: Internal server error. content: @@ -4651,6 +4758,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_7 security: + - bearer: [] - bearerAuth: [] - bearerAuth: [] post: @@ -4676,6 +4784,8 @@ paths: responses: '200': description: Operation completed. + '401': + description: Unauthorized '500': description: Internal server error. content: @@ -4684,6 +4794,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_7 security: + - bearer: [] - bearerAuth: [] - bearerAuth: [] /policies/{policyId}/blocks: @@ -4813,6 +4924,8 @@ paths: application/json: schema: type: object + '401': + description: Unauthorized '500': description: Internal server error. content: @@ -4821,6 +4934,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_7 security: + - bearer: [] - bearerAuth: [] - bearerAuth: [] get: @@ -4837,6 +4951,8 @@ paths: application/json: schema: type: object + '401': + description: Unauthorized '500': description: Internal server error. content: @@ -4845,6 +4961,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_7 security: + - bearer: [] - bearerAuth: [] - bearerAuth: [] /policies/{policyId}/tag/{tagName}: @@ -4862,6 +4979,8 @@ paths: application/json: schema: type: object + '401': + description: Unauthorized '500': description: Internal server error. content: @@ -4870,6 +4989,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_7 security: + - bearer: [] - bearerAuth: [] - bearerAuth: [] /policies/{policyId}/blocks/{uuid}/parents: @@ -4877,9 +4997,11 @@ paths: operationId: PolicyApi_getBlockParents parameters: [] responses: - '200': - description: '' + '401': + description: Unauthorized tags: *ref_7 + security: + - bearer: [] /policies/{policyId}/export/file: get: tags: @@ -5519,9 +5641,11 @@ paths: operationId: PolicyApi_getBlockAbout parameters: [] responses: - '200': - description: '' + '401': + description: Unauthorized tags: *ref_7 + security: + - bearer: [] /policies/{policyId}/dry-run/users: get: tags: @@ -6016,6 +6140,7 @@ paths: tags: &ref_8 - schema security: + - bearer: [] - bearerAuth: [] /schema/{schemaId}/tree: get: @@ -6057,6 +6182,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_8 security: + - bearer: [] - bearerAuth: [] /schemas: get: @@ -6246,6 +6372,7 @@ paths: tags: &ref_9 - schemas security: + - bearer: [] - bearerAuth: [] /schemas/list/all: get: @@ -6276,6 +6403,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_9 security: + - bearer: [] - bearerAuth: [] /schemas/list/sub: get: @@ -6318,6 +6446,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_9 security: + - bearer: [] - bearerAuth: [] /schemas/push/copy: post: @@ -7473,19 +7602,23 @@ paths: operationId: SettingsApi_getAbout parameters: [] responses: - '200': - description: '' + '401': + description: Unauthorized tags: - settings + security: + - bearer: [] /tags: post: operationId: TagsApi_setTags parameters: [] responses: - '201': - description: '' + '401': + description: Unauthorized tags: - tags + security: + - bearer: [] /tags/search: post: tags: @@ -8034,10 +8167,12 @@ paths: operationId: TokensApi_deleteTokenAsync parameters: [] responses: - '202': - description: '' + '401': + description: Unauthorized tags: &ref_10 - tokens + security: + - bearer: [] /tokens/{tokenId}/associate: put: tags: @@ -8590,6 +8725,7 @@ paths: tags: *ref_10 security: - bearer: [] + - bearer: [] /themes: get: tags: @@ -9019,6 +9155,8 @@ paths: application/json: schema: type: boolean + '401': + description: Unauthorized '500': description: Internal server error. content: @@ -9027,6 +9165,8 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: - wizard + security: + - bearer: [] /wizard/{policyId}/config: post: tags: @@ -9127,6 +9267,7 @@ paths: tags: &ref_12 - suggestions security: + - bearer: [] - bearer: [] - bearerAuth: [] /suggestions/config: @@ -9160,6 +9301,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_12 security: + - bearer: [] - bearer: [] - bearerAuth: [] get: @@ -9186,6 +9328,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_12 security: + - bearer: [] - bearer: [] - bearerAuth: [] /notifications: @@ -9217,6 +9360,7 @@ paths: tags: &ref_13 - notifications security: + - bearer: [] - bearer: [] - bearerAuth: [] /notifications/new: @@ -9244,6 +9388,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_13 security: + - bearer: [] - bearer: [] - bearerAuth: [] /notifications/progresses: @@ -9271,6 +9416,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_13 security: + - bearer: [] - bearer: [] - bearerAuth: [] /notifications/read/all: @@ -9298,6 +9444,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_13 security: + - bearer: [] - bearer: [] - bearerAuth: [] /notifications/delete/{notificationId}: @@ -9328,6 +9475,7 @@ paths: $ref: '#/components/schemas/InternalServerErrorDTO' tags: *ref_13 security: + - bearer: [] - bearer: [] - bearerAuth: [] /projects/search: From a80fda33c6c206a0719b6a90602e198a0041b91c Mon Sep 17 00:00:00 2001 From: Ihar Date: Wed, 8 May 2024 17:26:58 +0500 Subject: [PATCH 09/16] fix: remove local data for cache from contracts --- api-gateway/src/api/service/contract.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/api-gateway/src/api/service/contract.ts b/api-gateway/src/api/service/contract.ts index f2a8da6fe9..02872f8f72 100644 --- a/api-gateway/src/api/service/contract.ts +++ b/api-gateway/src/api/service/contract.ts @@ -401,7 +401,6 @@ export class ContractsApi { req.query.pageIndex as any, req.query.pageSize as any ); - res.locals.data = contracts return res.header('X-Total-Count', count).send(contracts); } catch (error) { new Logger().error(error, ['API_GATEWAY']); @@ -1125,7 +1124,6 @@ export class ContractsApi { req.query.pageIndex as any, req.query.pageSize as any ); - res.locals.data = contracts return res.header('X-Total-Count', count).send(contracts); } catch (error) { new Logger().error(error, ['API_GATEWAY']); @@ -1213,7 +1211,6 @@ export class ContractsApi { req.query.pageIndex as any, req.query.pageSize as any ); - res.locals.data = contracts return res.header('X-Total-Count', count).send(contracts); } catch (error) { new Logger().error(error, ['API_GATEWAY']); @@ -1790,7 +1787,6 @@ export class ContractsApi { req.query.pageIndex as any, req.query.pageSize as any ); - res.locals.data = vcs return res.header('X-Total-Count', count).send(vcs); } catch (error) { new Logger().error(error, ['API_GATEWAY']); From a0261582aacc6208600a83b14a3effccf6c91c0a Mon Sep 17 00:00:00 2001 From: Ihar Date: Wed, 8 May 2024 17:39:23 +0500 Subject: [PATCH 10/16] fix: remove local data for cache from tags schemas --- api-gateway/src/api/service/tags.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/api-gateway/src/api/service/tags.ts b/api-gateway/src/api/service/tags.ts index 21af33f91e..fc685f3045 100644 --- a/api-gateway/src/api/service/tags.ts +++ b/api-gateway/src/api/service/tags.ts @@ -160,7 +160,6 @@ export class TagsApi { } const { items, count } = await guardians.getTagSchemas(owner, pageIndex, pageSize); items.forEach((s) => { s.readonly = s.readonly || s.owner !== owner }); - res.locals.data = SchemaUtils.toOld(items) return res .header('X-Total-Count', count) .send(SchemaUtils.toOld(items)); From 4abd8166dea0aafecb5b195f79561feee85e4fa0 Mon Sep 17 00:00:00 2001 From: Ihar Date: Wed, 8 May 2024 18:44:01 +0500 Subject: [PATCH 11/16] fix: export strime for schema file --- api-gateway/src/api/service/schema.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/api-gateway/src/api/service/schema.ts b/api-gateway/src/api/service/schema.ts index 3427cf52b6..a454439024 100644 --- a/api-gateway/src/api/service/schema.ts +++ b/api-gateway/src/api/service/schema.ts @@ -1588,8 +1588,7 @@ export class SchemaApi { }); res.header('Content-disposition', `attachment; filename=${name}`); res.header('Content-type', 'application/zip'); - arcStream.pipe(res); - return res; + return res.send(arcStream); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw error; From 24fe807733c32d65b41c8cd9ba3fe586381ace05 Mon Sep 17 00:00:00 2001 From: Ihar Date: Wed, 8 May 2024 19:25:40 +0500 Subject: [PATCH 12/16] fix: setHeader to header for fastify --- api-gateway/src/api/service/policy.ts | 14 +++++++------- api-gateway/src/app.ts | 10 ++++------ 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/api-gateway/src/api/service/policy.ts b/api-gateway/src/api/service/policy.ts index ec496668b5..fcdcdb1408 100644 --- a/api-gateway/src/api/service/policy.ts +++ b/api-gateway/src/api/service/policy.ts @@ -818,11 +818,11 @@ export class PolicyApi { req.params.policyId, req.user.did ); - res.setHeader( + res.header( 'Content-Disposition', `attachment; filename=${policy.name}.data` ); - res.setHeader('Content-Type', 'application/policy-data'); + res.header('Content-Type', 'application/policy-data'); return res.send(downloadResult); } catch (error) { new Logger().error(error, ['API_GATEWAY']); @@ -960,11 +960,11 @@ export class PolicyApi { req.params.policyId, req.user.did ); - res.setHeader( + res.header( 'Content-Disposition', `attachment; filename=${policy.name}.vk` ); - res.setHeader('Content-Type', 'application/virtual-keys'); + res.header('Content-Type', 'application/virtual-keys'); return res.send(downloadResult); } catch (error) { new Logger().error(error, ['API_GATEWAY']); @@ -2249,7 +2249,7 @@ export class PolicyApi { pageSize = req.query.pageSize; } const [data, count] = await engineService.getVirtualDocuments(req.params.policyId, 'transactions', pageIndex, pageSize) - return res.setHeader('X-Total-Count', count).send(data); + return res.header('X-Total-Count', count).send(data); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -2283,7 +2283,7 @@ export class PolicyApi { pageSize = req.query.pageSize; } const [data, count] = await engineService.getVirtualDocuments(req.params.policyId, 'artifacts', pageIndex, pageSize); - return res.setHeader('X-Total-Count', count).send(data); + return res.header('X-Total-Count', count).send(data); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); @@ -2316,7 +2316,7 @@ export class PolicyApi { pageSize = req.query.pageSize; } const [data, count] = await engineService.getVirtualDocuments(req.params.policyId, 'ipfs', pageIndex, pageSize) - return res.setHeader('X-Total-Count', count).send(data); + return res.header('X-Total-Count', count).send(data); } catch (error) { new Logger().error(error, ['API_GATEWAY']); throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); diff --git a/api-gateway/src/app.ts b/api-gateway/src/app.ts index 22fa490fed..2a65bd6b8a 100644 --- a/api-gateway/src/app.ts +++ b/api-gateway/src/app.ts @@ -24,6 +24,8 @@ import fastifyMultipart from '@fastify/multipart'; const PORT = process.env.PORT || 3002; +const BODY_LIMIT = 1024 * 1024 * 1024 + Promise.all([ NestFactory.create(AppModule, new FastifyAdapter({ ignoreTrailingSlash: true }), { rawBody: true, @@ -48,12 +50,8 @@ Promise.all([ await app.register(fastifyFormbody); await app.register(fastifyMultipart); - const bodyLimit = 10_485_760; - app.useBodyParser('json', { bodyLimit: 1024 * 1024 * 1024 }); - app.useBodyParser('binary/octet-stream', { bodyLimit: 1024 * 1024 * 1024 }); - // app.useBodyParser('multipart/form-data', { bodyLimit: 1024 * 1024 * 1024 }); - // app.use(json({ limit: '10mb' })); - + app.useBodyParser('json', { bodyLimit: BODY_LIMIT }); + app.useBodyParser('binary/octet-stream', { bodyLimit: BODY_LIMIT }); new Logger().setConnection(cn); await new Guardians().setConnection(cn).init(); From f3e95165cd6150fd612b604726e264c9047c0f76 Mon Sep 17 00:00:00 2001 From: Ihar Date: Wed, 8 May 2024 19:45:19 +0500 Subject: [PATCH 13/16] fix: linter errors --- api-gateway/src/helpers/interceptors/multipart.ts | 1 - api-gateway/src/helpers/interceptors/utils/multipart.ts | 5 +++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/api-gateway/src/helpers/interceptors/multipart.ts b/api-gateway/src/helpers/interceptors/multipart.ts index c71fb39ae0..6a22725d01 100644 --- a/api-gateway/src/helpers/interceptors/multipart.ts +++ b/api-gateway/src/helpers/interceptors/multipart.ts @@ -9,7 +9,6 @@ import { getFileFromPart } from './utils/index.js'; //types and interfaces import { FastifyRequest, MultipartFile, MultipartOptions } from './types/index.js'; - export function AnyFilesInterceptor(options: MultipartOptions = {}): Type { class MixinInterceptor implements NestInterceptor { async intercept(context: ExecutionContext, next: CallHandler): Promise> { diff --git a/api-gateway/src/helpers/interceptors/utils/multipart.ts b/api-gateway/src/helpers/interceptors/utils/multipart.ts index dcf5c12492..a5cb614bbf 100644 --- a/api-gateway/src/helpers/interceptors/utils/multipart.ts +++ b/api-gateway/src/helpers/interceptors/utils/multipart.ts @@ -6,7 +6,6 @@ import { MultipartFile as MultipartFileFastify} from '@fastify/multipart'; //types and interfaces import { MultipartFile, MultipartOptions } from '../types/index.js'; - export const getFileFromPart = async (part: MultipartFileFastify): Promise => { const buffer: Buffer = await part.toBuffer() return { @@ -30,7 +29,9 @@ export const validateFile = (file: MultipartFile, options: MultipartOptions): st } for (const validator of validators) { - if (validator.isValid(file)) continue; + if (validator.isValid(file)) { + continue + } return validator.buildErrorMessage(file); } From 83733eafc3d2c38be98b6693b33262ffa37af5cc Mon Sep 17 00:00:00 2001 From: Ihar Date: Wed, 8 May 2024 21:43:18 +0500 Subject: [PATCH 14/16] fix: req body is undefined for logger --- api-gateway/src/api/service/logger.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/api-gateway/src/api/service/logger.ts b/api-gateway/src/api/service/logger.ts index 515b06308b..9cf701fa57 100644 --- a/api-gateway/src/api/service/logger.ts +++ b/api-gateway/src/api/service/logger.ts @@ -40,6 +40,11 @@ export class LoggerApi { try { const filters: any = {}; const pageParameters: IPageParameters = {}; + + if(!req.body) { + req.body = {} + } + if (req.body.type) { filters.type = req.body.type; } From 8a0bbdcc29fbcbf8372b0e541352af8122f75145 Mon Sep 17 00:00:00 2001 From: Ihar Date: Thu, 9 May 2024 20:47:42 +0500 Subject: [PATCH 15/16] fix: multipart intercepter for artifats --- api-gateway/src/api/service/artifact.ts | 6 ++--- .../src/helpers/interceptors/multipart.ts | 9 +++---- .../helpers/interceptors/types/multipart.ts | 2 ++ .../helpers/interceptors/utils/multipart.ts | 27 +++---------------- 4 files changed, 12 insertions(+), 32 deletions(-) diff --git a/api-gateway/src/api/service/artifact.ts b/api-gateway/src/api/service/artifact.ts index 697eb679f1..cd936d83e4 100644 --- a/api-gateway/src/api/service/artifact.ts +++ b/api-gateway/src/api/service/artifact.ts @@ -11,7 +11,6 @@ import { Post, Req, Response, - UploadedFiles, UseInterceptors, } from '@nestjs/common'; import { @@ -31,8 +30,9 @@ import { InternalServerErrorDTO } from '../../middlewares/validation/schemas/err import { ApiImplicitQuery } from '@nestjs/swagger/dist/decorators/api-implicit-query.decorator.js'; import { ArtifactDTOItem } from '../../middlewares/validation/schemas/artifacts.js'; import { ApiImplicitParam } from '@nestjs/swagger/dist/decorators/api-implicit-param.decorator.js'; -import { FilesInterceptor } from '@nestjs/platform-express'; import { Auth } from '../../auth/auth.decorator.js'; +import { AnyFilesInterceptor } from '../../helpers/interceptors/multipart.js'; +import { UploadedFiles } from '../../helpers/decorators/file.js'; @Controller('artifacts') @ApiTags('artifacts') @@ -181,7 +181,7 @@ export class ArtifactApi { } }) @ApiExtraModels(ArtifactDTOItem, InternalServerErrorDTO) - @UseInterceptors(FilesInterceptor('artifacts')) + @UseInterceptors(AnyFilesInterceptor()) @HttpCode(HttpStatus.CREATED) @Auth(UserRole.STANDARD_REGISTRY) async uploadArtifacts(@Req() req, @UploadedFiles() files): Promise { diff --git a/api-gateway/src/helpers/interceptors/multipart.ts b/api-gateway/src/helpers/interceptors/multipart.ts index 6a22725d01..1a57aa19e9 100644 --- a/api-gateway/src/helpers/interceptors/multipart.ts +++ b/api-gateway/src/helpers/interceptors/multipart.ts @@ -28,15 +28,14 @@ export function AnyFilesInterceptor(options: MultipartOptions = {}): Type => { const buffer: Buffer = await part.toBuffer() @@ -14,25 +11,7 @@ export const getFileFromPart = async (part: MultipartFileFastify): Promise { - const validators: FileValidator[] = []; - - if (options.maxFileSize) { - validators.push(new MaxFileSizeValidator({ maxSize: options.maxFileSize })); - } - - if (options.fileType) { - validators.push(new FileTypeValidator({ fileType: options.fileType })); - } - - for (const validator of validators) { - if (validator.isValid(file)) { - continue - } - - return validator.buildErrorMessage(file); - } }; \ No newline at end of file From 02a77e3ef15837ac85ce93c163ff83942a0103bd Mon Sep 17 00:00:00 2001 From: Ihar Date: Fri, 10 May 2024 19:33:27 +0500 Subject: [PATCH 16/16] fix: sypress 500 error instead 400 in artifact --- api-gateway/src/api/service/artifact.ts | 2 +- .../src/helpers/interceptors/multipart.ts | 26 ++++++++++++------- .../helpers/interceptors/utils/multipart.ts | 26 ++++++++++++------- 3 files changed, 35 insertions(+), 19 deletions(-) diff --git a/api-gateway/src/api/service/artifact.ts b/api-gateway/src/api/service/artifact.ts index cd936d83e4..c5e5e83839 100644 --- a/api-gateway/src/api/service/artifact.ts +++ b/api-gateway/src/api/service/artifact.ts @@ -187,7 +187,7 @@ export class ArtifactApi { async uploadArtifacts(@Req() req, @UploadedFiles() files): Promise { try { if (!files) { - throw new HttpException('There are no files to upload', HttpStatus.UNPROCESSABLE_ENTITY) + throw new HttpException('There are no files to upload', HttpStatus.BAD_REQUEST) } const owner = req.user.did; const parentId = req.params.parentId; diff --git a/api-gateway/src/helpers/interceptors/multipart.ts b/api-gateway/src/helpers/interceptors/multipart.ts index 1a57aa19e9..81acaff5a1 100644 --- a/api-gateway/src/helpers/interceptors/multipart.ts +++ b/api-gateway/src/helpers/interceptors/multipart.ts @@ -15,24 +15,32 @@ export function AnyFilesInterceptor(options: MultipartOptions = {}): Type => { - const buffer: Buffer = await part.toBuffer() +export const getFileFromPart = async (part: MultipartFileFastify): Promise => { + const buffer: Buffer = await part.toBuffer(); + + const { byteLength: size } = buffer; + const { filename, mimetype, fieldname, encoding } = part; + + if (!size || !fieldname) { + return null; + } + return { buffer, - size: buffer.byteLength, - filename: part.filename, - mimetype: part.mimetype, - fieldname: part.fieldname, - encoding: part.encoding, - originalname: part.fieldname + size, + filename, + mimetype, + fieldname, + encoding, + originalname: fieldname, }; }; \ No newline at end of file