summary refs log tree commit diff
path: root/src/api/routes/guilds/#guild_id/index.ts
blob: 79c20678017ccee2191cd8354ad6ac746057f00d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import { Request, Response, Router } from "express";
import {
	DiscordApiErrors,
	emitEvent,
	getPermission,
	getRights,
	Guild,
	GuildUpdateEvent,
	handleFile,
	Member,
	GuildUpdateSchema,
	FosscordApiErrors,
} from "@fosscord/util";
import { HTTPError } from "lambert-server";
import { route } from "@fosscord/api";

const router = Router();

router.get("/", route({}), async (req: Request, res: Response) => {
	const { guild_id } = req.params;

	const [guild, member] = await Promise.all([
		Guild.findOneOrFail({ where: { id: guild_id } }),
		Member.findOne({ where: { guild_id: guild_id, id: req.user_id } }),
	]);
	if (!member)
		throw new HTTPError(
			"You are not a member of the guild you are trying to access",
			401,
		);

	// @ts-ignore
	guild.joined_at = member?.joined_at;

	return res.send(guild);
});

router.patch(
	"/",
	route({ body: "GuildUpdateSchema" }),
	async (req: Request, res: Response) => {
		const body = req.body as GuildUpdateSchema;
		const { guild_id } = req.params;

		const rights = await getRights(req.user_id);
		const permission = await getPermission(req.user_id, guild_id);

		if (!rights.has("MANAGE_GUILDS") && !permission.has("MANAGE_GUILD"))
			throw DiscordApiErrors.MISSING_PERMISSIONS.withParams(
				"MANAGE_GUILDS",
			);

		var guild = await Guild.findOneOrFail({
			where: { id: guild_id },
			relations: ["emojis", "roles", "stickers"],
		});

		// TODO: guild update check image

		if (body.icon && body.icon != guild.icon)
			body.icon = await handleFile(`/icons/${guild_id}`, body.icon);

		if (body.banner && body.banner !== guild.banner)
			body.banner = await handleFile(`/banners/${guild_id}`, body.banner);

		if (body.splash && body.splash !== guild.splash)
			body.splash = await handleFile(
				`/splashes/${guild_id}`,
				body.splash,
			);

		if (
			body.discovery_splash &&
			body.discovery_splash !== guild.discovery_splash
		)
			body.discovery_splash = await handleFile(
				`/discovery-splashes/${guild_id}`,
				body.discovery_splash,
			);

		if (body.features) {
			const diff = guild.features
				.filter((x) => !body.features?.includes(x))
				.concat(
					body.features.filter((x) => !guild.features.includes(x)),
				);

			// TODO move these
			const MUTABLE_FEATURES = [
				"COMMUNITY",
				"INVITES_DISABLED",
				"DISCOVERABLE",
			];

			for (var feature of diff) {
				if (MUTABLE_FEATURES.includes(feature)) continue;

				throw FosscordApiErrors.FEATURE_IS_IMMUTABLE.withParams(
					feature,
				);
			}

			// for some reason, they don't update in the assign.
			guild.features = body.features;
		}

		// TODO: check if body ids are valid
		guild.assign(body);

		const data = guild.toJSON();
		// TODO: guild hashes
		// TODO: fix vanity_url_code, template_id
		delete data.vanity_url_code;
		delete data.template_id;

		await Promise.all([
			guild.save(),
			emitEvent({
				event: "GUILD_UPDATE",
				data,
				guild_id,
			} as GuildUpdateEvent),
		]);

		return res.json(data);
	},
);

export default router;