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);
|