5

I'm working on a WordPress website and I'd like to modify the password reset screen /wp-login.php?action=rp. Currently, the password reset screen generates a new password for the user and I want to add a Confirm Password field and make it a required field.

I think I've found the relevant code in the wp-login.php file and it looks like there is a confirm password option but I don't know how to get it to appear.

<form name="resetpassform" id="resetpassform" action="<?php echo esc_url( network_site_url( 'wp-login.php?action=resetpass', 'login_post' ) ); ?>" method="post" autocomplete="off">
<input type="hidden" id="user_login" value="<?php echo esc_attr( $rp_login ); ?>" autocomplete="off" />

<div class="user-pass1-wrap">
    <p>
        <label for="pass1"><?php _e( 'New password' ) ?></label>
    </p>

    <div class="wp-pwd">
        <span class="password-input-wrapper">
            <input type="password" data-reveal="1" data-pw="<?php echo esc_attr( wp_generate_password( 16 ) ); ?>" name="pass1" id="pass1" class="input" size="20" value="" autocomplete="off" aria-describedby="pass-strength-result" />
        </span>
        <div id="pass-strength-result" class="hide-if-no-js" aria-live="polite"><?php _e( 'Strength indicator' ); ?></div>
    </div>
</div>

<p class="user-pass2-wrap">
    <label for="pass2"><?php _e( 'Confirm new password' ) ?></label><br />
    <input type="password" name="pass2" id="pass2" class="input" size="20" value="" autocomplete="off" />
</p>

<p class="description indicator-hint"><?php echo wp_get_password_hint(); ?></p>
<br class="clear" />

<?php
/**
 * Fires following the 'Strength indicator' meter in the user password reset form.
 *
 * @since 3.9.0
 *
 * @param WP_User $user User object of the user whose password is being reset.
 */
do_action( 'resetpass_form', $user );
?>
<input type="hidden" name="rp_key" value="<?php echo esc_attr( $rp_key ); ?>" />
<p class="submit"><input type="submit" name="wp-submit" id="wp-submit" class="button button-primary button-large" value="<?php esc_attr_e('Reset Password'); ?>" /></p>
</form>
2

It's tempting to unhide the pass2 input but that's not enough.

In the file /wp-admin/js/user-profile.js the bindPass1() binds it to pass1 that makes writing to it not possible. The pass2 input is then hidden in bindPasswordForm() with $('.user-pass2-wrap').hide();

We can instead add our own input field to validate the password.

First we add it via the resetpass_form action:

add_action( 'resetpass_form', function( $user )
{ ?> <p class="user-wpse-pass2-wrap">
        <label for="wpse-pass2"><?php _e( 'Confirm new password' ) ?></label><br />
        <input type="password" name="wpse-pass2" id="wpse-pass2" class="input" 
               size="20" value="" autocomplete="off" />
    </p> <?php
} );

Then we use the validate_password_reset hook to validate it:

add_action( 'validate_password_reset', function( $errors )
{
    if ( isset( $_POST['pass1'] ) && $_POST['pass1'] != $_POST['wpse-pass2'] )
        $errors->add( 'password_reset_mismatch', __( 'The passwords do not match.' ) );
} );

This is just using similar code as we have in the wp-login.php file.

This is how it looks in Icelandic, when there's a mismatch:

reset

Plugin

Create the plugin under:

/wp-content/plugins/wpse-confirm-password/wpse-confirm-password.php

and add the following code into that file:

<?php
/**
 * Plugin Name: Confirm New Login Password
 * Plugin URI:  http://wordpress.stackexchange.com/a/262607/26350
 */

add_action( 'resetpass_form', function( $user )
{ ?> <p class="user-wpse-pass2-wrap">
        <label for="wpse-pass2"><?php _e( 'Confirm new password' ) ?></label><br />
        <input type="password" name="wpse-pass2" id="wpse-pass2" class="input" 
               size="20" value="" autocomplete="off" />
    </p> <?php
} );

add_action( 'validate_password_reset', function( $errors )
{
    if ( isset( $_POST['pass1'] ) && $_POST['pass1'] != $_POST['wpse-pass2'] )
        $errors->add( 'password_reset_mismatch', __( 'The passwords do not match.' ) );
} );

