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;
|