How do I configure the Auth0 sign up (registration) form to require users to enter their password twice?

147 Views Asked by At

I want my Auth0 registration form (but not the login form) to require users to enter their password twice to confirm they typed it correctly, but the Lock Configuration Options don't include such a feature.

How can I specify that users must enter their password twice when registering?

1

There are 1 best solutions below

0
kmoser On

You can use the additionalSignUpFields feature to include an additional 2nd password field, as demonstrated here in the Branding -> Universal Login page:

additionalSignUpFields: [
  {
    name: "repeat_password",
    placeholder: Repeat Password,          
    type: "password",
    validator: function (repeat_password) {
      const passwordField = document.getElementsByName("password")[0];

      if (passwordField === undefined || passwordField.value !== repeat_password) {
        return {
          valid: false,
          hint: 'Passwords do not match',
        };
      }
      return { valid: true };
    },
  },
],

However, this will cause the user's 2nd password field (repeat_password) to be stored in the user's Auth0 metadata. If this is unacceptably insecure, you can use Javascript to include a 2nd password field which is not part of the additionalSignUpFields:

function validatePassword(e) {
    var pwElmt = document.getElementById('1-password') // Auth0 default password field
    var confirmPwElmt = document.getElementById('confirm-password') // Our 'confirm password' field

    if (pwElmt.value == confirmPwElmt.value) {
        // Passwords match so show submit button:
        pwElmt.style.border = 'none'
        confirmPwElmt.style.border = 'none'
        document.getElementById('1-submit').style.display = 'block'
        return true;
    } else {
        // Passwords don't match so hide submit button:
        pwElmt.style.border = '1px solid red'
        confirmPwElmt.style.border = '1px solid red'
        document.getElementById('1-submit').style.display = 'none'
        return false;
    }
}

var pwTimer = null;
var pwElmt = null;

window.addEventListener('DOMContentLoaded', (event) => {
    console.log('Setting up pwTimer...');
    // Do this repeatedly until the element we want comes into view, i.e. the registration page:
    pwTimer = setInterval(
        function () {
            pwElmt = document.querySelector('.auth0-lock-input-block.auth0-lock-input-fname');
            if (pwElmt) {
                console.log('Got pwElmt!');
                clearInterval(pwTimer);

                // Inject the password confirmation 
                let confirmPasswordHTML = '<div class="auth0-lock-input-block auth0-lock-input-show-password"><div class="auth0-lock-input-block auth0-lock-input-password"><div class="auth0-lock-input-wrap auth0-lock-input-wrap-with-icon"><svg aria-hidden="true" focusable="false" width="11px" height="14px" viewBox="0 0 13 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="auth0-lock-icon auth0-lock-icon-box"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-288.000000, -1508.000000)" fill="#888888"><path d="M299,1523.998 L290,1523.998 C288.896,1523.998 288,1523.102 288,1521.999 L288,1515.999 C288,1514.895 288.896,1513.998 290,1513.998 L290,1513.998 L290,1512.499 C290,1510.015 292.015,1507.999 294.5,1507.999 C296.985,1507.999 299,1510.015 299,1512.499 L299,1513.999 C300.104,1513.999 301,1514.895 301,1515.999 L301,1521.999 C301,1523.103 300.104,1523.998 299,1523.998 L299,1523.998 Z M298,1512.499 C298,1510.566 296.433,1508.999 294.5,1508.999 C292.567,1508.999 291,1510.566 291,1512.499 L291,1513.998 L298,1513.998 L298,1512.499 L298,1512.499 Z M300,1515.999 C300,1515.446 299.552,1514.998 299,1514.998 L290,1514.998 C289.447,1514.998 289,1515.446 289,1515.999 L289,1521.999 C289,1522.551 289.447,1522.998 290,1522.998 L299,1522.998 C299.552,1522.998 300,1522.551 300,1521.999 L300,1515.999 L300,1515.999 Z M294.5,1520.998 C294.224,1520.998 294,1520.774 294,1520.498 L294,1517.498 C294,1517.223 294.224,1516.999 294.5,1516.999 C294.776,1516.999 295,1517.223 295,1517.498 L295,1520.498 C295,1520.774 294.776,1520.998 294.5,1520.998 L294.5,1520.998 Z"></path></g></g></svg><input type="password" id="confirm-password" name="confirm-password" class="auth0-lock-input" autocomplete="off" autocapitalize="none" value="" aria-label="Confirm password" aria-invalid="false" placeholder="confirm your password"></div></div></div>';

                pwElmt.insertAdjacentHTML('beforebegin', confirmPasswordHTML)
                console.log('Injected password confirmation')

                document.getElementById('1-password').addEventListener('input', validatePassword)
                document.getElementById('confirm-password').addEventListener('input', validatePassword)

                // Prevent Enter from submitting the form:
                var authForm = document.querySelector('.auth0-lock-form');
                if (authForm) {
                    authForm.addEventListener('keydown', function (event) {
                        if (event.key === 'Enter' || event.keyCode === 13) {
                            event.preventDefault();
                            return false;
                        }
                    });
                }
            } else {
                console.log('Still waiting for pwElmt...')
            }
        },
        1000 // Every second
    )
});

This uses setInterval() to wait until the Sign Up tab is showing, then injects a 2nd password field after the first one. As the user types into either of the password fields, the validatePassword() function is called which determines whether the passwords match; if so, it removes the red border around the fields and displays the Sign Up button; if not, it adds a red border around the fields and hides the Sign Up button.

It also traps the Enter key to prevent users from submitting the form by hitting Enter. This way, the passwords must match before the form can be submitted.