Skip to content

Commit

Permalink
feat(server): recaptcha guard on faucet route
Browse files Browse the repository at this point in the history
  • Loading branch information
chloezxyy committed Nov 22, 2023
1 parent e9592dd commit 6425835
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 6 deletions.
6 changes: 4 additions & 2 deletions apps/server/src/faucet/FaucetController.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { Controller, Get, HttpException, Inject, Param, Query, UseInterceptors } from '@nestjs/common';
import { Controller, HttpException, Inject, Param, Post, Query, UseGuards, UseInterceptors} from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { EnvironmentNetwork } from '@waveshq/walletkit-core';
import { TransactionResponse } from 'ethers';

import {RecaptchaGuard} from "../recaptcha/RecaptchaGuard";
import { AddressValidationInterceptor } from './AddressValidationInterceptor';
import { DefaultNetworkInterceptor } from './DefaultNetworkInterceptor';
import { FaucetService } from './FaucetService';
Expand All @@ -16,7 +17,8 @@ export class FaucetController {
private configService: ConfigService,
) {}

@Get(':address')
@Post(':address')
@UseGuards(RecaptchaGuard)
@UseInterceptors(AddressValidationInterceptor, DefaultNetworkInterceptor)
async sendFunds(
@Param('address') address: string,
Expand Down
6 changes: 4 additions & 2 deletions apps/server/src/faucet/FaucetModule.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import {HttpModule} from "@nestjs/axios";
import { CacheModule } from '@nestjs/cache-manager';
import { Module } from '@nestjs/common';

import {RecaptchaGuard} from "../recaptcha/RecaptchaGuard";
import { FaucetController } from './FaucetController';
import { FaucetService } from './FaucetService';

@Module({
imports: [CacheModule.register()],
imports: [CacheModule.register(), HttpModule],
controllers: [FaucetController],
providers: [FaucetService],
providers: [FaucetService, RecaptchaGuard],
})
export class FaucetModule {}
12 changes: 10 additions & 2 deletions apps/server/src/faucet/FaucetService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,20 @@ export class FaucetService {

private readonly privateKey: string;

constructor(private configService: ConfigService) {
constructor(
private configService: ConfigService,
) {
this.logger = new Logger(FaucetService.name);
this.privateKey = this.configService.getOrThrow('privateKey');
}

async sendFundsToUser(address: string, amount: string, network: EnvironmentNetwork): Promise<TransactionResponse> {
async sendFundsToUser(
address: string,
amount: string,
network: EnvironmentNetwork,
): Promise<TransactionResponse> {

// Send funds to user if recaptcha validation is successful
const evmProviderService = new EVMProviderService(network);
const wallet = new ethers.Wallet(this.privateKey, evmProviderService.provider);
const nonce = await evmProviderService.provider.getTransactionCount(wallet.address);
Expand Down
40 changes: 40 additions & 0 deletions apps/server/src/recaptcha/RecaptchaGuard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { HttpService } from '@nestjs/axios';
import { ExecutionContext, Injectable, Logger } from '@nestjs/common';
import { Request } from 'express';

@Injectable()
export class RecaptchaGuard {
private readonly logger: Logger;

constructor(private readonly httpService: HttpService) {
this.logger = new Logger(RecaptchaGuard.name);
}

async canActivate(context: ExecutionContext): Promise<boolean> {
const request = context.switchToHttp().getRequest<Request>();
return this.validateRecaptcha(request);
}

async validateRecaptcha(request: Request): Promise<boolean> {
const response = request.body.recaptchaValue;

if (!response) {
this.logger.log('Invalid body in recaptcha request');
return false;
}

const { data } = await this.httpService
.post(
`https://www.google.com/recaptcha/api/siteverify`,
null, // Since we're sending data in the body, set it to null
{
params: {
secret: process.env.SECRET_KEY,
response,
},
},
)
.toPromise();
return data.success;
}
}

0 comments on commit 6425835

Please sign in to comment.