diff --git a/node/db/API.js b/node/db/API.js index acce6485..9912b098 100644 --- a/node/db/API.js +++ b/node/db/API.js @@ -230,7 +230,6 @@ Example returns: */ exports.deletePad = function(padID, callback) { - //get the pad getPadSafe(padID, true, function(err, pad) { if(err) @@ -239,7 +238,7 @@ exports.deletePad = function(padID, callback) return; } - + pad.remove(callback); }); } diff --git a/node/db/Pad.js b/node/db/Pad.js index 3511728f..c36361c7 100644 --- a/node/db/Pad.js +++ b/node/db/Pad.js @@ -8,6 +8,9 @@ var db = require("./DB").db; var async = require("async"); var settings = require('../utils/Settings'); var authorManager = require("./AuthorManager"); +var padManager = require("./PadManager"); +var padMessageHandler = require("../handler/PadMessageHandler"); +var readOnlyManager = require("./ReadOnlyManager"); var crypto = require("crypto"); /** @@ -382,6 +385,97 @@ Class('Pad', { callback(null); }); }, + remove: function(callback) + { + var padID = this.id; + var _this = this; + + //kick everyone from this pad + padMessageHandler.kickSessionsFromPad(padID); + + async.series([ + //delete all relations + function(callback) + { + async.parallel([ + //is it a group pad? -> delete the entry of this pad in the group + function(callback) + { + //is it a group pad? + if(padID.indexOf("$")!=-1) + { + var groupID = padID.substring(0,padID.indexOf("$")); + + db.get("group:" + groupID, function (err, group) + { + if(err) {callback(err); return} + + //remove the pad entry + delete group.pads[padID]; + + //set the new value + db.set("group:" + groupID, group); + + callback(); + }); + } + //its no group pad, nothing to do here + else + { + callback(); + } + }, + //remove the readonly entries + function(callback) + { + readOnlyManager.getReadOnlyId(padID, function(err, readonlyID) + { + if(err) {callback(err); return} + + db.remove("pad2readonly:" + padID); + db.remove("readonly2pad:" + readonlyID); + + callback(); + }); + }, + //delete all chat messages + function(callback) + { + var chatHead = _this.chatHead; + + for(var i=0;i<=chatHead;i++) + { + db.remove("pad:"+padID+":chat:"+i); + } + + callback(); + }, + //delete all revisions + function(callback) + { + var revHead = _this.head; + + for(var i=0;i<=revHead;i++) + { + db.remove("pad:"+padID+":revs:"+i); + } + + callback(); + } + ], callback); + }, + //delete the pad entry and delete pad from padManager + function(callback) + { + db.remove("pad:"+padID); + padManager.unloadPad(padID); + callback(); + } + ], function(err) + { + callback(err); + }) + }, //set in db setPublicStatus: function(publicStatus) { diff --git a/node/db/PadManager.js b/node/db/PadManager.js index 01ec5143..8af299cc 100644 --- a/node/db/PadManager.js +++ b/node/db/PadManager.js @@ -107,3 +107,9 @@ exports.isValidPadId = function(padId) return /^(g.[a-zA-Z0-9]{16}\$)?[^$]{1,50}$/.test(padId); } +//removes a pad from the array +exports.unloadPad = function(padId) +{ + if(globalPads[padId]) + delete globalPads[padId]; +} diff --git a/node/handler/APIHandler.js b/node/handler/APIHandler.js index 5aa29a8a..7292c62c 100644 --- a/node/handler/APIHandler.js +++ b/node/handler/APIHandler.js @@ -42,7 +42,7 @@ var functions = { "createPad" : ["padID", "text"], "createGroupPad" : ["groupID", "padName", "text"], "createAuthor" : ["name"], - "createAuthorIfNotExistsFor" : ["authorMapper" , "name"], + "createAuthorIfNotExistsFor": ["authorMapper" , "name"], "createSession" : ["groupID", "authorID", "validUntil"], "deleteSession" : ["sessionID"], "getSessionInfo" : ["sessionID"], @@ -51,7 +51,7 @@ var functions = { "getText" : ["padID", "rev"], "setText" : ["padID", "text"], "getRevisionsCount" : ["padID"], -// "deletePad" : ["padID"], + "deletePad" : ["padID"], "getReadOnlyID" : ["padID"], "setPublicStatus" : ["padID", "publicStatus"], "getPublicStatus" : ["padID"], diff --git a/node/handler/PadMessageHandler.js b/node/handler/PadMessageHandler.js index 3b032314..2d0cf001 100644 --- a/node/handler/PadMessageHandler.js +++ b/node/handler/PadMessageHandler.js @@ -73,6 +73,23 @@ exports.handleConnect = function(client) sessioninfos[client.id]={}; } +/** + * Kicks all sessions from a pad + * @param client the new client + */ +exports.kickSessionsFromPad = function(padID) +{ + //skip if there is nobody on this pad + if(!pad2sessions[padID]) + return; + + //disconnect everyone from this pad + for(var i in pad2sessions[padID]) + { + socketio.sockets.sockets[pad2sessions[padID][i]].json.send({disconnect:"deleted"}); + } +} + /** * Handles the disconnection of a user * @param client the client that leaves @@ -687,7 +704,7 @@ function handleClientReady(client, message) { if(sessioninfos[pad2sessions[message.padId][i]].author == author) { - socketio.sockets.sockets[pad2sessions[message.padId][i]].json.send({disconnect:"doublelogin"}); + socketio.sockets.sockets[pad2sessions[message.padId][i]].json.send({disconnect:"userdup"}); } } } diff --git a/static/css/pad.css b/static/css/pad.css index df68985c..8b0db73c 100644 --- a/static/css/pad.css +++ b/static/css/pad.css @@ -431,6 +431,7 @@ table#otheruserstable { display: none; } } .cboxdisconnected #connectionboxinner div { display: none; } .cboxdisconnected_userdup #connectionboxinner #disconnected_userdup { display: block; } +.cboxdisconnected_deleted #connectionboxinner #disconnected_deleted { display: block; } .cboxdisconnected_initsocketfail #connectionboxinner #disconnected_initsocketfail { display: block; } .cboxdisconnected_looping #connectionboxinner #disconnected_looping { display: block; } .cboxdisconnected_slowcommit #connectionboxinner #disconnected_slowcommit { display: block; } diff --git a/static/js/pad2.js b/static/js/pad2.js index 5ebe6ae0..2653cccc 100644 --- a/static/js/pad2.js +++ b/static/js/pad2.js @@ -251,10 +251,11 @@ function handshake() //This handles every Message after the clientVars else { + //this message advices the client to disconnect if (obj.disconnect) { + padconnectionstatus.disconnected(obj.disconnect); socket.disconnect(); - padconnectionstatus.disconnected("userdup"); return; } else diff --git a/static/js/pad_connectionstatus.js b/static/js/pad_connectionstatus.js index e5f753aa..3d244303 100644 --- a/static/js/pad_connectionstatus.js +++ b/static/js/pad_connectionstatus.js @@ -46,15 +46,19 @@ var padconnectionstatus = (function() }, disconnected: function(msg) { + if(status.what == "disconnected") + return; + status = { what: 'disconnected', why: msg }; var k = String(msg).toLowerCase(); // known reason why - if (!(k == 'userdup' || k == 'looping' || k == 'slowcommit' || k == 'initsocketfail' || k == 'unauth')) + if (!(k == 'userdup' || k == 'deleted' || k == 'looping' || k == 'slowcommit' || k == 'initsocketfail' || k == 'unauth')) { k = 'unknown'; } + var cls = 'modaldialog cboxdisconnected cboxdisconnected_' + k; $("#connectionbox").get(0).className = cls; padmodals.showModal("#connectionbox", 500); diff --git a/static/pad.html b/static/pad.html index 6e1f75b8..513e9dc6 100644 --- a/static/pad.html +++ b/static/pad.html @@ -323,6 +323,11 @@ Use this link to share a read-only version of your pad: +
+ This pad was deleted. +
+If this continues to happen, please let us know