I am building a simple REST API. When registering a new user, my API returns:
{
"status": "success",
"data": {
"email": "[email protected]",
"password": "$2b$10$DcFdth1FKskyy6A7uwCHDOE15oy4pgZBj.TwEBcQnSVrUK4mntZdy"
"first_name": "Tester",
"last_name": "Test",
"id": 13
}
}
I want to hide the password field in my response like so:
{
"status": "success",
"data": {
"email": "[email protected]",
"first_name": "Tester",
"last_name": "Test",
"id": 13
}
}
I've added delete user.attributes.password to my code, but is this correct?
My code:
/**
* Auth Controller
*/
const bcrypt = require('bcrypt');
const debug = require('debug')('books:auth_controller');
const { matchedData, validationResult } = require('express-validator');
const models = require('../models');
/**
* Register a new user
*
* POST /register
*/
const register = async (req, res) => {
// check for any validation errors
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(422).send({ status: 'fail', data: errors.array() });
}
// get only the validated data from the request
const validData = matchedData(req);
console.log("The validated data:", validData);
// generate a hash of `validData.password`
// and overwrite `validData.password` with the generated hash
try {
validData.password = await bcrypt.hash(validData.password, models.User.hashSaltRounds);
} catch (error) {
res.status(500).send({
status: 'error',
message: 'Exception thrown when hashing the password.',
});
throw error;
}
try {
const user = await new models.User(validData).save();
debug("Created new user successfully: %O", user);
delete user.attributes.password;
res.send({
status: 'success',
data: user,
});
} catch (error) {
res.status(500).send({
status: 'error',
message: 'Exception thrown in database when creating a new user.',
});
throw error;
}
}
module.exports = {
register,
}
This is my user model. I am using Bookshelf.js.
/**
* User model
*/
module.exports = (bookshelf) => {
return bookshelf.model('User', {
tableName: 'users',
albums() {
return this.hasMany('Album');
},
photos() {
return this.hasMany('Photo');
}
}, {
hashSaltRounds: 10,
async fetchById(id, fetchOptions = {}) {
return await new this({ id }).fetch(fetchOptions);
},
async login(email, password) {
// find user based on the email (bail if no such user exists)
const user = await new this({ email }).fetch({ require: false });
if (!user) {
return false;
}
const hash = user.get('password');
// hash the incoming cleartext password using the salt from the db
// and compare if the generated hash matches the db-hash
const result = await bcrypt.compare(password, hash);
if (!result) {
return false;
}
// all is well, return user
return user;
}
});
};
you can add a list of model attributes to exclude from the output when serializing it. check it out here