upgrade to 1.6.5

This commit is contained in:
ilmar 2018-04-24 12:25:56 +03:00
parent d6fa065ef2
commit 7cc7bb1abc
38 changed files with 318 additions and 191 deletions

View file

@ -8,7 +8,8 @@
"Quinn",
"Aktron",
"Mormegil",
"Dvorapa"
"Dvorapa",
"Clon"
]
},
"index.newPad": "Založ nový Pad",
@ -63,6 +64,8 @@
"pad.modals.connected": "Připojeno.",
"pad.modals.reconnecting": "Znovupřipojování k Padu…",
"pad.modals.forcereconnect": "Vynutit znovupřipojení",
"pad.modals.reconnecttimer": "Zkouším to znovu připojit",
"pad.modals.cancel": "Zrušit",
"pad.modals.userdup": "Otevřeno v jiném okně",
"pad.modals.userdup.explanation": "Zdá se, že tento Pad je na tomto počítači otevřen ve více než jednom okně.",
"pad.modals.userdup.advice": "Pro použití tohoto okna je třeba se znovu připojit.",

View file

@ -47,7 +47,7 @@
"pad.settings.fontType.monospaced": "Yewca",
"pad.settings.globalView": "Asayışo Global",
"pad.settings.language": "Zıwan:",
"pad.importExport.import_export": "Zeredayış/Teberdayış",
"pad.importExport.import_export": "Zerredayış/Teberdayış",
"pad.importExport.import": "Dosya ya zi dokumanê meqaleyê de tesadufi bar ke",
"pad.importExport.importSuccessful": "Mıwafaq biye",
"pad.importExport.export": "Mewcud bloknoti ateberd:",
@ -95,7 +95,7 @@
"timeslider.toolbar.returnbutton": "Peyser şo ped",
"timeslider.toolbar.authors": "Nuştoği:",
"timeslider.toolbar.authorsList": "Nuştoği çıniyê",
"timeslider.toolbar.exportlink.title": "Teber de",
"timeslider.toolbar.exportlink.title": "Teberdayış",
"timeslider.exportCurrent": "Versiyonê enewki teber de:",
"timeslider.version": "Versiyonê {{version}}",
"timeslider.saved": "{{day}} {{month}}, {{year}} de biyo qeyd",

View file

@ -65,7 +65,7 @@
"pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF",
"pad.importExport.exportopen": "ODF (Open Document Format)",
"pad.importExport.abiword.innerHTML": "Tuonti on tuettu vain HTML- ja raakatekstitiedostoista. Lisätietoja tuonnin lisäasetuksista on sivulla <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-in-Ubuntu-or-OpenSuse-or-SLES-with-AbiWord\">install abiword</a>.",
"pad.importExport.abiword.innerHTML": "Tuonti on tuettu vain HTML- ja raakatekstitiedostoista. Monipuoliset tuontiominaisuudet ovat käytettävissä <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">asentamalla AbiWord</a>.",
"pad.modals.connected": "Yhdistetty.",
"pad.modals.reconnecting": "Muodostetaan yhteyttä muistioon uudelleen...",
"pad.modals.forcereconnect": "Pakota yhdistämään uudelleen",

View file

@ -23,7 +23,8 @@
"Fylip22",
"C13m3n7",
"Wladek92",
"Urhixidur"
"Urhixidur",
"Envlh"
]
},
"index.newPad": "Nouveau pad",
@ -48,7 +49,7 @@
"pad.colorpicker.save": "Enregistrer",
"pad.colorpicker.cancel": "Annuler",
"pad.loading": "Chargement…",
"pad.noCookie": "Le témoin (cookie) na pas pu être trouvé. Veuillez autoriser les témoins dans votre navigateur!",
"pad.noCookie": "Le cookie na pas pu être trouvé. Veuillez autoriser les cookies dans votre navigateur!",
"pad.passwordRequired": "Vous avez besoin d'un mot de passe pour accéder à ce pad",
"pad.permissionDenied": "Vous n'avez pas la permission daccéder à ce pad",
"pad.wrongPassword": "Votre mot de passe est incorrect",

View file

