Skip to content

Commit 322f6c1

Browse files
authored
Merge pull request #3167 from strongloop/backport/fix-token-invalidation-on-save
Preserve sessions on User.save() making no changes
2 parents 50743e9 + 0cc2b5b commit 322f6c1

File tree

2 files changed

+25
-25
lines changed

2 files changed

+25
-25
lines changed

common/models/user.js

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -866,30 +866,18 @@ module.exports = function(User) {
866866
next();
867867
});
868868

869-
// Delete old sessions once email is updated
870-
User.observe('before save', function beforeEmailUpdate(ctx, next) {
871-
if (!ctx.Model.app.get('logoutSessionsOnSensitiveChanges')) return next();
869+
User.observe('before save', function prepareForTokenInvalidation(ctx, next) {
870+
var invalidationEnabled = ctx.Model.app &&
871+
ctx.Model.app.get('logoutSessionsOnSensitiveChanges');
872+
if (!invalidationEnabled) return next();
872873

873-
var emailChanged;
874874
if (ctx.isNewInstance) return next();
875875
if (!ctx.where && !ctx.instance) return next();
876-
var pkName = ctx.Model.definition.idName() || 'id';
877-
878-
var isPartialUpdateChangingPassword = ctx.data && 'password' in ctx.data;
879-
880-
// Full replace of User instance => assume password change.
881-
// HashPassword returns a different value for each invocation,
882-
// therefore we cannot tell whether ctx.instance.password is the same
883-
// or not.
884-
var isFullReplaceChangingPassword = !!ctx.instance;
885876

886-
ctx.hookState.isPasswordChange = isPartialUpdateChangingPassword ||
887-
isFullReplaceChangingPassword;
877+
var pkName = ctx.Model.definition.idName() || 'id';
888878

889-
var where;
890-
if (ctx.where) {
891-
where = ctx.where;
892-
} else {
879+
var where = ctx.where;
880+
if (!where) {
893881
where = {};
894882
where[pkName] = ctx.instance[pkName];
895883
}
@@ -899,9 +887,11 @@ module.exports = function(User) {
899887
ctx.hookState.originalUserData = userInstances.map(function(u) {
900888
var user = {};
901889
user[pkName] = u[pkName];
902-
user['email'] = u['email'];
890+
user.email = u.email;
891+
user.password = u.password;
903892
return user;
904893
});
894+
var emailChanged;
905895
if (ctx.instance) {
906896
emailChanged = ctx.instance.email !== ctx.hookState.originalUserData[0].email;
907897
if (emailChanged && ctx.Model.settings.emailVerificationRequired) {
@@ -920,20 +910,23 @@ module.exports = function(User) {
920910
});
921911
});
922912

923-
User.observe('after save', function afterEmailUpdate(ctx, next) {
924-
if (!ctx.Model.app.get('logoutSessionsOnSensitiveChanges')) return next();
913+
User.observe('after save', function invalidateOtherTokens(ctx, next) {
914+
var invalidationEnabled = ctx.Model.app &&
915+
ctx.Model.app.get('logoutSessionsOnSensitiveChanges');
916+
if (!invalidationEnabled) return next();
925917

926918
if (!ctx.instance && !ctx.data) return next();
927919
if (!ctx.hookState.originalUserData) return next();
928920

929921
var pkName = ctx.Model.definition.idName() || 'id';
930922
var newEmail = (ctx.instance || ctx.data).email;
931-
var isPasswordChange = ctx.hookState.isPasswordChange;
923+
var newPassword = (ctx.instance || ctx.data).password;
932924

933-
if (!newEmail && !isPasswordChange) return next();
925+
if (!newEmail && !newPassword) return next();
934926

935927
var userIdsToExpire = ctx.hookState.originalUserData.filter(function(u) {
936-
return (newEmail && u.email !== newEmail) || isPasswordChange;
928+
return (newEmail && u.email !== newEmail) ||
929+
(newPassword && u.password !== newPassword);
937930
}).map(function(u) {
938931
return u[pkName];
939932
});

test/user.test.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2097,6 +2097,13 @@ describe('User', function() {
20972097
});
20982098
});
20992099

2100+
it('keeps sessions AS IS when calling save() with no changes', function(done) {
2101+
user.save(function(err) {
2102+
if (err) return done(err);
2103+
assertPreservedTokens(done);
2104+
});
2105+
});
2106+
21002107
it('keeps sessions AS IS if firstName is added using `updateOrCreate`', function(done) {
21012108
User.updateOrCreate({
21022109
pk: user.pk,

0 commit comments

Comments
 (0)