diff --git a/src/lib/rate-limiter/rate-limiter-get.ts b/src/lib/rate-limiter/rate-limiter-get.ts index 21b081e1..1ba00043 100644 --- a/src/lib/rate-limiter/rate-limiter-get.ts +++ b/src/lib/rate-limiter/rate-limiter-get.ts @@ -22,7 +22,7 @@ export const authenticatedRateLimiter = new RateLimiterRedis({ duration: config.get('measurement.rateLimit.get.reset'), }); -const getRateLimiter = (ctx: ExtendedContext): { +const getRateLimiter = (ctx: ExtendedContext, extraId?: string): { type: 'user'| 'ip', id: string, rateLimiter: RateLimiterRedis @@ -30,24 +30,25 @@ const getRateLimiter = (ctx: ExtendedContext): { if (ctx.state.user?.id) { return { type: 'user', - id: ctx.state.user.id, + id: extraId ? `${ctx.state.user.id}:${extraId}` : ctx.state.user.id, rateLimiter: authenticatedRateLimiter, }; } + const ip = requestIp.getClientIp(ctx.req) ?? ''; return { type: 'ip', - id: requestIp.getClientIp(ctx.req) ?? '', + id: extraId ? `${ip}:${extraId}` : ip, rateLimiter: anonymousRateLimiter, }; }; -export const rateLimitMW = async (ctx: ExtendedContext, next: Next) => { +export const getMeasurementRateLimit = async (ctx: ExtendedContext, next: Next) => { if (ctx['isAdmin']) { return next(); } - const { rateLimiter, id } = getRateLimiter(ctx); + const { rateLimiter, id } = getRateLimiter(ctx, ctx.params['id']); try { await rateLimiter.consume(id); diff --git a/src/measurement/route/get-measurement.ts b/src/measurement/route/get-measurement.ts index 9e8d089b..d3ae3203 100644 --- a/src/measurement/route/get-measurement.ts +++ b/src/measurement/route/get-measurement.ts @@ -3,7 +3,7 @@ import type Router from '@koa/router'; import { getMeasurementStore } from '../store.js'; import { corsAuthHandler } from '../../lib/http/middleware/cors.js'; import { authenticate } from '../../lib/http/middleware/authenticate.js'; -import { rateLimitMW } from '../../lib/rate-limiter/rate-limiter-get.js'; +import { getMeasurementRateLimit } from '../../lib/rate-limiter/rate-limiter-get.js'; const store = getMeasurementStore(); @@ -27,5 +27,5 @@ const handle = async (ctx: ParameterizedContext { - router.get('/measurements/:id', '/measurements/:id([a-zA-Z0-9]+)', corsAuthHandler(), authenticate(), rateLimitMW, handle); + router.get('/measurements/:id', '/measurements/:id([a-zA-Z0-9]+)', corsAuthHandler(), authenticate(), getMeasurementRateLimit, handle); };