var mongoose = require('mongoose'); var uniqueValidator = require('mongoose-unique-validator'); var crypto = require('crypto'); var jwt = require('jsonwebtoken'), secret = require('../../config').secret, session_lifetime = require('../../config').session_lifetime; var UserSchema = new mongoose.Schema({ email: { type: String, lowercase: true, unique: true, required: [true, "email can't be blank"], match: [/\S+@\S+\.\S+/, 'is invalid'], index: true }, username: { type: String, lowercase: true, unique: true, required: [true, "username can't be blank"], match: [/^[a-zA-Z0-9_]+$/, 'is invalid'], index: true }, role: String, firstname: { type: String, required: [true, "firstname can't be blank"] }, lastname: { type: String, required: [true, "lastname can't be blank"] }, phone: String, licence: Number, poids: Number, image: String, bg_image: String, favorites: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Product' }], following: [{ type: mongoose.Schema.Types.ObjectId, ref: 'User' }], hash: String, salt: String }, { timestamps: true, toJSON: { virtuals: true } }); UserSchema.plugin(uniqueValidator, { message: 'is already taken.' }); UserSchema.methods.validPassword = function (password) { let hash = crypto.pbkdf2Sync(password, this.salt, 10000, 512, 'sha512').toString('hex'); return this.hash === hash; }; UserSchema.methods.setPassword = function (password) { this.salt = crypto.randomBytes(16).toString('hex'); this.hash = crypto.pbkdf2Sync(password, this.salt, 10000, 512, 'sha512').toString('hex'); }; UserSchema.methods.generateJWT = function () { var today = new Date(); var exp = new Date(today.getTime() + (session_lifetime * 1000)); return jwt.sign({ id: this._id, username: this.username, exp: parseInt(exp.getTime() / 1000) }, secret, { algorithm: 'HS256' }); }; UserSchema.methods.toAuthJSON = function () { return { id: this._id, email: this.email, role: this.role, token: this.generateJWT(), firstname: this.firstname, lastname: this.lastname, phone: this.phone, licence: this.licence, poids: this.poids, username: this.username, image: this.image || '/assets/images/users/user.jpg', bg_image: this.bg_image || '/assets/images/users/bg_user.jpg' }; }; UserSchema.methods.toJSONFor = function () { return { email: this.email, role: this.role, firstname: this.firstname, lastname: this.lastname, phone: this.phone, licence: this.licence, poids: this.poids, username: this.username, image: this.image || '/assets/images/users/user.jpg', bg_image: this.bg_image || '/assets/images/users/bg_user.jpg' }; }; UserSchema.methods.toProfileJSONFor = function (user) { return { email: this.email, firstname: this.firstname, lastname: this.lastname, phone: this.phone, licence: this.licence, poids: this.poids, username: this.username, image: this.image || '/assets/images/users/user.jpg', bg_image: this.bg_image || '/assets/images/users/bg_user.jpg', following: user ? user.isFollowing(this._id) : false }; }; UserSchema.methods.favorite = function (id) { if (this.favorites.indexOf(id) === -1) { this.favorites.push(id); } return this.save(); }; UserSchema.methods.unfavorite = function (id) { this.favorites.remove(id); return this.save(); }; UserSchema.methods.isFavorite = function (id) { return this.favorites.some(function (favoriteId) { return favoriteId.toString() === id.toString(); }); }; UserSchema.methods.follow = function (id) { if (this.following.indexOf(id) === -1) { this.following.push(id); } return this.save(); }; UserSchema.methods.unfollow = function (id) { this.following.remove(id); return this.save(); }; UserSchema.methods.isFollowing = function (id) { return this.following.some(function (followId) { return followId.toString() === id.toString(); }); }; mongoose.model('User', UserSchema);