From dd7894d3c9389a000d11d3a89962d9fcc9c6c44b Mon Sep 17 00:00:00 2001 From: Peter 'Pita' Martischka Date: Fri, 23 Mar 2018 11:17:39 +0000 Subject: [PATCH 01/43] Added a jsonp var checker --- src/node/hooks/express/apicalls.js | 10 +-- src/node/hooks/express/isValidJSONPName.js | 83 ++++++++++++++++++++++ 2 files changed, 88 insertions(+), 5 deletions(-) create mode 100644 src/node/hooks/express/isValidJSONPName.js diff --git a/src/node/hooks/express/apicalls.js b/src/node/hooks/express/apicalls.js index 009a93d7..e07bbb0b 100644 --- a/src/node/hooks/express/apicalls.js +++ b/src/node/hooks/express/apicalls.js @@ -3,7 +3,7 @@ var apiLogger = log4js.getLogger("API"); var clientLogger = log4js.getLogger("client"); var formidable = require('formidable'); var apiHandler = require('../../handler/APIHandler'); -var isVarName = require('is-var-name'); +var isValidJSONPName = require('./isValidJsonPName'); //This is for making an api call, collecting all post information and passing it to the apiHandler var apiCaller = function(req, res, fields) { @@ -19,7 +19,7 @@ var apiCaller = function(req, res, fields) { apiLogger.info("RESPONSE, " + req.params.func + ", " + response); //is this a jsonp call, if yes, add the function call - if(req.query.jsonp && isVarName(req.query.jsonp)) + if(req.query.jsonp && isValidJSONPName.check(req.query.jsonp)) response = req.query.jsonp + "(" + response + ")"; res._____send(response); @@ -46,7 +46,7 @@ exports.expressCreateServer = function (hook_name, args, cb) { //The Etherpad client side sends information about how a disconnect happened args.app.post('/ep/pad/connection-diagnostic-info', function(req, res) { - new formidable.IncomingForm().parse(req, function(err, fields, files) { + new formidable.IncomingForm().parse(req, function(err, fields, files) { clientLogger.info("DIAGNOSTIC-INFO: " + fields.diagnosticInfo); res.end("OK"); }); @@ -54,7 +54,7 @@ exports.expressCreateServer = function (hook_name, args, cb) { //The Etherpad client side sends information about client side javscript errors args.app.post('/jserror', function(req, res) { - new formidable.IncomingForm().parse(req, function(err, fields, files) { + new formidable.IncomingForm().parse(req, function(err, fields, files) { try { var data = JSON.parse(fields.errorInfo) }catch(e){ @@ -64,7 +64,7 @@ exports.expressCreateServer = function (hook_name, args, cb) { res.end("OK"); }); }); - + //Provide a possibility to query the latest available API version args.app.get('/api', function (req, res) { res.json({"currentVersion" : apiHandler.latestApiVersion}); diff --git a/src/node/hooks/express/isValidJSONPName.js b/src/node/hooks/express/isValidJSONPName.js new file mode 100644 index 00000000..47755ef8 --- /dev/null +++ b/src/node/hooks/express/isValidJSONPName.js @@ -0,0 +1,83 @@ +const RESERVED_WORDS = [ + 'abstract', + 'arguments', + 'await', + 'boolean', + 'break', + 'byte', + 'case', + 'catch', + 'char', + 'class', + 'const', + 'continue', + 'debugger', + 'default', + 'delete', + 'do', + 'double', + 'else', + 'enum', + 'eval', + 'export', + 'extends', + 'false', + 'final', + 'finally', + 'float', + 'for', + 'function', + 'goto', + 'if', + 'implements', + 'import', + 'in', + 'instanceof', + 'int', + 'interface', + 'let', + 'long', + 'native', + 'new', + 'null', + 'package', + 'private', + 'protected', + 'public', + 'return', + 'short', + 'static', + 'super', + 'switch', + 'synchronized', + 'this', + 'throw', + 'throws', + 'transient', + 'true', + 'try', + 'typeof', + 'var', + 'void', + 'volatile', + 'while', + 'with', + 'yield' +]; + +const regex = /^[a-zA-Z_$][0-9a-zA-Z_$]*(?:\[(?:".+"|\'.+\'|\d+)\])*?$/; + +module.exports.check = function(inputStr) { + var isValid = true; + inputStr.split(".").forEach(function(part) { + if (!regex.test(part)) { + isValid = false; + } + + if (RESERVED_WORDS.indexOf(part) !== -1) { + isValid = false; + } + }); + + return isValid; +} From e285db9e80f5f7271bc6fb6ec05772763f0c3659 Mon Sep 17 00:00:00 2001 From: John McLear Date: Fri, 23 Mar 2018 13:21:59 +0000 Subject: [PATCH 02/43] Update Deps https://i.imgur.com/cxFXNeY.png --- src/package.json | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/package.json b/src/package.json index a88b5c6c..6aa17a69 100644 --- a/src/package.json +++ b/src/package.json @@ -24,7 +24,7 @@ "async" : "0.9.0", "clean-css" : "3.4.19", "uglify-js" : "2.6.2", - "formidable" : "1.0.17", + "formidable" : "1.2.1", "log4js" : "0.6.35", "cheerio" : "0.20.0", "async-stacktrace" : "0.0.2", @@ -42,13 +42,12 @@ "channels" : "0.0.4", "jsonminify" : "0.4.1", "measured" : "1.1.0", - "mocha" : "2.4.5", - "supertest" : "1.2.0", - "is-var-name" : "1.0.0" - }, + "mocha" : "5.0.5", + "supertest" : "3.0.0" + }, "bin": { "etherpad-lite": "./node/server.js" }, "devDependencies": { - "wd" : "0.3.11" + "wd" : "1.6.1" }, "engines" : { "node" : ">=0.10.0", "npm" : ">=1.0" From 8767410a36be9c42b85d0a11f199497caf79a1d8 Mon Sep 17 00:00:00 2001 From: John McLear Date: Fri, 23 Mar 2018 19:21:52 +0000 Subject: [PATCH 03/43] be more strict on password check --- src/node/hooks/express/webaccess.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node/hooks/express/webaccess.js b/src/node/hooks/express/webaccess.js index 190021a3..1faceec7 100644 --- a/src/node/hooks/express/webaccess.js +++ b/src/node/hooks/express/webaccess.js @@ -37,7 +37,7 @@ exports.basicAuth = function (req, res, next) { var username = userpass.shift(); var password = userpass.join(':'); - if (settings.users[username] != undefined && settings.users[username].password == password) { + if (settings.users[username] != undefined && settings.users[username].password === password) { settings.users[username].username = username; req.session.user = settings.users[username]; return cb(true); From bb40aa00bec361cef475791af338e3d0db68c3ae Mon Sep 17 00:00:00 2001 From: John McLear Date: Tue, 3 Apr 2018 10:59:10 +0100 Subject: [PATCH 04/43] Update express.js --- src/node/hooks/express.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/node/hooks/express.js b/src/node/hooks/express.js index 17910e4b..48dcf56c 100644 --- a/src/node/hooks/express.js +++ b/src/node/hooks/express.js @@ -25,6 +25,10 @@ exports.createServer = function () { else{ console.warn("Admin username and password not set in settings.json. To access admin please uncomment and edit 'users' in settings.json"); } + var env = process.env.NODE_ENV || 'development'; + if(env !== 'production'){ + console.warn("Etherpad is running in Development mode. This mode is slower for users and less secure than production mode. You should set the NODE_ENV environment variable to production by using: export NODE_ENV=production"); + } } exports.restartServer = function () { From 5a0afab02e7d27b0c6aeeb5d2f8b17b63550e6df Mon Sep 17 00:00:00 2001 From: John McLear Date: Wed, 4 Apr 2018 13:33:46 +0100 Subject: [PATCH 05/43] remove license thing from exports --- src/templates/export_html.html | 1 - 1 file changed, 1 deletion(-) diff --git a/src/templates/export_html.html b/src/templates/export_html.html index b29941c9..b8893b71 100644 --- a/src/templates/export_html.html +++ b/src/templates/export_html.html @@ -139,6 +139,5 @@ ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol { <%- body %> - From 806c9207e365304ef0f3130d7d3ec59f362f8f9d Mon Sep 17 00:00:00 2001 From: Peter 'Pita' Martischka Date: Wed, 4 Apr 2018 18:02:54 +0100 Subject: [PATCH 06/43] remove findkeys from pad export --- src/node/utils/ExportEtherpad.js | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/src/node/utils/ExportEtherpad.js b/src/node/utils/ExportEtherpad.js index 46ae0d7a..a68ab0b2 100644 --- a/src/node/utils/ExportEtherpad.js +++ b/src/node/utils/ExportEtherpad.js @@ -22,25 +22,18 @@ var ERR = require("async-stacktrace"); exports.getPadRaw = function(padId, callback){ async.waterfall([ function(cb){ - - // Get the Pad - db.findKeys("pad:"+padId, null, function(err,padcontent){ - if(!err){ - cb(err, padcontent); - } - }) + db.get("pad:"+padId, cb); }, function(padcontent,cb){ + var records = ["pad:"+padId]; + for (var i = 0; i <= padcontent.head; i++) { + records.push("pad:"+padId+":revs:" + i); + } + + for (var i = 0; i <= padcontent.chatHead; i++) { + records.push("pad:"+padId+":chat:" + i); + } - // Get the Pad available content keys - db.findKeys("pad:"+padId+":*", null, function(err,records){ - if(!err){ - for (var key in padcontent) { records.push(padcontent[key]);} - cb(err, records); - } - }) - }, - function(records, cb){ var data = {}; async.forEachSeries(Object.keys(records), function(key, r){ @@ -69,7 +62,7 @@ exports.getPadRaw = function(padId, callback){ } r(null); // callback; }); - }, function(err){ + }, function(err){ cb(err, data); }) } From 735052e1a22828337507f5168420f2daa242d864 Mon Sep 17 00:00:00 2001 From: John McLear Date: Wed, 4 Apr 2018 20:13:28 +0100 Subject: [PATCH 07/43] Update package.json --- src/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/package.json b/src/package.json index 039bfc7b..189d8a7b 100644 --- a/src/package.json +++ b/src/package.json @@ -17,7 +17,7 @@ "etherpad-require-kernel" : "1.0.9", "resolve" : "1.1.7", "socket.io" : "1.7.3", - "ueberdb2" : "0.3.6", + "ueberdb2" : "0.3.8", "express" : "4.13.4", "express-session" : "1.13.0", "cookie-parser" : "1.3.4", From a08c4383b82b1e5377a85ed0125ed1b977f7f324 Mon Sep 17 00:00:00 2001 From: Peter 'Pita' Martischka Date: Wed, 4 Apr 2018 21:48:32 +0100 Subject: [PATCH 08/43] check pad exists before importing / exporting --- src/node/hooks/express/importexport.js | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/node/hooks/express/importexport.js b/src/node/hooks/express/importexport.js index 5ebac1db..a62942cc 100644 --- a/src/node/hooks/express/importexport.js +++ b/src/node/hooks/express/importexport.js @@ -2,6 +2,7 @@ var hasPadAccess = require("../../padaccess"); var settings = require('../../utils/Settings'); var exportHandler = require('../../handler/ExportHandler'); var importHandler = require('../../handler/ImportHandler'); +var padManager = require("../../db/PadManager"); exports.expressCreateServer = function (hook_name, args, cb) { args.app.get('/p/:pad/:rev?/export/:type', function(req, res, next) { @@ -22,14 +23,29 @@ exports.expressCreateServer = function (hook_name, args, cb) { res.header("Access-Control-Allow-Origin", "*"); hasPadAccess(req, res, function() { - exportHandler.doExport(req, res, req.params.pad, req.params.type); + console.log('req.params.pad', req.params.pad); + padManager.doesPadExists(req.params.pad, function(err, exists) + { + if(!exists) { + return next(); + } + + exportHandler.doExport(req, res, req.params.pad, req.params.type); + }); }); }); //handle import requests args.app.post('/p/:pad/import', function(req, res, next) { hasPadAccess(req, res, function() { - importHandler.doImport(req, res, req.params.pad); + padManager.doesPadExists(req.params.pad, function(err, exists) + { + if(!exists) { + return next(); + } + + importHandler.doImport(req, res, req.params.pad); + }); }); }); } From 68d81e839c5883df0a6e8ca2c2e663ae5b6fb112 Mon Sep 17 00:00:00 2001 From: John McLear Date: Fri, 6 Apr 2018 10:38:14 +0100 Subject: [PATCH 09/43] Update CONTRIBUTING.md --- CONTRIBUTING.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 09ddc286..54ff0680 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -35,7 +35,7 @@ The logfile location is defined in startup script or the log is directly shown i To make sure everybody is going in the same direction: * easy to install for admins and easy to use for people * easy to integrate into other apps, but also usable as standalone -* using less resources on server side +* lightweight and scalable * extensible, as much functionality should be extendable with plugins so changes don't have to be done in core. Also, keep it maintainable. We don't wanna end up as the monster Etherpad was! @@ -92,3 +92,18 @@ You can build the docs e.g. produce html, using `make docs`. At some point in th ## Testing Front-end tests are found in the `tests/frontend/` folder in the repository. Run them by pointing your browser to `/tests/frontend`. + +## Things you can help with +Etherpad is much more than software. So if you aren't a developer then worry not, there is still a LOT you can do! A big part of what we do is community engagement. You can help in the following ways + * Triage bugs (applying labels) and confirming their existance + * Testing fixes (simply applying them and seeing if it fixes your issue or not) - Some git experience required + * Notifying large site admins of new releases + * Writing Changelogs for releases + * Creating Windows packages + * Creating releases + * Bumping dependencies periodically and checking they don't break anything + * Write proposals for grants + * Co-Author and Publish CVEs + * Work with SFC to maintain legal side of project + * Maintain TODO page - https://github.com/ether/etherpad-lite/wiki/TODO#IMPORTANT_TODOS + From 0225acfa06952363701571366441fd466b32f6f9 Mon Sep 17 00:00:00 2001 From: John McLear Date: Fri, 6 Apr 2018 10:40:36 +0100 Subject: [PATCH 10/43] Update CONTRIBUTING.md --- CONTRIBUTING.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 54ff0680..66946080 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -# Developer Guidelines +# Contributor Guidelines (Please talk to people on the mailing list before you change this page, see our section on [how to get in touch](https://github.com/ether/etherpad-lite#get-in-touch)) ## How to write a bug report @@ -106,4 +106,5 @@ Etherpad is much more than software. So if you aren't a developer then worry no * Co-Author and Publish CVEs * Work with SFC to maintain legal side of project * Maintain TODO page - https://github.com/ether/etherpad-lite/wiki/TODO#IMPORTANT_TODOS - + * Replying to messages on IRC / The Mailing list / Emails + From 98a03b08675dc821c5a44ce7f7e3555067ef1517 Mon Sep 17 00:00:00 2001 From: John McLear Date: Fri, 6 Apr 2018 13:51:08 +0100 Subject: [PATCH 11/43] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3ab7e358..d8d7b621 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Etherpad is a really-real time collaborative editor scalable to thousands of sim ``` curl -sL https://deb.nodesource.com/setup_9.x | sudo -E bash - sudo apt-get install -y nodejs -git clone git://github.com/ether/etherpad-lite.git && cd etherpad-lite && bin/run.sh +git clone https://github.com/ether/etherpad-lite.git && cd etherpad-lite && bin/run.sh ``` ## GNU/Linux and other UNIX-like systems From 86ec963775a9361856e52d6f734cdfad8cce07dc Mon Sep 17 00:00:00 2001 From: John McLear Date: Fri, 6 Apr 2018 13:52:04 +0100 Subject: [PATCH 12/43] Fixes #3137 #3137 --- src/static/css/pad.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/static/css/pad.css b/src/static/css/pad.css index eb62a6f9..484e6f2a 100644 --- a/src/static/css/pad.css +++ b/src/static/css/pad.css @@ -1072,9 +1072,9 @@ input[type=checkbox] { overflow: auto; } #mycolorpicker { - left: -73px; - top:auto !important; - bottom:33px !important; + left: 0px; + top:37px !important; + position:fixed; /* #mycolorpicker: width -#users: width */; } #editorcontainer { From ffe24c3dd93efc73e0cbf924db9a0cc40be9511b Mon Sep 17 00:00:00 2001 From: thomas Date: Fri, 6 Apr 2018 22:21:33 +0200 Subject: [PATCH 13/43] Update webaccess.js --- src/node/hooks/express/webaccess.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node/hooks/express/webaccess.js b/src/node/hooks/express/webaccess.js index 1faceec7..29475037 100644 --- a/src/node/hooks/express/webaccess.js +++ b/src/node/hooks/express/webaccess.js @@ -20,7 +20,7 @@ exports.basicAuth = function (req, res, next) { // Do not require auth for static paths and the API...this could be a bit brittle if (req.path.match(/^\/(static|javascripts|pluginfw|api)/)) return cb(true); - if (req.path.indexOf('/admin') != 0) { + if (req.path.toLowerCase().indexOf('/admin') != 0) { if (!settings.requireAuthentication) return cb(true); if (!settings.requireAuthorization && req.session && req.session.user) return cb(true); } From c34350f3075de5bd8a9055c174b4182c167f64b2 Mon Sep 17 00:00:00 2001 From: John McLear Date: Sat, 7 Apr 2018 09:22:13 +0100 Subject: [PATCH 14/43] Beginning to make release --- CHANGELOG.md | 26 ++++++++++++++++++++------ src/package.json | 2 +- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 74d06f45..bd79182c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,17 @@ +# 1.6.4 + * SECURITY: exploitable /admin access + * SECURITY: DoS with pad exports + * SECURITY: Remote Code Execution + * SECURITY: Pad data leak + * Fix: Admin redirect URL + * Fix: Various script Fixes + * Fix: Various CSS/Style/Layout fixes + * NEW: Improved Pad contents readability + * NEW: Hook: onAccessCheck + * NEW: SESSIONKEY and APIKey customizable path + * NEW: checkPads script + * NEW: Support "cluster mode" + # 1.6.3 * SECURITY: Update ejs * SECURITY: xss vulnerability when reading window.location.href @@ -56,7 +70,7 @@ * NEW: Allow LibreOffice to be used when exporting a pad * NEW: Create hook exportHtmlAdditionalTagsWithData * NEW: Improve DB migration performance - * NEW: allow settings to be applied from the filesystem + * NEW: allow settings to be applied from the filesystem * NEW: remove applySettings hook and allow credentials.json to be part of core * NEW: Use exec to switch to node process * NEW: Validate incoming color codes @@ -85,7 +99,7 @@ * Fix: switchToPad method * Fix: Dead keys * Fix: Preserve new lines in copy-pasted text - * Fix: Compatibility mode on IE + * Fix: Compatibility mode on IE * Fix: Content Collector to get the class of the DOM-node * Fix: Timeslider export links * Fix: Double prompt on file upload @@ -212,7 +226,7 @@ * Fix: Session Deletion error * Fix: Allow browser tabs to be cycled when focus is in editor * Fix: Various Editor issues with Easysync potentially entering forever loop on bad changeset - + # 1.4 * NEW: Disable toolbar items through settings.json * NEW: Internal stats/metrics engine @@ -244,7 +258,7 @@ # 1.3 * NEW: We now follow the semantic versioning scheme! * NEW: Option to disable IP logging - * NEW: Localisation updates from http://translatewiki.net. + * NEW: Localisation updates from http://translatewiki.net. * Fix: Fix readOnly group pads * Fix: don't fetch padList on every request @@ -337,7 +351,7 @@ * NEW: Add authorId to chat and userlist as a data attribute * NEW: Refactor and fix our frontend tests * NEW: Localisation updates - + # 1.2.81 * Fix: CtrlZ-Y for Undo Redo @@ -377,7 +391,7 @@ * Other: Change loading message asking user to please wait on first build * Other: Allow etherpad to use global npm installation (Safe since node 6.3) * Other: Better documentation for log rotation and log message handling - + # 1.2.7 diff --git a/src/package.json b/src/package.json index 189d8a7b..5b3d6d43 100644 --- a/src/package.json +++ b/src/package.json @@ -56,6 +56,6 @@ "repository" : { "type" : "git", "url" : "http://github.com/ether/etherpad-lite.git" }, - "version" : "1.6.3", + "version" : "1.6.4", "license" : "Apache-2.0" } From 0132f4d1da983638bcf8f13cc1a1fef6decc387b Mon Sep 17 00:00:00 2001 From: John McLear Date: Sat, 7 Apr 2018 10:13:09 +0100 Subject: [PATCH 15/43] Include CVE # --- CHANGELOG.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd79182c..02accf8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,8 @@ # 1.6.4 - * SECURITY: exploitable /admin access - * SECURITY: DoS with pad exports - * SECURITY: Remote Code Execution - * SECURITY: Pad data leak + * SECURITY: exploitable /admin access - CVE-2018-9845 + * SECURITY: DoS with pad exports - CVE-2018-9327 + * SECURITY: Remote Code Execution - CVE-2018-9326 + * SECURITY: Pad data leak - CVE-2018-9325 * Fix: Admin redirect URL * Fix: Various script Fixes * Fix: Various CSS/Style/Layout fixes @@ -10,7 +10,7 @@ * NEW: Hook: onAccessCheck * NEW: SESSIONKEY and APIKey customizable path * NEW: checkPads script - * NEW: Support "cluster mode" + * NEW: Support "cluster mode" # 1.6.3 * SECURITY: Update ejs From fa83de778cdc6e7c3b83e356b45b76b955ec63ba Mon Sep 17 00:00:00 2001 From: John McLear Date: Sat, 7 Apr 2018 10:31:47 +0100 Subject: [PATCH 16/43] Password check fix --- src/node/hooks/express/webaccess.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node/hooks/express/webaccess.js b/src/node/hooks/express/webaccess.js index 4b9ad4eb..4cb4b9d3 100644 --- a/src/node/hooks/express/webaccess.js +++ b/src/node/hooks/express/webaccess.js @@ -38,7 +38,7 @@ exports.basicAuth = function (req, res, next) { var password = userpass.join(':'); var fallback = function(success) { if (success) return cb(true); - if (settings.users[username] != undefined && settings.users[username].password == password) { + if (settings.users[username] != undefined && settings.users[username].password === password) { settings.users[username].username = username; req.session.user = settings.users[username]; return cb(true); From fba2bf4df907895f65356b5c8da84571c8ebddef Mon Sep 17 00:00:00 2001 From: John McLear Date: Sat, 7 Apr 2018 17:50:45 +0100 Subject: [PATCH 17/43] Update iframe_editor.css --- src/static/css/iframe_editor.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/static/css/iframe_editor.css b/src/static/css/iframe_editor.css index 757bfa96..36e0b2da 100644 --- a/src/static/css/iframe_editor.css +++ b/src/static/css/iframe_editor.css @@ -33,7 +33,7 @@ body.grayedout { background-color: #eee !important } #innerdocbody { font-size: 16px; /* overridden by body.style */ font-family:Arial, sans-serif; /* overridden by body.style */ - line-height: 16px; /* overridden by body.style */ + line-height: 22px; /* overridden by body.style */ background-color: white; color: black; } From b16e7ad25ead5f1dbed4664ecb85756622013ec9 Mon Sep 17 00:00:00 2001 From: John McLear Date: Sat, 7 Apr 2018 18:11:24 +0100 Subject: [PATCH 18/43] unbreak Safari iOS line wrapping fixes https://github.com/ether/etherpad-lite/commit/f5810957b4204d06563485953e3efeb1392304c2#diff-f639eb4efeaabf5624f3229daa1e88cd --- src/static/css/iframe_editor.css | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/static/css/iframe_editor.css b/src/static/css/iframe_editor.css index 36e0b2da..0286a5df 100644 --- a/src/static/css/iframe_editor.css +++ b/src/static/css/iframe_editor.css @@ -62,11 +62,9 @@ body.doesWrap { white-space: normal; } -@-moz-document url-prefix() { - body.doesWrap:not(.noprewrap) > div{ - /* Related to #1766 */ - white-space: pre-wrap; - } +body.doesWrap:not(.noprewrap) > div{ + /* Related to #1766 */ + white-space: pre-wrap; } #innerdocbody { From 1fdb01fd759133b4da001dc5e233420a14cd8d59 Mon Sep 17 00:00:00 2001 From: "translatewiki.net" Date: Mon, 9 Apr 2018 08:17:36 +0200 Subject: [PATCH 19/43] Localisation updates from https://translatewiki.net. --- src/locales/zh-hant.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/locales/zh-hant.json b/src/locales/zh-hant.json index 17591884..2a7d6d1e 100644 --- a/src/locales/zh-hant.json +++ b/src/locales/zh-hant.json @@ -117,7 +117,7 @@ "timeslider.month.october": "10月", "timeslider.month.november": "11月", "timeslider.month.december": "12月", - "timeslider.unnamedauthors": "{{num}}匿名{[plural(num) 作者]}", + "timeslider.unnamedauthors": "{{num}} 個匿名{[plural(num) one:作者, other:作者]}", "pad.savedrevs.marked": "標記此修訂版本為已儲存修訂版本。", "pad.savedrevs.timeslider": "您可使用時段滑標來查看先前保存的版本內容", "pad.userlist.entername": "輸入您的姓名", From 5b1e1f0c3556af3315d73edf9163cb528047fe28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20T=C3=A9tard?= Date: Sat, 7 Apr 2018 16:07:38 +0200 Subject: [PATCH 20/43] Fix typo in `apicalls.js` which prevents from importing `isValidJSONPName`. --- src/node/hooks/express/apicalls.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node/hooks/express/apicalls.js b/src/node/hooks/express/apicalls.js index e07bbb0b..d6011c97 100644 --- a/src/node/hooks/express/apicalls.js +++ b/src/node/hooks/express/apicalls.js @@ -3,7 +3,7 @@ var apiLogger = log4js.getLogger("API"); var clientLogger = log4js.getLogger("client"); var formidable = require('formidable'); var apiHandler = require('../../handler/APIHandler'); -var isValidJSONPName = require('./isValidJsonPName'); +var isValidJSONPName = require('./isValidJSONPName'); //This is for making an api call, collecting all post information and passing it to the apiHandler var apiCaller = function(req, res, fields) { From 92eee85f3619a1c0593391bb5dfc57a039b9a4ad Mon Sep 17 00:00:00 2001 From: nashe Date: Mon, 9 Apr 2018 22:08:43 +0200 Subject: [PATCH 21/43] Escape data when listing available plugins --- src/static/js/admin/plugins.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/static/js/admin/plugins.js b/src/static/js/admin/plugins.js index 3f88d9b1..c9a24487 100644 --- a/src/static/js/admin/plugins.js +++ b/src/static/js/admin/plugins.js @@ -79,12 +79,17 @@ $(document).ready(function () { for (attr in plugin) { if(attr == "name"){ // Hack to rewrite URLS into name - row.find(".name").html(""+plugin['name'].substr(3)+""); // remove 'ep_' - }else{ + var link = $(''); + link.attr('href', 'https://npmjs.org/package/'+plugin['name']); + link.attr('plugin', 'Plugin details'); + link.attr('target', '_blank'); + link.text(plugin['name'].substr(3)); + row.find('.name').append(link); + } else { row.find("." + attr).text(plugin[attr]); } } - row.find(".version").html( plugin.version ); + row.find(".version").text(plugin.version); row.addClass(plugin.name) row.data('plugin', plugin.name) container.append(row); From 1d4e2b3b114513506cf6e02782aab2a954db96d8 Mon Sep 17 00:00:00 2001 From: muxator Date: Tue, 10 Apr 2018 00:17:34 +0200 Subject: [PATCH 22/43] Release version 1.6.5 --- src/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/package.json b/src/package.json index bf2f8858..9813d6ab 100644 --- a/src/package.json +++ b/src/package.json @@ -55,6 +55,6 @@ "repository" : { "type" : "git", "url" : "http://github.com/ether/etherpad-lite.git" }, - "version" : "1.6.4", + "version" : "1.6.5", "license" : "Apache-2.0" } From 3eb3e301a2d729561751faab3aaa6151668203a9 Mon Sep 17 00:00:00 2001 From: muxator Date: Tue, 10 Apr 2018 00:44:14 +0200 Subject: [PATCH 23/43] manually updated CHANGELOG.md due to createRelease.sh not catching an error from sed and continuing: sed: -e expression #1, char 66: unterminated `s' command --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 02accf8c..df249c25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# 1.6.5 + * SECURITY: Escape data when listing available plugins + * FIX: Fix typo in apicalls.js which prevented importing isValidJSONPName + * FIX: fixed plugin dependency issue + * FIX: Update iframe_editor.css + * FIX: unbreak Safari iOS line wrapping + # 1.6.4 * SECURITY: exploitable /admin access - CVE-2018-9845 * SECURITY: DoS with pad exports - CVE-2018-9327 From 686ce054fae48cd0b63adc6370495c858f6a8514 Mon Sep 17 00:00:00 2001 From: "translatewiki.net" Date: Thu, 12 Apr 2018 09:12:18 +0200 Subject: [PATCH 24/43] Localisation updates from https://translatewiki.net. --- src/locales/pms.json | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/locales/pms.json b/src/locales/pms.json index 80a857e3..a389d349 100644 --- a/src/locales/pms.json +++ b/src/locales/pms.json @@ -44,5 +44,17 @@ "pad.importExport.import": "Carié n'archivi o document ëd test", "pad.importExport.importSuccessful": "Bele fàit!", "pad.importExport.export": "Esporté ël feuj atual coma:", - "pad.importExport.exportetherpad": "Etherpad" + "pad.importExport.exportetherpad": "Etherpad", + "pad.importExport.exporthtml": "HTML", + "pad.importExport.exportplain": "Mach test", + "pad.importExport.exportword": "Microsoft Word", + "pad.importExport.exportpdf": "PDF", + "pad.importExport.exportopen": "ODF (Open Document Format)", + "pad.importExport.abiword.innerHTML": "A peul mach amporté dij formà ëd test sempi o HTML. Për dle fonsionalità d'amportassion pi avansà, ch'a anstala AbiWord.", + "pad.modals.connected": "Colegà.", + "pad.modals.reconnecting": "Neuva conession a sò feuj...", + "pad.modals.forcereconnect": "Forsé la neuva conession", + "pad.modals.reconnecttimer": "Tentativ ëd neuva conession", + "pad.modals.cancel": "Anulé", + "pad.modals.userdup": "Duvertà an n'àutra fnestra" } From 6dc8ead8c9e3f17cce2bbb7f75ff1774dad66da4 Mon Sep 17 00:00:00 2001 From: "translatewiki.net" Date: Thu, 12 Apr 2018 15:16:27 +0200 Subject: [PATCH 25/43] Localisation updates from https://translatewiki.net. --- src/locales/pms.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/locales/pms.json b/src/locales/pms.json index a389d349..6ac0677b 100644 --- a/src/locales/pms.json +++ b/src/locales/pms.json @@ -56,5 +56,9 @@ "pad.modals.forcereconnect": "Forsé la neuva conession", "pad.modals.reconnecttimer": "Tentativ ëd neuva conession", "pad.modals.cancel": "Anulé", - "pad.modals.userdup": "Duvertà an n'àutra fnestra" + "pad.modals.userdup": "Duvertà an n'àutra fnestra", + "pad.modals.userdup.explanation": "Ës feuj a smija esse duvert an vàire fnestre ansima a st'ordinator.", + "pad.modals.userdup.advice": "Coleghesse torna për dovré costa fnestra.", + "pad.modals.unauth": "Nen autorisà", + "pad.modals.unauth.explanation": "Ij sò përmess a son cangià antramentre ch'a vëdìa costa pàgina. Ch'a sërca ëd coleghesse torna." } From 9daade0b95bbc5443637977652d3cd0dbc44e112 Mon Sep 17 00:00:00 2001 From: muxator Date: Fri, 13 Apr 2018 18:32:39 +0200 Subject: [PATCH 26/43] fix: line numbers was not aligned with text This change partially reverts 0a9d02562d7e, which got released in 1.6.4 due to #3280. Text size and line alignment are now reverted back to their 1.6.3 appearance (thus stay non customizable, for now). Fixes #3378 --- src/static/css/iframe_editor.css | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/static/css/iframe_editor.css b/src/static/css/iframe_editor.css index 0286a5df..9aa003aa 100644 --- a/src/static/css/iframe_editor.css +++ b/src/static/css/iframe_editor.css @@ -31,17 +31,13 @@ body { body.grayedout { background-color: #eee !important } #innerdocbody { - font-size: 16px; /* overridden by body.style */ + font-size: 12px; /* overridden by body.style */ font-family:Arial, sans-serif; /* overridden by body.style */ - line-height: 22px; /* overridden by body.style */ + line-height: 16px; /* overridden by body.style */ background-color: white; color: black; } -.innerdocbody>div{ - padding: 1px; -} - body.doesWrap { /* white-space: pre-wrap; */ From 4f2ff31a61f520beea42ddf40806c8e636834720 Mon Sep 17 00:00:00 2001 From: "translatewiki.net" Date: Thu, 19 Apr 2018 09:20:05 +0200 Subject: [PATCH 27/43] Localisation updates from https://translatewiki.net. --- src/locales/pms.json | 62 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/src/locales/pms.json b/src/locales/pms.json index 6ac0677b..c73567f5 100644 --- a/src/locales/pms.json +++ b/src/locales/pms.json @@ -60,5 +60,65 @@ "pad.modals.userdup.explanation": "Ës feuj a smija esse duvert an vàire fnestre ansima a st'ordinator.", "pad.modals.userdup.advice": "Coleghesse torna për dovré costa fnestra.", "pad.modals.unauth": "Nen autorisà", - "pad.modals.unauth.explanation": "Ij sò përmess a son cangià antramentre ch'a vëdìa costa pàgina. Ch'a sërca ëd coleghesse torna." + "pad.modals.unauth.explanation": "Ij sò përmess a son cangià antramentre ch'a vëdìa costa pàgina. Ch'a sërca ëd coleghesse torna.", + "pad.modals.looping.explanation": "A-i é dij problema ëd comunicassion con ël servent ëd sincronisassion.", + "pad.modals.looping.cause": "Peul desse che chiel a l'é colegasse con un para-feu o un mandatari incompatìbil.", + "pad.modals.initsocketfail": "Ël servent a l'é introvàbil.", + "pad.modals.initsocketfail.explanation": "Impossìbil coleghesse al servent ëd sincronisassion.", + "pad.modals.initsocketfail.cause": "A l'é probàbil che sòn a sia dovù a sò navigador o a soa conession an sl'aragnà.", + "pad.modals.slowcommit.explanation": "Ël servent a rëspond nen.", + "pad.modals.slowcommit.cause": "Sòn a podrìa esse dovù a dij problema ëd conession a l'aragnà.", + "pad.modals.badChangeset.explanation": "Na modìfica ch'a l'ha fàit a l'é stàita cassificà tanme ilegal dal servent ëd sincronisassion.", + "pad.modals.badChangeset.cause": "Sòn a podrìa esse dovù a na bruta configurassion dël servent o a chèich àutr comportament nen ëspetà. Për piasì, ch'a contata l'aministrator dël servissi, s'a pensa ch'a sia n'eror. Ch'a preuva a rintré torna ant ël sistema për andé anans a modifiché.", + "pad.modals.corruptPad.explanation": "Ël feuj al qual a sërca d'acede a l'é corompù.", + "pad.modals.corruptPad.cause": "Sòn a podrìa esse dovù a na configurassion ësbalià dël servent o a chèich àutr comportament nen ëspetà. Për piasì, ch'a contata l'aministrator dël servissi.", + "pad.modals.deleted": "Dëscancelà.", + "pad.modals.deleted.explanation": "Ës feuj a l'é stàit eliminà.", + "pad.modals.disconnected": "A l'é stàit dëscolegà", + "pad.modals.disconnected.explanation": "La conession al servent a l'é perdusse", + "pad.modals.disconnected.cause": "Ël servent a podrìa esse indisponìbil. Për piasì, ch'a anforma l'aministrator dël servissi si ël problema a persist.", + "pad.share": "Partagé 's feuj", + "pad.share.readonly": "Mach letura", + "pad.share.link": "Liura", + "pad.share.emebdcode": "Ancorporé na liura", + "pad.chat": "Ciaciarada", + "pad.chat.title": "Duverté la ciaciarada për cost feuj.", + "pad.chat.loadmessages": "Carié pi 'd mëssagi", + "timeslider.pageTitle": "Stòria dinàmica ëd {{appTitle}}", + "timeslider.toolbar.returnbutton": "Torné al feuj", + "timeslider.toolbar.authors": "Autor:", + "timeslider.toolbar.authorsList": "Gnun autor", + "timeslider.toolbar.exportlink.title": "Esporté", + "timeslider.exportCurrent": "Esporté la version corenta tanme:", + "timeslider.version": "Version {{version}}", + "timeslider.saved": "Argistrà ai {{day}} {{month}} {{year}}", + "timeslider.playPause": "Letura / Pàusa dij contnù dël feuj", + "timeslider.backRevision": "Andé andaré ëd na revision ant ës feuj", + "timeslider.forwardRevision": "Andé anans ëd na revision ant ëd feuj", + "timeslider.dateformat": "{{day}}/{{month}}/{{year}} {{hours}}:{{minutes}}:{{seconds}}", + "timeslider.month.january": "Gené", + "timeslider.month.february": "Fërvé", + "timeslider.month.march": "Mars", + "timeslider.month.april": "Avril", + "timeslider.month.may": "Maj", + "timeslider.month.june": "Giugn", + "timeslider.month.july": "Luj", + "timeslider.month.august": "Ost", + "timeslider.month.september": "Stèmber", + "timeslider.month.october": "Otóber", + "timeslider.month.november": "Novèmber", + "timeslider.month.december": "Dzèmber", + "timeslider.unnamedauthors": "{{num}} {[plural(num) one: autor anònim, other: autor anònim ]}", + "pad.savedrevs.marked": "Sa revision a l'é adess marcà tanme revision argistrà", + "pad.savedrevs.timeslider": "A peul vëdde le revision argistrà an visitand la stòria", + "pad.userlist.entername": "Ch'a buta sò nòm", + "pad.userlist.unnamed": "anònim", + "pad.userlist.guest": "Anvità", + "pad.userlist.deny": "Arfudé", + "pad.userlist.approve": "Aprové", + "pad.editbar.clearcolors": "Dëscancelé ij color ëd paternità dj'autor an tut ël document?", + "pad.impexp.importbutton": "Amporté adess", + "pad.impexp.importing": "An camin ch'as ampòrta...", + "pad.impexp.confirmimport": "Amportand n'archivi as dëscancelërà ël test corent dël feuj. É-lo sigur ëd vorèj felo?", + "pad.impexp.convertFailed": "I l'oma nen podù amporté s'archivi. Për piasì, ch'a deuvra n'àutr formà ëd document o ch'a còpia e ancòla a man" } From d26df864902510ca7f325b786183dc9031e04e42 Mon Sep 17 00:00:00 2001 From: Benjamin Schweizer Date: Fri, 19 Feb 2016 10:07:01 +0100 Subject: [PATCH 28/43] made url relative --- src/static/js/pad.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/static/js/pad.js b/src/static/js/pad.js index 8fcec23f..bab59f42 100644 --- a/src/static/js/pad.js +++ b/src/static/js/pad.js @@ -831,7 +831,7 @@ var pad = { $.ajax( { type: 'post', - url: '/ep/pad/connection-diagnostic-info', + url: 'ep/pad/connection-diagnostic-info', data: { diagnosticInfo: JSON.stringify(pad.diagnosticInfo) }, From fb20c26c5f36be272060a45286188f4eafbd451e Mon Sep 17 00:00:00 2001 From: anugu-chegg Date: Sat, 3 Feb 2018 13:29:52 +0530 Subject: [PATCH 29/43] Don't send COMMIT-MESSAGE when socketio connection is not active --- src/static/js/collab_client.js | 34 ++++++++++++++++++++-------------- src/static/js/pad.js | 4 ++++ 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/static/js/collab_client.js b/src/static/js/collab_client.js index fd0d9d44..9fc03991 100644 --- a/src/static/js/collab_client.js +++ b/src/static/js/collab_client.js @@ -181,20 +181,26 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad) } var sentMessage = false; - var userChangesData = editor.prepareUserChangeset(); - if (userChangesData.changeset) - { - lastCommitTime = t; - state = "COMMITTING"; - stateMessage = { - type: "USER_CHANGES", - baseRev: rev, - changeset: userChangesData.changeset, - apool: userChangesData.apool - }; - sendMessage(stateMessage); - sentMessage = true; - callbacks.onInternalAction("commitPerformed"); + if (getSocket().realConnected) { + var userChangesData = editor.prepareUserChangeset(); + if (userChangesData.changeset) + { + lastCommitTime = t; + state = "COMMITTING"; + stateMessage = { + type: "USER_CHANGES", + baseRev: rev, + changeset: userChangesData.changeset, + apool: userChangesData.apool + }; + sendMessage(stateMessage); + sentMessage = true; + callbacks.onInternalAction("commitPerformed"); + } + } + else { + // run again in a few seconds, to check if there was a reconnection attempt + setTimeout(wrapRecordingErrors("setTimeout(handleUserChanges)", handleUserChanges), 1000); } if (sentMessage) diff --git a/src/static/js/pad.js b/src/static/js/pad.js index bab59f42..152a48d9 100644 --- a/src/static/js/pad.js +++ b/src/static/js/pad.js @@ -201,15 +201,19 @@ function handshake() }); socket.once('connect', function () { + // Setup our own connected flag since socketio one doesn't work accurately + socket.realConnected = true; sendClientReady(false); }); socket.on('reconnect', function () { + socket.realConnected = true; pad.collabClient.setChannelState("CONNECTED"); pad.sendClientReady(true); }); socket.on('reconnecting', function() { + socket.realConnected = false; pad.collabClient.setChannelState("RECONNECTING"); }); From 4265f4175ee1e11664d6f637dfc6b7b0b601c23c Mon Sep 17 00:00:00 2001 From: anugu-chegg Date: Mon, 5 Feb 2018 22:37:49 +0530 Subject: [PATCH 30/43] Handle socketio errors properly --- src/static/js/collab_client.js | 3 ++- src/static/js/pad.js | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/static/js/collab_client.js b/src/static/js/collab_client.js index 9fc03991..7cf98ae6 100644 --- a/src/static/js/collab_client.js +++ b/src/static/js/collab_client.js @@ -662,7 +662,8 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad) getMissedChanges: getMissedChanges, callWhenNotCommitting: callWhenNotCommitting, addHistoricalAuthors: tellAceAboutHistoricalAuthors, - setChannelState: setChannelState + setChannelState: setChannelState, + setStateIdle: setStateIdle }; $(document).ready(setUpSocket); diff --git a/src/static/js/pad.js b/src/static/js/pad.js index 152a48d9..9abedd27 100644 --- a/src/static/js/pad.js +++ b/src/static/js/pad.js @@ -221,6 +221,11 @@ function handshake() pad.collabClient.setChannelState("DISCONNECTED", "reconnect_timeout"); }); + socket.on('error', function(error) { + socket.realConnected = false; + pad.collabClient.setStateIdle(); + }); + var initalized = false; socket.on('message', function(obj) From bf05e9ae89a73a1ceead364c42a2f66744c75723 Mon Sep 17 00:00:00 2001 From: anugu-chegg Date: Sat, 10 Feb 2018 22:30:22 +0530 Subject: [PATCH 31/43] Handle client reconnect properly --- src/node/handler/PadMessageHandler.js | 76 +++++++++++++++++++++++++++ src/static/js/collab_client.js | 57 ++++++++++++++++++-- src/static/js/pad.js | 4 +- 3 files changed, 131 insertions(+), 6 deletions(-) diff --git a/src/node/handler/PadMessageHandler.js b/src/node/handler/PadMessageHandler.js index 060bca7b..1d9b5cf1 100644 --- a/src/node/handler/PadMessageHandler.js +++ b/src/node/handler/PadMessageHandler.js @@ -1153,6 +1153,82 @@ function handleClientReady(client, message) client.join(padIds.padId); //Save the revision in sessioninfos, we take the revision from the info the client send to us sessioninfos[client.id].rev = message.client_rev; + + var changesetsNeeded = []; + var changesets = {}; + var changesetsAuthor = {}; + var changesetsTimestamp = {}; + + var startNum = message.client_rev + 1; + var endNum = pad.getHeadRevisionNumber() + 1; + + async.series([ + //fetch all changesets we need + function(callback) + { + var headNum = pad.getHeadRevisionNumber(); + if (endNum > headNum+1) + endNum = headNum+1; + if (startNum < 0) + startNum = 0; + //create a array for all changesets, we will + //replace the values with the changeset later + for(var r=startNum;r Date: Wed, 14 Feb 2018 13:18:44 +0530 Subject: [PATCH 32/43] Send commits missed during the reconnect --- src/node/handler/PadMessageHandler.js | 31 +++++++++++++++++++++------ src/static/js/collab_client.js | 14 +++++++++--- 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/src/node/handler/PadMessageHandler.js b/src/node/handler/PadMessageHandler.js index 1d9b5cf1..5e39bdb5 100644 --- a/src/node/handler/PadMessageHandler.js +++ b/src/node/handler/PadMessageHandler.js @@ -1177,33 +1177,51 @@ function handleClientReady(client, message) { changesetsNeeded.push(r); } - //get all changesets - async.forEach(changesetsNeeded, function(revNum) + callback(); + }, + //get all changesets + function(callback) + { + async.eachSeries(changesetsNeeded, function(revNum, callback) { pad.getRevisionChangeset(revNum, function(err, value) { if(ERR(err)) return; changesets[revNum] = value; + callback(); }); + }, callback); + }, + function(callback) + { + async.eachSeries(changesetsNeeded, function(revNum, callback) + { pad.getRevisionAuthor(revNum, function(err, value) { if(ERR(err)) return; changesetsAuthor[revNum] = value; + callback(); }); + }, callback); + }, + function(callback) + { + async.eachSeries(changesetsNeeded, function(revNum, callback) + { pad.getRevisionDate(revNum, function(err, value) { if(ERR(err)) return; changesetsTimestamp[revNum] = value; + callback(); }); - }); - callback(null); + }, callback); } ], //return err and changeset function(err) { if(ERR(err, callback)) return; - async.eachSeries(changesetsNeeded, function(r) + async.eachSeries(changesetsNeeded, function(r, callback) { var forWire = Changeset.prepareForWire(changesets[r], pad.pool); var wireMsg = {"type":"COLLABROOM", @@ -1216,7 +1234,8 @@ function handleClientReady(client, message) currentTime: changesetsTimestamp[r] }}; client.json.send(wireMsg); - }); + callback(); + }); if (startNum == endNum) { var Msg = {"type":"COLLABROOM", diff --git a/src/static/js/collab_client.js b/src/static/js/collab_client.js index 5259efd6..825803f1 100644 --- a/src/static/js/collab_client.js +++ b/src/static/js/collab_client.js @@ -342,6 +342,7 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad) } else if (msg.type == 'CLIENT_RECONNECT') { + // When client has reconnected but there are no pending changes from other clients if (msg.noChanges) { socketIOError = false; @@ -354,19 +355,26 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad) var author = (msg.author || ''); var apool = msg.apool; - if (rev + 1 == currRev) { if (author == pad.getUserId()) { editor.applyPreparedChangesetToBase(); setStateIdle(); + callCatchingErrors("onInternalAction", function() + { + callbacks.onInternalAction("commitAcceptedByServer"); + }); + callCatchingErrors("onConnectionTrouble", function() + { + callbacks.onConnectionTrouble("OK"); + }); + handleUserChanges(); } else { editor.applyChangesToBase(changeset, author, apool); } - } if (rev + 1 < currRev) { @@ -374,8 +382,8 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad) } if (currRev == newRev) { - socketIOError = false; rev = newRev; + socketIOError = false; } } else if (msg.type == "NO_COMMIT_PENDING") From 461ed413b735a641d0bbb248841411d25045caa7 Mon Sep 17 00:00:00 2001 From: anugu-chegg Date: Fri, 16 Feb 2018 01:31:47 +0530 Subject: [PATCH 33/43] Fix few mistakes --- src/node/handler/PadMessageHandler.js | 6 +-- src/static/js/collab_client.js | 55 +++++++++++++++++---------- 2 files changed, 37 insertions(+), 24 deletions(-) diff --git a/src/node/handler/PadMessageHandler.js b/src/node/handler/PadMessageHandler.js index 5e39bdb5..63349f14 100644 --- a/src/node/handler/PadMessageHandler.js +++ b/src/node/handler/PadMessageHandler.js @@ -1226,8 +1226,8 @@ function handleClientReady(client, message) var forWire = Changeset.prepareForWire(changesets[r], pad.pool); var wireMsg = {"type":"COLLABROOM", "data":{type:"CLIENT_RECONNECT", - currRev: r, - newRev:pad.getHeadRevisionNumber(), + headRev:pad.getHeadRevisionNumber(), + newRev:r, changeset:forWire.translated, apool: forWire.pool, author: changesetsAuthor[r], @@ -1243,8 +1243,6 @@ function handleClientReady(client, message) noChanges: true, newRev:pad.getHeadRevisionNumber() }}; - - console.log("About to send client reconnect event"); client.json.send(Msg); } }); diff --git a/src/static/js/collab_client.js b/src/static/js/collab_client.js index 825803f1..e2f1240a 100644 --- a/src/static/js/collab_client.js +++ b/src/static/js/collab_client.js @@ -349,38 +349,53 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad) return; } - var currRev = msg.currRev; + var headRev = msg.headRev; var newRev = msg.newRev; var changeset = msg.changeset; var author = (msg.author || ''); var apool = msg.apool; - if (rev + 1 == currRev) + if (msgQueue.length > 0) { - if (author == pad.getUserId()) + if (newRev != (msgQueue[msgQueue.length - 1].newRev + 1)) { - editor.applyPreparedChangesetToBase(); - setStateIdle(); - callCatchingErrors("onInternalAction", function() - { - callbacks.onInternalAction("commitAcceptedByServer"); - }); - callCatchingErrors("onConnectionTrouble", function() - { - callbacks.onConnectionTrouble("OK"); - }); - handleUserChanges(); - } - else - { - editor.applyChangesToBase(changeset, author, apool); + window.console.warn("bad message revision on ACCEPT_COMMIT: " + newRev + " not " + (msgQueue[msgQueue.length - 1][0] + 1)); + // setChannelState("DISCONNECTED", "badmessage_acceptcommit"); + return; } + msg.type = "NEW_CHANGES"; + msgQueue.push(msg); + return; } - if (rev + 1 < currRev) + + if (newRev != (rev + 1)) + { + window.console.warn("bad message revision on ACCEPT_COMMIT: " + newRev + " not " + (rev + 1)); + // setChannelState("DISCONNECTED", "badmessage_acceptcommit"); + return; + } + + rev = newRev; + if (author == pad.getUserId()) + { + editor.applyPreparedChangesetToBase(); + setStateIdle(); + callCatchingErrors("onInternalAction", function() + { + callbacks.onInternalAction("commitAcceptedByServer"); + }); + callCatchingErrors("onConnectionTrouble", function() + { + callbacks.onConnectionTrouble("OK"); + }); + handleUserChanges(); + } + else { editor.applyChangesToBase(changeset, author, apool); } - if (currRev == newRev) + + if (newRev == headRev) { rev = newRev; socketIOError = false; From b4068144c399848e12a1e3cfaf415917fb840499 Mon Sep 17 00:00:00 2001 From: anugu-chegg Date: Tue, 3 Apr 2018 18:51:14 +0530 Subject: [PATCH 34/43] Refactor code --- src/node/handler/PadMessageHandler.js | 40 ++++++++++++++------------- src/static/js/collab_client.js | 32 +++++++++++++-------- src/static/js/pad.js | 6 ++-- 3 files changed, 43 insertions(+), 35 deletions(-) diff --git a/src/node/handler/PadMessageHandler.js b/src/node/handler/PadMessageHandler.js index 63349f14..c9e0c73e 100644 --- a/src/node/handler/PadMessageHandler.js +++ b/src/node/handler/PadMessageHandler.js @@ -1154,16 +1154,16 @@ function handleClientReady(client, message) //Save the revision in sessioninfos, we take the revision from the info the client send to us sessioninfos[client.id].rev = message.client_rev; - var changesetsNeeded = []; + //During the client reconnect, client might miss some revisions from other clients. By using client revision, + //this below code sends all the revisions missed during the client reconnect + var revisionsNeeded = []; var changesets = {}; - var changesetsAuthor = {}; - var changesetsTimestamp = {}; var startNum = message.client_rev + 1; var endNum = pad.getHeadRevisionNumber() + 1; async.series([ - //fetch all changesets we need + //push all the revision numbers needed into revisionsNeeded array function(callback) { var headNum = pad.getHeadRevisionNumber(); @@ -1171,67 +1171,69 @@ function handleClientReady(client, message) endNum = headNum+1; if (startNum < 0) startNum = 0; - //create a array for all changesets, we will - //replace the values with the changeset later + for(var r=startNum;r Date: Fri, 20 Apr 2018 01:36:30 +0530 Subject: [PATCH 35/43] Remove leftover code from earlier commits --- src/node/handler/PadMessageHandler.js | 2 +- src/static/js/pad.js | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/node/handler/PadMessageHandler.js b/src/node/handler/PadMessageHandler.js index c9e0c73e..b575125a 100644 --- a/src/node/handler/PadMessageHandler.js +++ b/src/node/handler/PadMessageHandler.js @@ -1243,7 +1243,7 @@ function handleClientReady(client, message) var Msg = {"type":"COLLABROOM", "data":{type:"CLIENT_RECONNECT", noChanges: true, - newRev:pad.getHeadRevisionNumber() + newRev: pad.getHeadRevisionNumber() }}; client.json.send(Msg); } diff --git a/src/static/js/pad.js b/src/static/js/pad.js index ac6d6372..de613910 100644 --- a/src/static/js/pad.js +++ b/src/static/js/pad.js @@ -201,8 +201,6 @@ function handshake() }); socket.once('connect', function () { - // Setup our own connected flag since socketio one doesn't work accurately - socket.realConnected = true; sendClientReady(false); }); From ba322012d7151310496a716f2e968101493d860a Mon Sep 17 00:00:00 2001 From: "translatewiki.net" Date: Mon, 23 Apr 2018 08:52:57 +0200 Subject: [PATCH 36/43] Localisation updates from https://translatewiki.net. --- src/locales/pms.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/locales/pms.json b/src/locales/pms.json index c73567f5..cdc80bea 100644 --- a/src/locales/pms.json +++ b/src/locales/pms.json @@ -120,5 +120,10 @@ "pad.impexp.importbutton": "Amporté adess", "pad.impexp.importing": "An camin ch'as ampòrta...", "pad.impexp.confirmimport": "Amportand n'archivi as dëscancelërà ël test corent dël feuj. É-lo sigur ëd vorèj felo?", - "pad.impexp.convertFailed": "I l'oma nen podù amporté s'archivi. Për piasì, ch'a deuvra n'àutr formà ëd document o ch'a còpia e ancòla a man" + "pad.impexp.convertFailed": "I l'oma nen podù amporté s'archivi. Për piasì, ch'a deuvra n'àutr formà ëd document o ch'a còpia e ancòla a man", + "pad.impexp.padHasData": "I l'oma nen podù amporté s'archivi përché 's feuj a l'ha già avù dle modìfiche; për piasì, ch'a ampòrta un feuj neuv", + "pad.impexp.uploadFailed": "Ël cariament a l'ha falì, për piasì ch'a preuva torna", + "pad.impexp.importfailed": "Amportassion falìa", + "pad.impexp.copypaste": "Për piasì, ch'a còpia e ancòla", + "pad.impexp.exportdisabled": "L'esportassion an formà {{type}} a l'é disativà. Për piasì, ch'a contata sò aministrator ëd sistema për ij detaj." } From 903a2c8e43641574ac46f8be56cefd9278bbeb11 Mon Sep 17 00:00:00 2001 From: muxator Date: Thu, 3 May 2018 23:54:08 +0200 Subject: [PATCH 37/43] createRelease.sh: added error checking in modify_files() Otherwise, when inserting a multiline changelog sed would with this message: sed: -e expression #1, char 27: unterminated `s' command And the script would continue with an unmodified CHANGELOG.md For simmetry, added the same check to package.json, too --- bin/createRelease.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bin/createRelease.sh b/bin/createRelease.sh index 5afced8f..bffa96ad 100755 --- a/bin/createRelease.sh +++ b/bin/createRelease.sh @@ -66,8 +66,11 @@ function check_api_token { function modify_files { # Add changelog text to first line of CHANGELOG.md sed -i "1s/^/${changelogText}\n/" CHANGELOG.md + [[ $? != 0 ]] && echo "Aborting: Error modifying CHANGELOG.md" && exit 1 + # Replace version number of etherpad in package.json sed -i -r "s/(\"version\"[ ]*: \").*(\")/\1$VERSION\2/" src/package.json + [[ $? != 0 ]] && echo "Aborting: Error modifying package.json" && exit 1 } function create_release_branch { From 6dbeca217ed7209e63fa510d59a468136c3c0052 Mon Sep 17 00:00:00 2001 From: muxator Date: Fri, 4 May 2018 00:36:09 +0200 Subject: [PATCH 38/43] createRelease.sh: changelog editing failed for multiline messages sed does not accept multiline strings in its replacement text. Let's replace newlines with literal "\n" in modify_files() --- bin/createRelease.sh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/bin/createRelease.sh b/bin/createRelease.sh index bffa96ad..0439026b 100755 --- a/bin/createRelease.sh +++ b/bin/createRelease.sh @@ -65,7 +65,16 @@ function check_api_token { function modify_files { # Add changelog text to first line of CHANGELOG.md - sed -i "1s/^/${changelogText}\n/" CHANGELOG.md + + msg="" + # source: https://unix.stackexchange.com/questions/9784/how-can-i-read-line-by-line-from-a-variable-in-bash#9789 + while IFS= read -r line + do + # replace newlines with literal "\n" for using with sed + msg+="$line\n" + done < <(printf '%s\n' "${changelogText}") + + sed -i "1s/^/${msg}\n/" CHANGELOG.md [[ $? != 0 ]] && echo "Aborting: Error modifying CHANGELOG.md" && exit 1 # Replace version number of etherpad in package.json From 10d555bc91a04e1d4316d56ae1d7d092dfcfaaf1 Mon Sep 17 00:00:00 2001 From: muxator Date: Fri, 4 May 2018 23:15:22 +0200 Subject: [PATCH 39/43] changelog: better specified CVE description fixes #3372 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index df249c25..9dd333fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ # 1.6.4 * SECURITY: exploitable /admin access - CVE-2018-9845 - * SECURITY: DoS with pad exports - CVE-2018-9327 + * SECURITY: DoS with pad exports and arbitrary code execution - CVE-2018-9327 * SECURITY: Remote Code Execution - CVE-2018-9326 * SECURITY: Pad data leak - CVE-2018-9325 * Fix: Admin redirect URL From e13ae0aec58413293bb7368436c8eb3c2f760f88 Mon Sep 17 00:00:00 2001 From: muxator Date: Fri, 4 May 2018 23:24:58 +0200 Subject: [PATCH 40/43] changelog: better specified CVE description Previous commit was wrong. Fixes #3372, really. --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9dd333fe..7de4b605 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,9 +6,9 @@ * FIX: unbreak Safari iOS line wrapping # 1.6.4 - * SECURITY: exploitable /admin access - CVE-2018-9845 - * SECURITY: DoS with pad exports and arbitrary code execution - CVE-2018-9327 - * SECURITY: Remote Code Execution - CVE-2018-9326 + * SECURITY: Access Control bypass on /admin - CVE-2018-9845 + * SECURITY: Remote Code Execution through pad export - CVE-2018-9327 + * SECURITY: Remote Code Execution through JSONP handling - CVE-2018-9326 * SECURITY: Pad data leak - CVE-2018-9325 * Fix: Admin redirect URL * Fix: Various script Fixes From bfec44e34622295e2029c3779624ca4cd60e6307 Mon Sep 17 00:00:00 2001 From: muxator Date: Fri, 4 May 2018 23:40:09 +0200 Subject: [PATCH 41/43] Release version 1.6.6 --- CHANGELOG.md | 5 +++++ src/package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7de4b605..1293b578 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.6.6 + * FIX: line numbers are aligned with text again (broken in 1.6.4) + * FIX: text entered between connection loss and reconnection was not saved + * FIX: diagnostic call failed when etherpad was exposed in a subdirectory + # 1.6.5 * SECURITY: Escape data when listing available plugins * FIX: Fix typo in apicalls.js which prevented importing isValidJSONPName diff --git a/src/package.json b/src/package.json index 9813d6ab..cb243ccb 100644 --- a/src/package.json +++ b/src/package.json @@ -55,6 +55,6 @@ "repository" : { "type" : "git", "url" : "http://github.com/ether/etherpad-lite.git" }, - "version" : "1.6.5", + "version" : "1.6.6", "license" : "Apache-2.0" } From 784bd8c7cc02c15bb1e136a2bba22767d0bb69d4 Mon Sep 17 00:00:00 2001 From: Wikinaut Date: Fri, 11 May 2018 01:10:33 +0200 Subject: [PATCH 42/43] Update settings.json.template harmonizing the database name. "store" is the table name - not to be used here! Database name must not contain "-", but can contain "_". See https://github.com/ether/etherpad-lite/wiki/How-to-use-Etherpad-Lite-with-MySQL --- settings.json.template | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/settings.json.template b/settings.json.template index 699880bd..b5b1ccfb 100644 --- a/settings.json.template +++ b/settings.json.template @@ -45,12 +45,14 @@ }, /* An Example of MySQL Configuration + See https://github.com/ether/etherpad-lite/wiki/How-to-use-Etherpad-Lite-with-MySQL + "dbType" : "mysql", "dbSettings" : { "user" : "root", "host" : "localhost", "password": "", - "database": "store", + "database": "etherpad_lite_db", "charset" : "utf8mb4" }, */ From 6dd172d6b76cb219f0aa095ea09e43ef7f259d3d Mon Sep 17 00:00:00 2001 From: Wikinaut Date: Fri, 11 May 2018 01:14:47 +0200 Subject: [PATCH 43/43] Update settings.json.template --- settings.json.template | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/settings.json.template b/settings.json.template index b5b1ccfb..4275563a 100644 --- a/settings.json.template +++ b/settings.json.template @@ -49,9 +49,9 @@ "dbType" : "mysql", "dbSettings" : { - "user" : "root", + "user" : "etherpaduser", "host" : "localhost", - "password": "", + "password": "PASSWORD", "database": "etherpad_lite_db", "charset" : "utf8mb4" },