summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Server.ts2
-rw-r--r--src/routes/attachments.ts42
-rw-r--r--src/routes/external.ts1
-rw-r--r--src/util/FileStorage.ts23
-rw-r--r--src/util/Storage.ts5
5 files changed, 49 insertions, 24 deletions
diff --git a/src/Server.ts b/src/Server.ts

index 3ad794be..de02a585 100644 --- a/src/Server.ts +++ b/src/Server.ts
@@ -18,7 +18,7 @@ export class CDNServer extends Server { await Config.init(); console.log("[Database] connected"); - await this.registerRoutes(path.join(__dirname, "routes")); + await this.registerRoutes(path.join(__dirname, "routes/")); return super.start(); } diff --git a/src/routes/attachments.ts b/src/routes/attachments.ts
index 730d2bb1..f477d1b2 100644 --- a/src/routes/attachments.ts +++ b/src/routes/attachments.ts
@@ -2,6 +2,8 @@ import { Router } from "express"; import multer from "multer"; import { Config, Snowflake } from "@fosscord/server-util"; import { storage } from "../util/Storage"; +import FileType from "file-type"; +import { HTTPError } from "lambert-server"; const multer_ = multer({ storage: multer.memoryStorage(), @@ -13,42 +15,46 @@ const multer_ = multer({ }); const router = Router(); -router.post("/:channel_id", multer_.single("attachment"), async (req, res) => { - const { buffer, mimetype, stream, size, originalname, fieldname } = req.file; +router.post("/:channel_id", multer_.single("file"), async (req, res) => { + const { buffer, mimetype, size, originalname, fieldname } = req.file; const { channel_id } = req.params; - const filename = originalname.replaceAll(" ", "_").replace(/\W+/g, ""); - - const endpoint = Config.get().cdn.endpoint || "http://localhost:3003"; + const filename = originalname.replaceAll(" ", "_").replace(/[^a-zA-Z0-9._]+/g, ""); + const id = Snowflake.generate(); + const path = `attachments/${channel_id}/${id}/${filename}`; - await storage.set(originalname, buffer); + const endpoint = Config.get().cdn.endpoint || "http://localhost:3003"; - const id = Snowflake.generate(); + await storage.set(path, buffer); const file = { id, - type: mimetype, content_type: mimetype, - filename: originalname, + filename: filename, size, - url: `${endpoint}/attachments/${channel_id}/${id}/`, + url: `${endpoint}/attachments/${channel_id}/${id}/${filename}`, }; return res.json(file); }); -router.get("/:hash/:filename", async (req, res) => { - const { hash, filename } = req.params; +router.get("/:channel_id/:id/:filename", async (req, res) => { + const { channel_id, id, filename } = req.params; + + const file = await storage.get(`attachments/${channel_id}/${id}/${filename}`); + if (!file) throw new HTTPError("File not found"); + const result = await FileType.fromBuffer(file); - const File = await db.data.attachments({ id: hash, filename: filename }).get(); + res.set("Content-Type", result?.mime); - res.set("Content-Type", File.type); - return res.send(Buffer.from(File.file, "base64")); + return res.send(file); }); -router.delete("/:hash/:filename", async (req, res) => { - const { hash, filename } = req.params; +router.delete("/:channel_id/:id/:filename", async (req, res) => { + const { channel_id, id, filename } = req.params; + const path = `attachments/${channel_id}/${id}/${filename}`; + + storage.delete(path); - await db.data.attachments({ id: hash, filename: filename }).delete(); return res.send({ success: true, message: "attachment deleted" }); }); diff --git a/src/routes/external.ts b/src/routes/external.ts
index 045eb7da..3bcb39b0 100644 --- a/src/routes/external.ts +++ b/src/routes/external.ts
@@ -1,3 +1,4 @@ +// @ts-nocheck import bodyParser from "body-parser"; import { Router } from "express"; import fetch from "node-fetch"; diff --git a/src/util/FileStorage.ts b/src/util/FileStorage.ts
index b4d00213..9c9911f3 100644 --- a/src/util/FileStorage.ts +++ b/src/util/FileStorage.ts
@@ -1,13 +1,30 @@ import { Storage } from "./Storage"; import fs from "fs/promises"; import { join } from "path"; +import "missing-native-js-functions"; export class FileStorage implements Storage { - async get(path: string) { - return fs.readFile(join(process.env.STORAGE_LOCATION || "", path), { encoding: "binary" }); + async get(path: string): Promise<Buffer | null> { + path = join(process.env.STORAGE_LOCATION || "", path); + try { + const file = await fs.readFile(path); + // @ts-ignore + return file; + } catch (error) { + return null; + } } async set(path: string, value: any) { - return fs.writeFile(join(process.env.STORAGE_LOCATION || "", path), value, { encoding: "binary" }); + path = join(process.env.STORAGE_LOCATION || "", path); + const dir = path.split("/").slice(0, -1).join("/"); + await fs.mkdir(dir, { recursive: true }).caught(); + + return fs.writeFile(path, value, { encoding: "binary" }); + } + + async delete(path: string) { + path = join(process.env.STORAGE_LOCATION || "", path); + await fs.unlink(path); } } diff --git a/src/util/Storage.ts b/src/util/Storage.ts
index 391afa83..f8b09e71 100644 --- a/src/util/Storage.ts +++ b/src/util/Storage.ts
@@ -1,8 +1,9 @@ import { FileStorage } from "./FileStorage"; export interface Storage { - set(path: string, data: any): Promise<void>; - get(path: string): Promise<any>; + set(path: string, data: Buffer): Promise<void>; + get(path: string): Promise<Buffer | null>; + delete(path: string): Promise<void>; } var storage: Storage;