diff --git a/bun.lockb b/bun.lockb index 0b029f2..93d7318 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/controllers/Controller.ts b/controllers/Controller.ts index bdb4492..c6d398c 100644 --- a/controllers/Controller.ts +++ b/controllers/Controller.ts @@ -5,6 +5,7 @@ import RequestCtx from "../objects/RequestCtx"; import Session from "../objects/Session"; import SessionUser from "../objects/SessionUser"; import UserType from "../enums/UserType"; +import HeaderUtility from "../utilities/HeaderUtility"; // prepare for ts-ignore :3 // TODO: figure out some runtime field / type checking so @@ -72,15 +73,8 @@ export default abstract class Controller { } } - res.header("X-Powered-By", "MultiProbe"); if (controllerName !== "api") { - res.header("Strict-Transport-Security", "max-age=31536000; includeSubDomains"); - res.header("X-XSS-Protection", "1; mode=block"); - res.header("Permissions-Policy", "microphone=(), geolocation=(), magnetometer=(), camera=(), payment=(), usb=(), accelerometer=(), gyroscope=()"); - res.header("Referrer-Policy", "strict-origin-when-cross-origin"); - res.header("Content-Security-Policy", "block-all-mixed-content;frame-ancestors 'self'"); - res.header("X-Frame-Options", "SAMEORIGIN"); - res.header("X-Content-Type-Options", "nosniff"); + HeaderUtility.AddHeaders(res); } const requestCtx = new RequestCtx(req, res, controllerName, methodName, session); diff --git a/index.ts b/index.ts index ee5ae0c..f222af2 100644 --- a/index.ts +++ b/index.ts @@ -3,6 +3,7 @@ import FastifyFormBody from "@fastify/formbody"; import FastifyMultipart from "@fastify/multipart"; import FastifyCookie from "@fastify/cookie"; import FastifyView from "@fastify/view"; +import FastifySend from "@fastify/send" import FastifyStatic from "@fastify/static"; import Config from "./objects/Config"; import EJS from "ejs"; @@ -18,6 +19,7 @@ import HashFS from "./objects/HashFS"; import FunkyArray from "funky-array"; import MediaService from "./services/MediaService"; import Media from "./entities/Media"; +import HeaderUtility from "./utilities/HeaderUtility"; Console.customHeader(`EUS server started at ${new Date()}`); @@ -45,7 +47,9 @@ fastify.register(FastifyCookie, { fastify.register(FastifyStatic, { root: join(__dirname, "wwwroot"), - preCompressed: true + preCompressed: true, + decorateReply: false, + redirect: false }); const hashLookupCache = new FunkyArray(); @@ -53,6 +57,7 @@ fastify.addHook("preHandler", (req, res, done) => { (async () => { // @ts-ignore req.startTime = Date.now(); + HeaderUtility.AddHeaders(res); // * Take usual controller path if this path is registered. if (Controller.RegisteredPaths.includes(req.url)) { @@ -74,11 +79,18 @@ fastify.addHook("preHandler", (req, res, done) => { // @ts-ignore req.logType = cyan("IMAGE"); const fileStore = HashFS.GetHashFSInstance("images"); - res.header("content-type", media.MediaType); - res.sendFile(fileStore.GetRelativePath(media.Hash), fileStore.path, { contentType: false }); - //return done(); - return; - } + const { statusCode, headers, stream } = await FastifySend(req.raw, join(fileStore.path, fileStore.GetRelativePath(media.Hash)), {}); + headers["Content-Type"] = media.MediaType; + if (statusCode === 200) { + res.headers(headers); + HeaderUtility.AddHeaders(res); + stream.pipe(res.raw); + return; + } + + res.statusCode = statusCode; + return done(); + } } // @ts-ignore diff --git a/package.json b/package.json index e9be00e..30436f8 100644 --- a/package.json +++ b/package.json @@ -12,28 +12,28 @@ "type": "commonjs", "scripts": { "updateCheck": "check-outdated", - "dev:legacy_node": "nodemon --watch './**/*.ts' index.ts", + "dev:legacy_node": "nodemon --watch './**/*.ts' ts-node index.ts", "dev": "bun --watch index.ts", "build": "tsc --build" }, "devDependencies": { - "@types/bun": "^1.1.15", + "@types/bun": "^1.2.0", "@types/ejs": "^3.1.5", "@vercel/ncc": "^0.38.3", "check-outdated": "^2.12.0", "nodemon": "^3.1.9", "ts-node": "^10.9.2", - "typescript": "^5.7.2" + "typescript": "^5.7.3" }, "dependencies": { - "@fastify/cookie": "^11.0.1", - "@fastify/formbody": "^8.0.1", - "@fastify/multipart": "^9.0.1", - "@fastify/static": "^8.0.3", - "@fastify/view": "^10.0.1", + "@fastify/cookie": "^11.0.2", + "@fastify/formbody": "^8.0.2", + "@fastify/multipart": "^9.0.3", + "@fastify/static": "^8.0.4", + "@fastify/view": "^10.0.2", "dyetty": "^1.0.1", "ejs": "^3.1.10", - "fastify": "^5.2.0", + "fastify": "^5.2.1", "funky-array": "^1.0.0", "hsconsole": "^1.1.0", "mysql2": "^3.12.0" diff --git a/utilities/HeaderUtility.ts b/utilities/HeaderUtility.ts new file mode 100644 index 0000000..4851d48 --- /dev/null +++ b/utilities/HeaderUtility.ts @@ -0,0 +1,15 @@ +import type { FastifyReply } from "fastify"; + +export default abstract class HeaderUtility { + public static AddHeaders(res: FastifyReply) { + res.header("x-powered-by", "EUS"); + res.header("rel", "cute"); + res.header("Strict-Transport-Security", "max-age=31536000; includeSubDomains"); + res.header("X-XSS-Protection", "1; mode=block"); + res.header("Permissions-Policy", "microphone=(), geolocation=(), magnetometer=(), camera=(), payment=(), usb=(), accelerometer=(), gyroscope=()"); + res.header("Referrer-Policy", "strict-origin-when-cross-origin"); + res.header("Content-Security-Policy", "block-all-mixed-content;frame-ancestors 'self'"); + res.header("X-Frame-Options", "SAMEORIGIN"); + res.header("X-Content-Type-Options", "nosniff"); + } +} \ No newline at end of file