123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- const crypto = require('crypto')
- const mongoose = require('mongoose')
- mongoose.Promise = require('bluebird')
- var UserSchema = new mongoose.Schema({
- name: String,
- loginId: {
- type: String,
- lowercase: true,
- required: true
- },
- role: {
- type: String,
- default: 'user'
- },
- password: {
- type: String,
- required: true
- },
- provider: String,
- salt: String,
- token: String
- })
- /**
- * Validations
- */
- // Validate empty email
- UserSchema
- .path('loginId')
- .validate((loginId) => {
- return loginId.length
- }, '登陆名不能空')
- // Validate empty password
- UserSchema
- .path('password')
- .validate((password) => {
- return password.length
- }, '密码不能空')
- // Validate loginId is not taken
- UserSchema
- .path('loginId')
- .validate(function (value, respond) {
- return this.constructor.findOne({ loginId: value }).exec()
- .then(user => {
- if (user) {
- if (this.id === user.id) {
- return respond(true)
- }
- return respond(false)
- }
- return respond(true)
- })
- .catch((err) => {
- throw err
- })
- }, '该用户已存在')
- var validatePresenceOf = (value) => {
- return value && value.length
- }
- /**
- * Pre-save hook
- */
- UserSchema
- .pre('save', function (next) {
- // Handle new/update passwords
- if (!this.isModified('password')) {
- return next()
- }
- if (!validatePresenceOf(this.password)) {
- return next(new Error('密码错误'))
- }
- // Make salt with a callback
- this.makeSalt((saltErr, salt) => {
- if (saltErr) {
- return next(saltErr)
- }
- this.salt = salt
- this.encryptPassword(this.password, (encryptErr, hashedPassword) => {
- if (encryptErr) {
- return next(encryptErr)
- }
- this.password = hashedPassword
- return next()
- })
- })
- })
- /**
- * Methods
- */
- UserSchema.methods = {
- /**
- * Authenticate - check if the passwords are the same
- *
- * @param {String} password
- * @param {Function} callback
- * @return {Boolean}
- * @api public
- */
- authenticate(password, callback) {
- if (!callback) {
- return this.password === this.encryptPassword(password)
- }
- this.encryptPassword(password, (err, pwdGen) => {
- if (err) {
- return callback(err)
- }
- if (this.password === pwdGen) {
- return callback(null, true)
- } else {
- return callback(null, false)
- }
- })
- },
- /**
- * Make salt
- *
- * @param {Number} [byteSize] - Optional salt byte size, default to 16
- * @param {Function} callback
- * @return {String}
- * @api public
- */
- makeSalt(byteSize, callback) {
- var defaultByteSize = 16
- if (typeof arguments[0] === 'function') {
- callback = arguments[0]
- byteSize = defaultByteSize;
- } else if (typeof arguments[1] === 'function') {
- callback = arguments[1]
- } else {
- throw new Error('却少回调方法')
- }
- if (!byteSize) {
- byteSize = defaultByteSize
- }
- return crypto.randomBytes(byteSize, (err, salt) => {
- if (err) {
- return callback(err)
- } else {
- return callback(null, salt.toString('base64'))
- }
- })
- },
- /**
- * Encrypt password
- *
- * @param {String} password
- * @param {Function} callback
- * @return {String}
- * @api public
- */
- encryptPassword(password, callback) {
- if (!password || !this.salt) {
- if (!callback) {
- return null
- } else {
- return callback('却少密码或者加密内容')
- }
- }
- var defaultIterations = 10000
- var defaultKeyLength = 64
- var salt = new Buffer(this.salt, 'base64')
- if (!callback) {
- return crypto.pbkdf2Sync(password, salt, defaultIterations, defaultKeyLength)
- .toString('base64')
- }
- return crypto.pbkdf2(password, salt, defaultIterations, defaultKeyLength, (err, key) => {
- if (err) {
- return callback(err)
- } else {
- return callback(null, key.toString('base64'))
- }
- })
- }
- }
- module.exports = mongoose.model('User', UserSchema)
|