Handle errors from redis store in request rate limit

This commit is contained in:
Ajay
2022-09-22 11:12:47 -04:00
parent 30bac658ed
commit 7007ab05e1

View File

@@ -1,9 +1,9 @@
import { getIP } from "../utils/getIP"; import { getIP } from "../utils/getIP";
import { getHash } from "../utils/getHash"; import { getHash } from "../utils/getHash";
import { getHashCache } from "../utils/getHashCache"; import { getHashCache } from "../utils/getHashCache";
import rateLimit, { RateLimitRequestHandler } from "express-rate-limit"; import rateLimit from "express-rate-limit";
import { RateLimitConfig } from "../types/config.model"; import { RateLimitConfig } from "../types/config.model";
import { Request } from "express"; import { Request, RequestHandler } from "express";
import { isUserVIP } from "../utils/isUserVIP"; import { isUserVIP } from "../utils/isUserVIP";
import { UserID } from "../types/user.model"; import { UserID } from "../types/user.model";
import RedisStore, { RedisReply } from "rate-limit-redis"; import RedisStore, { RedisReply } from "rate-limit-redis";
@@ -11,27 +11,32 @@ import redis from "../utils/redis";
import { config } from "../config"; import { config } from "../config";
import { Logger } from "../utils/logger"; import { Logger } from "../utils/logger";
export function rateLimitMiddleware(limitConfig: RateLimitConfig, getUserID?: (req: Request) => UserID): RateLimitRequestHandler { export function rateLimitMiddleware(limitConfig: RateLimitConfig, getUserID?: (req: Request) => UserID): RequestHandler {
return rateLimit({ try {
windowMs: limitConfig.windowMs, return rateLimit({
max: limitConfig.max, windowMs: limitConfig.windowMs,
message: limitConfig.message, max: limitConfig.max,
statusCode: limitConfig.statusCode, message: limitConfig.message,
legacyHeaders: false, statusCode: limitConfig.statusCode,
standardHeaders: false, legacyHeaders: false,
keyGenerator: (req) => { standardHeaders: false,
return getHash(getIP(req), 1); keyGenerator: (req) => {
}, return getHash(getIP(req), 1);
// eslint-disable-next-line @typescript-eslint/no-misused-promises },
handler: async (req, res, next) => { // eslint-disable-next-line @typescript-eslint/no-misused-promises
if (getUserID === undefined || !await isUserVIP(await getHashCache(getUserID(req)))) { handler: async (req, res, next) => {
return res.status(limitConfig.statusCode).send(limitConfig.message); if (getUserID === undefined || !await isUserVIP(await getHashCache(getUserID(req)))) {
} else { return res.status(limitConfig.statusCode).send(limitConfig.message);
return next(); } else {
} return next();
}, }
store: config.redis?.enabled ? new RedisStore({ },
sendCommand: (...args: string[]) => redis.sendCommand(args).catch((err) => Logger.error(err)) as Promise<RedisReply>, store: config.redis?.enabled ? new RedisStore({
}) : null, sendCommand: (...args: string[]) => redis.sendCommand(args).catch((err) => Logger.error(err)) as Promise<RedisReply>,
}); }) : null,
});
} catch (e) {
Logger.error(`Rate limit error: ${e}`);
return (req, res, next) => next();
}
} }