diff --git a/govtool/metadata-validation/src/app.service.ts b/govtool/metadata-validation/src/app.service.ts index 9f7abfd36..b19d1d568 100644 --- a/govtool/metadata-validation/src/app.service.ts +++ b/govtool/metadata-validation/src/app.service.ts @@ -1,13 +1,20 @@ import { Injectable, Logger } from '@nestjs/common'; -import { catchError, firstValueFrom } from 'rxjs'; +import { catchError, firstValueFrom, timeout } from 'rxjs'; import { HttpService } from '@nestjs/axios'; import * as blake from 'blakejs'; +import { AxiosRequestConfig } from 'axios'; import { ValidateMetadataDTO } from '@dto'; import { LoggerMessage, MetadataValidationStatus } from '@enums'; import { validateMetadataStandard, parseMetadata } from '@utils'; import { ValidateMetadataResult } from '@types'; +const axiosConfig: AxiosRequestConfig = { + timeout: 5000, + maxContentLength: 10 * 1024 * 1024, // Max content length 10MB + maxBodyLength: 10 * 1024 * 1024, // Max body length 10MB +}; + @Injectable() export class AppService { constructor(private readonly httpService: HttpService) {} @@ -18,10 +25,12 @@ export class AppService { standard, }: ValidateMetadataDTO): Promise { let status: MetadataValidationStatus; - let metadata: any; + let metadata: Record; + try { const { data } = await firstValueFrom( - this.httpService.get(url).pipe( + this.httpService.get(url, axiosConfig).pipe( + timeout(5000), catchError(() => { throw MetadataValidationStatus.URL_NOT_FOUND; }), @@ -32,7 +41,12 @@ export class AppService { await validateMetadataStandard(data, standard); metadata = parseMetadata(data.body, standard); } - const hashedMetadata = blake.blake2bHex(data, undefined, 32); + + const hashedMetadata = blake.blake2bHex( + JSON.stringify(data), + undefined, + 32, + ); if (hashedMetadata !== hash) { throw MetadataValidationStatus.INVALID_HASH; diff --git a/govtool/metadata-validation/src/dto/validateMetadata.dto.ts b/govtool/metadata-validation/src/dto/validateMetadata.dto.ts index 69462cee0..63d66fb35 100644 --- a/govtool/metadata-validation/src/dto/validateMetadata.dto.ts +++ b/govtool/metadata-validation/src/dto/validateMetadata.dto.ts @@ -1,3 +1,5 @@ +import { IsEnum } from 'class-validator'; + import { MetadataStandard } from '@types'; export class ValidateMetadataDTO { @@ -5,5 +7,6 @@ export class ValidateMetadataDTO { url: string; + @IsEnum(MetadataStandard, { message: 'Invalid metadata standard' }) standard?: MetadataStandard; } diff --git a/govtool/metadata-validation/src/main.ts b/govtool/metadata-validation/src/main.ts index 756b909d9..bdedab481 100644 --- a/govtool/metadata-validation/src/main.ts +++ b/govtool/metadata-validation/src/main.ts @@ -3,6 +3,7 @@ import { ValidationPipe } from '@nestjs/common'; import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'; import { AppModule } from './app.module'; +import { version } from '../package.json'; async function bootstrap() { const app = await NestFactory.create(AppModule, { @@ -13,18 +14,14 @@ async function bootstrap() { const config = new DocumentBuilder() .setTitle('Metadata Validation Tool') .setDescription('The Metadata Validation Tool API description') - .setVersion('1.0.14') + .setVersion(version) .build(); const document = SwaggerModule.createDocument(app, config); SwaggerModule.setup('api', app, document); - app.useGlobalPipes( - new ValidationPipe({ - // Do not throw error on missing fields - exceptionFactory: () => ({ status: 200, valid: false }), - }), - ); + app.useGlobalPipes(new ValidationPipe()); + await app.listen(process.env.PORT); } bootstrap(); diff --git a/govtool/metadata-validation/tsconfig.json b/govtool/metadata-validation/tsconfig.json index 1044dc39f..46c6b800c 100644 --- a/govtool/metadata-validation/tsconfig.json +++ b/govtool/metadata-validation/tsconfig.json @@ -17,6 +17,7 @@ "strictBindCallApply": false, "forceConsistentCasingInFileNames": false, "noFallthroughCasesInSwitch": false, + "resolveJsonModule": true, "paths": { "@/*": ["src/*"], "@dto": ["src/dto"],