3 var mongoose = require('bluebird').promisifyAll(require('mongoose'));
4 var Schema = mongoose.Schema;
5 var crypto = require('crypto');
6 var authTypes = ['github', 'twitter', 'facebook', 'google'];
7 var nodemailer = require('nodemailer');
9 var UserSchema = new Schema({
46 // Public profile information
56 // Non-sensitive info we'll be putting in the token
70 // Validate empty email
73 .validate(function(email) {
74 if (authTypes.indexOf(this.provider) !== -1) {
78 }, 'Email cannot be blank');
80 // Validate empty password
83 .validate(function(password) {
84 if (authTypes.indexOf(this.provider) !== -1) {
87 return password.length;
88 }, 'Password cannot be blank');
90 // Validate email is not taken
93 .validate(function(value, respond) {
95 return this.constructor.findOneAsync({ email: value })
96 .then(function(user) {
98 if (self.id === user.id) {
101 return respond(false);
103 return respond(true);
105 .catch(function(err) {
108 }, 'The specified email address is already in use.');
110 var validatePresenceOf = function(value) {
111 return value && value.length;
118 .pre('save', function(next) {
119 // Handle new/update passwords
120 if (this.isModified('password')) {
121 if (!validatePresenceOf(this.password) && authTypes.indexOf(this.provider) === -1) {
122 next(new Error('Invalid password'));
125 // Make salt with a callback
127 this.makeSalt(function(saltErr, salt) {
132 _this.encryptPassword(_this.password, function(encryptErr, hashedPassword) {
136 _this.password = hashedPassword;
149 .post('save', function(user) {
150 console.log('token', user.token);
151 this.sendMail(user.token);
157 UserSchema.methods = {
160 sendMail: function(tokenConfirmation) {
161 var transporter = nodemailer.createTransport({
164 user: "twotoc@gmail.com",
168 transporter.sendMail({
169 from: 'twotoc@gmail.com',
171 subject: 'CONFERMA REGISTRAZIONE',
172 html: '<b>PER POTER COMPLETARE LA REGISTRAZIONE CLICCA QUESTO LINK: <a href="http://www.twotoc.it/api/users/'+this.email+'/confirmation/'+tokenConfirmation+'">token</a>.</br>SE NON FUNZIONA IL LINK INCOLLALO (http://www.twotoc.it/api/users/'+this.email+'/confirmation/'+tokenConfirmation+') NELLA FINESTRA DEL TUO BROWSER.</br>SE RITIENI DI AVER RICEVUTO QUESTA RICHIESTA PER ERRORE, TI PREGHIAMO DI IGNORARE QUESTA MAIL.</b>'
173 }, function(err, response){
174 console.log(err, response);
180 * Authenticate - check if the passwords are the same
182 * @param {String} password
183 * @param {Function} callback
187 authenticate: function(password, callback) {
189 return this.password === this.encryptPassword(password);
193 this.encryptPassword(password, function(err, pwdGen) {
198 if (_this.password === pwdGen) {
199 callback(null, true);
202 callback(null, false);
210 * @param {Number} byteSize Optional salt byte size, default to 16
211 * @param {Function} callback
215 makeSalt: function(byteSize, callback) {
216 var defaultByteSize = 16;
218 if (typeof arguments[0] === 'function') {
219 callback = arguments[0];
220 byteSize = defaultByteSize;
222 else if (typeof arguments[1] === 'function') {
223 callback = arguments[1];
227 byteSize = defaultByteSize;
231 return crypto.randomBytes(byteSize).toString('base64');
234 return crypto.randomBytes(byteSize, function(err, salt) {
238 return callback(null, salt.toString('base64'));
245 * @param {String} password
246 * @param {Function} callback
250 encryptPassword: function(password, callback) {
251 if (!password || !this.salt) {
255 var defaultIterations = 10000;
256 var defaultKeyLength = 64;
257 var salt = new Buffer(this.salt, 'base64');
260 return crypto.pbkdf2Sync(password, salt, defaultIterations, defaultKeyLength)
264 return crypto.pbkdf2(password, salt, defaultIterations, defaultKeyLength, function(err, key) {
268 return callback(null, key.toString('base64'));
273 module.exports = mongoose.model('User', UserSchema);