Skip to content

Instantly share code, notes, and snippets.

@chriswitko
Created November 11, 2014 09:20
Show Gist options
  • Save chriswitko/490c76c93c3508a468e5 to your computer and use it in GitHub Desktop.
Save chriswitko/490c76c93c3508a468e5 to your computer and use it in GitHub Desktop.
var mongoose = require('mongoose');
var bcrypt = require('bcrypt-nodejs');
var crypto = require('crypto');
var monguurl = require('monguurl');
var timestamps = require("mongoose-times")
var mongoosePaginate = require('mongoose-paginate')
var ROLE_USER = 1, ROLE_MODERATOR = 2, ROLE_ADMIN = 3;
var VARIANT_USER = 1, VARIANT_BLOGGER = 2, VARIANT_STORE = 3;
var schemaOptions = {
toObject: {
virtuals: true
}
,toJSON: {
virtuals: true
}
};
var userSchema = new mongoose.Schema({
username: { type: String, unique: true, lowercase: true },
permalink: { type: String, unique: true, index: { unique: true } },
email: { type: String, unique: true, lowercase: true },
password: String,
website: String,
role: { type: Number, default: ROLE_USER },
variant: { type: Number, default: VARIANT_USER },
facebook: String,
twitter: String,
google: String,
github: String,
instagram: String,
linkedin: String,
tokens: Array,
meta: {
emailInvitesLeft: { type: Number, default: 5},
emailInvitesSent: { type: Number, default: 0},
products: { type: Number, default: 0},
karma: { type: Number, default: 0}
},
isVerified: { type: Boolean, default: false },
profile: {
name: { type: String, default: '' },
gender: { type: String, default: '' },
location: { type: String, default: '' },
website: { type: String, default: '' },
picture: { type: String, default: '' },
about: { type: String, default: '' }
},
resetPasswordToken: String,
resetPasswordExpires: Date,
lastNotifsReadAt: Date
}, schemaOptions);
userSchema.pre('save', function(next) {
var user = this;
if (!user.isModified('email')&&!user.username) return next();
user.username = user.email.split('@')[0];
next();
});
/**
* Hash the password for security.
* "Pre" is a Mongoose middleware that executes before each user.save() call.
*/
userSchema.pre('save', function(next) {
var user = this;
if (!user.isModified('password')) return next();
bcrypt.genSalt(5, function(err, salt) {
if (err) return next(err);
bcrypt.hash(user.password, salt, null, function(err, hash) {
if (err) return next(err);
user.password = hash;
next();
});
});
});
/**
* Validate user's password.
* Used by Passport-Local Strategy for password validation.
*/
userSchema.methods.comparePassword = function(candidatePassword, cb) {
bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
if (err) return cb(err);
cb(null, isMatch);
});
};
/**
* Get URL to a user's gravatar.
* Used in Navbar and Account Management page.
*/
userSchema.virtual('photo').get(function() {
size = 200;
if (!this.email) {
return 'https://gravatar.com/avatar/?s=' + size + '&d=retro';
}
var md5 = crypto.createHash('md5').update(this.email).digest('hex');
return 'https://gravatar.com/avatar/' + md5 + '?s=' + size + '&d=retro';
});
userSchema.methods.gravatar = function(size) {
if (!size) size = 200;
if (!this.email) {
return 'https://gravatar.com/avatar/?s=' + size + '&d=retro';
}
var md5 = crypto.createHash('md5').update(this.email).digest('hex');
return 'https://gravatar.com/avatar/' + md5 + '?s=' + size + '&d=retro';
};
userSchema.methods.getName = function() {
return this.profile.name || this.username || this.email || this.id
};
userSchema.methods.getRole = function() {
if(this.role==1) return 'User';
else if(this.role==2) return 'Moderator';
else if(this.role>2) return 'Admin';
};
userSchema.methods.getPermalink = function() {
if(this.permalink) return '/' + this.permalink;
else return '/' + this.id;
};
userSchema.methods.getExternalLink = function() {
if(this.profile.website) return this.profile.website;
else return this.getPermalink();
};
userSchema.plugin(monguurl({source: 'username', target: 'permalink'}));
userSchema.plugin(timestamps, { created: 'createdAt', lastUpdated: 'updatedAt' })
userSchema.plugin(mongoosePaginate)
module.exports = mongoose.model('User', userSchema);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment