From 603f251824b55be022023633333b215cc996e4b9 Mon Sep 17 00:00:00 2001 From: johnyma22 Date: Wed, 12 Sep 2012 19:34:33 +0100 Subject: [PATCH 01/51] error handling and close is removed in express 3 --- src/node/hooks/express/errorhandling.js | 25 ++++++++++++++++++++++--- src/package.json | 2 +- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/node/hooks/express/errorhandling.js b/src/node/hooks/express/errorhandling.js index cb8c58987..3c5727ed4 100644 --- a/src/node/hooks/express/errorhandling.js +++ b/src/node/hooks/express/errorhandling.js @@ -16,9 +16,6 @@ exports.gracefulShutdown = function(err) { console.log("graceful shutdown..."); - //stop the http server - exports.app.close(); - //do the db shutdown db.db.doShutdown(function() { console.log("db sucessfully closed."); @@ -35,11 +32,33 @@ exports.gracefulShutdown = function(err) { exports.expressCreateServer = function (hook_name, args, cb) { exports.app = args.app; + + +/* + Below breaks Express 3, commented out to allow express 3o to run. For mroe details see: + https://github.com/visionmedia/express/wiki/Migrating-from-2.x-to-3.x +/* +/* args.app.error(function(err, req, res, next){ res.send(500); console.error(err.stack ? err.stack : err.toString()); exports.gracefulShutdown(); }); +*/ + + + +// args.app.on('close', function(){ +// console.log("Exited in a sloppy fashion"); +// }) + + args.app.use(function(err, req, res, next){ + // 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!' }); + }) + //connect graceful shutdown with sigint and uncaughtexception if(os.type().indexOf("Windows") == -1) { diff --git a/src/package.json b/src/package.json index a2fc147ab..a7550faed 100644 --- a/src/package.json +++ b/src/package.json @@ -17,7 +17,7 @@ "socket.io" : "0.9.x", "ueberDB" : "0.1.7", "async" : "0.1.x", - "express" : "2.5.x", + "express" : "3.x", "connect" : "1.x", "clean-css" : "0.3.2", "uglify-js" : "1.2.5", From c8b6d3b4f3bb8677b259a8c5be2e9611004347c0 Mon Sep 17 00:00:00 2001 From: johnyma22 Date: Wed, 12 Sep 2012 19:38:53 +0100 Subject: [PATCH 02/51] attempt to put correct init in right place but could be wrong --- src/node/hooks/express.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/node/hooks/express.js b/src/node/hooks/express.js index 1f4a6f2cc..e4ff40d96 100644 --- a/src/node/hooks/express.js +++ b/src/node/hooks/express.js @@ -42,12 +42,13 @@ exports.createServer = function () { } exports.restartServer = function () { + if (server) { console.log("Restarting express server"); server.close(); } - server = express.createServer(); + server = express(); // New syntax for express v3 server.use(function (req, res, next) { res.header("Server", serverName); @@ -60,4 +61,4 @@ exports.restartServer = function () { hooks.callAll("expressCreateServer", {"app": server}); server.listen(settings.port, settings.ip); -} \ No newline at end of file +} From afc90604bfad7ab5805873cb5bafc3bbb74c4b01 Mon Sep 17 00:00:00 2001 From: Charlie DeTar Date: Sat, 15 Sep 2012 17:48:04 -0400 Subject: [PATCH 03/51] Add `userColor` query param to set initial color Add a URL parameter which sets the initial color for a user, e.g.: http://example.com/p/mypad?userColor=%2300ff00 Sanitize the given color value to ensure that it's a valid css value (could be any supported CSS color format -- #fff, rgba(), "red", etc). Shortly after rejoining a pad, the server responds with a USER_NEWINFO message which may contain an old color value; however, this message arrives after we have set and sent the new color value to the server. To avoid this race condition, if the query parameter has been set, ignore the color value in a USER_NEWINFO message which matches our user ID. --- src/static/js/collab_client.js | 8 ++++++++ src/static/js/pad.js | 25 +++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/static/js/collab_client.js b/src/static/js/collab_client.js index d149b2565..b3e17c256 100644 --- a/src/static/js/collab_client.js +++ b/src/static/js/collab_client.js @@ -358,6 +358,14 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad) { var userInfo = msg.userInfo; var id = userInfo.userId; + + // Avoid a race condition when setting colors. If our color was set by a + // query param, ignore our own "new user" message's color value. + if (id === initialUserInfo.userId && initialUserInfo.globalUserColor) + { + msg.userInfo.colorId = initialUserInfo.globalUserColor; + } + if (userSet[id]) { diff --git a/src/static/js/pad.js b/src/static/js/pad.js index 737f5dc62..8f8e8729e 100644 --- a/src/static/js/pad.js +++ b/src/static/js/pad.js @@ -114,6 +114,7 @@ function getParams() var showControls = params["showControls"]; var showChat = params["showChat"]; var userName = params["userName"]; + var userColor = params["userColor"]; var showLineNumbers = params["showLineNumbers"]; var useMonospaceFont = params["useMonospaceFont"]; var IsnoColors = params["noColors"]; @@ -162,6 +163,11 @@ function getParams() // If the username is set as a parameter we should set a global value that we can call once we have initiated the pad. settings.globalUserName = decodeURIComponent(userName); } + if(userColor) + // If the userColor is set as a parameter, set a global value to use once we have initiated hte pad. + { + settings.globalUserColor = decodeURIComponent(userColor); + } if(rtl) { if(rtl == "true") @@ -363,6 +369,24 @@ function handshake() pad.myUserInfo.name = settings.globalUserName; $('#myusernameedit').attr({"value":settings.globalUserName}); // Updates the current users UI } + if (settings.globalUserColor !== false) + { + // First, check the color to ensure it's a valid css color value. + var check = $("").css("background-color", "white"); + $("body").append(check); + var white = check.css("background-color"); + check.css("background-color", settings.globalUserColor); + // Ensure that setting the element changed the color. + if (check.css("background-color") === white) { + settings.globalUserColor = "#ff0000"; + } + check.remove(); + + // Add a 'globalUserColor' property to myUserInfo, so collabClient knows we have a query parameter. + pad.myUserInfo.globalUserColor = settings.globalUserColor; + pad.notifyChangeColor(settings.globalUserColor); // Updates pad.myUserInfo.colorId + paduserlist.setMyUserInfo(pad.myUserInfo); + } } //This handles every Message after the clientVars else @@ -1025,6 +1049,7 @@ var settings = { , noColors: false , useMonospaceFontGlobal: false , globalUserName: false +, globalUserColor: false , rtlIsTrue: false }; From bc6e495e8c691a3e3ce047b1dbe8ba600ef49eef Mon Sep 17 00:00:00 2001 From: Charlie DeTar Date: Mon, 17 Sep 2012 00:19:57 -0400 Subject: [PATCH 04/51] Use 'transparent' as reference to validate css Use 'transparent' instead of 'white' as a reference color for validating CSS color values. Presumably, a user setting a userColor wants some color other than 'transparent' if they are setting it (they could always duplicate the background's color if not). --- src/static/js/pad.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/static/js/pad.js b/src/static/js/pad.js index 8f8e8729e..3e2663c89 100644 --- a/src/static/js/pad.js +++ b/src/static/js/pad.js @@ -164,7 +164,7 @@ function getParams() settings.globalUserName = decodeURIComponent(userName); } if(userColor) - // If the userColor is set as a parameter, set a global value to use once we have initiated hte pad. + // If the userColor is set as a parameter, set a global value to use once we have initiated the pad. { settings.globalUserColor = decodeURIComponent(userColor); } @@ -372,12 +372,12 @@ function handshake() if (settings.globalUserColor !== false) { // First, check the color to ensure it's a valid css color value. - var check = $("").css("background-color", "white"); + var check = $("").css("background-color", "transparent"); $("body").append(check); - var white = check.css("background-color"); + var transparent = check.css("background-color"); check.css("background-color", settings.globalUserColor); // Ensure that setting the element changed the color. - if (check.css("background-color") === white) { + if (check.css("background-color") === transparent) { settings.globalUserColor = "#ff0000"; } check.remove(); From 53113644a0464929316be67ea878d47d13714aba Mon Sep 17 00:00:00 2001 From: Charlie DeTar Date: Mon, 17 Sep 2012 10:59:12 -0400 Subject: [PATCH 05/51] Require userColor to be valid css hex The utility functions colorutils.js assume that background colors are in CSS hex format, so require userColor to do the same, rather than allowing inputs like "red" and "rgba(...)", to insure that inversion checks will succeed. --- src/static/js/colorutils.js | 7 +++++++ src/static/js/pad.js | 13 ++----------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/static/js/colorutils.js b/src/static/js/colorutils.js index 5fbefb4df..74a2e4635 100644 --- a/src/static/js/colorutils.js +++ b/src/static/js/colorutils.js @@ -24,6 +24,13 @@ var colorutils = {}; +// Check that a given value is a css hex color value, e.g. +// "#ffffff" or "#fff" +colorutils.isCssHex = function(cssColor) +{ + return /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(cssColor); +} + // "#ffffff" or "#fff" or "ffffff" or "fff" to [1.0, 1.0, 1.0] colorutils.css2triple = function(cssColor) { diff --git a/src/static/js/pad.js b/src/static/js/pad.js index 3e2663c89..21dea4409 100644 --- a/src/static/js/pad.js +++ b/src/static/js/pad.js @@ -43,6 +43,7 @@ var padmodals = require('./pad_modals').padmodals; var padsavedrevs = require('./pad_savedrevs'); var paduserlist = require('./pad_userlist').paduserlist; var padutils = require('./pad_utils').padutils; +var colorutils = require('./colorutils').colorutils; var createCookie = require('./pad_utils').createCookie; var readCookie = require('./pad_utils').readCookie; @@ -369,18 +370,8 @@ function handshake() pad.myUserInfo.name = settings.globalUserName; $('#myusernameedit').attr({"value":settings.globalUserName}); // Updates the current users UI } - if (settings.globalUserColor !== false) + if (settings.globalUserColor !== false && colorutils.isCssHex(settings.globalUserColor)) { - // First, check the color to ensure it's a valid css color value. - var check = $("").css("background-color", "transparent"); - $("body").append(check); - var transparent = check.css("background-color"); - check.css("background-color", settings.globalUserColor); - // Ensure that setting the element changed the color. - if (check.css("background-color") === transparent) { - settings.globalUserColor = "#ff0000"; - } - check.remove(); // Add a 'globalUserColor' property to myUserInfo, so collabClient knows we have a query parameter. pad.myUserInfo.globalUserColor = settings.globalUserColor; From 4416210471e1964d7c30babc354e0e03d1cc00ca Mon Sep 17 00:00:00 2001 From: Marcel Klehr Date: Fri, 21 Sep 2012 17:12:22 +0200 Subject: [PATCH 06/51] Differentiate between http server and express app --- doc/api/hooks_server-side.md | 3 ++- src/node/hooks/express.js | 12 +++++++----- src/node/hooks/express/socketio.js | 4 ++-- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/doc/api/hooks_server-side.md b/doc/api/hooks_server-side.md index 518e12130..0bcd85a3b 100644 --- a/doc/api/hooks_server-side.md +++ b/doc/api/hooks_server-side.md @@ -54,7 +54,8 @@ Called from: src/node/server.js Things in context: -1. app - the main application object (helpful for adding new paths and such) +1. app - the main express application object (helpful for adding new paths and such) +1. server - the http server object This hook gets called after the application object has been created, but before it starts listening. This is similar to the expressConfigure hook, but it's not guaranteed that the application object will have all relevant configuration variables. diff --git a/src/node/hooks/express.js b/src/node/hooks/express.js index e4ff40d96..eb3f6188a 100644 --- a/src/node/hooks/express.js +++ b/src/node/hooks/express.js @@ -1,4 +1,5 @@ var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks"); +var http = require('http'); var express = require('express'); var settings = require('../utils/Settings'); var fs = require('fs'); @@ -48,17 +49,18 @@ exports.restartServer = function () { server.close(); } - server = express(); // New syntax for express v3 + var app = express(); // New syntax for express v3 + server = http.createServer(app); - server.use(function (req, res, next) { + app.use(function (req, res, next) { res.header("Server", serverName); next(); }); - server.configure(function() { - hooks.callAll("expressConfigure", {"app": server}); + app.configure(function() { + hooks.callAll("expressConfigure", {"app": app}); }); - hooks.callAll("expressCreateServer", {"app": server}); + 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 4f780cb0b..9e1a010fc 100644 --- a/src/node/hooks/express/socketio.js +++ b/src/node/hooks/express/socketio.js @@ -10,7 +10,7 @@ var connect = require('connect'); exports.expressCreateServer = function (hook_name, args, cb) { //init socket.io and redirect all requests to the MessageHandler - var io = socketio.listen(args.app); + var io = socketio.listen(args.server); /* Require an express session cookie to be present, and load the * session. See http://www.danielbaulig.de/socket-ioexpress for more @@ -62,5 +62,5 @@ exports.expressCreateServer = function (hook_name, args, cb) { socketIORouter.setSocketIO(io); socketIORouter.addComponent("pad", padMessageHandler); - hooks.callAll("socketio", {"app": args.app, "io": io}); + hooks.callAll("socketio", {"app": args.app, "io": io, "server": args.server}); } From ff7cf991c9f6bb6b7d1c9f9d1bd0963050170bb8 Mon Sep 17 00:00:00 2001 From: Marcel Klehr Date: Fri, 21 Sep 2012 21:39:08 +0200 Subject: [PATCH 07/51] Upgrade log4js to v0.5 --- src/node/hooks/express/webaccess.js | 1 + src/node/server.js | 10 +++++++--- src/package.json | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/node/hooks/express/webaccess.js b/src/node/hooks/express/webaccess.js index ffced0476..a6a270c02 100644 --- a/src/node/hooks/express/webaccess.js +++ b/src/node/hooks/express/webaccess.js @@ -95,6 +95,7 @@ exports.expressConfigure = function (hook_name, args, cb) { // Not installing the log4js connect logger when the log level has a higher severity than INFO since it would not log at that level anyway. if (!(settings.loglevel === "WARN" || settings.loglevel == "ERROR")) args.app.use(log4js.connectLogger(httpLogger, { level: log4js.levels.INFO, format: ':status, :method :url'})); + args.app.use(express.cookieParser()); /* Do not let express create the session, so that we can retain a diff --git a/src/node/server.js b/src/node/server.js index cca76c1f9..b91b0e17c 100755 --- a/src/node/server.js +++ b/src/node/server.js @@ -21,8 +21,15 @@ * limitations under the License. */ +// set up logger var log4js = require('log4js'); +log4js.replaceConsole(); + var settings = require('./utils/Settings'); + +//set loglevel +log4js.setGlobalLogLevel(settings.loglevel); + var db = require('./db/DB'); var async = require('async'); var plugins = require("ep_etherpad-lite/static/js/pluginfw/plugins"); @@ -31,9 +38,6 @@ var npm = require("npm/lib/npm.js"); hooks.plugins = plugins; -//set loglevel -log4js.setGlobalLogLevel(settings.loglevel); - async.waterfall([ //initalize the database function (callback) diff --git a/src/package.json b/src/package.json index a7550faed..bee732058 100644 --- a/src/package.json +++ b/src/package.json @@ -22,7 +22,7 @@ "clean-css" : "0.3.2", "uglify-js" : "1.2.5", "formidable" : "1.0.9", - "log4js" : "0.4.1", + "log4js" : "0.5.x", "jsdom-nocontextifiy" : "0.2.10", "async-stacktrace" : "0.0.2", "npm" : "1.1.24", From 71579d14783aa0f020664353f6596142dddfb069 Mon Sep 17 00:00:00 2001 From: Marcel Klehr Date: Sat, 22 Sep 2012 13:51:39 +0200 Subject: [PATCH 08/51] Fix res.send (migrate to express v3) --- src/node/hooks/express/adminplugins.js | 8 ++------ src/node/hooks/express/padreadonly.js | 2 +- src/node/hooks/express/padurlsanitize.js | 4 ++-- src/node/hooks/express/webaccess.js | 4 ++-- src/node/padaccess.js | 2 +- 5 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/node/hooks/express/adminplugins.js b/src/node/hooks/express/adminplugins.js index fc274a075..97a0d602f 100644 --- a/src/node/hooks/express/adminplugins.js +++ b/src/node/hooks/express/adminplugins.js @@ -12,14 +12,10 @@ exports.expressCreateServer = function (hook_name, args, cb) { errors: [], }; - res.send(eejs.require( - "ep_etherpad-lite/templates/admin/plugins.html", - render_args), {}); + res.send( eejs.require("ep_etherpad-lite/templates/admin/plugins.html", render_args) ); }); args.app.get('/admin/plugins/info', function(req, res) { - res.send(eejs.require( - "ep_etherpad-lite/templates/admin/plugins-info.html", - {}), {}); + res.send( eejs.require("ep_etherpad-lite/templates/admin/plugins-info.html", {}) ); }); } diff --git a/src/node/hooks/express/padreadonly.js b/src/node/hooks/express/padreadonly.js index 60ece0add..af5cbed39 100644 --- a/src/node/hooks/express/padreadonly.js +++ b/src/node/hooks/express/padreadonly.js @@ -56,7 +56,7 @@ exports.expressCreateServer = function (hook_name, args, cb) { ERR(err); if(err == "notfound") - res.send('404 - Not Found', 404); + res.send(404, '404 - Not Found'); else res.send(html); }); diff --git a/src/node/hooks/express/padurlsanitize.js b/src/node/hooks/express/padurlsanitize.js index 24ec2c3d0..29782b692 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('Such a padname is forbidden', 404); + res.send(404, '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('You should be redirected to ' + real_url + '', 302); + res.send(302, 'You should be redirected to ' + real_url + ''); } //the pad id was fine, so just render it else diff --git a/src/node/hooks/express/webaccess.js b/src/node/hooks/express/webaccess.js index a6a270c02..99971206e 100644 --- a/src/node/hooks/express/webaccess.js +++ b/src/node/hooks/express/webaccess.js @@ -56,10 +56,10 @@ exports.basicAuth = function (req, res, next) { res.header('WWW-Authenticate', 'Basic realm="Protected Area"'); if (req.headers.authorization) { setTimeout(function () { - res.send('Authentication required', 401); + res.send(401, 'Authentication required'); }, 1000); } else { - res.send('Authentication required', 401); + res.send(401, 'Authentication required'); } })); } diff --git a/src/node/padaccess.js b/src/node/padaccess.js index a3d1df332..4388ab946 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 - Can't touch this", 403); + res.send(403, "403 - Can't touch this"); } }); } From 794c3d1afe9616fdd611fc8cc8f1c0131998a6a2 Mon Sep 17 00:00:00 2001 From: Marcel Klehr Date: Sat, 22 Sep 2012 14:05:41 +0200 Subject: [PATCH 09/51] Set secret on cookieParser (migrate to express v3) --- src/node/hooks/express/webaccess.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/node/hooks/express/webaccess.js b/src/node/hooks/express/webaccess.js index 99971206e..28cb649e4 100644 --- a/src/node/hooks/express/webaccess.js +++ b/src/node/hooks/express/webaccess.js @@ -95,8 +95,6 @@ exports.expressConfigure = function (hook_name, args, cb) { // Not installing the log4js connect logger when the log level has a higher severity than INFO since it would not log at that level anyway. if (!(settings.loglevel === "WARN" || settings.loglevel == "ERROR")) args.app.use(log4js.connectLogger(httpLogger, { level: log4js.levels.INFO, format: ':status, :method :url'})); - - args.app.use(express.cookieParser()); /* Do not let express create the session, so that we can retain a * reference to it for socket.io to use. Also, set the key (cookie @@ -107,11 +105,12 @@ exports.expressConfigure = function (hook_name, args, cb) { exports.sessionStore = new express.session.MemoryStore(); secret = randomString(32); } + + args.app.use(express.cookieParser(secret)); args.app.sessionStore = exports.sessionStore; args.app.use(express.session({store: args.app.sessionStore, - key: 'express_sid', - secret: secret})); + key: 'express_sid' })); args.app.use(exports.basicAuth); } From 0f436d5916807cde879617c85a5aea18b98ae1d4 Mon Sep 17 00:00:00 2001 From: Marcel Klehr Date: Sat, 22 Sep 2012 15:22:15 +0200 Subject: [PATCH 10/51] Migrate error handling middleware to express v3 --- src/node/hooks/express/errorhandling.js | 26 +++++-------------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/src/node/hooks/express/errorhandling.js b/src/node/hooks/express/errorhandling.js index 3c5727ed4..749b04273 100644 --- a/src/node/hooks/express/errorhandling.js +++ b/src/node/hooks/express/errorhandling.js @@ -32,31 +32,15 @@ exports.gracefulShutdown = function(err) { exports.expressCreateServer = function (hook_name, args, cb) { exports.app = args.app; - - -/* - Below breaks Express 3, commented out to allow express 3o to run. For mroe details see: - https://github.com/visionmedia/express/wiki/Migrating-from-2.x-to-3.x -/* -/* - args.app.error(function(err, req, res, next){ - res.send(500); - console.error(err.stack ? err.stack : err.toString()); - exports.gracefulShutdown(); - }); -*/ - - - -// args.app.on('close', function(){ -// console.log("Exited in a sloppy fashion"); -// }) - + // Handle errors args.app.use(function(err, req, res, next){ // 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.send(500, { error: 'Sorry, something bad happened!' }); + console.error(err.stack? err.stack : err.toString()); + exports.gracefulShutdown(); + next(); }) From 0c9c1f514fba98b4333d92ce6a331818ec2ebe97 Mon Sep 17 00:00:00 2001 From: Marcel Klehr Date: Sat, 22 Sep 2012 16:03:40 +0200 Subject: [PATCH 11/51] Fix socket.io auth: Use connect to parse signed cookies (migrate to express v3) --- src/node/hooks/express/socketio.js | 22 ++++++++++++++++------ src/node/hooks/express/webaccess.js | 6 +++--- src/package.json | 2 +- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/node/hooks/express/socketio.js b/src/node/hooks/express/socketio.js index 9e1a010fc..546ba2af6 100644 --- a/src/node/hooks/express/socketio.js +++ b/src/node/hooks/express/socketio.js @@ -3,6 +3,7 @@ var socketio = require('socket.io'); var settings = require('../../utils/Settings'); var socketIORouter = require("../../handler/SocketIORouter"); var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks"); +var webaccess = require("ep_etherpad-lite/node/hooks/express/webaccess"); var padMessageHandler = require("../../handler/PadMessageHandler"); @@ -17,12 +18,21 @@ exports.expressCreateServer = function (hook_name, args, cb) { * info */ io.set('authorization', function (data, accept) { if (!data.headers.cookie) return accept('No session cookie transmitted.', false); - data.cookie = connect.utils.parseCookie(data.headers.cookie); - data.sessionID = data.cookie.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); - accept(null, true); + + // Use connect's cookie parser, because it knows how to parse signed cookies + connect.cookieParser(webaccess.secret)(data, {}, function(err){ + if(err) { + console.error(err); + accept("Couldn't parse request cookies. ", false); + return; + } + + 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); + accept(null, true); + }); }); }); diff --git a/src/node/hooks/express/webaccess.js b/src/node/hooks/express/webaccess.js index 28cb649e4..41bf38805 100644 --- a/src/node/hooks/express/webaccess.js +++ b/src/node/hooks/express/webaccess.js @@ -88,7 +88,7 @@ exports.basicAuth = function (req, res, next) { }); } -var secret = null; +exports.secret = null; exports.expressConfigure = function (hook_name, args, cb) { // If the log level specified in the config file is WARN or ERROR the application server never starts listening to requests as reported in issue #158. @@ -103,10 +103,10 @@ exports.expressConfigure = function (hook_name, args, cb) { if (!exports.sessionStore) { exports.sessionStore = new express.session.MemoryStore(); - secret = randomString(32); + exports.secret = randomString(32); } - args.app.use(express.cookieParser(secret)); + args.app.use(express.cookieParser(exports.secret)); args.app.sessionStore = exports.sessionStore; args.app.use(express.session({store: args.app.sessionStore, diff --git a/src/package.json b/src/package.json index bee732058..67aa1037c 100644 --- a/src/package.json +++ b/src/package.json @@ -18,7 +18,7 @@ "ueberDB" : "0.1.7", "async" : "0.1.x", "express" : "3.x", - "connect" : "1.x", + "connect" : "2.4.x", "clean-css" : "0.3.2", "uglify-js" : "1.2.5", "formidable" : "1.0.9", From 1c38f5bab9a2c78655c9230e0fca0cfb80a7b8f3 Mon Sep 17 00:00:00 2001 From: Marcel Klehr Date: Sat, 22 Sep 2012 16:04:30 +0200 Subject: [PATCH 12/51] Update docs --- doc/api/hooks_server-side.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/api/hooks_server-side.md b/doc/api/hooks_server-side.md index 0bcd85a3b..c60bbe733 100644 --- a/doc/api/hooks_server-side.md +++ b/doc/api/hooks_server-side.md @@ -55,7 +55,7 @@ Called from: src/node/server.js Things in context: 1. app - the main express application object (helpful for adding new paths and such) -1. server - the http server object +2. server - the http server object This hook gets called after the application object has been created, but before it starts listening. This is similar to the expressConfigure hook, but it's not guaranteed that the application object will have all relevant configuration variables. @@ -77,6 +77,7 @@ Things in context: 1. app - the application object 2. io - the socketio object +3. server - the http server object I have no idea what this is useful for, someone else will have to add this description. From 07c33c77c4b41a3181064beacc407565738c4929 Mon Sep 17 00:00:00 2001 From: d-a-n Date: Tue, 2 Oct 2012 22:10:18 +0300 Subject: [PATCH 13/51] Updated docs for new pad hooks (add, edit, remove) --- doc/api/hooks_server-side.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/doc/api/hooks_server-side.md b/doc/api/hooks_server-side.md index 06ec7374b..be5564a66 100644 --- a/doc/api/hooks_server-side.md +++ b/doc/api/hooks_server-side.md @@ -64,6 +64,34 @@ This hook gets called upon the rendering of an ejs template block. For any speci Have a look at `src/templates/pad.html` and `src/templates/timeslider.html` to see which blocks are available. +## padCreated +Called from: src/node/db/Pad.js + +1. pad - the pad instance + +This hook gets called when a new pad was created. + +## padLoaded +Called from: src/node/db/Pad.js + +1. pad - the pad instance + +This hook gets called when an pad was loaded. + +## padUpdated +Called from: src/node/db/Pad.js + +1. pad - the pad instance + +This hook gets called when an existing pad was updated. + +## padRemoved +Called from: src/node/db/Pad.js + +1. pad - the pad instance + +This hook gets called when an existing pad was removed/deleted. + ## socketio Called from: src/node/hooks/express/socketio.js From c0f2e557d36f5b13604fff603ff26d5a9e4d0f64 Mon Sep 17 00:00:00 2001 From: d-a-n Date: Tue, 2 Oct 2012 22:11:54 +0300 Subject: [PATCH 14/51] Updated docs for new pad hooks (add, edit, remove) --- doc/api/hooks_server-side.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/api/hooks_server-side.md b/doc/api/hooks_server-side.md index be5564a66..b6ee1604c 100644 --- a/doc/api/hooks_server-side.md +++ b/doc/api/hooks_server-side.md @@ -67,6 +67,8 @@ Have a look at `src/templates/pad.html` and `src/templates/timeslider.html` to s ## padCreated Called from: src/node/db/Pad.js +Things in context: + 1. pad - the pad instance This hook gets called when a new pad was created. @@ -74,6 +76,8 @@ This hook gets called when a new pad was created. ## padLoaded Called from: src/node/db/Pad.js +Things in context: + 1. pad - the pad instance This hook gets called when an pad was loaded. @@ -81,6 +85,8 @@ This hook gets called when an pad was loaded. ## padUpdated Called from: src/node/db/Pad.js +Things in context: + 1. pad - the pad instance This hook gets called when an existing pad was updated. @@ -88,6 +94,8 @@ This hook gets called when an existing pad was updated. ## padRemoved Called from: src/node/db/Pad.js +Things in context: + 1. pad - the pad instance This hook gets called when an existing pad was removed/deleted. From 64a3d60b943bdf7ae643f3fcb5791ffbc95b77ae Mon Sep 17 00:00:00 2001 From: d-a-n Date: Tue, 2 Oct 2012 22:30:13 +0300 Subject: [PATCH 15/51] Added pad hooks (create, load, edit, remove) --- src/node/db/Pad.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/node/db/Pad.js b/src/node/db/Pad.js index ad2d59f38..cf04f9bc0 100644 --- a/src/node/db/Pad.js +++ b/src/node/db/Pad.js @@ -16,6 +16,7 @@ var padMessageHandler = require("../handler/PadMessageHandler"); var readOnlyManager = require("./ReadOnlyManager"); var crypto = require("crypto"); var randomString = require("../utils/randomstring"); +var hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks'); //serialization/deserialization attributes var attributeBlackList = ["id"]; @@ -86,6 +87,12 @@ Pad.prototype.appendRevision = function appendRevision(aChangeset, author) { // set the author to pad if(author) authorManager.addPad(author, this.id); + + if (this.head == 0) { + hooks.callAll("padCreated", this); + } else { + hooks.callAll("padUpdated", this); + } }; //save all attributes to the database @@ -368,6 +375,7 @@ Pad.prototype.init = function init(text, callback) { _this.appendRevision(firstChangeset, ''); } + hooks.callAll("padLoaded", _this); callback(null); }); }; @@ -467,6 +475,7 @@ Pad.prototype.remove = function remove(callback) { { db.remove("pad:"+padID); padManager.unloadPad(padID); + hooks.callAll("padRemoved", padID ); callback(); } ], function(err) From 4652751285ed4c4788442910574350f163f51ca9 Mon Sep 17 00:00:00 2001 From: d-a-n Date: Tue, 2 Oct 2012 22:32:30 +0300 Subject: [PATCH 16/51] Updated docs for new pad hooks (add, edit, remove) --- doc/api/hooks_server-side.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/hooks_server-side.md b/doc/api/hooks_server-side.md index b6ee1604c..84ca44904 100644 --- a/doc/api/hooks_server-side.md +++ b/doc/api/hooks_server-side.md @@ -96,7 +96,7 @@ Called from: src/node/db/Pad.js Things in context: -1. pad - the pad instance +1. pad id This hook gets called when an existing pad was removed/deleted. From 85b44119aee2339856a2fccadef99f9629f68895 Mon Sep 17 00:00:00 2001 From: Richard Braakman Date: Tue, 2 Oct 2012 23:27:30 +0300 Subject: [PATCH 17/51] USERINFO_UPDATE: construct a new message for broadcast The server was reusing the client's message when broadcasting userinfo updates. This would allow a malicious client to insert arbitrary fields into a message that the other clients would trust as coming from the server. For example, adding "disconnect" or renaming other authors. This commit fixes it by having the server construct a new message with known fields before broadcasting. --- src/node/handler/PadMessageHandler.js | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/node/handler/PadMessageHandler.js b/src/node/handler/PadMessageHandler.js index 10b259ae2..28797a3ac 100644 --- a/src/node/handler/PadMessageHandler.js +++ b/src/node/handler/PadMessageHandler.js @@ -415,22 +415,34 @@ function handleUserInfoUpdate(client, message) authorManager.setAuthorName(author, message.data.userInfo.name); var padId = sessioninfos[client.id].padId; + + var infoMsg = { + type: "COLLABROOM", + data: { + // The Client doesn't know about USERINFO_UPDATE, use USER_NEWINFO + type: "USER_NEWINFO", + userInfo: { + userId: author, + name: message.data.userInfo.name, + colorId: message.data.userInfo.colorId, + userAgent: "Anonymous", + ip: "127.0.0.1", + } + } + }; //set a null name, when there is no name set. cause the client wants it null - if(message.data.userInfo.name == null) + if(infoMsg.data.userInfo.name == null) { - message.data.userInfo.name = null; + infoMsg.data.userInfo.name = null; } - //The Client don't know about a USERINFO_UPDATE, it can handle only new user_newinfo, so change the message type - message.data.type = "USER_NEWINFO"; - //Send the other clients on the pad the update message for(var i in pad2sessions[padId]) { if(pad2sessions[padId][i] != client.id) { - socketio.sockets.sockets[pad2sessions[padId][i]].json.send(message); + socketio.sockets.sockets[pad2sessions[padId][i]].json.send(infoMsg); } } } From 754c559d632c08be58f06c3eedb3a9494c51dedf Mon Sep 17 00:00:00 2001 From: d-a-n Date: Wed, 3 Oct 2012 13:35:31 +0300 Subject: [PATCH 18/51] Changed pad hook names to follow naming conventions. --- doc/api/hooks_server-side.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/api/hooks_server-side.md b/doc/api/hooks_server-side.md index 84ca44904..bc56f19bb 100644 --- a/doc/api/hooks_server-side.md +++ b/doc/api/hooks_server-side.md @@ -64,7 +64,7 @@ This hook gets called upon the rendering of an ejs template block. For any speci Have a look at `src/templates/pad.html` and `src/templates/timeslider.html` to see which blocks are available. -## padCreated +## padCreate Called from: src/node/db/Pad.js Things in context: @@ -73,16 +73,16 @@ Things in context: This hook gets called when a new pad was created. -## padLoaded +## padLoad Called from: src/node/db/Pad.js Things in context: 1. pad - the pad instance -This hook gets called when an pad was loaded. +This hook gets called when an pad was loaded. If a new pad was created and loaded this event will be emitted too. -## padUpdated +## padUpdate Called from: src/node/db/Pad.js Things in context: @@ -91,7 +91,7 @@ Things in context: This hook gets called when an existing pad was updated. -## padRemoved +## padRemove Called from: src/node/db/Pad.js Things in context: From 358e4817310eceec8df664f3c428ba0afdc430dc Mon Sep 17 00:00:00 2001 From: d-a-n Date: Wed, 3 Oct 2012 13:41:40 +0300 Subject: [PATCH 19/51] Changed pad hook names to follow naming conventions. Arguments will now be passed as hash. --- src/node/db/Pad.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/node/db/Pad.js b/src/node/db/Pad.js index cf04f9bc0..d6ea8277d 100644 --- a/src/node/db/Pad.js +++ b/src/node/db/Pad.js @@ -89,9 +89,9 @@ Pad.prototype.appendRevision = function appendRevision(aChangeset, author) { authorManager.addPad(author, this.id); if (this.head == 0) { - hooks.callAll("padCreated", this); + hooks.callAll("padCreate", {'pad':this}); } else { - hooks.callAll("padUpdated", this); + hooks.callAll("padUpdate", {'pad':this}); } }; @@ -375,7 +375,7 @@ Pad.prototype.init = function init(text, callback) { _this.appendRevision(firstChangeset, ''); } - hooks.callAll("padLoaded", _this); + hooks.callAll("padLoad", {'pad':_this}); callback(null); }); }; @@ -475,7 +475,7 @@ Pad.prototype.remove = function remove(callback) { { db.remove("pad:"+padID); padManager.unloadPad(padID); - hooks.callAll("padRemoved", padID ); + hooks.callAll("padRemove", {'pad_id':padID}); callback(); } ], function(err) From 0fd8490ca6e3f2218c9ab16bf722725d173caa34 Mon Sep 17 00:00:00 2001 From: d-a-n Date: Wed, 3 Oct 2012 15:49:28 +0300 Subject: [PATCH 20/51] Changed pad_id to padID to follow projct standards. --- doc/api/hooks_server-side.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/hooks_server-side.md b/doc/api/hooks_server-side.md index bc56f19bb..49eb6cc5f 100644 --- a/doc/api/hooks_server-side.md +++ b/doc/api/hooks_server-side.md @@ -96,7 +96,7 @@ Called from: src/node/db/Pad.js Things in context: -1. pad id +1. padID This hook gets called when an existing pad was removed/deleted. From a521a125830a18213d71991d55c5d04269c5ee94 Mon Sep 17 00:00:00 2001 From: d-a-n Date: Wed, 3 Oct 2012 15:50:43 +0300 Subject: [PATCH 21/51] Changed pad_id to padID to follow projct standards. --- src/node/db/Pad.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node/db/Pad.js b/src/node/db/Pad.js index d6ea8277d..dba791fd2 100644 --- a/src/node/db/Pad.js +++ b/src/node/db/Pad.js @@ -475,7 +475,7 @@ Pad.prototype.remove = function remove(callback) { { db.remove("pad:"+padID); padManager.unloadPad(padID); - hooks.callAll("padRemove", {'pad_id':padID}); + hooks.callAll("padRemove", {'padID':padID}); callback(); } ], function(err) From a97c63b80955e9b2e960f12b4f0f075ca629fd1d Mon Sep 17 00:00:00 2001 From: johnyma22 Date: Thu, 4 Oct 2012 18:53:02 +0100 Subject: [PATCH 22/51] Fix issue caused by broken async update --- src/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/package.json b/src/package.json index 5f981a7b8..f729b3c16 100644 --- a/src/package.json +++ b/src/package.json @@ -16,7 +16,7 @@ "resolve" : "0.2.x", "socket.io" : "0.9.x", "ueberDB" : "0.1.7", - "async" : "0.1.x", + "async" : "0.1.22", "express" : "3.x", "connect" : "2.4.x", "clean-css" : "0.3.2", From 90373964d31c61013fff941459c84688170636a8 Mon Sep 17 00:00:00 2001 From: John McLear Date: Sat, 6 Oct 2012 02:36:51 +0200 Subject: [PATCH 23/51] Remove two instances of the same function name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both functions did the same thing, the first function was buggy.  Might be worth someone looking through the history of this file and pointing out when I made this heinous error ;) --- src/node/db/AuthorManager.js | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/node/db/AuthorManager.js b/src/node/db/AuthorManager.js index 2a6625c85..28b2dd91e 100644 --- a/src/node/db/AuthorManager.js +++ b/src/node/db/AuthorManager.js @@ -141,22 +141,6 @@ exports.getAuthor = function (author, callback) db.get("globalAuthor:" + author, callback); } -/** - * Returns the Author Name of the author - * @param {String} author The id of the author - * @param {Function} callback callback(err, name) - */ - -exports.getAuthorName = function (authorID, callback) -{ - db.getSub("globalAuthor:" + author, ["name"], callback); - console.log(authorID); - db.getSub("globalAuthor:" + authorID, ["name"], function(err, authorName){ - if(ERR(err, callback)) return; - callback(null, {authorName: authorName}); - }); -} - /** From 9d1274abafb1887c2d4c7586946954e6e6532347 Mon Sep 17 00:00:00 2001 From: Chad Weider Date: Tue, 9 Oct 2012 01:32:21 -0700 Subject: [PATCH 24/51] Drop method deprecated in Express 3.x. --- src/node/utils/caching_middleware.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node/utils/caching_middleware.js b/src/node/utils/caching_middleware.js index 1f5336733..c6b237139 100644 --- a/src/node/utils/caching_middleware.js +++ b/src/node/utils/caching_middleware.js @@ -48,7 +48,7 @@ CachingMiddleware.prototype = new function () { var old_res = {}; var supportsGzip = - req.header('Accept-Encoding', '').indexOf('gzip') != -1; + (req.get('Accept-Encoding') || '').indexOf('gzip') != -1; var path = require('url').parse(req.url).path; var cacheKey = (new Buffer(path)).toString('base64').replace(/[\/\+=]/g, ''); From 0fa954c1a0d2a7e2c6c1d3dcc9987889857f77d9 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Thu, 11 Oct 2012 17:51:57 +0400 Subject: [PATCH 25/51] fixed variable name in handleMessageHook the code would never work as expected with this type --- src/node/handler/PadMessageHandler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node/handler/PadMessageHandler.js b/src/node/handler/PadMessageHandler.js index 10b259ae2..831acdbbf 100644 --- a/src/node/handler/PadMessageHandler.js +++ b/src/node/handler/PadMessageHandler.js @@ -178,7 +178,7 @@ exports.handleMessage = function(client, message) // handleMessage will be called, even if the client is not authorized hooks.aCallAll("handleMessage", { client: client, message: message }, function ( messages ) { _.each(messages, function(newMessage){ - if ( newmessage === null ) { + if ( newMessage === null ) { dropMessage = true; } }); From dbcdc2f956172d4d0c89424ff5114c57b71cb4e3 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Thu, 11 Oct 2012 18:07:45 +0400 Subject: [PATCH 26/51] fix for error handling in callback code The callback code does not follow error handling guidelines, thus always receiving NULL instead of results array. --- src/node/handler/PadMessageHandler.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/node/handler/PadMessageHandler.js b/src/node/handler/PadMessageHandler.js index 831acdbbf..b889a8a03 100644 --- a/src/node/handler/PadMessageHandler.js +++ b/src/node/handler/PadMessageHandler.js @@ -176,7 +176,9 @@ exports.handleMessage = function(client, message) // Call handleMessage hook. If a plugin returns null, the message will be dropped. Note that for all messages // handleMessage will be called, even if the client is not authorized - hooks.aCallAll("handleMessage", { client: client, message: message }, function ( messages ) { + hooks.aCallAll("handleMessage", { client: client, message: message }, function ( err, messages ) { + if(ERR(err, callback)) return; + _.each(messages, function(newMessage){ if ( newMessage === null ) { dropMessage = true; From 957a0aa873f2df13483a9b17589c064cc229a80a Mon Sep 17 00:00:00 2001 From: "NAGOYA, Yoshihiko" Date: Thu, 11 Oct 2012 23:39:01 +0900 Subject: [PATCH 27/51] fix Pita/etherpad-lite #1032 refact inInternationalComposition --- src/static/js/ace.js | 5 +++++ src/static/js/ace2_inner.js | 21 ++++++++++++++++++--- src/static/js/collab_client.js | 4 ++-- src/static/js/pad.js | 16 ---------------- 4 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/static/js/ace.js b/src/static/js/ace.js index e50f75c76..83ad9447b 100644 --- a/src/static/js/ace.js +++ b/src/static/js/ace.js @@ -122,6 +122,11 @@ function Ace2Editor() return info.ace_getDebugProperty(prop); }; + editor.getInInternationalComposition = function() + { + return info.ace_getInInternationalComposition(); + }; + // prepareUserChangeset: // Returns null if no new changes or ACE not ready. Otherwise, bundles up all user changes // to the latest base text into a Changeset, which is returned (as a string if encodeAsString). diff --git a/src/static/js/ace2_inner.js b/src/static/js/ace2_inner.js index 652a3d259..2e56b950f 100644 --- a/src/static/js/ace2_inner.js +++ b/src/static/js/ace2_inner.js @@ -1173,7 +1173,7 @@ function Ace2Inner(){ //if (! top.BEFORE) top.BEFORE = []; //top.BEFORE.push(magicdom.root.dom.innerHTML); //if (! isEditable) return; // and don't reschedule - if (window.parent.parent.inInternationalComposition) + if (inInternationalComposition) { // don't do idle input incorporation during international input composition idleWorkTimer.atLeast(500); @@ -3729,7 +3729,7 @@ function Ace2Inner(){ thisKeyDoesntTriggerNormalize = true; } - if ((!specialHandled) && (!thisKeyDoesntTriggerNormalize) && (!window.parent.parent.inInternationalComposition)) + if ((!specialHandled) && (!thisKeyDoesntTriggerNormalize) && (!inInternationalComposition)) { if (type != "keyup" || !incorpIfQuick()) { @@ -4589,9 +4589,24 @@ function Ace2Inner(){ } } + + var inInternationalComposition = false; function handleCompositionEvent(evt) { - window.parent.parent.handleCompositionEvent(evt); + // international input events, fired in FF3, at least; allow e.g. Japanese input + if (evt.type == "compositionstart") + { + inInternationalComposition = true; + } + else if (evt.type == "compositionend") + { + inInternationalComposition = false; + } + } + + editorInfo.ace_getInInternationalComposition = function () + { + return inInternationalComposition; } function bindTheEventHandlers() diff --git a/src/static/js/collab_client.js b/src/static/js/collab_client.js index b3e17c256..b700fc490 100644 --- a/src/static/js/collab_client.js +++ b/src/static/js/collab_client.js @@ -111,7 +111,7 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad) function handleUserChanges() { - if (window.parent.parent.inInternationalComposition) return; + if (editor.getInInternationalComposition()) return; if ((!getSocket()) || channelState == "CONNECTING") { if (channelState == "CONNECTING" && (((+new Date()) - initialStartConnectTime) > 20000)) @@ -288,7 +288,7 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad) var apool = msg.apool; // When inInternationalComposition, msg pushed msgQueue. - if (msgQueue.length > 0 || window.parent.parent.inInternationalComposition) { + if (msgQueue.length > 0 || editor.getInInternationalComposition()) { if (msgQueue.length > 0) oldRev = msgQueue[msgQueue.length - 1].newRev; else oldRev = rev; diff --git a/src/static/js/pad.js b/src/static/js/pad.js index 21dea4409..897770405 100644 --- a/src/static/js/pad.js +++ b/src/static/js/pad.js @@ -51,22 +51,6 @@ var randomString = require('./pad_utils').randomString; var hooks = require('./pluginfw/hooks'); -window.inInternationalComposition = false; -var inInternationalComposition = window.inInternationalComposition; - -window.handleCompositionEvent = function handleCompositionEvent(evt) - { - // international input events, fired in FF3, at least; allow e.g. Japanese input - if (evt.type == "compositionstart") - { - this.inInternationalComposition = true; - } - else if (evt.type == "compositionend") - { - this.inInternationalComposition = false; - } - } - function createCookie(name, value, days, path) { if (days) From c45739becb27d5031cd8983c4fcce8f3a5b98e1b Mon Sep 17 00:00:00 2001 From: John McLear Date: Thu, 11 Oct 2012 23:38:56 +0200 Subject: [PATCH 28/51] Update src/package.json Bump version # --- src/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/package.json b/src/package.json index f729b3c16..c5a4d0aa9 100644 --- a/src/package.json +++ b/src/package.json @@ -42,5 +42,5 @@ "engines" : { "node" : ">=0.6.0", "npm" : ">=1.0" }, - "version" : "1.1.2" + "version" : "1.1.4" } From b7d0751b185cd55e74390a87353b7df02640090d Mon Sep 17 00:00:00 2001 From: John McLear Date: Mon, 15 Oct 2012 13:09:55 +0200 Subject: [PATCH 29/51] couch, level, mongo, postgres, redis DB support Support for additional underlying databases --- src/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/package.json b/src/package.json index c5a4d0aa9..504b88c20 100644 --- a/src/package.json +++ b/src/package.json @@ -15,7 +15,7 @@ "require-kernel" : "1.0.5", "resolve" : "0.2.x", "socket.io" : "0.9.x", - "ueberDB" : "0.1.7", + "ueberDB" : "0.1.8", "async" : "0.1.22", "express" : "3.x", "connect" : "2.4.x", From 6c89187f952ee248ff78c3ab9b3cbf4a78ae9e9f Mon Sep 17 00:00:00 2001 From: Marcel Klehr Date: Tue, 16 Oct 2012 20:46:27 +0200 Subject: [PATCH 30/51] Fix #1067 Corrected exports links regexp --- src/static/js/timeslider.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/static/js/timeslider.js b/src/static/js/timeslider.js index e630bde0e..a2156b16b 100644 --- a/src/static/js/timeslider.js +++ b/src/static/js/timeslider.js @@ -144,13 +144,12 @@ function handleClientVars(message) require('./pad_impexp').padimpexp.init(); //change export urls when the slider moves - var export_rev_regex = /(\/\d+)?\/export/ BroadcastSlider.onSlider(function(revno) { // export_links is a jQuery Array, so .each is allowed. export_links.each(function() { - this.setAttribute('href', this.href.replace(export_rev_regex, '/' + revno + '/export')); + this.setAttribute('href', this.href.replace( /(.+?)\/\w+\/(\d+\/)?export/ , '$1/' + padId + '/' + revno + '/export')); }); }); From a770910a3a7285be3e45a16255b078051c5afa26 Mon Sep 17 00:00:00 2001 From: johnyma22 Date: Wed, 17 Oct 2012 17:53:28 +0100 Subject: [PATCH 31/51] Add LibreJS Licensing information to headers of HTML templates --- src/templates/index.html | 23 +++++++++++++++++++++++ src/templates/pad.html | 24 +++++++++++++++++++++++- src/templates/timeslider.html | 27 ++++++++++++++++++++++++--- 3 files changed, 70 insertions(+), 4 deletions(-) diff --git a/src/templates/index.html b/src/templates/index.html index 4a45d6a54..a6e5123fa 100644 --- a/src/templates/index.html +++ b/src/templates/index.html @@ -2,6 +2,29 @@ Etherpad Lite + diff --git a/src/templates/pad.html b/src/templates/pad.html index 425e476d8..5cbae7aa5 100644 --- a/src/templates/pad.html +++ b/src/templates/pad.html @@ -3,8 +3,30 @@ %> - Etherpad Lite + diff --git a/src/templates/timeslider.html b/src/templates/timeslider.html index 469ddd94e..bc3c176be 100644 --- a/src/templates/timeslider.html +++ b/src/templates/timeslider.html @@ -1,11 +1,32 @@ +Etherpad Lite Timeslider + - - Etherpad Lite Timeslider - From 8199bf8377a110168a23dab1b8b074b722d18ffe Mon Sep 17 00:00:00 2001 From: Chia-liang Kao Date: Tue, 23 Oct 2012 15:21:05 +0800 Subject: [PATCH 32/51] Do not assume window object exists --- src/static/js/contentcollector.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/static/js/contentcollector.js b/src/static/js/contentcollector.js index 6a75de43a..dd4fd1e54 100644 --- a/src/static/js/contentcollector.js +++ b/src/static/js/contentcollector.js @@ -311,7 +311,7 @@ function makeContentCollector(collectStyles, browser, apool, domInterface, class ['insertorder', 'first'] ].concat( _.map(state.lineAttributes,function(value,key){ - if (window.console) console.log([key, value]) + if (typeof(window)!= 'undefined' && window.console) console.log([key, value]) return [key, value]; }) ); From 526610e2e7a3d3ec687dc7ea8736081c7d69255b Mon Sep 17 00:00:00 2001 From: neurolit Date: Wed, 24 Oct 2012 19:48:13 +0200 Subject: [PATCH 33/51] =?UTF-8?q?Templates:=20relative=20links=20instead?= =?UTF-8?q?=20of=20absolute=20ones=20for=20/static=20directory=20=E2=80=A6?= =?UTF-8?q?irector?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two links were absolute ("/static/...") instead of relative ("../static"). The image was not loaded with sites behind reverse proxies and subdirectory. --- src/templates/pad.html | 2 +- src/templates/timeslider.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/templates/pad.html b/src/templates/pad.html index 425e476d8..7e19535e5 100644 --- a/src/templates/pad.html +++ b/src/templates/pad.html @@ -233,7 +233,7 @@

Reestablishing connection...

-

+

Opened in another window.

diff --git a/src/templates/timeslider.html b/src/templates/timeslider.html index 469ddd94e..c7defcc00 100644 --- a/src/templates/timeslider.html +++ b/src/templates/timeslider.html @@ -83,7 +83,7 @@

Reestablishing connection...

-

+

Opened in another window.

From cb760aae5287a3cddbff31118194806323939a66 Mon Sep 17 00:00:00 2001 From: 0ip Date: Thu, 25 Oct 2012 14:37:41 +0300 Subject: [PATCH 34/51] Fix broken layout (Chrome Mobile) --- src/templates/index.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/templates/index.html b/src/templates/index.html index 4a45d6a54..b1d34eb4f 100644 --- a/src/templates/index.html +++ b/src/templates/index.html @@ -9,9 +9,11 @@