Search code examples
node.jsormvirtual-attributenode-orm2

How can I define virtual properties in node-orm?


I'm trying to set up a users table with node-orm, and I want to define password & passwordConfirmation as virtual properties (i.e.: not saved, just used for validation & computation) as well as encryptedPassword, which actually gets saved to the DB. As far as I can tell, this doesn't seem to be built into the package.

As a workaround, I'm trying to use Object.defineProperties, but I'm getting nowhere. Here's the relevant code I've got so far.

var User = db.define('user', {
  id                : { type: 'serial', key: true },
  email             : { type: 'text', required: true, unique: true },
  encryptedPassword : { type: 'text', required: true, mapsTo: 'encrypted_password' }
}, {
  hooks: {
    beforeValidation: function (next) {
      this.encryptPassword(function (err, hash) {
        if (err) return next(err);

        this.encryptedPassword = hash;
        next();
      }.bind(this));
    }
  },

  validations: {
    password: [
      orm.enforce.security.password('6', 'must be 6+ characters')
    ],
    passwordConfirmation: [
      orm.enforce.equalToProperty('password', 'does not match password')
    ]
  },

  methods: {
    encryptPassword: function (callback) {
      bcrypt.hash(this.password, config.server.salt, callback);
    }
  }
});

Object.defineProperties(User.prototype, {
  password: {
    writable: true,
    enumerable: true
  },
  passwordConfirmation: {
    writable: true,
    enumerable: true
  }
});

I then try to create a user via:

var params = require('params');  // https://github.com/vesln/params

app.post('/register', function (req, res, next) {
  req.models.user.create([ userParams(req.body) ], function (err, users) {
    // post-create logic here
  });
});

function userParams(body) {
  return params(body).only('email', 'password', 'passwordConfirmation');
};

The problem I'm getting is when the bcrypt.hash method is called, the value of this.password is undefined, which is causing it to throw this error:

{ [Error: data and salt arguments required]
  index: 0,
  instance: 
   { id: [Getter/Setter],
     email: [Getter/Setter],
     encryptedPassword: [Getter/Setter] } }

It seems that the password property is not getting set via my create call, so I'm assuming that it's either because node-orm2 isn't passing custom property values through, or else I've defined the properties wrong (which is likely since I've not really used Object.defineProperties before).

What am I doing wrong, and/or is there another way of doing this that I just can't seem to find in my Googling? Thanks!


Solution

  • After digging through the code, it turns out that node-orm doesn't support this. I opened an issue in hopes of adding it as a feature, but I haven't heard anything from the owner.