Skip to content

Commit 66e4e5b

Browse files
authored
Merge pull request #3015 from strongloop/fix/repeated-user-hooks-2x
Fix registration of operation hooks in User model [2.x]
2 parents 9bea50c + 01b2faf commit 66e4e5b

File tree

1 file changed

+57
-53
lines changed

1 file changed

+57
-53
lines changed

common/models/user.js

Lines changed: 57 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -679,15 +679,6 @@ module.exports = function(User) {
679679
}
680680
};
681681

682-
// Access token to normalize email credentials
683-
UserModel.observe('access', function normalizeEmailCase(ctx, next) {
684-
if (!ctx.Model.settings.caseSensitiveEmail && ctx.query.where &&
685-
ctx.query.where.email && typeof(ctx.query.where.email) === 'string') {
686-
ctx.query.where.email = ctx.query.where.email.toLowerCase();
687-
}
688-
next();
689-
});
690-
691682
// Make sure emailVerified is not set by creation
692683
UserModel.beforeRemote('create', function(ctx, user, next) {
693684
var body = ctx.req.body;
@@ -697,50 +688,6 @@ module.exports = function(User) {
697688
next();
698689
});
699690

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

844791
User.setup();
845792

793+
// --- OPERATION HOOKS ---
794+
//
795+
// Important: Operation hooks are inherited by subclassed models,
796+
// therefore they must be registered outside of setup() function
797+
798+
// Access token to normalize email credentials
799+
User.observe('access', function normalizeEmailCase(ctx, next) {
800+
if (!ctx.Model.settings.caseSensitiveEmail && ctx.query.where &&
801+
ctx.query.where.email && typeof(ctx.query.where.email) === 'string') {
802+
ctx.query.where.email = ctx.query.where.email.toLowerCase();
803+
}
804+
next();
805+
});
806+
807+
// Delete old sessions once email is updated
808+
User.observe('before save', function beforeEmailUpdate(ctx, next) {
809+
var emailChanged;
810+
if (ctx.isNewInstance) return next();
811+
if (!ctx.where && !ctx.instance) return next();
812+
var where = ctx.where || { id: ctx.instance.id };
813+
ctx.Model.find({ where: where }, function(err, userInstances) {
814+
if (err) return next(err);
815+
ctx.hookState.originalUserData = userInstances.map(function(u) {
816+
return { id: u.id, email: u.email };
817+
});
818+
if (ctx.instance) {
819+
emailChanged = ctx.instance.email !== ctx.hookState.originalUserData[0].email;
820+
if (emailChanged && ctx.Model.settings.emailVerificationRequired) {
821+
ctx.instance.emailVerified = false;
822+
}
823+
} else {
824+
emailChanged = ctx.hookState.originalUserData.some(function(data) {
825+
return data.email != ctx.data.email;
826+
});
827+
if (emailChanged && ctx.Model.settings.emailVerificationRequired) {
828+
ctx.data.emailVerified = false;
829+
}
830+
}
831+
next();
832+
});
833+
});
834+
835+
User.observe('after save', function afterEmailUpdate(ctx, next) {
836+
if (!ctx.Model.relations.accessTokens) return next();
837+
var AccessToken = ctx.Model.relations.accessTokens.modelTo;
838+
if (!ctx.instance && !ctx.data) return next();
839+
var newEmail = (ctx.instance || ctx.data).email;
840+
if (!newEmail) return next();
841+
if (!ctx.hookState.originalUserData) return next();
842+
var idsToExpire = ctx.hookState.originalUserData.filter(function(u) {
843+
return u.email !== newEmail;
844+
}).map(function(u) {
845+
return u.id;
846+
});
847+
if (!idsToExpire.length) return next();
848+
AccessToken.deleteAll({ userId: { inq: idsToExpire }}, next);
849+
});
846850
};
847851

848852
function emailValidator(err, done) {

0 commit comments

Comments
 (0)