mirror of
https://github.com/ether/etherpad-lite.git
synced 2025-04-24 01:16:15 -04:00
prepare to async: trivial reformatting
This change is only cosmetic. Its aim is do make it easier to understand the async changes that are going to be merged later on. It was extracted from the original work from Ray Bellis. To verify that nothing has changed, you can run the following command on each file touched by this commit: npm install uglify-es diff --unified <(uglify-js --beautify bracketize <BEFORE.js>) <(uglify-js --beautify bracketize <AFTER.js>) This is a complete script that does the same automatically (works from a mercurial clone): ```bash #!/usr/bin/env bash set -eu REVISION=<THIS_REVISION> PARENT_REV=$(hg identify --rev "${REVISION}" --template '{p1rev}') FILE_LIST=$(hg status --no-status --change ${REVISION}) UGLIFYJS="node_modules/uglify-es/bin/uglifyjs" for FILE_NAME in ${FILE_LIST[@]}; do echo "Checking ${FILE_NAME}" diff --unified \ <("${UGLIFYJS}" --beautify bracketize <(hg cat --rev "${PARENT_REV}" "${FILE_NAME}")) \ <("${UGLIFYJS}" --beautify bracketize <(hg cat --rev "${REVISION}" "${FILE_NAME}")) done ```
This commit is contained in:
parent
cc23bd18a4
commit
9497ee734f
33 changed files with 2706 additions and 2943 deletions
File diff suppressed because it is too large
Load diff
|
@ -18,25 +18,33 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
var ERR = require("async-stacktrace");
|
||||
var db = require("./DB").db;
|
||||
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", "#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"];
|
||||
exports.getColorPalette = function() {
|
||||
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"
|
||||
];
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if the author exists
|
||||
*/
|
||||
exports.doesAuthorExists = function (authorID, callback)
|
||||
exports.doesAuthorExists = function(authorID, callback)
|
||||
{
|
||||
//check if the database entry of this author exists
|
||||
db.get("globalAuthor:" + authorID, function (err, author)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
// check if the database entry of this author exists
|
||||
db.get("globalAuthor:" + authorID, function(err, author) {
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
callback(null, author != null);
|
||||
});
|
||||
}
|
||||
|
@ -46,12 +54,12 @@ exports.doesAuthorExists = function (authorID, callback)
|
|||
* @param {String} token The token
|
||||
* @param {Function} callback callback (err, author)
|
||||
*/
|
||||
exports.getAuthor4Token = function (token, callback)
|
||||
exports.getAuthor4Token = function(token, callback)
|
||||
{
|
||||
mapAuthorWithDBKey("token2author", token, function(err, author)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
//return only the sub value authorID
|
||||
mapAuthorWithDBKey("token2author", token, function(err, author) {
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
// return only the sub value authorID
|
||||
callback(null, author ? author.authorID : author);
|
||||
});
|
||||
}
|
||||
|
@ -62,17 +70,17 @@ exports.getAuthor4Token = function (token, callback)
|
|||
* @param {String} name The name of the author (optional)
|
||||
* @param {Function} callback callback (err, author)
|
||||
*/
|
||||
exports.createAuthorIfNotExistsFor = function (authorMapper, name, callback)
|
||||
exports.createAuthorIfNotExistsFor = function(authorMapper, name, callback)
|
||||
{
|
||||
mapAuthorWithDBKey("mapper2author", authorMapper, function(err, author)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
mapAuthorWithDBKey("mapper2author", authorMapper, function(err, author) {
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
//set the name of this author
|
||||
if(name)
|
||||
if (name) {
|
||||
// set the name of this author
|
||||
exports.setAuthorName(author.authorID, name);
|
||||
}
|
||||
|
||||
//return the authorID
|
||||
// return the authorID
|
||||
callback(null, author);
|
||||
});
|
||||
}
|
||||
|
@ -86,33 +94,30 @@ exports.createAuthorIfNotExistsFor = function (authorMapper, name, callback)
|
|||
*/
|
||||
function mapAuthorWithDBKey (mapperkey, mapper, callback)
|
||||
{
|
||||
//try to map to an author
|
||||
db.get(mapperkey + ":" + mapper, function (err, author)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
// 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;
|
||||
if (author == null) {
|
||||
// there is no author with this mapper, so create one
|
||||
exports.createAuthor(null, function(err, author) {
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
//create the token2author relation
|
||||
// create the token2author relation
|
||||
db.set(mapperkey + ":" + mapper, author.authorID);
|
||||
|
||||
//return the author
|
||||
// return the author
|
||||
callback(null, author);
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//there is a author with this mapper
|
||||
//update the timestamp of this author
|
||||
// there is an author with this mapper
|
||||
// update the timestamp of this author
|
||||
db.setSub("globalAuthor:" + author, ["timestamp"], Date.now());
|
||||
|
||||
//return the author
|
||||
// return the author
|
||||
callback(null, {authorID: author});
|
||||
});
|
||||
}
|
||||
|
@ -123,13 +128,17 @@ function mapAuthorWithDBKey (mapperkey, mapper, callback)
|
|||
*/
|
||||
exports.createAuthor = function(name, callback)
|
||||
{
|
||||
//create the new author name
|
||||
// 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": Date.now()};
|
||||
// create the globalAuthors db entry
|
||||
var authorObj = {
|
||||
"colorId": Math.floor(Math.random() * (exports.getColorPalette().length)),
|
||||
"name": name,
|
||||
"timestamp": Date.now()
|
||||
};
|
||||
|
||||
//set the global author db entry
|
||||
// set the global author db entry
|
||||
db.set("globalAuthor:" + author, authorObj);
|
||||
|
||||
callback(null, {authorID: author});
|
||||
|
@ -140,19 +149,17 @@ exports.createAuthor = function(name, callback)
|
|||
* @param {String} author The id of the author
|
||||
* @param {Function} callback callback(err, authorObj)
|
||||
*/
|
||||
exports.getAuthor = function (author, callback)
|
||||
exports.getAuthor = function(author, callback)
|
||||
{
|
||||
db.get("globalAuthor:" + author, callback);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the color Id of the author
|
||||
* @param {String} author The id of the author
|
||||
* @param {Function} callback callback(err, colorId)
|
||||
*/
|
||||
exports.getAuthorColorId = function (author, callback)
|
||||
exports.getAuthorColorId = function(author, callback)
|
||||
{
|
||||
db.getSub("globalAuthor:" + author, ["colorId"], callback);
|
||||
}
|
||||
|
@ -163,7 +170,7 @@ exports.getAuthorColorId = function (author, callback)
|
|||
* @param {String} colorId The color id of the author
|
||||
* @param {Function} callback (optional)
|
||||
*/
|
||||
exports.setAuthorColorId = function (author, colorId, callback)
|
||||
exports.setAuthorColorId = function(author, colorId, callback)
|
||||
{
|
||||
db.setSub("globalAuthor:" + author, ["colorId"], colorId, callback);
|
||||
}
|
||||
|
@ -173,7 +180,7 @@ exports.setAuthorColorId = function (author, colorId, callback)
|
|||
* @param {String} author The id of the author
|
||||
* @param {Function} callback callback(err, name)
|
||||
*/
|
||||
exports.getAuthorName = function (author, callback)
|
||||
exports.getAuthorName = function(author, callback)
|
||||
{
|
||||
db.getSub("globalAuthor:" + author, ["name"], callback);
|
||||
}
|
||||
|
@ -184,7 +191,7 @@ exports.getAuthorName = function (author, callback)
|
|||
* @param {String} name The name of the author
|
||||
* @param {Function} callback (optional)
|
||||
*/
|
||||
exports.setAuthorName = function (author, name, callback)
|
||||
exports.setAuthorName = function(author, name, callback)
|
||||
{
|
||||
db.setSub("globalAuthor:" + author, ["name"], name, callback);
|
||||
}
|
||||
|
@ -194,33 +201,33 @@ exports.setAuthorName = function (author, name, callback)
|
|||
* @param {String} author The id of the author
|
||||
* @param {Function} callback (optional)
|
||||
*/
|
||||
exports.listPadsOfAuthor = function (authorID, callback)
|
||||
exports.listPadsOfAuthor = function(authorID, callback)
|
||||
{
|
||||
/* There are two other places where this array is manipulated:
|
||||
* (1) When the author is added to a pad, the author object is also updated
|
||||
* (2) When a pad is deleted, each author of that pad is also updated
|
||||
*/
|
||||
//get the globalAuthor
|
||||
db.get("globalAuthor:" + authorID, function(err, author)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
//author does not exists
|
||||
if(author == null)
|
||||
{
|
||||
callback(new customError("authorID does not exist","apierror"))
|
||||
// get the globalAuthor
|
||||
db.get("globalAuthor:" + authorID, function(err, author) {
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
if (author == null) {
|
||||
// author does not exist
|
||||
callback(new customError("authorID does not exist", "apierror"));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//everything is fine, return the pad IDs
|
||||
// everything is fine, return the pad IDs
|
||||
var pads = [];
|
||||
if(author.padIDs != null)
|
||||
{
|
||||
for (var padId in author.padIDs)
|
||||
{
|
||||
|
||||
if (author.padIDs != null) {
|
||||
for (var padId in author.padIDs) {
|
||||
pads.push(padId);
|
||||
}
|
||||
}
|
||||
|
||||
callback(null, {padIDs: pads});
|
||||
});
|
||||
}
|
||||
|
@ -230,24 +237,22 @@ exports.listPadsOfAuthor = function (authorID, callback)
|
|||
* @param {String} author The id of the author
|
||||
* @param {String} padID The id of the pad the author contributes to
|
||||
*/
|
||||
exports.addPad = function (authorID, padID)
|
||||
exports.addPad = function(authorID, padID)
|
||||
{
|
||||
//get the entry
|
||||
db.get("globalAuthor:" + authorID, function(err, author)
|
||||
{
|
||||
if(ERR(err)) return;
|
||||
if(author == null) return;
|
||||
// get the entry
|
||||
db.get("globalAuthor:" + authorID, function(err, author) {
|
||||
if (ERR(err)) return;
|
||||
if (author == null) return;
|
||||
|
||||
//the entry doesn't exist so far, let's create it
|
||||
if(author.padIDs == null)
|
||||
{
|
||||
if (author.padIDs == null) {
|
||||
// the entry doesn't exist so far, let's create it
|
||||
author.padIDs = {};
|
||||
}
|
||||
|
||||
//add the entry for this pad
|
||||
author.padIDs[padID] = 1;// anything, because value is not used
|
||||
// add the entry for this pad
|
||||
author.padIDs[padID] = 1; // anything, because value is not used
|
||||
|
||||
//save the new element back
|
||||
// save the new element back
|
||||
db.set("globalAuthor:" + authorID, author);
|
||||
});
|
||||
}
|
||||
|
@ -257,16 +262,14 @@ exports.addPad = function (authorID, padID)
|
|||
* @param {String} author The id of the author
|
||||
* @param {String} padID The id of the pad the author contributes to
|
||||
*/
|
||||
exports.removePad = function (authorID, padID)
|
||||
exports.removePad = function(authorID, padID)
|
||||
{
|
||||
db.get("globalAuthor:" + authorID, function (err, author)
|
||||
{
|
||||
if(ERR(err)) return;
|
||||
if(author == null) return;
|
||||
db.get("globalAuthor:" + authorID, function(err, author) {
|
||||
if (ERR(err)) return;
|
||||
if (author == null) return;
|
||||
|
||||
if(author.padIDs != null)
|
||||
{
|
||||
//remove pad from author
|
||||
if (author.padIDs != null) {
|
||||
// remove pad from author
|
||||
delete author.padIDs[padID];
|
||||
db.set("globalAuthor:" + authorID, author);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* The DB Module provides a database initalized with the settings
|
||||
* The DB Module provides a database initalized with the settings
|
||||
* provided by the settings module
|
||||
*/
|
||||
|
||||
|
@ -23,7 +23,7 @@ var ueberDB = require("ueberdb2");
|
|||
var settings = require("../utils/Settings");
|
||||
var log4js = require('log4js');
|
||||
|
||||
//set database settings
|
||||
// set database settings
|
||||
var db = new ueberDB.database(settings.dbType, settings.dbSettings, null, log4js.getLogger("ueberDB"));
|
||||
|
||||
/**
|
||||
|
@ -33,24 +33,19 @@ exports.db = null;
|
|||
|
||||
/**
|
||||
* Initalizes the database with the settings provided by the settings module
|
||||
* @param {Function} callback
|
||||
* @param {Function} callback
|
||||
*/
|
||||
exports.init = function(callback)
|
||||
{
|
||||
//initalize the database async
|
||||
db.init(function(err)
|
||||
{
|
||||
//there was an error while initializing the database, output it and stop
|
||||
if(err)
|
||||
{
|
||||
exports.init = function(callback) {
|
||||
// initalize the database async
|
||||
db.init(function(err) {
|
||||
if (err) {
|
||||
// there was an error while initializing the database, output it and stop
|
||||
console.error("ERROR: Problem while initalizing the database");
|
||||
console.error(err.stack ? err.stack : err);
|
||||
process.exit(1);
|
||||
}
|
||||
//everything ok
|
||||
else
|
||||
{
|
||||
exports.db = db;
|
||||
} else {
|
||||
// everything ok
|
||||
exports.db = db;
|
||||
callback(null);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
var ERR = require("async-stacktrace");
|
||||
var customError = require("../utils/customError");
|
||||
|
@ -29,117 +28,112 @@ var sessionManager = require("./SessionManager");
|
|||
|
||||
exports.listAllGroups = function(callback) {
|
||||
db.get("groups", function (err, groups) {
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
// there are no groups
|
||||
if(groups == null) {
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
if (groups == null) {
|
||||
// there are no groups
|
||||
callback(null, {groupIDs: []});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var groupIDs = [];
|
||||
for ( var groupID in groups ) {
|
||||
for (var groupID in groups) {
|
||||
groupIDs.push(groupID);
|
||||
}
|
||||
callback(null, {groupIDs: groupIDs});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
exports.deleteGroup = function(groupID, callback)
|
||||
{
|
||||
var group;
|
||||
|
||||
async.series([
|
||||
//ensure group exists
|
||||
function (callback)
|
||||
{
|
||||
//try to get the group entry
|
||||
db.get("group:" + groupID, function (err, _group)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
//group does not exist
|
||||
if(_group == null)
|
||||
{
|
||||
callback(new customError("groupID does not exist","apierror"));
|
||||
// ensure group exists
|
||||
function (callback) {
|
||||
// try to get the group entry
|
||||
db.get("group:" + groupID, function (err, _group) {
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
if (_group == null) {
|
||||
// group does not exist
|
||||
callback(new customError("groupID does not exist", "apierror"));
|
||||
return;
|
||||
}
|
||||
|
||||
//group exists, everything is fine
|
||||
// group exists, everything is fine
|
||||
group = _group;
|
||||
callback();
|
||||
});
|
||||
},
|
||||
//iterate trough all pads of this groups and delete them
|
||||
function(callback)
|
||||
{
|
||||
//collect all padIDs in an array, that allows us to use async.forEach
|
||||
|
||||
// iterate through all pads of this group and delete them
|
||||
function(callback) {
|
||||
// collect all padIDs in an array, that allows us to use async.forEach
|
||||
var padIDs = [];
|
||||
for(var i in group.pads)
|
||||
{
|
||||
for(var i in group.pads) {
|
||||
padIDs.push(i);
|
||||
}
|
||||
|
||||
//loop trough all pads and delete them
|
||||
async.forEach(padIDs, function(padID, callback)
|
||||
{
|
||||
padManager.getPad(padID, function(err, pad)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
|
||||
// loop through all pads and delete them
|
||||
async.forEach(padIDs, function(padID, callback) {
|
||||
padManager.getPad(padID, function(err, pad) {
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
pad.remove(callback);
|
||||
});
|
||||
}, callback);
|
||||
},
|
||||
//iterate trough group2sessions and delete all sessions
|
||||
|
||||
// iterate through group2sessions and delete all sessions
|
||||
function(callback)
|
||||
{
|
||||
//try to get the group entry
|
||||
db.get("group2sessions:" + groupID, function (err, group2sessions)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
//skip if there is no group2sessions entry
|
||||
if(group2sessions == null) {callback(); return}
|
||||
|
||||
//collect all sessions in an array, that allows us to use async.forEach
|
||||
// try to get the group entry
|
||||
db.get("group2sessions:" + groupID, function (err, group2sessions) {
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
// skip if there is no group2sessions entry
|
||||
if (group2sessions == null) { callback(); return }
|
||||
|
||||
// collect all sessions in an array, that allows us to use async.forEach
|
||||
var sessions = [];
|
||||
for(var i in group2sessions.sessionsIDs)
|
||||
{
|
||||
for (var i in group2sessions.sessionsIDs) {
|
||||
sessions.push(i);
|
||||
}
|
||||
|
||||
//loop trough all sessions and delete them
|
||||
async.forEach(sessions, function(session, callback)
|
||||
{
|
||||
|
||||
// loop through all sessions and delete them
|
||||
async.forEach(sessions, function(session, callback) {
|
||||
sessionManager.deleteSession(session, callback);
|
||||
}, callback);
|
||||
});
|
||||
},
|
||||
//remove group and group2sessions entry
|
||||
function(callback)
|
||||
{
|
||||
|
||||
// remove group and group2sessions entry
|
||||
function(callback) {
|
||||
db.remove("group2sessions:" + groupID);
|
||||
db.remove("group:" + groupID);
|
||||
callback();
|
||||
},
|
||||
//unlist the group
|
||||
function(callback)
|
||||
{
|
||||
|
||||
// unlist the group
|
||||
function(callback) {
|
||||
exports.listAllGroups(function(err, groups) {
|
||||
if(ERR(err, callback)) return;
|
||||
if (ERR(err, callback)) return;
|
||||
groups = groups? groups.groupIDs : [];
|
||||
|
||||
// it's not listed
|
||||
if(groups.indexOf(groupID) == -1) {
|
||||
if (groups.indexOf(groupID) == -1) {
|
||||
// it's not listed
|
||||
callback();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// remove from the list
|
||||
groups.splice(groups.indexOf(groupID), 1);
|
||||
|
||||
// store empty groupe list
|
||||
if(groups.length == 0) {
|
||||
|
||||
// store empty group list
|
||||
if (groups.length == 0) {
|
||||
db.set("groups", {});
|
||||
callback();
|
||||
return;
|
||||
|
@ -150,50 +144,51 @@ exports.deleteGroup = function(groupID, callback)
|
|||
async.forEach(groups, function(group, cb) {
|
||||
newGroups[group] = 1;
|
||||
cb();
|
||||
},function() {
|
||||
},
|
||||
function() {
|
||||
db.set("groups", newGroups);
|
||||
callback();
|
||||
});
|
||||
});
|
||||
}
|
||||
], function(err)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
],
|
||||
function(err) {
|
||||
if (ERR(err, callback)) return;
|
||||
callback();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
exports.doesGroupExist = function(groupID, callback)
|
||||
{
|
||||
//try to get the group entry
|
||||
db.get("group:" + groupID, function (err, group)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
// try to get the group entry
|
||||
db.get("group:" + groupID, function (err, group) {
|
||||
if (ERR(err, callback)) return;
|
||||
callback(null, group != null);
|
||||
});
|
||||
}
|
||||
|
||||
exports.createGroup = function(callback)
|
||||
{
|
||||
//search for non existing groupID
|
||||
// search for non existing groupID
|
||||
var groupID = "g." + randomString(16);
|
||||
|
||||
//create the group
|
||||
|
||||
// create the group
|
||||
db.set("group:" + groupID, {pads: {}});
|
||||
|
||||
//list the group
|
||||
|
||||
// list the group
|
||||
exports.listAllGroups(function(err, groups) {
|
||||
if(ERR(err, callback)) return;
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
groups = groups? groups.groupIDs : [];
|
||||
|
||||
groups.push(groupID);
|
||||
|
||||
|
||||
// regenerate group list
|
||||
var newGroups = {};
|
||||
async.forEach(groups, function(group, cb) {
|
||||
newGroups[group] = 1;
|
||||
cb();
|
||||
},function() {
|
||||
},
|
||||
function() {
|
||||
db.set("groups", newGroups);
|
||||
callback(null, {groupID: groupID});
|
||||
});
|
||||
|
@ -202,129 +197,121 @@ exports.createGroup = function(callback)
|
|||
|
||||
exports.createGroupIfNotExistsFor = function(groupMapper, callback)
|
||||
{
|
||||
//ensure mapper is optional
|
||||
if(typeof groupMapper != "string")
|
||||
{
|
||||
callback(new customError("groupMapper is no string","apierror"));
|
||||
// ensure mapper is optional
|
||||
if (typeof groupMapper != "string") {
|
||||
callback(new customError("groupMapper is no string", "apierror"));
|
||||
return;
|
||||
}
|
||||
|
||||
//try to get a group for this mapper
|
||||
db.get("mapper2group:"+groupMapper, function(err, groupID)
|
||||
{
|
||||
|
||||
// try to get a group for this mapper
|
||||
db.get("mapper2group:" + groupMapper, function(err, groupID) {
|
||||
function createGroupForMapper(cb) {
|
||||
exports.createGroup(function(err, responseObj)
|
||||
{
|
||||
if(ERR(err, cb)) return;
|
||||
|
||||
//create the mapper entry for this group
|
||||
db.set("mapper2group:"+groupMapper, responseObj.groupID);
|
||||
|
||||
exports.createGroup(function(err, responseObj) {
|
||||
if (ERR(err, cb)) return;
|
||||
|
||||
// create the mapper entry for this group
|
||||
db.set("mapper2group:" + groupMapper, responseObj.groupID);
|
||||
|
||||
cb(null, responseObj);
|
||||
});
|
||||
}
|
||||
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
// there is a group for this mapper
|
||||
if(groupID) {
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
if (groupID) {
|
||||
// there is a group for this mapper
|
||||
exports.doesGroupExist(groupID, function(err, exists) {
|
||||
if(ERR(err, callback)) return;
|
||||
if(exists) return callback(null, {groupID: groupID});
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
if (exists) return callback(null, {groupID: groupID});
|
||||
|
||||
// hah, the returned group doesn't exist, let's create one
|
||||
createGroupForMapper(callback)
|
||||
})
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//there is no group for this mapper, let's create a group
|
||||
// there is no group for this mapper, let's create a group
|
||||
createGroupForMapper(callback)
|
||||
});
|
||||
}
|
||||
|
||||
exports.createGroupPad = function(groupID, padName, text, callback)
|
||||
{
|
||||
//create the padID
|
||||
// create the padID
|
||||
var padID = groupID + "$" + padName;
|
||||
|
||||
async.series([
|
||||
//ensure group exists
|
||||
function (callback)
|
||||
{
|
||||
exports.doesGroupExist(groupID, function(err, exists)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
//group does not exist
|
||||
if(exists == false)
|
||||
{
|
||||
callback(new customError("groupID does not exist","apierror"));
|
||||
// ensure group exists
|
||||
function (callback) {
|
||||
exports.doesGroupExist(groupID, function(err, exists) {
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
if (exists == false) {
|
||||
// group does not exist
|
||||
callback(new customError("groupID does not exist", "apierror"));
|
||||
return;
|
||||
}
|
||||
|
||||
//group exists, everything is fine
|
||||
// group exists, everything is fine
|
||||
callback();
|
||||
});
|
||||
},
|
||||
//ensure pad does not exists
|
||||
function (callback)
|
||||
{
|
||||
padManager.doesPadExists(padID, function(err, exists)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
//pad exists already
|
||||
if(exists == true)
|
||||
{
|
||||
callback(new customError("padName does already exist","apierror"));
|
||||
|
||||
// ensure pad doesn't exist already
|
||||
function (callback) {
|
||||
padManager.doesPadExists(padID, function(err, exists) {
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
if (exists == true) {
|
||||
// pad exists already
|
||||
callback(new customError("padName does already exist", "apierror"));
|
||||
return;
|
||||
}
|
||||
|
||||
//pad does not exist, everything is fine
|
||||
// pad does not exist, everything is fine
|
||||
callback();
|
||||
});
|
||||
},
|
||||
//create the pad
|
||||
function (callback)
|
||||
{
|
||||
padManager.getPad(padID, text, function(err)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
// create the pad
|
||||
function (callback) {
|
||||
padManager.getPad(padID, text, function(err) {
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
callback();
|
||||
});
|
||||
},
|
||||
//create an entry in the group for this pad
|
||||
function (callback)
|
||||
{
|
||||
|
||||
// create an entry in the group for this pad
|
||||
function (callback) {
|
||||
db.setSub("group:" + groupID, ["pads", padID], 1);
|
||||
callback();
|
||||
}
|
||||
], function(err)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
],
|
||||
function(err) {
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
callback(null, {padID: padID});
|
||||
});
|
||||
}
|
||||
|
||||
exports.listPads = function(groupID, callback)
|
||||
{
|
||||
exports.doesGroupExist(groupID, function(err, exists)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
//group does not exist
|
||||
if(exists == false)
|
||||
{
|
||||
callback(new customError("groupID does not exist","apierror"));
|
||||
exports.doesGroupExist(groupID, function(err, exists) {
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
// ensure the group exists
|
||||
if (exists == false) {
|
||||
callback(new customError("groupID does not exist", "apierror"));
|
||||
return;
|
||||
}
|
||||
|
||||
//group exists, let's get the pads
|
||||
db.getSub("group:" + groupID, ["pads"], function(err, result)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
// group exists, let's get the pads
|
||||
db.getSub("group:" + groupID, ["pads"], function(err, result) {
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
var pads = [];
|
||||
for ( var padId in result ) {
|
||||
pads.push(padId);
|
||||
|
|
|
@ -19,7 +19,7 @@ var crypto = require("crypto");
|
|||
var randomString = require("../utils/randomstring");
|
||||
var hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks');
|
||||
|
||||
//serialization/deserialization attributes
|
||||
// serialization/deserialization attributes
|
||||
var attributeBlackList = ["id"];
|
||||
var jsonableList = ["pool"];
|
||||
|
||||
|
@ -33,7 +33,6 @@ exports.cleanText = function (txt) {
|
|||
|
||||
|
||||
var Pad = function Pad(id) {
|
||||
|
||||
this.atext = Changeset.makeAText("\n");
|
||||
this.pool = new AttributePool();
|
||||
this.head = -1;
|
||||
|
@ -60,7 +59,7 @@ Pad.prototype.getSavedRevisionsNumber = function getSavedRevisionsNumber() {
|
|||
|
||||
Pad.prototype.getSavedRevisionsList = function getSavedRevisionsList() {
|
||||
var savedRev = new Array();
|
||||
for(var rev in this.savedRevisions){
|
||||
for (var rev in this.savedRevisions) {
|
||||
savedRev.push(this.savedRevisions[rev].revNum);
|
||||
}
|
||||
savedRev.sort(function(a, b) {
|
||||
|
@ -74,8 +73,9 @@ Pad.prototype.getPublicStatus = function getPublicStatus() {
|
|||
};
|
||||
|
||||
Pad.prototype.appendRevision = function appendRevision(aChangeset, author) {
|
||||
if(!author)
|
||||
if (!author) {
|
||||
author = '';
|
||||
}
|
||||
|
||||
var newAText = Changeset.applyToAText(aChangeset, this.atext, this.pool);
|
||||
Changeset.copyAText(newAText, this.atext);
|
||||
|
@ -88,21 +88,22 @@ Pad.prototype.appendRevision = function appendRevision(aChangeset, author) {
|
|||
newRevData.meta.author = author;
|
||||
newRevData.meta.timestamp = Date.now();
|
||||
|
||||
//ex. getNumForAuthor
|
||||
if(author != '')
|
||||
// ex. getNumForAuthor
|
||||
if (author != '') {
|
||||
this.pool.putAttrib(['author', author || '']);
|
||||
}
|
||||
|
||||
if(newRev % 100 == 0)
|
||||
{
|
||||
if (newRev % 100 == 0) {
|
||||
newRevData.meta.atext = this.atext;
|
||||
}
|
||||
|
||||
db.set("pad:"+this.id+":revs:"+newRev, newRevData);
|
||||
db.set("pad:" + this.id + ":revs:" + newRev, newRevData);
|
||||
this.saveToDatabase();
|
||||
|
||||
// set the author to pad
|
||||
if(author)
|
||||
if (author) {
|
||||
authorManager.addPad(author, this.id);
|
||||
}
|
||||
|
||||
if (this.head == 0) {
|
||||
hooks.callAll("padCreate", {'pad':this, 'author': author});
|
||||
|
@ -111,49 +112,47 @@ Pad.prototype.appendRevision = function appendRevision(aChangeset, author) {
|
|||
}
|
||||
};
|
||||
|
||||
//save all attributes to the database
|
||||
Pad.prototype.saveToDatabase = function saveToDatabase(){
|
||||
// save all attributes to the database
|
||||
Pad.prototype.saveToDatabase = function saveToDatabase() {
|
||||
var dbObject = {};
|
||||
|
||||
for(var attr in this){
|
||||
if(typeof this[attr] === "function") continue;
|
||||
if(attributeBlackList.indexOf(attr) !== -1) continue;
|
||||
for (var attr in this) {
|
||||
if (typeof this[attr] === "function") continue;
|
||||
if (attributeBlackList.indexOf(attr) !== -1) continue;
|
||||
|
||||
dbObject[attr] = this[attr];
|
||||
|
||||
if(jsonableList.indexOf(attr) !== -1){
|
||||
if (jsonableList.indexOf(attr) !== -1) {
|
||||
dbObject[attr] = dbObject[attr].toJsonable();
|
||||
}
|
||||
}
|
||||
|
||||
db.set("pad:"+this.id, dbObject);
|
||||
db.set("pad:" + this.id, dbObject);
|
||||
}
|
||||
|
||||
// get time of last edit (changeset application)
|
||||
Pad.prototype.getLastEdit = function getLastEdit(callback){
|
||||
Pad.prototype.getLastEdit = function getLastEdit(callback) {
|
||||
var revNum = this.getHeadRevisionNumber();
|
||||
db.getSub("pad:"+this.id+":revs:"+revNum, ["meta", "timestamp"], callback);
|
||||
db.getSub("pad:" + this.id + ":revs:" + revNum, ["meta", "timestamp"], callback);
|
||||
}
|
||||
|
||||
Pad.prototype.getRevisionChangeset = function getRevisionChangeset(revNum, callback) {
|
||||
db.getSub("pad:"+this.id+":revs:"+revNum, ["changeset"], callback);
|
||||
db.getSub("pad:" + this.id + ":revs:" + revNum, ["changeset"], callback);
|
||||
};
|
||||
|
||||
Pad.prototype.getRevisionAuthor = function getRevisionAuthor(revNum, callback) {
|
||||
db.getSub("pad:"+this.id+":revs:"+revNum, ["meta", "author"], callback);
|
||||
db.getSub("pad:" + this.id + ":revs:" + revNum, ["meta", "author"], callback);
|
||||
};
|
||||
|
||||
Pad.prototype.getRevisionDate = function getRevisionDate(revNum, callback) {
|
||||
db.getSub("pad:"+this.id+":revs:"+revNum, ["meta", "timestamp"], callback);
|
||||
db.getSub("pad:" + this.id + ":revs:" + revNum, ["meta", "timestamp"], callback);
|
||||
};
|
||||
|
||||
Pad.prototype.getAllAuthors = function getAllAuthors() {
|
||||
var authors = [];
|
||||
|
||||
for(var key in this.pool.numToAttrib)
|
||||
{
|
||||
if(this.pool.numToAttrib[key][0] == "author" && this.pool.numToAttrib[key][1] != "")
|
||||
{
|
||||
for(var key in this.pool.numToAttrib) {
|
||||
if (this.pool.numToAttrib[key][0] == "author" && this.pool.numToAttrib[key][1] != "") {
|
||||
authors.push(this.pool.numToAttrib[key][1]);
|
||||
}
|
||||
}
|
||||
|
@ -168,26 +167,22 @@ Pad.prototype.getInternalRevisionAText = function getInternalRevisionAText(targe
|
|||
var atext;
|
||||
var changesets = [];
|
||||
|
||||
//find out which changesets are needed
|
||||
// find out which changesets are needed
|
||||
var neededChangesets = [];
|
||||
var curRev = keyRev;
|
||||
while (curRev < targetRev)
|
||||
{
|
||||
while (curRev < targetRev) {
|
||||
curRev++;
|
||||
neededChangesets.push(curRev);
|
||||
}
|
||||
|
||||
async.series([
|
||||
//get all needed data out of the database
|
||||
function(callback)
|
||||
{
|
||||
// get all needed data out of the database
|
||||
function(callback) {
|
||||
async.parallel([
|
||||
//get the atext of the key revision
|
||||
function (callback)
|
||||
{
|
||||
db.getSub("pad:"+_this.id+":revs:"+keyRev, ["meta", "atext"], function(err, _atext)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
// get the atext of the key revision
|
||||
function (callback) {
|
||||
db.getSub("pad:" + _this.id + ":revs:" + keyRev, ["meta", "atext"], function(err, _atext) {
|
||||
if (ERR(err, callback)) return;
|
||||
try {
|
||||
atext = Changeset.cloneAText(_atext);
|
||||
} catch (e) {
|
||||
|
@ -197,14 +192,12 @@ Pad.prototype.getInternalRevisionAText = function getInternalRevisionAText(targe
|
|||
callback();
|
||||
});
|
||||
},
|
||||
//get all needed changesets
|
||||
function (callback)
|
||||
{
|
||||
async.forEach(neededChangesets, function(item, callback)
|
||||
{
|
||||
_this.getRevisionChangeset(item, function(err, changeset)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
// get all needed changesets
|
||||
function (callback) {
|
||||
async.forEach(neededChangesets, function(item, callback) {
|
||||
_this.getRevisionChangeset(item, function(err, changeset) {
|
||||
if (ERR(err, callback)) return;
|
||||
changesets[item] = changeset;
|
||||
callback();
|
||||
});
|
||||
|
@ -212,52 +205,53 @@ Pad.prototype.getInternalRevisionAText = function getInternalRevisionAText(targe
|
|||
}
|
||||
], callback);
|
||||
},
|
||||
//apply all changesets to the key changeset
|
||||
function(callback)
|
||||
{
|
||||
|
||||
// apply all changesets to the key changeset
|
||||
function(callback) {
|
||||
var apool = _this.apool();
|
||||
var curRev = keyRev;
|
||||
|
||||
while (curRev < targetRev)
|
||||
{
|
||||
while (curRev < targetRev) {
|
||||
curRev++;
|
||||
var cs = changesets[curRev];
|
||||
try{
|
||||
try {
|
||||
atext = Changeset.applyToAText(cs, atext, apool);
|
||||
}catch(e) {
|
||||
} catch(e) {
|
||||
return callback(e)
|
||||
}
|
||||
}
|
||||
|
||||
callback(null);
|
||||
}
|
||||
], function(err)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
],
|
||||
function(err) {
|
||||
if (ERR(err, callback)) return;
|
||||
callback(null, atext);
|
||||
});
|
||||
};
|
||||
|
||||
Pad.prototype.getRevision = function getRevisionChangeset(revNum, callback) {
|
||||
db.get("pad:"+this.id+":revs:"+revNum, callback);
|
||||
db.get("pad:" + this.id + ":revs:" + revNum, callback);
|
||||
};
|
||||
|
||||
Pad.prototype.getAllAuthorColors = function getAllAuthorColors(callback){
|
||||
Pad.prototype.getAllAuthorColors = function getAllAuthorColors(callback) {
|
||||
var authors = this.getAllAuthors();
|
||||
var returnTable = {};
|
||||
var colorPalette = authorManager.getColorPalette();
|
||||
|
||||
async.forEach(authors, function(author, callback){
|
||||
authorManager.getAuthorColorId(author, function(err, colorId){
|
||||
if(err){
|
||||
async.forEach(authors, function(author, callback) {
|
||||
authorManager.getAuthorColorId(author, function(err, colorId) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
//colorId might be a hex color or an number out of the palette
|
||||
returnTable[author]=colorPalette[colorId] || colorId;
|
||||
|
||||
// colorId might be a hex color or an number out of the palette
|
||||
returnTable[author] = colorPalette[colorId] || colorId;
|
||||
|
||||
callback();
|
||||
});
|
||||
}, function(err){
|
||||
},
|
||||
function(err) {
|
||||
callback(err, returnTable);
|
||||
});
|
||||
};
|
||||
|
@ -266,15 +260,18 @@ Pad.prototype.getValidRevisionRange = function getValidRevisionRange(startRev, e
|
|||
startRev = parseInt(startRev, 10);
|
||||
var head = this.getHeadRevisionNumber();
|
||||
endRev = endRev ? parseInt(endRev, 10) : head;
|
||||
if(isNaN(startRev) || startRev < 0 || startRev > head) {
|
||||
|
||||
if (isNaN(startRev) || startRev < 0 || startRev > head) {
|
||||
startRev = null;
|
||||
}
|
||||
if(isNaN(endRev) || endRev < startRev) {
|
||||
|
||||
if (isNaN(endRev) || endRev < startRev) {
|
||||
endRev = null;
|
||||
} else if(endRev > head) {
|
||||
} else if (endRev > head) {
|
||||
endRev = head;
|
||||
}
|
||||
if(startRev !== null && endRev !== null) {
|
||||
|
||||
if (startRev !== null && endRev !== null) {
|
||||
return { startRev: startRev , endRev: endRev }
|
||||
}
|
||||
return null;
|
||||
|
@ -289,12 +286,12 @@ Pad.prototype.text = function text() {
|
|||
};
|
||||
|
||||
Pad.prototype.setText = function setText(newText) {
|
||||
//clean the new text
|
||||
// clean the new text
|
||||
newText = exports.cleanText(newText);
|
||||
|
||||
var oldText = this.text();
|
||||
|
||||
//create the changeset
|
||||
// create the changeset
|
||||
// We want to ensure the pad still ends with a \n, but otherwise keep
|
||||
// getText() and setText() consistent.
|
||||
var changeset;
|
||||
|
@ -304,27 +301,27 @@ Pad.prototype.setText = function setText(newText) {
|
|||
changeset = Changeset.makeSplice(oldText, 0, oldText.length-1, newText);
|
||||
}
|
||||
|
||||
//append the changeset
|
||||
// append the changeset
|
||||
this.appendRevision(changeset);
|
||||
};
|
||||
|
||||
Pad.prototype.appendText = function appendText(newText) {
|
||||
//clean the new text
|
||||
// clean the new text
|
||||
newText = exports.cleanText(newText);
|
||||
|
||||
var oldText = this.text();
|
||||
|
||||
//create the changeset
|
||||
// create the changeset
|
||||
var changeset = Changeset.makeSplice(oldText, oldText.length, 0, newText);
|
||||
|
||||
//append the changeset
|
||||
// append the changeset
|
||||
this.appendRevision(changeset);
|
||||
};
|
||||
|
||||
Pad.prototype.appendChatMessage = function appendChatMessage(text, userId, time) {
|
||||
this.chatHead++;
|
||||
//save the chat entry in the database
|
||||
db.set("pad:"+this.id+":chat:"+this.chatHead, {"text": text, "userId": userId, "time": time});
|
||||
// save the chat entry in the database
|
||||
db.set("pad:" + this.id + ":chat:" + this.chatHead, { "text": text, "userId": userId, "time": time });
|
||||
this.saveToDatabase();
|
||||
};
|
||||
|
||||
|
@ -333,77 +330,70 @@ Pad.prototype.getChatMessage = function getChatMessage(entryNum, callback) {
|
|||
var entry;
|
||||
|
||||
async.series([
|
||||
//get the chat entry
|
||||
function(callback)
|
||||
{
|
||||
db.get("pad:"+_this.id+":chat:"+entryNum, function(err, _entry)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
// get the chat entry
|
||||
function(callback) {
|
||||
db.get("pad:" + _this.id + ":chat:" + entryNum, function(err, _entry) {
|
||||
if (ERR(err, callback)) return;
|
||||
entry = _entry;
|
||||
callback();
|
||||
});
|
||||
},
|
||||
//add the authorName
|
||||
function(callback)
|
||||
{
|
||||
//this chat message doesn't exist, return null
|
||||
if(entry == null)
|
||||
{
|
||||
|
||||
// add the authorName
|
||||
function(callback) {
|
||||
// this chat message doesn't exist, return null
|
||||
if (entry == null) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
//get the authorName
|
||||
authorManager.getAuthorName(entry.userId, function(err, authorName)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
// get the authorName
|
||||
authorManager.getAuthorName(entry.userId, function(err, authorName) {
|
||||
if (ERR(err, callback)) return;
|
||||
entry.userName = authorName;
|
||||
callback();
|
||||
});
|
||||
}
|
||||
], function(err)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
],
|
||||
function(err) {
|
||||
if (ERR(err, callback)) return;
|
||||
callback(null, entry);
|
||||
});
|
||||
};
|
||||
|
||||
Pad.prototype.getChatMessages = function getChatMessages(start, end, callback) {
|
||||
//collect the numbers of chat entries and in which order we need them
|
||||
// collect the numbers of chat entries and in which order we need them
|
||||
var neededEntries = [];
|
||||
var order = 0;
|
||||
for(var i=start;i<=end; i++)
|
||||
{
|
||||
neededEntries.push({entryNum:i, order: order});
|
||||
for (var i = start; i <= end; i++) {
|
||||
neededEntries.push({ entryNum: i, order: order });
|
||||
order++;
|
||||
}
|
||||
|
||||
var _this = this;
|
||||
|
||||
//get all entries out of the database
|
||||
// get all entries out of the database
|
||||
var entries = [];
|
||||
async.forEach(neededEntries, function(entryObject, callback)
|
||||
{
|
||||
_this.getChatMessage(entryObject.entryNum, function(err, entry)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
async.forEach(neededEntries, function(entryObject, callback) {
|
||||
_this.getChatMessage(entryObject.entryNum, function(err, entry) {
|
||||
if (ERR(err, callback)) return;
|
||||
entries[entryObject.order] = entry;
|
||||
callback();
|
||||
});
|
||||
}, function(err)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
},
|
||||
function(err) {
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
//sort out broken chat entries
|
||||
//it looks like in happend in the past that the chat head was
|
||||
//incremented, but the chat message wasn't added
|
||||
// sort out broken chat entries
|
||||
// it looks like in happened in the past that the chat head was
|
||||
// incremented, but the chat message wasn't added
|
||||
var cleanedEntries = [];
|
||||
for(var i=0;i<entries.length;i++)
|
||||
{
|
||||
if(entries[i]!=null)
|
||||
for (var i=0; i < entries.length; i++) {
|
||||
if (entries[i] != null) {
|
||||
cleanedEntries.push(entries[i]);
|
||||
else
|
||||
} else {
|
||||
console.warn("WARNING: Found broken chat entry in pad " + _this.id);
|
||||
}
|
||||
}
|
||||
|
||||
callback(null, cleanedEntries);
|
||||
|
@ -413,38 +403,33 @@ Pad.prototype.getChatMessages = function getChatMessages(start, end, callback) {
|
|||
Pad.prototype.init = function init(text, callback) {
|
||||
var _this = this;
|
||||
|
||||
//replace text with default text if text isn't set
|
||||
if(text == null)
|
||||
{
|
||||
// replace text with default text if text isn't set
|
||||
if (text == null) {
|
||||
text = settings.defaultPadText;
|
||||
}
|
||||
|
||||
//try to load the pad
|
||||
db.get("pad:"+this.id, function(err, value)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
// try to load the pad
|
||||
db.get("pad:" + this.id, function(err, value) {
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
//if this pad exists, load it
|
||||
if(value != null)
|
||||
{
|
||||
//copy all attr. To a transfrom via fromJsonable if necassary
|
||||
for(var attr in value){
|
||||
if(jsonableList.indexOf(attr) !== -1){
|
||||
// if this pad exists, load it
|
||||
if (value != null) {
|
||||
// copy all attr. To a transfrom via fromJsonable if necessary
|
||||
for (var attr in value) {
|
||||
if (jsonableList.indexOf(attr) !== -1) {
|
||||
_this[attr] = _this[attr].fromJsonable(value[attr]);
|
||||
} else {
|
||||
_this[attr] = value[attr];
|
||||
}
|
||||
}
|
||||
}
|
||||
//this pad doesn't exist, so create it
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// this pad doesn't exist, so create it
|
||||
var firstChangeset = Changeset.makeSplice("\n", 0, 0, exports.cleanText(text));
|
||||
|
||||
_this.appendRevision(firstChangeset, '');
|
||||
}
|
||||
|
||||
hooks.callAll("padLoad", {'pad':_this});
|
||||
hooks.callAll("padLoad", { 'pad': _this });
|
||||
callback(null);
|
||||
});
|
||||
};
|
||||
|
@ -471,51 +456,44 @@ Pad.prototype.copy = function copy(destinationID, force, callback) {
|
|||
|
||||
async.series([
|
||||
// if it's a group pad, let's make sure the group exists.
|
||||
function(callback)
|
||||
{
|
||||
if (destinationID.indexOf("$") === -1)
|
||||
{
|
||||
function(callback) {
|
||||
if (destinationID.indexOf("$") === -1) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
destGroupID = destinationID.split("$")[0]
|
||||
groupManager.doesGroupExist(destGroupID, function (err, exists)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
destGroupID = destinationID.split("$")[0];
|
||||
groupManager.doesGroupExist(destGroupID, function (err, exists) {
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
//group does not exist
|
||||
if(exists == false)
|
||||
{
|
||||
callback(new customError("groupID does not exist for destinationID","apierror"));
|
||||
// group does not exist
|
||||
if (exists == false) {
|
||||
callback(new customError("groupID does not exist for destinationID", "apierror"));
|
||||
return;
|
||||
}
|
||||
|
||||
//everything is fine, continue
|
||||
// everything is fine, continue
|
||||
callback();
|
||||
});
|
||||
},
|
||||
|
||||
// if the pad exists, we should abort, unless forced.
|
||||
function(callback)
|
||||
{
|
||||
padManager.doesPadExists(destinationID, function (err, exists)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
function(callback) {
|
||||
padManager.doesPadExists(destinationID, function (err, exists) {
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
/*
|
||||
* this is the negation of a truthy comparison. Has been left in this
|
||||
* wonky state to keep the old (possibly buggy) behaviour
|
||||
*/
|
||||
if (!(exists == true))
|
||||
{
|
||||
if (!(exists == true)) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!force)
|
||||
{
|
||||
if (!force) {
|
||||
console.error("erroring out without force");
|
||||
callback(new customError("destinationID already exists","apierror"));
|
||||
callback(new customError("destinationID already exists", "apierror"));
|
||||
console.error("erroring out without force - after");
|
||||
return;
|
||||
}
|
||||
|
@ -527,54 +505,50 @@ Pad.prototype.copy = function copy(destinationID, force, callback) {
|
|||
});
|
||||
});
|
||||
},
|
||||
|
||||
// copy the 'pad' entry
|
||||
function(callback)
|
||||
{
|
||||
db.get("pad:"+sourceID, function(err, pad) {
|
||||
db.set("pad:"+destinationID, pad);
|
||||
function(callback) {
|
||||
db.get("pad:" + sourceID, function(err, pad) {
|
||||
db.set("pad:" + destinationID, pad);
|
||||
});
|
||||
|
||||
callback();
|
||||
},
|
||||
//copy all relations
|
||||
function(callback)
|
||||
{
|
||||
|
||||
// copy all relations
|
||||
function(callback) {
|
||||
async.parallel([
|
||||
//copy all chat messages
|
||||
function(callback)
|
||||
{
|
||||
// copy all chat messages
|
||||
function(callback) {
|
||||
var chatHead = _this.chatHead;
|
||||
|
||||
for(var i=0;i<=chatHead;i++)
|
||||
{
|
||||
db.get("pad:"+sourceID+":chat:"+i, function (err, chat) {
|
||||
for (var i=0; i <= chatHead; i++) {
|
||||
db.get("pad:" + sourceID + ":chat:" + i, function (err, chat) {
|
||||
if (ERR(err, callback)) return;
|
||||
db.set("pad:"+destinationID+":chat:"+i, chat);
|
||||
db.set("pad:" + destinationID + ":chat:" + i, chat);
|
||||
});
|
||||
}
|
||||
|
||||
callback();
|
||||
},
|
||||
//copy all revisions
|
||||
function(callback)
|
||||
{
|
||||
|
||||
// copy all revisions
|
||||
function(callback) {
|
||||
var revHead = _this.head;
|
||||
for(var i=0;i<=revHead;i++)
|
||||
{
|
||||
db.get("pad:"+sourceID+":revs:"+i, function (err, rev) {
|
||||
for (var i=0; i <= revHead; i++) {
|
||||
db.get("pad:" + sourceID + ":revs:" + i, function (err, rev) {
|
||||
if (ERR(err, callback)) return;
|
||||
db.set("pad:"+destinationID+":revs:"+i, rev);
|
||||
db.set("pad:" + destinationID + ":revs:" + i, rev);
|
||||
});
|
||||
}
|
||||
|
||||
callback();
|
||||
},
|
||||
//add the new pad to all authors who contributed to the old one
|
||||
function(callback)
|
||||
{
|
||||
|
||||
// add the new pad to all authors who contributed to the old one
|
||||
function(callback) {
|
||||
var authorIDs = _this.getAllAuthors();
|
||||
authorIDs.forEach(function (authorID)
|
||||
{
|
||||
authorIDs.forEach(function (authorID) {
|
||||
authorManager.addPad(authorID, destinationID);
|
||||
});
|
||||
|
||||
|
@ -583,25 +557,29 @@ Pad.prototype.copy = function copy(destinationID, force, callback) {
|
|||
// parallel
|
||||
], callback);
|
||||
},
|
||||
|
||||
function(callback) {
|
||||
// Group pad? Add it to the group's list
|
||||
if(destGroupID) db.setSub("group:" + destGroupID, ["pads", destinationID], 1);
|
||||
if (destGroupID) {
|
||||
// Group pad? Add it to the group's list
|
||||
db.setSub("group:" + destGroupID, ["pads", destinationID], 1);
|
||||
}
|
||||
|
||||
// Initialize the new pad (will update the listAllPads cache)
|
||||
setTimeout(function(){
|
||||
setTimeout(function() {
|
||||
padManager.getPad(destinationID, null, callback) // this runs too early.
|
||||
},10);
|
||||
}, 10);
|
||||
},
|
||||
|
||||
// let the plugins know the pad was copied
|
||||
function(callback) {
|
||||
hooks.callAll('padCopy', { 'originalPad': _this, 'destinationID': destinationID });
|
||||
callback();
|
||||
}
|
||||
// series
|
||||
], function(err)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
callback(null, {padID: destinationID});
|
||||
],
|
||||
function(err) {
|
||||
if (ERR(err, callback)) return;
|
||||
callback(null, { padID: destinationID });
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -609,46 +587,41 @@ Pad.prototype.remove = function remove(callback) {
|
|||
var padID = this.id;
|
||||
var _this = this;
|
||||
|
||||
//kick everyone from this pad
|
||||
// kick everyone from this pad
|
||||
padMessageHandler.kickSessionsFromPad(padID);
|
||||
|
||||
async.series([
|
||||
//delete all relations
|
||||
function(callback)
|
||||
{
|
||||
// delete all relations
|
||||
function(callback) {
|
||||
async.parallel([
|
||||
//is it a group pad? -> delete the entry of this pad in the group
|
||||
function(callback)
|
||||
{
|
||||
if(padID.indexOf("$") === -1)
|
||||
{
|
||||
// is it a group pad? -> delete the entry of this pad in the group
|
||||
function(callback) {
|
||||
if (padID.indexOf("$") === -1) {
|
||||
// it isn't a group pad, nothing to do here
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
// it is a group pad
|
||||
var groupID = padID.substring(0,padID.indexOf("$"));
|
||||
var groupID = padID.substring(0, padID.indexOf("$"));
|
||||
|
||||
db.get("group:" + groupID, function (err, group)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
db.get("group:" + groupID, function (err, group) {
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
//remove the pad entry
|
||||
// remove the pad entry
|
||||
delete group.pads[padID];
|
||||
|
||||
//set the new value
|
||||
// set the new value
|
||||
db.set("group:" + groupID, group);
|
||||
|
||||
callback();
|
||||
});
|
||||
},
|
||||
//remove the readonly entries
|
||||
function(callback)
|
||||
{
|
||||
readOnlyManager.getReadOnlyId(padID, function(err, readonlyID)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
// remove the readonly entries
|
||||
function(callback) {
|
||||
readOnlyManager.getReadOnlyId(padID, function(err, readonlyID) {
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
db.remove("pad2readonly:" + padID);
|
||||
db.remove("readonly2pad:" + readonlyID);
|
||||
|
@ -656,37 +629,34 @@ Pad.prototype.remove = function remove(callback) {
|
|||
callback();
|
||||
});
|
||||
},
|
||||
//delete all chat messages
|
||||
function(callback)
|
||||
{
|
||||
|
||||
// delete all chat messages
|
||||
function(callback) {
|
||||
var chatHead = _this.chatHead;
|
||||
|
||||
for(var i=0;i<=chatHead;i++)
|
||||
{
|
||||
db.remove("pad:"+padID+":chat:"+i);
|
||||
for (var i = 0; i <= chatHead; i++) {
|
||||
db.remove("pad:" + padID + ":chat:" + i);
|
||||
}
|
||||
|
||||
callback();
|
||||
},
|
||||
//delete all revisions
|
||||
function(callback)
|
||||
{
|
||||
|
||||
// delete all revisions
|
||||
function(callback) {
|
||||
var revHead = _this.head;
|
||||
|
||||
for(var i=0;i<=revHead;i++)
|
||||
{
|
||||
db.remove("pad:"+padID+":revs:"+i);
|
||||
for (var i = 0; i <= revHead; i++) {
|
||||
db.remove("pad:" + padID + ":revs:" + i);
|
||||
}
|
||||
|
||||
callback();
|
||||
},
|
||||
//remove pad from all authors who contributed
|
||||
function(callback)
|
||||
{
|
||||
|
||||
// remove pad from all authors who contributed
|
||||
function(callback) {
|
||||
var authorIDs = _this.getAllAuthors();
|
||||
|
||||
authorIDs.forEach(function (authorID)
|
||||
{
|
||||
authorIDs.forEach(function (authorID) {
|
||||
authorManager.removePad(authorID, padID);
|
||||
});
|
||||
|
||||
|
@ -694,20 +664,21 @@ Pad.prototype.remove = function remove(callback) {
|
|||
}
|
||||
], callback);
|
||||
},
|
||||
//delete the pad entry and delete pad from padManager
|
||||
function(callback)
|
||||
{
|
||||
|
||||
// delete the pad entry and delete pad from padManager
|
||||
function(callback) {
|
||||
padManager.removePad(padID);
|
||||
hooks.callAll("padRemove", {'padID':padID});
|
||||
hooks.callAll("padRemove", { 'padID': padID });
|
||||
callback();
|
||||
}
|
||||
], function(err)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
],
|
||||
function(err) {
|
||||
if (ERR(err, callback)) return;
|
||||
callback();
|
||||
});
|
||||
};
|
||||
//set in db
|
||||
|
||||
// set in db
|
||||
Pad.prototype.setPublicStatus = function setPublicStatus(publicStatus) {
|
||||
this.publicStatus = publicStatus;
|
||||
this.saveToDatabase();
|
||||
|
@ -727,14 +698,14 @@ Pad.prototype.isPasswordProtected = function isPasswordProtected() {
|
|||
};
|
||||
|
||||
Pad.prototype.addSavedRevision = function addSavedRevision(revNum, savedById, label) {
|
||||
//if this revision is already saved, return silently
|
||||
for(var i in this.savedRevisions){
|
||||
if(this.savedRevisions[i] && this.savedRevisions[i].revNum === revNum){
|
||||
// if this revision is already saved, return silently
|
||||
for (var i in this.savedRevisions) {
|
||||
if (this.savedRevisions[i] && this.savedRevisions[i].revNum === revNum) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//build the saved revision object
|
||||
// build the saved revision object
|
||||
var savedRevision = {};
|
||||
savedRevision.revNum = revNum;
|
||||
savedRevision.savedById = savedById;
|
||||
|
@ -742,7 +713,7 @@ Pad.prototype.addSavedRevision = function addSavedRevision(revNum, savedById, la
|
|||
savedRevision.timestamp = Date.now();
|
||||
savedRevision.id = randomString(10);
|
||||
|
||||
//save this new saved revision
|
||||
// save this new saved revision
|
||||
this.savedRevisions.push(savedRevision);
|
||||
this.saveToDatabase();
|
||||
};
|
||||
|
@ -753,19 +724,17 @@ Pad.prototype.getSavedRevisions = function getSavedRevisions() {
|
|||
|
||||
/* Crypto helper methods */
|
||||
|
||||
function hash(password, salt)
|
||||
{
|
||||
function hash(password, salt) {
|
||||
var shasum = crypto.createHash('sha512');
|
||||
shasum.update(password + salt);
|
||||
|
||||
return shasum.digest("hex") + "$" + salt;
|
||||
}
|
||||
|
||||
function generateSalt()
|
||||
{
|
||||
function generateSalt() {
|
||||
return randomString(86);
|
||||
}
|
||||
|
||||
function compare(hashStr, password)
|
||||
{
|
||||
function compare(hashStr, password) {
|
||||
return hash(password, hashStr.split("$")[1]) === hashStr;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ var customError = require("../utils/customError");
|
|||
var Pad = require("../db/Pad").Pad;
|
||||
var db = require("./DB").db;
|
||||
|
||||
/**
|
||||
/**
|
||||
* A cache of all loaded Pads.
|
||||
*
|
||||
* Provides "get" and "set" functions,
|
||||
|
@ -35,12 +35,11 @@ var db = require("./DB").db;
|
|||
* that's defined somewhere more sensible.
|
||||
*/
|
||||
var globalPads = {
|
||||
get: function (name) { return this[':'+name]; },
|
||||
set: function (name, value)
|
||||
{
|
||||
get: function(name) { return this[':'+name]; },
|
||||
set: function(name, value) {
|
||||
this[':'+name] = value;
|
||||
},
|
||||
remove: function (name) {
|
||||
remove: function(name) {
|
||||
delete this[':'+name];
|
||||
}
|
||||
};
|
||||
|
@ -54,56 +53,63 @@ var padList = {
|
|||
list: [],
|
||||
sorted : false,
|
||||
initiated: false,
|
||||
init: function(cb)
|
||||
{
|
||||
db.findKeys("pad:*", "*:*:*", function(err, dbData)
|
||||
{
|
||||
if(ERR(err, cb)) return;
|
||||
if(dbData != null){
|
||||
init: function(cb) {
|
||||
db.findKeys("pad:*", "*:*:*", function(err, dbData) {
|
||||
if (ERR(err, cb)) return;
|
||||
|
||||
if (dbData != null) {
|
||||
padList.initiated = true
|
||||
dbData.forEach(function(val){
|
||||
dbData.forEach(function(val) {
|
||||
padList.addPad(val.replace(/pad:/,""),false);
|
||||
});
|
||||
cb && cb()
|
||||
|
||||
cb && cb();
|
||||
}
|
||||
});
|
||||
|
||||
return this;
|
||||
},
|
||||
load: function(cb) {
|
||||
if(this.initiated) cb && cb()
|
||||
else this.init(cb)
|
||||
if (this.initiated) {
|
||||
cb && cb();
|
||||
} else {
|
||||
this.init(cb);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Returns all pads in alphabetical order as array.
|
||||
*/
|
||||
getPads: function(cb){
|
||||
getPads: function(cb) {
|
||||
this.load(function() {
|
||||
if(!padList.sorted){
|
||||
if (!padList.sorted) {
|
||||
padList.list = padList.list.sort();
|
||||
padList.sorted = true;
|
||||
}
|
||||
|
||||
cb && cb(padList.list);
|
||||
})
|
||||
},
|
||||
addPad: function(name)
|
||||
{
|
||||
if(!this.initiated) return;
|
||||
if(this.list.indexOf(name) == -1){
|
||||
addPad: function(name) {
|
||||
if (!this.initiated) return;
|
||||
|
||||
if (this.list.indexOf(name) == -1) {
|
||||
this.list.push(name);
|
||||
this.sorted=false;
|
||||
this.sorted = false;
|
||||
}
|
||||
},
|
||||
removePad: function(name)
|
||||
{
|
||||
if(!this.initiated) return;
|
||||
removePad: function(name) {
|
||||
if (!this.initiated) return;
|
||||
|
||||
var index = this.list.indexOf(name);
|
||||
if(index>-1){
|
||||
this.list.splice(index,1);
|
||||
this.sorted=false;
|
||||
|
||||
if (index > -1) {
|
||||
this.list.splice(index, 1);
|
||||
this.sorted = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
//initialises the allknowing data structure
|
||||
|
||||
// initialises the all-knowing data structure
|
||||
|
||||
/**
|
||||
* An array of padId transformations. These represent changes in pad name policy over
|
||||
|
@ -117,58 +123,56 @@ var padIdTransforms = [
|
|||
/**
|
||||
* Returns a Pad Object with the callback
|
||||
* @param id A String with the id of the pad
|
||||
* @param {Function} callback
|
||||
* @param {Function} callback
|
||||
*/
|
||||
exports.getPad = function(id, text, callback)
|
||||
{
|
||||
//check if this is a valid padId
|
||||
if(!exports.isValidPadId(id))
|
||||
{
|
||||
callback(new customError(id + " is not a valid padId","apierror"));
|
||||
{
|
||||
// check if this is a valid padId
|
||||
if (!exports.isValidPadId(id)) {
|
||||
callback(new customError(id + " is not a valid padId", "apierror"));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//make text an optional parameter
|
||||
if(typeof text == "function")
|
||||
{
|
||||
|
||||
// make text an optional parameter
|
||||
if (typeof text == "function") {
|
||||
callback = text;
|
||||
text = null;
|
||||
}
|
||||
|
||||
//check if this is a valid text
|
||||
if(text != null)
|
||||
{
|
||||
//check if text is a string
|
||||
if(typeof text != "string")
|
||||
{
|
||||
callback(new customError("text is not a string","apierror"));
|
||||
|
||||
// check if this is a valid text
|
||||
if (text != null) {
|
||||
// check if text is a string
|
||||
if (typeof text != "string") {
|
||||
callback(new customError("text is not a string", "apierror"));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//check if text is less than 100k chars
|
||||
if(text.length > 100000)
|
||||
{
|
||||
callback(new customError("text must be less than 100k chars","apierror"));
|
||||
|
||||
// check if text is less than 100k chars
|
||||
if (text.length > 100000) {
|
||||
callback(new customError("text must be less than 100k chars", "apierror"));
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var pad = globalPads.get(id);
|
||||
|
||||
//return pad if its already loaded
|
||||
if(pad != null)
|
||||
{
|
||||
|
||||
// return pad if it's already loaded
|
||||
if (pad != null) {
|
||||
callback(null, pad);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//try to load pad
|
||||
// try to load pad
|
||||
pad = new Pad(id);
|
||||
|
||||
//initalize the pad
|
||||
pad.init(text, function(err)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
// initalize the pad
|
||||
pad.init(text, function(err) {
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
globalPads.set(id, pad);
|
||||
padList.addPad(id);
|
||||
callback(null, pad);
|
||||
|
@ -182,49 +186,48 @@ exports.listAllPads = function(cb)
|
|||
});
|
||||
}
|
||||
|
||||
//checks if a pad exists
|
||||
// checks if a pad exists
|
||||
exports.doesPadExists = function(padId, callback)
|
||||
{
|
||||
db.get("pad:"+padId, function(err, value)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
if(value != null && value.atext){
|
||||
db.get("pad:" + padId, function(err, value) {
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
if (value != null && value.atext) {
|
||||
callback(null, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
callback(null, false);
|
||||
} else {
|
||||
callback(null, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//returns a sanitized padId, respecting legacy pad id formats
|
||||
// returns a sanitized padId, respecting legacy pad id formats
|
||||
exports.sanitizePadId = function(padId, callback) {
|
||||
var transform_index = arguments[2] || 0;
|
||||
//we're out of possible transformations, so just return it
|
||||
if(transform_index >= padIdTransforms.length)
|
||||
{
|
||||
|
||||
// we're out of possible transformations, so just return it
|
||||
if (transform_index >= padIdTransforms.length) {
|
||||
callback(padId);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//check if padId exists
|
||||
exports.doesPadExists(padId, function(junk, exists)
|
||||
{
|
||||
if(exists)
|
||||
{
|
||||
// check if padId exists
|
||||
exports.doesPadExists(padId, function(junk, exists) {
|
||||
if (exists) {
|
||||
callback(padId);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//get the next transformation *that's different*
|
||||
// get the next transformation *that's different*
|
||||
var transformedPadId = padId;
|
||||
while(transformedPadId == padId && transform_index < padIdTransforms.length)
|
||||
{
|
||||
|
||||
while(transformedPadId == padId && transform_index < padIdTransforms.length) {
|
||||
transformedPadId = padId.replace(padIdTransforms[transform_index][0], padIdTransforms[transform_index][1]);
|
||||
transform_index += 1;
|
||||
}
|
||||
//check the next transform
|
||||
|
||||
// check the next transform
|
||||
exports.sanitizePadId(transformedPadId, callback, transform_index);
|
||||
});
|
||||
}
|
||||
|
@ -237,13 +240,13 @@ exports.isValidPadId = function(padId)
|
|||
/**
|
||||
* Removes the pad from database and unloads it.
|
||||
*/
|
||||
exports.removePad = function(padId){
|
||||
db.remove("pad:"+padId);
|
||||
exports.removePad = function(padId) {
|
||||
db.remove("pad:" + padId);
|
||||
exports.unloadPad(padId);
|
||||
padList.removePad(padId);
|
||||
}
|
||||
|
||||
//removes a pad from the cache
|
||||
// removes a pad from the cache
|
||||
exports.unloadPad = function(padId)
|
||||
{
|
||||
globalPads.remove(padId);
|
||||
|
|
|
@ -29,43 +29,40 @@ var randomString = require("../utils/randomstring");
|
|||
* @param {String} padId the id of the pad
|
||||
*/
|
||||
exports.getReadOnlyId = function (padId, callback)
|
||||
{
|
||||
{
|
||||
var readOnlyId;
|
||||
|
||||
|
||||
async.waterfall([
|
||||
//check if there is a pad2readonly entry
|
||||
function(callback)
|
||||
{
|
||||
// check if there is a pad2readonly entry
|
||||
function(callback) {
|
||||
db.get("pad2readonly:" + padId, callback);
|
||||
},
|
||||
function(dbReadOnlyId, callback)
|
||||
{
|
||||
//there is no readOnly Entry in the database, let's create one
|
||||
if(dbReadOnlyId == null)
|
||||
{
|
||||
|
||||
function(dbReadOnlyId, callback) {
|
||||
if (dbReadOnlyId == null) {
|
||||
// there is no readOnly Entry in the database, let's create one
|
||||
readOnlyId = "r." + randomString(16);
|
||||
|
||||
|
||||
db.set("pad2readonly:" + padId, readOnlyId);
|
||||
db.set("readonly2pad:" + readOnlyId, padId);
|
||||
}
|
||||
//there is a readOnly Entry in the database, let's take this one
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// there is a readOnly Entry in the database, let's take this one
|
||||
readOnlyId = dbReadOnlyId;
|
||||
}
|
||||
|
||||
|
||||
callback();
|
||||
}
|
||||
], function(err)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
//return the results
|
||||
],
|
||||
function(err) {
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
// return the results
|
||||
callback(null, readOnlyId);
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a the padId for a read only id
|
||||
* returns the padId for a read only id
|
||||
* @param {String} readOnlyId read only id
|
||||
*/
|
||||
exports.getPadId = function(readOnlyId, callback)
|
||||
|
@ -74,20 +71,21 @@ exports.getPadId = function(readOnlyId, callback)
|
|||
}
|
||||
|
||||
/**
|
||||
* returns a the padId and readonlyPadId in an object for any id
|
||||
* returns the padId and readonlyPadId in an object for any id
|
||||
* @param {String} padIdOrReadonlyPadId read only id or real pad id
|
||||
*/
|
||||
exports.getIds = function(id, callback) {
|
||||
if (id.indexOf("r.") == 0)
|
||||
if (id.indexOf("r.") == 0) {
|
||||
exports.getPadId(id, function (err, value) {
|
||||
if(ERR(err, callback)) return;
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
callback(null, {
|
||||
readOnlyPadId: id,
|
||||
padId: value, // Might be null, if this is an unknown read-only id
|
||||
readonly: true
|
||||
});
|
||||
});
|
||||
else
|
||||
} else {
|
||||
exports.getReadOnlyId(id, function (err, value) {
|
||||
callback(null, {
|
||||
readOnlyPadId: value,
|
||||
|
@ -95,4 +93,5 @@ exports.getIds = function(id, callback) {
|
|||
readonly: false
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
var ERR = require("async-stacktrace");
|
||||
var async = require("async");
|
||||
var authorManager = require("./AuthorManager");
|
||||
|
@ -34,59 +33,57 @@ var authLogger = log4js.getLogger("auth");
|
|||
* @param padID the pad the user wants to access
|
||||
* @param sessionCookie the session the user has (set via api)
|
||||
* @param token the token of the author (randomly generated at client side, used for public pads)
|
||||
* @param password the password the user has given to access this pad, can be null
|
||||
* @param password the password the user has given to access this pad, can be null
|
||||
* @param callback will be called with (err, {accessStatus: grant|deny|wrongPassword|needPassword, authorID: a.xxxxxx})
|
||||
*/
|
||||
exports.checkAccess = function (padID, sessionCookie, token, password, callback)
|
||||
{
|
||||
*/
|
||||
exports.checkAccess = function(padID, sessionCookie, token, password, callback)
|
||||
{
|
||||
var statusObject;
|
||||
|
||||
if(!padID) {
|
||||
|
||||
if (!padID) {
|
||||
callback(null, {accessStatus: "deny"});
|
||||
return;
|
||||
}
|
||||
|
||||
// allow plugins to deny access
|
||||
var deniedByHook = hooks.callAll("onAccessCheck", {'padID': padID, 'password': password, 'token': token, 'sessionCookie': sessionCookie}).indexOf(false) > -1;
|
||||
if(deniedByHook)
|
||||
{
|
||||
if (deniedByHook) {
|
||||
callback(null, {accessStatus: "deny"});
|
||||
return;
|
||||
}
|
||||
|
||||
// a valid session is required (api-only mode)
|
||||
if(settings.requireSession)
|
||||
{
|
||||
// without sessionCookie, access is denied
|
||||
if(!sessionCookie)
|
||||
{
|
||||
if (settings.requireSession) {
|
||||
// a valid session is required (api-only mode)
|
||||
if (!sessionCookie) {
|
||||
// without sessionCookie, access is denied
|
||||
callback(null, {accessStatus: "deny"});
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
// a session is not required, so we'll check if it's a public pad
|
||||
else
|
||||
{
|
||||
// it's not a group pad, means we can grant access
|
||||
if(padID.indexOf("$") == -1)
|
||||
{
|
||||
//get author for this token
|
||||
authorManager.getAuthor4Token(token, function(err, author)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
} else {
|
||||
// a session is not required, so we'll check if it's a public pad
|
||||
if (padID.indexOf("$") == -1) {
|
||||
// it's not a group pad, means we can grant access
|
||||
|
||||
// get author for this token
|
||||
authorManager.getAuthor4Token(token, function(err, author) {
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
// assume user has access
|
||||
statusObject = {accessStatus: "grant", authorID: author};
|
||||
// user can't create pads
|
||||
if(settings.editOnly)
|
||||
{
|
||||
statusObject = { accessStatus: "grant", authorID: author };
|
||||
|
||||
if (settings.editOnly) {
|
||||
// user can't create pads
|
||||
|
||||
// check if pad exists
|
||||
padManager.doesPadExists(padID, function(err, exists)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
// pad doesn't exist - user can't have access
|
||||
if(!exists) statusObject.accessStatus = "deny";
|
||||
padManager.doesPadExists(padID, function(err, exists) {
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
if (!exists) {
|
||||
// pad doesn't exist - user can't have access
|
||||
statusObject.accessStatus = "deny";
|
||||
}
|
||||
|
||||
// grant or deny access, with author of token
|
||||
callback(null, statusObject);
|
||||
});
|
||||
|
@ -98,12 +95,12 @@ exports.checkAccess = function (padID, sessionCookie, token, password, callback)
|
|||
// grant access, with author of token
|
||||
callback(null, statusObject);
|
||||
});
|
||||
|
||||
//don't continue
|
||||
|
||||
// don't continue
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var groupID = padID.split("$")[0];
|
||||
var padExists = false;
|
||||
var validSession = false;
|
||||
|
@ -114,216 +111,193 @@ exports.checkAccess = function (padID, sessionCookie, token, password, callback)
|
|||
var passwordStatus = password == null ? "notGiven" : "wrong"; // notGiven, correct, wrong
|
||||
|
||||
async.series([
|
||||
//get basic informations from the database
|
||||
function(callback)
|
||||
{
|
||||
// get basic informations from the database
|
||||
function(callback) {
|
||||
async.parallel([
|
||||
//does pad exists
|
||||
function(callback)
|
||||
{
|
||||
padManager.doesPadExists(padID, function(err, exists)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
// does pad exist
|
||||
function(callback) {
|
||||
padManager.doesPadExists(padID, function(err, exists) {
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
padExists = exists;
|
||||
callback();
|
||||
});
|
||||
},
|
||||
//get information about all sessions contained in this cookie
|
||||
function(callback)
|
||||
{
|
||||
if (!sessionCookie)
|
||||
{
|
||||
|
||||
// get information about all sessions contained in this cookie
|
||||
function(callback) {
|
||||
if (!sessionCookie) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var sessionIDs = sessionCookie.split(',');
|
||||
async.forEach(sessionIDs, function(sessionID, callback)
|
||||
{
|
||||
sessionManager.getSessionInfo(sessionID, function(err, sessionInfo)
|
||||
{
|
||||
//skip session if it doesn't exist
|
||||
if(err && err.message == "sessionID does not exist")
|
||||
{
|
||||
|
||||
async.forEach(sessionIDs, function(sessionID, callback) {
|
||||
sessionManager.getSessionInfo(sessionID, function(err, sessionInfo) {
|
||||
// skip session if it doesn't exist
|
||||
if (err && err.message == "sessionID does not exist") {
|
||||
authLogger.debug("Auth failed: unknown session");
|
||||
callback();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
var now = Math.floor(Date.now()/1000);
|
||||
|
||||
//is it for this group?
|
||||
if(sessionInfo.groupID != groupID)
|
||||
{
|
||||
|
||||
// is it for this group?
|
||||
if (sessionInfo.groupID != groupID) {
|
||||
authLogger.debug("Auth failed: wrong group");
|
||||
callback();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//is validUntil still ok?
|
||||
if(sessionInfo.validUntil <= now)
|
||||
{
|
||||
|
||||
// is validUntil still ok?
|
||||
if (sessionInfo.validUntil <= now) {
|
||||
authLogger.debug("Auth failed: validUntil");
|
||||
callback();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// There is a valid session
|
||||
validSession = true;
|
||||
sessionAuthor = sessionInfo.authorID;
|
||||
|
||||
|
||||
callback();
|
||||
});
|
||||
}, callback);
|
||||
},
|
||||
//get author for token
|
||||
function(callback)
|
||||
{
|
||||
//get author for this token
|
||||
authorManager.getAuthor4Token(token, function(err, author)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
// get author for token
|
||||
function(callback) {
|
||||
// get author for this token
|
||||
authorManager.getAuthor4Token(token, function(err, author) {
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
tokenAuthor = author;
|
||||
callback();
|
||||
});
|
||||
}
|
||||
], callback);
|
||||
},
|
||||
//get more informations of this pad, if avaiable
|
||||
function(callback)
|
||||
{
|
||||
//skip this if the pad doesn't exists
|
||||
if(padExists == false)
|
||||
{
|
||||
|
||||
// get more informations of this pad, if avaiable
|
||||
function(callback) {
|
||||
// skip this if the pad doesn't exist
|
||||
if (padExists == false) {
|
||||
callback();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
padManager.getPad(padID, function(err, pad)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
//is it a public pad?
|
||||
|
||||
padManager.getPad(padID, function(err, pad) {
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
// is it a public pad?
|
||||
isPublic = pad.getPublicStatus();
|
||||
|
||||
//is it password protected?
|
||||
|
||||
// is it password protected?
|
||||
isPasswordProtected = pad.isPasswordProtected();
|
||||
|
||||
//is password correct?
|
||||
if(isPasswordProtected && password && pad.isCorrectPassword(password))
|
||||
{
|
||||
|
||||
// is password correct?
|
||||
if (isPasswordProtected && password && pad.isCorrectPassword(password)) {
|
||||
passwordStatus = "correct";
|
||||
}
|
||||
|
||||
|
||||
callback();
|
||||
});
|
||||
},
|
||||
function(callback)
|
||||
{
|
||||
//- a valid session for this group is avaible AND pad exists
|
||||
if(validSession && padExists)
|
||||
{
|
||||
//- the pad is not password protected
|
||||
if(!isPasswordProtected)
|
||||
{
|
||||
//--> grant access
|
||||
statusObject = {accessStatus: "grant", authorID: sessionAuthor};
|
||||
}
|
||||
//- the setting to bypass password validation is set
|
||||
else if(settings.sessionNoPassword)
|
||||
{
|
||||
//--> grant access
|
||||
statusObject = {accessStatus: "grant", authorID: sessionAuthor};
|
||||
}
|
||||
//- the pad is password protected and password is correct
|
||||
else if(isPasswordProtected && passwordStatus == "correct")
|
||||
{
|
||||
//--> grant access
|
||||
statusObject = {accessStatus: "grant", authorID: sessionAuthor};
|
||||
}
|
||||
//- the pad is password protected but wrong password given
|
||||
else if(isPasswordProtected && passwordStatus == "wrong")
|
||||
{
|
||||
//--> deny access, ask for new password and tell them that the password is wrong
|
||||
statusObject = {accessStatus: "wrongPassword"};
|
||||
}
|
||||
//- the pad is password protected but no password given
|
||||
else if(isPasswordProtected && passwordStatus == "notGiven")
|
||||
{
|
||||
//--> ask for password
|
||||
statusObject = {accessStatus: "needPassword"};
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
function(callback) {
|
||||
if (validSession && padExists) {
|
||||
// - a valid session for this group is avaible AND pad exists
|
||||
if (!isPasswordProtected) {
|
||||
// - the pad is not password protected
|
||||
|
||||
// --> grant access
|
||||
statusObject = { accessStatus: "grant", authorID: sessionAuthor };
|
||||
} else if (settings.sessionNoPassword) {
|
||||
// - the setting to bypass password validation is set
|
||||
|
||||
// --> grant access
|
||||
statusObject = { accessStatus: "grant", authorID: sessionAuthor };
|
||||
} else if (isPasswordProtected && passwordStatus == "correct") {
|
||||
// - the pad is password protected and password is correct
|
||||
|
||||
// --> grant access
|
||||
statusObject = { accessStatus: "grant", authorID: sessionAuthor };
|
||||
} else if (isPasswordProtected && passwordStatus == "wrong") {
|
||||
// - the pad is password protected but wrong password given
|
||||
|
||||
// --> deny access, ask for new password and tell them that the password is wrong
|
||||
statusObject = { accessStatus: "wrongPassword" };
|
||||
} else if (isPasswordProtected && passwordStatus == "notGiven") {
|
||||
// - the pad is password protected but no password given
|
||||
|
||||
// --> ask for password
|
||||
statusObject = { accessStatus: "needPassword" };
|
||||
} else {
|
||||
throw new Error("Ops, something wrong happend");
|
||||
}
|
||||
}
|
||||
//- a valid session for this group avaible but pad doesn't exists
|
||||
else if(validSession && !padExists)
|
||||
{
|
||||
//--> grant access
|
||||
} else if (validSession && !padExists) {
|
||||
// - a valid session for this group avaible but pad doesn't exist
|
||||
|
||||
// --> grant access
|
||||
statusObject = {accessStatus: "grant", authorID: sessionAuthor};
|
||||
//--> deny access if user isn't allowed to create the pad
|
||||
if(settings.editOnly)
|
||||
{
|
||||
|
||||
if (settings.editOnly) {
|
||||
// --> deny access if user isn't allowed to create the pad
|
||||
authLogger.debug("Auth failed: valid session & pad does not exist");
|
||||
statusObject.accessStatus = "deny";
|
||||
}
|
||||
}
|
||||
// there is no valid session avaiable AND pad exists
|
||||
else if(!validSession && padExists)
|
||||
{
|
||||
//-- its public and not password protected
|
||||
if(isPublic && !isPasswordProtected)
|
||||
{
|
||||
//--> grant access, with author of token
|
||||
} else if (!validSession && padExists) {
|
||||
// there is no valid session avaiable AND pad exists
|
||||
|
||||
// -- it's public and not password protected
|
||||
if (isPublic && !isPasswordProtected) {
|
||||
// --> grant access, with author of token
|
||||
statusObject = {accessStatus: "grant", authorID: tokenAuthor};
|
||||
}
|
||||
//- its public and password protected and password is correct
|
||||
else if(isPublic && isPasswordProtected && passwordStatus == "correct")
|
||||
{
|
||||
//--> grant access, with author of token
|
||||
} else if (isPublic && isPasswordProtected && passwordStatus == "correct") {
|
||||
// - it's public and password protected and password is correct
|
||||
|
||||
// --> grant access, with author of token
|
||||
statusObject = {accessStatus: "grant", authorID: tokenAuthor};
|
||||
}
|
||||
//- its public and the pad is password protected but wrong password given
|
||||
else if(isPublic && isPasswordProtected && passwordStatus == "wrong")
|
||||
{
|
||||
//--> deny access, ask for new password and tell them that the password is wrong
|
||||
} else if (isPublic && isPasswordProtected && passwordStatus == "wrong") {
|
||||
// - it's public and the pad is password protected but wrong password given
|
||||
|
||||
// --> deny access, ask for new password and tell them that the password is wrong
|
||||
statusObject = {accessStatus: "wrongPassword"};
|
||||
}
|
||||
//- its public and the pad is password protected but no password given
|
||||
else if(isPublic && isPasswordProtected && passwordStatus == "notGiven")
|
||||
{
|
||||
//--> ask for password
|
||||
} else if (isPublic && isPasswordProtected && passwordStatus == "notGiven") {
|
||||
// - it's public and the pad is password protected but no password given
|
||||
|
||||
// --> ask for password
|
||||
statusObject = {accessStatus: "needPassword"};
|
||||
}
|
||||
//- its not public
|
||||
else if(!isPublic)
|
||||
{
|
||||
} else if (!isPublic) {
|
||||
// - it's not public
|
||||
|
||||
authLogger.debug("Auth failed: invalid session & pad is not public");
|
||||
//--> deny access
|
||||
// --> deny access
|
||||
statusObject = {accessStatus: "deny"};
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
throw new Error("Ops, something wrong happend");
|
||||
}
|
||||
}
|
||||
// there is no valid session avaiable AND pad doesn't exists
|
||||
else
|
||||
{
|
||||
authLogger.debug("Auth failed: invalid session & pad does not exist");
|
||||
//--> deny access
|
||||
statusObject = {accessStatus: "deny"};
|
||||
} else {
|
||||
// there is no valid session avaiable AND pad doesn't exist
|
||||
authLogger.debug("Auth failed: invalid session & pad does not exist");
|
||||
// --> deny access
|
||||
statusObject = {accessStatus: "deny"};
|
||||
}
|
||||
|
||||
|
||||
callback();
|
||||
}
|
||||
], function(err)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
],
|
||||
function(err) {
|
||||
if (ERR(err, callback)) return;
|
||||
|
||||
callback(null, statusObject);
|
||||
});
|
||||
};
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
var ERR = require("async-stacktrace");
|
||||
var customError = require("../utils/customError");
|
||||
|
@ -26,7 +25,7 @@ var db = require("./DB").db;
|
|||
var async = require("async");
|
||||
var groupMangager = require("./GroupManager");
|
||||
var authorMangager = require("./AuthorManager");
|
||||
|
||||
|
||||
exports.doesSessionExist = function(sessionID, callback)
|
||||
{
|
||||
//check if the database entry of this session exists
|
||||
|
@ -36,7 +35,7 @@ exports.doesSessionExist = function(sessionID, callback)
|
|||
callback(null, session != null);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new session between an author and a group
|
||||
*/
|
||||
|
@ -45,159 +44,148 @@ exports.createSession = function(groupID, authorID, validUntil, callback)
|
|||
var sessionID;
|
||||
|
||||
async.series([
|
||||
//check if group exists
|
||||
// check if the group exists
|
||||
function(callback)
|
||||
{
|
||||
groupMangager.doesGroupExist(groupID, function(err, exists)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
//group does not exist
|
||||
if(exists == false)
|
||||
{
|
||||
callback(new customError("groupID does not exist","apierror"));
|
||||
}
|
||||
//everything is fine, continue
|
||||
else
|
||||
{
|
||||
|
||||
// group does not exist
|
||||
if (exists == false) {
|
||||
callback(new customError("groupID does not exist", "apierror"));
|
||||
} else {
|
||||
// everything is fine, continue
|
||||
callback();
|
||||
}
|
||||
});
|
||||
},
|
||||
//check if author exists
|
||||
|
||||
// check if the author exists
|
||||
function(callback)
|
||||
{
|
||||
authorMangager.doesAuthorExists(authorID, function(err, exists)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
//author does not exist
|
||||
if(exists == false)
|
||||
{
|
||||
callback(new customError("authorID does not exist","apierror"));
|
||||
}
|
||||
//everything is fine, continue
|
||||
else
|
||||
{
|
||||
|
||||
if (exists == false) {
|
||||
// author does not exist
|
||||
callback(new customError("authorID does not exist", "apierror"));
|
||||
} else {
|
||||
// everything is fine, continue
|
||||
callback();
|
||||
}
|
||||
});
|
||||
},
|
||||
//check validUntil and create the session db entry
|
||||
|
||||
// check validUntil and create the session db entry
|
||||
function(callback)
|
||||
{
|
||||
//check if rev is a number
|
||||
if(typeof validUntil != "number")
|
||||
// check if rev is a number
|
||||
if (typeof validUntil != "number")
|
||||
{
|
||||
//try to parse the number
|
||||
if(isNaN(parseInt(validUntil)))
|
||||
{
|
||||
callback(new customError("validUntil is not a number","apierror"));
|
||||
// try to parse the number
|
||||
if (isNaN(parseInt(validUntil))) {
|
||||
callback(new customError("validUntil is not a number", "apierror"));
|
||||
return;
|
||||
}
|
||||
|
||||
validUntil = parseInt(validUntil);
|
||||
}
|
||||
|
||||
//ensure this is not a negativ number
|
||||
if(validUntil < 0)
|
||||
{
|
||||
callback(new customError("validUntil is a negativ number","apierror"));
|
||||
|
||||
// ensure this is not a negative number
|
||||
if (validUntil < 0) {
|
||||
callback(new customError("validUntil is a negativ number", "apierror"));
|
||||
return;
|
||||
}
|
||||
|
||||
//ensure this is not a float value
|
||||
if(!is_int(validUntil))
|
||||
{
|
||||
callback(new customError("validUntil is a float value","apierror"));
|
||||
|
||||
// ensure this is not a float value
|
||||
if (!is_int(validUntil)) {
|
||||
callback(new customError("validUntil is a float value", "apierror"));
|
||||
return;
|
||||
}
|
||||
|
||||
//check if validUntil is in the future
|
||||
if(Math.floor(Date.now()/1000) > validUntil)
|
||||
{
|
||||
callback(new customError("validUntil is in the past","apierror"));
|
||||
|
||||
// check if validUntil is in the future
|
||||
if (Math.floor(Date.now()/1000) > validUntil) {
|
||||
callback(new customError("validUntil is in the past", "apierror"));
|
||||
return;
|
||||
}
|
||||
|
||||
//generate sessionID
|
||||
|
||||
// generate sessionID
|
||||
sessionID = "s." + randomString(16);
|
||||
|
||||
//set the session into the database
|
||||
|
||||
// set the session into the database
|
||||
db.set("session:" + sessionID, {"groupID": groupID, "authorID": authorID, "validUntil": validUntil});
|
||||
|
||||
|
||||
callback();
|
||||
},
|
||||
//set the group2sessions entry
|
||||
|
||||
// set the group2sessions entry
|
||||
function(callback)
|
||||
{
|
||||
//get the entry
|
||||
// get the entry
|
||||
db.get("group2sessions:" + groupID, function(err, group2sessions)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
//the entry doesn't exist so far, let's create it
|
||||
if(group2sessions == null || group2sessions.sessionIDs == null)
|
||||
{
|
||||
|
||||
if (group2sessions == null || group2sessions.sessionIDs == null) {
|
||||
// the entry doesn't exist so far, let's create it
|
||||
group2sessions = {sessionIDs : {}};
|
||||
}
|
||||
|
||||
//add the entry for this session
|
||||
|
||||
// add the entry for this session
|
||||
group2sessions.sessionIDs[sessionID] = 1;
|
||||
|
||||
//save the new element back
|
||||
|
||||
// save the new element back
|
||||
db.set("group2sessions:" + groupID, group2sessions);
|
||||
|
||||
|
||||
callback();
|
||||
});
|
||||
},
|
||||
//set the author2sessions entry
|
||||
|
||||
// set the author2sessions entry
|
||||
function(callback)
|
||||
{
|
||||
//get the entry
|
||||
// get the entry
|
||||
db.get("author2sessions:" + authorID, function(err, author2sessions)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
//the entry doesn't exist so far, let's create it
|
||||
if(author2sessions == null || author2sessions.sessionIDs == null)
|
||||
{
|
||||
|
||||
if (author2sessions == null || author2sessions.sessionIDs == null) {
|
||||
// the entry doesn't exist so far, let's create it
|
||||
author2sessions = {sessionIDs : {}};
|
||||
}
|
||||
|
||||
//add the entry for this session
|
||||
|
||||
// add the entry for this session
|
||||
author2sessions.sessionIDs[sessionID] = 1;
|
||||
|
||||
|
||||
//save the new element back
|
||||
db.set("author2sessions:" + authorID, author2sessions);
|
||||
|
||||
|
||||
callback();
|
||||
});
|
||||
}
|
||||
], function(err)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
//return error and sessionID
|
||||
|
||||
// return error and sessionID
|
||||
callback(null, {sessionID: sessionID});
|
||||
})
|
||||
}
|
||||
|
||||
exports.getSessionInfo = function(sessionID, callback)
|
||||
{
|
||||
//check if the database entry of this session exists
|
||||
// check if the database entry of this session exists
|
||||
db.get("session:" + sessionID, function (err, session)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
//session does not exists
|
||||
if(session == null)
|
||||
{
|
||||
callback(new customError("sessionID does not exist","apierror"))
|
||||
}
|
||||
//everything is fine, return the sessioninfos
|
||||
else
|
||||
{
|
||||
|
||||
if (session == null) {
|
||||
// session does not exist
|
||||
callback(new customError("sessionID does not exist", "apierror"))
|
||||
} else {
|
||||
// everything is fine, return the sessioninfos
|
||||
callback(null, session);
|
||||
}
|
||||
});
|
||||
|
@ -214,27 +202,25 @@ exports.deleteSession = function(sessionID, callback)
|
|||
async.series([
|
||||
function(callback)
|
||||
{
|
||||
//get the session entry
|
||||
// get the session entry
|
||||
db.get("session:" + sessionID, function (err, session)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
//session does not exists
|
||||
if(session == null)
|
||||
{
|
||||
callback(new customError("sessionID does not exist","apierror"))
|
||||
}
|
||||
//everything is fine, return the sessioninfos
|
||||
else
|
||||
{
|
||||
|
||||
if (session == null) {
|
||||
// session does not exist
|
||||
callback(new customError("sessionID does not exist", "apierror"))
|
||||
} else {
|
||||
// everything is fine, use the sessioninfos
|
||||
authorID = session.authorID;
|
||||
groupID = session.groupID;
|
||||
|
||||
|
||||
callback();
|
||||
}
|
||||
});
|
||||
},
|
||||
//get the group2sessions entry
|
||||
|
||||
// get the group2sessions entry
|
||||
function(callback)
|
||||
{
|
||||
db.get("group2sessions:" + groupID, function (err, _group2sessions)
|
||||
|
@ -244,7 +230,8 @@ exports.deleteSession = function(sessionID, callback)
|
|||
callback();
|
||||
});
|
||||
},
|
||||
//get the author2sessions entry
|
||||
|
||||
// get the author2sessions entry
|
||||
function(callback)
|
||||
{
|
||||
db.get("author2sessions:" + authorID, function (err, _author2sessions)
|
||||
|
@ -254,24 +241,25 @@ exports.deleteSession = function(sessionID, callback)
|
|||
callback();
|
||||
});
|
||||
},
|
||||
//remove the values from the database
|
||||
|
||||
// remove the values from the database
|
||||
function(callback)
|
||||
{
|
||||
//remove the session
|
||||
db.remove("session:" + sessionID);
|
||||
|
||||
//remove session from group2sessions
|
||||
|
||||
// remove session from group2sessions
|
||||
if(group2sessions != null) { // Maybe the group was already deleted
|
||||
delete group2sessions.sessionIDs[sessionID];
|
||||
db.set("group2sessions:" + groupID, group2sessions);
|
||||
}
|
||||
|
||||
//remove session from author2sessions
|
||||
// remove session from author2sessions
|
||||
if(author2sessions != null) { // Maybe the author was already deleted
|
||||
delete author2sessions.sessionIDs[sessionID];
|
||||
db.set("author2sessions:" + authorID, author2sessions);
|
||||
}
|
||||
|
||||
|
||||
callback();
|
||||
}
|
||||
], function(err)
|
||||
|
@ -286,40 +274,34 @@ exports.listSessionsOfGroup = function(groupID, callback)
|
|||
groupMangager.doesGroupExist(groupID, function(err, exists)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
//group does not exist
|
||||
if(exists == false)
|
||||
{
|
||||
callback(new customError("groupID does not exist","apierror"));
|
||||
}
|
||||
//everything is fine, continue
|
||||
else
|
||||
{
|
||||
|
||||
if (exists == false) {
|
||||
// group does not exist
|
||||
callback(new customError("groupID does not exist", "apierror"));
|
||||
} else {
|
||||
// everything is fine, continue
|
||||
listSessionsWithDBKey("group2sessions:" + groupID, callback);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
exports.listSessionsOfAuthor = function(authorID, callback)
|
||||
{
|
||||
{
|
||||
authorMangager.doesAuthorExists(authorID, function(err, exists)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
//group does not exist
|
||||
if(exists == false)
|
||||
{
|
||||
callback(new customError("authorID does not exist","apierror"));
|
||||
}
|
||||
//everything is fine, continue
|
||||
else
|
||||
{
|
||||
|
||||
if (exists == false) {
|
||||
// group does not exist
|
||||
callback(new customError("authorID does not exist", "apierror"));
|
||||
} else {
|
||||
// everything is fine, continue
|
||||
listSessionsWithDBKey("author2sessions:" + authorID, callback);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//this function is basicly the code listSessionsOfAuthor and listSessionsOfGroup has in common
|
||||
// this function is basically the code listSessionsOfAuthor and listSessionsOfGroup has in common
|
||||
function listSessionsWithDBKey (dbkey, callback)
|
||||
{
|
||||
var sessions;
|
||||
|
@ -327,7 +309,7 @@ function listSessionsWithDBKey (dbkey, callback)
|
|||
async.series([
|
||||
function(callback)
|
||||
{
|
||||
//get the group2sessions entry
|
||||
// get the group2sessions entry
|
||||
db.get(dbkey, function(err, sessionObject)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
@ -335,26 +317,24 @@ function listSessionsWithDBKey (dbkey, callback)
|
|||
callback();
|
||||
});
|
||||
},
|
||||
|
||||
function(callback)
|
||||
{
|
||||
//collect all sessionIDs in an arrary
|
||||
{
|
||||
// collect all sessionIDs in an arrary
|
||||
var sessionIDs = [];
|
||||
for (var i in sessions)
|
||||
{
|
||||
sessionIDs.push(i);
|
||||
}
|
||||
|
||||
//foreach trough the sessions and get the sessioninfos
|
||||
|
||||
// iterate through the sessions and get the sessioninfos
|
||||
async.forEach(sessionIDs, function(sessionID, callback)
|
||||
{
|
||||
exports.getSessionInfo(sessionID, function(err, sessionInfo)
|
||||
{
|
||||
if (err == "apierror: sessionID does not exist")
|
||||
{
|
||||
if (err == "apierror: sessionID does not exist") {
|
||||
console.warn(`Found bad session ${sessionID} in ${dbkey}`);
|
||||
}
|
||||
else if(ERR(err, callback))
|
||||
{
|
||||
} else if(ERR(err, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -370,8 +350,8 @@ function listSessionsWithDBKey (dbkey, callback)
|
|||
});
|
||||
}
|
||||
|
||||
//checks if a number is an int
|
||||
// checks if a number is an int
|
||||
function is_int(value)
|
||||
{
|
||||
return (parseFloat(value) == parseInt(value)) && !isNaN(value)
|
||||
{
|
||||
return (parseFloat(value) == parseInt(value)) && !isNaN(value);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* Stores session data in the database
|
||||
* Source; https://github.com/edy-b/SciFlowWriter/blob/develop/available_plugins/ep_sciflowwriter/db/DirtyStore.js
|
||||
* This is not used for authors that are created via the API at current
|
||||
|
@ -13,11 +13,12 @@ var SessionStore = module.exports = function SessionStore() {};
|
|||
|
||||
SessionStore.prototype.__proto__ = Store.prototype;
|
||||
|
||||
SessionStore.prototype.get = function(sid, fn){
|
||||
SessionStore.prototype.get = function(sid, fn) {
|
||||
messageLogger.debug('GET ' + sid);
|
||||
|
||||
var self = this;
|
||||
db.get("sessionstorage:" + sid, function (err, sess)
|
||||
{
|
||||
|
||||
db.get("sessionstorage:" + sid, function(err, sess) {
|
||||
if (sess) {
|
||||
sess.cookie.expires = 'string' == typeof sess.cookie.expires ? new Date(sess.cookie.expires) : sess.cookie.expires;
|
||||
if (!sess.cookie.expires || new Date() < sess.cookie.expires) {
|
||||
|
@ -31,26 +32,30 @@ SessionStore.prototype.get = function(sid, fn){
|
|||
});
|
||||
};
|
||||
|
||||
SessionStore.prototype.set = function(sid, sess, fn){
|
||||
SessionStore.prototype.set = function(sid, sess, fn) {
|
||||
messageLogger.debug('SET ' + sid);
|
||||
|
||||
db.set("sessionstorage:" + sid, sess);
|
||||
process.nextTick(function(){
|
||||
if(fn) fn();
|
||||
process.nextTick(function() {
|
||||
if (fn) fn();
|
||||
});
|
||||
};
|
||||
|
||||
SessionStore.prototype.destroy = function(sid, fn){
|
||||
SessionStore.prototype.destroy = function(sid, fn) {
|
||||
messageLogger.debug('DESTROY ' + sid);
|
||||
|
||||
db.remove("sessionstorage:" + sid);
|
||||
process.nextTick(function(){
|
||||
if(fn) fn();
|
||||
process.nextTick(function() {
|
||||
if (fn) fn();
|
||||
});
|
||||
};
|
||||
|
||||
SessionStore.prototype.all = function(fn){
|
||||
SessionStore.prototype.all = function(fn) {
|
||||
messageLogger.debug('ALL');
|
||||
|
||||
var sessions = [];
|
||||
db.forEach(function(key, value){
|
||||
|
||||
db.forEach(function(key, value) {
|
||||
if (key.substr(0,15) === "sessionstorage:") {
|
||||
sessions.push(value);
|
||||
}
|
||||
|
@ -58,20 +63,23 @@ SessionStore.prototype.all = function(fn){
|
|||
fn(null, sessions);
|
||||
};
|
||||
|
||||
SessionStore.prototype.clear = function(fn){
|
||||
SessionStore.prototype.clear = function(fn) {
|
||||
messageLogger.debug('CLEAR');
|
||||
db.forEach(function(key, value){
|
||||
|
||||
db.forEach(function(key, value) {
|
||||
if (key.substr(0,15) === "sessionstorage:") {
|
||||
db.db.remove("session:" + key);
|
||||
}
|
||||
});
|
||||
if(fn) fn();
|
||||
if (fn) fn();
|
||||
};
|
||||
|
||||
SessionStore.prototype.length = function(fn){
|
||||
SessionStore.prototype.length = function(fn) {
|
||||
messageLogger.debug('LENGTH');
|
||||
|
||||
var i = 0;
|
||||
db.forEach(function(key, value){
|
||||
|
||||
db.forEach(function(key, value) {
|
||||
if (key.substr(0,15) === "sessionstorage:") {
|
||||
i++;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue