v1.18.x
barisusakli 8 years ago
parent 9d75c48236
commit 55b68197aa

@ -9,6 +9,16 @@ define('admin/settings/cookies', [
Module.init = function () { Module.init = function () {
colorpicker.enable($('[data-colorpicker="1"]')); 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; return Module;

@ -3,7 +3,6 @@
var async = require('async'); var async = require('async');
var winston = require('winston'); var winston = require('winston');
var nconf = require('nconf'); var nconf = require('nconf');
var path = require('path');
var meta = require('../meta'); var meta = require('../meta');
var plugins = require('../plugins'); 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; module.exports = SocketAdmin;

@ -5,6 +5,7 @@ var winston = require('winston');
var db = require('../database'); var db = require('../database');
var meta = require('../meta'); var meta = require('../meta');
var events = require('../events'); var events = require('../events');
var batch = require('../batch');
module.exports = function (User) { module.exports = function (User) {
User.auth = {}; User.auth = {};
@ -142,4 +143,36 @@ module.exports = function (User) {
} }
], callback); ], 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);
};
}; };

@ -48,6 +48,13 @@
Leave blank for default Leave blank for default
</p> </p>
</div> </div>
<div class="form-group">
<button id="delete-all-sessions" class="btn btn-danger">Revoke All Sessions</button>
<p class="help-block">
This will delete all sessions, you will be logged out and will have to login again!
</p>
</div>
</form> </form>
</div> </div>
</div> </div>

@ -10,10 +10,11 @@ var user = require('../src/user');
describe('authentication', function () { describe('authentication', function () {
var jar = request.jar(); var jar = request.jar();
var regularUid;
before(function (done) { 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); assert.ifError(err);
regularUid = uid;
done(); done();
}); });
}); });
@ -71,7 +72,7 @@ describe('authentication', function () {
headers: { headers: {
'x-csrf-token': body.csrf_token 'x-csrf-token': body.csrf_token
} }
}, function (err, response, body) { }, function (err) {
assert.ifError(err); assert.ifError(err);
request({ 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) { after(function (done) {
db.emptydb(done); db.emptydb(done);

Loading…
Cancel
Save