Files

93 lines
2.2 KiB
JavaScript
Raw Permalink Normal View History

2025-09-02 21:43:00 +10:00
import bodyParser from "body-parser";
import compression from "compression";
import express from "express";
import fileUpload from "express-fileupload";
import { isDebugMode } from "./lib/config.js";
import cors from "./lib/express/cors.js";
import jwt from "./lib/express/jwt.js";
2025-11-04 13:43:52 +10:00
import { debug, express as logger } from "./logger.js";
2025-09-02 21:43:00 +10:00
import mainRoutes from "./routes/main.js";
2020-02-19 15:55:06 +11:00
/**
* App
*/
const app = express();
app.use(fileUpload());
app.use(bodyParser.json());
2025-09-02 21:43:00 +10:00
app.use(bodyParser.urlencoded({ extended: true }));
2020-02-19 15:55:06 +11:00
// Gzip
app.use(compression());
/**
* General Logging, BEFORE routes
*/
2025-09-02 21:43:00 +10:00
app.disable("x-powered-by");
app.enable("trust proxy", ["loopback", "linklocal", "uniquelocal"]);
app.enable("strict routing");
2020-02-19 15:55:06 +11:00
// pretty print JSON when not live
2025-09-02 21:43:00 +10:00
if (isDebugMode()) {
app.set("json spaces", 2);
2020-02-19 15:55:06 +11:00
}
// CORS for everything
2025-09-02 21:43:00 +10:00
app.use(cors);
2020-02-19 15:55:06 +11:00
// General security/cache related headers + server header
2025-09-02 21:43:00 +10:00
app.use((_, res, next) => {
let x_frame_options = "DENY";
2020-02-19 15:55:06 +11:00
2025-09-02 21:43:00 +10:00
if (typeof process.env.X_FRAME_OPTIONS !== "undefined" && process.env.X_FRAME_OPTIONS) {
2020-02-19 15:55:06 +11:00
x_frame_options = process.env.X_FRAME_OPTIONS;
}
res.set({
2025-09-02 21:43:00 +10:00
"X-XSS-Protection": "1; mode=block",
"X-Content-Type-Options": "nosniff",
"X-Frame-Options": x_frame_options,
"Cache-Control": "no-cache, no-store, max-age=0, must-revalidate",
Pragma: "no-cache",
Expires: 0,
2020-02-19 15:55:06 +11:00
});
next();
});
2025-09-02 21:43:00 +10:00
app.use(jwt());
app.use("/", mainRoutes);
2020-02-19 15:55:06 +11:00
// production error handler
// no stacktraces leaked to user
2025-09-02 21:43:00 +10:00
app.use((err, req, res, _) => {
const payload = {
2020-02-19 15:55:06 +11:00
error: {
code: err.status || 500,
2025-09-02 21:43:00 +10:00
message: err.public ? err.message : "Internal Error",
},
2020-02-19 15:55:06 +11:00
};
2025-09-02 21:43:00 +10:00
if (typeof err.message_i18n !== "undefined") {
payload.error.message_i18n = err.message_i18n;
}
if (isDebugMode() || (req.baseUrl + req.path).includes("nginx/certificates")) {
2020-02-19 15:55:06 +11:00
payload.debug = {
2025-09-02 21:43:00 +10:00
stack: typeof err.stack !== "undefined" && err.stack ? err.stack.split("\n") : null,
previous: err.previous,
2020-02-19 15:55:06 +11:00
};
}
// Not every error is worth logging - but this is good for now until it gets annoying.
2025-09-02 21:43:00 +10:00
if (typeof err.stack !== "undefined" && err.stack) {
2025-11-04 13:43:52 +10:00
debug(logger, err.stack);
2025-09-02 21:43:00 +10:00
if (typeof err.public === "undefined" || !err.public) {
logger.warn(err.message);
2020-02-19 15:55:06 +11:00
}
}
2025-09-02 21:43:00 +10:00
res.status(err.status || 500).send(payload);
2020-02-19 15:55:06 +11:00
});
2025-09-02 21:43:00 +10:00
export default app;