ニジカ投稿局 https://tv.nizika.tv
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

rate-limiter.ts 2.0 KiB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import express from 'express'
  2. import RateLimit, { Options as RateLimitHandlerOptions } from 'express-rate-limit'
  3. import { UserRole, UserRoleType } from '@peertube/peertube-models'
  4. import { CONFIG } from '@server/initializers/config.js'
  5. import { RunnerModel } from '@server/models/runner/runner.js'
  6. import { optionalAuthenticate } from './auth.js'
  7. import { logger } from '@server/helpers/logger.js'
  8. const whitelistRoles = new Set<UserRoleType>([ UserRole.ADMINISTRATOR, UserRole.MODERATOR ])
  9. export function buildRateLimiter (options: {
  10. windowMs: number
  11. max: number
  12. skipFailedRequests?: boolean
  13. }) {
  14. return RateLimit({
  15. windowMs: options.windowMs,
  16. max: options.max,
  17. skipFailedRequests: options.skipFailedRequests,
  18. handler: (req, res, next, options) => {
  19. // Bypass rate limit for registered runners
  20. if (req.body?.runnerToken) {
  21. return RunnerModel.loadByToken(req.body.runnerToken)
  22. .then(runner => {
  23. if (runner) return next()
  24. return sendRateLimited(req, res, options)
  25. })
  26. }
  27. // Bypass rate limit for admins/moderators
  28. return optionalAuthenticate(req, res, () => {
  29. if (res.locals.authenticated === true && whitelistRoles.has(res.locals.oauth.token.User.role)) {
  30. return next()
  31. }
  32. return sendRateLimited(req, res, options)
  33. })
  34. }
  35. })
  36. }
  37. export const apiRateLimiter = buildRateLimiter({
  38. windowMs: CONFIG.RATES_LIMIT.API.WINDOW_MS,
  39. max: CONFIG.RATES_LIMIT.API.MAX
  40. })
  41. export const activityPubRateLimiter = buildRateLimiter({
  42. windowMs: CONFIG.RATES_LIMIT.ACTIVITY_PUB.WINDOW_MS,
  43. max: CONFIG.RATES_LIMIT.ACTIVITY_PUB.MAX
  44. })
  45. // ---------------------------------------------------------------------------
  46. // Private
  47. // ---------------------------------------------------------------------------
  48. function sendRateLimited (req: express.Request, res: express.Response, options: RateLimitHandlerOptions) {
  49. logger.debug('Rate limit exceeded for route ' + req.originalUrl)
  50. return res.status(options.statusCode).send(options.message)
  51. }