水线0.10.14 + express - beforeCreate未执行

时间:2014-11-27 17:57:07

标签: node.js express sails.js waterline

我正在尝试在我的用户模型上设置密码,但在创建被调用之前从未见过。

使用Express 4.2和水线0.10.14。

用户模型:

var Waterline = require('waterline'),
    uuid = require('uuid'),
    bcrypt = require('bcrypt');

var User = module.exports = Waterline.Collection.extend({

  identity: 'user',
  connection: 'default',
  autoPK: false, // prevents creation of the id
  schema: true,


  types: {
    // Custom Validation - https://github.com/balderdashy/waterline-docs/blob/master/models.md#custom-validations
  },

  attributes: {

    uuid: {
      type: 'uuidv4',
      primaryKey: true,
      defaultsTo: uuid.v4
    },

    first_name: {
      type: 'string',
      required: true
    },

    last_name: {
      type: 'string',
      required: true
    },

    email: {
      type: 'email',
      required: true,
      unique: true
    },

    username: {

      // TODO: validate no spaces, or special characters

      type: 'string',
      required: true,
      unique: true,
      index: true,
      minLength: 3,
      maxLength: 30
    },

    password: {
      // TODO:  add rules on password
      type: 'string',
      minLength: 6,
      maxLength: 50,
      required: true,
      columnName: 'encrypted_password'
    },

    // TODO: custom input with - https://developers.google.com/places/documentation/autocomplete#place_autocomplete_requests
    location: {
      type: 'string'
    },

    activated: {
        type: 'boolean',
        defaultsTo: false
    },
    activationToken: {
        type: 'string'
    },

    // Override toJSON instance method to remove values
    toJSON: function() {
      var obj = this.toObject();
      // delete obj.password;
      delete obj.email;
      delete obj.activated;
      delete obj.activationToken;

      return obj;
    },


    verifyPassword: function (password) {
      return bcrypt.compareSync(password, this.password);
    },

    changePassword: function(newPassword, next){
      this.password = newPassword;
      this.save(function(err, u) {
        return next(err,u);
      });
    },


    // Lifecycle Callbacks
    beforeCreate: function(attrs, next) { 

      console.log('beforeCreate - user');

      bcrypt.genSalt(process.env.SALT_WORK_FACTOR, function(err, salt) {
          if (err) return next(err);

          bcrypt.hash(attrs.password, salt, function(err, crypted) {
            if(err) return next(err);

            attrs.password = crypted;
            attrs.activationToken = crypto.token(new Date().getTime() + attrs.email);

            return next();
          });
        });

    },

    beforeUpdate: function (attrs, next) {
      if(attrs.newPassword){
        bcrypt.genSalt(process.env.SALT_WORK_FACTOR, function(err, salt) {
          if (err) return next(err);

          bcrypt.hash(attrs.newPassword, salt, function(err, crypted) {
            if(err) return next(err);

            delete attrs.newPassword;
            attrs.password = crypted;
            return next();
          });
        });
      }
      else {
        return next();
      }
    }


  }

});

这是我在我的控制器上调用它的方式。

exports.create = function (req, res, next) {
    app.models.user.create(req.body, function (err, model) {
        if(err) return res.error('users/signup', err);
        res.success('users/welcome', model);
    });
};

我从未看到我的beforeCreate上的日志被调用,密码永远不会被哈希。想法?

编辑:用户模型以反映最近的更改。还注意到beforeCreate应该在验证之前运行。

2 个答案:

答案 0 :(得分:1)

我想我知道为什么你的beforeCreate没有运行。这是因为密码是必填字段。 Waterline实际上在运行beforeCreate回调之前运行验证回调。由于密码在创建values.password之前不存在,因此验证失败并且beforeCreate永远不会被调用。我假设您在创建新用户时只是传递了一个newPassword参数。

答案 1 :(得分:1)

这是我的一个小错误,生命周期回调与我的属性包含在同一个对象中。他们必须在那个对象之外。