mirror of https://github.com/calzoneman/sync.git
More refactoring
This commit is contained in:
parent
c2726898e5
commit
6505aa2f5e
|
@ -1,9 +1,9 @@
|
||||||
import clone from 'clone';
|
import clone from 'clone';
|
||||||
|
|
||||||
const DEFAULT_TRUSTED_PROXIES = [
|
const DEFAULT_TRUSTED_PROXIES = Object.freeze([
|
||||||
'127.0.0.1',
|
'127.0.0.1',
|
||||||
'::1'
|
'::1'
|
||||||
];
|
]);
|
||||||
|
|
||||||
export default class WebConfiguration {
|
export default class WebConfiguration {
|
||||||
constructor(config) {
|
constructor(config) {
|
||||||
|
@ -15,7 +15,31 @@ export default class WebConfiguration {
|
||||||
}
|
}
|
||||||
|
|
||||||
getTrustedProxies() {
|
getTrustedProxies() {
|
||||||
return DEFAULT_TRUSTED_PROXIES.slice();
|
return DEFAULT_TRUSTED_PROXIES;
|
||||||
|
}
|
||||||
|
|
||||||
|
getCookieSecret() {
|
||||||
|
return this.config.authCookie.cookieSecret;
|
||||||
|
}
|
||||||
|
|
||||||
|
getCookieDomain() {
|
||||||
|
return this.config.authCookie.cookieDomain;
|
||||||
|
}
|
||||||
|
|
||||||
|
getEnableGzip() {
|
||||||
|
return this.config.gzip.enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
getGzipThreshold() {
|
||||||
|
return this.config.gzip.threshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
getEnableMinification() {
|
||||||
|
return this.config.enableMinification;
|
||||||
|
}
|
||||||
|
|
||||||
|
getCacheTTL() {
|
||||||
|
return this.config.cacheTTL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,5 +56,19 @@ WebConfiguration.fromOldConfig = function (oldConfig) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
config.gzip = {
|
||||||
|
enabled: oldConfig.get('http.gzip'),
|
||||||
|
threshold: oldConfig.get('http.gzip-threshold')
|
||||||
|
};
|
||||||
|
|
||||||
|
config.authCookie = {
|
||||||
|
cookieSecret: oldConfig.get('http.cookie-secret'),
|
||||||
|
cookieDomain: oldConfig.get('http.root-domain-dotted')
|
||||||
|
};
|
||||||
|
|
||||||
|
config.enableMinification = oldConfig.get('http.minify');
|
||||||
|
|
||||||
|
config.cacheTTL = oldConfig.get('http.max-age');
|
||||||
|
|
||||||
return new WebConfiguration(config);
|
return new WebConfiguration(config);
|
||||||
};
|
};
|
||||||
|
|
|
@ -46,6 +46,7 @@ import LocalChannelIndex from './web/localchannelindex';
|
||||||
import IOConfiguration from './configuration/ioconfig';
|
import IOConfiguration from './configuration/ioconfig';
|
||||||
import WebConfiguration from './configuration/webconfig';
|
import WebConfiguration from './configuration/webconfig';
|
||||||
import NullClusterClient from './io/cluster/nullclusterclient';
|
import NullClusterClient from './io/cluster/nullclusterclient';
|
||||||
|
import session from './session';
|
||||||
|
|
||||||
var Server = function () {
|
var Server = function () {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
@ -73,7 +74,8 @@ var Server = function () {
|
||||||
webConfig,
|
webConfig,
|
||||||
ioConfig,
|
ioConfig,
|
||||||
clusterClient,
|
clusterClient,
|
||||||
channelIndex);
|
channelIndex,
|
||||||
|
session);
|
||||||
|
|
||||||
// http/https/sio server init -----------------------------------------
|
// http/https/sio server init -----------------------------------------
|
||||||
var key = "", cert = "", ca = undefined;
|
var key = "", cert = "", ca = undefined;
|
||||||
|
@ -255,4 +257,3 @@ Server.prototype.shutdown = function () {
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
const STATIC_RESOURCE = /\..+$/;
|
||||||
|
|
||||||
|
export default function initialize(app, session) {
|
||||||
|
app.use((req, res, next) => {
|
||||||
|
if (STATIC_RESOURCE.test(req.path)) {
|
||||||
|
return next();
|
||||||
|
} else if (!req.signedCookies || !req.signedCookies.auth) {
|
||||||
|
return nuext();
|
||||||
|
} else {
|
||||||
|
session.verifySession(req.signedCookies.auth, (err, account) => {
|
||||||
|
if (!err) {
|
||||||
|
req.user = res.user = account;
|
||||||
|
}
|
||||||
|
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
|
@ -1,33 +1,37 @@
|
||||||
var path = require("path");
|
import fs from 'fs';
|
||||||
var fs = require("fs");
|
import path from 'path';
|
||||||
var net = require("net");
|
import net from 'net';
|
||||||
var express = require("express");
|
import express from 'express';
|
||||||
var webroot = path.join(__dirname, "..", "www");
|
import { sendJade } from './jade';
|
||||||
var sendJade = require("./jade").sendJade;
|
import Logger from '../logger';
|
||||||
var Server = require("../server");
|
import Config from '../config';
|
||||||
var $util = require("../utilities");
|
import bodyParser from 'body-parser';
|
||||||
var Logger = require("../logger");
|
import cookieParser from 'cookie-parser';
|
||||||
var Config = require("../config");
|
import serveStatic from 'serve-static';
|
||||||
var db = require("../database");
|
import morgan from 'morgan';
|
||||||
var bodyParser = require("body-parser");
|
import csrf from './csrf';
|
||||||
var cookieParser = require("cookie-parser");
|
|
||||||
var serveStatic = require("serve-static");
|
|
||||||
var morgan = require("morgan");
|
|
||||||
var session = require("../session");
|
|
||||||
var csrf = require("./csrf");
|
|
||||||
var XSS = require("../xss");
|
|
||||||
import * as HTTPStatus from './httpstatus';
|
import * as HTTPStatus from './httpstatus';
|
||||||
import { CSRFError, HTTPError } from '../errors';
|
import { CSRFError, HTTPError } from '../errors';
|
||||||
|
|
||||||
const LOG_FORMAT = ':real-address - :remote-user [:date] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"';
|
function initializeLog(app) {
|
||||||
morgan.token('real-address', function (req) { return req.realIP; });
|
const logFormat = ':real-address - :remote-user [:date] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"';
|
||||||
|
const logPath = path.join(__dirname, '..', '..', 'http.log');
|
||||||
|
const outputStream = fs.createWriteStream(logPath, {
|
||||||
|
flags: 'a', // append to existing file
|
||||||
|
encoding: 'utf8'
|
||||||
|
});
|
||||||
|
morgan.token('real-address', req => req.realIP);
|
||||||
|
app.use(morgan(logFormat, {
|
||||||
|
stream: outputStream
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Redirects a request to HTTPS if the server supports it
|
* Redirects a request to HTTPS if the server supports it
|
||||||
*/
|
*/
|
||||||
function redirectHttps(req, res) {
|
function redirectHttps(req, res) {
|
||||||
if (!req.secure && Config.get("https.enabled") && Config.get("https.redirect")) {
|
if (!req.secure && Config.get('https.enabled') && Config.get('https.redirect')) {
|
||||||
var ssldomain = Config.get("https.full-address");
|
var ssldomain = Config.get('https.full-address');
|
||||||
if (ssldomain.indexOf(req.hostname) < 0) {
|
if (ssldomain.indexOf(req.hostname) < 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -43,7 +47,7 @@ function redirectHttps(req, res) {
|
||||||
*/
|
*/
|
||||||
function redirectHttp(req, res) {
|
function redirectHttp(req, res) {
|
||||||
if (req.secure) {
|
if (req.secure) {
|
||||||
var domain = Config.get("http.full-address");
|
var domain = Config.get('http.full-address');
|
||||||
res.redirect(domain + req.path);
|
res.redirect(domain + req.path);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -54,36 +58,81 @@ function redirectHttp(req, res) {
|
||||||
* Legacy socket.io configuration endpoint. This is being migrated to
|
* Legacy socket.io configuration endpoint. This is being migrated to
|
||||||
* /socketconfig/<channel name>.json (see ./routes/socketconfig.js)
|
* /socketconfig/<channel name>.json (see ./routes/socketconfig.js)
|
||||||
*/
|
*/
|
||||||
function handleSocketConfig(req, res) {
|
function handleLegacySocketConfig(req, res) {
|
||||||
if (/\.json$/.test(req.path)) {
|
if (/\.json$/.test(req.path)) {
|
||||||
res.json(Config.get("sioconfigjson"));
|
res.json(Config.get('sioconfigjson'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
res.type("application/javascript");
|
res.type('application/javascript');
|
||||||
|
|
||||||
var sioconfig = Config.get("sioconfig");
|
var sioconfig = Config.get('sioconfig');
|
||||||
var iourl;
|
var iourl;
|
||||||
var ip = req.realIP;
|
var ip = req.realIP;
|
||||||
var ipv6 = false;
|
var ipv6 = false;
|
||||||
|
|
||||||
if (net.isIPv6(ip)) {
|
if (net.isIPv6(ip)) {
|
||||||
iourl = Config.get("io.ipv6-default");
|
iourl = Config.get('io.ipv6-default');
|
||||||
ipv6 = true;
|
ipv6 = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!iourl) {
|
if (!iourl) {
|
||||||
iourl = Config.get("io.ipv4-default");
|
iourl = Config.get('io.ipv4-default');
|
||||||
}
|
}
|
||||||
|
|
||||||
sioconfig += "var IO_URL='" + iourl + "';";
|
sioconfig += 'var IO_URL=\'' + iourl + '\';';
|
||||||
sioconfig += "var IO_V6=" + ipv6 + ";";
|
sioconfig += 'var IO_V6=' + ipv6 + ';';
|
||||||
res.send(sioconfig);
|
res.send(sioconfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleUserAgreement(req, res) {
|
function handleUserAgreement(req, res) {
|
||||||
sendJade(res, "tos", {
|
sendJade(res, 'tos', {
|
||||||
domain: Config.get("http.domain")
|
domain: Config.get('http.domain')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function initializeErrorHandlers(app) {
|
||||||
|
app.use((req, res, next) => {
|
||||||
|
return next(new HTTPError(`No route for ${req.path}`, {
|
||||||
|
status: HTTPStatus.NOT_FOUND
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
app.use((err, req, res, next) => {
|
||||||
|
if (err) {
|
||||||
|
if (err instanceof CSRFError) {
|
||||||
|
res.status(HTTPStatus.FORBIDDEN);
|
||||||
|
return sendJade(res, 'csrferror', {
|
||||||
|
path: req.path,
|
||||||
|
referer: req.header('referer')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let { message, status } = err;
|
||||||
|
if (!status) {
|
||||||
|
status = HTTPStatus.INTERNAL_SERVER_ERROR;
|
||||||
|
}
|
||||||
|
if (!message) {
|
||||||
|
message = 'An unknown error occurred.';
|
||||||
|
} else if (/\.(jade|js)/.test(message)) {
|
||||||
|
// Prevent leakage of stack traces
|
||||||
|
message = 'An internal error occurred.';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log 5xx (server) errors
|
||||||
|
if (Math.floor(status / 100) === 5) {
|
||||||
|
Logger.errlog.log(err.stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(status);
|
||||||
|
return sendJade(res, 'httperror', {
|
||||||
|
path: req.path,
|
||||||
|
status: status,
|
||||||
|
message: message
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
next();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,113 +140,54 @@ module.exports = {
|
||||||
/**
|
/**
|
||||||
* Initializes webserver callbacks
|
* Initializes webserver callbacks
|
||||||
*/
|
*/
|
||||||
init: function (app, webConfig, ioConfig, clusterClient, channelIndex) {
|
init: function (app, webConfig, ioConfig, clusterClient, channelIndex, session) {
|
||||||
require("./middleware/x-forwarded-for")(app, webConfig);
|
require('./middleware/x-forwarded-for')(app, webConfig);
|
||||||
app.use(bodyParser.urlencoded({
|
app.use(bodyParser.urlencoded({
|
||||||
extended: false,
|
extended: false,
|
||||||
limit: '1kb' // No POST data should ever exceed this size under normal usage
|
limit: '1kb' // No POST data should ever exceed this size under normal usage
|
||||||
}));
|
}));
|
||||||
if (Config.get("http.cookie-secret") === "change-me") {
|
if (webConfig.getCookieSecret() === 'change-me') {
|
||||||
Logger.errlog.log("YOU SHOULD CHANGE THE VALUE OF cookie-secret IN config.yaml");
|
Logger.errlog.log('WARNING: The configured cookie secret was left as the ' +
|
||||||
|
'default of "change-me".');
|
||||||
}
|
}
|
||||||
app.use(cookieParser(Config.get("http.cookie-secret")));
|
app.use(cookieParser(webConfig.getCookieSecret()));
|
||||||
app.use(csrf.init(Config.get("http.root-domain-dotted")));
|
app.use(csrf.init(webConfig.getCookieDomain()));
|
||||||
app.use(morgan(LOG_FORMAT, {
|
initializeLog(app);
|
||||||
stream: require("fs").createWriteStream(path.join(__dirname, "..", "..",
|
require('./middleware/authorize')(app, session);
|
||||||
"http.log"), {
|
|
||||||
flags: "a",
|
|
||||||
encoding: "utf-8"
|
|
||||||
})
|
|
||||||
}));
|
|
||||||
|
|
||||||
app.use(function (req, res, next) {
|
if (webConfig.getEnableGzip()) {
|
||||||
if (req.path.match(/^\/(css|js|img|boop).*$/)) {
|
app.use(require('compression')({
|
||||||
return next();
|
threshold: webConfig.getGzipThreshold()
|
||||||
}
|
}));
|
||||||
|
Logger.syslog.log('Enabled gzip compression');
|
||||||
if (!req.signedCookies || !req.signedCookies.auth) {
|
|
||||||
return next();
|
|
||||||
}
|
|
||||||
|
|
||||||
session.verifySession(req.signedCookies.auth, function (err, account) {
|
|
||||||
if (!err) {
|
|
||||||
req.user = res.user = account;
|
|
||||||
}
|
|
||||||
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
if (Config.get("http.gzip")) {
|
|
||||||
app.use(require("compression")({ threshold: Config.get("http.gzip-threshold") }));
|
|
||||||
Logger.syslog.log("Enabled gzip compression");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Config.get("http.minify")) {
|
if (webConfig.getEnableMinification()) {
|
||||||
var cache = path.join(__dirname, "..", "..", "www", "cache")
|
const cacheDir = path.join(__dirname, '..', '..', 'www', 'cache');
|
||||||
if (!fs.existsSync(cache)) {
|
if (!fs.existsSync(cache)) {
|
||||||
fs.mkdirSync(cache);
|
fs.mkdirSync(cache);
|
||||||
}
|
}
|
||||||
app.use(require("express-minify")({
|
app.use(require('express-minify')({
|
||||||
cache: cache
|
cache: cacheDir
|
||||||
}));
|
}));
|
||||||
Logger.syslog.log("Enabled express-minify for CSS and JS");
|
Logger.syslog.log('Enabled express-minify for CSS and JS');
|
||||||
}
|
}
|
||||||
|
|
||||||
require("./routes/channel")(app, ioConfig);
|
require('./routes/channel')(app, ioConfig);
|
||||||
require("./routes/index")(app, channelIndex);
|
require('./routes/index')(app, channelIndex);
|
||||||
app.get("/sioconfig(.json)?", handleSocketConfig);
|
app.get('/sioconfig(.json)?', handleLegacySocketConfig);
|
||||||
require("./routes/socketconfig")(app, clusterClient);
|
require('./routes/socketconfig')(app, clusterClient);
|
||||||
app.get("/useragreement", handleUserAgreement);
|
app.get('/useragreement', handleUserAgreement);
|
||||||
require("./routes/contact")(app, webConfig);
|
require('./routes/contact')(app, webConfig);
|
||||||
require("./auth").init(app);
|
require('./auth').init(app);
|
||||||
require("./account").init(app);
|
require('./account').init(app);
|
||||||
require("./acp").init(app);
|
require('./acp').init(app);
|
||||||
require("../google2vtt").attach(app);
|
require('../google2vtt').attach(app);
|
||||||
app.use(serveStatic(path.join(__dirname, "..", "..", "www"), {
|
app.use(serveStatic(path.join(__dirname, '..', '..', 'www'), {
|
||||||
maxAge: Config.get("http.max-age") || Config.get("http.cache-ttl")
|
maxAge: webConfig.getCacheTTL()
|
||||||
}));
|
}));
|
||||||
app.use((req, res, next) => {
|
|
||||||
return next(new HTTPError(`No route for ${req.path}`, {
|
|
||||||
status: HTTPStatus.NOT_FOUND
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
app.use(function (err, req, res, next) {
|
|
||||||
if (err) {
|
|
||||||
if (err instanceof CSRFError) {
|
|
||||||
res.status(HTTPStatus.FORBIDDEN);
|
|
||||||
return sendJade(res, 'csrferror', {
|
|
||||||
path: req.path,
|
|
||||||
referer: req.header('referer')
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let { message, status } = err;
|
initializeErrorHandlers(app);
|
||||||
if (!status) {
|
|
||||||
status = HTTPStatus.INTERNAL_SERVER_ERROR;
|
|
||||||
}
|
|
||||||
if (!message) {
|
|
||||||
message = 'An unknown error occurred.';
|
|
||||||
} else if (/\.(jade|js)/.test(message)) {
|
|
||||||
// Prevent leakage of stack traces
|
|
||||||
message = 'An internal error occurred.';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Log 5xx (server) errors
|
|
||||||
if (Math.floor(status / 100) === 5) {
|
|
||||||
Logger.errlog.log(err.stack);
|
|
||||||
}
|
|
||||||
|
|
||||||
res.status(status);
|
|
||||||
return sendJade(res, 'httperror', {
|
|
||||||
path: req.path,
|
|
||||||
status: status,
|
|
||||||
message: message
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
redirectHttps: redirectHttps,
|
redirectHttps: redirectHttps,
|
||||||
|
|
Loading…
Reference in New Issue