Then activate the plugin from the backend as usual.

  • Thanks @birgire this looks great! Just wondering, where does this code get added to the wp-login.php file? Should it be above do_action( 'validate_password_reset', $errors, $user) line 602 or above do_action( 'resetpass_form', $user ) line 650 or somewhere else? – zzMzz Apr 7 '17 at 14:11
  • 1
    I updated the answer on how you can test it as a plugin, but don't modify core files @MikeG – birgire Apr 7 '17 at 14:27
  • Very useful, +1. – Fayaz Apr 7 '17 at 14:40
  • 1
    It'll definitely be useful. In addition to your CODE, I've also added a small modification (to hide password text). I thought of updating your answer, but it would've become too long. – Fayaz Apr 7 '17 at 16:32
  • 1
    good idea ;-) @Fayaz – birgire Apr 7 '17 at 17:01
2

In addition to the very useful Plugin CODE @birgire added in his answer, it may also be useful to hide the Password Text (as you type in the password field) on the password reset page. Since with this CODE we will have Confirm Password field anyway, it doesn't make sense to show the password as you type.

The reason WordPress core doesn't add a Confirm Password field is mainly because WordPress already shows the password text as you type it. Confirm Password field is the replacement for that feature and can be very useful (more secure) when the user is typing in front of someone else.

So, I suggest you add the following CODE in addition to birgire's Plugin CODE:

add_action( 'login_enqueue_scripts', function ()
{
    if ( ! wp_script_is( 'jquery', 'done' ) ) {
        wp_enqueue_script( 'jquery' );
    }
    // this line basically hides the password text
    wp_add_inline_script( 'jquery-migrate', 'jQuery(document).ready(function(){ jQuery( "#pass1" ).data( "reveal", 0 ); });' );
}, 1 );

Of course, in this case WordPress will not auto generate the password for you, because obviously auto generating password & then hiding the password text doesn't make sense, as users will not be able to see it & type it in the Confirm Password field.

Anyways, if you want to use this, then the final Plugin CODE will become:

<?php
/**
 * Plugin Name: Confirm New Login Password
 * Plugin URI:  https://wordpress.stackexchange.com/a/262851/110572
 */

add_action( 'resetpass_form', function( $user )
{ ?> <p class="user-wpse-pass2-wrap">
        <label for="wpse-pass2"><?php _e( 'Confirm new password' ) ?></label><br />
        <input type="password" name="wpse-pass2" id="wpse-pass2" class="input" 
               size="20" value="" autocomplete="off" />
    </p> <?php
} );

add_action( 'validate_password_reset', function( $errors )
{
    if ( isset( $_POST['pass1'] ) && $_POST['pass1'] != $_POST['wpse-pass2'] )
        $errors->add( 'password_reset_mismatch', __( 'The passwords do not match.' ) );
} );

add_action( 'login_enqueue_scripts', function ()
{
    if ( ! wp_script_is( 'jquery', 'done' ) ) {
        wp_enqueue_script( 'jquery' );
    }
    wp_add_inline_script( 'jquery-migrate', 'jQuery(document).ready(function(){ jQuery( "#pass1" ).data( "reveal", 0 ); });' );
}, 1 );
  • Is it possible to add policy about confirm password field like :10 character lenght. 1 uppercase letter, 1 lowcase letter, 1 special character? – sampaii Mar 15 '18 at 15:57
  • @sampaii yes, it's possible. Add the conditions in javascript (either in a new script or in the already enqueued inline script). Then add the same conditions in the validate_password_reset action on PHP side. – Fayaz Mar 16 '18 at 5:03
  • thank you. Is it possible to show me how the code can looks like. I'm not vert confortable with it. Thanks again for you Help. – sampaii Mar 16 '18 at 7:06
  • @sampaii I can't answer in the comment section, also it's not possible to edit the answer as it's not relevant to the original question. It's better if you ask a new question, that way other people will also easily find the answer when they need it. This is how WPSE works. – Fayaz Mar 16 '18 at 8:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.