1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
/**
* Module dependencies
*/
var mongoose = require('mongoose')
, Schema = mongoose.Schema
, crypto =require('crypto')
, authTypes = ['facebook', 'twitter'];
/**
* User schema
*/
var UserSchema = new Schema({
name: String,
email: String,
username: String,
provider: String,
hashed_password: String,
salt: String,
facebook: {},
twitter: {}
});
/**
* Virtuals
*/
UserSchema
.virtual('password')
.set(function(password) {
this._password = password
this.salt = this.makeSalt()
this.hashed_password = this.encryptPassword(password)
}).get(function() { return this._password });
/**
* Validations
*/
var validatePrecenceOf = function (value) {
return value && value.length;
}
// the four validations below only apply if you are signing up traditionally
UserSchema.path('name').validate(function(name) {
// if you're authenticated by any of the oauth strategies (facebook, twitter), don't validate
if(authTypes.indexOf(this.provider) !== -1) return true;
return name.length;
}, 'Name cannot be blank');
UserSchema.path('email').validate(function(email) {
if(authTypes.indexOf(this.provider) !== -1) return true;
return email.length;
}, 'Email cannot be blank');
UserSchema.path('username').validate(function(username) {
if(authTypes.indexOf(this.provider) !== -1) return true;
return username.length;
}, 'Username cannot be blank');
UserSchema.path('hashed_password').validate(function(hashed_password) {
if(authTypes.indexOf(this.provider) !== -1) return true;
return hashed_password.length;
}, 'Password cannot be blank');
/**
* Pre-save hook
*/
UserSchema.pre('save', function(next) {
if (!this.isNew) return next();
if(!validatePrecenceOf(this.password)
&& authTypes.indexOf(this.provider) === -1)
next(new Error('Invalid password'));
else next();
});
/**
* Methods
*/
UserSchema.methods = {
/**
* Authenticate - check if passwords are the same
*
* @param {String} plainText
* @return {Bolean}
* @api public
*/
authenticate: function(plainText) {
return this.encryptPassword(plainText) === this.hashed_password;
},
/**
* Make salt
*
* @return {String}
* @api public
*/
makeSalt: function() {
return Math.round((new Date().valueOf() * Math.random())) + '';
},
/**
* Encrypt password
*
* @param {String} password
* @return {String}
* @api public
*/
encryptPassword: function(password) {
if (!password) return '';
return crypto.createHmac('sha1', this.salt).update(password).digest('hex');
}
}
mongoose.model('User', UserSchema);
|