12 $weakRow, |
12 $weakRow, |
13 $weakCheckbox, |
13 $weakCheckbox, |
14 $toggleButton, |
14 $toggleButton, |
15 $submitButtons, |
15 $submitButtons, |
16 $submitButton, |
16 $submitButton, |
17 currentPass; |
17 currentPass, |
|
18 $passwordWrapper; |
18 |
19 |
19 function generatePassword() { |
20 function generatePassword() { |
20 if ( typeof zxcvbn !== 'function' ) { |
21 if ( typeof zxcvbn !== 'function' ) { |
21 setTimeout( generatePassword, 50 ); |
22 setTimeout( generatePassword, 50 ); |
22 return; |
23 return; |
23 } else if ( ! $pass1.val() ) { |
24 } else if ( ! $pass1.val() || $passwordWrapper.hasClass( 'is-open' ) ) { |
24 // zxcvbn loaded before user entered password. |
25 // zxcvbn loaded before user entered password, or generating new password. |
25 $pass1.val( $pass1.data( 'pw' ) ); |
26 $pass1.val( $pass1.data( 'pw' ) ); |
26 $pass1.trigger( 'pwupdate' ); |
27 $pass1.trigger( 'pwupdate' ); |
27 showOrHideWeakPasswordCheckbox(); |
28 showOrHideWeakPasswordCheckbox(); |
28 } |
29 } else { |
29 else { |
|
30 // zxcvbn loaded after the user entered password, check strength. |
30 // zxcvbn loaded after the user entered password, check strength. |
31 check_pass_strength(); |
31 check_pass_strength(); |
32 showOrHideWeakPasswordCheckbox(); |
32 showOrHideWeakPasswordCheckbox(); |
33 } |
33 } |
34 |
34 |
|
35 // Install screen. |
35 if ( 1 !== parseInt( $toggleButton.data( 'start-masked' ), 10 ) ) { |
36 if ( 1 !== parseInt( $toggleButton.data( 'start-masked' ), 10 ) ) { |
|
37 // Show the password not masked if admin_password hasn't been posted yet. |
36 $pass1.attr( 'type', 'text' ); |
38 $pass1.attr( 'type', 'text' ); |
37 } else { |
39 } else { |
|
40 // Otherwise, mask the password. |
38 $toggleButton.trigger( 'click' ); |
41 $toggleButton.trigger( 'click' ); |
39 } |
42 } |
40 |
43 |
41 // Once zxcvbn loads, passwords strength is known. |
44 // Once zxcvbn loads, passwords strength is known. |
42 $( '#pw-weak-text-label' ).text( __( 'Confirm use of weak password' ) ); |
45 $( '#pw-weak-text-label' ).text( __( 'Confirm use of weak password' ) ); |
82 resetToggle( false ); |
86 resetToggle( false ); |
83 } else { |
87 } else { |
84 $pass1.attr( 'type', 'password' ); |
88 $pass1.attr( 'type', 'password' ); |
85 resetToggle( true ); |
89 resetToggle( true ); |
86 } |
90 } |
87 |
91 }); |
88 $pass1.focus(); |
92 } |
89 |
93 |
90 if ( ! _.isUndefined( $pass1[0].setSelectionRange ) ) { |
94 /** |
91 $pass1[0].setSelectionRange( 0, 100 ); |
95 * Handle the password reset button. Sets up an ajax callback to trigger sending |
92 } |
96 * a password reset email. |
93 }); |
97 */ |
|
98 function bindPasswordRestLink() { |
|
99 $( '#generate-reset-link' ).on( 'click', function() { |
|
100 var $this = $(this), |
|
101 data = { |
|
102 'user_id': userProfileL10n.user_id, // The user to send a reset to. |
|
103 'nonce': userProfileL10n.nonce // Nonce to validate the action. |
|
104 }; |
|
105 |
|
106 // Remove any previous error messages. |
|
107 $this.parent().find( '.notice-error' ).remove(); |
|
108 |
|
109 // Send the reset request. |
|
110 var resetAction = wp.ajax.post( 'send-password-reset', data ); |
|
111 |
|
112 // Handle reset success. |
|
113 resetAction.done( function( response ) { |
|
114 addInlineNotice( $this, true, response ); |
|
115 } ); |
|
116 |
|
117 // Handle reset failure. |
|
118 resetAction.fail( function( response ) { |
|
119 addInlineNotice( $this, false, response ); |
|
120 } ); |
|
121 |
|
122 }); |
|
123 |
|
124 } |
|
125 |
|
126 /** |
|
127 * Helper function to insert an inline notice of success or failure. |
|
128 * |
|
129 * @param {jQuery Object} $this The button element: the message will be inserted |
|
130 * above this button |
|
131 * @param {bool} success Whether the message is a success message. |
|
132 * @param {string} message The message to insert. |
|
133 */ |
|
134 function addInlineNotice( $this, success, message ) { |
|
135 var resultDiv = $( '<div />' ); |
|
136 |
|
137 // Set up the notice div. |
|
138 resultDiv.addClass( 'notice inline' ); |
|
139 |
|
140 // Add a class indicating success or failure. |
|
141 resultDiv.addClass( 'notice-' + ( success ? 'success' : 'error' ) ); |
|
142 |
|
143 // Add the message, wrapping in a p tag, with a fadein to highlight each message. |
|
144 resultDiv.text( $( $.parseHTML( message ) ).text() ).wrapInner( '<p />'); |
|
145 |
|
146 // Disable the button when the callback has succeeded. |
|
147 $this.prop( 'disabled', success ); |
|
148 |
|
149 // Remove any previous notices. |
|
150 $this.siblings( '.notice' ).remove(); |
|
151 |
|
152 // Insert the notice. |
|
153 $this.before( resultDiv ); |
94 } |
154 } |
95 |
155 |
96 function bindPasswordForm() { |
156 function bindPasswordForm() { |
97 var $passwordWrapper, |
157 var $generateButton, |
98 $generateButton, |
|
99 $cancelButton; |
158 $cancelButton; |
100 |
159 |
101 $pass1Row = $( '.user-pass1-wrap, .user-pass-wrap' ); |
160 $pass1Row = $( '.user-pass1-wrap, .user-pass-wrap, .reset-pass-submit' ); |
102 |
161 |
103 // Hide the confirm password field when JavaScript support is enabled. |
162 // Hide the confirm password field when JavaScript support is enabled. |
104 $('.user-pass2-wrap').hide(); |
163 $('.user-pass2-wrap').hide(); |
105 |
164 |
106 $submitButton = $( '#submit, #wp-submit' ).on( 'click', function () { |
165 $submitButton = $( '#submit, #wp-submit' ).on( 'click', function () { |
109 |
168 |
110 $submitButtons = $submitButton.add( ' #createusersub' ); |
169 $submitButtons = $submitButton.add( ' #createusersub' ); |
111 |
170 |
112 $weakRow = $( '.pw-weak' ); |
171 $weakRow = $( '.pw-weak' ); |
113 $weakCheckbox = $weakRow.find( '.pw-checkbox' ); |
172 $weakCheckbox = $weakRow.find( '.pw-checkbox' ); |
114 $weakCheckbox.change( function() { |
173 $weakCheckbox.on( 'change', function() { |
115 $submitButtons.prop( 'disabled', ! $weakCheckbox.prop( 'checked' ) ); |
174 $submitButtons.prop( 'disabled', ! $weakCheckbox.prop( 'checked' ) ); |
116 } ); |
175 } ); |
117 |
176 |
118 $pass1 = $('#pass1'); |
177 $pass1 = $('#pass1'); |
119 if ( $pass1.length ) { |
178 if ( $pass1.length ) { |
147 $passwordWrapper = $pass1Row.find( '.wp-pwd' ); |
206 $passwordWrapper = $pass1Row.find( '.wp-pwd' ); |
148 $generateButton = $pass1Row.find( 'button.wp-generate-pw' ); |
207 $generateButton = $pass1Row.find( 'button.wp-generate-pw' ); |
149 |
208 |
150 bindToggleButton(); |
209 bindToggleButton(); |
151 |
210 |
152 if ( $generateButton.length ) { |
|
153 $passwordWrapper.hide(); |
|
154 } |
|
155 |
|
156 $generateButton.show(); |
211 $generateButton.show(); |
157 $generateButton.on( 'click', function () { |
212 $generateButton.on( 'click', function () { |
158 updateLock = true; |
213 updateLock = true; |
159 |
214 |
160 $generateButton.hide(); |
215 // Make sure the password fields are shown. |
161 $passwordWrapper.show(); |
216 $generateButton.attr( 'aria-expanded', 'true' ); |
|
217 $passwordWrapper |
|
218 .show() |
|
219 .addClass( 'is-open' ); |
162 |
220 |
163 // Enable the inputs when showing. |
221 // Enable the inputs when showing. |
164 $pass1.attr( 'disabled', false ); |
222 $pass1.attr( 'disabled', false ); |
165 $pass2.attr( 'disabled', false ); |
223 $pass2.attr( 'disabled', false ); |
166 |
224 |
167 if ( $pass1.val().length === 0 ) { |
225 // Set the password to the generated value. |
168 generatePassword(); |
226 generatePassword(); |
169 } |
227 |
170 } ); |
228 // Show generated password in plaintext by default. |
171 |
229 resetToggle ( false ); |
172 $cancelButton = $pass1Row.find( 'button.wp-cancel-pw' ); |
230 |
173 $cancelButton.on( 'click', function () { |
231 // Generate the next password and cache. |
174 updateLock = false; |
|
175 |
|
176 // Clear any entered password. |
|
177 $pass1.val( '' ); |
|
178 |
|
179 // Generate a new password. |
|
180 wp.ajax.post( 'generate-password' ) |
232 wp.ajax.post( 'generate-password' ) |
181 .done( function( data ) { |
233 .done( function( data ) { |
182 $pass1.data( 'pw', data ); |
234 $pass1.data( 'pw', data ); |
183 } ); |
235 } ); |
184 |
236 } ); |
185 $generateButton.show().focus(); |
237 |
186 $passwordWrapper.hide(); |
238 $cancelButton = $pass1Row.find( 'button.wp-cancel-pw' ); |
187 |
239 $cancelButton.on( 'click', function () { |
188 $weakRow.hide( 0, function () { |
240 updateLock = false; |
189 $weakCheckbox.removeProp( 'checked' ); |
|
190 } ); |
|
191 |
241 |
192 // Disable the inputs when hiding to prevent autofill and submission. |
242 // Disable the inputs when hiding to prevent autofill and submission. |
193 $pass1.prop( 'disabled', true ); |
243 $pass1.prop( 'disabled', true ); |
194 $pass2.prop( 'disabled', true ); |
244 $pass2.prop( 'disabled', true ); |
195 |
245 |
|
246 // Clear password field and update the UI. |
|
247 $pass1.val( '' ).trigger( 'pwupdate' ); |
196 resetToggle( false ); |
248 resetToggle( false ); |
197 |
249 |
198 if ( $pass1Row.closest( 'form' ).is( '#your-profile' ) ) { |
250 // Hide password controls. |
199 // Clear password field to prevent update. |
251 $passwordWrapper |
200 $pass1.val( '' ).trigger( 'pwupdate' ); |
252 .hide() |
201 $submitButtons.prop( 'disabled', false ); |
253 .removeClass( 'is-open' ); |
202 } |
254 |
|
255 // Stop an empty password from being submitted as a change. |
|
256 $submitButtons.prop( 'disabled', false ); |
203 } ); |
257 } ); |
204 |
258 |
205 $pass1Row.closest( 'form' ).on( 'submit', function () { |
259 $pass1Row.closest( 'form' ).on( 'submit', function () { |
206 updateLock = false; |
260 updateLock = false; |
207 |
261 |
213 |
267 |
214 function check_pass_strength() { |
268 function check_pass_strength() { |
215 var pass1 = $('#pass1').val(), strength; |
269 var pass1 = $('#pass1').val(), strength; |
216 |
270 |
217 $('#pass-strength-result').removeClass('short bad good strong empty'); |
271 $('#pass-strength-result').removeClass('short bad good strong empty'); |
218 if ( ! pass1 ) { |
272 if ( ! pass1 || '' === pass1.trim() ) { |
219 $( '#pass-strength-result' ).addClass( 'empty' ).html( ' ' ); |
273 $( '#pass-strength-result' ).addClass( 'empty' ).html( ' ' ); |
220 return; |
274 return; |
221 } |
275 } |
222 |
276 |
223 strength = wp.passwordStrength.meter( pass1, wp.passwordStrength.userInputDisallowedList(), pass1 ); |
277 strength = wp.passwordStrength.meter( pass1, wp.passwordStrength.userInputDisallowedList(), pass1 ); |
263 $weakRow.hide(); |
317 $weakRow.hide(); |
264 } |
318 } |
265 } |
319 } |
266 } |
320 } |
267 |
321 |
268 $(document).ready( function() { |
322 $( function() { |
269 var $colorpicker, $stylesheet, user_id, current_user_id, |
323 var $colorpicker, $stylesheet, user_id, current_user_id, |
270 select = $( '#display_name' ), |
324 select = $( '#display_name' ), |
271 current_name = select.val(), |
325 current_name = select.val(), |
272 greeting = $( '#wp-admin-bar-my-account' ).find( '.display-name' ); |
326 greeting = $( '#wp-admin-bar-my-account' ).find( '.display-name' ); |
273 |
327 |
274 $( '#pass1' ).val( '' ).on( 'input' + ' pwupdate', check_pass_strength ); |
328 $( '#pass1' ).val( '' ).on( 'input' + ' pwupdate', check_pass_strength ); |
275 $('#pass-strength-result').show(); |
329 $('#pass-strength-result').show(); |
276 $('.color-palette').click( function() { |
330 $('.color-palette').on( 'click', function() { |
277 $(this).siblings('input[name="admin_color"]').prop('checked', true); |
331 $(this).siblings('input[name="admin_color"]').prop('checked', true); |
278 }); |
332 }); |
279 |
333 |
280 if ( select.length ) { |
334 if ( select.length ) { |
281 $('#first_name, #last_name, #nickname').bind( 'blur.user_profile', function() { |
335 $('#first_name, #last_name, #nickname').on( 'blur.user_profile', function() { |
282 var dub = [], |
336 var dub = [], |
283 inputs = { |
337 inputs = { |
284 display_nickname : $('#nickname').val() || '', |
338 display_nickname : $('#nickname').val() || '', |
285 display_username : $('#user_login').val() || '', |
339 display_username : $('#user_login').val() || '', |
286 display_firstname : $('#first_name').val() || '', |
340 display_firstname : $('#first_name').val() || '', |
397 e.preventDefault(); |
452 e.preventDefault(); |
398 }); |
453 }); |
399 |
454 |
400 window.generatePassword = generatePassword; |
455 window.generatePassword = generatePassword; |
401 |
456 |
402 /* Warn the user if password was generated but not saved */ |
457 // Warn the user if password was generated but not saved. |
403 $( window ).on( 'beforeunload', function () { |
458 $( window ).on( 'beforeunload', function () { |
404 if ( true === updateLock ) { |
459 if ( true === updateLock ) { |
405 return __( 'Your new password has not been saved.' ); |
460 return __( 'Your new password has not been saved.' ); |
406 } |
461 } |
407 } ); |
462 } ); |
408 |
463 |
|
464 /* |
|
465 * We need to generate a password as soon as the Reset Password page is loaded, |
|
466 * to avoid double clicking the button to retrieve the first generated password. |
|
467 * See ticket #39638. |
|
468 */ |
|
469 $( function() { |
|
470 if ( $( '.reset-pass-submit' ).length ) { |
|
471 $( '.reset-pass-submit button.wp-generate-pw' ).trigger( 'click' ); |
|
472 } |
|
473 }); |
|
474 |
409 })(jQuery); |
475 })(jQuery); |