diff --git a/backend/ratelimit.ts b/backend/ratelimit.ts index 0706ade..77115f1 100644 --- a/backend/ratelimit.ts +++ b/backend/ratelimit.ts @@ -7,12 +7,7 @@ import { rateLimit } from 'express-rate-limit'; */ const rateLimiterGroups = new Map void>(); -/** - * creates middleware for rate limiting - */ -export const rateLimiterMiddleware = (group: string, config: EndpointRateLimitConfiguration | undefined): (req: Request, res: Response, next: NextFunction) => void => { - if (rateLimiterGroups.has(group)) return rateLimiterGroups.get(group)!; - +export const setRateLimiter = (group: string, config: EndpointRateLimitConfiguration | undefined): (req: Request, res: Response, next: NextFunction) => void => { if (config == null) { // config might be null if the user doesnt want a rate limit rateLimiterGroups.set(group, (req, res, next) => { next(); @@ -38,4 +33,14 @@ export const rateLimiterMiddleware = (group: string, config: EndpointRateLimitCo return rateLimiterGroups.get(group)!; } +} +/** + * creates middleware for rate limiting + */ +export const rateLimiterMiddleware = (group: string, config: EndpointRateLimitConfiguration | undefined): (req: Request, res: Response, next: NextFunction) => void => { + if (!rateLimiterGroups.has(group)) setRateLimiter(group, config); + + return (req, res, next) => { + return rateLimiterGroups.get(group)!(req, res, next); + }; }; \ No newline at end of file diff --git a/backend/routers/api.ts b/backend/routers/api.ts index 3ef56db..2117bcd 100644 --- a/backend/routers/api.ts +++ b/backend/routers/api.ts @@ -8,7 +8,7 @@ import { log } from '../log'; import { nanoid } from '../generators'; import { UserConfig } from '../UserConfig'; import { MySql } from '../sql/mysql'; -import { rateLimiterMiddleware } from '../ratelimit'; +import { rateLimiterMiddleware, setRateLimiter } from '../ratelimit'; const router = Router({ caseSensitive: true }); @@ -30,6 +30,11 @@ router.post('/setup', BodyParserJson(), async (req, res) => { if (UserConfig.config.sql?.mySql != null) await Promise.all([MySql.configure(), data.setDataModeToSql()]); + // set rate limits + if (UserConfig.config.rateLimit?.api) setRateLimiter('api', UserConfig.config.rateLimit.api); + if (UserConfig.config.rateLimit?.login) setRateLimiter('login', UserConfig.config.rateLimit.login); + if (UserConfig.config.rateLimit?.upload) setRateLimiter('upload', UserConfig.config.rateLimit.upload); + log.success('Setup', 'completed'); return res.json({ success: true }); @@ -39,7 +44,7 @@ router.post('/setup', BodyParserJson(), async (req, res) => { }); // User login -router.post('/login', rateLimiterMiddleware('login', UserConfig.config.rateLimit?.login), BodyParserJson(), (req, res) => { +router.post('/login', rateLimiterMiddleware('login', UserConfig.config?.rateLimit?.login), BodyParserJson(), (req, res) => { const { username, password } = req.body; data.getAll('users') @@ -69,7 +74,7 @@ router.post('/login', rateLimiterMiddleware('login', UserConfig.config.rateLimit }); // todo: authenticate API endpoints -router.post('/user', rateLimiterMiddleware('api', UserConfig.config.rateLimit?.api), BodyParserJson(), async (req, res) => { +router.post('/user', rateLimiterMiddleware('api', UserConfig.config?.rateLimit?.api), BodyParserJson(), async (req, res) => { if (!UserConfig.ready) return res.status(409).json({ success: false, message: 'User config not ready' }); diff --git a/backend/routers/index.ts b/backend/routers/index.ts index e49df5e..eed8d13 100644 --- a/backend/routers/index.ts +++ b/backend/routers/index.ts @@ -30,7 +30,7 @@ bb.extend(router, { router.get('/', (req, res) => UserConfig.ready ? res.render('index', { version: App.pkgVersion }) : res.redirect('/setup')); // Upload flow -router.post('/', rateLimiterMiddleware("upload", UserConfig.config.rateLimit?.upload), async (req, res) => { +router.post('/', rateLimiterMiddleware("upload", UserConfig.config?.rateLimit?.upload), async (req, res) => { // Check user config if (!UserConfig.ready) return res.status(500).type('text').send('Configuration missing!');