@ -5,7 +5,8 @@
"Dilyaramude",
"George Animal",
"Gomada",
"Mehk63"
"Mehk63",
"Ghybu"
]
},
"index.newPad": "Bloknota nû",
@ -40,6 +41,7 @@
"pad.importExport.exportpdf": "PDF",
"pad.modals.connected": "Hate girêdan.",
"pad.modals.reconnecting": "Ji bloknota te re dîsa tê girêdan...",
"pad.modals.cancel": "Betal bike",
"pad.modals.userdup": "Di pencereyek din de vebû",
"pad.modals.userdup.advice": "Ji bo di vê pencereye de bikarbînîy dîsa giredanek çeke.",
"pad.modals.unauth": "Desthilatdar nîne",

View file

@ -7,7 +7,8 @@
"Okras",
"Volkov",
"Nzeemin",
"Facenapalm"
"Facenapalm",
"Patrick Star"
]
},
"index.newPad": "Создать",
@ -58,7 +59,7 @@
"pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF",
"pad.importExport.exportopen": "ODF (документ OpenOffice)",
"pad.importExport.abiword.innerHTML": "Вы можете импортировать только из обычного текста или HTML. Для более продвинутых функций импорта, пожалуйста, <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-in-Ubuntu-or-OpenSuse-or-SLES-with-AbiWord\">установите AbiWord</a>.",
"pad.importExport.abiword.innerHTML": "Вы можете импортировать только из обычного текста или HTML. Для более продвинутых функций импорта, пожалуйста, <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">установите AbiWord</a>.",
"pad.modals.connected": "Подключен.",
"pad.modals.reconnecting": "Повторное подключение к вашему документу",
"pad.modals.forcereconnect": "Принудительное переподключение",

View file

@ -11,12 +11,12 @@
},
"index.newPad": "కొత్త పలక",
"index.createOpenPad": "ఒక పేరుతో పలకని సృష్టించండి లేదా అదే పేరుతో ఉన్న పలకని తెరవండి",
"pad.toolbar.bold.title": "మందం",
"pad.toolbar.italic.title": "వాలు అక్షరాలు",
"pad.toolbar.bold.title": "బొద్దు (Ctrl+B)",
"pad.toolbar.italic.title": "వాలు (Ctrl+I)",
"pad.toolbar.underline.title": "క్రిందగీత",
"pad.toolbar.strikethrough.title": "కొట్టివేత (Ctrl+5)",
"pad.toolbar.ol.title": "నిర్ధేశింపబడిన జాబితా",
"pad.toolbar.ul.title": "అనిర్దేశిత జాబితా, ( క్రమపద్ధతి లేని జాబితా )",
"pad.toolbar.ol.title": "క్రమ జాబితా (Ctrl+Shift+N)",
"pad.toolbar.ul.title": "బిందు జాబితా (Ctrl+Shift+L)",
"pad.toolbar.undo.title": "చేయవద్దు",
"pad.toolbar.redo.title": "తిరిగిచెయ్యి",
"pad.toolbar.clearAuthorship.title": "మూలకర్తపు వర్ణాలను తీసివేయండి",
@ -53,6 +53,7 @@
"pad.modals.connected": "సంబంధం కుదిరింది.",
"pad.modals.reconnecting": "మీ పలకకు మరల సంబంధం కలుపుతుంది...",
"pad.modals.forcereconnect": "బలవంతంగానైనా సంబంధం కుదిరించు",
"pad.modals.cancel": "రద్దుచేయి",
"pad.modals.userdup.explanation": "ఈ పలక, ఈ కంప్యూటర్లో ఒకటికన్న ఎక్కువ గవాక్షములలో తెరుచుకున్నట్లు అనిపిస్తుంది.",
"pad.modals.userdup.advice": "బదులుగా ఈ గవాక్షమును వాడడానికి మరల సంబంధం కలపండి",
"pad.modals.unauth": "అధికారం లేదు",

View file

@ -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": "輸入您的姓名",

View file

