Preserve current session when invalidating tokens

Fix User model to preserve the current session (provided via
"options.accessToken") when invalidating access tokens after a change
of email or password property.
This commit is contained in:
Miroslav Bajtoš 2017-01-13 11:03:06 +01:00
parent 24bb15233d
commit e17cc3d23a
4 changed files with 43 additions and 3 deletions

View File

@ -657,7 +657,12 @@ module.exports = function(User) {
throw err;
};
User._invalidateAccessTokensOfUsers = function(userIds, cb) {
User._invalidateAccessTokensOfUsers = function(userIds, options, cb) {
if (typeof options === 'function' && cb === undefined) {
cb = options;
options = {};
}
if (!Array.isArray(userIds) || !userIds.length)
return process.nextTick(cb);
@ -666,7 +671,14 @@ module.exports = function(User) {
return process.nextTick(cb);
var AccessToken = accessTokenRelation.modelTo;
AccessToken.deleteAll({userId: {inq: userIds}}, cb);
var query = {userId: {inq: userIds}};
var tokenPK = AccessToken.definition.idName() || 'id';
if (options.accessToken && tokenPK in options.accessToken) {
query[tokenPK] = {neq: options.accessToken[tokenPK]};
}
AccessToken.deleteAll(query, options, cb);
};
/*!
@ -893,7 +905,7 @@ module.exports = function(User) {
}).map(function(u) {
return u.id;
});
ctx.Model._invalidateAccessTokensOfUsers(userIdsToExpire, next);
ctx.Model._invalidateAccessTokensOfUsers(userIdsToExpire, ctx.options, next);
});
};

View File

@ -34,6 +34,7 @@ _beforeEach.withApp = function(app) {
this.get = _request.get;
this.put = _request.put;
this.del = _request.del;
this.patch = _request.patch;
if (app.booting) {
return app.once('booted', done);

View File

@ -92,6 +92,20 @@ describe('users - integration', function() {
done();
});
});
it('should preserve current session when invalidating tokens', function(done) {
var url = '/api/users/' + userId;
var self = this;
this.patch(url)
.send({email: 'new@example.com'})
.set('Authorization', accessToken)
.expect(200, function(err) {
if (err) return done(err);
self.get(url)
.set('Authorization', accessToken)
.expect(200, done);
});
});
});
describe('sub-user', function() {

View File

@ -2263,6 +2263,19 @@ describe('User', function() {
});
});
it('preserves current session', function(done) {
var options = {accessToken: originalUserToken1};
user.updateAttribute('email', 'new@example.com', options, function(err) {
if (err) return done(err);
AccessToken.find({where: {userId: user.id}}, function(err, tokens) {
if (err) return done(err);
var tokenIds = tokens.map(function(t) { return t.id; });
expect(tokenIds).to.eql([originalUserToken1.id]);
done();
});
});
});
it('preserves other user sessions if their password is untouched', function(done) {
var user1, user2, user1Token;
async.series([