From 072be4383ffcdf528481cdc4b0512062ff7c1e12 Mon Sep 17 00:00:00 2001 From: AlTech98 Date: Mon, 13 Sep 2021 17:31:07 +0200 Subject: [PATCH 1/2] Fix attachments not being saved to db --- util/src/entities/Message.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/src/entities/Message.ts b/util/src/entities/Message.ts index f4c7fdc7..506db71a 100644 --- a/util/src/entities/Message.ts +++ b/util/src/entities/Message.ts @@ -128,7 +128,7 @@ export class Message extends BaseClass { sticker_items?: Sticker[]; @JoinColumn({ name: "attachment_ids" }) - @OneToMany(() => Attachment, (attachment: Attachment) => attachment.message) + @OneToMany(() => Attachment, (attachment: Attachment) => attachment.message, { cascade: true }) attachments?: Attachment[]; @Column({ type: "simple-json" }) From b438a21b9c252ace62f9ce803bae939cbc1677e3 Mon Sep 17 00:00:00 2001 From: AlTech98 Date: Mon, 13 Sep 2021 17:32:31 +0200 Subject: [PATCH 2/2] Delete attachments of deleted messages, fix #273 --- api/assets/schemas.json | 6 +++++- .../#channel_id/messages/#message_id/index.ts | 7 ++++--- .../routes/channels/#channel_id/messages/index.ts | 1 + api/src/util/Attachments.ts | 12 ++++++++++++ api/src/util/cdn.ts | 13 +++++++++++++ cdn/src/util/FileStorage.ts | 1 + 6 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 api/src/util/Attachments.ts diff --git a/api/assets/schemas.json b/api/assets/schemas.json index ac7df859..94aa0660 100644 --- a/api/assets/schemas.json +++ b/api/assets/schemas.json @@ -462,7 +462,11 @@ "payload_json": { "type": "string" }, - "file": {} + "file": {}, + "attachments": { + "type": "array", + "items": {} + } }, "additionalProperties": false, "definitions": { diff --git a/api/src/routes/channels/#channel_id/messages/#message_id/index.ts b/api/src/routes/channels/#channel_id/messages/#message_id/index.ts index d0f780db..b5220fab 100644 --- a/api/src/routes/channels/#channel_id/messages/#message_id/index.ts +++ b/api/src/routes/channels/#channel_id/messages/#message_id/index.ts @@ -3,6 +3,7 @@ import { Router, Response, Request } from "express"; import { route } from "@fosscord/api"; import { handleMessage, postHandleMessage } from "@fosscord/api"; import { MessageCreateSchema } from "../index"; +import { deleteMessageAttachments } from "@fosscord/api/util/Attachments"; const router = Router(); // TODO: message content/embed string length limit @@ -11,7 +12,7 @@ router.patch("/", route({ body: "MessageCreateSchema", permission: "SEND_MESSAGE const { message_id, channel_id } = req.params; var body = req.body as MessageCreateSchema; - const message = await Message.findOneOrFail({ id: message_id, channel_id }); + const message = await Message.findOneOrFail({ where: { id: message_id, channel_id }, relations: ["attachments"] }); const permissions = await getPermission(req.user_id, undefined, channel_id); @@ -33,6 +34,7 @@ router.patch("/", route({ body: "MessageCreateSchema", permission: "SEND_MESSAGE }); await Promise.all([ + await deleteMessageAttachments(message_id, new_message.attachments), //This delete all the attachments not in the array new_message!.save(), await emitEvent({ event: "MESSAGE_UPDATE", @@ -46,8 +48,6 @@ router.patch("/", route({ body: "MessageCreateSchema", permission: "SEND_MESSAGE return res.json(message); }); -// TODO: delete attachments in message - // permission check only if deletes messagr from other user router.delete("/", route({}), async (req: Request, res: Response) => { const { message_id, channel_id } = req.params; @@ -60,6 +60,7 @@ router.delete("/", route({}), async (req: Request, res: Response) => { permission.hasThrow("MANAGE_MESSAGES"); } + await deleteMessageAttachments(message_id); await Message.delete({ id: message_id }); await emitEvent({ diff --git a/api/src/routes/channels/#channel_id/messages/index.ts b/api/src/routes/channels/#channel_id/messages/index.ts index 11334367..25ecc1c7 100644 --- a/api/src/routes/channels/#channel_id/messages/index.ts +++ b/api/src/routes/channels/#channel_id/messages/index.ts @@ -51,6 +51,7 @@ export interface MessageCreateSchema { }; payload_json?: string; file?: any; + attachments?: any[]; //TODO we should create an interface for attachments } // https://discord.com/developers/docs/resources/channel#create-message diff --git a/api/src/util/Attachments.ts b/api/src/util/Attachments.ts new file mode 100644 index 00000000..addda97f --- /dev/null +++ b/api/src/util/Attachments.ts @@ -0,0 +1,12 @@ +import { Attachment } from "@fosscord/util"; +import { deleteFile } from "@fosscord/api"; +import { URL } from "url"; + +export async function deleteMessageAttachments(messageId: string, keep?: Attachment[]) { + let attachments = await Attachment.find({ message_id: messageId }); + if (keep) + attachments = attachments.filter(x => !keep.map(k => k.id).includes(x.id)); + await Promise.all(attachments.map(a => a.remove())); + + attachments.forEach(a => deleteFile((new URL(a.url)).pathname)); //We don't need to await since this is done on the cdn +} diff --git a/api/src/util/cdn.ts b/api/src/util/cdn.ts index 3c71d980..88b0ea0d 100644 --- a/api/src/util/cdn.ts +++ b/api/src/util/cdn.ts @@ -38,3 +38,16 @@ export async function handleFile(path: string, body?: string): Promise