@ -25,7 +25,7 @@ var customError = require("../utils/customError");
var randomString = require('ep_etherpad-lite/static/js/pad_utils').randomString;
exports.getColorPalette = function(){
return ["#ffc7c7", "#fff1c7", "#e3ffc7", "#c7ffd5", "#c7ffff", "#c7d5ff", "#e3c7ff", "#ffc7f1", "#ff8f8f", "#ffe38f", "#c7ff8f", "#8fffab", "#8fffff", "#8fabff", "#c78fff", "#ff8fe3", "#d97979", "#d9c179", "#a9d979", "#79d991", "#79d9d9", "#7991d9", "#a979d9", "#d979c1", "#d9a9a9", "#d9cda9", "#c1d9a9", "#a9d9b5", "#a9d9d9", "#a9b5d9", "#c1a9d9", "#d9a9cd", "#4c9c82", "#12d1ad", "#2d8e80", "#7485c3", "#a091c7", "#3185ab", "#6818b4", "#e6e76d", "#a42c64", "#f386e5", "#4ecc0c", "#c0c236", "#693224", "#b5de6a", "#9b88fd", "#358f9b", "#496d2f", "#e267fe", "#d23056", "#1a1a64", "#5aa335", "#d722bb", "#86dc6c", "#b5a714", "#955b6a", "#9f2985", "#4b81c8", "#3d6a5b", "#434e16", "#d16084", "#af6a0e", "#8c8bd8"];
return ["#ffc7c7", "#fff1c7", "#e3ffc7", "#c7ffd5", "#c7ffff", "#c7d5ff", "#e3c7ff", "#ffc7f1", "#ffa8a8", "#ffe699", "#cfff9e", "#99ffb3", "#a3ffff", "#99b3ff", "#cc99ff", "#ff99e5", "#e7b1b1", "#e9dcAf", "#cde9af", "#bfedcc", "#b1e7e7", "#c3cdee", "#d2b8ea", "#eec3e6", "#e9cece", "#e7e0ca", "#d3e5c7", "#bce1c5", "#c1e2e2", "#c1c9e2", "#cfc1e2", "#e0bdd9", "#baded3", "#a0f8eb", "#b1e7e0", "#c3c8e4", "#cec5e2", "#b1d5e7", "#cda8f0", "#f0f0a8", "#f2f2a6", "#f5a8eb", "#c5f9a9", "#ececbb", "#e7c4bc", "#daf0b2", "#b0a0fd", "#bce2e7", "#cce2bb", "#ec9afe", "#edabbd", "#aeaeea", "#c4e7b1", "#d722bb", "#f3a5e7", "#ffa8a8", "#d8c0c5", "#eaaedd", "#adc6eb", "#bedad1", "#dee9af", "#e9afc2", "#f8d2a0", "#b3b3e6"];
};
/**
@ -42,9 +42,9 @@ exports.doesAuthorExists = function (authorID, callback)
}
/**
* Returns the AuthorID for a token.
* @param {String} token The token
* @param {Function} callback callback (err, author)
* Returns the AuthorID for a token.
* @param {String} token The token
* @param {Function} callback callback (err, author)
*/
exports.getAuthor4Token = function (token, callback)
{
@ -57,21 +57,21 @@ exports.getAuthor4Token = function (token, callback)
}
/**
* Returns the AuthorID for a mapper.
* Returns the AuthorID for a mapper.
* @param {String} token The mapper
* @param {String} name The name of the author (optional)
* @param {Function} callback callback (err, author)
* @param {Function} callback callback (err, author)
*/
exports.createAuthorIfNotExistsFor = function (authorMapper, name, callback)
{
mapAuthorWithDBKey("mapper2author", authorMapper, function(err, author)
{
if(ERR(err, callback)) return;
//set the name of this author
if(name)
exports.setAuthorName(author.authorID, name);
//return the authorID
callback(null, author);
});
@ -80,27 +80,27 @@ exports.createAuthorIfNotExistsFor = function (authorMapper, name, callback)
/**
* Returns the AuthorID for a mapper. We can map using a mapperkey,
* so far this is token2author and mapper2author
* @param {String} mapperkey The database key name for this mapper
* @param {String} mapperkey The database key name for this mapper
* @param {String} mapper The mapper
* @param {Function} callback callback (err, author)
* @param {Function} callback callback (err, author)
*/
function mapAuthorWithDBKey (mapperkey, mapper, callback)
{
{
//try to map to an author
db.get(mapperkey + ":" + mapper, function (err, author)
{
if(ERR(err, callback)) return;
//there is no author with this mapper, so create one
if(author == null)
{
exports.createAuthor(null, function(err, author)
{
if(ERR(err, callback)) return;
//create the token2author relation
db.set(mapperkey + ":" + mapper, author.authorID);
//return the author
callback(null, author);
});
@ -110,7 +110,7 @@ function mapAuthorWithDBKey (mapperkey, mapper, callback)
{
//update the timestamp of this author
db.setSub("globalAuthor:" + author, ["timestamp"], new Date().getTime());
//return the author
callback(null, {authorID: author});
}
@ -118,20 +118,20 @@ function mapAuthorWithDBKey (mapperkey, mapper, callback)
}
/**
* Internal function that creates the database entry for an author
* @param {String} name The name of the author
* Internal function that creates the database entry for an author
* @param {String} name The name of the author
*/
exports.createAuthor = function(name, callback)
{
//create the new author name
var author = "a." + randomString(16);
//create the globalAuthors db entry
var authorObj = {"colorId" : Math.floor(Math.random()*(exports.getColorPalette().length)), "name": name, "timestamp": new Date().getTime()};
//set the global author db entry
db.set("globalAuthor:" + author, authorObj);
callback(null, {authorID: author});
}
@ -212,7 +212,7 @@ exports.listPadsOfAuthor = function (authorID, callback)
}
//everything is fine, return the pad IDs
else
{
{
var pads = [];
if(author.padIDs != null)
{
@ -238,16 +238,16 @@ exports.addPad = function (authorID, padID)
{
if(ERR(err)) return;
if(author == null) return;
//the entry doesn't exist so far, let's create it
if(author.padIDs == null)
{
author.padIDs = {};
}
//add the entry for this pad
author.padIDs[padID] = 1;// anything, because value is not used
//save the new element back
db.set("globalAuthor:" + authorID, author);
});
@ -264,11 +264,11 @@ exports.removePad = function (authorID, padID)
{
if(ERR(err)) return;
if(author == null) return;
if(author.padIDs != null)
{
//remove pad from author
delete author.padIDs[padID];
delete author.padIDs[padID];
db.set("globalAuthor:" + authorID, author);
}
});

View file

@ -464,9 +464,10 @@ Pad.prototype.copy = function copy(destinationID, force, callback) {
}
else force = true;
//kick everyone from this pad
// TODO: this presents a message on the client saying that the pad was 'deleted'. Fix this?
padMessageHandler.kickSessionsFromPad(sourceID);
// Kick everyone from this pad.
// This was commented due to https://github.com/ether/etherpad-lite/issues/3183.
// Do we really need to kick everyone out?
// padMessageHandler.kickSessionsFromPad(sourceID);
// flush the source pad:
_this.saveToDatabase();

View file

@ -22,6 +22,7 @@
var ERR = require("async-stacktrace");
var async = require("async");
var authorManager = require("./AuthorManager");
var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks.js");
var padManager = require("./PadManager");
var sessionManager = require("./SessionManager");
var settings = require("../utils/Settings");
@ -45,6 +46,14 @@ exports.checkAccess = function (padID, sessionCookie, token, password, callback)
return;
}
// allow plugins to deny access
var deniedByHook = hooks.callAll("onAccessCheck", {'padID': padID, 'password': password, 'token': token, 'sessionCookie': sessionCookie}).indexOf(false) > -1;
if(deniedByHook)
{
callback(null, {accessStatus: "deny"});
return;
}
// a valid session is required (api-only mode)
if(settings.requireSession)
{

View file

@ -24,17 +24,19 @@ var fs = require("fs");
var api = require("../db/API");
var padManager = require("../db/PadManager");
var randomString = require("../utils/randomstring");
var argv = require('../utils/Cli').argv;
//ensure we have an apikey
var apikey = null;
var apikeyFilename = argv.apikey || "./APIKEY.txt";
try
{
apikey = fs.readFileSync("./APIKEY.txt","utf8");
apikey = fs.readFileSync(apikeyFilename,"utf8");
}
catch(e)
{
apikey = randomString(32);
fs.writeFileSync("./APIKEY.txt",apikey,"utf8");
fs.writeFileSync(apikeyFilename,apikey,"utf8");
}
//a list of all functions

View file

@ -90,7 +90,7 @@ exports.doImport = function(req, res, padId)
//this allows us to accept source code files like .c or .java
function(callback) {
var fileEnding = path.extname(srcFile).toLowerCase()
, knownFileEndings = [".txt", ".doc", ".docx", ".pdf", ".odt", ".html", ".htm", ".etherpad"]
, knownFileEndings = [".txt", ".doc", ".docx", ".pdf", ".odt", ".html", ".htm", ".etherpad", ".rtf"]
, fileEndingKnown = (knownFileEndings.indexOf(fileEnding) > -1);
//if the file ending is known, continue as normal

View file

@ -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 () {

View file

@ -2,7 +2,7 @@ var eejs = require('ep_etherpad-lite/node/eejs');
exports.expressCreateServer = function (hook_name, args, cb) {
args.app.get('/admin', function(req, res) {
if('/' != req.path[req.path.length-1]) return res.redirect('/admin/');
if('/' != req.path[req.path.length-1]) return res.redirect('./admin/');
res.send( eejs.require("ep_etherpad-lite/templates/admin/index.html", {}) );
});
}

View file

@ -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(response))
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});

View file

@ -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);
});
});
});
}

