#64 Returned promises in model method definitions

master
Keith Irwin 2017-12-13 20:29:22 +00:00
parent 9040013de4
commit afb52b4084
No known key found for this signature in database
GPG Key ID: 378933C743E2BBC0
1 changed files with 144 additions and 60 deletions

View File

@ -47,94 +47,178 @@ const userSchema = new mongoose.Schema({
}).plugin(unique)
/* User methods */
// TODO: Return promises instead of taking callbacks
// See https://gist.github.com/7h1b0/5154fda207e68ad1cefc#file-random-js
// For an example
// Create email confirmation token
userSchema.methods.createEmailToken = function (next) { // next(err,token)
userSchema.methods.createEmailToken = function (next) {
debug('user.createEmailToken() called')
var user = this
crypto.randomBytes(16, (err, buf) => {
if (err) return next(err)
if (buf) {
debug(`Buffer ${buf.toString('hex')} created`)
user.emailToken = buf.toString('hex')
// Callback next(err, token)
if (typeof next === 'function') {
crypto.randomBytes(16, (err, buf) => {
if (err) return next(err)
if (buf) {
debug(`Buffer ${buf.toString('hex')} created`)
user.emailToken = buf.toString('hex')
user.save()
.then(() => {
return next(null, user.emailToken)
})
.catch((err) => {
return next(err)
})
}
})
// Promise
} else return new Promise((resolve, reject) => {
crypto.randomBytes(16, (err, buf) => {
if (err) reject(err)
if (buf) {
debug(`Buffer ${buf.toString('hex')} created`)
user.emailToken = buf.toString('hex')
user.save()
.then(() => {
resolve(user.emailToken)
})
.catch((err) => {
reject(err)
})
}
})
})
}
// Create password reset token
userSchema.methods.createPassToken = function (next) {
debug('user.createPassToken() called')
var user = this
// Callback next(err, token, expires)
if (typeof next === 'function') {
// Reuse old token, resetting clock
if (user.auth.passTokenExpires >= Date.now()) {
debug(`Reusing old password token...`)
user.auth.passTokenExpires = Date.now() + 3600000 // 1 hour
user.save()
.then(() => {
return next(null, user.emailToken)
return next(null, user.auth.passToken, user.auth.passTokenExpires)
})
.catch((err) => {
return next(err, null)
return next(err)
})
// Create new token
} else {
debug(`Creating new password token...`)
crypto.randomBytes(16, (err, buf) => {
if (err) return next(err)
if (buf) {
user.auth.passToken = buf.toString('hex')
user.auth.passTokenExpires = Date.now() + 3600000 // 1 hour
user.save()
.then(() => {
debug('successfully saved user in createPassToken')
return next(null, user.auth.passToken, user.auth.passTokenExpires)
})
.catch((err) => {
debug('error saving user in createPassToken')
return next(err)
})
}
})
}
// Promise
} else return new Promise((resolve, reject) => {
// Reuse old token, resetting clock
if (user.auth.passTokenExpires >= Date.now()) {
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)
})
// Create new token
} else {
debug(`Creating new password token...`)
crypto.randomBytes(16, (err, buf) => {
if (err) return next(err)
if (buf) {
user.auth.passToken = buf.toString('hex')
user.auth.passTokenExpires = Date.now() + 3600000 // 1 hour
user.save()
.then(() => {
debug('successfully saved user in createPassToken')
resolve(user.auth.passToken, user.auth.passTokenExpires)
})
.catch((err) => {
debug('error saving user in createPassToken')
reject(err)
})
}
})
}
})
}
// Create password reset token
userSchema.methods.createPassToken = function (next) { // next(err,token,expires)
var user = this
// Reuse old token, resetting clock
if (user.auth.passTokenExpires >= Date.now()) {
debug(`Reusing old password token...`)
user.auth.passTokenExpires = Date.now() + 3600000 // 1 hour
user.save()
.then(() => {
return next(null, user.auth.passToken, user.auth.passTokenExpires)
})
.catch((err) => {
return next(err)
})
// Create new token
} else {
debug(`Creating new password token...`)
crypto.randomBytes(16, (err, buf) => {
if (err) return next(err)
if (buf) {
user.auth.passToken = buf.toString('hex')
user.auth.passTokenExpires = Date.now() + 3600000 // 1 hour
user.save()
.then(() => {
debug('successfully saved user in createPassToken')
return next(null, user.auth.passToken, user.auth.passTokenExpires)
})
.catch((err) => {
debug('error saving user in createPassToken')
return next(err)
})
}
})
}
}
// Generate hash for new password and save it to the database
userSchema.methods.generateHashedPassword = function (password, next) {
// next(err);
// Delete token
this.auth.passToken = undefined
this.auth.passTokenExpires = undefined
// Generate hash
bcrypt.genSalt(8, (err, salt) => {
if (err) return next(err)
bcrypt.hash(password, salt, (err, hash) => {
// Callback next(err, token, expires)
if (typeof next === 'function') {
// Generate hash
bcrypt.genSalt(8, (err, salt) => {
if (err) return next(err)
this.auth.password = hash
this.save()
next()
bcrypt.hash(password, salt, (err, hash) => {
if (err) return next(err)
this.auth.password = hash
this.save()
.then(next)
.catch((err) => next(err) )
})
})
} else return new Promise((resolve, reject) => {
// Generate hash
bcrypt.genSalt(8, (err, salt) => {
if (err) reject(err)
bcrypt.hash(password, salt, (err, hash) => {
if (err) reject(err)
this.auth.password = hash
this.save()
.then(resolve)
.catch( (err) => reject(err) )
})
})
})
}
// Check for valid password
userSchema.methods.validPassword = function (password, next) {
// next(err,res);
// res = true/false
bcrypt.compare(password, this.auth.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) )
}
module.exports = {