diff --git a/config/models.js b/config/models.js index bc00be0..9b31d31 100644 --- a/config/models.js +++ b/config/models.js @@ -81,9 +81,7 @@ userSchema.methods.createEmailToken = function (next) { .then(() => { resolve(user.emailToken) }) - .catch((err) => { - reject(err) - }) + .catch(reject) } }) }) @@ -140,12 +138,10 @@ userSchema.methods.createPassToken = function (next) { debug(`Reusing old password token...`) user.auth.passTokenExpires = Date.now() + 3600000 // 1 hour user.save() - .then(() => { - resolve(user.auth.passToken, user.auth.passTokenExpires) - }) - .catch((err) => { - reject(err) - }) + .then(() => { + resolve(user.auth.passToken, user.auth.passTokenExpires) + }) + .catch(reject) // Create new token } else { @@ -201,8 +197,8 @@ userSchema.methods.generateHashedPassword = function (password, next) { if (err) return reject(err) this.auth.password = hash this.save() - .then(resolve) - .catch( (err) => reject(err) ) + .then(resolve) + .catch(reject) }) }) @@ -213,12 +209,14 @@ userSchema.methods.generateHashedPassword = function (password, next) { userSchema.methods.validPassword = function (password, next) { // Callback next(err, res) if (typeof next === 'function') bcrypt.compare(password, this.auth.password, next) - else bcrypt.compare(password, this.auth.password) - .then((result) => { - if (result===true) resolve() - else reject(new Error('Passwords don\'t match')) - }) - .catch( (err) => reject(err) ) + else return new Promise( (resolve, reject) => { + bcrypt.compare(password, this.auth.password) + .then( (result) => { + if (result===true) resolve() + else reject(new Error('Passwords don\'t match')) + }) + .catch( (err) => reject(err) ) + }) } module.exports = { diff --git a/config/passport.js b/config/passport.js index e849d9d..33dde56 100644 --- a/config/passport.js +++ b/config/passport.js @@ -40,22 +40,28 @@ module.exports = (passport) => { // User exists } else { + // Check password - user.validPassword(password, (err, res) => { - if (err) return done(err) + user.validPassword(password) + .then( (res) => { - // Password incorrect - if (!res) { - req.session.next = undefined - return done(null, false, req.flash('warning', 'Incorrect email or password.')) + // Password incorrect + if (!res) { + req.session.next = undefined + return done(null, false, req.flash('warning', 'Incorrect email or password.')) + + // Successful login + } else { + user.lastLogin = Date.now() + user.save() + return done(null, user) + } + + }) + .catch( (err) => { + return done(err) + }) - // Successful login - } else { - user.lastLogin = Date.now() - user.save() - return done(null, user) - } - }) } }) .catch((err) => { diff --git a/config/routes/auth.js b/config/routes/auth.js index 2fe5dea..18aff04 100644 --- a/config/routes/auth.js +++ b/config/routes/auth.js @@ -59,12 +59,8 @@ module.exports = (app, passport) => { debug(`sendToken() called for user ${user.id}`) // Create a new password token - user.createPassToken((err, token, expires) => { - if (err) { - debug(`Error creating password token for user ${user.id}!`) - mw.throwErr(err, req) - res.redirect('/login#signup') - } else { + user.createPassToken() + .then( (token, expires) => { debug(`Created password token for user ${user.id} successfully`) // Figure out expiration time @@ -125,10 +121,15 @@ module.exports = (app, passport) => { } } }) - } }) + .catch( (err) => { + debug(`Error creating password token for user ${user.id}!`) + mw.throwErr(err, req) + res.redirect('/login#signup') + }) + } - + // Validate email req.checkBody('email', 'Please enter a valid email address.').isEmail() @@ -273,8 +274,8 @@ module.exports = (app, passport) => { // User with that email does exist } else { // Create reset token - user.createPassToken((err, token) => { - if (err) return next(err) + user.createPassToken() + .then( (token) => { // Email reset link mail.send({ @@ -294,24 +295,31 @@ module.exports = (app, passport) => { ${env.url}/settings/password/${token}

\

If you didn't initiate this request, just ignore this email.

` ) - }).then(() => { + }) + .then(() => { req.flash( 'success', `If an account exists with the email ${req.body.email}, \ an email has been sent there with a password reset link. `) res.redirect('/login') - }).catch((err) => { + }) + .catch((err) => { debug(`Failed to send reset link to ${user.email}`) mw.throwErr(err, req) res.redirect('/login') }) }) + .catch( (err) => { + return next(err) + }) } - }).catch((err) => { + }) + .catch((err) => { debug(`Failed to check for if somebody has that email (in reset request)!`) mw.throwErr(err, req) res.redirect('/login/forgot') }) + }) // Android diff --git a/config/routes/settings.js b/config/routes/settings.js index 71b284f..18fa718 100644 --- a/config/routes/settings.js +++ b/config/routes/settings.js @@ -38,6 +38,7 @@ router.route('/') else { User.findOne({ email: req.body.email }) .then((existingUser) => { + // Not unique! if (existingUser && existingUser.id !== req.user.id) { debug('Email not unique!') @@ -53,38 +54,38 @@ router.route('/') // Create token debug(`Creating email token...`) - req.user.createEmailToken((err, token) => { - if (err) reject(err) - - // Send token to user by email - debug(`Mailing new email token to ${req.body.email}...`) - mail.send({ - to: `"${req.user.name}" <${req.body.email}>`, - from: mail.noReply, - subject: 'Confirm your new email address for Tracman', - text: mail.text( - `A request has been made to change your Tracman email address. \ - If you did not initiate this request, please disregard it. \n\n\ - To confirm your email, follow this link:\n${env.url}/settings/email/${token}. ` - ), - html: mail.html( - `

A request has been made to change your Tracman email address. \ - If you did not initiate this request, please disregard it.

\ -

To confirm your email, follow this link:\ -
\ - ${env.url}/settings/email/${token}.

` - ) - }) - .then(() => { - req.flash('warning', - `An email has been sent to ${req.body.email}. \ - Check your inbox to confirm your new email address. ` - ) - resolve() - }) - .catch(reject) - }) + return req.user.createEmailToken() } + + }) + .then( (token) => { + + // Send token to user by email + debug(`Mailing new email token to ${req.body.email}...`) + return mail.send({ + to: `"${req.user.name}" <${req.body.email}>`, + from: mail.noReply, + subject: 'Confirm your new email address for Tracman', + text: mail.text( + `A request has been made to change your Tracman email address. \ + If you did not initiate this request, please disregard it. \n\n\ + To confirm your email, follow this link:\n${env.url}/settings/email/${token}. ` + ), + html: mail.html( + `

A request has been made to change your Tracman email address. \ + If you did not initiate this request, please disregard it.

\ +

To confirm your email, follow this link:\ +
\ + ${env.url}/settings/email/${token}.

` + ) + }) + + }) + .then( () => { + req.flash('warning', + `An email has been sent to ${req.body.email}. Check your inbox to confirm your new email address. ` + ) + resolve() }) .catch(reject) } @@ -210,52 +211,49 @@ router.route('/password') // Email user a token, proceed at /password/:token .get((req, res, next) => { // Create token for password change - req.user.createPassToken((err, token, expires) => { - if (err) { - mw.throwErr(err, req) - res.redirect((req.user) ? '/settings' : '/login') - } else { - // Figure out expiration time - let expirationTimeString = (req.query.tz) - ? moment(expires).utcOffset(req.query.tz).toDate().toLocaleTimeString(req.acceptsLanguages[0]) - : moment(expires).toDate().toLocaleTimeString(req.acceptsLanguages[0]) + ' UTC' + req.user.createPassToken() + .then( (token, expires) => { + // Figure out expiration time + let expirationTimeString = (req.query.tz) + ? moment(expires).utcOffset(req.query.tz).toDate().toLocaleTimeString(req.acceptsLanguages[0]) + : moment(expires).toDate().toLocaleTimeString(req.acceptsLanguages[0]) + ' UTC' - // Confirm password change request by email. - mail.send({ - to: mail.to(req.user), - from: mail.noReply, - subject: 'Request to change your Tracman password', - text: mail.text( - `A request has been made to change your tracman password. \ - If you did not initiate this request, please contact support at keith@tracman.org. \ - \n\nTo change your password, follow this link:\n\ - ${env.url}/settings/password/${token}. \n\n\ - This request will expire at ${expirationTimeString}. ` - ), - html: mail.html( - `

A request has been made to change your tracman password. \ - If you did not initiate this request, please contact support at \ - keith@tracman.org.

\ -

To change your password, follow this link:\ -
\ - ${env.url}/settings/password/${token}.

\ -

This request will expire at ${expirationTimeString}.

` - ) - }) - .then(() => { - // Alert user to check email. - req.flash('success', - `An link has been sent to ${req.user.email}. \ - Click on the link to complete your password change. \ - This link will expire in one hour (${expirationTimeString}). ` - ) - res.redirect((req.user) ? '/settings' : '/login') - }) - .catch((err) => { - mw.throwErr(err, req) - res.redirect((req.user) ? '/settings' : '/login') - }) - } + // Confirm password change request by email. + return mail.send({ + to: mail.to(req.user), + from: mail.noReply, + subject: 'Request to change your Tracman password', + text: mail.text( + `A request has been made to change your tracman password. \ + If you did not initiate this request, please contact support at keith@tracman.org. \ + \n\nTo change your password, follow this link:\n\ + ${env.url}/settings/password/${token}. \n\n\ + This request will expire at ${expirationTimeString}. ` + ), + html: mail.html( + `

A request has been made to change your tracman password. \ + If you did not initiate this request, please contact support at \ + keith@tracman.org.

\ +

To change your password, follow this link:\ +
\ + ${env.url}/settings/password/${token}.

\ +

This request will expire at ${expirationTimeString}.

` + ) + }) + + }) + .then(() => { + // Alert user to check email. + req.flash('success', + `An link has been sent to ${req.user.email}. \ + Click on the link to complete your password change. \ + This link will expire in one hour (${expirationTimeString}). ` + ) + res.redirect((req.user) ? '/settings' : '/login') + }) + .catch( (err) => { + mw.throwErr(err, req) + res.redirect((req.user) ? '/settings' : '/login') }) }) @@ -304,26 +302,26 @@ router.route('/password/:token') } else { // Create hashed password and save to db - res.locals.passwordUser.generateHashedPassword(req.body.password, (err) => { - if (err) { + res.locals.passwordUser.generateHashedPassword(req.body.password) + .then( () => { + // User changed password + if (req.user) { + debug('User saved password') + req.flash('success', 'Your password has been changed. ') + res.redirect('/settings') + + // New user created password + } else { + debug('New user created password') + req.flash('success', 'Password set. You can use it to log in now. ') + res.redirect('/login?next=/map?new=1') + } + }) + .catch( (err) => { debug('Error creating hashed password and saving to db') mw.throwErr(err, req) res.redirect(`/settings/password/${req.params.token}`) - - // User changed password - } else if (req.user) { - debug('User saved password') - req.flash('success', 'Your password has been changed. ') - res.redirect('/settings') - - // New user created password - } else { - debug('New user created password') - req.flash('success', 'Password set. You can use it to log in now. ') - res.redirect('/login?next=/map?new=1') - } - - }) + }) } })