diff --git a/src/api/routes/policies/instance/config.ts b/src/api/routes/policies/instance/config.ts
new file mode 100755
index 00000000..0885e95d
--- /dev/null
+++ b/src/api/routes/policies/instance/config.ts
@@ -0,0 +1,71 @@
+/*
+ Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
+ Copyright (C) 2023 Spacebar and Spacebar Contributors
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+
+import { route } from "@spacebar/api";
+import { Config, getRights } from "@spacebar/util";
+import { Request, Response, Router } from "express";
+
+const router = Router();
+
+router.get(
+ "/",
+ route({
+ responses: {
+ 200: {
+ body: "Object",
+ },
+ },
+ }),
+ async (req: Request, res: Response) => {
+ const general = Config.get();
+ let outputtedConfig;
+ if (req.user_id) {
+ const rights = await getRights(req.user_id);
+ if (rights.has("OPERATOR")) outputtedConfig = general;
+ } else {
+ outputtedConfig = {
+ limits_user_maxGuilds: general.limits.user.maxGuilds,
+ limits_user_maxBio: general.limits.user.maxBio,
+ limits_guild_maxEmojis: general.limits.guild.maxEmojis,
+ limits_guild_maxRoles: general.limits.guild.maxRoles,
+ limits_message_maxCharacters:
+ general.limits.message.maxCharacters,
+ limits_message_maxAttachmentSize:
+ general.limits.message.maxAttachmentSize,
+ limits_message_maxEmbedDownloadSize:
+ general.limits.message.maxEmbedDownloadSize,
+ limits_channel_maxWebhooks: general.limits.channel.maxWebhooks,
+ register_dateOfBirth_requiredc:
+ general.register.dateOfBirth.required,
+ register_password_required: general.register.password.required,
+ register_disabled: general.register.disabled,
+ register_requireInvite: general.register.requireInvite,
+ register_allowNewRegistration:
+ general.register.allowNewRegistration,
+ register_allowMultipleAccounts:
+ general.register.allowMultipleAccounts,
+ guild_autoJoin_canLeave: general.guild.autoJoin.canLeave,
+ guild_autoJoin_guilds_x: general.guild.autoJoin.guilds,
+ register_email_required: general.register.email.required,
+ };
+ }
+ res.send(outputtedConfig);
+ },
+);
+
+export default router;
diff --git a/src/api/routes/webhooks/#webhook_id/#token/index.ts b/src/api/routes/webhooks/#webhook_id/#token/index.ts
index aa73b3fe..6b0ba7de 100644
--- a/src/api/routes/webhooks/#webhook_id/#token/index.ts
+++ b/src/api/routes/webhooks/#webhook_id/#token/index.ts
@@ -13,6 +13,7 @@ import {
WebhooksUpdateEvent,
WebhookUpdateSchema,
handleFile,
+ ValidateName,
} from "@spacebar/util";
import { Request, Response, Router } from "express";
import { HTTPError } from "lambert-server";
@@ -350,7 +351,6 @@ router.patch(
"application",
],
});
-
const channel_id = webhook.channel_id;
if (!body.name && !body.avatar) {
throw new HTTPError("Empty messages are not allowed", 50006);
@@ -360,6 +360,11 @@ router.patch(
`/avatars/${webhook_id}`,
body.avatar as string,
);
+
+ if (body.name) {
+ ValidateName(body.name);
+ }
+
webhook.assign(body);
await Promise.all([
diff --git a/src/api/routes/webhooks/#webhook_id/index.ts b/src/api/routes/webhooks/#webhook_id/index.ts
index c27b4612..25eebc76 100644
--- a/src/api/routes/webhooks/#webhook_id/index.ts
+++ b/src/api/routes/webhooks/#webhook_id/index.ts
@@ -10,6 +10,7 @@ import {
Channel,
handleFile,
FieldErrors,
+ ValidateName,
} from "@spacebar/util";
import { Request, Response, Router } from "express";
import { HTTPError } from "lambert-server";
@@ -167,37 +168,7 @@ router.patch(
);
if (body.name) {
- const check_username = body.name.replace(/\s/g, "");
- if (!check_username) {
- throw FieldErrors({
- username: {
- code: "BASE_TYPE_REQUIRED",
- message: req.t("common:field.BASE_TYPE_REQUIRED"),
- },
- });
- }
-
- const { maxUsername } = Config.get().limits.user;
- if (
- check_username.length > maxUsername ||
- check_username.length < 2
- ) {
- throw FieldErrors({
- username: {
- code: "BASE_TYPE_BAD_LENGTH",
- message: `Must be between 2 and ${maxUsername} in length.`,
- },
- });
- }
-
- const blockedContains = ["discord", "clyde", "spacebar"];
- for (const word of blockedContains) {
- if (body.name.toLowerCase().includes(word)) {
- return res.status(400).json({
- username: [`Username cannot contain "${word}"`],
- });
- }
- }
+ ValidateName(body.name);
}
const channel_id = body.channel_id || webhook.channel_id;
diff --git a/src/util/util/NameValidation.ts b/src/util/util/NameValidation.ts
new file mode 100755
index 00000000..857a2517
--- /dev/null
+++ b/src/util/util/NameValidation.ts
@@ -0,0 +1,51 @@
+/*
+ Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
+ Copyright (C) 2023 Spacebar and Spacebar Contributors
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+
+import { Config } from "./Config";
+import { FieldErrors } from "./FieldError";
+import { HTTPError } from "lambert-server";
+
+export function ValidateName(name: string) {
+ const check_username = name.replace(/\s/g, "");
+ if (!check_username) {
+ throw FieldErrors({
+ username: {
+ code: "BASE_TYPE_REQUIRED",
+ message: "common:field.BASE_TYPE_REQUIRED",
+ },
+ });
+ }
+
+ const { maxUsername } = Config.get().limits.user;
+ if (check_username.length > maxUsername || check_username.length < 2) {
+ throw FieldErrors({
+ username: {
+ code: "BASE_TYPE_BAD_LENGTH",
+ message: `Must be between 2 and ${maxUsername} in length.`,
+ },
+ });
+ }
+
+ const blockedContains = ["discord", "clyde", "spacebar"];
+ for (const word of blockedContains) {
+ if (name.toLowerCase().includes(word)) {
+ throw new HTTPError(`Username cannot contain "${word}"`, 400);
+ }
+ }
+ return name;
+}
diff --git a/src/util/util/index.ts b/src/util/util/index.ts
index 10e09b5c..f55315e3 100644
--- a/src/util/util/index.ts
+++ b/src/util/util/index.ts
@@ -43,3 +43,4 @@ export * from "./TraverseDirectory";
export * from "./WebAuthn";
export * from "./Gifs";
export * from "./Application";
+export * from "./NameValidation";