summaryrefslogtreecommitdiff
path: root/src/node/handler
diff options
context:
space:
mode:
Diffstat (limited to 'src/node/handler')
-rw-r--r--src/node/handler/APIHandler.js47
-rw-r--r--src/node/handler/ExportHandler.js300
-rw-r--r--src/node/handler/ImportHandler.js6
-rw-r--r--src/node/handler/PadMessageHandler.js3
4 files changed, 209 insertions, 147 deletions
diff --git a/src/node/handler/APIHandler.js b/src/node/handler/APIHandler.js
index 62025c50..273a58a6 100644
--- a/src/node/handler/APIHandler.js
+++ b/src/node/handler/APIHandler.js
@@ -300,10 +300,55 @@ var version =
, "getChatHistory" : ["padID", "start", "end"]
, "getChatHead" : ["padID"]
}
+, "1.2.10":
+ { "createGroup" : []
+ , "createGroupIfNotExistsFor" : ["groupMapper"]
+ , "deleteGroup" : ["groupID"]
+ , "listPads" : ["groupID"]
+ , "listAllPads" : []
+ , "createDiffHTML" : ["padID", "startRev", "endRev"]
+ , "createPad" : ["padID", "text"]
+ , "createGroupPad" : ["groupID", "padName", "text"]
+ , "createAuthor" : ["name"]
+ , "createAuthorIfNotExistsFor": ["authorMapper" , "name"]
+ , "listPadsOfAuthor" : ["authorID"]
+ , "createSession" : ["groupID", "authorID", "validUntil"]
+ , "deleteSession" : ["sessionID"]
+ , "getSessionInfo" : ["sessionID"]
+ , "listSessionsOfGroup" : ["groupID"]
+ , "listSessionsOfAuthor" : ["authorID"]
+ , "getText" : ["padID", "rev"]
+ , "setText" : ["padID", "text"]
+ , "getHTML" : ["padID", "rev"]
+ , "setHTML" : ["padID", "html"]
+ , "getAttributePool" : ["padID"]
+ , "getRevisionsCount" : ["padID"]
+ , "getRevisionChangeset" : ["padID", "rev"]
+ , "getLastEdited" : ["padID"]
+ , "deletePad" : ["padID"]
+ , "copyPad" : ["sourceID", "destinationID", "force"]
+ , "movePad" : ["sourceID", "destinationID", "force"]
+ , "getReadOnlyID" : ["padID"]
+ , "getPadID" : ["roID"]
+ , "setPublicStatus" : ["padID", "publicStatus"]
+ , "getPublicStatus" : ["padID"]
+ , "setPassword" : ["padID", "password"]
+ , "isPasswordProtected" : ["padID"]
+ , "listAuthorsOfPad" : ["padID"]
+ , "padUsersCount" : ["padID"]
+ , "getAuthorName" : ["authorID"]
+ , "padUsers" : ["padID"]
+ , "sendClientsMessage" : ["padID", "msg"]
+ , "listAllGroups" : []
+ , "checkToken" : []
+ , "getChatHistory" : ["padID"]
+ , "getChatHistory" : ["padID", "start", "end"]
+ , "getChatHead" : ["padID"]
+ }
};
// set the latest available API version here
-exports.latestApiVersion = '1.2.9';
+exports.latestApiVersion = '1.2.10';
// exports the versions so it can be used by the new Swagger endpoint
exports.version = version;
diff --git a/src/node/handler/ExportHandler.js b/src/node/handler/ExportHandler.js
index 8ff5bc48..a748d3f2 100644
--- a/src/node/handler/ExportHandler.js
+++ b/src/node/handler/ExportHandler.js
@@ -27,6 +27,7 @@ var async = require("async");
var fs = require("fs");
var settings = require('../utils/Settings');
var os = require('os');
+var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks");
//load abiword only if its enabled
if(settings.abiword != null)
@@ -45,175 +46,186 @@ if(os.type().indexOf("Windows") > -1)
*/
exports.doExport = function(req, res, padId, type)
{
- //tell the browser that this is a downloadable file
- res.attachment(padId + "." + type);
+ var fileName = padId;
- //if this is a plain text export, we can do this directly
- // We have to over engineer this because tabs are stored as attributes and not plain text
+ // allow fileName to be overwritten by a hook, the type type is kept static for security reasons
+ hooks.aCallFirst("exportFileName", padId,
+ function(err, hookFileName){
+ // if fileName is set then set it to the padId, note that fileName is returned as an array.
+ if(hookFileName) fileName = hookFileName;
- if(type == "txt")
- {
- var txt;
- var randNum;
- var srcFile, destFile;
- async.series([
- //render the txt document
- function(callback)
+ //tell the browser that this is a downloadable file
+ res.attachment(fileName + "." + type);
+
+ //if this is a plain text export, we can do this directly
+ // We have to over engineer this because tabs are stored as attributes and not plain text
+
+ if(type == "txt")
{
- exporttxt.getPadTXTDocument(padId, req.params.rev, false, function(err, _txt)
- {
- if(ERR(err, callback)) return;
- txt = _txt;
- callback();
- });
- },
- //decide what to do with the txt export
- function(callback)
- {
- //if this is a txt export, we can send this from here directly
- res.send(txt);
- callback("stop");
- },
- //send the convert job to abiword
- function(callback)
- {
- //ensure html can be collected by the garbage collector
- txt = null;
-
- destFile = tempDirectory + "/eplite_export_" + randNum + "." + type;
- abiword.convertFile(srcFile, destFile, type, callback);
- },
- //send the file
- function(callback)
- {
- res.sendfile(destFile, null, callback);
- },
- //clean up temporary files
- function(callback)
- {
- async.parallel([
+ var txt;
+ var randNum;
+ var srcFile, destFile;
+
+ async.series([
+ //render the txt document
function(callback)
{
- fs.unlink(srcFile, callback);
+ exporttxt.getPadTXTDocument(padId, req.params.rev, false, function(err, _txt)
+ {
+ if(ERR(err, callback)) return;
+ txt = _txt;
+ callback();
+ });
},
+ //decide what to do with the txt export
function(callback)
{
- //100ms delay to accomidate for slow windows fs
- if(os.type().indexOf("Windows") > -1)
- {
- setTimeout(function()
+ //if this is a txt export, we can send this from here directly
+ res.send(txt);
+ callback("stop");
+ },
+ //send the convert job to abiword
+ function(callback)
+ {
+ //ensure html can be collected by the garbage collector
+ txt = null;
+
+ destFile = tempDirectory + "/etherpad_export_" + randNum + "." + type;
+ abiword.convertFile(srcFile, destFile, type, callback);
+ },
+ //send the file
+ function(callback)
+ {
+ res.sendfile(destFile, null, callback);
+ },
+ //clean up temporary files
+ function(callback)
+ {
+ async.parallel([
+ function(callback)
{
- fs.unlink(destFile, callback);
- }, 100);
- }
- else
- {
- fs.unlink(destFile, callback);
- }
+ fs.unlink(srcFile, callback);
+ },
+ function(callback)
+ {
+ //100ms delay to accomidate for slow windows fs
+ if(os.type().indexOf("Windows") > -1)
+ {
+ setTimeout(function()
+ {
+ fs.unlink(destFile, callback);
+ }, 100);
+ }
+ else
+ {
+ fs.unlink(destFile, callback);
+ }
+ }
+ ], callback);
}
- ], callback);
+ ], function(err)
+ {
+ if(err && err != "stop") ERR(err);
+ })
}
- ], function(err)
- {
- if(err && err != "stop") ERR(err);
- })
- }
- else if(type == 'dokuwiki')
- {
- var randNum;
- var srcFile, destFile;
-
- async.series([
- //render the dokuwiki document
- function(callback)
+ else if(type == 'dokuwiki')
{
- exportdokuwiki.getPadDokuWikiDocument(padId, req.params.rev, function(err, dokuwiki)
+ var randNum;
+ var srcFile, destFile;
+
+ async.series([
+ //render the dokuwiki document
+ function(callback)
+ {
+ exportdokuwiki.getPadDokuWikiDocument(padId, req.params.rev, function(err, dokuwiki)
+ {
+ res.send(dokuwiki);
+ callback("stop");
+ });
+ },
+ ], function(err)
{
- res.send(dokuwiki);
- callback("stop");
+ if(err && err != "stop") throw err;
});
- },
- ], function(err)
- {
- if(err && err != "stop") throw err;
- });
- }
- else
- {
- var html;
- var randNum;
- var srcFile, destFile;
-
- async.series([
- //render the html document
- function(callback)
- {
- exporthtml.getPadHTMLDocument(padId, req.params.rev, false, function(err, _html)
- {
- if(ERR(err, callback)) return;
- html = _html;
- callback();
- });
- },
- //decide what to do with the html export
- function(callback)
- {
- //if this is a html export, we can send this from here directly
- if(type == "html")
- {
- res.send(html);
- callback("stop");
- }
- else //write the html export to a file
- {
- randNum = Math.floor(Math.random()*0xFFFFFFFF);
- srcFile = tempDirectory + "/eplite_export_" + randNum + ".html";
- fs.writeFile(srcFile, html, callback);
- }
- },
- //send the convert job to abiword
- function(callback)
- {
- //ensure html can be collected by the garbage collector
- html = null;
-
- destFile = tempDirectory + "/eplite_export_" + randNum + "." + type;
- abiword.convertFile(srcFile, destFile, type, callback);
- },
- //send the file
- function(callback)
- {
- res.sendfile(destFile, null, callback);
- },
- //clean up temporary files
- function(callback)
+ }
+ else
{
- async.parallel([
+ var html;
+ var randNum;
+ var srcFile, destFile;
+
+ async.series([
+ //render the html document
function(callback)
{
- fs.unlink(srcFile, callback);
+ exporthtml.getPadHTMLDocument(padId, req.params.rev, false, function(err, _html)
+ {
+ if(ERR(err, callback)) return;
+ html = _html;
+ callback();
+ });
},
+ //decide what to do with the html export
function(callback)
{
- //100ms delay to accomidate for slow windows fs
- if(os.type().indexOf("Windows") > -1)
+ //if this is a html export, we can send this from here directly
+ if(type == "html")
{
- setTimeout(function()
- {
- fs.unlink(destFile, callback);
- }, 100);
+ res.send(html);
+ callback("stop");
}
- else
+ else //write the html export to a file
{
- fs.unlink(destFile, callback);
+ randNum = Math.floor(Math.random()*0xFFFFFFFF);
+ srcFile = tempDirectory + "/etherpad_export_" + randNum + ".html";
+ fs.writeFile(srcFile, html, callback);
}
+ },
+ //send the convert job to abiword
+ function(callback)
+ {
+ //ensure html can be collected by the garbage collector
+ html = null;
+
+ destFile = tempDirectory + "/etherpad_export_" + randNum + "." + type;
+ abiword.convertFile(srcFile, destFile, type, callback);
+ },
+ //send the file
+ function(callback)
+ {
+ res.sendfile(destFile, null, callback);
+ },
+ //clean up temporary files
+ function(callback)
+ {
+ async.parallel([
+ function(callback)
+ {
+ fs.unlink(srcFile, callback);
+ },
+ function(callback)
+ {
+ //100ms delay to accomidate for slow windows fs
+ if(os.type().indexOf("Windows") > -1)
+ {
+ setTimeout(function()
+ {
+ fs.unlink(destFile, callback);
+ }, 100);
+ }
+ else
+ {
+ fs.unlink(destFile, callback);
+ }
+ }
+ ], callback);
}
- ], callback);
+ ], function(err)
+ {
+ if(err && err != "stop") ERR(err);
+ })
}
- ], function(err)
- {
- if(err && err != "stop") ERR(err);
- })
- }
+ }
+ );
};
diff --git a/src/node/handler/ImportHandler.js b/src/node/handler/ImportHandler.js
index f58076bb..60fa5ffb 100644
--- a/src/node/handler/ImportHandler.js
+++ b/src/node/handler/ImportHandler.js
@@ -98,7 +98,7 @@ exports.doImport = function(req, res, padId)
}
},
function(callback){
- destFile = path.join(tmpDirectory, "eplite_import_" + randNum + ".htm");
+ destFile = path.join(tmpDirectory, "etherpad_import_" + randNum + ".htm");
// Logic for allowing external Import Plugins
hooks.aCallAll("import", {srcFile: srcFile, destFile: destFile}, function(err, result){
@@ -114,7 +114,9 @@ exports.doImport = function(req, res, padId)
//convert file to html
function(callback) {
if(!importHandledByPlugin){
- if (abiword) {
+ var fileEnding = path.extname(srcFile).toLowerCase();
+ var fileIsHTML = (fileEnding === ".html" || fileEnding === ".htm");
+ if (abiword && !fileIsHTML) {
abiword.convertFile(srcFile, destFile, "htm", function(err) {
//catch convert errors
if(err) {
diff --git a/src/node/handler/PadMessageHandler.js b/src/node/handler/PadMessageHandler.js
index 26eb17a6..e1ac994e 100644
--- a/src/node/handler/PadMessageHandler.js
+++ b/src/node/handler/PadMessageHandler.js
@@ -145,6 +145,9 @@ exports.handleDisconnect = function(client)
//Go trough all user that are still on the pad, and send them the USER_LEAVE message
client.broadcast.to(session.padId).json.send(messageToTheOtherUsers);
+
+ // Allow plugins to hook into users leaving the pad
+ hooks.callAll("userLeave", session);
});
}