attachments

This commit is contained in:
Flam3rboy
2021-05-28 21:19:19 +02:00
parent 9352b965d8
commit 614d8f14fa
21 changed files with 54 additions and 559 deletions

View File

@@ -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();
}

View File

@@ -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 filename = originalname.replaceAll(" ", "_").replace(/[^a-zA-Z0-9._]+/g, "");
const id = Snowflake.generate();
const path = `attachments/${channel_id}/${id}/${filename}`;
const endpoint = Config.get().cdn.endpoint || "http://localhost:3003";
await storage.set(originalname, buffer);
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 db.data.attachments({ id: hash, filename: filename }).get();
const file = await storage.get(`attachments/${channel_id}/${id}/${filename}`);
if (!file) throw new HTTPError("File not found");
const result = await FileType.fromBuffer(file);
res.set("Content-Type", File.type);
return res.send(Buffer.from(File.file, "base64"));
res.set("Content-Type", result?.mime);
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" });
});

View File

@@ -1,3 +1,4 @@
// @ts-nocheck
import bodyParser from "body-parser";
import { Router } from "express";
import fetch from "node-fetch";

View File

@@ -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);
}
}

View File

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