<commit_before>var bcrypt = require('bcrypt'),
    mongoose = require('mongoose'),
    Schema = mongoose.Schema,

    utils = require('../helpers/utils');

var UserSchema = new Schema({
  username: {
    type: String,
    required: true,
    index: { unique: true }
  },
  password: {
    type: String,
    required: true
  },
  email: {
    type: String,
    required: true
  },
  name: {
    type: String,
    required: true
  },
  slug: {
    type: String,
    index: { unique: true }
  },
  photo: String,
  bio: String,

  meta: {
    created: {
      type: Date,
      required: true,
      default: Date.now,
    },
    modified: {
      type: Date,
      required: true,
      default: Date.now,
    }
  }
});

UserSchema.pre('save', function (next) {
  if(!this.slug)
    this.slug = utils.slugify(this.username);

  if(!this.isModified('password'))
    return next();

  // Generate the password hash
  bcrypt.genSalt(10, function (err, salt) {
    if(err)
      return next(err)

    // Hash with the new salt
    bcrypt.hash(this.password, salt, function (err, hash) {
      if(err)
        return next(err);

      this.password = hash;
      next();
    }.bind(this));
  }.bind(this));
});

/**
 * Compares the plaintext password against the stored hash
 */
UserSchema.methods.comparePassword = function (candidate, callback) {
  bcrypt.compare(candidate, this.password, function (err, matches) {
    if(err)
      return callback(err);
    else
      callback(null, matches);
  });
};

// The mongoose object performing operations on the database
var User = mongoose.model('User', UserSchema);

module.exports = {

  Model: User,

  /**
   * GET '/api/users'
   */
  findAll: function (req, res) {
    var query = User.find();
    query.exec(function (err, docs) {
      if(err)
        res.json(500, { message: err });
      else
        res.json(200, docs);
    });
  },

  /**
   * GET '/api/users/:slug'
   */
  findBySlug: function (req, res) {
    var query = User.find({ slug: req.params.slug });
    query.exec(function (err, docs) {
      if(err)
        res.json(500, { message: err });
      else
        res.json(200, docs);
    });
  }

};<commit_msg>Added Update and Delete endpoints to the User schema<commit_after>var bcrypt = require('bcrypt'),
    mongoose = require('mongoose'),
    Schema = mongoose.Schema,

    utils = require('../helpers/utils');

var UserSchema = new Schema({
  username: {
    type: String,
    required: true,
    index: { unique: true }
  },
  password: {
    type: String,
    required: true
  },
  email: {
    type: String,
    required: true
  },
  name: {
    type: String,
    required: true
  },
  slug: {
    type: String,
    index: { unique: true }
  },
  photo: String,
  bio: String,

  meta: {
    created: {
      type: Date,
      required: true,
      default: Date.now,
    },
    modified: {
      type: Date,
      required: true,
      default: Date.now,
    }
  }
});

/**
 * Slugifies the username if a slug isn't already set and generates password hash
 * before saving to the database
 */
UserSchema.pre('save', function (next) {
  if(!this.slug)
    this.slug = utils.slugify(this.username);
  else
    this.slug = utils.slugify(this.slug); // Enforce rules eve if it's populated

  if(!this.isModified('password'))
    return next();

  // Generate the password hash
  bcrypt.genSalt(10, function (err, salt) {
    if(err)
      return next(err)

    // Hash with the new salt
    bcrypt.hash(this.password, salt, function (err, hash) {
      if(err)
        return next(err);

      this.password = hash;
      return next();
    }.bind(this));
  }.bind(this));
});

/**
 * Compares the plaintext password against the stored hash
 */
UserSchema.methods.comparePassword = function (candidate, callback) {
  bcrypt.compare(candidate, this.password, function (err, matches) {
    if(err)
      return callback(err);
    
    return callback(null, matches);
  });
};

// The mongoose object performing operations on the database
var User = mongoose.model('User', UserSchema);

module.exports = {

  Model: User,

  /**
   * GET '/api/users'
   */
  findAll: function (req, res) {
    var query = User.find();
    query.exec(function (err, docs) {
      if(err)
        return res.json(500, { message: err });
      
      return res.json(200, docs);
    });
  },

  /**
   * POST '/api/users'
   */
  new: function (req, res) {
    var doc = new User(req.body);

    doc.save(function (err, doc) {
      if(err)
        return res.json(500, { message: err });
      
      return res.json(200, doc);
    });
  },

  /**
   * GET '/api/users/:slug'
   */
  findBySlug: function (req, res) {
    var query = User.find({ slug: req.params.slug });

    query.exec(function (err, docs) {
      if(err)
        return res.json(500, { message: err });

      return res.json(200, docs);
    });
  },

  /**
   * UPDATE '/api/users/:slug'
   */
  update: function (req, res) {
    var query = User.update({ slug: req.params.slug }, 
               { $set: req.body, $inc: { count: 1 } }, 
               { multi: false });

    query.exec(function (err, doc) {
      if(err)
        return res.json(500, { message: err });

      return res.json(200, doc);
    });
  },

  /**
   * DELETE '/api/users/:slug'
   */
  remove: function (req, res) {
    var query = User.remove({ slug: req.params.slug });
    query.exec(function (err, doc) {
      if(err)
        return res.json(500, { message: err });

      // HTTP 204 is the code for no content
      return res.json(204);
    });
  }

};
{'fraction_non_alphanumeric': 0.15438533429187634, 'fraction_numerical': 0.008986340762041696, 'mean_word_length': 2.3164481525625744, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4767251', 'n_tokens_mistral': 1902, 'n_tokens_neox': 1847, 'n_words': 471}