140 lines
No EOL
4.1 KiB
TypeScript
140 lines
No EOL
4.1 KiB
TypeScript
import Fastify from "fastify";
|
|
import FastifyFormBody from "@fastify/formbody";
|
|
import FastifyMultipart from "@fastify/multipart";
|
|
import FastifyCookie from "@fastify/cookie";
|
|
import FastifyView from "@fastify/view";
|
|
import FastifyStatic from "@fastify/static";
|
|
import Config from "./objects/Config";
|
|
import EJS from "ejs";
|
|
import { Console } from "hsconsole";
|
|
import Controller from "./controllers/Controller";
|
|
import HomeController from "./controllers/HomeController";
|
|
import Database from "./objects/Database";
|
|
import { join } from "path";
|
|
import AccountController from "./controllers/AccountController";
|
|
import { magenta, blue, cyan, green, red } from "dyetty";
|
|
import ConsoleUtility from "./utilities/ConsoleUtility";
|
|
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";
|
|
import { createReadStream } from "fs";
|
|
|
|
Console.customHeader(`EUS server started at ${new Date()}`);
|
|
|
|
const fastify = Fastify({
|
|
logger: false
|
|
});
|
|
|
|
fastify.register(FastifyView, {
|
|
engine: {
|
|
ejs: EJS
|
|
}
|
|
});
|
|
|
|
fastify.register(FastifyFormBody);
|
|
|
|
fastify.register(FastifyMultipart);
|
|
|
|
fastify.register(FastifyCookie, {
|
|
secret: Config.session.secret,
|
|
parseOptions: {
|
|
path: "/",
|
|
secure: true
|
|
}
|
|
});
|
|
|
|
fastify.register(FastifyStatic, {
|
|
root: join(__dirname, "wwwroot"),
|
|
preCompressed: true,
|
|
decorateReply: false,
|
|
redirect: false
|
|
});
|
|
|
|
const hashLookupCache = new FunkyArray<string, Media>();
|
|
fastify.addHook("preHandler", (req, res, done) => {
|
|
(async () => {
|
|
// @ts-ignore
|
|
req.startTime = Date.now();
|
|
|
|
// * Take usual controller path if this path is registered.
|
|
if (Controller.RegisteredPaths.includes(req.url)) {
|
|
// @ts-ignore
|
|
req.logType = cyan("CONTROLLER");
|
|
HeaderUtility.AddBakedHeaders(res);
|
|
return done();
|
|
} else {
|
|
const urlParts = req.url.split("/");
|
|
if (urlParts.length === 2 && urlParts[1].length === 16) {
|
|
let media = hashLookupCache.get(urlParts[1]) ?? null;
|
|
if (!media) {
|
|
media = await MediaService.GetByTag(urlParts[1]);
|
|
if (media) {
|
|
hashLookupCache.set(urlParts[1], media);
|
|
}
|
|
}
|
|
|
|
if (media) {
|
|
// @ts-ignore
|
|
req.logType = cyan("IMAGE");
|
|
const fileStore = HashFS.GetHashFSInstance("images");
|
|
const readStream = createReadStream(join(fileStore.path, fileStore.GetRelativePath(media.Hash)));
|
|
res.raw.writeHead(200, HeaderUtility.CombineHeaders({
|
|
"content-type": media.MediaType,
|
|
"content-length": media.FileSize,
|
|
}));
|
|
readStream.pipe(res.raw);
|
|
return;
|
|
}
|
|
} else {
|
|
HeaderUtility.AddBakedHeaders(res);
|
|
}
|
|
|
|
// @ts-ignore
|
|
req.logType = magenta("STATIC");
|
|
}
|
|
|
|
return done();
|
|
})();
|
|
});
|
|
|
|
fastify.addHook("onSend", (req, res, _payload, done) => {
|
|
// @ts-ignore
|
|
Console.printInfo(`[ ${req.logType} ] [ ${req.method.toUpperCase()} ] [ ${ConsoleUtility.StatusColor(res.statusCode)} ] [ ${blue(`${Date.now() - req.startTime}ms`)} ] > ${req.url}`);
|
|
|
|
//console.log(res.getHeaders());
|
|
|
|
done();
|
|
});
|
|
|
|
fastify.setNotFoundHandler(async (_req, res) => {
|
|
|
|
return res.status(404).view("views/404.ejs");
|
|
});
|
|
|
|
HashFS.STARTUP_DIR = __dirname;
|
|
new HashFS("images");
|
|
|
|
if (Config.database.enabled) {
|
|
new Database(Config.database.address, Config.database.port, Config.database.username, Config.database.password, Config.database.name);
|
|
} else {
|
|
Console.printInfo(`[ ${red("DATABASE")} ] Database is disabled.`);
|
|
}
|
|
|
|
if (Config.controllers.enabled && Config.database.enabled) {
|
|
Controller.FastifyInstance = fastify;
|
|
new AccountController();
|
|
new HomeController();
|
|
} else {
|
|
Console.printInfo(`[ ${red("CONTROLLER")} ] Controllers are disabled${Config.controllers.enabled && !Config.database.enabled ? " because the database is disabled but required by the controllers." : "."} Server will operate in static mode only.`);
|
|
}
|
|
|
|
fastify.listen({ port: Config.hosts.webPort, host: Config.hosts.webHost }, (err, address) => {
|
|
if (err) {
|
|
Console.printError(`Error occured while spinning up fastify:\n${err}`);
|
|
process.exit(1);
|
|
}
|
|
|
|
Console.printInfo(`[ ${green("MAIN")} ] Listening at ${address.replace("0.0.0.0", "localhost").replace("127.0.0.1", "localhost")}`);
|
|
}); |