Google recaptcha module
The NestJS module to protect your endpoints via google recaptcha.
Usage example here
Installation
$ npm i @nestlab/google-recaptcha
Configuration
@Module({
imports: [
GoogleRecaptchaModule.forRoot({
secretKey: process.env.GOOGLE_RECAPTCHA_SECRET_KEY,
response: req => req.headers.recaptcha,
skipIf: () => process.env.NODE_ENV !== 'production',
})
],
})
export class AppModule {
}
Usage
Use @Recaptcha
decorator to protect your endpoints.
@Controller('feedback')
export class FeedbackController {
@Recaptcha()
@Post('send')
async send(): Promise<any> {
}
}
If you want use google recaptcha guard in combination with another guards then you can use @UseGuards
decorator.
@Controller('feedback')
export class FeedbackController {
@UseGuards(Guard1, GoogleRecaptchaGuard, Guard2)
@Post('send')
async send(): Promise<any> {
}
}
Error handling
Google recaptcha guard will throw GoogleRecaptchaException on error.
GoogleRecaptchaException
has data with google recaptcha error codes.
GoogleRecaptchaException
← BadRequestException
← HttpException
← Error
.
You can handle it via ExceptionFilter.
Example exception filter implementation.
@Catch(GoogleRecaptchaException)
export class GoogleRecaptchaFilter implements ExceptionFilter {
catch(exception: GoogleRecaptchaException, host: ArgumentsHost): any {
const res: Response = host.switchToHttp().getResponse();
const firstErrorCode = exception.errorCodes.shift();
const transformedError = this.transformError(firstErrorCode);
res.status(transformedError.status).send({
type: 'GoogleRecaptchaError',
message: transformedError.message,
});
}
transformError(errorCode: ErrorCode): {status: number, message: string} {
switch (errorCode) {
case ErrorCode.InvalidInputResponse:
return {
status: HttpStatus.BAD_REQUEST,
message: 'The response parameter is invalid or malformed.',
};
case ErrorCode.MissingInputResponse:
return {
status: HttpStatus.BAD_REQUEST,
message: 'The response parameter is missing.',
};
case ErrorCode.TimeoutOrDuplicate:
return {
status: HttpStatus.BAD_REQUEST,
message: 'The response is no longer valid: either is too old or has been used previously.',
};
case ErrorCode.InvalidInputSecret:
case ErrorCode.MissingInputSecret:
return {
status: HttpStatus.INTERNAL_SERVER_ERROR,
message: 'Invalid module configuration. Please check public-secret keys.',
};
case ErrorCode.UnknownError:
case ErrorCode.BadRequest:
default:
return {
status: HttpStatus.INTERNAL_SERVER_ERROR,
message: 'Unexpected error. Please submit issue to @nestlab/google-recaptcha.',
};
}
}
}
And add your filter to application
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalFilters(new ErrorFilter(), new GoogleRecaptchaFilter());
await app.listen(3000);
}
bootstrap();
Enjoy!