diff --git a/src/app.ts b/src/app.ts index 2d3945e..098e5f3 100644 --- a/src/app.ts +++ b/src/app.ts @@ -18,7 +18,7 @@ import {shadowBanUser} from './routes/shadowBanUser'; import {getUsername} from './routes/getUsername'; import {setUsername} from './routes/setUsername'; import {viewedVideoSponsorTime} from './routes/viewedVideoSponsorTime'; -import {voteOnSponsorTime} from './routes/voteOnSponsorTime'; +import {voteOnSponsorTime, getUserID as voteGetUserID} from './routes/voteOnSponsorTime'; import {getSkipSegmentsByHash} from './routes/getSkipSegmentsByHash'; import {postSkipSegments} from './routes/postSkipSegments'; import {endpoint as getSkipSegments} from './routes/getSkipSegments'; @@ -55,7 +55,7 @@ function setupRoutes(app: Express) { const voteEndpoints: RequestHandler[] = [voteOnSponsorTime]; const viewEndpoints: RequestHandler[] = [viewedVideoSponsorTime]; if (config.rateLimit) { - if (config.rateLimit.vote) voteEndpoints.unshift(rateLimitMiddleware(config.rateLimit.vote)); + if (config.rateLimit.vote) voteEndpoints.unshift(rateLimitMiddleware(config.rateLimit.vote, voteGetUserID)); if (config.rateLimit.view) viewEndpoints.unshift(rateLimitMiddleware(config.rateLimit.view)); } diff --git a/src/middleware/requestRateLimit.ts b/src/middleware/requestRateLimit.ts index 8489fd8..807d291 100644 --- a/src/middleware/requestRateLimit.ts +++ b/src/middleware/requestRateLimit.ts @@ -2,8 +2,11 @@ import {getIP} from '../utils/getIP'; import {getHash} from '../utils/getHash'; import rateLimit from 'express-rate-limit'; import {RateLimitConfig} from '../types/config.model'; +import {Request} from 'express'; +import { isUserVIP } from '../utils/isUserVIP'; +import { UserID } from '../types/user.model'; -export function rateLimitMiddleware(limitConfig: RateLimitConfig): rateLimit.RateLimit { +export function rateLimitMiddleware(limitConfig: RateLimitConfig, getUserID?: (req: Request) => UserID): rateLimit.RateLimit { return rateLimit({ windowMs: limitConfig.windowMs, max: limitConfig.max, @@ -13,5 +16,12 @@ export function rateLimitMiddleware(limitConfig: RateLimitConfig): rateLimit.Rat keyGenerator: (req) => { return getHash(getIP(req), 1); }, + handler: (req, res, next) => { + if (getUserID === undefined || !isUserVIP(getHash(getUserID(req)))) { + return res.status(limitConfig.statusCode).send(limitConfig.message); + } else { + return next(); + } + } }); } diff --git a/src/routes/voteOnSponsorTime.ts b/src/routes/voteOnSponsorTime.ts index e343ed3..0ea328d 100644 --- a/src/routes/voteOnSponsorTime.ts +++ b/src/routes/voteOnSponsorTime.ts @@ -10,6 +10,7 @@ import {getFormattedTime} from '../utils/getFormattedTime'; import {getIP} from '../utils/getIP'; import {getHash} from '../utils/getHash'; import {config} from '../config'; +import { UserID } from '../types/user.model'; const voteTypes = { normal: 0, @@ -214,21 +215,25 @@ function categoryVote(UUID: string, userID: string, isVIP: boolean, isOwnSubmiss res.sendStatus(200); } -async function voteOnSponsorTime(req: Request, res: Response) { +export function getUserID(req: Request): UserID { + return req.query.userID as UserID; +} + +export async function voteOnSponsorTime(req: Request, res: Response) { const UUID = req.query.UUID as string; - let userID = req.query.userID as string; + const paramUserID = getUserID(req); let type = req.query.type !== undefined ? parseInt(req.query.type as string) : undefined; const category = req.query.category as string; - if (UUID === undefined || userID === undefined || (type === undefined && category === undefined)) { + if (UUID === undefined || paramUserID === undefined || (type === undefined && category === undefined)) { //invalid request res.sendStatus(400); return; } //hash the userID - const nonAnonUserID = getHash(userID); - userID = getHash(userID + UUID); + const nonAnonUserID = getHash(paramUserID); + const userID = getHash(paramUserID + UUID); //x-forwarded-for if this server is behind a proxy const ip = getIP(req); @@ -421,8 +426,4 @@ async function voteOnSponsorTime(req: Request, res: Response) { res.status(500).json({error: 'Internal error creating segment vote'}); } -} - -export { - voteOnSponsorTime, -}; +} \ No newline at end of file