mirror of
https://github.com/ether/etherpad-lite.git
synced 2025-04-23 08:56:17 -04:00
resolve merge conflict
This commit is contained in:
commit
58bbfd8a65
210 changed files with 12113 additions and 7505 deletions
|
@ -74,6 +74,124 @@ exports.listSessionsOfAuthor = sessionManager.listSessionsOfAuthor;
|
|||
/**PAD CONTENT FUNCTIONS*/
|
||||
/************************/
|
||||
|
||||
/**
|
||||
getAttributePool(padID) returns the attribute pool of a pad
|
||||
|
||||
Example returns:
|
||||
{
|
||||
"code":0,
|
||||
"message":"ok",
|
||||
"data": {
|
||||
"pool":{
|
||||
"numToAttrib":{
|
||||
"0":["author","a.X4m8bBWJBZJnWGSh"],
|
||||
"1":["author","a.TotfBPzov54ihMdH"],
|
||||
"2":["author","a.StiblqrzgeNTbK05"],
|
||||
"3":["bold","true"]
|
||||
},
|
||||
"attribToNum":{
|
||||
"author,a.X4m8bBWJBZJnWGSh":0,
|
||||
"author,a.TotfBPzov54ihMdH":1,
|
||||
"author,a.StiblqrzgeNTbK05":2,
|
||||
"bold,true":3
|
||||
},
|
||||
"nextNum":4
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
exports.getAttributePool = function (padID, callback)
|
||||
{
|
||||
getPadSafe(padID, true, function(err, pad)
|
||||
{
|
||||
if (ERR(err, callback)) return;
|
||||
callback(null, {pool: pad.pool});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
getRevisionChangeset (padID, [rev])
|
||||
|
||||
get the changeset at a given revision, or last revision if 'rev' is not defined.
|
||||
|
||||
Example returns:
|
||||
{
|
||||
"code" : 0,
|
||||
"message" : "ok",
|
||||
"data" : "Z:1>6b|5+6b$Welcome to Etherpad!\n\nThis pad text is synchronized as you type, so that everyone viewing this page sees the same text. This allows you to collaborate seamlessly on documents!\n\nGet involved with Etherpad at http://etherpad.org\n"
|
||||
}
|
||||
|
||||
*/
|
||||
exports.getRevisionChangeset = function(padID, rev, callback)
|
||||
{
|
||||
// check if rev is set
|
||||
if (typeof rev === "function")
|
||||
{
|
||||
callback = rev;
|
||||
rev = undefined;
|
||||
}
|
||||
|
||||
// check if rev is a number
|
||||
if (rev !== undefined && typeof rev !== "number")
|
||||
{
|
||||
// try to parse the number
|
||||
if (!isNaN(parseInt(rev)))
|
||||
{
|
||||
rev = parseInt(rev);
|
||||
}
|
||||
else
|
||||
{
|
||||
callback(new customError("rev is not a number", "apierror"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// ensure this is not a negative number
|
||||
if (rev !== undefined && rev < 0)
|
||||
{
|
||||
callback(new customError("rev is not a negative number", "apierror"));
|
||||
return;
|
||||
}
|
||||
|
||||
// ensure this is not a float value
|
||||
if (rev !== undefined && !is_int(rev))
|
||||
{
|
||||
callback(new customError("rev is a float value", "apierror"));
|
||||
return;
|
||||
}
|
||||
|
||||
// get the pad
|
||||
getPadSafe(padID, true, function(err, pad)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
//the client asked for a special revision
|
||||
if(rev !== undefined)
|
||||
{
|
||||
//check if this is a valid revision
|
||||
if(rev > pad.getHeadRevisionNumber())
|
||||
{
|
||||
callback(new customError("rev is higher than the head revision of the pad","apierror"));
|
||||
return;
|
||||
}
|
||||
|
||||
//get the changeset for this revision
|
||||
pad.getRevisionChangeset(rev, function(err, changeset)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
callback(null, changeset);
|
||||
})
|
||||
}
|
||||
//the client wants the latest changeset, lets return it to him
|
||||
else
|
||||
{
|
||||
callback(null, {"changeset": pad.getRevisionChangeset(pad.getHeadRevisionNumber())});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
getText(padID, [rev]) returns the text of a pad
|
||||
|
||||
|
@ -326,8 +444,8 @@ exports.getChatHistory = function(padID, start, end, callback)
|
|||
// fall back to getting the whole chat-history if a parameter is missing
|
||||
if(!start || !end)
|
||||
{
|
||||
start = 0;
|
||||
end = pad.chatHead;
|
||||
start = 0;
|
||||
end = pad.chatHead;
|
||||
}
|
||||
|
||||
if(start >= chatHead && chatHead > 0)
|
||||
|
@ -438,6 +556,46 @@ exports.deletePad = function(padID, callback)
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
copyPad(sourceID, destinationID[, force=false]) copies a pad. If force is true,
|
||||
the destination will be overwritten if it exists.
|
||||
|
||||
Example returns:
|
||||
|
||||
{code: 0, message:"ok", data: {padID: destinationID}}
|
||||
{code: 1, message:"padID does not exist", data: null}
|
||||
*/
|
||||
exports.copyPad = function(sourceID, destinationID, force, callback)
|
||||
{
|
||||
getPadSafe(sourceID, true, function(err, pad)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
pad.copy(destinationID, force, callback);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
movePad(sourceID, destinationID[, force=false]) moves a pad. If force is true,
|
||||
the destination will be overwritten if it exists.
|
||||
|
||||
Example returns:
|
||||
|
||||
{code: 0, message:"ok", data: {padID: destinationID}}
|
||||
{code: 1, message:"padID does not exist", data: null}
|
||||
*/
|
||||
exports.movePad = function(sourceID, destinationID, force, callback)
|
||||
{
|
||||
getPadSafe(sourceID, true, function(err, pad)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
pad.copy(destinationID, force, function(err) {
|
||||
if(ERR(err, callback)) return;
|
||||
pad.remove(callback);
|
||||
});
|
||||
});
|
||||
}
|
||||
/**
|
||||
getReadOnlyLink(padID) returns the read only link of a pad
|
||||
|
||||
|
@ -664,7 +822,7 @@ createDiffHTML(padID, startRev, endRev) returns an object of diffs from 2 points
|
|||
|
||||
Example returns:
|
||||
|
||||
{"code":0,"message":"ok","data":{"html":"<style>\n.authora_HKIv23mEbachFYfH {background-color: #a979d9}\n.authora_n4gEeMLsv1GivNeh {background-color: #a9b5d9}\n.removed {text-decoration: line-through; -ms-filter:'progid:DXImageTransform.Microsoft.Alpha(Opacity=80)'; filter: alpha(opacity=80); opacity: 0.8; }\n</style>Welcome to Etherpad Lite!<br><br>This pad text is synchronized as you type, so that everyone viewing this page sees the same text. This allows you to collaborate seamlessly on documents!<br><br>Get involved with Etherpad at <a href=\"http://etherpad.org\">http://etherpad.org</a><br><span class=\"authora_HKIv23mEbachFYfH\">aw</span><br><br>","authors":["a.HKIv23mEbachFYfH",""]}}
|
||||
{"code":0,"message":"ok","data":{"html":"<style>\n.authora_HKIv23mEbachFYfH {background-color: #a979d9}\n.authora_n4gEeMLsv1GivNeh {background-color: #a9b5d9}\n.removed {text-decoration: line-through; -ms-filter:'progid:DXImageTransform.Microsoft.Alpha(Opacity=80)'; filter: alpha(opacity=80); opacity: 0.8; }\n</style>Welcome to Etherpad!<br><br>This pad text is synchronized as you type, so that everyone viewing this page sees the same text. This allows you to collaborate seamlessly on documents!<br><br>Get involved with Etherpad at <a href=\"http://etherpad.org\">http://etherpad.org</a><br><span class=\"authora_HKIv23mEbachFYfH\">aw</span><br><br>","authors":["a.HKIv23mEbachFYfH",""]}}
|
||||
{"code":4,"message":"no or wrong API Key","data":null}
|
||||
*/
|
||||
exports.createDiffHTML = function(padID, startRev, endRev, callback){
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
var ERR = require("async-stacktrace");
|
||||
var db = require("./DB").db;
|
||||
var async = require("async");
|
||||
var customError = require("../utils/customError");
|
||||
var randomString = require('ep_etherpad-lite/static/js/pad_utils').randomString;
|
||||
|
||||
exports.getColorPalette = function(){
|
||||
|
@ -272,4 +273,4 @@ exports.removePad = function (authorID, padID)
|
|||
db.set("globalAuthor:" + authorID, author);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -215,25 +215,32 @@ exports.createGroupIfNotExistsFor = function(groupMapper, callback)
|
|||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
// there is a group for this mapper
|
||||
if(groupID) {
|
||||
exports.doesGroupExist(groupID, function(err, exists) {
|
||||
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)
|
||||
})
|
||||
}
|
||||
//there is no group for this mapper, let's create a group
|
||||
if(groupID == null)
|
||||
{
|
||||
else {
|
||||
createGroupForMapper(callback)
|
||||
}
|
||||
|
||||
function createGroupForMapper(cb) {
|
||||
exports.createGroup(function(err, responseObj)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
if(ERR(err, cb)) return;
|
||||
|
||||
//create the mapper entry for this group
|
||||
db.set("mapper2group:"+groupMapper, responseObj.groupID);
|
||||
|
||||
callback(null, responseObj);
|
||||
cb(null, responseObj);
|
||||
});
|
||||
}
|
||||
//there is a group for this mapper, let's return it
|
||||
else
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
callback(null, {groupID: groupID});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,8 @@ var settings = require('../utils/Settings');
|
|||
var authorManager = require("./AuthorManager");
|
||||
var padManager = require("./PadManager");
|
||||
var padMessageHandler = require("../handler/PadMessageHandler");
|
||||
var groupManager = require("./GroupManager");
|
||||
var customError = require("../utils/customError");
|
||||
var readOnlyManager = require("./ReadOnlyManager");
|
||||
var crypto = require("crypto");
|
||||
var randomString = require("../utils/randomstring");
|
||||
|
@ -404,6 +406,152 @@ Pad.prototype.init = function init(text, callback) {
|
|||
});
|
||||
};
|
||||
|
||||
Pad.prototype.copy = function copy(destinationID, force, callback) {
|
||||
var sourceID = this.id;
|
||||
var _this = this;
|
||||
|
||||
// make force optional
|
||||
if (typeof force == "function") {
|
||||
callback = force;
|
||||
force = false;
|
||||
}
|
||||
else if (force == undefined || force.toLowerCase() != "true") {
|
||||
force = false;
|
||||
}
|
||||
else force = true;
|
||||
|
||||
//kick everyone from this pad
|
||||
// TODO: this presents a message on the client saying that the pad was 'deleted'. Fix this?
|
||||
padMessageHandler.kickSessionsFromPad(sourceID);
|
||||
|
||||
// flush the source pad:
|
||||
_this.saveToDatabase();
|
||||
|
||||
async.series([
|
||||
// if it's a group pad, let's make sure the group exists.
|
||||
function(callback)
|
||||
{
|
||||
if (destinationID.indexOf("$") != -1)
|
||||
{
|
||||
groupManager.doesGroupExist(destinationID.split("$")[0], 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"));
|
||||
return;
|
||||
}
|
||||
//everything is fine, continue
|
||||
else
|
||||
{
|
||||
callback();
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
callback();
|
||||
},
|
||||
// if the pad exists, we should abort, unless forced.
|
||||
function(callback)
|
||||
{
|
||||
console.log("destinationID", destinationID, force);
|
||||
padManager.doesPadExists(destinationID, function (err, exists)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
if(exists == true)
|
||||
{
|
||||
if (!force)
|
||||
{
|
||||
console.log("erroring out without force");
|
||||
callback(new customError("destinationID already exists","apierror"));
|
||||
console.log("erroring out without force - after");
|
||||
return;
|
||||
}
|
||||
else // exists and forcing
|
||||
{
|
||||
padManager.getPad(destinationID, function(err, pad) {
|
||||
if (ERR(err, callback)) return;
|
||||
pad.remove(callback);
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
callback();
|
||||
}
|
||||
});
|
||||
},
|
||||
// copy the 'pad' entry
|
||||
function(callback)
|
||||
{
|
||||
db.get("pad:"+sourceID, function(err, pad) {
|
||||
db.set("pad:"+destinationID, pad);
|
||||
});
|
||||
callback();
|
||||
},
|
||||
//copy all relations
|
||||
function(callback)
|
||||
{
|
||||
async.parallel([
|
||||
//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) {
|
||||
if (ERR(err, callback)) return;
|
||||
db.set("pad:"+destinationID+":chat:"+i, chat);
|
||||
});
|
||||
}
|
||||
|
||||
callback();
|
||||
},
|
||||
//copy all revisions
|
||||
function(callback)
|
||||
{
|
||||
var revHead = _this.head;
|
||||
//console.log(revHead);
|
||||
for(var i=0;i<=revHead;i++)
|
||||
{
|
||||
db.get("pad:"+sourceID+":revs:"+i, function (err, rev) {
|
||||
//console.log("HERE");
|
||||
|
||||
if (ERR(err, callback)) return;
|
||||
db.set("pad:"+destinationID+":revs:"+i, rev);
|
||||
});
|
||||
}
|
||||
|
||||
callback();
|
||||
},
|
||||
//add the new pad to all authors who contributed to the old one
|
||||
function(callback)
|
||||
{
|
||||
var authorIDs = _this.getAllAuthors();
|
||||
|
||||
authorIDs.forEach(function (authorID)
|
||||
{
|
||||
console.log("authors");
|
||||
authorManager.addPad(authorID, destinationID);
|
||||
});
|
||||
|
||||
callback();
|
||||
},
|
||||
// parallel
|
||||
], callback);
|
||||
},
|
||||
// series
|
||||
], function(err)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
callback(null, {padID: destinationID});
|
||||
});
|
||||
};
|
||||
|
||||
Pad.prototype.remove = function remove(callback) {
|
||||
var padID = this.id;
|
||||
var _this = this;
|
||||
|
@ -487,7 +635,7 @@ Pad.prototype.remove = function remove(callback) {
|
|||
|
||||
authorIDs.forEach(function (authorID)
|
||||
{
|
||||
authorManager.removePad(authorID, padID);
|
||||
authorManager.removePad(authorID, padID);
|
||||
});
|
||||
|
||||
callback();
|
||||
|
|
|
@ -24,7 +24,9 @@ var Pad = require("../db/Pad").Pad;
|
|||
var db = require("./DB").db;
|
||||
|
||||
/**
|
||||
* An Object containing all known Pads. Provides "get" and "set" functions,
|
||||
* A cache of all loaded Pads.
|
||||
*
|
||||
* Provides "get" and "set" functions,
|
||||
* which should be used instead of indexing with brackets. These prepend a
|
||||
* colon to the key, to avoid conflicting with built-in Object methods or with
|
||||
* these functions themselves.
|
||||
|
@ -37,39 +39,55 @@ var globalPads = {
|
|||
set: function (name, value)
|
||||
{
|
||||
this[':'+name] = value;
|
||||
padList.addPad(name);
|
||||
},
|
||||
remove: function (name) { delete this[':'+name]; }
|
||||
remove: function (name) {
|
||||
delete this[':'+name];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A cache of the list of all pads.
|
||||
*
|
||||
* Updated without db access as new pads are created/old ones removed.
|
||||
*/
|
||||
var padList = {
|
||||
list: [],
|
||||
sorted : false,
|
||||
init: function()
|
||||
initiated: false,
|
||||
init: function(cb)
|
||||
{
|
||||
db.findKeys("pad:*", "*:*:*", function(err, dbData)
|
||||
{
|
||||
if(ERR(err)) return;
|
||||
if(ERR(err, cb)) return;
|
||||
if(dbData != null){
|
||||
padList.initiated = true
|
||||
dbData.forEach(function(val){
|
||||
padList.addPad(val.replace(/pad:/,""),false);
|
||||
});
|
||||
cb && cb()
|
||||
}
|
||||
});
|
||||
return this;
|
||||
},
|
||||
load: function(cb) {
|
||||
if(this.initiated) cb && cb()
|
||||
else this.init(cb)
|
||||
},
|
||||
/**
|
||||
* Returns all pads in alphabetical order as array.
|
||||
*/
|
||||
getPads: function(){
|
||||
if(!this.sorted){
|
||||
this.list=this.list.sort();
|
||||
this.sorted=true;
|
||||
}
|
||||
return this.list;
|
||||
getPads: function(cb){
|
||||
this.load(function() {
|
||||
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){
|
||||
this.list.push(name);
|
||||
this.sorted=false;
|
||||
|
@ -77,7 +95,8 @@ var padList = {
|
|||
},
|
||||
removePad: function(name)
|
||||
{
|
||||
var index=this.list.indexOf(name);
|
||||
if(!this.initiated) return;
|
||||
var index = this.list.indexOf(name);
|
||||
if(index>-1){
|
||||
this.list.splice(index,1);
|
||||
this.sorted=false;
|
||||
|
@ -85,7 +104,6 @@ var padList = {
|
|||
}
|
||||
};
|
||||
//initialises the allknowing data structure
|
||||
padList.init();
|
||||
|
||||
/**
|
||||
* An array of padId transformations. These represent changes in pad name policy over
|
||||
|
@ -146,25 +164,23 @@ exports.getPad = function(id, text, callback)
|
|||
else
|
||||
{
|
||||
pad = new Pad(id);
|
||||
|
||||
|
||||
//initalize the pad
|
||||
pad.init(text, function(err)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
globalPads.set(id, pad);
|
||||
padList.addPad(id);
|
||||
callback(null, pad);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
exports.listAllPads = function(callback)
|
||||
exports.listAllPads = function(cb)
|
||||
{
|
||||
if(callback != null){
|
||||
callback(null,{padIDs: padList.getPads()});
|
||||
}else{
|
||||
return {padIDs: padList.getPads()};
|
||||
}
|
||||
padList.getPads(function(list) {
|
||||
cb && cb(null, {padIDs: list});
|
||||
});
|
||||
}
|
||||
|
||||
//checks if a pad exists
|
||||
|
@ -230,9 +246,8 @@ exports.removePad = function(padId){
|
|||
padList.removePad(padId);
|
||||
}
|
||||
|
||||
//removes a pad from the array
|
||||
//removes a pad from the cache
|
||||
exports.unloadPad = function(padId)
|
||||
{
|
||||
if(globalPads.get(padId))
|
||||
globalPads.remove(padId);
|
||||
globalPads.remove(padId);
|
||||
}
|
||||
|
|
|
@ -77,28 +77,22 @@ exports.getPadId = function(readOnlyId, callback)
|
|||
* returns a the padId and readonlyPadId in an object for any id
|
||||
* @param {String} padIdOrReadonlyPadId read only id or real pad id
|
||||
*/
|
||||
exports.getIds = function(padIdOrReadonlyPadId, callback) {
|
||||
var handleRealPadId = function () {
|
||||
exports.getReadOnlyId(padIdOrReadonlyPadId, function (err, value) {
|
||||
exports.getIds = function(id, callback) {
|
||||
if (id.indexOf("r.") == 0)
|
||||
exports.getPadId(id, function (err, value) {
|
||||
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
|
||||
exports.getReadOnlyId(id, function (err, value) {
|
||||
callback(null, {
|
||||
readOnlyPadId: value,
|
||||
padId: padIdOrReadonlyPadId,
|
||||
padId: id,
|
||||
readonly: false
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (padIdOrReadonlyPadId.indexOf("r.") != 0)
|
||||
return handleRealPadId();
|
||||
|
||||
exports.getPadId(padIdOrReadonlyPadId, function (err, value) {
|
||||
if(ERR(err, callback)) return;
|
||||
if (value == null)
|
||||
return handleRealPadId();
|
||||
callback(null, {
|
||||
readOnlyPadId: padIdOrReadonlyPadId,
|
||||
padId: value,
|
||||
readonly: true
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@ var padManager = require("./PadManager");
|
|||
var sessionManager = require("./SessionManager");
|
||||
var settings = require("../utils/Settings");
|
||||
var randomString = require('ep_etherpad-lite/static/js/pad_utils').randomString;
|
||||
var log4js = require('log4js');
|
||||
var authLogger = log4js.getLogger("auth");
|
||||
|
||||
/**
|
||||
* This function controlls the access to a pad, it checks if the user can access a pad.
|
||||
|
@ -39,6 +41,11 @@ var randomString = require('ep_etherpad-lite/static/js/pad_utils').randomString;
|
|||
exports.checkAccess = function (padID, sessionCookie, token, password, callback)
|
||||
{
|
||||
var statusObject;
|
||||
|
||||
if(!padID) {
|
||||
callback(null, {accessStatus: "deny"});
|
||||
return;
|
||||
}
|
||||
|
||||
// a valid session is required (api-only mode)
|
||||
if(settings.requireSession)
|
||||
|
@ -117,31 +124,43 @@ exports.checkAccess = function (padID, sessionCookie, token, password, callback)
|
|||
//get information about all sessions contained in this cookie
|
||||
function(callback)
|
||||
{
|
||||
if (!sessionCookie) {
|
||||
if (!sessionCookie)
|
||||
{
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
var sessionIDs = sessionCookie.split(',');
|
||||
async.forEach(sessionIDs, function(sessionID, callback) {
|
||||
sessionManager.getSessionInfo(sessionID, function(err, sessionInfo) {
|
||||
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") return;
|
||||
if(err && err.message == "sessionID does not exist")
|
||||
{
|
||||
authLogger.debug("Auth failed: unknown session");
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
var now = Math.floor(new Date().getTime()/1000);
|
||||
|
||||
//is it for this group?
|
||||
if(sessionInfo.groupID != groupID) {
|
||||
callback();
|
||||
return;
|
||||
if(sessionInfo.groupID != groupID)
|
||||
{
|
||||
authLogger.debug("Auth failed: wrong group");
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
//is validUntil still ok?
|
||||
if(sessionInfo.validUntil <= now){
|
||||
callback();
|
||||
return;
|
||||
if(sessionInfo.validUntil <= now)
|
||||
{
|
||||
authLogger.debug("Auth failed: validUntil");
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
// There is a valid session
|
||||
|
@ -234,7 +253,11 @@ exports.checkAccess = function (padID, sessionCookie, token, password, callback)
|
|||
//--> grant access
|
||||
statusObject = {accessStatus: "grant", authorID: sessionAuthor};
|
||||
//--> deny access if user isn't allowed to create the pad
|
||||
if(settings.editOnly) statusObject.accessStatus = "deny";
|
||||
if(settings.editOnly)
|
||||
{
|
||||
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)
|
||||
|
@ -266,6 +289,7 @@ exports.checkAccess = function (padID, sessionCookie, token, password, callback)
|
|||
//- its not public
|
||||
else if(!isPublic)
|
||||
{
|
||||
authLogger.debug("Auth failed: invalid session & pad is not public");
|
||||
//--> deny access
|
||||
statusObject = {accessStatus: "deny"};
|
||||
}
|
||||
|
@ -277,6 +301,7 @@ exports.checkAccess = function (padID, sessionCookie, token, password, callback)
|
|||
// 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"};
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* The Session Manager provides functions to manage session in the database
|
||||
* The Session Manager provides functions to manage session in the database, it only provides session management for sessions created by the API
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
82
src/node/db/SessionStore.js
Normal file
82
src/node/db/SessionStore.js
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
var Store = require('ep_etherpad-lite/node_modules/connect/lib/middleware/session/store'),
|
||||
utils = require('ep_etherpad-lite/node_modules/connect/lib/utils'),
|
||||
Session = require('ep_etherpad-lite/node_modules/connect/lib/middleware/session/session'),
|
||||
db = require('ep_etherpad-lite/node/db/DB').db,
|
||||
log4js = require('ep_etherpad-lite/node_modules/log4js'),
|
||||
messageLogger = log4js.getLogger("SessionStore");
|
||||
|
||||
var SessionStore = module.exports = function SessionStore() {};
|
||||
|
||||
SessionStore.prototype.__proto__ = Store.prototype;
|
||||
|
||||
SessionStore.prototype.get = function(sid, fn){
|
||||
messageLogger.debug('GET ' + sid);
|
||||
var self = this;
|
||||
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) {
|
||||
fn(null, sess);
|
||||
} else {
|
||||
self.destroy(sid, fn);
|
||||
}
|
||||
} else {
|
||||
fn();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
SessionStore.prototype.set = function(sid, sess, fn){
|
||||
messageLogger.debug('SET ' + sid);
|
||||
db.set("sessionstorage:" + sid, sess);
|
||||
process.nextTick(function(){
|
||||
if(fn) fn();
|
||||
});
|
||||
};
|
||||
|
||||
SessionStore.prototype.destroy = function(sid, fn){
|
||||
messageLogger.debug('DESTROY ' + sid);
|
||||
db.remove("sessionstorage:" + sid);
|
||||
process.nextTick(function(){
|
||||
if(fn) fn();
|
||||
});
|
||||
};
|
||||
|
||||
SessionStore.prototype.all = function(fn){
|
||||
messageLogger.debug('ALL');
|
||||
var sessions = [];
|
||||
db.forEach(function(key, value){
|
||||
if (key.substr(0,15) === "sessionstorage:") {
|
||||
sessions.push(value);
|
||||
}
|
||||
});
|
||||
fn(null, sessions);
|
||||
};
|
||||
|
||||
SessionStore.prototype.clear = function(fn){
|
||||
messageLogger.debug('CLEAR');
|
||||
db.forEach(function(key, value){
|
||||
if (key.substr(0,15) === "sessionstorage:") {
|
||||
db.db.remove("session:" + key);
|
||||
}
|
||||
});
|
||||
if(fn) fn();
|
||||
};
|
||||
|
||||
SessionStore.prototype.length = function(fn){
|
||||
messageLogger.debug('LENGTH');
|
||||
var i = 0;
|
||||
db.forEach(function(key, value){
|
||||
if (key.substr(0,15) === "sessionstorage:") {
|
||||
i++;
|
||||
}
|
||||
});
|
||||
fn(null, i);
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue