Skip to content

Commit 4edce47

Browse files
committed
Fix registration of operation hooks in User model
Operation hooks are inherited by subclassed models, therefore they must be registered outside of `Model.setup()` function. This commit fixes this problem in the built-in User model. There are not tests verifying this change, as writing a test would be too cumbersome and not worth the cost IMO.
1 parent 63beaa2 commit 4edce47

File tree

1 file changed

+48
-43
lines changed

1 file changed

+48
-43
lines changed

common/models/user.js

Lines changed: 48 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -700,49 +700,6 @@ module.exports = function(User) {
700700
next();
701701
});
702702

703-
// Delete old sessions once email is updated
704-
UserModel.observe('before save', function beforeEmailUpdate(ctx, next) {
705-
if (ctx.isNewInstance) return next();
706-
if (!ctx.where && !ctx.instance) return next();
707-
var where = ctx.where || {id: ctx.instance.id};
708-
ctx.Model.find({where: where}, function(err, userInstances) {
709-
if (err) return next(err);
710-
ctx.hookState.originalUserData = userInstances.map(function(u) {
711-
return {id: u.id, email: u.email};
712-
});
713-
if (ctx.instance) {
714-
var emailChanged = ctx.instance.email !== ctx.hookState.originalUserData[0].email;
715-
if (emailChanged && ctx.Model.settings.emailVerificationRequired) {
716-
ctx.instance.emailVerified = false;
717-
}
718-
} else {
719-
var emailChanged = ctx.hookState.originalUserData.some(function(data) {
720-
return data.email != ctx.data.email;
721-
});
722-
if (emailChanged && ctx.Model.settings.emailVerificationRequired) {
723-
ctx.data.emailVerified = false;
724-
}
725-
}
726-
next();
727-
});
728-
});
729-
730-
UserModel.observe('after save', function afterEmailUpdate(ctx, next) {
731-
if (!ctx.Model.relations.accessTokens) return next();
732-
var AccessToken = ctx.Model.relations.accessTokens.modelTo;
733-
if (!ctx.instance && !ctx.data) return next();
734-
var newEmail = (ctx.instance || ctx.data).email;
735-
if (!newEmail) return next();
736-
if (!ctx.hookState.originalUserData) return next();
737-
var idsToExpire = ctx.hookState.originalUserData.filter(function(u) {
738-
return u.email !== newEmail;
739-
}).map(function(u) {
740-
return u.id;
741-
});
742-
if (!idsToExpire.length) return next();
743-
AccessToken.deleteAll({userId: {inq: idsToExpire}}, next);
744-
});
745-
746703
UserModel.remoteMethod(
747704
'login',
748705
{
@@ -855,6 +812,54 @@ module.exports = function(User) {
855812
*/
856813

857814
User.setup();
815+
816+
// --- OPERATION HOOKS ---
817+
//
818+
// Important: Operation hooks are inherited by subclassed models,
819+
// therefore they must be registered outside of setup() function
820+
821+
// Delete old sessions once email is updated
822+
User.observe('before save', function beforeEmailUpdate(ctx, next) {
823+
if (ctx.isNewInstance) return next();
824+
if (!ctx.where && !ctx.instance) return next();
825+
var where = ctx.where || {id: ctx.instance.id};
826+
ctx.Model.find({where: where}, function(err, userInstances) {
827+
if (err) return next(err);
828+
ctx.hookState.originalUserData = userInstances.map(function(u) {
829+
return {id: u.id, email: u.email};
830+
});
831+
if (ctx.instance) {
832+
var emailChanged = ctx.instance.email !== ctx.hookState.originalUserData[0].email;
833+
if (emailChanged && ctx.Model.settings.emailVerificationRequired) {
834+
ctx.instance.emailVerified = false;
835+
}
836+
} else {
837+
var emailChanged = ctx.hookState.originalUserData.some(function(data) {
838+
return data.email != ctx.data.email;
839+
});
840+
if (emailChanged && ctx.Model.settings.emailVerificationRequired) {
841+
ctx.data.emailVerified = false;
842+
}
843+
}
844+
next();
845+
});
846+
});
847+
848+
User.observe('after save', function afterEmailUpdate(ctx, next) {
849+
if (!ctx.Model.relations.accessTokens) return next();
850+
var AccessToken = ctx.Model.relations.accessTokens.modelTo;
851+
if (!ctx.instance && !ctx.data) return next();
852+
var newEmail = (ctx.instance || ctx.data).email;
853+
if (!newEmail) return next();
854+
if (!ctx.hookState.originalUserData) return next();
855+
var idsToExpire = ctx.hookState.originalUserData.filter(function(u) {
856+
return u.email !== newEmail;
857+
}).map(function(u) {
858+
return u.id;
859+
});
860+
if (!idsToExpire.length) return next();
861+
AccessToken.deleteAll({userId: {inq: idsToExpire}}, next);
862+
});
858863
};
859864

860865
function emailValidator(err, done) {

0 commit comments

Comments
 (0)