diff --git a/package.json b/package.json index 16de6baa..7cb574c4 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "bluebird": "^2.10.1", "body-parser": "^1.14.0", "cheerio": "^0.19.0", + "clone": "^1.0.2", "compression": "^1.5.2", "cookie-parser": "^1.4.0", "create-error": "^0.3.1", diff --git a/src/configuration/webconfig.js b/src/configuration/webconfig.js new file mode 100644 index 00000000..607094f7 --- /dev/null +++ b/src/configuration/webconfig.js @@ -0,0 +1,27 @@ +import clone from 'clone'; + +export default class WebConfiguration { + constructor(config) { + this.config = config; + } + + getEmailContacts() { + return clone(this.config.contacts); + } +} + +WebConfiguration.fromOldConfig = function (oldConfig) { + const config = { + contacts: [] + }; + + oldConfig.get('contacts').forEach(contact => { + config.contacts.push({ + name: contact.name, + email: contact.email, + title: contact.title + }); + }); + + return new WebConfiguration(config); +}; diff --git a/src/server.js b/src/server.js index 234bd57d..54ae6557 100644 --- a/src/server.js +++ b/src/server.js @@ -44,6 +44,7 @@ var Flags = require("./flags"); var sio = require("socket.io"); import LocalChannelIndex from './web/localchannelindex'; import IOConfiguration from './configuration/ioconfig'; +import WebConfiguration from './configuration/webconfig'; import NullClusterClient from './io/cluster/nullclusterclient'; var Server = function () { @@ -64,10 +65,12 @@ var Server = function () { // webserver init ----------------------------------------------------- const ioConfig = IOConfiguration.fromOldConfig(Config); + const webConfig = WebConfiguration.fromOldConfig(Config); const clusterClient = new NullClusterClient(ioConfig); const channelIndex = new LocalChannelIndex(); self.express = express(); require("./web/webserver").init(self.express, + webConfig, ioConfig, clusterClient, channelIndex); diff --git a/src/web/routes/contact.js b/src/web/routes/contact.js new file mode 100644 index 00000000..32907469 --- /dev/null +++ b/src/web/routes/contact.js @@ -0,0 +1,26 @@ +import CyTubeUtil from '../../utilities'; +import { sendJade } from '../jade'; + +export default function initialize(app, webConfig) { + app.get('/contact', (req, res) => { + // Basic obfuscation of email addresses to prevent spambots + // from picking them up. Not real encryption. + // Deobfuscated by clientside JS. + const contacts = webConfig.getEmailContacts().map(contact => { + const emkey = CyTubeUtil.randomSalt(16); + let email = new Array(contact.email.length); + for (let i = 0; i < contact.email.length; i++) { + email[i] = String.fromCharCode( + contact.email.charCodeAt(i) ^ emkey.charCodeAt(i % emkey.length) + ); + } + contact.email = escape(email.join("")); + contact.emkey = escape(emkey); + return contact; + }); + + return sendJade(res, 'contact', { + contacts: contacts + }); + }); +} diff --git a/src/web/webserver.js b/src/web/webserver.js index c0c4b586..3b2ba345 100644 --- a/src/web/webserver.js +++ b/src/web/webserver.js @@ -110,39 +110,11 @@ function handleUserAgreement(req, res) { }); } -function handleContactPage(req, res) { - // Make a copy to prevent messing with the original - var contacts = Config.get("contacts").map(function (c) { - return { - name: c.name, - email: c.email, - title: c.title - }; - }); - - // Rudimentary hiding of email addresses to prevent spambots - contacts.forEach(function (c) { - c.emkey = $util.randomSalt(16) - var email = new Array(c.email.length); - for (var i = 0; i < c.email.length; i++) { - email[i] = String.fromCharCode( - c.email.charCodeAt(i) ^ c.emkey.charCodeAt(i % c.emkey.length) - ); - } - c.email = escape(email.join("")); - c.emkey = escape(c.emkey); - }); - - sendJade(res, "contact", { - contacts: contacts - }); -} - module.exports = { /** * Initializes webserver callbacks */ - init: function (app, ioConfig, clusterClient, channelIndex) { + init: function (app, webConfig, ioConfig, clusterClient, channelIndex) { app.use(function (req, res, next) { req._ip = ipForRequest(req); next(); @@ -203,7 +175,7 @@ module.exports = { app.get("/sioconfig(.json)?", handleSocketConfig); require("./routes/socketconfig")(app, clusterClient); app.get("/useragreement", handleUserAgreement); - app.get("/contact", handleContactPage); + require("./routes/contact")(app, webConfig); require("./auth").init(app); require("./account").init(app); require("./acp").init(app); @@ -232,6 +204,9 @@ module.exports = { } 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