mirror of
https://github.com/ether/etherpad-lite.git
synced 2025-01-31 19:02:59 +01:00
Merge pull request #1523 from ether/store-sessions-in-db
Store sessions in db
This commit is contained in:
commit
18b6cf1534
8 changed files with 111 additions and 16 deletions
|
@ -15,6 +15,10 @@
|
|||
"ip": "0.0.0.0",
|
||||
"port" : 9001,
|
||||
|
||||
// Session Key, used for reconnecting user sessions
|
||||
// Set this to a secure string at least 10 characters long. Do not share this value.
|
||||
"sessionKey" : "",
|
||||
|
||||
/*
|
||||
// Node native SSL support
|
||||
// this is disabled by default
|
||||
|
|
|
@ -253,9 +253,7 @@ exports.getHTML = function(padID, rev, callback)
|
|||
exportHtml.getPadHTML(pad, undefined, function (err, html)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
data = {html: html};
|
||||
|
||||
callback(null, data);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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() < 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);
|
||||
};
|
|
@ -928,6 +928,8 @@ function handleClientReady(client, message)
|
|||
//If this is a reconnect, we don't have to send the client the ClientVars again
|
||||
if(message.reconnect == true)
|
||||
{
|
||||
//Join the pad and start receiving updates
|
||||
client.join(padIds.padId);
|
||||
//Save the revision in sessioninfos, we take the revision from the info the client send to us
|
||||
sessioninfos[client.id].rev = message.client_rev;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ var httpLogger = log4js.getLogger("http");
|
|||
var settings = require('../../utils/Settings');
|
||||
var randomString = require('ep_etherpad-lite/static/js/pad_utils').randomString;
|
||||
var hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks');
|
||||
|
||||
var ueberStore = require('../../db/SessionStore');
|
||||
|
||||
//checks for basic http auth
|
||||
exports.basicAuth = function (req, res, next) {
|
||||
|
@ -102,15 +102,14 @@ exports.expressConfigure = function (hook_name, args, cb) {
|
|||
* handling it cleaner :) */
|
||||
|
||||
if (!exports.sessionStore) {
|
||||
exports.sessionStore = new express.session.MemoryStore();
|
||||
exports.secret = randomString(32);
|
||||
exports.sessionStore = new ueberStore();
|
||||
exports.secret = settings.sessionKey; // Isn't this being reset each time the server spawns?
|
||||
}
|
||||
|
||||
args.app.use(express.cookieParser(exports.secret));
|
||||
|
||||
args.app.use(express.cookieParser(exports.secret));
|
||||
args.app.sessionStore = exports.sessionStore;
|
||||
args.app.use(express.session({store: args.app.sessionStore,
|
||||
key: 'express_sid' }));
|
||||
args.app.use(express.session({secret: exports.secret, store: args.app.sessionStore, key: 'express_sid' }));
|
||||
|
||||
args.app.use(exports.basicAuth);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@ var argv = require('./Cli').argv;
|
|||
var npm = require("npm/lib/npm.js");
|
||||
var vm = require('vm');
|
||||
var log4js = require("log4js");
|
||||
var randomString = require('ep_etherpad-lite/static/js/pad_utils').randomString;
|
||||
|
||||
|
||||
/* Root path of the installation */
|
||||
exports.root = path.normalize(path.join(npm.dir, ".."));
|
||||
|
@ -112,6 +114,11 @@ exports.loglevel = "INFO";
|
|||
*/
|
||||
exports.logconfig = { appenders: [{ type: "console" }]};
|
||||
|
||||
/*
|
||||
* Session Key, do not sure this.
|
||||
*/
|
||||
exports.sessionKey = false;
|
||||
|
||||
/* This setting is used if you need authentication and/or
|
||||
* authorization. Note: /admin always requires authentication, and
|
||||
* either authorization by a module, or a user with is_admin set */
|
||||
|
@ -132,8 +139,6 @@ exports.abiwordAvailable = function()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
exports.reloadSettings = function reloadSettings() {
|
||||
// Discover where the settings file lives
|
||||
var settingsFilename = argv.settings || "settings.json";
|
||||
|
@ -184,6 +189,11 @@ exports.reloadSettings = function reloadSettings() {
|
|||
log4js.setGlobalLogLevel(exports.loglevel);//set loglevel
|
||||
log4js.replaceConsole();
|
||||
|
||||
if(!exports.sessionKey){ // If the secretKey isn't set we also create yet another unique value here
|
||||
exports.sessionKey = randomString(32);
|
||||
console.warn("You need to set a sessionKey value in settings.json, this will allow your users to reconnect to your Etherpad Instance if your instance restarts");
|
||||
}
|
||||
|
||||
if(exports.dbType === "dirty"){
|
||||
console.warn("DirtyDB is used. This is fine for testing but not recommended for production.")
|
||||
}
|
||||
|
|
|
@ -43,9 +43,8 @@ var padconnectionstatus = (function()
|
|||
status = {
|
||||
what: 'connected'
|
||||
};
|
||||
|
||||
padmodals.showModal('connected');
|
||||
padmodals.hideOverlay(500);
|
||||
padmodals.hideOverlay();
|
||||
},
|
||||
reconnecting: function()
|
||||
{
|
||||
|
@ -54,7 +53,7 @@ var padconnectionstatus = (function()
|
|||
};
|
||||
|
||||
padmodals.showModal('reconnecting');
|
||||
padmodals.showOverlay(500);
|
||||
padmodals.showOverlay();
|
||||
},
|
||||
disconnected: function(msg)
|
||||
{
|
||||
|
@ -73,10 +72,11 @@ var padconnectionstatus = (function()
|
|||
}
|
||||
|
||||
padmodals.showModal(k);
|
||||
padmodals.showOverlay(500);
|
||||
padmodals.showOverlay();
|
||||
},
|
||||
isFullyConnected: function()
|
||||
{
|
||||
padmodals.hideOverlay();
|
||||
return status.what == 'connected';
|
||||
},
|
||||
getStatus: function()
|
||||
|
|
Loading…
Reference in a new issue