Magento – Password Strength Meter – Uncaught TypeError: Cannot read property ‘toLowerCase’ of undefined

change-passworderrorjavascriptmagento2

I have an issue where the password strength meter on the reset password page isn't working and just says "Password Strength: No Password".

I receive the following console error when I enter text into the password input.

Uncaught TypeError: Cannot read property 'toLowerCase' of undefined

I haven't edited the reset password template.

Would anyone be able to advise why I receive this error and how I can resolve so that the password strength meter works?

The error appears within password-strength-indicator.js

_calculateStrength: function () {
    var password = this._getPassword(),
        isEmpty = password.length === 0,
        zxcvbnScore,
        displayScore,
        isValid;

    // Display score is based on combination of whether password is empty, valid, and zxcvbn strength
    if (isEmpty) {
        displayScore = 0;
    } else {
        this.options.cache.input.rules('add', {
            'password-not-equal-to-user-name': this.options.cache.email.val()
        });

        if (password.toLowerCase() === this.options.cache.email.val().toLowerCase()) {
            displayScore = 1;
        } else {
            isValid = $.validator.validateSingleElement(this.options.cache.input);
            zxcvbnScore = zxcvbn(password).score;
            displayScore = isValid ? zxcvbnScore : 1;
        }
    }

    // Update label
    this._displayStrength(displayScore);
},

Best Answer

The error that you have with this script is because the reset password page does not contain a field for the email which is being compared to the value of the password every time you type with this line: password.toLowerCase() === this.options.cache.email.val().toLowerCase()

The way around it is to extend the function in your theme and check that an email field exists on the page before comparing its value.

I've written the following functions in my theme extension to fix this issue:

_calculateStrength: function () {
        var password = this._getPassword(),
            isEmpty = password.length === 0,
            displayScore;                

        // Display score is based on combination of whether password is empty, valid, and zxcvbn strength
        if (isEmpty) {
            displayScore = 0;
            this._displayStrength(displayScore);
        } else if (this.options.cache.email.length) {

            this.options.cache.input.rules('add', {
                'password-not-equal-to-user-name': this.options.cache.email.val()
            });

            if (password.toLowerCase() === this.options.cache.email.val().toLowerCase()) {
                displayScore = 1;
                this._displayStrength(displayScore);
            }else{
                this._calculateScore(password);    
            }

        }else{
            this._calculateScore(password);
        }

    },

    _calculateScore: function (password) {
        var isValid,
            zxcvbnScore,
            displayScore;

        isValid = $.validator.validateSingleElement(this.options.cache.input);
        zxcvbnScore = zxcvbn(password).score;
        displayScore = isValid ? zxcvbnScore : 1;

        this._displayStrength(displayScore);
    }

Hope this helps anybody who encounters the same issue,