| 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, |
| }; |
|
|