From d0b39c01fbc06b6f5d92613e4b35732f7f9d90c7 Mon Sep 17 00:00:00 2001 From: Tom Hunkapiller Date: Tue, 7 Apr 2015 07:55:05 -0500 Subject: [PATCH 1/6] update for express 4.x --- src/node/db/SessionStore.js | 2 +- src/node/handler/ExportHandler.js | 4 ++-- src/node/hooks/express.js | 6 ++---- src/node/hooks/express/socketio.js | 9 +++++---- src/node/hooks/express/specialpages.js | 8 ++++---- src/node/hooks/express/static.js | 7 ++++--- src/node/hooks/express/webaccess.js | 6 +++--- src/package.json | 7 ++++--- 8 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/node/db/SessionStore.js b/src/node/db/SessionStore.js index 5c45ddb3..97404690 100644 --- a/src/node/db/SessionStore.js +++ b/src/node/db/SessionStore.js @@ -4,7 +4,7 @@ * This is not used for authors that are created via the API at current */ -var Store = require('ep_etherpad-lite/node_modules/connect/lib/middleware/session/store'), +var Store = require('ep_etherpad-lite/node_modules/express-session').Store, db = require('ep_etherpad-lite/node/db/DB').db, log4js = require('ep_etherpad-lite/node_modules/log4js'), messageLogger = log4js.getLogger("SessionStore"); diff --git a/src/node/handler/ExportHandler.js b/src/node/handler/ExportHandler.js index 0654deb4..f20e8715 100644 --- a/src/node/handler/ExportHandler.js +++ b/src/node/handler/ExportHandler.js @@ -103,7 +103,7 @@ exports.doExport = function(req, res, padId, type) //send the file function(callback) { - res.sendfile(destFile, null, callback); + res.sendFile(destFile, null, callback); }, //clean up temporary files function(callback) @@ -184,7 +184,7 @@ exports.doExport = function(req, res, padId, type) //send the file function(callback) { - res.sendfile(destFile, null, callback); + res.sendFile(destFile, null, callback); }, //clean up temporary files function(callback) diff --git a/src/node/hooks/express.js b/src/node/hooks/express.js index 3275bd3f..692be589 100644 --- a/src/node/hooks/express.js +++ b/src/node/hooks/express.js @@ -67,10 +67,8 @@ exports.restartServer = function () { if(settings.trustProxy){ app.enable('trust proxy'); } - - app.configure(function() { - hooks.callAll("expressConfigure", {"app": app}); - }); + + hooks.callAll("expressConfigure", {"app": app}); hooks.callAll("expressCreateServer", {"app": app, "server": server}); server.listen(settings.port, settings.ip); diff --git a/src/node/hooks/express/socketio.js b/src/node/hooks/express/socketio.js index 35d6d074..23622f3a 100644 --- a/src/node/hooks/express/socketio.js +++ b/src/node/hooks/express/socketio.js @@ -6,7 +6,8 @@ var webaccess = require("ep_etherpad-lite/node/hooks/express/webaccess"); var padMessageHandler = require("../../handler/PadMessageHandler"); -var connect = require('connect'); +var cookieParser = require('cookie-parser'); +var sessionModule = require('express-session'); exports.expressCreateServer = function (hook_name, args, cb) { //init socket.io and redirect all requests to the MessageHandler @@ -20,6 +21,7 @@ exports.expressCreateServer = function (hook_name, args, cb) { /* Require an express session cookie to be present, and load the * session. See http://www.danielbaulig.de/socket-ioexpress for more * info */ + var cookieParserFn = cookieParser(webaccess.secret, {}); io.use(function(socket, accept) { var data = socket.request; @@ -29,8 +31,7 @@ exports.expressCreateServer = function (hook_name, args, cb) { }else{ if (!data.headers.cookie) return accept('No session cookie transmitted.', false); } - // Use connect's cookie parser, because it knows how to parse signed cookies - connect.cookieParser(webaccess.secret)(data, {}, function(err){ + cookieParserFn(data, {}, function(err){ if(err) { console.error(err); accept("Couldn't parse request cookies. ", false); @@ -40,7 +41,7 @@ exports.expressCreateServer = function (hook_name, args, cb) { data.sessionID = data.signedCookies.express_sid; args.app.sessionStore.get(data.sessionID, function (err, session) { if (err || !session) return accept('Bad session / session has expired', false); - data.session = new connect.middleware.session.Session(data, session); + data.session = new sessionModule.Session(data, session); accept(null, true); }); }); diff --git a/src/node/hooks/express/specialpages.js b/src/node/hooks/express/specialpages.js index 063328fb..0370c4fc 100644 --- a/src/node/hooks/express/specialpages.js +++ b/src/node/hooks/express/specialpages.js @@ -19,13 +19,13 @@ exports.expressCreateServer = function (hook_name, args, cb) { args.app.get('/robots.txt', function(req, res) { var filePath = path.normalize(__dirname + "/../../../static/custom/robots.txt"); - res.sendfile(filePath, function(err) + res.sendFile(filePath, function(err) { //there is no custom favicon, send the default robots.txt which dissallows all if(err) { filePath = path.normalize(__dirname + "/../../../static/robots.txt"); - res.sendfile(filePath); + res.sendFile(filePath); } }); }); @@ -60,13 +60,13 @@ exports.expressCreateServer = function (hook_name, args, cb) { args.app.get( /\/favicon.ico$/, function(req, res) { var filePath = path.normalize(__dirname + "/../../../static/custom/favicon.ico"); - res.sendfile(filePath, function(err) + res.sendFile(filePath, function(err) { //there is no custom favicon, send the default favicon if(err) { filePath = path.normalize(__dirname + "/../../../static/favicon.ico"); - res.sendfile(filePath); + res.sendFile(filePath); } }); }); diff --git a/src/node/hooks/express/static.js b/src/node/hooks/express/static.js index e5a2bff0..7ae20db2 100644 --- a/src/node/hooks/express/static.js +++ b/src/node/hooks/express/static.js @@ -9,11 +9,11 @@ exports.expressCreateServer = function (hook_name, args, cb) { // Cache both minified and static. var assetCache = new CachingMiddleware; - args.app.all('/(javascripts|static)/*', assetCache.handle); + args.app.all(/\/(javascripts|static)\/(.*)/, assetCache.handle); // Minify will serve static files compressed (minify enabled). It also has // file-specific hacks for ace/require-kernel/etc. - args.app.all('/static/:filename(*)', minify.minify); + args.app.all('/static/:filename', minify.minify); // Setup middleware that will package JavaScript files served by minify for // CommonJS loader on the client-side. @@ -30,7 +30,8 @@ exports.expressCreateServer = function (hook_name, args, cb) { Yajsml.associators.associationsForSimpleMapping(minify.tar); var associator = new StaticAssociator(associations); jsServer.setAssociator(associator); - args.app.use(jsServer); + + args.app.use(jsServer.handle.bind(jsServer)); // serve plugin definitions // not very static, but served here so that client can do require("pluginfw/static/js/plugin-definitions.js"); diff --git a/src/node/hooks/express/webaccess.js b/src/node/hooks/express/webaccess.js index b798f2c7..60b3e651 100644 --- a/src/node/hooks/express/webaccess.js +++ b/src/node/hooks/express/webaccess.js @@ -4,7 +4,8 @@ var httpLogger = log4js.getLogger("http"); var settings = require('../../utils/Settings'); var hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks'); var ueberStore = require('../../db/SessionStore'); -var stats = require('ep_etherpad-lite/node/stats') +var stats = require('ep_etherpad-lite/node/stats'); +var sessionModule = require('express-session'); //checks for basic http auth exports.basicAuth = function (req, res, next) { @@ -117,9 +118,8 @@ exports.expressConfigure = function (hook_name, args, cb) { exports.secret = settings.sessionKey; // Isn't this being reset each time the server spawns? } - args.app.use(express.cookieParser(exports.secret)); args.app.sessionStore = exports.sessionStore; - args.app.use(express.session({secret: exports.secret, store: args.app.sessionStore, key: 'express_sid' })); + args.app.use(sessionModule({secret: exports.secret, store: args.app.sessionStore, resave: true, saveUninitialized: true, name: 'express_sid' })); args.app.use(exports.basicAuth); } diff --git a/src/package.json b/src/package.json index 4070431e..051119e4 100644 --- a/src/package.json +++ b/src/package.json @@ -18,9 +18,10 @@ "resolve" : "1.1.6", "socket.io" : "1.3.5", "ueberDB" : "0.2.15", - "express" : "3.8.1", + "express" : "4.12.3", + "express-session" : "1.10.4", + "cookie-parser" : "1.3.4", "async" : "0.9.0", - "connect" : "2.7.11", "clean-css" : "3.1.9", "uglify-js" : "2.4.19", "formidable" : "1.0.17", @@ -48,7 +49,7 @@ "devDependencies": { "wd" : "0.3.11" }, - "engines" : { "node" : ">=0.6.3", + "engines" : { "node" : ">=0.10.0", "npm" : ">=1.0" }, "repository" : { "type" : "git", From 63cbab484dd569796f2636363a069e7981a8e6ea Mon Sep 17 00:00:00 2001 From: Tom Hunkapiller Date: Tue, 7 Apr 2015 21:00:44 -0500 Subject: [PATCH 2/6] express dropped support for node 0.8; update engine requirements --- README.md | 2 +- bin/buildForWindows.sh | 2 +- bin/installDeps.sh | 4 ++-- bin/installOnWindows.bat | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 3d266827..dc5bdcf6 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Also, check out the **[FAQ](https://github.com/ether/etherpad-lite/wiki/FAQ)**, # Installation -Etherpad works with node v0.8, v0.10 and v0.11, only. (We don't support v0.6) +Etherpad works with node v0.10 and v0.11, only. (We don't support v0.6 or v0.8) ## Windows diff --git a/bin/buildForWindows.sh b/bin/buildForWindows.sh index 78441ba0..212e946b 100755 --- a/bin/buildForWindows.sh +++ b/bin/buildForWindows.sh @@ -1,6 +1,6 @@ #!/bin/sh -NODE_VERSION="0.8.4" +NODE_VERSION="0.10.38" #Move to the folder where ep-lite is installed cd `dirname $0` diff --git a/bin/installDeps.sh b/bin/installDeps.sh index a5e4d5ab..f2a3aafc 100755 --- a/bin/installDeps.sh +++ b/bin/installDeps.sh @@ -50,9 +50,9 @@ NODE_V_MINOR=$(echo $NODE_VERSION | cut -d "." -f 1-2) if hash iojs 2>/dev/null; then IOJS_VERSION=$(iojs --version) fi -if [ ! $NODE_V_MINOR = "v0.8" ] && [ ! $NODE_V_MINOR = "v0.10" ] && [ ! $NODE_V_MINOR = "v0.11" ] && [ ! $NODE_V_MINOR = "v0.12" ]; then +if [ ! $NODE_V_MINOR = "v0.10" ] && [ ! $NODE_V_MINOR = "v0.11" ] && [ ! $NODE_V_MINOR = "v0.12" ]; then if [ ! $IOJS_VERSION ]; then - echo "You're running a wrong version of node, or io.js is not installed. You're using $NODE_VERSION, we need v0.8.x, v0.10.x, v0.11.x or v0.12.x" >&2 + echo "You're running a wrong version of node, or io.js is not installed. You're using $NODE_VERSION, we need v0.10.x, v0.11.x or v0.12.x" >&2 exit 1 fi fi diff --git a/bin/installOnWindows.bat b/bin/installOnWindows.bat index 86223064..c1e0a822 100644 --- a/bin/installOnWindows.bat +++ b/bin/installOnWindows.bat @@ -8,7 +8,7 @@ cmd /C node -e "" || ( echo "Please install node.js ( http://nodejs.org )" && ex echo _ echo Checking node version... -set check_version="if(['8','10'].indexOf(process.version.split('.')[1].toString()) === -1) { console.log('You are running a wrong version of Node. Etherpad requires v0.8.x or v0.10.x'); process.exit(1) }" +set check_version="if(['10'].indexOf(process.version.split('.')[1].toString()) === -1) { console.log('You are running a wrong version of Node. Etherpad requires v0.10.x'); process.exit(1) }" cmd /C node -e %check_version% || exit /B 1 echo _ From 4385598de64988da6040e4b7a222110c67826a92 Mon Sep 17 00:00:00 2001 From: Tom Hunkapiller Date: Wed, 8 Apr 2015 23:11:39 -0500 Subject: [PATCH 3/6] update node version checking to 0.10+ or io.js --- README.md | 2 +- bin/installOnWindows.bat | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index dc5bdcf6..bef84656 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Also, check out the **[FAQ](https://github.com/ether/etherpad-lite/wiki/FAQ)**, # Installation -Etherpad works with node v0.10 and v0.11, only. (We don't support v0.6 or v0.8) +Etherpad works with node v0.10+ and io.js. ## Windows diff --git a/bin/installOnWindows.bat b/bin/installOnWindows.bat index c1e0a822..9b9a42e4 100644 --- a/bin/installOnWindows.bat +++ b/bin/installOnWindows.bat @@ -8,7 +8,7 @@ cmd /C node -e "" || ( echo "Please install node.js ( http://nodejs.org )" && ex echo _ echo Checking node version... -set check_version="if(['10'].indexOf(process.version.split('.')[1].toString()) === -1) { console.log('You are running a wrong version of Node. Etherpad requires v0.10.x'); process.exit(1) }" +set check_version="if(['10','11','12'].indexOf(process.version.split('.')[1]) === -1 && process.version.split('.')[0] !== '1') { console.log('You are running a wrong version of Node. Etherpad requires v0.10+'); process.exit(1) }" cmd /C node -e %check_version% || exit /B 1 echo _ From de67714cf805ad60589a48ad0da57f132cb21c7d Mon Sep 17 00:00:00 2001 From: Tom Hunkapiller Date: Fri, 10 Apr 2015 05:52:58 -0500 Subject: [PATCH 4/6] fix minify route path; update deprecated calls --- src/node/hooks/express/static.js | 2 +- src/node/hooks/express/tests.js | 2 +- src/node/hooks/express/webaccess.js | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/node/hooks/express/static.js b/src/node/hooks/express/static.js index 7ae20db2..7af54b5d 100644 --- a/src/node/hooks/express/static.js +++ b/src/node/hooks/express/static.js @@ -13,7 +13,7 @@ exports.expressCreateServer = function (hook_name, args, cb) { // Minify will serve static files compressed (minify enabled). It also has // file-specific hacks for ace/require-kernel/etc. - args.app.all('/static/:filename', minify.minify); + args.app.all('/static/:filename(*)', minify.minify); // Setup middleware that will package JavaScript files served by minify for // CommonJS loader on the client-side. diff --git a/src/node/hooks/express/tests.js b/src/node/hooks/express/tests.js index 3157d68e..fcd81381 100644 --- a/src/node/hooks/express/tests.js +++ b/src/node/hooks/express/tests.js @@ -50,7 +50,7 @@ exports.expressCreateServer = function (hook_name, args, cb) { args.app.get('/tests/frontend/*', function (req, res) { var filePath = url2FilePath(req.url); - res.sendfile(filePath); + res.sendFile(filePath); }); args.app.get('/tests/frontend', function (req, res) { diff --git a/src/node/hooks/express/webaccess.js b/src/node/hooks/express/webaccess.js index 60b3e651..cb5a2207 100644 --- a/src/node/hooks/express/webaccess.js +++ b/src/node/hooks/express/webaccess.js @@ -57,10 +57,10 @@ exports.basicAuth = function (req, res, next) { res.header('WWW-Authenticate', 'Basic realm="Protected Area"'); if (req.headers.authorization) { setTimeout(function () { - res.send(401, 'Authentication required'); + res.status(401).send('Authentication required'); }, 1000); } else { - res.send(401, 'Authentication required'); + res.status(401).send('Authentication required'); } })); } From 6fad2ca39a01dbde3ef9f6ea7384b27d9d14661d Mon Sep 17 00:00:00 2001 From: Tom Hunkapiller Date: Fri, 10 Apr 2015 06:16:17 -0500 Subject: [PATCH 5/6] fix vulnerability --- src/node/utils/Minify.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/node/utils/Minify.js b/src/node/utils/Minify.js index da101f8d..ba45ab75 100644 --- a/src/node/utils/Minify.js +++ b/src/node/utils/Minify.js @@ -145,7 +145,6 @@ function minify(req, res, next) filename = path.normalize(path.join(ROOT_DIR, filename)); if (filename.indexOf(ROOT_DIR) == 0) { filename = filename.slice(ROOT_DIR.length); - filename = filename.replace(/\\/g, '/'); // Windows (safe generally?) } else { res.writeHead(404, {}); res.end(); From fd1d285a77db1c583be3e42fb1929ecd4dd41633 Mon Sep 17 00:00:00 2001 From: Tom Hunkapiller Date: Fri, 10 Apr 2015 14:10:55 -0500 Subject: [PATCH 6/6] fix the rest of the deprecation warnings --- src/node/handler/ImportHandler.js | 2 +- src/node/hooks/express/errorhandling.js | 4 ++-- src/node/hooks/express/padreadonly.js | 2 +- src/node/hooks/express/padurlsanitize.js | 4 ++-- src/node/hooks/i18n.js | 2 +- src/node/padaccess.js | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/node/handler/ImportHandler.js b/src/node/handler/ImportHandler.js index 2dad8b3d..ba6f4415 100644 --- a/src/node/handler/ImportHandler.js +++ b/src/node/handler/ImportHandler.js @@ -303,7 +303,7 @@ exports.doImport = function(req, res, padId) var impexp = window.parent.padimpexp.handleFrameCall('" + directDatabaseAccess +"', '" + status + "'); \ }) \ " - , 200); + ); }); } diff --git a/src/node/hooks/express/errorhandling.js b/src/node/hooks/express/errorhandling.js index 087dd50e..7afe80ae 100644 --- a/src/node/hooks/express/errorhandling.js +++ b/src/node/hooks/express/errorhandling.js @@ -39,7 +39,7 @@ exports.expressCreateServer = function (hook_name, args, cb) { // if an error occurs Connect will pass it down // through these "error-handling" middleware // allowing you to respond however you like - res.send(500, { error: 'Sorry, something bad happened!' }); + res.status(500).send({ error: 'Sorry, something bad happened!' }); console.error(err.stack? err.stack : err.toString()); stats.meter('http500').mark() }) @@ -50,4 +50,4 @@ exports.expressCreateServer = function (hook_name, args, cb) { //https://github.com/joyent/node/issues/1553 process.on('SIGINT', exports.gracefulShutdown); } -} \ No newline at end of file +} diff --git a/src/node/hooks/express/padreadonly.js b/src/node/hooks/express/padreadonly.js index d60d3863..66be3339 100644 --- a/src/node/hooks/express/padreadonly.js +++ b/src/node/hooks/express/padreadonly.js @@ -55,7 +55,7 @@ exports.expressCreateServer = function (hook_name, args, cb) { ERR(err); if(err == "notfound") - res.send(404, '404 - Not Found'); + res.status(404).send('404 - Not Found'); else res.send(html); }); diff --git a/src/node/hooks/express/padurlsanitize.js b/src/node/hooks/express/padurlsanitize.js index 2aadccdc..94cbe36a 100644 --- a/src/node/hooks/express/padurlsanitize.js +++ b/src/node/hooks/express/padurlsanitize.js @@ -7,7 +7,7 @@ exports.expressCreateServer = function (hook_name, args, cb) { //ensure the padname is valid and the url doesn't end with a / if(!padManager.isValidPadId(padId) || /\/$/.test(req.url)) { - res.send(404, 'Such a padname is forbidden'); + res.status(404).send('Such a padname is forbidden'); } else { @@ -19,7 +19,7 @@ exports.expressCreateServer = function (hook_name, args, cb) { var query = url.parse(req.url).query; if ( query ) real_url += '?' + query; res.header('Location', real_url); - res.send(302, 'You should be redirected to ' + real_url + ''); + res.status(302).send('You should be redirected to ' + real_url + ''); } //the pad id was fine, so just render it else diff --git a/src/node/hooks/i18n.js b/src/node/hooks/i18n.js index 67815659..1d28b544 100644 --- a/src/node/hooks/i18n.js +++ b/src/node/hooks/i18n.js @@ -91,7 +91,7 @@ exports.expressCreateServer = function(n, args) { res.setHeader('Content-Type', 'application/json; charset=utf-8'); res.send('{"'+locale+'":'+JSON.stringify(locales[locale])+'}'); } else { - res.send(404, 'Language not available'); + res.status(404).send('Language not available'); } }) diff --git a/src/node/padaccess.js b/src/node/padaccess.js index d8780914..97333514 100644 --- a/src/node/padaccess.js +++ b/src/node/padaccess.js @@ -15,7 +15,7 @@ module.exports = function (req, res, callback) { callback(); //no access } else { - res.send(403, "403 - Can't touch this"); + res.status(403).send("403 - Can't touch this"); } }); }