Skip to content

Commit

Permalink
feat: rate limit teams
Browse files Browse the repository at this point in the history
  • Loading branch information
hsanger committed Oct 16, 2024
1 parent fc3a030 commit 532a953
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 7 deletions.
5 changes: 5 additions & 0 deletions server/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,11 @@ export interface ConfigType {
* The list is only reloaded on server startup.
*/
readonly ipBlocklistURL?: string

/**
* Limits the number of teams that can be created by any one IP address.
*/
readonly maxTeams?: number
}

/**
Expand Down
28 changes: 21 additions & 7 deletions server/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ function removePunishment(ip: string): void {
}
}

let teamsCreated: Record<string, number> = {};

export const customTeams: Map<string, CustomTeam> = new Map<string, CustomTeam>();

export let maxTeamSize = typeof Config.maxTeamSize === "number" ? Config.maxTeamSize : Config.maxTeamSize.rotation[0];
Expand Down Expand Up @@ -148,19 +150,25 @@ if (isMainThread) {
upgrade(res, req, context) {
res.onAborted((): void => { /* Handle errors in WS connection */ });

const searchParams = new URLSearchParams(req.getQuery());
const ip = getIP(res, req);
const maxTeams = Config.protection?.maxTeams;
if (
maxTeamSize === TeamSize.Solo
|| (maxTeams && teamsCreated[ip] > maxTeams)
) {
forbidden(res);
return;
}

const searchParams = new URLSearchParams(req.getQuery());
const teamID = searchParams.get("teamID");

let team!: CustomTeam;
const noTeamIdGiven = teamID !== null;
if (
maxTeamSize === TeamSize.Solo
|| (
noTeamIdGiven
// @ts-expect-error cleanest overall way to do this (`undefined` gets filtered out anyways)
&& (team = customTeams.get(teamID)) === undefined
)
noTeamIdGiven
// @ts-expect-error cleanest overall way to do this (`undefined` gets filtered out anyways)
&& (team = customTeams.get(teamID)) === undefined
) {
forbidden(res);
return;
Expand All @@ -177,6 +185,10 @@ if (isMainThread) {
isLeader = true;
team = new CustomTeam();
customTeams.set(team.id, team);

if (Config.protection?.maxTeams) {
teamsCreated[ip] = (teamsCreated[ip] ?? 0) + 1;
}
}

const name = cleanUsername(searchParams.get("name"));
Expand Down Expand Up @@ -354,6 +366,8 @@ if (isMainThread) {
}
}

teamsCreated = {};

Logger.log("Reloaded punishment list");
}, protection.refreshDuration);

Expand Down

0 comments on commit 532a953

Please sign in to comment.