Accounts-password difficulties enforcing password strength

I’m building a user registration and password reset interaction with the accounts-password package and having some problems, hoping someone here can help. I’m trying to build the following interaction:

  1. User signs up for an account, they get an email sent to them via Accounts.sendEnrollmentEmail with a link to click to create their password and complete account setup.
  2. When the user enters their new password, I want the server side to validate the password strength (min length, requires at least on special character, etc)
  3. when the password is strong enough and the account is created, the email address for their account completed and marked as verified

Number 2 doesn’t seem possible currently, I’m hoping I’m just misunderstasnding how to use accounts-password. My is the following:

  • For # 2 above, the function Accounts.resetPassword(token, newPassword) with the token the user received in their email is only available on the client. Because of this, it’s impossible to do validation on the new password on the server. Why is this not available on the server as well? It would be great if similar to Accounts.validateNewUser there was a Accounts.validateNewPassword() method, so that I could trust calling Accounts.resetPassword(token, newPassword) from the client will have its password strength enforced.

Hi,

I’m not sure why you are “programming” this yourself. I basically got the interaction you got, without programming anything? I added this code:


AccountsTemplates.removeField('password');                                      // IC153
AccountsTemplates.addField({
    _id: 'password',
    type: 'password',
    placeholder: {
        signUp: "Minimum 8 characters length."
    },
    required: true,
    minLength: 8,
    re: /(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}/,
    errStr: 'Minimum 1 digit, 1 smallcaps letter en 1 caps letter.',
});

to the file: both/accounts/config.js and that did it for me, as far as configuration was concerned. For the rest, it worked as I expected. What exactly are you missing the existing workflow that you feel the need to really program?

regards,

Paul

From what I can tell that relies on Blaze, Im using Vue and don’t want that extra dependency in my bundle. That also appears to only do client side password validation, I’m asking for server side validation. And finally, I want to keep all UI state in Vuex as a central state management solution for consistency, including UI validation errors, which does not work if I use a pre-built UI solution.

Server-side validation requires that you send the requested password as clear-text over the wire, so you have to consider which is the highest risk:

  • as clear text, anyone ‘in-the-middle’ can potentially snoop on the password.
  • client-side validation hashes the password before sending it to the server, so it’s harder for man-in-the-middle attackers to get the original password.

The only risk with client-side validation, is that a user who knows his way around Meteor and JS is able to set a password for himself with less characters than you would prefer. In the end, none of the actual passwords are stored, everything is hashed and bcrypted.

Any password form should be using SSL, so MITM attack isn’t an issue. I just want to enforce strong passwords in a financial application, even if client side validation fails for some reason. But the issue is I can’t do it on the server because the resetPassword(token, new password) with the token from their email is only available on the client

You could implement it yourself: the callback you set on Accounts.onEnrollmentLink on the client gets the token from the email. Make a custom server method you call from the client with the token and the desired password. The server method checks the token from the client with the server’s version ( it is stored in the user’s profile) and validates the password. If all is ok, the server sets Accounts.setPassword, and notifies the client.

What package defines AccountsTemplates?

Hi @mvolkmann,

I’m not sure, but would assume accounts-ui, as that defines the UI for this function.

regards,

Paul

I’ve looked there and also done lots of googling. So far I haven’t found information on how to do this.

I think I got it from here:

and followed the instructions from there…