From 4a7811a25ce78a108e9a42fcb6c86ac0ed6e09eb Mon Sep 17 00:00:00 2001 From: Puyodead1 Date: Thu, 23 Mar 2023 11:56:17 -0400 Subject: [PATCH] channels --- assets/schemas.json | Bin 3951834 -> 8216740 bytes src/api/routes/channels/#channel_id/index.ts | 40 +++- .../routes/channels/#channel_id/invites.ts | 32 ++- .../#channel_id/messages/#message_id/ack.ts | 10 +- .../messages/#message_id/crosspost.ts | 11 +- .../#channel_id/messages/#message_id/index.ts | 131 +++++++---- .../messages/#message_id/reactions.ts | 66 +++++- .../#channel_id/messages/bulk-delete.ts | 18 +- .../channels/#channel_id/messages/index.ts | 211 ++++++++++-------- .../channels/#channel_id/permissions.ts | 12 +- src/api/routes/channels/#channel_id/pins.ts | 42 +++- src/api/routes/channels/#channel_id/purge.ts | 22 +- .../routes/channels/#channel_id/recipients.ts | 150 +++++++------ src/api/routes/channels/#channel_id/typing.ts | 13 +- .../routes/channels/#channel_id/webhooks.ts | 40 +++- .../responses/ChannelInvitesResponse.ts | 3 + .../responses/ChannelMessagesResponse.ts | 3 + .../schemas/responses/ChannelPinsResponse.ts | 3 + .../responses/ChannelWebhooksResponse.ts | 3 + .../responses/WebhookCreateResponse.ts | 6 + src/util/schemas/responses/index.ts | 4 + 21 files changed, 562 insertions(+), 258 deletions(-) create mode 100644 src/util/schemas/responses/ChannelInvitesResponse.ts create mode 100644 src/util/schemas/responses/ChannelMessagesResponse.ts create mode 100644 src/util/schemas/responses/ChannelPinsResponse.ts create mode 100644 src/util/schemas/responses/ChannelWebhooksResponse.ts create mode 100644 src/util/schemas/responses/WebhookCreateResponse.ts diff --git a/assets/schemas.json b/assets/schemas.json index db47e1fc5544fc8a7f6039b32e61a86c5a683ca4..476a43b521303ea24daac984636073424e1bf7f6 100644 GIT binary patch delta 544172 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 diff --git a/src/api/routes/channels/#channel_id/index.ts b/src/api/routes/channels/#channel_id/index.ts index db0d4242..74e21a02 100644 --- a/src/api/routes/channels/#channel_id/index.ts +++ b/src/api/routes/channels/#channel_id/index.ts @@ -16,18 +16,18 @@ along with this program. If not, see . */ +import { route } from "@spacebar/api"; import { Channel, ChannelDeleteEvent, + ChannelModifySchema, ChannelType, ChannelUpdateEvent, - emitEvent, Recipient, + emitEvent, handleFile, - ChannelModifySchema, } from "@spacebar/util"; import { Request, Response, Router } from "express"; -import { route } from "@spacebar/api"; const router: Router = Router(); // TODO: delete channel @@ -35,7 +35,15 @@ const router: Router = Router(); router.get( "/", - route({ permission: "VIEW_CHANNEL" }), + route({ + permission: "VIEW_CHANNEL", + responses: { + 200: { + body: "Channel", + }, + 404: {}, + }, + }), async (req: Request, res: Response) => { const { channel_id } = req.params; @@ -49,7 +57,15 @@ router.get( router.delete( "/", - route({ permission: "MANAGE_CHANNELS" }), + route({ + permission: "MANAGE_CHANNELS", + responses: { + 200: { + body: "Channel", + }, + 404: {}, + }, + }), async (req: Request, res: Response) => { const { channel_id } = req.params; @@ -90,7 +106,19 @@ router.delete( router.patch( "/", - route({ body: "ChannelModifySchema", permission: "MANAGE_CHANNELS" }), + route({ + body: "ChannelModifySchema", + permission: "MANAGE_CHANNELS", + responses: { + 200: { + body: "Channel", + }, + 404: {}, + 400: { + body: "APIErrorResponse", + }, + }, + }), async (req: Request, res: Response) => { const payload = req.body as ChannelModifySchema; const { channel_id } = req.params; diff --git a/src/api/routes/channels/#channel_id/invites.ts b/src/api/routes/channels/#channel_id/invites.ts index 9f247fe8..35cdbca8 100644 --- a/src/api/routes/channels/#channel_id/invites.ts +++ b/src/api/routes/channels/#channel_id/invites.ts @@ -16,19 +16,18 @@ along with this program. If not, see . */ -import { Router, Request, Response } from "express"; -import { HTTPError } from "lambert-server"; -import { route } from "@spacebar/api"; -import { random } from "@spacebar/api"; +import { random, route } from "@spacebar/api"; import { Channel, + Guild, Invite, InviteCreateEvent, - emitEvent, - User, - Guild, PublicInviteRelation, + User, + emitEvent, } from "@spacebar/util"; +import { Request, Response, Router } from "express"; +import { HTTPError } from "lambert-server"; import { isTextChannel } from "./messages"; const router: Router = Router(); @@ -39,6 +38,15 @@ router.post( body: "InviteCreateSchema", permission: "CREATE_INSTANT_INVITE", right: "CREATE_INVITES", + responses: { + 201: { + body: "Invite", + }, + 404: {}, + 400: { + body: "APIErrorResponse", + }, + }, }), async (req: Request, res: Response) => { const { user_id } = req; @@ -84,7 +92,15 @@ router.post( router.get( "/", - route({ permission: "MANAGE_CHANNELS" }), + route({ + permission: "MANAGE_CHANNELS", + responses: { + 200: { + body: "ChannelInvitesResponse", + }, + 404: {}, + }, + }), async (req: Request, res: Response) => { const { channel_id } = req.params; const channel = await Channel.findOneOrFail({ diff --git a/src/api/routes/channels/#channel_id/messages/#message_id/ack.ts b/src/api/routes/channels/#channel_id/messages/#message_id/ack.ts index f098fa8e..f11fdcb2 100644 --- a/src/api/routes/channels/#channel_id/messages/#message_id/ack.ts +++ b/src/api/routes/channels/#channel_id/messages/#message_id/ack.ts @@ -16,6 +16,7 @@ along with this program. If not, see . */ +import { route } from "@spacebar/api"; import { emitEvent, getPermission, @@ -23,7 +24,6 @@ import { ReadState, } from "@spacebar/util"; import { Request, Response, Router } from "express"; -import { route } from "@spacebar/api"; const router = Router(); @@ -33,7 +33,13 @@ const router = Router(); router.post( "/", - route({ body: "MessageAcknowledgeSchema" }), + route({ + body: "MessageAcknowledgeSchema", + responses: { + 200: {}, + 403: {}, + }, + }), async (req: Request, res: Response) => { const { channel_id, message_id } = req.params; diff --git a/src/api/routes/channels/#channel_id/messages/#message_id/crosspost.ts b/src/api/routes/channels/#channel_id/messages/#message_id/crosspost.ts index 909a459e..5ca645c0 100644 --- a/src/api/routes/channels/#channel_id/messages/#message_id/crosspost.ts +++ b/src/api/routes/channels/#channel_id/messages/#message_id/crosspost.ts @@ -16,14 +16,21 @@ along with this program. If not, see . */ -import { Router, Response, Request } from "express"; import { route } from "@spacebar/api"; +import { Request, Response, Router } from "express"; const router = Router(); router.post( "/", - route({ permission: "MANAGE_MESSAGES" }), + route({ + permission: "MANAGE_MESSAGES", + responses: { + 200: { + body: "Message", + }, + }, + }), (req: Request, res: Response) => { // TODO: res.json({ diff --git a/src/api/routes/channels/#channel_id/messages/#message_id/index.ts b/src/api/routes/channels/#channel_id/messages/#message_id/index.ts index cd4b243e..77bc1e0e 100644 --- a/src/api/routes/channels/#channel_id/messages/#message_id/index.ts +++ b/src/api/routes/channels/#channel_id/messages/#message_id/index.ts @@ -19,24 +19,23 @@ import { Attachment, Channel, - emitEvent, - SpacebarApiErrors, - getPermission, - getRights, Message, MessageCreateEvent, + MessageCreateSchema, MessageDeleteEvent, + MessageEditSchema, MessageUpdateEvent, Snowflake, + SpacebarApiErrors, + emitEvent, + getPermission, + getRights, uploadFile, - MessageCreateSchema, - MessageEditSchema, } from "@spacebar/util"; -import { Router, Response, Request } from "express"; -import multer from "multer"; -import { route } from "@spacebar/api"; -import { handleMessage, postHandleMessage } from "@spacebar/api"; +import { Request, Response, Router } from "express"; import { HTTPError } from "lambert-server"; +import multer from "multer"; +import { handleMessage, postHandleMessage, route } from "../../../../../util"; const router = Router(); // TODO: message content/embed string length limit @@ -56,6 +55,16 @@ router.patch( body: "MessageEditSchema", permission: "SEND_MESSAGES", right: "SEND_MESSAGES", + responses: { + 200: { + body: "Message", + }, + 400: { + body: "APIErrorResponse", + }, + 403: {}, + 404: {}, + }, }), async (req: Request, res: Response) => { const { message_id, channel_id } = req.params; @@ -146,6 +155,16 @@ router.put( body: "MessageCreateSchema", permission: "SEND_MESSAGES", right: "SEND_BACKDATED_EVENTS", + responses: { + 200: { + body: "Message", + }, + 400: { + body: "APIErrorResponse", + }, + 403: {}, + 404: {}, + }, }), async (req: Request, res: Response) => { const { channel_id, message_id } = req.params; @@ -230,7 +249,19 @@ router.put( router.get( "/", - route({ permission: "VIEW_CHANNEL" }), + route({ + permission: "VIEW_CHANNEL", + responses: { + 200: { + body: "Message", + }, + 400: { + body: "APIErrorResponse", + }, + 403: {}, + 404: {}, + }, + }), async (req: Request, res: Response) => { const { message_id, channel_id } = req.params; @@ -252,38 +283,54 @@ router.get( }, ); -router.delete("/", route({}), async (req: Request, res: Response) => { - const { message_id, channel_id } = req.params; - - const channel = await Channel.findOneOrFail({ where: { id: channel_id } }); - const message = await Message.findOneOrFail({ where: { id: message_id } }); - - const rights = await getRights(req.user_id); - - if (message.author_id !== req.user_id) { - if (!rights.has("MANAGE_MESSAGES")) { - const permission = await getPermission( - req.user_id, - channel.guild_id, - channel_id, - ); - permission.hasThrow("MANAGE_MESSAGES"); - } - } else rights.hasThrow("SELF_DELETE_MESSAGES"); - - await Message.delete({ id: message_id }); - - await emitEvent({ - event: "MESSAGE_DELETE", - channel_id, - data: { - id: message_id, - channel_id, - guild_id: channel.guild_id, +router.delete( + "/", + route({ + responses: { + 204: {}, + 400: { + body: "APIErrorResponse", + }, + 404: {}, }, - } as MessageDeleteEvent); + }), + async (req: Request, res: Response) => { + const { message_id, channel_id } = req.params; - res.sendStatus(204); -}); + const channel = await Channel.findOneOrFail({ + where: { id: channel_id }, + }); + const message = await Message.findOneOrFail({ + where: { id: message_id }, + }); + + const rights = await getRights(req.user_id); + + if (message.author_id !== req.user_id) { + if (!rights.has("MANAGE_MESSAGES")) { + const permission = await getPermission( + req.user_id, + channel.guild_id, + channel_id, + ); + permission.hasThrow("MANAGE_MESSAGES"); + } + } else rights.hasThrow("SELF_DELETE_MESSAGES"); + + await Message.delete({ id: message_id }); + + await emitEvent({ + event: "MESSAGE_DELETE", + channel_id, + data: { + id: message_id, + channel_id, + guild_id: channel.guild_id, + }, + } as MessageDeleteEvent); + + res.sendStatus(204); + }, +); export default router; diff --git a/src/api/routes/channels/#channel_id/messages/#message_id/reactions.ts b/src/api/routes/channels/#channel_id/messages/#message_id/reactions.ts index cb66cd64..c6db772b 100644 --- a/src/api/routes/channels/#channel_id/messages/#message_id/reactions.ts +++ b/src/api/routes/channels/#channel_id/messages/#message_id/reactions.ts @@ -16,6 +16,7 @@ along with this program. If not, see . */ +import { route } from "@spacebar/api"; import { Channel, emitEvent, @@ -32,8 +33,7 @@ import { PublicUserProjection, User, } from "@spacebar/util"; -import { route } from "@spacebar/api"; -import { Router, Response, Request } from "express"; +import { Request, Response, Router } from "express"; import { HTTPError } from "lambert-server"; import { In } from "typeorm"; @@ -57,7 +57,17 @@ function getEmoji(emoji: string): PartialEmoji { router.delete( "/", - route({ permission: "MANAGE_MESSAGES" }), + route({ + permission: "MANAGE_MESSAGES", + responses: { + 204: {}, + 400: { + body: "APIErrorResponse", + }, + 404: {}, + 403: {}, + }, + }), async (req: Request, res: Response) => { const { message_id, channel_id } = req.params; @@ -83,7 +93,17 @@ router.delete( router.delete( "/:emoji", - route({ permission: "MANAGE_MESSAGES" }), + route({ + permission: "MANAGE_MESSAGES", + responses: { + 204: {}, + 400: { + body: "APIErrorResponse", + }, + 404: {}, + 403: {}, + }, + }), async (req: Request, res: Response) => { const { message_id, channel_id } = req.params; const emoji = getEmoji(req.params.emoji); @@ -120,7 +140,19 @@ router.delete( router.get( "/:emoji", - route({ permission: "VIEW_CHANNEL" }), + route({ + permission: "VIEW_CHANNEL", + responses: { + 200: { + body: "UserPublic", + }, + 400: { + body: "APIErrorResponse", + }, + 404: {}, + 403: {}, + }, + }), async (req: Request, res: Response) => { const { message_id, channel_id } = req.params; const emoji = getEmoji(req.params.emoji); @@ -148,7 +180,18 @@ router.get( router.put( "/:emoji/:user_id", - route({ permission: "READ_MESSAGE_HISTORY", right: "SELF_ADD_REACTIONS" }), + route({ + permission: "READ_MESSAGE_HISTORY", + right: "SELF_ADD_REACTIONS", + responses: { + 204: {}, + 400: { + body: "APIErrorResponse", + }, + 404: {}, + 403: {}, + }, + }), async (req: Request, res: Response) => { const { message_id, channel_id, user_id } = req.params; if (user_id !== "@me") throw new HTTPError("Invalid user"); @@ -219,7 +262,16 @@ router.put( router.delete( "/:emoji/:user_id", - route({}), + route({ + responses: { + 204: {}, + 400: { + body: "APIErrorResponse", + }, + 404: {}, + 403: {}, + }, + }), async (req: Request, res: Response) => { let { user_id } = req.params; const { message_id, channel_id } = req.params; diff --git a/src/api/routes/channels/#channel_id/messages/bulk-delete.ts b/src/api/routes/channels/#channel_id/messages/bulk-delete.ts index 18476d5c..db1617e2 100644 --- a/src/api/routes/channels/#channel_id/messages/bulk-delete.ts +++ b/src/api/routes/channels/#channel_id/messages/bulk-delete.ts @@ -16,18 +16,18 @@ along with this program. If not, see . */ -import { Router, Response, Request } from "express"; +import { route } from "@spacebar/api"; import { Channel, Config, emitEvent, getPermission, getRights, - MessageDeleteBulkEvent, Message, + MessageDeleteBulkEvent, } from "@spacebar/util"; +import { Request, Response, Router } from "express"; import { HTTPError } from "lambert-server"; -import { route } from "@spacebar/api"; const router: Router = Router(); @@ -38,7 +38,17 @@ export default router; // https://discord.com/developers/docs/resources/channel#bulk-delete-messages router.post( "/", - route({ body: "BulkDeleteSchema" }), + route({ + body: "BulkDeleteSchema", + responses: { + 204: {}, + 400: { + body: "APIErrorResponse", + }, + 403: {}, + 404: {}, + }, + }), async (req: Request, res: Response) => { const { channel_id } = req.params; const channel = await Channel.findOneOrFail({ diff --git a/src/api/routes/channels/#channel_id/messages/index.ts b/src/api/routes/channels/#channel_id/messages/index.ts index 7f0c9fb5..8e3c43d7 100644 --- a/src/api/routes/channels/#channel_id/messages/index.ts +++ b/src/api/routes/channels/#channel_id/messages/index.ts @@ -16,7 +16,7 @@ along with this program. If not, see . */ -import { Router, Response, Request } from "express"; +import { handleMessage, postHandleMessage, route } from "@spacebar/api"; import { Attachment, Channel, @@ -26,19 +26,19 @@ import { emitEvent, FieldErrors, getPermission, + Member, Message, MessageCreateEvent, - Snowflake, - uploadFile, - Member, MessageCreateSchema, + Reaction, ReadState, Rights, - Reaction, + Snowflake, + uploadFile, User, } from "@spacebar/util"; +import { Request, Response, Router } from "express"; import { HTTPError } from "lambert-server"; -import { handleMessage, postHandleMessage, route } from "@spacebar/api"; import multer from "multer"; import { FindManyOptions, FindOperator, LessThan, MoreThan } from "typeorm"; import { URL } from "url"; @@ -73,108 +73,123 @@ export function isTextChannel(type: ChannelType): boolean { // https://discord.com/developers/docs/resources/channel#create-message // get messages -router.get("/", route({}), async (req: Request, res: Response) => { - const channel_id = req.params.channel_id; - const channel = await Channel.findOneOrFail({ - where: { id: channel_id }, - }); - if (!channel) throw new HTTPError("Channel not found", 404); +router.get( + "/", + route({ + responses: { + 200: { + body: "ChannelMessagesResponse", + }, + 400: { + body: "APIErrorResponse", + }, + 403: {}, + 404: {}, + }, + }), + async (req: Request, res: Response) => { + const channel_id = req.params.channel_id; + const channel = await Channel.findOneOrFail({ + where: { id: channel_id }, + }); + if (!channel) throw new HTTPError("Channel not found", 404); - isTextChannel(channel.type); - const around = req.query.around ? `${req.query.around}` : undefined; - const before = req.query.before ? `${req.query.before}` : undefined; - const after = req.query.after ? `${req.query.after}` : undefined; - const limit = Number(req.query.limit) || 50; - if (limit < 1 || limit > 100) - throw new HTTPError("limit must be between 1 and 100", 422); + isTextChannel(channel.type); + const around = req.query.around ? `${req.query.around}` : undefined; + const before = req.query.before ? `${req.query.before}` : undefined; + const after = req.query.after ? `${req.query.after}` : undefined; + const limit = Number(req.query.limit) || 50; + if (limit < 1 || limit > 100) + throw new HTTPError("limit must be between 1 and 100", 422); - const halfLimit = Math.floor(limit / 2); + const halfLimit = Math.floor(limit / 2); - const permissions = await getPermission( - req.user_id, - channel.guild_id, - channel_id, - ); - permissions.hasThrow("VIEW_CHANNEL"); - if (!permissions.has("READ_MESSAGE_HISTORY")) return res.json([]); + const permissions = await getPermission( + req.user_id, + channel.guild_id, + channel_id, + ); + permissions.hasThrow("VIEW_CHANNEL"); + if (!permissions.has("READ_MESSAGE_HISTORY")) return res.json([]); - const query: FindManyOptions & { - where: { id?: FindOperator | FindOperator[] }; - } = { - order: { timestamp: "DESC" }, - take: limit, - where: { channel_id }, - relations: [ - "author", - "webhook", - "application", - "mentions", - "mention_roles", - "mention_channels", - "sticker_items", - "attachments", - ], - }; + const query: FindManyOptions & { + where: { id?: FindOperator | FindOperator[] }; + } = { + order: { timestamp: "DESC" }, + take: limit, + where: { channel_id }, + relations: [ + "author", + "webhook", + "application", + "mentions", + "mention_roles", + "mention_channels", + "sticker_items", + "attachments", + ], + }; - if (after) { - if (BigInt(after) > BigInt(Snowflake.generate())) - return res.status(422); - query.where.id = MoreThan(after); - } else if (before) { - if (BigInt(before) < BigInt(req.params.channel_id)) - return res.status(422); - query.where.id = LessThan(before); - } else if (around) { - query.where.id = [ - MoreThan((BigInt(around) - BigInt(halfLimit)).toString()), - LessThan((BigInt(around) + BigInt(halfLimit)).toString()), - ]; + if (after) { + if (BigInt(after) > BigInt(Snowflake.generate())) + return res.status(422); + query.where.id = MoreThan(after); + } else if (before) { + if (BigInt(before) < BigInt(req.params.channel_id)) + return res.status(422); + query.where.id = LessThan(before); + } else if (around) { + query.where.id = [ + MoreThan((BigInt(around) - BigInt(halfLimit)).toString()), + LessThan((BigInt(around) + BigInt(halfLimit)).toString()), + ]; - return res.json([]); // TODO: fix around - } + return res.json([]); // TODO: fix around + } - const messages = await Message.find(query); - const endpoint = Config.get().cdn.endpointPublic; + const messages = await Message.find(query); + const endpoint = Config.get().cdn.endpointPublic; - return res.json( - messages.map((x: Partial) => { - (x.reactions || []).forEach((y: Partial) => { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - //@ts-ignore - if ((y.user_ids || []).includes(req.user_id)) y.me = true; - delete y.user_ids; - }); - if (!x.author) - x.author = User.create({ - id: "4", - discriminator: "0000", - username: "Spacebar Ghost", - public_flags: 0, + return res.json( + messages.map((x: Partial) => { + (x.reactions || []).forEach((y: Partial) => { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + if ((y.user_ids || []).includes(req.user_id)) y.me = true; + delete y.user_ids; + }); + if (!x.author) + x.author = User.create({ + id: "4", + discriminator: "0000", + username: "Fosscord Ghost", + public_flags: 0, + }); + x.attachments?.forEach((y: Attachment) => { + // dynamically set attachment proxy_url in case the endpoint changed + const uri = y.proxy_url.startsWith("http") + ? y.proxy_url + : `https://example.org${y.proxy_url}`; + y.proxy_url = `${endpoint == null ? "" : endpoint}${ + new URL(uri).pathname + }`; }); - x.attachments?.forEach((y: Attachment) => { - // dynamically set attachment proxy_url in case the endpoint changed - const uri = y.proxy_url.startsWith("http") - ? y.proxy_url - : `https://example.org${y.proxy_url}`; - y.proxy_url = `${endpoint == null ? "" : endpoint}${ - new URL(uri).pathname - }`; - }); - /** + /** Some clients ( discord.js ) only check if a property exists within the response, which causes errors when, say, the `application` property is `null`. **/ - // for (var curr in x) { - // if (x[curr] === null) - // delete x[curr]; - // } + // for (var curr in x) { + // if (x[curr] === null) + // delete x[curr]; + // } - return x; - }), - ); -}); + return x; + }), + ); + }, +); // TODO: config max upload size const messageUpload = multer({ @@ -208,6 +223,16 @@ router.post( body: "MessageCreateSchema", permission: "SEND_MESSAGES", right: "SEND_MESSAGES", + responses: { + 200: { + body: "Message", + }, + 400: { + body: "APIErrorResponse", + }, + 403: {}, + 404: {}, + }, }), async (req: Request, res: Response) => { const { channel_id } = req.params; diff --git a/src/api/routes/channels/#channel_id/permissions.ts b/src/api/routes/channels/#channel_id/permissions.ts index 68dbc2f2..c6a9def6 100644 --- a/src/api/routes/channels/#channel_id/permissions.ts +++ b/src/api/routes/channels/#channel_id/permissions.ts @@ -19,13 +19,13 @@ import { Channel, ChannelPermissionOverwrite, + ChannelPermissionOverwriteSchema, ChannelUpdateEvent, emitEvent, Member, Role, - ChannelPermissionOverwriteSchema, } from "@spacebar/util"; -import { Router, Response, Request } from "express"; +import { Request, Response, Router } from "express"; import { HTTPError } from "lambert-server"; import { route } from "@spacebar/api"; @@ -38,6 +38,12 @@ router.put( route({ body: "ChannelPermissionOverwriteSchema", permission: "MANAGE_ROLES", + responses: { + 204: {}, + 404: {}, + 501: {}, + 400: { body: "APIErrorResponse" }, + }, }), async (req: Request, res: Response) => { const { channel_id, overwrite_id } = req.params; @@ -92,7 +98,7 @@ router.put( // TODO: check permission hierarchy router.delete( "/:overwrite_id", - route({ permission: "MANAGE_ROLES" }), + route({ permission: "MANAGE_ROLES", responses: { 204: {}, 404: {} } }), async (req: Request, res: Response) => { const { channel_id, overwrite_id } = req.params; diff --git a/src/api/routes/channels/#channel_id/pins.ts b/src/api/routes/channels/#channel_id/pins.ts index 32820916..7b379c30 100644 --- a/src/api/routes/channels/#channel_id/pins.ts +++ b/src/api/routes/channels/#channel_id/pins.ts @@ -16,23 +16,33 @@ along with this program. If not, see . */ +import { route } from "@spacebar/api"; import { Channel, ChannelPinsUpdateEvent, Config, + DiscordApiErrors, emitEvent, Message, MessageUpdateEvent, - DiscordApiErrors, } from "@spacebar/util"; -import { Router, Request, Response } from "express"; -import { route } from "@spacebar/api"; +import { Request, Response, Router } from "express"; const router: Router = Router(); router.put( "/:message_id", - route({ permission: "VIEW_CHANNEL" }), + route({ + permission: "VIEW_CHANNEL", + responses: { + 204: {}, + 403: {}, + 404: {}, + 400: { + body: "APIErrorResponse", + }, + }, + }), async (req: Request, res: Response) => { const { channel_id, message_id } = req.params; @@ -74,7 +84,17 @@ router.put( router.delete( "/:message_id", - route({ permission: "VIEW_CHANNEL" }), + route({ + permission: "VIEW_CHANNEL", + responses: { + 204: {}, + 403: {}, + 404: {}, + 400: { + body: "APIErrorResponse", + }, + }, + }), async (req: Request, res: Response) => { const { channel_id, message_id } = req.params; @@ -114,7 +134,17 @@ router.delete( router.get( "/", - route({ permission: ["READ_MESSAGE_HISTORY"] }), + route({ + permission: ["READ_MESSAGE_HISTORY"], + responses: { + 200: { + body: "ChannelPinsResponse", + }, + 400: { + body: "APIErrorResponse", + }, + }, + }), async (req: Request, res: Response) => { const { channel_id } = req.params; diff --git a/src/api/routes/channels/#channel_id/purge.ts b/src/api/routes/channels/#channel_id/purge.ts index c8da6760..cbd46bd0 100644 --- a/src/api/routes/channels/#channel_id/purge.ts +++ b/src/api/routes/channels/#channel_id/purge.ts @@ -16,20 +16,20 @@ along with this program. If not, see . */ -import { HTTPError } from "lambert-server"; import { route } from "@spacebar/api"; -import { isTextChannel } from "./messages"; -import { FindManyOptions, Between, Not, FindOperator } from "typeorm"; import { Channel, - emitEvent, - getPermission, - getRights, Message, MessageDeleteBulkEvent, PurgeSchema, + emitEvent, + getPermission, + getRights, } from "@spacebar/util"; -import { Router, Response, Request } from "express"; +import { Request, Response, Router } from "express"; +import { HTTPError } from "lambert-server"; +import { Between, FindManyOptions, FindOperator, Not } from "typeorm"; +import { isTextChannel } from "./messages"; const router: Router = Router(); @@ -42,6 +42,14 @@ router.post( "/", route({ /*body: "PurgeSchema",*/ + responses: { + 204: {}, + 400: { + body: "APIErrorResponse", + }, + 404: {}, + 403: {}, + }, }), async (req: Request, res: Response) => { const { channel_id } = req.params; diff --git a/src/api/routes/channels/#channel_id/recipients.ts b/src/api/routes/channels/#channel_id/recipients.ts index f1fb48af..569bb5cd 100644 --- a/src/api/routes/channels/#channel_id/recipients.ts +++ b/src/api/routes/channels/#channel_id/recipients.ts @@ -16,7 +16,7 @@ along with this program. If not, see . */ -import { Request, Response, Router } from "express"; +import { route } from "@spacebar/api"; import { Channel, ChannelRecipientAddEvent, @@ -28,80 +28,98 @@ import { Recipient, User, } from "@spacebar/util"; -import { route } from "@spacebar/api"; +import { Request, Response, Router } from "express"; const router: Router = Router(); -router.put("/:user_id", route({}), async (req: Request, res: Response) => { - const { channel_id, user_id } = req.params; - const channel = await Channel.findOneOrFail({ - where: { id: channel_id }, - relations: ["recipients"], - }); +router.put( + "/:user_id", + route({ + responses: { + 201: {}, + 404: {}, + }, + }), + async (req: Request, res: Response) => { + const { channel_id, user_id } = req.params; + const channel = await Channel.findOneOrFail({ + where: { id: channel_id }, + relations: ["recipients"], + }); - if (channel.type !== ChannelType.GROUP_DM) { - const recipients = [ - ...(channel.recipients?.map((r) => r.user_id) || []), - user_id, - ].unique(); + if (channel.type !== ChannelType.GROUP_DM) { + const recipients = [ + ...(channel.recipients?.map((r) => r.user_id) || []), + user_id, + ].unique(); - const new_channel = await Channel.createDMChannel( - recipients, - req.user_id, - ); - return res.status(201).json(new_channel); - } else { - if (channel.recipients?.map((r) => r.user_id).includes(user_id)) { + const new_channel = await Channel.createDMChannel( + recipients, + req.user_id, + ); + return res.status(201).json(new_channel); + } else { + if (channel.recipients?.map((r) => r.user_id).includes(user_id)) { + throw DiscordApiErrors.INVALID_RECIPIENT; //TODO is this the right error? + } + + channel.recipients?.push( + Recipient.create({ channel_id: channel_id, user_id: user_id }), + ); + await channel.save(); + + await emitEvent({ + event: "CHANNEL_CREATE", + data: await DmChannelDTO.from(channel, [user_id]), + user_id: user_id, + }); + + await emitEvent({ + event: "CHANNEL_RECIPIENT_ADD", + data: { + channel_id: channel_id, + user: await User.findOneOrFail({ + where: { id: user_id }, + select: PublicUserProjection, + }), + }, + channel_id: channel_id, + } as ChannelRecipientAddEvent); + return res.sendStatus(204); + } + }, +); + +router.delete( + "/:user_id", + route({ + responses: { + 204: {}, + 404: {}, + }, + }), + async (req: Request, res: Response) => { + const { channel_id, user_id } = req.params; + const channel = await Channel.findOneOrFail({ + where: { id: channel_id }, + relations: ["recipients"], + }); + if ( + !( + channel.type === ChannelType.GROUP_DM && + (channel.owner_id === req.user_id || user_id === req.user_id) + ) + ) + throw DiscordApiErrors.MISSING_PERMISSIONS; + + if (!channel.recipients?.map((r) => r.user_id).includes(user_id)) { throw DiscordApiErrors.INVALID_RECIPIENT; //TODO is this the right error? } - channel.recipients?.push( - Recipient.create({ channel_id: channel_id, user_id: user_id }), - ); - await channel.save(); + await Channel.removeRecipientFromChannel(channel, user_id); - await emitEvent({ - event: "CHANNEL_CREATE", - data: await DmChannelDTO.from(channel, [user_id]), - user_id: user_id, - }); - - await emitEvent({ - event: "CHANNEL_RECIPIENT_ADD", - data: { - channel_id: channel_id, - user: await User.findOneOrFail({ - where: { id: user_id }, - select: PublicUserProjection, - }), - }, - channel_id: channel_id, - } as ChannelRecipientAddEvent); return res.sendStatus(204); - } -}); - -router.delete("/:user_id", route({}), async (req: Request, res: Response) => { - const { channel_id, user_id } = req.params; - const channel = await Channel.findOneOrFail({ - where: { id: channel_id }, - relations: ["recipients"], - }); - if ( - !( - channel.type === ChannelType.GROUP_DM && - (channel.owner_id === req.user_id || user_id === req.user_id) - ) - ) - throw DiscordApiErrors.MISSING_PERMISSIONS; - - if (!channel.recipients?.map((r) => r.user_id).includes(user_id)) { - throw DiscordApiErrors.INVALID_RECIPIENT; //TODO is this the right error? - } - - await Channel.removeRecipientFromChannel(channel, user_id); - - return res.sendStatus(204); -}); + }, +); export default router; diff --git a/src/api/routes/channels/#channel_id/typing.ts b/src/api/routes/channels/#channel_id/typing.ts index 6a2fef39..b5d61d74 100644 --- a/src/api/routes/channels/#channel_id/typing.ts +++ b/src/api/routes/channels/#channel_id/typing.ts @@ -16,15 +16,22 @@ along with this program. If not, see . */ -import { Channel, emitEvent, Member, TypingStartEvent } from "@spacebar/util"; import { route } from "@spacebar/api"; -import { Router, Request, Response } from "express"; +import { Channel, emitEvent, Member, TypingStartEvent } from "@spacebar/util"; +import { Request, Response, Router } from "express"; const router: Router = Router(); router.post( "/", - route({ permission: "SEND_MESSAGES" }), + route({ + permission: "SEND_MESSAGES", + responses: { + 204: {}, + 404: {}, + 403: {}, + }, + }), async (req: Request, res: Response) => { const { channel_id } = req.params; const user_id = req.user_id; diff --git a/src/api/routes/channels/#channel_id/webhooks.ts b/src/api/routes/channels/#channel_id/webhooks.ts index 14791a1c..4e98a1c9 100644 --- a/src/api/routes/channels/#channel_id/webhooks.ts +++ b/src/api/routes/channels/#channel_id/webhooks.ts @@ -16,34 +16,56 @@ along with this program. If not, see . */ -import { Router, Response, Request } from "express"; import { route } from "@spacebar/api"; import { Channel, Config, - handleFile, - trimSpecial, + DiscordApiErrors, User, Webhook, WebhookCreateSchema, WebhookType, + handleFile, + trimSpecial, } from "@spacebar/util"; +import crypto from "crypto"; +import { Request, Response, Router } from "express"; import { HTTPError } from "lambert-server"; import { isTextChannel } from "./messages/index"; -import { DiscordApiErrors } from "@spacebar/util"; -import crypto from "crypto"; const router: Router = Router(); //TODO: implement webhooks -router.get("/", route({}), async (req: Request, res: Response) => { - res.json([]); -}); +router.get( + "/", + route({ + responses: { + 200: { + body: "ChannelWebhooksResponse", + }, + }, + }), + async (req: Request, res: Response) => { + res.json([]); + }, +); // TODO: use Image Data Type for avatar instead of String router.post( "/", - route({ body: "WebhookCreateSchema", permission: "MANAGE_WEBHOOKS" }), + route({ + body: "WebhookCreateSchema", + permission: "MANAGE_WEBHOOKS", + responses: { + 200: { + body: "WebhookCreateResponse", + }, + 400: { + body: "APIErrorResponse", + }, + 403: {}, + }, + }), async (req: Request, res: Response) => { const channel_id = req.params.channel_id; const channel = await Channel.findOneOrFail({ diff --git a/src/util/schemas/responses/ChannelInvitesResponse.ts b/src/util/schemas/responses/ChannelInvitesResponse.ts new file mode 100644 index 00000000..c50d033c --- /dev/null +++ b/src/util/schemas/responses/ChannelInvitesResponse.ts @@ -0,0 +1,3 @@ +import { Invite } from "../../entities"; + +export type ChannelInvitesResponse = Invite[]; diff --git a/src/util/schemas/responses/ChannelMessagesResponse.ts b/src/util/schemas/responses/ChannelMessagesResponse.ts new file mode 100644 index 00000000..65b7dab5 --- /dev/null +++ b/src/util/schemas/responses/ChannelMessagesResponse.ts @@ -0,0 +1,3 @@ +import { Message } from "../../entities"; + +export type ChannelMessagesResponse = Message[]; diff --git a/src/util/schemas/responses/ChannelPinsResponse.ts b/src/util/schemas/responses/ChannelPinsResponse.ts new file mode 100644 index 00000000..7a1b8d43 --- /dev/null +++ b/src/util/schemas/responses/ChannelPinsResponse.ts @@ -0,0 +1,3 @@ +import { Message } from "../../entities"; + +export type ChannelPinsResponse = Message[]; diff --git a/src/util/schemas/responses/ChannelWebhooksResponse.ts b/src/util/schemas/responses/ChannelWebhooksResponse.ts new file mode 100644 index 00000000..84f49dce --- /dev/null +++ b/src/util/schemas/responses/ChannelWebhooksResponse.ts @@ -0,0 +1,3 @@ +import { Webhook } from "../../entities"; + +export type ChannelWebhooksResponse = Webhook[]; diff --git a/src/util/schemas/responses/WebhookCreateResponse.ts b/src/util/schemas/responses/WebhookCreateResponse.ts new file mode 100644 index 00000000..ae142632 --- /dev/null +++ b/src/util/schemas/responses/WebhookCreateResponse.ts @@ -0,0 +1,6 @@ +import { User, Webhook } from "../../entities"; + +export interface WebhookCreateResponse { + user: User; + hook: Webhook; +} diff --git a/src/util/schemas/responses/index.ts b/src/util/schemas/responses/index.ts index 6dde4d24..2a1180ad 100644 --- a/src/util/schemas/responses/index.ts +++ b/src/util/schemas/responses/index.ts @@ -6,6 +6,10 @@ export * from "./ApplicationSkusResponse"; export * from "./ApplicationsResponse"; export * from "./BackupCodesChallengeResponse"; export * from "./CaptchaRequiredResponse"; +export * from "./ChannelInvitesResponse"; +export * from "./ChannelPinsResponse"; +export * from "./ChannelWebhooksResponse"; export * from "./GenerateRegistrationTokensResponse"; export * from "./LocationMetadataResponse"; export * from "./TokenResponse"; +export * from "./WebhookCreateResponse";