diff --git a/bundle/package-lock.json b/bundle/package-lock.json index 4c5e5b77..6e4d70c7 100644 Binary files a/bundle/package-lock.json and b/bundle/package-lock.json differ diff --git a/bundle/package.json b/bundle/package.json index 83186be4..1e6bc5e9 100644 --- a/bundle/package.json +++ b/bundle/package.json @@ -54,7 +54,8 @@ "ts-patch": "^1.4.4", "tsconfig-paths": "^3.12.0", "typescript": "^4.2.3", - "typescript-json-schema": "0.50.1" + "typescript-json-schema": "0.50.1", + "@types/sharp": "^0.30.4" }, "dependencies": { "@aws-sdk/client-s3": "^3.36.1", @@ -110,6 +111,7 @@ "typescript": "^4.1.2", "typescript-cached-transpile": "^0.0.6", "typescript-json-schema": "^0.50.1", - "ws": "^7.4.2" + "ws": "^7.4.2", + "sharp": "^0.30.7" } -} +} \ No newline at end of file diff --git a/cdn/package.json b/cdn/package.json index c63713c0..ca1e6416 100644 --- a/cdn/package.json +++ b/cdn/package.json @@ -31,6 +31,7 @@ "@types/multer": "^1.4.7", "@types/node": "^14.17.0", "@types/node-fetch": "^2.5.7", + "@types/sharp": "^0.30.4", "@zerollup/ts-transform-paths": "^1.7.18", "ts-patch": "^1.4.4" }, @@ -55,6 +56,7 @@ "multer": "^1.4.2", "nanocolors": "^0.2.12", "node-fetch": "^2.6.2", + "sharp": "^0.30.7", "supertest": "^6.1.6", "typescript": "^4.1.2" }, diff --git a/cdn/src/routes/external.ts b/cdn/src/routes/external.ts index dc90e3c8..65b8bcb1 100644 --- a/cdn/src/routes/external.ts +++ b/cdn/src/routes/external.ts @@ -3,8 +3,9 @@ import fetch from "node-fetch"; import { HTTPError } from "lambert-server"; import { Snowflake } from "@fosscord/util"; import { storage } from "../util/Storage"; -import FileType from "file-type"; +import FileType, { stream } from "file-type"; import { Config } from "@fosscord/util"; +import sharp from "sharp"; // TODO: somehow handle the deletion of images posted to the /external route @@ -56,4 +57,39 @@ router.get("/:id", async (req: Request, res: Response) => { return res.send(file); }); +// this method is gross lol don't care +router.get("/resize/:url", async (req: Request, res: Response) => { + const url = decodeURIComponent(req.params.url); + const { width, height } = req.query; + if (!width || !height) throw new HTTPError("Must provide width and height"); + const w = parseInt(width as string); + const h = parseInt(height as string); + if (w < 1 || h < 1) throw new HTTPError("Width and height must be greater than 0"); + + const { resizeHeightMax, resizeWidthMax } = Config.get().cdn; + if (resizeHeightMax && resizeWidthMax && + (w > resizeWidthMax || h > resizeHeightMax)) + throw new HTTPError(`Width and height must not exceed ${resizeWidthMax}, ${resizeHeightMax}`); + + let buffer; + try { + const response = await fetch(url, DEFAULT_FETCH_OPTIONS); + buffer = await response.buffer(); + } + catch (e) { + throw new HTTPError("Couldn't fetch website"); + } + + const resizedBuffer = await sharp(buffer) + .resize(parseInt(width as string), parseInt(height as string), { + fit: "inside", + }) + .png() + .toBuffer(); + + res.setHeader("Content-Disposition", "attachment"); + res.setHeader("Content-Type", "image/png"); + return res.end(resizedBuffer); +}); + export default router; diff --git a/package-lock.json b/package-lock.json index 6bfe9d85..9a887d06 100644 Binary files a/package-lock.json and b/package-lock.json differ diff --git a/util/src/entities/Config.ts b/util/src/entities/Config.ts index 84bd367e..e545e36a 100644 --- a/util/src/entities/Config.ts +++ b/util/src/entities/Config.ts @@ -50,6 +50,8 @@ export interface ConfigValue { endpointClient: string | null; endpointPublic: string | null; endpointPrivate: string | null; + resizeHeightMax: number | null; + resizeWidthMax: number | null; }; api: { defaultVersion: string; @@ -218,6 +220,8 @@ export const DefaultConfigOptions: ConfigValue = { endpointClient: null, endpointPrivate: null, endpointPublic: null, + resizeHeightMax: 1000, + resizeWidthMax: 1000, }, api: { defaultVersion: "9", diff --git a/util/src/entities/Message.ts b/util/src/entities/Message.ts index 013e92a9..e18cf691 100644 --- a/util/src/entities/Message.ts +++ b/util/src/entities/Message.ts @@ -114,7 +114,7 @@ export class Message extends BaseClass { @ManyToOne(() => Application) application?: Application; - @Column({ nullable: true, type: "longtext" }) + @Column({ nullable: true }) content?: string; @Column()