summary refs log tree commit diff
path: root/src/api/routes/guilds/templates/index.ts
diff options
context:
space:
mode:
authorMadeline <46743919+MaddyUnderStars@users.noreply.github.com>2022-09-25 18:24:21 +1000
committerMadeline <46743919+MaddyUnderStars@users.noreply.github.com>2022-09-25 23:35:18 +1000
commitf44f5d7ac2d24ff836c2e1d4b2fa58da04b13052 (patch)
treea6655c41bb3db79c30fd876b06ee60fe9cf70c9b /src/api/routes/guilds/templates/index.ts
parentAllow edited_timestamp to passthrough in handleMessage (diff)
downloadserver-f44f5d7ac2d24ff836c2e1d4b2fa58da04b13052.tar.xz
Refactor to mono-repo + upgrade packages
Diffstat (limited to 'src/api/routes/guilds/templates/index.ts')
-rw-r--r--src/api/routes/guilds/templates/index.ts84
1 files changed, 84 insertions, 0 deletions
diff --git a/src/api/routes/guilds/templates/index.ts b/src/api/routes/guilds/templates/index.ts
new file mode 100644
index 00000000..e281214f
--- /dev/null
+++ b/src/api/routes/guilds/templates/index.ts
@@ -0,0 +1,84 @@
+import { Request, Response, Router } from "express";
+import { Template, Guild, Role, Snowflake, Config, User, Member } from "@fosscord/util";
+import { route } from "@fosscord/api";
+import { DiscordApiErrors } from "@fosscord/util";
+import fetch from "node-fetch";
+const router: Router = Router();
+
+export interface GuildTemplateCreateSchema {
+	name: string;
+	avatar?: string | null;
+}
+
+router.get("/:code", route({}), async (req: Request, res: Response) => {
+	const { allowDiscordTemplates, allowRaws, enabled } = Config.get().templates;
+	if (!enabled) res.json({ code: 403, message: "Template creation & usage is disabled on this instance." }).sendStatus(403);
+
+	const { code } = req.params;
+
+	if (code.startsWith("discord:")) {
+		if (!allowDiscordTemplates) return res.json({ code: 403, message: "Discord templates cannot be used on this instance." }).sendStatus(403);
+		const discordTemplateID = code.split("discord:", 2)[1];
+
+		const discordTemplateData = await fetch(`https://discord.com/api/v9/guilds/templates/${discordTemplateID}`, {
+			method: "get",
+			headers: { "Content-Type": "application/json" }
+		});
+		return res.json(await discordTemplateData.json());
+	}
+
+	if (code.startsWith("external:")) {
+		if (!allowRaws) return res.json({ code: 403, message: "Importing raws is disabled on this instance." }).sendStatus(403);
+
+		return res.json(code.split("external:", 2)[1]);
+	}
+
+	const template = await Template.findOneOrFail({ where: { code: code } });
+	res.json(template);
+});
+
+router.post("/:code", route({ body: "GuildTemplateCreateSchema" }), async (req: Request, res: Response) => {
+	const { enabled, allowTemplateCreation, allowDiscordTemplates, allowRaws } = Config.get().templates;
+	if (!enabled) return res.json({ code: 403, message: "Template creation & usage is disabled on this instance." }).sendStatus(403);
+	if (!allowTemplateCreation) return res.json({ code: 403, message: "Template creation is disabled on this instance." }).sendStatus(403);
+
+	const { code } = req.params;
+	const body = req.body as GuildTemplateCreateSchema;
+
+	const { maxGuilds } = Config.get().limits.user;
+
+	const guild_count = await Member.count({ where: { id: req.user_id } });
+	if (guild_count >= maxGuilds) {
+		throw DiscordApiErrors.MAXIMUM_GUILDS.withParams(maxGuilds);
+	}
+
+	const template = await Template.findOneOrFail({ where: { code: code } });
+
+	const guild_id = Snowflake.generate();
+
+	const [guild, role] = await Promise.all([
+		Guild.create({
+			...body,
+			...template.serialized_source_guild,
+			id: guild_id,
+			owner_id: req.user_id
+		}).save(),
+		Role.create({
+			id: guild_id,
+			guild_id: guild_id,
+			color: 0,
+			hoist: false,
+			managed: true,
+			mentionable: true,
+			name: "@everyone",
+			permissions: BigInt("2251804225").toString(), // TODO: where did this come from?
+			position: 0,
+		}).save()
+	]);
+
+	await Member.addToGuild(req.user_id, guild_id);
+
+	res.status(201).json({ id: guild.id });
+});
+
+export default router;