1/** 2 * Debounce function to prevent password checks before the user finishes typing. 3 * 4 * @param func 5 * @param delay 6 * @returns {(function(): void)|*} 7 */ 8const debounce = ( func, delay = 500 ) => { 9 let Timer 10 return function() { 11 const context = this 12 const args = arguments 13 clearTimeout(Timer); 14 Timer = setTimeout(() => 15 func.apply(context, args), delay 16 ) 17 } 18} 19 20/** 21 * Submits a REST API request to check an entered password. 22 * 23 * @param newPass 24 */ 25function checkPassword( newPass ) { 26 const options = {}; 27 28 options.data = { password: newPass }; 29 options.type = 'GET'; 30 31 window.wp.ajax.send( 'sp-is-password-secure', options ) 32 .done( function( response ) { 33 if ( true === response ) { 34 securePasswordDetected(); 35 } else { 36 insecurePasswordDetected(); 37 } 38 } ); 39} 40 41/** 42 * Creates a WordPress admin notice for an insecure password. 43 * 44 * @returns {*} 45 */ 46function insecurePasswordNotice() { 47 const messageText = 'Please choose a different password. This password was found in a database of insecure passwords.'; 48 let insecureNotice; 49 50 if ( document.body.classList.contains( 'login-action-rp' ) ) { 51 insecureNotice = document.createElement( 'p' ); 52 insecureNotice.className = 'message nfd-sp-insecure-password-notice'; 53 insecureNotice.innerHTML = messageText; 54 } else { 55 insecureNotice = document.createElement( 'tr' ); 56 insecureNotice.className = 'form-field nfd-sp-insecure-password-notice'; 57 58 insecureNotice.appendChild( document.createElement( 'th' ) ); 59 insecureNotice.appendChild( document.createElement( 'td' ) ); 60 61 const notice = document.createElement( 'div' ); 62 notice.className = 'notice notice-error error'; 63 notice.innerHTML = '<p>' + messageText + '</p>'; 64 65 insecureNotice.getElementsByTagName( 'td' )[0].appendChild( notice ); 66 } 67 68 return insecureNotice; 69} 70 71/** 72 * Takes appropriate actions when an insecure password is detected. 73 */ 74function insecurePasswordDetected() { 75 hideWeakPasswordOverride(); 76 77 if ( 0 < document.getElementsByClassName('nfd-sp-insecure-password-notice').length ) { 78 return; 79 } 80 81 const notice = insecurePasswordNotice(); 82 const body = document.body; 83 84 if ( body.classList.contains( 'login' ) ) { 85 document.getElementById( 'login' ).insertBefore( notice, document.getElementById( 'resetpassform' ) ); 86 } else if ( body.classList.contains( 'user-new-php' ) ) { 87 document.getElementsByClassName( 'form-table' )[0].firstElementChild.insertBefore( notice, document.getElementsByClassName( 'pw-weak' )[0] ); 88 } else { 89 // Editing a user. 90 document.getElementById( 'password' ).parentNode.insertBefore( notice, document.getElementsByClassName( 'pw-weak' )[0] ); 91 } 92} 93 94/** 95 * Takes appropriate actions when a secure password is entered. 96 */ 97function securePasswordDetected() { 98 const notices = document.getElementsByClassName( 'nfd-sp-insecure-password-notice' ); 99 100 if ( notices.length > 0 ) { 101 Array.prototype.forEach.call( notices, function( element ) { 102 element.remove(); 103 }); 104 } 105} 106 107/** 108 * Handles a keyup event on the password field. 109 * 110 * @param event 111 */ 112function passwordKeyup( event ) { 113 checkPassword( event.target.value ); 114} 115 116/** 117 * Hides the confirm weak password override field. 118 */ 119function hideWeakPasswordOverride() { 120 // Hide the weak password confirmation. User can't save without using a secure password. 121 document.getElementsByClassName( 'pw-weak' )[0].style.display = "none"; 122} 123 124window.addEventListener('load', function () { 125 const passwordField = document.getElementById('pass1'); 126 127 if (passwordField) { 128 passwordField.addEventListener('keyup', debounce(passwordKeyup)); 129 } 130 131 const generatePasswordButtons = document.getElementsByClassName('wp-generate-pw'); 132 133 if (generatePasswordButtons.length > 0) { 134 Array.prototype.forEach.call(generatePasswordButtons, function (element) { 135 /* 136 * When generate password buttons are clicked, it's safe to assume that the returned 137 * password is secure. 138 */ 139 element.addEventListener('click', function () { 140 securePasswordDetected(); 141 }); 142 }); 143 } 144});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.