diff options
Diffstat (limited to 'server/middlewares/rate-limiter.ts')
-rw-r--r-- | server/middlewares/rate-limiter.ts | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/server/middlewares/rate-limiter.ts b/server/middlewares/rate-limiter.ts index bc9513969..1eef8b360 100644 --- a/server/middlewares/rate-limiter.ts +++ b/server/middlewares/rate-limiter.ts | |||
@@ -1,10 +1,12 @@ | |||
1 | import express from 'express' | ||
2 | import RateLimit, { Options as RateLimitHandlerOptions } from 'express-rate-limit' | ||
3 | import { RunnerModel } from '@server/models/runner/runner' | ||
1 | import { UserRole } from '@shared/models' | 4 | import { UserRole } from '@shared/models' |
2 | import RateLimit from 'express-rate-limit' | ||
3 | import { optionalAuthenticate } from './auth' | 5 | import { optionalAuthenticate } from './auth' |
4 | 6 | ||
5 | const whitelistRoles = new Set([ UserRole.ADMINISTRATOR, UserRole.MODERATOR ]) | 7 | const whitelistRoles = new Set([ UserRole.ADMINISTRATOR, UserRole.MODERATOR ]) |
6 | 8 | ||
7 | function buildRateLimiter (options: { | 9 | export function buildRateLimiter (options: { |
8 | windowMs: number | 10 | windowMs: number |
9 | max: number | 11 | max: number |
10 | skipFailedRequests?: boolean | 12 | skipFailedRequests?: boolean |
@@ -15,17 +17,33 @@ function buildRateLimiter (options: { | |||
15 | skipFailedRequests: options.skipFailedRequests, | 17 | skipFailedRequests: options.skipFailedRequests, |
16 | 18 | ||
17 | handler: (req, res, next, options) => { | 19 | handler: (req, res, next, options) => { |
20 | // Bypass rate limit for registered runners | ||
21 | if (req.body?.runnerToken) { | ||
22 | return RunnerModel.loadByToken(req.body.runnerToken) | ||
23 | .then(runner => { | ||
24 | if (runner) return next() | ||
25 | |||
26 | return sendRateLimited(res, options) | ||
27 | }) | ||
28 | } | ||
29 | |||
30 | // Bypass rate limit for admins/moderators | ||
18 | return optionalAuthenticate(req, res, () => { | 31 | return optionalAuthenticate(req, res, () => { |
19 | if (res.locals.authenticated === true && whitelistRoles.has(res.locals.oauth.token.User.role)) { | 32 | if (res.locals.authenticated === true && whitelistRoles.has(res.locals.oauth.token.User.role)) { |
20 | return next() | 33 | return next() |
21 | } | 34 | } |
22 | 35 | ||
23 | return res.status(options.statusCode).send(options.message) | 36 | return sendRateLimited(res, options) |
24 | }) | 37 | }) |
25 | } | 38 | } |
26 | }) | 39 | }) |
27 | } | 40 | } |
28 | 41 | ||
29 | export { | 42 | // --------------------------------------------------------------------------- |
30 | buildRateLimiter | 43 | // Private |
44 | // --------------------------------------------------------------------------- | ||
45 | |||
46 | function sendRateLimited (res: express.Response, options: RateLimitHandlerOptions) { | ||
47 | return res.status(options.statusCode).send(options.message) | ||
48 | |||
31 | } | 49 | } |