The frontend/UI server, written in JS using the MarkoJS library
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

136 lines
4.2 KiB

// 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))