Getters and Setters for Virtual fields in Sequelize

Viewed 1322

I'm trying to hash my password field before storing it in the database. For that reason I've created a virtual field called password and an actual field called hashedPassword. The trouble is that when I try to encrypt the password in beforeCreate hook, it the user.password is undefined. I have tried every thing. I've also defined custom getters and setters for the virtual field. I don't know what I'm doing wrong here. Any help or guidance would be appreciated. Thanks.

import bcrypt from 'bcrypt';

module.exports = (sequelize, DataTypes) => {
  const User = sequelize.define(
    'User',
    {
        passwordhash: {
          type: DataTypes.STRING,
          allowNull: false,
          validate: {
            notEmpty: true
          }
        },
        password: {
          allowNull: false,
          type: DataTypes.VIRTUAL,
          set(password) {
            const valid = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[#$^+=!*()@%&]).{8,30}$/.test(
              password
            );
            if (!valid) {
              throw new Error(`Password not valid ${password}`);
            }
            this.setDataValue('password', password);
          },
          get() {
            return this.getDataValue('password');
          }
        }
      }
    },
    {
      hooks: {
        beforeCreate: function hashPassword(user) {
          console.log('user is:', user);
          return bcrypt
            .hash('Abcdefgh1@', 12)
            .then(hashed => {
              user.passwordhash = hashed;
            })
            .catch(error => error);
        }
      }
    }
  );
  User.associate = function(models) {
    // associations can be defined here
  };
  return User;
};


1 Answers

use hooks :

hooks: {
      beforeCreate: async (user, options) => {
        let salt = await bcrypt.genSalt(10)
        let hash = await bcrypt.hash(user.password, salt)
        user.password = hash;
      }
    }

and for updating password fields use this:

User.beforeBulkUpdate(async instance => {
    if (instance.attributes.password) {
      let salt = await bcrypt.genSalt(10)
      let hash = await bcrypt.hash(instance.attributes.password, salt)
      instance.attributes.password = hash;
    }
  })

this works fine for me

Related