Alberto Vilches
Alberto Vilches

Reputation: 333

How to set automatic password hashing in Sequelize's user model?

Right now I'm hashing the password on the route function and providing the hash when creating the user but I know there's a way to have this be handled through Sequelize itself. I have searched around but every answer seems to be outdated or the methods never got called. Here is my config:

server/models/User.js

module.exports = (sequelize, type) => {
  const User = sequelize.define(
    "User",
    {
      user_id: {
        type: type.INTEGER,
        allowNull: false,
        primaryKey: true,
        autoIncrement: true
      },
      name: {
        type: type.STRING,
        allowNull: false
      },
      email: {
        type: type.STRING,
        allowNull: false
      },
      password: {
        type: type.STRING,
        allowNull: false
      },
      reg_date: {
        type: type.DATEONLY,
        allowNull: false,
        defaultValue: sequelize.fn("now")
      }
    },
    {
      timestamps: false
    }
  );
  return User;
};

server/config/sequelize.js

const Sequelize = require("sequelize");

const sequelize = new Sequelize(process.env.CLEARDB_DATABASE_URL);

sequelize
  .authenticate()
  .then(() => {
    console.log("Connection has been established successfully.");
  })
  .catch(err => {
    console.error("Unable to connect to the database:", err);
  });

const UserModel = require("../models/User");


const User = UserModel(sequelize, Sequelize);


module.exports = User;

This is how I'm handling hashing right now:

server/routes/register.js

User.findOne({ where: { email: email } }).then(user => {
        if (!user) {
          bcrypt.hash(password, 10, (err, hash) => {
            if (err) throw err;

            User.create({
              name: req.body.name,
              email: email,
              password: hash
            })
              .then(user => {
                return user;
              })
              .catch(err => console.log(err));
          });
        }
      });

Upvotes: 0

Views: 1714

Answers (2)

Alberto Vilches
Alberto Vilches

Reputation: 333

This did the trick:

    ...
    {
      timestamps: false
    }
  );
  User.addHook(
    "beforeCreate",
    user => (user.password = bcrypt.hashSync(user.password, 10))
  );
  return User;
};

Upvotes: 1

Anatoly
Anatoly

Reputation: 22758

Please don't mix your model definition with a business or a security logic (or another one). In future you might want to change an encryption library or a hashing algorithm and you will have to change your model accordingly. A security layer should be separated from your models.

Upvotes: 0

Related Questions