text: var mongoose = require('mongoose'),
  	crypto = require('crypto'),
  	Schema = mongoose.Schema;
  
  // Define the User Schema
  var UserSchema = new Schema({
  	// The username is the user's email. In the code it is always 
  	// referred to as `username`, but to the end-user we call it
  	// their email.
  	username: {
  		type: String,
  		trim: true,
  		unique: 'Email address already in use.',
  		required: 'Email address is required',
  		match: [/.+\@.+\..+/, 'Invalid email address']
  	},
  	password: {
  		type: String,
  		required: 'A password is required'
  	},
  	salt: {
  		type: String
  	},	
  	firstName: {
  		type: String,
  		trim: true,
  		default: ''
  	},
  	lastName: {
  		type: String,
  		trim: true,
  		default: ''
  	},
  	provider: {
  		type: String,
  		required: 'Provider is required'
  	},
  	providerId: String,
  	providerData: {},
  	roles: {
  		type: [{
  			type: String,
  			enum: ['user', 'admin']
  		}],
  		default: ['user']
  	},
  	created: {
  		type: Date,
  		default: Date.now
  	},
  	updated: {
  		type: Date,
  		default: Date.now		
  	}	
  });
  
  /**
   * Hook a pre save method to hash the password
   */
  UserSchema.pre('save', function(next) {
  	if (this.password) {
  		this.salt = new Buffer(crypto.randomBytes(16).toString('base64'), 'base64');
  		this.password = this.hashPassword(this.password);
  	}
  	next();
  });
  
  /**
   * Create instance method for hashing a password
   */
  UserSchema.methods.hashPassword = function(password) {
  	if (this.salt && password) {
  		return crypto.pbkdf2Sync(password, this.salt, 10000, 64).toString('base64');
  	} else {
  		return password;
  	}
  };
  
  /**
   * Create instance method for authenticating user
   */
  UserSchema.methods.authenticate = function(password) {
  	return this.password === this.hashPassword(password);
  };
  
  mongoose.model('User', UserSchema);