From fe059c224e2cde21392d0f08c953672ad31b6618 Mon Sep 17 00:00:00 2001 From: Mrugesh Mohapatra Date: Mon, 9 Oct 2017 23:57:47 +0530 Subject: [PATCH 1/5] fix(User): Naming convention updates --- common/models/user.js | 2 +- server/views/emails/user-request-sign-in.ejs | 2 +- server/views/emails/user-request-sign-up.ejs | 8 ++++---- ...ser-email-verify.ejs => user-request-update-email.ejs} | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) rename server/views/emails/{user-email-verify.ejs => user-request-update-email.ejs} (93%) diff --git a/common/models/user.js b/common/models/user.js index 28483950b9..938e6ed4b5 100644 --- a/common/models/user.js +++ b/common/models/user.js @@ -625,7 +625,7 @@ module.exports = function(User) { 'server', 'views', 'emails', - 'user-email-verify.ejs' + 'user-request-update-email.ejs' ) }; return this.verify(mailOptions); diff --git a/server/views/emails/user-request-sign-in.ejs b/server/views/emails/user-request-sign-in.ejs index 866a77c96b..fc9cfb1bd6 100644 --- a/server/views/emails/user-request-sign-in.ejs +++ b/server/views/emails/user-request-sign-in.ejs @@ -14,4 +14,4 @@ Good luck with the challenges! Thanks, The freeCodeCamp Team. -team@freecodecamp.com +team@freecodecamp.org diff --git a/server/views/emails/user-request-sign-up.ejs b/server/views/emails/user-request-sign-up.ejs index fadeccf4bc..ec251e24e9 100644 --- a/server/views/emails/user-request-sign-up.ejs +++ b/server/views/emails/user-request-sign-up.ejs @@ -9,9 +9,9 @@ This above link is valid for 15 minutes. And when you have a moment: 1. Visit the settings page and link your account to GitHub. -2. Follow our Medium Publication: https://medium.freecodecamp.com -3. Checkout our forum: https://forum.freecodecamp.com -4. Join the conversation: https://gitter.im/FreeCodeCamp/FreeCodeCamp +2. Follow our Medium Publication: https://medium.freecodecamp.org +3. Checkout our forum: https://forum.freecodecamp.org +4. Join the conversation: https://gitter.im/freeCodeCamp/freeCodeCamp IMPORTANT NOTE: If you did not make any such request, simply delete or ignore this email. @@ -21,4 +21,4 @@ Good luck with the challenges! Thanks, The freeCodeCamp Team. -team@freecodecamp.com +team@freecodecamp.org diff --git a/server/views/emails/user-email-verify.ejs b/server/views/emails/user-request-update-email.ejs similarity index 93% rename from server/views/emails/user-email-verify.ejs rename to server/views/emails/user-request-update-email.ejs index db8df54f39..130f5f1263 100644 --- a/server/views/emails/user-email-verify.ejs +++ b/server/views/emails/user-request-update-email.ejs @@ -10,4 +10,4 @@ Good luck with the challenges! Thanks, The freeCodeCamp Team. -team@freecodecamp.com +team@freecodecamp.org From 2a3703b95ae9b3bf9655c4f1f25ca518f065322a Mon Sep 17 00:00:00 2001 From: Mrugesh Mohapatra Date: Thu, 19 Oct 2017 12:08:23 +0530 Subject: [PATCH 2/5] fix(user): Add LoopBack email validation once again Earlier we did not need emails for everyone, this is not the case anymore. We now require emails, and all other auth mechanisms are now deprecated for new users. --- common/models/user.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/common/models/user.js b/common/models/user.js index 938e6ed4b5..8695e03a5b 100644 --- a/common/models/user.js +++ b/common/models/user.js @@ -83,11 +83,6 @@ function getWaitPeriod(ttl) { return 0; } module.exports = function(User) { - // NOTE(berks): user email validation currently not needed but build in. This - // work around should let us sneak by - // see: - // https://github.com/strongloop/loopback/issues/1137#issuecomment-109200135 - delete User.validations.email; // set salt factor for passwords User.settings.saltWorkFactor = 5; // set user.rand to random number From 9ccfe4f72ce9c528ff90b09326ba65e34e566eb8 Mon Sep 17 00:00:00 2001 From: Mrugesh Mohapatra Date: Sat, 21 Oct 2017 04:58:53 +0530 Subject: [PATCH 3/5] refactor: Update methods to sensible names --- common/models/user.js | 6 +++--- common/models/user.json | 4 ++-- server/boot/settings.js | 2 +- server/boot/user.js | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/common/models/user.js b/common/models/user.js index 8695e03a5b..38b76dd5ac 100644 --- a/common/models/user.js +++ b/common/models/user.js @@ -472,7 +472,7 @@ module.exports = function(User) { } ); - User.requestAuthLink = function requestAuthLink(email) { + User.requestAuthEmail = function requestAuthEmail(email) { if (!isEmail(email)) { return Promise.reject( new Error('The submitted email not valid.') @@ -545,7 +545,7 @@ module.exports = function(User) { }; User.remoteMethod( - 'requestAuthLink', + 'requestAuthEmail', { description: 'request a link on email with temporary token to sign in', accepts: [{ @@ -560,7 +560,7 @@ module.exports = function(User) { } ); - User.prototype.updateEmail = function updateEmail(email) { + User.prototype.requestUpdateEmail = function requestUpdateEmail(email) { const ownEmail = email === this.email; if (!isEmail('' + email)) { return Observable.throw(createEmailError()); diff --git a/common/models/user.json b/common/models/user.json index 521b36f9bf..5aff4d4e88 100644 --- a/common/models/user.json +++ b/common/models/user.json @@ -277,7 +277,7 @@ "principalType": "ROLE", "principalId": "$owner", "permission": "ALLOW", - "property": "updateEmail" + "property": "requestUpdateEmail" }, { "accessType": "EXECUTE", @@ -298,7 +298,7 @@ "principalType": "ROLE", "principalId": "$everyone", "permission": "ALLOW", - "property": "requestAuthLink" + "property": "requestAuthEmail" } ], "methods": {} diff --git a/server/boot/settings.js b/server/boot/settings.js index 5a407b080b..9264d16fcb 100644 --- a/server/boot/settings.js +++ b/server/boot/settings.js @@ -21,7 +21,7 @@ export default function settingsController(app) { function updateMyEmail(req, res, next) { const { user, body: { email } } = req; - return user.updateEmail(email) + return user.requestUpdateEmail(email) .subscribe( (message) => res.json({ message }), next diff --git a/server/boot/user.js b/server/boot/user.js index e167481e9d..ee7faee3eb 100644 --- a/server/boot/user.js +++ b/server/boot/user.js @@ -248,7 +248,7 @@ module.exports = function(app) { return res.redirect('/'); } - return User.requestAuthLink(req.body.email) + return User.requestAuthEmail(req.body.email) .then(msg => { return res.status(200).send({ message: msg }); }) From 5e61fd53d162ddb7de4b2a1726fb5d896ddb59a1 Mon Sep 17 00:00:00 2001 From: Mrugesh Mohapatra Date: Mon, 23 Oct 2017 21:02:00 +0530 Subject: [PATCH 4/5] fix(user): Add update new-email placeholder property --- common/models/user.js | 22 +++++++++++++--------- common/models/user.json | 3 +++ 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/common/models/user.js b/common/models/user.js index 38b76dd5ac..bddb70e96b 100644 --- a/common/models/user.js +++ b/common/models/user.js @@ -560,15 +560,17 @@ module.exports = function(User) { } ); - User.prototype.requestUpdateEmail = function requestUpdateEmail(email) { - const ownEmail = email === this.email; - if (!isEmail('' + email)) { + User.prototype.requestUpdateEmail = function requestUpdateEmail( + emailUpdateNew + ) { + const ownEmail = emailUpdateNew === this.email; + if (!isEmail('' + emailUpdateNew)) { return Observable.throw(createEmailError()); } // email is already associated and verified with this account if (ownEmail && this.emailVerified) { return Observable.throw(new Error( - `${email} is already associated with this account.` + `${emailUpdateNew} is already associated with this account.` )); } @@ -583,23 +585,25 @@ module.exports = function(User) { `); } - return Observable.fromPromise(User.doesExist(null, email)) + return Observable.fromPromise(User.doesExist(null, emailUpdateNew)) .flatMap(exists => { // not associated with this account, but is associated with another if (!ownEmail && exists) { return Promise.reject( - new Error(`${email} is already associated with another account.`) + new Error( + `${emailUpdateNew} is already associated with another account.` + ) ); } const emailVerified = false; return this.update$({ - email, + emailUpdateNew, emailVerified, emailVerifyTTL: new Date() }) .do(() => { - this.email = email; + this.emailUpdateNew = emailUpdateNew; this.emailVerified = emailVerified; this.emailVerifyTTL = new Date(); }); @@ -607,7 +611,7 @@ module.exports = function(User) { .flatMap(() => { const mailOptions = { type: 'email', - to: email, + to: emailUpdateNew, from: getEmailSender(), subject: 'freeCodeCamp - Email Update Requested', protocol: getProtocol(), diff --git a/common/models/user.json b/common/models/user.json index 5aff4d4e88..ecfb861376 100644 --- a/common/models/user.json +++ b/common/models/user.json @@ -16,6 +16,9 @@ } } }, + "emailUpdateNew":{ + "type": "string" + }, "emailVerifyTTL": { "type": "date" }, From e652ad934ad9a5331c6307687a9d75ba71959d9c Mon Sep 17 00:00:00 2001 From: Mrugesh Mohapatra Date: Sat, 28 Oct 2017 00:24:00 +0530 Subject: [PATCH 5/5] fix: Email should be switched before confirm --- common/models/user.js | 31 ++++++++++++++++++++----------- common/models/user.json | 2 +- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/common/models/user.js b/common/models/user.js index bddb70e96b..a34348f0ef 100644 --- a/common/models/user.js +++ b/common/models/user.js @@ -236,7 +236,7 @@ module.exports = function(User) { return User.findById(uid, (err, user) => { - if (err || !user) { + if (err || !user || !user.newEmail) { ctx.req.flash('error', { msg: dedent`Oops, something went wrong, please try again later` }); @@ -268,7 +268,16 @@ module.exports = function(User) { return ctx.res.redirect(redirect); } - return next(); + return user.update$({ + email: user.newEmail, + newEmail: null, + emailVerifyTTL: null + }) + .do(() => { + return next(); + }) + .toPromise(); + }); }); @@ -561,16 +570,16 @@ module.exports = function(User) { ); User.prototype.requestUpdateEmail = function requestUpdateEmail( - emailUpdateNew + newEmail ) { - const ownEmail = emailUpdateNew === this.email; - if (!isEmail('' + emailUpdateNew)) { + const ownEmail = newEmail === this.email; + if (!isEmail('' + newEmail)) { return Observable.throw(createEmailError()); } // email is already associated and verified with this account if (ownEmail && this.emailVerified) { return Observable.throw(new Error( - `${emailUpdateNew} is already associated with this account.` + `${newEmail} is already associated with this account.` )); } @@ -585,25 +594,25 @@ module.exports = function(User) { `); } - return Observable.fromPromise(User.doesExist(null, emailUpdateNew)) + return Observable.fromPromise(User.doesExist(null, newEmail)) .flatMap(exists => { // not associated with this account, but is associated with another if (!ownEmail && exists) { return Promise.reject( new Error( - `${emailUpdateNew} is already associated with another account.` + `${newEmail} is already associated with another account.` ) ); } const emailVerified = false; return this.update$({ - emailUpdateNew, + newEmail, emailVerified, emailVerifyTTL: new Date() }) .do(() => { - this.emailUpdateNew = emailUpdateNew; + this.newEmail = newEmail; this.emailVerified = emailVerified; this.emailVerifyTTL = new Date(); }); @@ -611,7 +620,7 @@ module.exports = function(User) { .flatMap(() => { const mailOptions = { type: 'email', - to: emailUpdateNew, + to: newEmail, from: getEmailSender(), subject: 'freeCodeCamp - Email Update Requested', protocol: getProtocol(), diff --git a/common/models/user.json b/common/models/user.json index ecfb861376..c8152d7f96 100644 --- a/common/models/user.json +++ b/common/models/user.json @@ -16,7 +16,7 @@ } } }, - "emailUpdateNew":{ + "newEmail":{ "type": "string" }, "emailVerifyTTL": {