// Setup global environment require("marko/node-require").install() require("es6-promise").polyfill() // Load server config const config = require("./config") // Express depedencies const express = require("express") const proxy = require("express-http-proxy") const proxy2 = require("http-proxy-middleware") const ip = require("ip") const dns = require("dns") const lasso = require("lasso") const lassoMiddleware = require("lasso/middleware") const markoExpress = require("marko/express") const bodyParser = require("body-parser") // Load middleware const passport = require("./middleware/passport") const session = require("./middleware/session") // Setup express const app = express() // Configure lasso lasso.configure(require("./marko-config")) // Set trusted proxy if (config.trustedProxy != null) { if (config.trustedProxy === "GATEWAY") { const ip = require("child_process").execSync("/sbin/ip route|awk '/default/ { print $3 }'").toString().trim() app.set('trust proxy', ip) console.log("Trusting proxy from default gateway", ip); } else if (ip.isV4Format(config.trustedProxy) || ip.isV6Format(config.trustedProxy)) { app.set('trust proxy', config.trustedProxy) console.log("Trusting proxy", config.trustedProxy); } else { let trusted = null setInterval(() => { dns.resolve4(config.trustedProxy, (err, res) => { if (err != null) { if (trusted === null) { console.error("Failed to resolve trustedProxy hostname") } return } if (res.length === 0) { if (trusted === null) { console.error("No results for trustedProxy hostname") } return } if (trusted !== res[0]) { console.log("Trusting proxy", res[0], `(${config.trustedProxy})`); app.set('trust proxy', res[0]) trusted = res[0] } }) }, 1000) } } // Apply middleware app.use(markoExpress()) app.use(session) app.use(passport.initialize()) app.use(passport.session()) app.use(require("./middleware/locals")) // Proxy (does not want all middleware) app.use("/graphql", require("./routes/graphql").router) app.use("/playground", proxy(config.playgroundEndpoint)) // The rest of the middleware app.use(bodyParser.json({limit: "1mb"})) app.use(bodyParser.text({limit: "256kb"})) // Static assets app.use("/assets", express.static(__dirname + "/assets")) app.use(lassoMiddleware.serveStatic()) // Authentication app.use("/auth", require("./routes/auth")) // Global css doesn't work with prebuild. if (process.env.NODE_ENV === "production") { app.use("/hax/global.css", require("./routes/globalcss")) } else { app.get("/hax/global.css", (req, res) => { res.type(".css").end("") }) } // Page routes app.use("/story/", require("./routes/story")) app.use("/story/unlisted/", require("./routes/story/unlisted")) app.use("/story/by-category/", require("./routes/story/by-category")) app.use("/story/by-tag/", require("./routes/story/by-tag")) app.use("/story/by-month/", require("./routes/story/by-month")) app.use("/story/by-author/", require("./routes/story/by-author")) app.use("/story/tag-list/", require("./routes/story/tag-list")) app.use("/story/:id(S[0-9a-z]{15})/", require("./routes/story-content")) app.use("/logs/", require("./routes/logs")) app.use("/logs/:id([0-9]{4}-[0-1][0-9]-[0-3][0-9]_[0-9]{9}_[A-Za-z0-9\,\'\-]{2,})/", require("./routes/logs-content")) app.use("/logs/:id(L[0-9]{0,7})/", require("./routes/logs-content")) app.use("/data/", require("./routes/data")) app.use("/data/characters/", require("./routes/data/characters")) app.use("/data/channels/", require("./routes/data/channels")) app.use("/data/changes/", require("./routes/data/changes")) app.use("/data/files/", require("./routes/data/files")) // Entry point app.get("/", function(req, res) { res.redirect("/story/") }) // Start server app.listen(config.port, function() { console.log("Server started: http://localhost:" + config.port + "/") if (process.send) { setTimeout(() => process.send("online"), 100) } }) // Handle shutdown signals (Docker needs this to shutdown quickly) process.on('SIGINT', () => process.exit(0)) process.on('SIGTERM', () => process.exit(0))