2
\$\begingroup\$

I am creating a REST API to access a database of users. I am new to Node.js and developing REST APIs in general. I am also trying to use best security practices.

main.js

var fs = require('fs');
var restify = require('restify');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var bcrypt = require('bcrypt');

mongoose.connect('localhost', 'nodejs-sample');

var User = require('./models/user')

// SSL options
var options = {
  certificate: fs.readFileSync('./ssl/cert.pem'),
  key: fs.readFileSync('./ssl/key.pem')
}

var server = restify.createServer(options);

server.use(bodyParser.urlencoded({extended: true}));
server.use(bodyParser.json());

server.get('/users', function(req, res) {
  User.find(function(err, users) {
    if (err) {
      res.send(err);
    }

    res.json(users);
  });
});

server.post('/users', function(req, res) {
  bcrypt.hash(req.body.password, 10, function(err, hash) {
    if (err) {
      res.send(err);
    }

    User.create({
      username: req.body.username,
      first_name: req.body.first_name,
      last_name: req.body.last_name,
      email: req.body.email,
      hash: hash
    }, function(err) {
      if (err) {
        res.send(err)
      }

      res.json({message: 'User added'});
    });
  });
});

server.get('/users/:user_id', function(req, res) {
  User.findById(req.params.user_id, function(err, user) {
    if (err) {
      res.send(err);
    }

    res.json(user);
  });
});

server.put('/users/:user_id', function(req, res) {
  var body = req.body;
  if (body.password) {
    bcrypt.hash(body.password, 10, function(err, hash) {
      if (err) {
        res.send(err);
      }

      delete body.password;
      body.hash = hash;
      User.update({_id: req.params.user_id}, body, function() {
        res.json({message: 'User updated'});
      });
    });
  } else {
    User.update({_id: req.params.user_id}, body, function() {
      res.json({message: 'User updated'});
    });
  }
});

server.del('/users/:user_id', function(req, res) {
  User.findByIdAndRemove(req.params.user_id, function(err) {
    if (err) {
      res.send(err);
    }

    res.json({message: 'User deleted'});
  });
});

server.listen(process.env.PORT || 8080, function() {
  console.log('%s listening at %s', server.name, server.url);
});

models/user.js

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var UserSchema = new Schema({
  username: {
    type: String,
    required: true,
    unique: true
  },
  first_name: {
    type: String,
    required: true
  },
  last_name: {
    type: String,
    required: true
  },
  email: {
    type: String,
    required: true
  },
  hash: {
    type: String,
    required: true
  }
});

// remove hash from JSON output
UserSchema.methods.toJSON = function() {
  var obj = this.toObject();
  delete obj.hash;
  return obj;
};

UserSchema.methods.verifyPassword = function(password, cb) {
  bcrypt.compare(password, this.hash, function(err, res) {
    if (err) {
      return cb(err);
    }

    cb(null, res);
  });
};

module.exports = mongoose.model('User', UserSchema);
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Few points to consider:
- Extract users CRUD logic to UsersService - this service will interact with mongoose and will be responsible for create, get, update and delete operations.
- Consider using Json Web Tokens instead of passing the password for every put request - it is an alternative for using sessions.

Overall for a newbie I consider this as a very good code.

\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.