Users: improve password generation feature.

On the user edit screen improve handling and clarify language: rename the "Generate Password" and "Show password" buttons to "Set New Password". Clicking it always generates a password. Also: improve inline code comments and descriptions.

Props afercia, bookdude13, michaelarestad, pento.
Fixes #42852.


Built from https://develop.svn.wordpress.org/trunk@49248


git-svn-id: http://core.svn.wordpress.org/trunk@49010 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Adam Silverstein 2020-10-20 18:27:13 +00:00
parent 0e85b07bc8
commit daa977c495
9 changed files with 76 additions and 60 deletions

View File

@ -534,6 +534,14 @@ fieldset label,
margin: 0 0 1em; margin: 0 0 1em;
} }
.wp-generate-pw {
margin-top: 1em;
}
.wp-pwd {
margin-top: 1em;
}
#misc-publishing-actions label { #misc-publishing-actions label {
vertical-align: baseline; vertical-align: baseline;
} }

File diff suppressed because one or more lines are too long

View File

@ -533,6 +533,14 @@ fieldset label,
margin: 0 0 1em; margin: 0 0 1em;
} }
.wp-generate-pw {
margin-top: 1em;
}
.wp-pwd {
margin-top: 1em;
}
#misc-publishing-actions label { #misc-publishing-actions label {
vertical-align: baseline; vertical-align: baseline;
} }

File diff suppressed because one or more lines are too long

View File

