|
@@ -3,24 +3,24 @@ 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
|
|
|
-});
|
|
|
+ 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
|
|
|
+})
|
|
|
|
|
|
|
|
|
/**
|
|
@@ -29,168 +29,168 @@ var UserSchema = new mongoose.Schema({
|
|
|
|
|
|
// Validate empty email
|
|
|
UserSchema
|
|
|
- .path('loginId')
|
|
|
- .validate((loginId) => {
|
|
|
- return loginId.length;
|
|
|
- }, '登陆名不能空');
|
|
|
+ .path('loginId')
|
|
|
+ .validate((loginId) => {
|
|
|
+ return loginId.length
|
|
|
+ }, '登陆名不能空')
|
|
|
|
|
|
// Validate empty password
|
|
|
UserSchema
|
|
|
- .path('password')
|
|
|
- .validate((password) => {
|
|
|
- return password.length;
|
|
|
- }, '密码不能空');
|
|
|
+ .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;
|
|
|
- });
|
|
|
- }, '该用户已存在');
|
|
|
+ .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;
|
|
|
-};
|
|
|
+ return value && value.length
|
|
|
+}
|
|
|
|
|
|
/**
|
|
|
* Pre-save hook
|
|
|
*/
|
|
|
UserSchema
|
|
|
- .pre('save', function (next) {
|
|
|
- // Handle new/update passwords
|
|
|
- if (!this.isModified('password')) {
|
|
|
- return next();
|
|
|
- }
|
|
|
+ .pre('save', function (next) {
|
|
|
+ // Handle new/update passwords
|
|
|
+ if (!this.isModified('password')) {
|
|
|
+ return next()
|
|
|
+ }
|
|
|
|
|
|
- if (!validatePresenceOf(this.password)) {
|
|
|
- return next(new Error('密码错误'));
|
|
|
- }
|
|
|
+ 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();
|
|
|
- });
|
|
|
- });
|
|
|
- });
|
|
|
+ // 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('却少回调方法');
|
|
|
- }
|
|
|
+ /**
|
|
|
+ * 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)
|
|
|
+ }
|
|
|
|
|
|
- if (!byteSize) {
|
|
|
- byteSize = defaultByteSize;
|
|
|
- }
|
|
|
+ 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('却少回调方法')
|
|
|
+ }
|
|
|
|
|
|
- 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('却少密码或者加密内容');
|
|
|
- }
|
|
|
- }
|
|
|
+ if (!byteSize) {
|
|
|
+ byteSize = defaultByteSize
|
|
|
+ }
|
|
|
|
|
|
- var defaultIterations = 10000;
|
|
|
- var defaultKeyLength = 64;
|
|
|
- var salt = new Buffer(this.salt, 'base64');
|
|
|
+ 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('却少密码或者加密内容')
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- if (!callback) {
|
|
|
- return crypto.pbkdf2Sync(password, salt, defaultIterations, defaultKeyLength)
|
|
|
- .toString('base64');
|
|
|
- }
|
|
|
+ var defaultIterations = 10000
|
|
|
+ var defaultKeyLength = 64
|
|
|
+ var salt = new Buffer(this.salt, 'base64')
|
|
|
|
|
|
- return crypto.pbkdf2(password, salt, defaultIterations, defaultKeyLength, (err, key) => {
|
|
|
- if (err) {
|
|
|
- return callback(err);
|
|
|
- } else {
|
|
|
- return callback(null, key.toString('base64'));
|
|
|
- }
|
|
|
- });
|
|
|
+ if (!callback) {
|
|
|
+ return crypto.pbkdf2Sync(password, salt, defaultIterations, defaultKeyLength)
|
|
|
+ .toString('base64')
|
|
|
}
|
|
|
-};
|
|
|
|
|
|
-module.exports = mongoose.model('User', UserSchema);
|
|
|
+ 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)
|