Search code examples
meteormeteor-accounts

Meteor password validation


I'm struggling to figure out how to make password validation with my user Schema, that's how I've being doing so far:

This is the schema:

Schema = {};
Schema.UserProfile = new SimpleSchema({
  //LOTS OF FIELDS WORKING FINE
});

Schema.User = new SimpleSchema({
    username: {
        type: String,
        optional: true
    },
    emails: {
        type: Array,
    },
    "emails.$": {
        type: Object
    },
    "emails.$.address": {
        type: String,
        regEx: SimpleSchema.RegEx.Email
    },
    "emails.$.verified": {
        type: Boolean
    },
    createdAt: {
        type: Date
    },
    profile: {
        type: Schema.UserProfile,
        label: "Perfil",
        optional: false
    },
    services: {
        type: Object,
        blackbox: true
    },
    "services.$": {
        type: Object,
        blackbox: true
    },
    "services.$.password": {   // IS IT RIGHT?
      type: String,
      label: "Senha",
      min: 8
    },
    roles: {
        type: String,
        optional: true
    }
});

Meteor.users.attachSchema(Schema.User);

And this is how I'm saving:

let company = {};
company = {
  email: $('#email').val(),
  password: $('#password').val(),
  roles: 'company',
  profile: companyProfile
}

Meteor.call('saveUser', company, function(error, result) {
  if ( error ) {
    console.log(error);    
  }
}

 Meteor.methods({
  saveUser: function(data) {
    return Accounts.createUser(data);
  }
});

I'm still a beginner, so I'm probably messing something up here. When I try to create the user, if there is an issue with any of the fields, the validation throws an error as expected. However no error is thrown in case I miss the password, any ideas of what I'm doing wrong here?

------------------------------- UPDATE ----------------------------------

Thanks @aedm for your answer. I really wish I could have something like this to verify the password and password confirmation:

password: {
    type: String,
    label: "Senha",
      min: 8
  },
  password_confirmation: {
    type: String,
    label: "Confirmação de Senha",
    min: 8,
    custom: function () {
      if (this.value !== this.field('password').value) {
        return "passwordMismatch";
      }
    }
  },

I guess it's not possible then, is it?


Solution

  • Meteor only stores a bcrypt hash for the password, it's always longer than 8 characters.

    Instead, your saveUser method should throw an error when the password criteria isn't met.

    Meteor.methods({
      saveUser: function(data) {
        if (data.password.length < 8) throw new Meteor.Error("Password too short");
        return Accounts.createUser(data);
      }
    });
    

    I'd try to avoid defining a schema for users, Meteor handles it pretty well without one, and it's not trivial how to do it properly.