From 55b68197aacde66cd99037ff04752e30da700e89 Mon Sep 17 00:00:00 2001
From: barisusakli
Date: Thu, 15 Dec 2016 14:47:42 +0300
Subject: [PATCH] closes #4544
---
public/src/admin/settings/cookies.js | 10 +++++++++
src/socket.io/admin.js | 5 ++++-
src/user/auth.js | 33 ++++++++++++++++++++++++++++
src/views/admin/settings/cookies.tpl | 7 ++++++
test/authentication.js | 24 +++++++++++++++++---
5 files changed, 75 insertions(+), 4 deletions(-)
diff --git a/public/src/admin/settings/cookies.js b/public/src/admin/settings/cookies.js
index d113d99dba..0e85691c12 100644
--- a/public/src/admin/settings/cookies.js
+++ b/public/src/admin/settings/cookies.js
@@ -9,6 +9,16 @@ define('admin/settings/cookies', [
Module.init = function () {
colorpicker.enable($('[data-colorpicker="1"]'));
+
+ $('#delete-all-sessions').on('click', function () {
+ socket.emit('admin.deleteAllSessions', function (err) {
+ if (err) {
+ return app.alertError(err.message);
+ }
+ window.location.href = config.relative_path + '/login';
+ });
+ return false;
+ });
};
return Module;
diff --git a/src/socket.io/admin.js b/src/socket.io/admin.js
index d9312cc871..88b800a5ce 100644
--- a/src/socket.io/admin.js
+++ b/src/socket.io/admin.js
@@ -3,7 +3,6 @@
var async = require('async');
var winston = require('winston');
var nconf = require('nconf');
-var path = require('path');
var meta = require('../meta');
var plugins = require('../plugins');
@@ -285,5 +284,9 @@ SocketAdmin.getSearchDict = function (socket, data, callback) {
});
};
+SocketAdmin.deleteAllSessions = function (socket, data, callback) {
+ user.auth.deleteAllSessions(callback);
+};
+
module.exports = SocketAdmin;
diff --git a/src/user/auth.js b/src/user/auth.js
index a6222728e4..219c468304 100644
--- a/src/user/auth.js
+++ b/src/user/auth.js
@@ -5,6 +5,7 @@ var winston = require('winston');
var db = require('../database');
var meta = require('../meta');
var events = require('../events');
+var batch = require('../batch');
module.exports = function (User) {
User.auth = {};
@@ -142,4 +143,36 @@ module.exports = function (User) {
}
], callback);
};
+
+ User.auth.deleteAllSessions = function (callback) {
+ var _ = require('underscore');
+ batch.processSortedSet('users:joindate', function (uids, next) {
+
+ var sessionKeys = uids.map(function (uid) {
+ return 'uid:' + uid + ':sessions';
+ });
+
+ var sessionUUIDKeys = uids.map(function (uid) {
+ return 'uid:' + uid + ':sessionUUID:sessionId';
+ });
+
+ async.waterfall([
+ function (next) {
+ db.getSortedSetRange(sessionKeys, 0, -1, next);
+ },
+ function (sids, next) {
+ sids = _.flatten(sids);
+ async.parallel([
+ async.apply(db.deleteAll, sessionUUIDKeys),
+ async.apply(db.deleteAll, sessionKeys),
+ function (next) {
+ async.each(sids, function (sid, next) {
+ db.sessionStore.destroy(sid, next);
+ }, next);
+ }
+ ], next);
+ }
+ ], next);
+ }, {batch: 1000}, callback);
+ };
};
\ No newline at end of file
diff --git a/src/views/admin/settings/cookies.tpl b/src/views/admin/settings/cookies.tpl
index 8717d63729..516aa8ceca 100644
--- a/src/views/admin/settings/cookies.tpl
+++ b/src/views/admin/settings/cookies.tpl
@@ -48,6 +48,13 @@
Leave blank for default
+
+
diff --git a/test/authentication.js b/test/authentication.js
index 38860e873a..e3ab49a5f5 100644
--- a/test/authentication.js
+++ b/test/authentication.js
@@ -10,10 +10,11 @@ var user = require('../src/user');
describe('authentication', function () {
var jar = request.jar();
-
+ var regularUid;
before(function (done) {
- user.create({username: 'regular', password: 'regularpwd', email: 'regular@nodebb.org' }, function (err) {
+ user.create({username: 'regular', password: 'regularpwd', email: 'regular@nodebb.org' }, function (err, uid) {
assert.ifError(err);
+ regularUid = uid;
done();
});
});
@@ -71,7 +72,7 @@ describe('authentication', function () {
headers: {
'x-csrf-token': body.csrf_token
}
- }, function (err, response, body) {
+ }, function (err) {
assert.ifError(err);
request({
@@ -125,6 +126,23 @@ describe('authentication', function () {
});
});
+ it('should revoke all sessions', function (done) {
+ var socketAdmin = require('../src/socket.io/admin');
+ db.sortedSetCard('uid:' + regularUid + ':sessions', function (err, count) {
+ assert.ifError(err);
+ assert(count);
+ socketAdmin.deleteAllSessions({uid: 1}, {}, function (err) {
+ assert.ifError(err);
+ db.sortedSetCard('uid:' + regularUid + ':sessions', function (err, count) {
+ assert.ifError(err);
+ assert(!count);
+ done();
+ });
+ });
+ });
+
+ });
+
after(function (done) {
db.emptydb(done);