出于某种原因,每当我在数据库中创建一个新用户时,它会尝试先添加另一个用户然后再输出错误。
我正在使用Yeoman的生成器angular-fullstack为我的应用程序创建一个api。在上周,我开始注意到,当我的数据库填充时,它没有显示“已完成填充用户”,表示它未成功添加我的seed.js文件中的用户。这是我的seed.js文件。
Seed.js
'use strict';
var Thing = require('../api/thing/thing.model');
var User = require('../api/user/user.model');
var Item = require('../api/item/item.model');
var Calendar = require('../api/calendar/calendar.model');
Thing.find({}).remove(function() {});
User.find({}).remove(function() {
User.create({
provider: 'local',
role: 'student',
name: 'Student',
email: 'student@test.com',
password: 'test',
pin: '0807'
}, {
provider: 'local',
role: 'teacher',
name: 'Teacher',
email: 'teacher@test.com',
password: 'test',
pin: '0807'
}, {
provider: 'local',
role: 'admin',
name: 'Admin',
email: 'admin@admin.com',
password: 'admin',
pin: '0807'
}, function() {
console.log('finished populating users');
}, function(err) {
console.log(err);
});
});
Calendar.find({}).remove(function() {});
console.log("Removed Calendars");
Item.find({}).remove(function () {
Item.create({
calendarId: "dd7sfasd8f8sd",
title: "title",
description: "description",
date: new Date(),
checklists: [],
attachments: [],
status: "Not Completed",
edit: false,
verification: "test", //This will not be here in the long run
verify: false
}, {
calendarId: "323k3k2l23lk4j4",
title: "other",
description: "description",
date: new Date(),
checklists: [],
attachments: [],
status: "Completed",
edit: false,
verification: "test", //This will not be here in the long run
verify: false
}, {
calendarId: "323k3k2l23lk4j4",
title: "title",
description: "description",
date: new Date(),
checklists: [],
attachments: [],
status: "Verified",
edit: false,
verification: "test", //This will not be here in the long run
verify: false
}, {
calendarId: "323k3k2l23lk4j4",
title: "test",
description: "description",
date: new Date(),
checklists: [],
attachments: [],
status: "Not Completed",
edit: false,
verification: "test", //This will not be here in the long run
verify: false
}, function() {
console.log('finished populating items');
}
);
});
当我在发生错误时添加了该功能时,它显示了这个:
Express server listening on 9000, in development mode
Done waiting!
Running "open:server" (open) task
Running "watch" task
Waiting...
{ _id: 5704a4d8b414a48822cd30a6, students: [], role: 'teacher' }
[Error: Invalid or no password]
finished populating items
您可能会注意到,显示为要添加的用户的对象不是我的seed.js文件中的用户。为了节省查看整个模型的时间,这里是我打印正在创建的用户以及发生此错误的方法:
UserSchema
.pre('save', function(next) {
if (!this.isNew) return next();
console.log(this);
if (!validatePresenceOf(this.hashedPassword) && authTypes.indexOf(this.provider) === -1) {
next(new Error('Invalid or no password'));
if (!validatePresenceOf(this.hashedPin))
next(new Error('Invalid pin'));
} else {
next();
}
});
但是,有关此错误的更多信息,我的整个文件如下所示:
user.model.js
'use strict';
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var crypto = require('crypto');
var authTypes = ['github', 'twitter', 'facebook', 'google'];
var Student = new Schema({
firstName: String,
lastName: String,
age: Number
});
var UserSchema = new Schema({
name: String,
username: String,
email: { type: String, lowercase: true },
role: {
type: String,
default: 'teacher'
},
teachersEmail: { type: String, lowercase: true },
students: [Student],
status: String,
hashedPassword: String,
hashedPin: String,
hasPassword: Boolean,
provider: String,
salt: String,
pinSalt: String,
facebook: {},
twitter: {},
google: {},
github: {}
});
/**
* Virtuals
*/
UserSchema
.virtual('password')
.set(function(password) {
this._password = password;
this.salt = this.makeSalt();
this.hashedPassword = this.encryptPassword(password);
})
.get(function() {
return this._password;
});
UserSchema
.virtual('pin')
.set(function(pin) {
this._pin = pin;
this.pinSalt = this.makeSalt();
this.hashedPin = this.encryptPin(pin);
})
.get(function() {
return this._pin;
});
// Public profile information
UserSchema
.virtual('profile')
.get(function() {
return {
'name': this.name,
'role': this.role
};
});
// Non-sensitive info we'll be putting in the token
UserSchema
.virtual('token')
.get(function() {
return {
'_id': this._id,
'role': this.role
};
});
/**
* Validations
*/
// Validate empty email
UserSchema
.path('email')
.validate(function(email) {
if (authTypes.indexOf(this.provider) !== -1) return true;
return email.length;
}, 'Email cannot be blank');
// Validate empty password
UserSchema
.path('hashedPassword')
.validate(function(hashedPassword) {
if (authTypes.indexOf(this.provider) !== -1) return true;
return hashedPassword.length;
}, 'Password cannot be blank');
// Validate empty pin
UserSchema
.path('hashedPin')
.validate(function(hashedPin) {
return hashedPin.length;
}, 'PIN cannot be blank');
// Validate empty pin
UserSchema
.path('hashedPin')
.validate(function(hashedPin) {
return hashedPin.length == 4;
}, 'PIN must be 4 characters in length');
// Validate email is not taken
UserSchema
.path('email')
.validate(function(value, respond) {
var self = this;
this.constructor.findOne({email: value}, function(err, user) {
if(err) throw err;
if(user) {
if(self.id === user.id) return respond(true);
return respond(false);
}
respond(true);
});
}, 'The specified email address is already in use.');
var validatePresenceOf = function(value) {
return value && value.length;
};
/**
* Pre-save hook
*/
UserSchema
.pre('save', function(next) {
if (!this.isNew) return next();
console.log(this);
if (!validatePresenceOf(this.hashedPassword) && authTypes.indexOf(this.provider) === -1) {
next(new Error('Invalid or no password'));
if (!validatePresenceOf(this.hashedPin))
next(new Error('Invalid pin'));
} else {
next();
}
});
/**
* Methods
*/
UserSchema.methods = {
/**
* Authenticate - check if the passwords are the same
*
* @param {String} plainText
* @return {Boolean}
* @api public
*/
authenticate: function(plainText) {
if (this.hashedPassword) {
return this.encryptPassword(plainText) === this.hashedPassword;
} else {
return !!(this.google || this.facebook);
}
},
verify: function(plainText) {
return this.encryptPin(plainText) === this.hashedPin;
},
/**
* Make salt
*
* @return {String}
* @api public
*/
makeSalt: function() {
return crypto.randomBytes(16).toString('base64');
},
/**
* Encrypt password
*
* @param {String} password
* @return {String}
* @api public
*/
encryptPassword: function(password) {
if (!password || !this.salt) return '';
var salt = new Buffer(this.salt, 'base64');
return crypto.pbkdf2Sync(password, salt, 10000, 64).toString('base64');
},
encryptPin: function(pin) {
if (!pin || !this.pinSalt) return '';
var pinSalt = new Buffer(this.pinSalt, 'base64');
return crypto.pbkdf2Sync(pin, pinSalt, 10000, 64).toString('base64');
}
};
module.exports = mongoose.model('User', UserSchema);
最后,我决定在seed.js文件中单独添加用户,看看会发生什么,就像这样......
User.find({}).remove(function() {
User.create({
provider: 'local',
role: 'student',
name: 'Student',
email: 'student@test.com',
password: 'test',
pin: '0807'
}, function() {
console.log('Added user');
}, function(err) {
console.log(err);
});
User.create({
provider: 'local',
role: 'teacher',
name: 'Teacher',
email: 'teacher@test.com',
password: 'test',
pin: '0807'
}, function() {
console.log('Added user');
}, function(err) {
console.log(err);
});
User.create({
provider: 'local',
role: 'admin',
name: 'Admin',
email: 'admin@admin.com',
password: 'admin',
pin: '0807'
}, function() {
console.log('Added user');
}, function(err) {
console.log(err);
});
});
这是终端显示的内容:
Running "watch" task
Completed in 2.258s at Wed Apr 06 2016 00:08:34 GMT-0600 (Mountain Daylight Time) - Waiting...
{ _id: 5704a7e2d85623902a78e1fc, students: [], role: 'teacher' }
[Error: Invalid or no password]
{ _id: 5704a7e2d85623902a78e1fe, students: [], role: 'teacher' }
[Error: Invalid or no password]
{ _id: 5704a7e2d85623902a78e200, students: [], role: 'teacher' }
[Error: Invalid or no password]
finished populating items
这里的主要问题是它正在添加一个我没有添加的用户。 (我添加了三个。第一个被命名为“学生”。终端显示的用户没有姓名,没有电子邮件,没有。请记住,当我通过我的注册屏幕添加用户时,这不会发生。用户是加上好......
导致这种情况的原因是什么?