Merge branch 'develop' of github.com:tracman-org/server into develop
commit
bf0d6ddd8e
|
@ -81,9 +81,7 @@ userSchema.methods.createEmailToken = function (next) {
|
||||||
.then(() => {
|
.then(() => {
|
||||||
resolve(user.emailToken)
|
resolve(user.emailToken)
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch(reject)
|
||||||
reject(err)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -140,12 +138,10 @@ userSchema.methods.createPassToken = function (next) {
|
||||||
debug(`Reusing old password token...`)
|
debug(`Reusing old password token...`)
|
||||||
user.auth.passTokenExpires = Date.now() + 3600000 // 1 hour
|
user.auth.passTokenExpires = Date.now() + 3600000 // 1 hour
|
||||||
user.save()
|
user.save()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
resolve(user.auth.passToken, user.auth.passTokenExpires)
|
resolve(user.auth.passToken, user.auth.passTokenExpires)
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch(reject)
|
||||||
reject(err)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Create new token
|
// Create new token
|
||||||
} else {
|
} else {
|
||||||
|
@ -201,8 +197,8 @@ userSchema.methods.generateHashedPassword = function (password, next) {
|
||||||
if (err) return reject(err)
|
if (err) return reject(err)
|
||||||
this.auth.password = hash
|
this.auth.password = hash
|
||||||
this.save()
|
this.save()
|
||||||
.then(resolve)
|
.then(resolve)
|
||||||
.catch( (err) => reject(err) )
|
.catch(reject)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -213,12 +209,14 @@ userSchema.methods.generateHashedPassword = function (password, next) {
|
||||||
userSchema.methods.validPassword = function (password, next) {
|
userSchema.methods.validPassword = function (password, next) {
|
||||||
// Callback next(err, res)
|
// Callback next(err, res)
|
||||||
if (typeof next === 'function') bcrypt.compare(password, this.auth.password, next)
|
if (typeof next === 'function') bcrypt.compare(password, this.auth.password, next)
|
||||||
else bcrypt.compare(password, this.auth.password)
|
else return new Promise( (resolve, reject) => {
|
||||||
.then((result) => {
|
bcrypt.compare(password, this.auth.password)
|
||||||
if (result===true) resolve()
|
.then( (result) => {
|
||||||
else reject(new Error('Passwords don\'t match'))
|
if (result===true) resolve()
|
||||||
})
|
else reject(new Error('Passwords don\'t match'))
|
||||||
.catch( (err) => reject(err) )
|
})
|
||||||
|
.catch( (err) => reject(err) )
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
|
@ -40,22 +40,28 @@ module.exports = (passport) => {
|
||||||
|
|
||||||
// User exists
|
// User exists
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Check password
|
// Check password
|
||||||
user.validPassword(password, (err, res) => {
|
user.validPassword(password)
|
||||||
if (err) return done(err)
|
.then( (res) => {
|
||||||
|
|
||||||
// Password incorrect
|
// Password incorrect
|
||||||
if (!res) {
|
if (!res) {
|
||||||
req.session.next = undefined
|
req.session.next = undefined
|
||||||
return done(null, false, req.flash('warning', 'Incorrect email or password.'))
|
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) => {
|
.catch((err) => {
|
||||||
|
|
|
@ -59,12 +59,8 @@ module.exports = (app, passport) => {
|
||||||
debug(`sendToken() called for user ${user.id}`)
|
debug(`sendToken() called for user ${user.id}`)
|
||||||
|
|
||||||
// Create a new password token
|
// Create a new password token
|
||||||
user.createPassToken((err, token, expires) => {
|
user.createPassToken()
|
||||||
if (err) {
|
.then( (token, expires) => {
|
||||||
debug(`Error creating password token for user ${user.id}!`)
|
|
||||||
mw.throwErr(err, req)
|
|
||||||
res.redirect('/login#signup')
|
|
||||||
} else {
|
|
||||||
debug(`Created password token for user ${user.id} successfully`)
|
debug(`Created password token for user ${user.id} successfully`)
|
||||||
|
|
||||||
// Figure out expiration time
|
// 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
|
// Validate email
|
||||||
req.checkBody('email', 'Please enter a valid email address.').isEmail()
|
req.checkBody('email', 'Please enter a valid email address.').isEmail()
|
||||||
|
|
||||||
|
@ -273,8 +274,8 @@ module.exports = (app, passport) => {
|
||||||
// User with that email does exist
|
// User with that email does exist
|
||||||
} else {
|
} else {
|
||||||
// Create reset token
|
// Create reset token
|
||||||
user.createPassToken((err, token) => {
|
user.createPassToken()
|
||||||
if (err) return next(err)
|
.then( (token) => {
|
||||||
|
|
||||||
// Email reset link
|
// Email reset link
|
||||||
mail.send({
|
mail.send({
|
||||||
|
@ -294,24 +295,31 @@ module.exports = (app, passport) => {
|
||||||
${env.url}/settings/password/${token}</a></p>\
|
${env.url}/settings/password/${token}</a></p>\
|
||||||
<p>If you didn't initiate this request, just ignore this email. </p>`
|
<p>If you didn't initiate this request, just ignore this email. </p>`
|
||||||
)
|
)
|
||||||
}).then(() => {
|
})
|
||||||
|
.then(() => {
|
||||||
req.flash(
|
req.flash(
|
||||||
'success',
|
'success',
|
||||||
`If an account exists with the email <u>${req.body.email}</u>, \
|
`If an account exists with the email <u>${req.body.email}</u>, \
|
||||||
an email has been sent there with a password reset link. `)
|
an email has been sent there with a password reset link. `)
|
||||||
res.redirect('/login')
|
res.redirect('/login')
|
||||||
}).catch((err) => {
|
})
|
||||||
|
.catch((err) => {
|
||||||
debug(`Failed to send reset link to ${user.email}`)
|
debug(`Failed to send reset link to ${user.email}`)
|
||||||
mw.throwErr(err, req)
|
mw.throwErr(err, req)
|
||||||
res.redirect('/login')
|
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)!`)
|
debug(`Failed to check for if somebody has that email (in reset request)!`)
|
||||||
mw.throwErr(err, req)
|
mw.throwErr(err, req)
|
||||||
res.redirect('/login/forgot')
|
res.redirect('/login/forgot')
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Android
|
// Android
|
||||||
|
|
|
@ -38,6 +38,7 @@ router.route('/')
|
||||||
else {
|
else {
|
||||||
User.findOne({ email: req.body.email })
|
User.findOne({ email: req.body.email })
|
||||||
.then((existingUser) => {
|
.then((existingUser) => {
|
||||||
|
|
||||||
// Not unique!
|
// Not unique!
|
||||||
if (existingUser && existingUser.id !== req.user.id) {
|
if (existingUser && existingUser.id !== req.user.id) {
|
||||||
debug('Email not unique!')
|
debug('Email not unique!')
|
||||||
|
@ -53,38 +54,38 @@ router.route('/')
|
||||||
|
|
||||||
// Create token
|
// Create token
|
||||||
debug(`Creating email token...`)
|
debug(`Creating email token...`)
|
||||||
req.user.createEmailToken((err, token) => {
|
return req.user.createEmailToken()
|
||||||
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(
|
|
||||||
`<p>A request has been made to change your Tracman email address. \
|
|
||||||
If you did not initiate this request, please disregard it. </p>\
|
|
||||||
<p>To confirm your email, follow this link:\
|
|
||||||
<br><a href="${env.url}/settings/email/${token}">\
|
|
||||||
${env.url}/settings/email/${token}</a>. </p>`
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
req.flash('warning',
|
|
||||||
`An email has been sent to <u>${req.body.email}</u>. \
|
|
||||||
Check your inbox to confirm your new email address. `
|
|
||||||
)
|
|
||||||
resolve()
|
|
||||||
})
|
|
||||||
.catch(reject)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
.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(
|
||||||
|
`<p>A request has been made to change your Tracman email address. \
|
||||||
|
If you did not initiate this request, please disregard it. </p>\
|
||||||
|
<p>To confirm your email, follow this link:\
|
||||||
|
<br><a href="${env.url}/settings/email/${token}">\
|
||||||
|
${env.url}/settings/email/${token}</a>. </p>`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
.then( () => {
|
||||||
|
req.flash('warning',
|
||||||
|
`An email has been sent to <u>${req.body.email}</u>. Check your inbox to confirm your new email address. `
|
||||||
|
)
|
||||||
|
resolve()
|
||||||
})
|
})
|
||||||
.catch(reject)
|
.catch(reject)
|
||||||
}
|
}
|
||||||
|
@ -210,52 +211,49 @@ router.route('/password')
|
||||||
// Email user a token, proceed at /password/:token
|
// Email user a token, proceed at /password/:token
|
||||||
.get((req, res, next) => {
|
.get((req, res, next) => {
|
||||||
// Create token for password change
|
// Create token for password change
|
||||||
req.user.createPassToken((err, token, expires) => {
|
req.user.createPassToken()
|
||||||
if (err) {
|
.then( (token, expires) => {
|
||||||
mw.throwErr(err, req)
|
// Figure out expiration time
|
||||||
res.redirect((req.user) ? '/settings' : '/login')
|
let expirationTimeString = (req.query.tz)
|
||||||
} else {
|
? moment(expires).utcOffset(req.query.tz).toDate().toLocaleTimeString(req.acceptsLanguages[0])
|
||||||
// Figure out expiration time
|
: moment(expires).toDate().toLocaleTimeString(req.acceptsLanguages[0]) + ' UTC'
|
||||||
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.
|
// Confirm password change request by email.
|
||||||
mail.send({
|
return mail.send({
|
||||||
to: mail.to(req.user),
|
to: mail.to(req.user),
|
||||||
from: mail.noReply,
|
from: mail.noReply,
|
||||||
subject: 'Request to change your Tracman password',
|
subject: 'Request to change your Tracman password',
|
||||||
text: mail.text(
|
text: mail.text(
|
||||||
`A request has been made to change your tracman password. \
|
`A request has been made to change your tracman password. \
|
||||||
If you did not initiate this request, please contact support at keith@tracman.org. \
|
If you did not initiate this request, please contact support at keith@tracman.org. \
|
||||||
\n\nTo change your password, follow this link:\n\
|
\n\nTo change your password, follow this link:\n\
|
||||||
${env.url}/settings/password/${token}. \n\n\
|
${env.url}/settings/password/${token}. \n\n\
|
||||||
This request will expire at ${expirationTimeString}. `
|
This request will expire at ${expirationTimeString}. `
|
||||||
),
|
),
|
||||||
html: mail.html(
|
html: mail.html(
|
||||||
`<p>A request has been made to change your tracman password. \
|
`<p>A request has been made to change your tracman password. \
|
||||||
If you did not initiate this request, please contact support at \
|
If you did not initiate this request, please contact support at \
|
||||||
<a href="mailto:keith@tracman.org">keith@tracman.org</a>. </p>\
|
<a href="mailto:keith@tracman.org">keith@tracman.org</a>. </p>\
|
||||||
<p>To change your password, follow this link:\
|
<p>To change your password, follow this link:\
|
||||||
<br><a href="${env.url}/settings/password/${token}">\
|
<br><a href="${env.url}/settings/password/${token}">\
|
||||||
${env.url}/settings/password/${token}</a>. </p>\
|
${env.url}/settings/password/${token}</a>. </p>\
|
||||||
<p>This request will expire at ${expirationTimeString}. </p>`
|
<p>This request will expire at ${expirationTimeString}. </p>`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.then(() => {
|
|
||||||
// Alert user to check email.
|
})
|
||||||
req.flash('success',
|
.then(() => {
|
||||||
`An link has been sent to <u>${req.user.email}</u>. \
|
// Alert user to check email.
|
||||||
Click on the link to complete your password change. \
|
req.flash('success',
|
||||||
This link will expire in one hour (${expirationTimeString}). `
|
`An link has been sent to <u>${req.user.email}</u>. \
|
||||||
)
|
Click on the link to complete your password change. \
|
||||||
res.redirect((req.user) ? '/settings' : '/login')
|
This link will expire in one hour (${expirationTimeString}). `
|
||||||
})
|
)
|
||||||
.catch((err) => {
|
res.redirect((req.user) ? '/settings' : '/login')
|
||||||
mw.throwErr(err, req)
|
})
|
||||||
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 {
|
} else {
|
||||||
|
|
||||||
// Create hashed password and save to db
|
// Create hashed password and save to db
|
||||||
res.locals.passwordUser.generateHashedPassword(req.body.password, (err) => {
|
res.locals.passwordUser.generateHashedPassword(req.body.password)
|
||||||
if (err) {
|
.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')
|
debug('Error creating hashed password and saving to db')
|
||||||
mw.throwErr(err, req)
|
mw.throwErr(err, req)
|
||||||
res.redirect(`/settings/password/${req.params.token}`)
|
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')
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue