sails: Trying to get model validation messages to NOT include the failing data

My use case is user passwords.

I have added some custom validations, as documented here: http://sailsjs.org/documentation/concepts/models-and-orm/validations in the User model:

types: {
    hasUpperCase: function(s) { return /[A-Z]/.test(s) },
    hasLowerCase: function(s) { return /[a-z]/.test(s) },
    hasNumber: function(s) { return /\d/.test(s) },
    notGuessable: function(s) { return (PasswordService.strength(s).score > 2) }
},

And the password field definition:

password: {
  type: 'string',
  columnName: 'encrypted_password',
  minLength: 8,
  maxLength: 128,
  required: true,
  hasUpperCase: true,
  hasLowerCase: true,
  hasNumber: true,
  notGuessable: true
},

I’d like to be able to specify somehow that validation messages should redact the actual password that the user tried to set.

For example, a User.create() with the password “abc” yields this error:

{"error":"E_VALIDATION",
    "status":400,
    "summary":"1 attribute is invalid",
    "model":"User",
    "invalidAttributes":{
        "password":[
            {"rule":"minLength","message":"\"minLength\" validation rule failed for input: 'abc'"},
            {"rule":"hasUpperCase","message":"\"hasUpperCase\" validation rule failed for input: 'abc'"},
            {"rule":"hasNumber","message":"\"hasNumber\" validation rule failed for input: 'abc'"},
            {"rule":"notGuessable","message":"\"notGuessable\" validation rule failed for input: 'abc'"}
        ]
    }
}

The problem is that the error messages all include the bad (failing) password: “abc”

I have not figured out an elegant way to fix this, since the message is set in the matchRule.js file in the project’s node_modules/sails/node_modules/anchor/lib/match/matchRule.js

Any suggestions?

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 15 (8 by maintainers)

Most upvoted comments

@ksylvan Great question!

A couple of years ago I probably would have told you something like:

Promises, promises. Historically the Node community has been rather divided on the dichotomy, but I believe Ryan Dahl et al made the right decision to demonstrate only callback usage within examples in the official documentation for Node core. We should follow his example.”

But since then, I’ve learned a lot from reading issues, SO questions, and tutorials about promises in Sails, using them myself (particularly in Angular and JQuery), and watching other developers on our team. My opinion has changed somewhat.

I have no problem with promises (in some cases I use them too). I’m really fond of the way they allow you to assign separate scopes for the various parallel universes that could exist after an asynchronous function runs. I don’t think promises truly solve the problem of implementing asynchronous versions of return/try/catch/finally as a language feature yet, but I’m a big fan of the motivations, and the related standardization efforts-- frankly, anything with the mission of improving the UX of building stuff with JavaScript is awesome.

However, I don’t think it’s productive for people to learn about promises before or instead of learning about callbacks. I’ve found that learning from the beginning with promises rather than callbacks risks a kind of “shallow” understanding of asynchronous flow control that can eventually dry up (if you’ve ever read His Dark Materials, think of the moment when Lyra realizes she is no longer able to read the alethiometer).

In other words, if I’m helping a developer get started with intermediate-to-advanced JavaScript, and there’s only time to learn one or the other, I’d much rather she take that time to obtain a true understanding of callbacks and the event loop. If you understand callbacks, then understanding promises down the road is as easy as trying to write your own promise library, which you can do in a couple of (albeit painful) hours. But if you start with promises, you may or may not have a true understanding of callbacks, and that can come back to bite you; e.g. when you throw an error inside of a vanilla setTimeout() callback, or when you up inheriting code which uses a promise library with nonstandard syntax (think of $.ajax vs. angular.http).

So to sum up, there’s a reason why we support promises in Waterline, and I’m happy to do anything I can to support folks who like to use them in their Sails apps. I just think we’re best served using traditional callbacks in examples, tutorials, and documentation – unless of course it’s a tutorial about using promises 😃

How do I get the exact model fields that failed validation? UsageError that is passed to callback gives a plain text describing errors but fields and actual errors are getting lost in waterline/utils/query/forge-stage-two-query.js.