diff --git a/src/api/routes/auth/register.ts b/src/api/routes/auth/register.ts
index 370d7c52..eba86f77 100644
--- a/src/api/routes/auth/register.ts
+++ b/src/api/routes/auth/register.ts
@@ -17,6 +17,7 @@ import {
} from "@fosscord/api";
import bcrypt from "bcrypt";
import { HTTPError } from "lambert-server";
+import { MoreThan } from "typeorm";
const router: Router = Router();
@@ -25,7 +26,7 @@ router.post(
route({ body: "RegisterSchema" }),
async (req: Request, res: Response) => {
const body = req.body as RegisterSchema;
- const { register, security } = Config.get();
+ const { register, security, limits } = Config.get();
const ip = getIpAdress(req);
// email will be slightly modified version of the user supplied email -> e.g. protection against GMail Trick
@@ -198,6 +199,19 @@ router.post(
});
}
+ if (
+ limits.absoluteRate.register.enabled &&
+ (await User.count({ where: { created_at: MoreThan(new Date(Date.now() - limits.absoluteRate.register.window)) } }))
+ >= limits.absoluteRate.register.limit
+ ) {
+ console.log(
+ `Global register ratelimit exceeded for ${getIpAdress(req)}, ${req.body.username}, ${req.body.invite || "No invite given"}`
+ );
+ throw FieldErrors({
+ email: { code: "TOO_MANY_REGISTRATIONS", message: req.t("auth:register.TOO_MANY_REGISTRATIONS") }
+ });
+ }
+
const user = await User.register({ ...body, req });
if (body.invite) {
diff --git a/src/util/config/types/LimitConfigurations.ts b/src/util/config/types/LimitConfigurations.ts
index bcc2e7e2..105fd1d6 100644
--- a/src/util/config/types/LimitConfigurations.ts
+++ b/src/util/config/types/LimitConfigurations.ts
@@ -1,4 +1,4 @@
-import { ChannelLimits, GuildLimits, MessageLimits, RateLimits, UserLimits } from ".";
+import { ChannelLimits, GlobalRateLimits, GuildLimits, MessageLimits, RateLimits, UserLimits } from ".";
export class LimitsConfiguration {
user: UserLimits = new UserLimits();
@@ -6,4 +6,5 @@ export class LimitsConfiguration {
message: MessageLimits = new MessageLimits();
channel: ChannelLimits = new ChannelLimits();
rate: RateLimits = new RateLimits();
-}
\ No newline at end of file
+ absoluteRate: GlobalRateLimits = new GlobalRateLimits();
+}
diff --git a/src/util/config/types/subconfigurations/limits/GlobalRateLimits.ts b/src/util/config/types/subconfigurations/limits/GlobalRateLimits.ts
new file mode 100644
index 00000000..85280d3a
--- /dev/null
+++ b/src/util/config/types/subconfigurations/limits/GlobalRateLimits.ts
@@ -0,0 +1,10 @@
+export class GlobalRateLimits {
+ register: GlobalRateLimit = { limit: 25, window: 60 * 60 * 1000, enabled: true };
+ sendMessage: GlobalRateLimit = { limit: 50, window: 60 * 1000, enabled: true };
+}
+
+export class GlobalRateLimit {
+ limit: number = 100;
+ window: number = 60 * 60 * 1000;
+ enabled: boolean = true;
+}
diff --git a/src/util/config/types/subconfigurations/limits/index.ts b/src/util/config/types/subconfigurations/limits/index.ts
index 0b7304f6..ab7d9a5b 100644
--- a/src/util/config/types/subconfigurations/limits/index.ts
+++ b/src/util/config/types/subconfigurations/limits/index.ts
@@ -1,4 +1,5 @@
export * from "./ChannelLimits";
+export * from "./GlobalRateLimits";
export * from "./GuildLimits";
export * from "./MessageLimits";
export * from "./RateLimits";
|