aboutsummaryrefslogtreecommitdiffstats
path: root/lib/app.ts
diff options
context:
space:
mode:
Diffstat (limited to 'lib/app.ts')
-rw-r--r--lib/app.ts66
1 files changed, 66 insertions, 0 deletions
diff --git a/lib/app.ts b/lib/app.ts
new file mode 100644
index 00000000..03ed3bb0
--- /dev/null
+++ b/lib/app.ts
@@ -0,0 +1,66 @@
+import config from "$config";
+import fastify from "fastify";
+import fastifyMultipart from "@fastify/multipart";
+import fastifyStatic from "@fastify/static";
+import fastifyPassport from "@fastify/passport";
+import fastifySecureSession from "@fastify/secure-session";
+import cors from "@fastify/cors";
+
+import path from "path";
+import pino from "pino";
+
+import { jwtStrategy } from "$lib/auth";
+
+const app = fastify({
+ logger: pino(),
+ disableRequestLogging: true,
+ maxParamLength: 500,
+});
+
+await app.register(import("@fastify/rate-limit"), {
+ allowList: (req, key) => req.raw.url.includes("public"),
+ max: 100,
+ timeWindow: 2000,
+ keyGenerator: (req) => req.headers["cf-connecting-ip"],
+ errorResponseBuilder: (req, context) => {
+ return {
+ statusCode: 429,
+ error: "Too Many Requests",
+ message: "Rate limit exceeded, retry in 2 seconds",
+ };
+ },
+});
+
+app.register(fastifySecureSession, {
+ key: Buffer.from(config.jwt, "hex"),
+});
+
+app.register(fastifyPassport.initialize());
+app.register(fastifyPassport.secureSession());
+
+fastifyPassport.use("jwt", jwtStrategy);
+
+app.register(fastifyMultipart, { limits: { fileSize: 10 ** 7 } });
+
+app.register(fastifyStatic, {
+ root: path.join("/home/bun/app/data/uploads"),
+ prefix: "/public/",
+});
+
+await app.register(cors, {
+ origin: true,
+});
+
+app.setErrorHandler((error, request, reply) => {
+ if (error instanceof fastify.errorCodes.FST_ERR_BAD_STATUS_CODE) {
+ reply.status(500).send({ ok: false });
+ } else {
+ reply.send(error);
+ }
+});
+
+app.setNotFoundHandler((request, reply) => {
+ reply.code(404).type("text/html").send("Not Found");
+});
+
+export default app;