2

I have requests in my controller, the @Param is the string version of the MongoId. If I call this request with an invalid format of the string, not Matching the MongoId format, the request goes through until the MongoDB call throws an internal server Error.

How do I validate that for example "aaa" or "ANWPINREBAFSOFASD" is not validated and stops as early as possible in my requests

Current Controller Endpoint:

@Get(':id')
  @ApiOperation({ summary: 'Get nice information' })
  findOne(
    @Param('id') id: string) {
    return this.niceService.findOne(id);
  }

The service that is called:

async findOne(id: string): Promise<NiceDocument> {

    const niceResult: NiceDocument = await this.NiceSchema.findById(id)

    if (!niceResult) {
      throw new NotFoundException()
    }
    return table
  }

2 Answers 2

6

The answer to this is to use a custom Validation pipe:

Create the pipe and export it:

import { ArgumentMetadata, BadRequestException, Injectable, PipeTransform } from "@nestjs/common";
import {ObjectId} from 'mongodb'

@Injectable()
export class ValidateMongoId implements PipeTransform<string> {
  transform(value: string, metadata: ArgumentMetadata): string{ // Optional casting into ObjectId if wanted!
      if(ObjectId.isValid(value)){
          if((String)(new ObjectId(value)) === value)
              return value;        
          throw new BadRequestException
      }
      throw new BadRequestException
  
  };
}

Use the pipe in the controller to validate the string

@Get(':id')
  @ApiOperation({ summary: 'Get nice information' })
  findOne(
    @Param('id', ValidateMongoId) id: string) {
    return this.niceService.findOne(id);
  }

Alternatively you could change the returntype in the pipe from string to ObjectId if you are using mongoDB instead of mongoose, mongoose supports requests witht he id in a string format

0

use class-validator in nestjs

by using @IsMongoIdObject()
like this:

   class ParamDTO{
@IsMongoIdObject()   
id:string
}

----Your Funcation---

@Get(':id')
  @ApiOperation({ summary: 'Get nice information' })
  findOne(
    @Param() id: ParamDTO) {
    return this.niceService.findOne(id.id);
  }
7
  • @IsMongoIdObject does not exist in class validator, and the Param is not an object per default And yes solving it with DtO by casting id like this: @Param(new ValidationPipe({ whitelist: true })) { id }: MongoIdDto) works too, but the goal is to NOT use a DtO / object and validate the string directly Commented Dec 12, 2021 at 10:04
  • please read Nestjs doc for validation: [docs.nestjs.com/techniques/validation] Commented Dec 12, 2021 at 10:07
  • I read through it, but there is no @IsMongoIdObject() in class-validator Commented Dec 12, 2021 at 11:04
  • sorry its @IsMongoId() not @IsMongoIdObject() Commented Dec 12, 2021 at 11:05
  • yea I figured xD, but there is another problem, making use of app.useGlobalPipes etc. the validation works while manually sending REST requests, but not when using the TestModule? Any suggestions Commented Dec 12, 2021 at 11:06

Not the answer you're looking for? Browse other questions tagged or ask your own question.