forked from Chatbot/v3-api
first commit v3 initialiazed a temporary repository for darmanet client
This commit is contained in:
48
src/auth/guards/ip-rate-limiter.guard.ts
Normal file
48
src/auth/guards/ip-rate-limiter.guard.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { Request, Response } from 'express';
|
||||
import { rateLimit } from 'express-rate-limit';
|
||||
|
||||
@Injectable()
|
||||
export class IpRateLimiterGuard implements CanActivate {
|
||||
private readonly limiter: ReturnType<typeof rateLimit>;
|
||||
|
||||
constructor(private readonly configService: ConfigService) {
|
||||
const isProduction = this.configService.get('NODE_ENV') === 'production';
|
||||
this.limiter = rateLimit({
|
||||
windowMs: 15 * 60 * 1000, // 15 minutes
|
||||
max: isProduction ? 50 : 100, // Stricter in production
|
||||
standardHeaders: false,
|
||||
legacyHeaders: false,
|
||||
skip: () =>
|
||||
!isProduction &&
|
||||
this.configService.get('DISABLE_RATE_LIMIT') === 'true', // Skip in dev if needed
|
||||
keyGenerator: (req) => {
|
||||
// Use IP or user ID if available
|
||||
return isProduction ? req.ip : ''; // Less strict in development
|
||||
},
|
||||
handler: (req, res) => {
|
||||
res.status(429).json({
|
||||
statusCode: 429,
|
||||
message: isProduction
|
||||
? 'Too many requests'
|
||||
: 'Dev Mode: Rate limit warning (not enforced)',
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async canActivate(context: ExecutionContext): Promise<boolean> {
|
||||
const httpContext = context.switchToHttp();
|
||||
const req = httpContext.getRequest<Request>();
|
||||
const res = httpContext.getResponse<Response>();
|
||||
return new Promise((resolve) => {
|
||||
this.limiter(req, res, (err?: unknown) => {
|
||||
if (err) {
|
||||
return resolve(false);
|
||||
}
|
||||
resolve(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user