feat: Rate limiter on requests and login attempts.

This commit is contained in:
a.bouhuolia
2020-12-15 20:25:23 +02:00
parent 27483495cb
commit 6dd1229412
11 changed files with 170 additions and 4 deletions

View File

@@ -0,0 +1,24 @@
import { Container } from 'typedi';
import { Request, Response, NextFunction } from 'express';
import config from 'config';
const MAX_CONSECUTIVE_FAILS = config.throttler.login.points;
export default async (req: Request, res: Response, next: NextFunction) => {
const { crediential } = req.body;
const loginThrottler = Container.get('rateLimiter.login');
// Retrieve the rate limiter response of the given crediential.
const emailRateRes = await loginThrottler.get(crediential);
if (emailRateRes !== null && emailRateRes.consumedPoints >= MAX_CONSECUTIVE_FAILS) {
const retrySecs = Math.round(emailRateRes.msBeforeNext / 1000) || 1;
res.set('Retry-After', retrySecs);
res.status(429).send({
errors: [{ type: 'LOGIN_TO_MANY_ATTEMPTS', code: 400 }],
});
} else {
next();
}
}

View File

@@ -0,0 +1,16 @@
import { Container } from 'typedi';
import { Request, Response, NextFunction } from 'express';
/**
* Rate limiter middleware.
*/
export default (req: Request, res: Response, next: NextFunction) => {
const requestRateLimiter = Container.get('rateLimiter.request');
requestRateLimiter.attempt(req.ip).then(() => {
next();
})
.catch(() => {
res.status(429).send('Too Many Requests');
});
}