-
Dominik Hebeler authoredDominik Hebeler authored
app.js 4.32 KiB
var createError = require("http-errors");
var express = require("express");
var path = require("path");
var cookieParser = require("cookie-parser");
var logger = require("morgan");
const { readdirSync, lstatSync } = require("fs");
var indexRouter = require("./routes/index");
const RedisClient = require("./app/RedisClient");
// Localization
const i18next = require("i18next");
let i18nextfsbackend = require("i18next-fs-backend");
const i18nextmiddleware = require("i18next-http-middleware");
const mglangdetector = require("./app/Langdetector");
const langdetector = new i18nextmiddleware.LanguageDetector();
langdetector.addDetector(mglangdetector);
let ns = [];
readdirSync(path.join(__dirname, "lang", "en")).forEach((fileName) => {
const joinedPath = path.join(path.join(__dirname, "lang", "en"), fileName);
if (!lstatSync(joinedPath).isDirectory()) {
ns.push(fileName.replace(".json", ""));
}
});
let env = process.env.NODE_ENV;
/** @global */
global.__redis_client = RedisClient.CLIENT();
/** @global */
global.__database_client = require("knex")(require("./knexfile"));
i18next
.use(langdetector)
.use(i18nextfsbackend)
.init({
debug: false,
// Lang Detector Options
detection: {
order: ["mg_detection"],
},
// FS Backend Options
backend: {
loadPath: path.join(__dirname, "lang", "{{lng}}", "{{ns}}.json"),
addPath: path.join(__dirname, "lang", "{{lng}}", "{{ns}}.missing.json"),
},
ns: ns,
defaultNS: "index",
fallbackLng: "en",
initImmediate: false,
preload: readdirSync(path.join(__dirname, "lang")).filter((fileName) => {
const joinedPath = path.join(path.join(__dirname, "lang"), fileName);
const isDirectory = lstatSync(joinedPath).isDirectory();
return isDirectory;
}),
});
var app = express();
// view engine setup
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "ejs");
// Setup logging
if (process.env.NODE_ENV === "development") {
app.use(logger("dev"));
} else {
// Do not log successful requests in production
app.use(
logger("dev", {
skip: (req, res) => {
return res.statusCode < 400;
},
})
);
}
app.use(express.json());
app.use(express.urlencoded({ extended: false, limit: "1mb" }));
app.use(cookieParser());
// Healthcheck URL
app.get("/healthz", (req, res) => {
res.status(200);
res.header({ "Content-Type": "application/json" });
res.send(JSON.stringify({ status: "OK" }));
});
app.get("/healthz/cron", async (req, res) => {
let live = await __redis_client.get("cron_liveness");
if (live !== null) {
res.json({ message: "OK" });
} else {
res.status(404).json({ message: "DOWN" });
}
});
app.use((req, res, next) => {
// Make req and res accessible in EJS
res.locals = req;
res.locals = res;
res.locals.baseDir = "";
let subPath = req.url.match(/^((\/.*)?\/keys)/);
let allowed_hosts = ["localhost", "metager.de", "metager.org", "metager3.de"];
if (
allowed_hosts.includes(req.hostname) ||
(process.env.NODE_ENV === "development" &&
req.hostname.match(
/^(localhost|.*\.ngrok-free\.app|.*\.review\.metager\.de)$/
))
) {
let proto = req.get("x-forwarded-proto") ?? req.protocol;
let host = req.get("x-forwarded-host") ?? req.get("host");
let port = req.get("x-forwarded-port");
if (
host.match(
/^(.*\.ngrok-free\.app|metager\.de|metager\.org|metager3\.de)$/
)
) {
proto = "https";
port = undefined;
}
res.locals.baseDir =
`${proto}://${host}` +
(port ? `:${port}` : "") +
(subPath ? subPath[1] : "");
}
next();
});
app.use(
i18nextmiddleware.handle(i18next, {
ignoreRoutes: (req, res, options, i18next) => {
if (
req.path.match(/^(\/[a-zA-Z\-]{2,5})?(\/keys)?\/(styles|js|images)\//)
) {
return true;
}
},
})
);
app.use(/^((\/.*)?\/keys)/, indexRouter);
app.use(indexRouter);
// catch 404 and forward to error handler
app.use(function (req, res, next) {
next(createError(404));
});
// error handler
app.use(function (err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = err;
if (err.status != 404) console.error(err.stack);
// render the error page
res.status(err.status || 500);
res.render("error");
});
module.exports = app;