@ -14,27 +14,30 @@
$toggleButton, $toggleButton,
$submitButtons, $submitButtons,
$submitButton, $submitButton,
currentPass; currentPass,
$passwordWrapper;
function generatePassword() { function generatePassword() {
if ( typeof zxcvbn !== 'function' ) { if ( typeof zxcvbn !== 'function' ) {
setTimeout( generatePassword, 50 ); setTimeout( generatePassword, 50 );
return; return;
} else if ( ! $pass1.val() ) { } else if ( ! $pass1.val() || $passwordWrapper.hasClass( 'is-open' ) ) {
// zxcvbn loaded before user entered password. // zxcvbn loaded before user entered password, or generating new password.
$pass1.val( $pass1.data( 'pw' ) ); $pass1.val( $pass1.data( 'pw' ) );
$pass1.trigger( 'pwupdate' ); $pass1.trigger( 'pwupdate' );
showOrHideWeakPasswordCheckbox(); showOrHideWeakPasswordCheckbox();
} } else {
else {
// zxcvbn loaded after the user entered password, check strength. // zxcvbn loaded after the user entered password, check strength.
check_pass_strength(); check_pass_strength();
showOrHideWeakPasswordCheckbox(); showOrHideWeakPasswordCheckbox();
} }
// Install screen.
if ( 1 !== parseInt( $toggleButton.data( 'start-masked' ), 10 ) ) { if ( 1 !== parseInt( $toggleButton.data( 'start-masked' ), 10 ) ) {
// Show the password not masked if admin_password hasn't been posted yet.
$pass1.attr( 'type', 'text' ); $pass1.attr( 'type', 'text' );
} else { } else {
// Otherwise, mask the password.
$toggleButton.trigger( 'click' ); $toggleButton.trigger( 'click' );
} }
@ -56,6 +59,7 @@
currentPass = $pass1.val(); currentPass = $pass1.val();
// Refresh password strength area.
$pass1.removeClass( 'short bad good strong' ); $pass1.removeClass( 'short bad good strong' );
showOrHideWeakPasswordCheckbox(); showOrHideWeakPasswordCheckbox();
} ); } );
@ -84,18 +88,11 @@
$pass1.attr( 'type', 'password' ); $pass1.attr( 'type', 'password' );
resetToggle( true ); resetToggle( true );
} }
$pass1.focus();
if ( ! _.isUndefined( $pass1[0].setSelectionRange ) ) {
$pass1[0].setSelectionRange( 0, 100 );
}
}); });
} }
function bindPasswordForm() { function bindPasswordForm() {
var $passwordWrapper, var $generateButton,
$generateButton,
$cancelButton; $cancelButton;
$pass1Row = $( '.user-pass1-wrap, .user-pass-wrap' ); $pass1Row = $( '.user-pass1-wrap, .user-pass-wrap' );
@ -123,7 +120,7 @@
$pass1 = $( '#user_pass' ); $pass1 = $( '#user_pass' );
} }
/** /*
* Fix a LastPass mismatch issue, LastPass only changes pass2. * Fix a LastPass mismatch issue, LastPass only changes pass2.
* *
* This fixes the issue by copying any changes from the hidden * This fixes the issue by copying any changes from the hidden
@ -149,57 +146,59 @@
bindToggleButton(); bindToggleButton();
if ( $generateButton.length ) { // Generate the first password and cache it, but don't set it yet.
$passwordWrapper.hide(); wp.ajax.post( 'generate-password' )
} .done( function( data ) {
// Cache password.
$pass1.data( 'pw', data );
} );
$generateButton.show(); $generateButton.show();
$generateButton.on( 'click', function () { $generateButton.on( 'click', function () {
updateLock = true; updateLock = true;
$generateButton.hide(); // Make sure the password fields are shown.
$passwordWrapper.show(); $generateButton.attr( 'aria-expanded', 'true' );
$passwordWrapper
.show()
.addClass( 'is-open' );
// Enable the inputs when showing. // Enable the inputs when showing.
$pass1.attr( 'disabled', false ); $pass1.attr( 'disabled', false );
$pass2.attr( 'disabled', false ); $pass2.attr( 'disabled', false );
if ( $pass1.val().length === 0 ) { // Set the password to the generated value.
generatePassword(); generatePassword();
}
// Show generated password in plaintext by default.
resetToggle ( false );
// Generate the next password and cache.
wp.ajax.post( 'generate-password' )
.done( function( data ) {
$pass1.data( 'pw', data );
} );
} ); } );
$cancelButton = $pass1Row.find( 'button.wp-cancel-pw' ); $cancelButton = $pass1Row.find( 'button.wp-cancel-pw' );
$cancelButton.on( 'click', function () { $cancelButton.on( 'click', function () {
updateLock = false; updateLock = false;
// Clear any entered password.
$pass1.val( '' );
// Generate a new password.
wp.ajax.post( 'generate-password' )
.done( function( data ) {
$pass1.data( 'pw', data );
} );
$generateButton.show().focus();
$passwordWrapper.hide();
$weakRow.hide( 0, function () {
$weakCheckbox.removeProp( 'checked' );
} );
// Disable the inputs when hiding to prevent autofill and submission. // Disable the inputs when hiding to prevent autofill and submission.
$pass1.prop( 'disabled', true ); $pass1.prop( 'disabled', true );
$pass2.prop( 'disabled', true ); $pass2.prop( 'disabled', true );
// Clear password field and update the UI.
$pass1.val( '' ).trigger( 'pwupdate' );
resetToggle( false ); resetToggle( false );
if ( $pass1Row.closest( 'form' ).is( '#your-profile' ) ) { // Hide password controls.
// Clear password field to prevent update. $passwordWrapper
$pass1.val( '' ).trigger( 'pwupdate' ); .hide()
$submitButtons.prop( 'disabled', false ); .removeClass( 'is-open' );
}
// Stop an empty password from being submitted as a change.
$submitButtons.prop( 'disabled', false );
} ); } );
$pass1Row.closest( 'form' ).on( 'submit', function () { $pass1Row.closest( 'form' ).on( 'submit', function () {
@ -399,7 +398,7 @@
window.generatePassword = generatePassword; window.generatePassword = generatePassword;
/* Warn the user if password was generated but not saved */ // Warn the user if password was generated but not saved.
$( window ).on( 'beforeunload', function () { $( window ).on( 'beforeunload', function () {
if ( true === updateLock ) { if ( true === updateLock ) {
return __( 'Your new password has not been saved.' ); return __( 'Your new password has not been saved.' );

File diff suppressed because one or more lines are too long

View File

@ -632,7 +632,7 @@ endif;
<th><label for="pass1"><?php _e( 'New Password' ); ?></label></th> <th><label for="pass1"><?php _e( 'New Password' ); ?></label></th>
<td> <td>
<input class="hidden" value=" " /><!-- #24364 workaround --> <input class="hidden" value=" " /><!-- #24364 workaround -->
<button type="button" class="button wp-generate-pw hide-if-no-js"><?php _e( 'Generate Password' ); ?></button> <button type="button" class="button wp-generate-pw hide-if-no-js" aria-expanded="false"><?php _e( 'Set New Password' ); ?></button>
<div class="wp-pwd hide-if-js"> <div class="wp-pwd hide-if-js">
<span class="password-input-wrapper"> <span class="password-input-wrapper">
<input type="password" name="pass1" id="pass1" class="regular-text" value="" autocomplete="off" data-pw="<?php echo esc_attr( wp_generate_password( 24 ) ); ?>" aria-describedby="pass-strength-result" /> <input type="password" name="pass1" id="pass1" class="regular-text" value="" autocomplete="off" data-pw="<?php echo esc_attr( wp_generate_password( 24 ) ); ?>" aria-describedby="pass-strength-result" />
@ -641,7 +641,7 @@ endif;
<span class="dashicons dashicons-hidden" aria-hidden="true"></span> <span class="dashicons dashicons-hidden" aria-hidden="true"></span>
<span class="text"><?php _e( 'Hide' ); ?></span> <span class="text"><?php _e( 'Hide' ); ?></span>
</button> </button>
<button type="button" class="button wp-cancel-pw hide-if-no-js" data-toggle="0" aria-label="<?php esc_attr_e( 'Cancel password change' ); ?>"> <button type="button" class="button wp-cancel-pw hide-if-no-js" data-toggle="0" aria-label="<?php esc_attr_e( 'Cancel' ); ?>">
<span class="dashicons dashicons-no" aria-hidden="true"></span> <span class="dashicons dashicons-no" aria-hidden="true"></span>
<span class="text"><?php _e( 'Cancel' ); ?></span> <span class="text"><?php _e( 'Cancel' ); ?></span>
</button> </button>
@ -652,8 +652,12 @@ endif;
<tr class="user-pass2-wrap hide-if-js"> <tr class="user-pass2-wrap hide-if-js">
<th scope="row"><label for="pass2"><?php _e( 'Repeat New Password' ); ?></label></th> <th scope="row"><label for="pass2"><?php _e( 'Repeat New Password' ); ?></label></th>
<td> <td>
<input name="pass2" type="password" id="pass2" class="regular-text" value="" autocomplete="off" /> <input name="pass2" type="password" id="pass2" class="regular-text" value="" autocomplete="off" aria-describedby="pass2-desc" />
<p class="description"><?php _e( 'Type your new password again.' ); ?></p> <?php if ( IS_PROFILE_PAGE ) : ?>
<p class="description" id="pass2-desc"><?php _e( 'Type your new password again.' ); ?></p>
<?php else : ?>
<p class="description" id="pass2-desc"><?php _e( 'Type the new password again.' ); ?></p>
<?php endif; ?>
</td> </td>
</tr> </tr>
<tr class="pw-weak"> <tr class="pw-weak">
@ -661,7 +665,7 @@ endif;
<td> <td>
<label> <label>
<input type="checkbox" name="pw_weak" class="pw-checkbox" /> <input type="checkbox" name="pw_weak" class="pw-checkbox" />
<span id="pw-weak-text-label"><?php _e( 'Confirm use of potentially weak password' ); ?></span> <span id="pw-weak-text-label"><?php _e( 'Confirm use of weak password' ); ?></span>
</label> </label>
</td> </td>
</tr> </tr>

View File

@ -560,8 +560,8 @@ if ( current_user_can( 'create_users' ) ) {
</th> </th>
<td> <td>
<input class="hidden" value=" " /><!-- #24364 workaround --> <input class="hidden" value=" " /><!-- #24364 workaround -->
<button type="button" class="button wp-generate-pw hide-if-no-js"><?php _e( 'Show password' ); ?></button> <button type="button" class="button wp-generate-pw hide-if-no-js"><?php _e( 'Generate password' ); ?></button>
<div class="wp-pwd hide-if-js"> <div class="wp-pwd">
<?php $initial_password = wp_generate_password( 24 ); ?> <?php $initial_password = wp_generate_password( 24 ); ?>
<span class="password-input-wrapper"> <span class="password-input-wrapper">
<input type="password" name="pass1" id="pass1" class="regular-text" autocomplete="off" data-reveal="1" data-pw="<?php echo esc_attr( $initial_password ); ?>" aria-describedby="pass-strength-result" /> <input type="password" name="pass1" id="pass1" class="regular-text" autocomplete="off" data-reveal="1" data-pw="<?php echo esc_attr( $initial_password ); ?>" aria-describedby="pass-strength-result" />
@ -570,10 +570,6 @@ if ( current_user_can( 'create_users' ) ) {
<span class="dashicons dashicons-hidden" aria-hidden="true"></span> <span class="dashicons dashicons-hidden" aria-hidden="true"></span>
<span class="text"><?php _e( 'Hide' ); ?></span> <span class="text"><?php _e( 'Hide' ); ?></span>
</button> </button>
<button type="button" class="button wp-cancel-pw hide-if-no-js" data-toggle="0" aria-label="<?php esc_attr_e( 'Cancel password change' ); ?>">
<span class="dashicons dashicons-no" aria-hidden="true"></span>
<span class="text"><?php _e( 'Cancel' ); ?></span>
</button>
<div style="display:none" id="pass-strength-result" aria-live="polite"></div> <div style="display:none" id="pass-strength-result" aria-live="polite"></div>
</div> </div>
</td> </td>
@ -581,7 +577,8 @@ if ( current_user_can( 'create_users' ) ) {
<tr class="form-field form-required user-pass2-wrap hide-if-js"> <tr class="form-field form-required user-pass2-wrap hide-if-js">
<th scope="row"><label for="pass2"><?php _e( 'Repeat Password' ); ?> <span class="description"><?php _e( '(required)' ); ?></span></label></th> <th scope="row"><label for="pass2"><?php _e( 'Repeat Password' ); ?> <span class="description"><?php _e( '(required)' ); ?></span></label></th>
<td> <td>
<input name="pass2" type="password" id="pass2" autocomplete="off" /> <input name="pass2" type="password" id="pass2" autocomplete="off" aria-describedby="pass2-desc" />
<p class="description" id="pass2-desc"><?php _e( 'Type the password again.' ); ?></p>
</td> </td>
</tr> </tr>
<tr class="pw-weak"> <tr class="pw-weak">

View File

@ -13,7 +13,7 @@
* *
* @global string $wp_version * @global string $wp_version
*/ */
$wp_version = '5.6-alpha-49247'; $wp_version = '5.6-alpha-49248';
/** /**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema. * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.