summary refs log tree commit diff
path: root/src/activitypub/routes/channel/#channel_id/outbox.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/activitypub/routes/channel/#channel_id/outbox.ts')
-rw-r--r--src/activitypub/routes/channel/#channel_id/outbox.ts76
1 files changed, 76 insertions, 0 deletions
diff --git a/src/activitypub/routes/channel/#channel_id/outbox.ts b/src/activitypub/routes/channel/#channel_id/outbox.ts
new file mode 100644

index 00000000..03a31253 --- /dev/null +++ b/src/activitypub/routes/channel/#channel_id/outbox.ts
@@ -0,0 +1,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}`, + })), + }); +});