View file

@ -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);
}
@ -36,13 +36,16 @@ exports.basicAuth = function (req, res, next) {
var userpass = new Buffer(req.headers.authorization.split(' ')[1], 'base64').toString().split(":")
var username = userpass.shift();
var password = userpass.join(':');
if (settings.users[username] != undefined && settings.users[username].password == password) {
settings.users[username].username = username;
req.session.user = settings.users[username];
return cb(true);
}
return hooks.aCallFirst("authenticate", {req: req, res:res, next:next, username: username, password: password}, hookResultMangle(cb));
var fallback = function(success) {
if (success) return cb(true);
if (settings.users[username] != undefined && settings.users[username].password === password) {
settings.users[username].username = username;
req.session.user = settings.users[username];
return cb(true);
}
return cb(false);
};
return hooks.aCallFirst("authenticate", {req: req, res:res, next:next, username: username, password: password}, hookResultMangle(fallback));
}
hooks.aCallFirst("authenticate", {req: req, res:res, next:next}, hookResultMangle(cb));
}
@ -126,4 +129,3 @@ exports.expressConfigure = function (hook_name, args, cb) {
args.app.use(exports.basicAuth);
}

View file

@ -39,5 +39,15 @@ for ( var i = 0; i < argv.length; i++ ) {
exports.argv.credentials = arg;
}
// Override location of settings.json file
if ( prevArg == '--sessionkey' || prevArg == '-k' ) {
exports.argv.sessionkey = arg;
}
// Override location of settings.json file
if ( prevArg == '--apikey' || prevArg == '-k' ) {
exports.argv.apikey = arg;
}
prevArg = arg;
}

