summary refs log tree commit diff
path: root/src/activitypub/routes/channel/#channel_id/outbox.ts
blob: 03a3125385b57d5e058115515848dbf67fc48254 (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
import { route } from "@spacebar/api";
import { Config, Message, Snowflake } from "@spacebar/util";
import { Router } from "express";
import { FindManyOptions, FindOperator, LessThan, MoreThan } from "typeorm";

const router = Router();
export default router;

router.get("/", route({}), async (req, res) => {
	// TODO: authentication

	const { channel_id } = req.params;
	const { page, min_id, max_id } = req.query;

	const { webDomain } = Config.get().federation;

	if (!page)
		return res.json({
			"@context": "https://www.w3.org/ns/activitystreams",
			id: `https://${webDomain}/fed/users/${channel_id}/outbox`,
			type: "OrderedCollection",
			first: `https://${webDomain}/fed/users/${channel_id}/outbox?page=true`,
			last: `https://${webDomain}/fed/users/${channel_id}/outbox?page=true&min_id=0`,
		});

	const after = min_id ? `${min_id}` : undefined;
	const before = max_id ? `${max_id}` : undefined;

	const query: FindManyOptions<Message> & {
		where: { id?: FindOperator<string> | FindOperator<string>[] };
	} = {
		order: { timestamp: "DESC" },
		take: 20,
		where: { channel_id: channel_id },
		relations: ["author"],
	};

	if (after) {
		if (BigInt(after) > BigInt(Snowflake.generate()))
			return res.status(422);
		query.where.id = MoreThan(after);
	} else if (before) {
		if (BigInt(before) > BigInt(Snowflake.generate()))
			return res.status(422);
		query.where.id = LessThan(before);
	}

	const messages = await Message.find(query);

	return res.json({
		"@context": "https://www.w3.org/ns/activitystreams",
		id: `https://${webDomain}/fed/channel/${channel_id}/outbox?page=true`,
		type: "OrderedCollection",
		next: `https://${webDomain}/fed/channel/${channel_id}/outbox?page=true&max_id=${
			messages[0]?.id || "0"
		}`,
		prev: `https://${webDomain}/fed/channel/${channel_id}/outbox?page=true&max_id=${
			messages[messages.length - 1]?.id || "0"
		}`,
		partOf: `https://${webDomain}/fed/channel/${channel_id}/outbox`,
		orderedItems: messages.map((message) => ({
			id: `https://${webDomain}/fed/channel/${channel_id}/message/${message.id}`,
			type: "Announce", // hmm
			actor: `https://${webDomain}/fed/channel/${channel_id}`,
			published: message.timestamp,
			to: ["https://www.w3.org/ns/activitystreams#Public"],
			cc: [
				message.author?.id
					? `https://${webDomain}/fed/users/${message.author.id}`
					: undefined,
				`https://${webDomain}/fed/channel/${channel_id}/followers`,
			],
			object: `https://${webDomain}/fed/channel/${channel_id}/messages/${message.id}`,
		})),
	});
});