| | const rateLimit = require('express-rate-limit'); |
| | const { limiterCache } = require('@librechat/api'); |
| | const { ViolationTypes } = require('librechat-data-provider'); |
| | const denyRequest = require('~/server/middleware/denyRequest'); |
| | const { logViolation } = require('~/cache'); |
| |
|
| | const { |
| | MESSAGE_IP_MAX = 40, |
| | MESSAGE_IP_WINDOW = 1, |
| | MESSAGE_USER_MAX = 40, |
| | MESSAGE_USER_WINDOW = 1, |
| | MESSAGE_VIOLATION_SCORE: score, |
| | } = process.env; |
| |
|
| | const ipWindowMs = MESSAGE_IP_WINDOW * 60 * 1000; |
| | const ipMax = MESSAGE_IP_MAX; |
| | const ipWindowInMinutes = ipWindowMs / 60000; |
| |
|
| | const userWindowMs = MESSAGE_USER_WINDOW * 60 * 1000; |
| | const userMax = MESSAGE_USER_MAX; |
| | const userWindowInMinutes = userWindowMs / 60000; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | const createHandler = (ip = true) => { |
| | return async (req, res) => { |
| | const type = ViolationTypes.MESSAGE_LIMIT; |
| | const errorMessage = { |
| | type, |
| | max: ip ? ipMax : userMax, |
| | limiter: ip ? 'ip' : 'user', |
| | windowInMinutes: ip ? ipWindowInMinutes : userWindowInMinutes, |
| | }; |
| |
|
| | await logViolation(req, res, type, errorMessage, score); |
| | return await denyRequest(req, res, errorMessage); |
| | }; |
| | }; |
| |
|
| | |
| | |
| | |
| | const ipLimiterOptions = { |
| | windowMs: ipWindowMs, |
| | max: ipMax, |
| | handler: createHandler(), |
| | store: limiterCache('message_ip_limiter'), |
| | }; |
| |
|
| | const userLimiterOptions = { |
| | windowMs: userWindowMs, |
| | max: userMax, |
| | handler: createHandler(false), |
| | keyGenerator: function (req) { |
| | return req.user?.id; |
| | }, |
| | store: limiterCache('message_user_limiter'), |
| | }; |
| |
|
| | |
| | |
| | |
| | const messageIpLimiter = rateLimit(ipLimiterOptions); |
| |
|
| | |
| | |
| | |
| | const messageUserLimiter = rateLimit(userLimiterOptions); |
| |
|
| | module.exports = { |
| | messageIpLimiter, |
| | messageUserLimiter, |
| | }; |
| |
|