summary refs log tree commit diff
path: root/api/src/routes/webhooks/#webhook_id/index.ts
blob: e9b40ebf5a5dcffcd05f9818b28a8745bbd60f60 (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
import { Channel, Config, emitEvent, JWTOptions, Webhook, WebhooksUpdateEvent } from "@fosscord/util";
import { route, Authentication, handleFile } from "@fosscord/api";
import { Router, Request, Response, NextFunction } from "express";
import jwt from "jsonwebtoken";
import { HTTPError } from "lambert-server";
const router = Router();

export interface WebhookModifySchema {
	name?: string;
	avatar?: string;
	// channel_id?: string; // TODO
}

function validateWebhookToken(req: Request, res: Response, next: NextFunction) {
	const { jwtSecret } = Config.get().security;

	jwt.verify(req.params.token, jwtSecret, JWTOptions, async (err, decoded: any) => {
		if (err) return next(new HTTPError("Invalid Token", 401));
		next();
	});
}

router.get("/", route({}), async (req: Request, res: Response) => {
	res.json(await Webhook.findOneOrFail({ id: req.params.webhook_id }));
});

router.get("/:token", route({}), validateWebhookToken, async (req: Request, res: Response) => {
	res.json(await Webhook.findOneOrFail({ id: req.params.webhook_id }));
});

router.patch("/", route({ body: "WebhookModifySchema", permission: "MANAGE_WEBHOOKS" }), (req: Request, res: Response) => {
	return updateWebhook(req, res);
});

router.patch("/:token", route({ body: "WebhookModifySchema" }), validateWebhookToken, (req: Request, res: Response) => {
	return updateWebhook(req, res);
});

async function updateWebhook(req: Request, res: Response) {
	const webhook = await Webhook.findOneOrFail({ id: req.params.webhook_id });
	if (req.body.channel_id) await Channel.findOneOrFail({ id: req.body.channel_id, guild_id: webhook.guild_id });

	webhook.assign({
		...req.body,
		avatar: await handleFile(`/icons/${req.params.webhook_id}`, req.body.avatar)
	});

	await Promise.all([
		emitEvent({
			event: "WEBHOOKS_UPDATE",
			channel_id: webhook.channel_id,
			data: {
				channel_id: webhook.channel_id,
				guild_id: webhook.guild_id
			}
		} as WebhooksUpdateEvent),
		webhook.save()
	]);

	res.json(webhook);
}

router.delete("/", route({ permission: "MANAGE_WEBHOOKS" }), async (req: Request, res: Response) => {
	return deleteWebhook(req, res);
});

router.delete("/:token", route({}), validateWebhookToken, (req: Request, res: Response) => {
	return deleteWebhook(req, res);
});

async function deleteWebhook(req: Request, res: Response) {
	const webhook = await Webhook.findOneOrFail({ id: req.params.webhook_id });

	await Promise.all([
		emitEvent({
			event: "WEBHOOKS_UPDATE",
			channel_id: webhook.channel_id,
			data: {
				channel_id: webhook.channel_id,
				guild_id: webhook.guild_id
			}
		} as WebhooksUpdateEvent),
		webhook.remove()
	]);

	res.sendStatus(204);
}

export default router;