View file

@ -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);
})
}

View file

@ -110,31 +110,27 @@ function getHTMLFromAtext(pad, atext, authorColors)
css+="<style>\n";
for (var a in apool.numToAttrib) {
if (apool.numToAttrib.hasOwnProperty.call(a)) {
var attr = apool.numToAttrib[a];
var attr = apool.numToAttrib[a];
var newLength = null;
var propName = null;
//skip non author attributes
if (attr[0] === "author" && attr[1] !== ""){
//add to props array
propName = "author" + stripDotFromAuthorID(attr[1]);
newLength = props.push(propName);
anumMap[a] = newLength - 1;
//skip non author attributes
if(attr[0] === "author" && attr[1] !== ""){
//add to props array
var propName = "author" + stripDotFromAuthorID(attr[1]);
var newLength = props.push(propName);
anumMap[a] = newLength -1;
css+="." + propName + " {background-color: " + authorColors[attr[1]]+ "}\n";
} else if(attr[0] === "removed") {
propName = "removed";
css+="." + propName + " {background-color: " + authorColors[attr[1]]+ "}\n";
} else if(attr[0] === "removed") {
var propName = "removed";
newLength = props.push(propName);
anumMap[a] = newLength -1;
var newLength = props.push(propName);
anumMap[a] = newLength -1;
css+=".removed {text-decoration: line-through; " +
"-ms-filter:'progid:DXImageTransform.Microsoft.Alpha(Opacity=80)'; "+
"filter: alpha(opacity=80); "+
"opacity: 0.8; "+
"}\n";
}
css+=".removed {text-decoration: line-through; " +
"-ms-filter:'progid:DXImageTransform.Microsoft.Alpha(Opacity=80)'; "+
"filter: alpha(opacity=80); "+
"opacity: 0.8; "+
"}\n";
}
}

View file

@ -35,7 +35,21 @@ var queue = async.queue(doConvertTask, 1);
* @param {Function} callback Standard callback function
*/
exports.convertFile = function(srcFile, destFile, type, callback) {
queue.push({"srcFile": srcFile, "destFile": destFile, "type": type, "callback": callback});
// soffice can't convert from html to doc directly (verified with LO 5 and 6)
// we need to convert to odt first, then to doc
// to avoid `Error: no export filter for /tmp/xxxx.doc` error
if (type === 'doc') {
queue.push({
"srcFile": srcFile,
"destFile": destFile.replace(/\.doc$/, '.odt'),
"type": 'odt',
"callback": function () {
queue.push({"srcFile": srcFile.replace(/\.html$/, '.odt'), "destFile": destFile, "type": type, "callback": callback});
}
});
} else {
queue.push({"srcFile": srcFile, "destFile": destFile, "type": type, "callback": callback});
}
};
function doConvertTask(task, callback) {

View file

@ -476,11 +476,12 @@ exports.reloadSettings = function reloadSettings() {
}
if (!exports.sessionKey) {
var sessionkeyFilename = argv.sessionkey || "./SESSIONKEY.txt";
try {
exports.sessionKey = fs.readFileSync("./SESSIONKEY.txt","utf8");
exports.sessionKey = fs.readFileSync(sessionkeyFilename,"utf8");
} catch(e) {
exports.sessionKey = randomString(32);
fs.writeFileSync("./SESSIONKEY.txt",exports.sessionKey,"utf8");
fs.writeFileSync(sessionkeyFilename,exports.sessionKey,"utf8");
}
} else {
console.warn("Declaring the sessionKey in the settings.json is deprecated. This value is auto-generated now. Please remove the setting from the file.");

View file

@ -17,18 +17,18 @@
"etherpad-require-kernel" : "1.0.9",
"resolve" : "1.1.7",
"socket.io" : "1.7.3",
"ueberdb2" : "0.3.7",
"ueberdb2" : "0.3.8",
"express" : "4.13.4",
"express-session" : "1.13.0",
"cookie-parser" : "1.3.4",
"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",
"npm" : "4.0.2",
"npm" : ">=4.0.2",
"ejs" : "2.5.7",
"graceful-fs" : "4.1.3",
"slide" : "1.1.6",
@ -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"
@ -56,6 +55,6 @@
"repository" : { "type" : "git",
"url" : "http://github.com/ether/etherpad-lite.git"
},
"version" : "1.6.3",
"version" : "1.6.5",
"license" : "Apache-2.0"
}

View file

@ -31,13 +31,17 @@ body {
body.grayedout { background-color: #eee !important }
#innerdocbody {
font-size: 12px; /* overridden by body.style */
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;
}
.innerdocbody>div{
padding: 1px;
}
body.doesWrap {
/* white-space: pre-wrap; */

View file

@ -3,8 +3,9 @@ html,
body,
p {
margin: 0;
padding: 0;
padding: 0px;
}
.clear {
clear: both
}
@ -1071,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 {

View file

@ -5404,8 +5404,8 @@ function Ace2Inner(){
// height is taken to be the top offset of the next line. If we
// didn't do this special case, we would miss out on any top margin
// included on the first line. The default stylesheet doesn't add
// extra margins, but plugins might.
h = b.nextSibling.offsetTop;
// extra margins/padding, but plugins might.
h = b.nextSibling.offsetTop - window.getComputedStyle(doc.body).getPropertyValue("padding-top");
} else {
h = b.nextSibling.offsetTop - b.offsetTop;
}

View file

@ -79,12 +79,17 @@ $(document).ready(function () {
for (attr in plugin) {
if(attr == "name"){ // Hack to rewrite URLS into name
row.find(".name").html("<a target='_blank' title='Plugin details' href='https://npmjs.org/package/"+plugin['name']+"'>"+plugin['name'].substr(3)+"</a>"); // remove 'ep_'
}else{
var link = $('<a>');
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);

View file

@ -33,7 +33,7 @@ var padcookie = (function()
return null;
}
// look for (start of string OR semicolon) followed by whitespace followed by prefs=(something);
var regexResult = document.cookie.match(new RegExp("(?:^|;)\s*" + cookieName + "=([^;]*)(?:;|$)"));
var regexResult = document.cookie.match(new RegExp("(?:^|;)\\s*" + cookieName + "=([^;]*)(?:;|$)"));
if ((!regexResult) || (!regexResult[1]))
{
return null;

View file

@ -124,7 +124,7 @@ exports.getPackages = function (cb) {
var tmp = {};
tmp[data.name] = data;
flatten(tmp[undefined].dependencies);
flatten(tmp[data.name].dependencies);
cb(null, packages);
});
};

View file

@ -139,6 +139,5 @@ ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol {
</head>
<body>
<%- body %>
<div style="display:none"><a href="/javascript" data-jslicense="1">JavaScript license information</a></div>
</body>
</html>