| | const rateLimit = require('express-rate-limit'); |
| | const { limiterCache } = require('@librechat/api'); |
| | const { ViolationTypes } = require('librechat-data-provider'); |
| | const logViolation = require('~/cache/logViolation'); |
| |
|
| | const getEnvironmentVariables = () => { |
| | const FILE_UPLOAD_IP_MAX = parseInt(process.env.FILE_UPLOAD_IP_MAX) || 100; |
| | const FILE_UPLOAD_IP_WINDOW = parseInt(process.env.FILE_UPLOAD_IP_WINDOW) || 15; |
| | const FILE_UPLOAD_USER_MAX = parseInt(process.env.FILE_UPLOAD_USER_MAX) || 50; |
| | const FILE_UPLOAD_USER_WINDOW = parseInt(process.env.FILE_UPLOAD_USER_WINDOW) || 15; |
| | const FILE_UPLOAD_VIOLATION_SCORE = process.env.FILE_UPLOAD_VIOLATION_SCORE; |
| |
|
| | const fileUploadIpWindowMs = FILE_UPLOAD_IP_WINDOW * 60 * 1000; |
| | const fileUploadIpMax = FILE_UPLOAD_IP_MAX; |
| | const fileUploadIpWindowInMinutes = fileUploadIpWindowMs / 60000; |
| |
|
| | const fileUploadUserWindowMs = FILE_UPLOAD_USER_WINDOW * 60 * 1000; |
| | const fileUploadUserMax = FILE_UPLOAD_USER_MAX; |
| | const fileUploadUserWindowInMinutes = fileUploadUserWindowMs / 60000; |
| |
|
| | return { |
| | fileUploadIpWindowMs, |
| | fileUploadIpMax, |
| | fileUploadIpWindowInMinutes, |
| | fileUploadUserWindowMs, |
| | fileUploadUserMax, |
| | fileUploadUserWindowInMinutes, |
| | fileUploadViolationScore: FILE_UPLOAD_VIOLATION_SCORE, |
| | }; |
| | }; |
| |
|
| | const createFileUploadHandler = (ip = true) => { |
| | const { |
| | fileUploadIpMax, |
| | fileUploadIpWindowInMinutes, |
| | fileUploadUserMax, |
| | fileUploadUserWindowInMinutes, |
| | fileUploadViolationScore, |
| | } = getEnvironmentVariables(); |
| |
|
| | return async (req, res) => { |
| | const type = ViolationTypes.FILE_UPLOAD_LIMIT; |
| | const errorMessage = { |
| | type, |
| | max: ip ? fileUploadIpMax : fileUploadUserMax, |
| | limiter: ip ? 'ip' : 'user', |
| | windowInMinutes: ip ? fileUploadIpWindowInMinutes : fileUploadUserWindowInMinutes, |
| | }; |
| |
|
| | await logViolation(req, res, type, errorMessage, fileUploadViolationScore); |
| | res.status(429).json({ message: 'Too many file upload requests. Try again later' }); |
| | }; |
| | }; |
| |
|
| | const createFileLimiters = () => { |
| | const { fileUploadIpWindowMs, fileUploadIpMax, fileUploadUserWindowMs, fileUploadUserMax } = |
| | getEnvironmentVariables(); |
| |
|
| | const ipLimiterOptions = { |
| | windowMs: fileUploadIpWindowMs, |
| | max: fileUploadIpMax, |
| | handler: createFileUploadHandler(), |
| | store: limiterCache('file_upload_ip_limiter'), |
| | }; |
| |
|
| | const userLimiterOptions = { |
| | windowMs: fileUploadUserWindowMs, |
| | max: fileUploadUserMax, |
| | handler: createFileUploadHandler(false), |
| | keyGenerator: function (req) { |
| | return req.user?.id; |
| | }, |
| | store: limiterCache('file_upload_user_limiter'), |
| | }; |
| |
|
| | const fileUploadIpLimiter = rateLimit(ipLimiterOptions); |
| | const fileUploadUserLimiter = rateLimit(userLimiterOptions); |
| |
|
| | return { fileUploadIpLimiter, fileUploadUserLimiter }; |
| | }; |
| |
|
| | module.exports = { |
| | createFileLimiters, |
| | }; |
| |
|