Ticket #16470: 16470.diff
File 16470.diff, 13.8 KB (added by , 6 years ago) |
---|
-
src/wp-admin/includes/admin-filters.php
102 102 103 103 add_action( 'profile_update', 'default_password_nag_edit_user', 10, 2 ); 104 104 105 add_action( 'personal_options_update', 'send_confirmation_on_profile_email' ); 106 105 107 // Update hooks. 106 108 add_action( 'load-plugins.php', 'wp_plugin_update_rows', 20 ); // After wp_update_plugins() is called. 107 109 add_action( 'load-themes.php', 'wp_theme_update_rows', 20 ); // After wp_update_themes() is called. -
src/wp-admin/includes/ms-admin-filters.php
18 18 19 19 add_action( 'add_option_new_admin_email', 'update_option_new_admin_email', 10, 2 ); 20 20 21 add_action( 'personal_options_update', 'send_confirmation_on_profile_email' );22 23 21 add_action( 'update_option_new_admin_email', 'update_option_new_admin_email', 10, 2 ); 24 22 25 23 // Site Hooks. -
src/wp-admin/includes/ms.php
326 326 } 327 327 328 328 /** 329 * Sends an email when an email address change is requested.330 *331 * @since 3.0.0332 *333 * @global WP_Error $errors WP_Error object.334 * @global wpdb $wpdb WordPress database object.335 */336 function send_confirmation_on_profile_email() {337 global $errors, $wpdb;338 $current_user = wp_get_current_user();339 if ( ! is_object($errors) )340 $errors = new WP_Error();341 342 if ( $current_user->ID != $_POST['user_id'] )343 return false;344 345 if ( $current_user->user_email != $_POST['email'] ) {346 if ( !is_email( $_POST['email'] ) ) {347 $errors->add( 'user_email', __( "<strong>ERROR</strong>: The email address isn’t correct." ), array( 'form-field' => 'email' ) );348 return;349 }350 351 if ( $wpdb->get_var( $wpdb->prepare( "SELECT user_email FROM {$wpdb->users} WHERE user_email=%s", $_POST['email'] ) ) ) {352 $errors->add( 'user_email', __( "<strong>ERROR</strong>: The email address is already used." ), array( 'form-field' => 'email' ) );353 delete_user_meta( $current_user->ID, '_new_email' );354 return;355 }356 357 $hash = md5( $_POST['email'] . time() . mt_rand() );358 $new_user_email = array(359 'hash' => $hash,360 'newemail' => $_POST['email']361 );362 update_user_meta( $current_user->ID, '_new_email', $new_user_email );363 364 $switched_locale = switch_to_locale( get_user_locale() );365 366 /* translators: Do not translate USERNAME, ADMIN_URL, EMAIL, SITENAME, SITEURL: those are placeholders. */367 $email_text = __( 'Howdy ###USERNAME###,368 369 You recently requested to have the email address on your account changed.370 371 If this is correct, please click on the following link to change it:372 ###ADMIN_URL###373 374 You can safely ignore and delete this email if you do not want to375 take this action.376 377 This email has been sent to ###EMAIL###378 379 Regards,380 All at ###SITENAME###381 ###SITEURL###' );382 383 /**384 * Filters the email text sent when a user changes emails.385 *386 * The following strings have a special meaning and will get replaced dynamically:387 * ###USERNAME### The current user's username.388 * ###ADMIN_URL### The link to click on to confirm the email change.389 * ###EMAIL### The new email.390 * ###SITENAME### The name of the site.391 * ###SITEURL### The URL to the site.392 *393 * @since MU394 *395 * @param string $email_text Text in the email.396 * @param string $new_user_email New user email that the current user has changed to.397 */398 $content = apply_filters( 'new_user_email_content', $email_text, $new_user_email );399 400 $content = str_replace( '###USERNAME###', $current_user->user_login, $content );401 $content = str_replace( '###ADMIN_URL###', esc_url( self_admin_url( 'profile.php?newuseremail=' . $hash ) ), $content );402 $content = str_replace( '###EMAIL###', $_POST['email'], $content);403 $content = str_replace( '###SITENAME###', get_site_option( 'site_name' ), $content );404 $content = str_replace( '###SITEURL###', network_home_url(), $content );405 406 wp_mail( $_POST['email'], sprintf( __( '[%s] New Email Address' ), wp_specialchars_decode( get_option( 'blogname' ) ) ), $content );407 $_POST['email'] = $current_user->user_email;408 409 if ( $switched_locale ) {410 restore_previous_locale();411 }412 }413 }414 415 /**416 * Adds an admin notice alerting the user to check for confirmation email417 * after email address change.418 *419 * @since 3.0.0420 *421 * @global string $pagenow422 */423 function new_user_email_admin_notice() {424 global $pagenow;425 if ( 'profile.php' === $pagenow && isset( $_GET['updated'] ) && $email = get_user_meta( get_current_user_id(), '_new_email', true ) ) {426 /* translators: %s: New email address */427 echo '<div class="notice notice-info"><p>' . sprintf( __( 'Your email address has not been updated yet. Please check your inbox at %s for a confirmation email.' ), '<code>' . esc_html( $email['newemail'] ) . '</code>' ) . '</p></div>';428 }429 }430 431 /**432 329 * Check whether a site has used its allotted upload space. 433 330 * 434 331 * @since MU -
src/wp-admin/user-edit.php
82 82 } 83 83 84 84 // Execute confirmed email change. See send_confirmation_on_profile_email(). 85 if ( is_multisite() &&IS_PROFILE_PAGE && isset( $_GET[ 'newuseremail' ] ) && $current_user->ID ) {85 if ( IS_PROFILE_PAGE && isset( $_GET[ 'newuseremail' ] ) && $current_user->ID ) { 86 86 $new_email = get_user_meta( $current_user->ID, '_new_email', true ); 87 87 if ( $new_email && hash_equals( $new_email[ 'hash' ], $_GET[ 'newuseremail' ] ) ) { 88 88 $user = new stdClass; 89 89 $user->ID = $current_user->ID; 90 90 $user->user_email = esc_html( trim( $new_email[ 'newemail' ] ) ); 91 if ( $wpdb->get_var( $wpdb->prepare( "SELECT user_login FROM {$wpdb->signups} WHERE user_login = %s", $current_user->user_login ) ) ) {91 if ( is_multisite() && $wpdb->get_var( $wpdb->prepare( "SELECT user_login FROM {$wpdb->signups} WHERE user_login = %s", $current_user->user_login ) ) ) { 92 92 $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->signups} SET user_email = %s WHERE user_login = %s", $user->user_email, $current_user->user_login ) ); 93 93 } 94 94 wp_update_user( $user ); … … 98 98 } else { 99 99 wp_redirect( add_query_arg( array( 'error' => 'new-email' ), self_admin_url( 'profile.php' ) ) ); 100 100 } 101 } elseif ( is_multisite() &&IS_PROFILE_PAGE && !empty( $_GET['dismiss'] ) && $current_user->ID . '_new_email' === $_GET['dismiss'] ) {101 } elseif ( IS_PROFILE_PAGE && !empty( $_GET['dismiss'] ) && $current_user->ID . '_new_email' === $_GET['dismiss'] ) { 102 102 check_admin_referer( 'dismiss-' . $current_user->ID . '_new_email' ); 103 103 delete_user_meta( $current_user->ID, '_new_email' ); 104 104 wp_redirect( add_query_arg( array('updated' => 'true'), self_admin_url( 'profile.php' ) ) ); -
src/wp-includes/user.php
2531 2531 2532 2532 return $current_user; 2533 2533 } 2534 2535 /** 2536 * Sends an email when an email address change is requested. 2537 * 2538 * @since 3.0.0 2539 * 2540 * @global WP_Error $errors WP_Error object. 2541 * @global wpdb $wpdb WordPress database object. 2542 */ 2543 function send_confirmation_on_profile_email() { 2544 global $errors, $wpdb; 2545 2546 $current_user = wp_get_current_user(); 2547 if ( ! is_object( $errors ) ) { 2548 $errors = new WP_Error(); 2549 } 2550 2551 if ( $current_user->ID != $_POST['user_id'] ) { 2552 return false; 2553 } 2554 2555 if ( $current_user->user_email != $_POST['email'] ) { 2556 if ( ! is_email( $_POST['email'] ) ) { 2557 $errors->add( 'user_email', __( "<strong>ERROR</strong>: The email address isn’t correct." ), array( 'form-field' => 'email' ) ); 2558 2559 return; 2560 } 2561 2562 if ( $wpdb->get_var( $wpdb->prepare( "SELECT user_email FROM {$wpdb->users} WHERE user_email=%s", $_POST['email'] ) ) ) { 2563 $errors->add( 'user_email', __( "<strong>ERROR</strong>: The email address is already used." ), array( 'form-field' => 'email' ) ); 2564 delete_user_meta( $current_user->ID, '_new_email' ); 2565 2566 return; 2567 } 2568 2569 $hash = md5( $_POST['email'] . time() . mt_rand() ); 2570 $new_user_email = array( 2571 'hash' => $hash, 2572 'newemail' => $_POST['email'] 2573 ); 2574 update_user_meta( $current_user->ID, '_new_email', $new_user_email ); 2575 2576 /* translators: Do not translate USERNAME, ADMIN_URL, EMAIL, SITENAME, SITEURL: those are placeholders. */ 2577 $email_text = __( 'Howdy ###USERNAME###, 2578 2579 You recently requested to have the email address on your account changed. 2580 2581 If this is correct, please click on the following link to change it: 2582 ###ADMIN_URL### 2583 2584 You can safely ignore and delete this email if you do not want to 2585 take this action. 2586 2587 This email has been sent to ###EMAIL### 2588 2589 Regards, 2590 All at ###SITENAME### 2591 ###SITEURL###' ); 2592 2593 /** 2594 * Filters the email text sent when a user changes emails. 2595 * 2596 * The following strings have a special meaning and will get replaced dynamically: 2597 * ###USERNAME### The current user's username. 2598 * ###ADMIN_URL### The link to click on to confirm the email change. 2599 * ###EMAIL### The new email. 2600 * ###SITENAME### The name of the site. 2601 * ###SITEURL### The URL to the site. 2602 * 2603 * @since MU 2604 * 2605 * @param string $email_text Text in the email. 2606 * @param string $new_user_email New user email that the current user has changed to. 2607 */ 2608 $content = apply_filters( 'new_user_email_content', $email_text, $new_user_email ); 2609 2610 $content = str_replace( '###USERNAME###', $current_user->user_login, $content ); 2611 $content = str_replace( '###ADMIN_URL###', esc_url( admin_url( 'profile.php?newuseremail=' . $hash ) ), $content ); 2612 $content = str_replace( '###EMAIL###', $_POST['email'], $content ); 2613 $content = str_replace( '###SITENAME###', get_site_option( 'site_name' ), $content ); 2614 $content = str_replace( '###SITEURL###', network_home_url(), $content ); 2615 2616 wp_mail( $_POST['email'], sprintf( __( '[%s] New Email Address' ), wp_specialchars_decode( get_option( 'blogname' ) ) ), $content ); 2617 $_POST['email'] = $current_user->user_email; 2618 } 2619 } 2620 2621 /** 2622 * Adds an admin notice alerting the user to check for confirmation email 2623 * after email address change. 2624 * 2625 * @since 3.0.0 2626 * 2627 * @global string $pagenow 2628 */ 2629 function new_user_email_admin_notice() { 2630 global $pagenow; 2631 if ( 'profile.php' === $pagenow && isset( $_GET['updated'] ) && $email = get_user_meta( get_current_user_id(), '_new_email', true ) ) { 2632 /* translators: %s: New email address */ 2633 echo '<div class="notice notice-info"><p>' . sprintf( __( 'Your email address has not been updated yet. Please check your inbox at %s for a confirmation email.' ), '<code>' . esc_html( $email['newemail'] ) . '</code>' ) . '</p></div>'; 2634 } 2635 } -
tests/phpunit/tests/user.php
1207 1207 function action_check_passwords_blank_pw( $user_login, &$pass1 ) { 1208 1208 $pass1 = ''; 1209 1209 } 1210 1211 /** 1212 * @ticket 16470 1213 */ 1214 function test_send_confirmation_on_profile_email() { 1215 1216 reset_phpmailer_instance(); 1217 $was_confirmation_email_sent = false; 1218 1219 $user_id = wp_insert_user( array( 1220 'user_login' => 'alison', 1221 'user_pass' => 'password', 1222 'user_email' => 'alison@battlefield4.com', 1223 ) ); 1224 1225 $user = new WP_User( $user_id ); 1226 1227 $_POST['email'] = 'alison@battlefield5.com'; 1228 $_POST['user_id'] = $user_id; 1229 1230 wp_set_current_user( $user_id ); 1231 1232 do_action( 'personal_options_update' ); 1233 1234 if ( ! empty( $GLOBALS['phpmailer']->mock_sent ) ) { 1235 $was_confirmation_email_sent = ( isset( $GLOBALS['phpmailer']->mock_sent[0] ) && 'alison@battlefield5.com' == $GLOBALS['phpmailer']->mock_sent[0]['to'][0][0] ); 1236 } 1237 1238 // A confirmation email is sent. 1239 $this->assertTrue( $was_confirmation_email_sent ); 1240 1241 // The new email address gets put into user_meta. 1242 $new_email_meta = get_user_meta( $user_id, '_new_email', true ); 1243 $this->assertEquals( 'alison@battlefield5.com', $new_email_meta['newemail'] ); 1244 1245 // The email address of the user doesn't change. $_POST['email'] should be the email address pre-update. 1246 $this->assertEquals( $_POST['email'], $user->user_email ); 1247 1248 // Once the confirmation link is clicked, the email changes. 1249 // I'm not sure how to load the profile page with the query string so this can be tested. 1250 } 1251 1252 /** 1253 * @ticket 16470 1254 */ 1255 function test_remove_send_confirmation_on_profile_email() { 1256 1257 remove_action( 'personal_options_update', 'send_confirmation_on_profile_email' ); 1258 1259 reset_phpmailer_instance(); 1260 $was_confirmation_email_sent = false; 1261 1262 $user_id = wp_insert_user( array( 1263 'user_login' => 'arthur', 1264 'user_pass' => 'password', 1265 'user_email' => 'arthur@battlefield4.com', 1266 ) ); 1267 1268 $user = new WP_User( $user_id ); 1269 1270 $_POST['email'] = 'arthur@battlefield5.com'; 1271 $_POST['user_id'] = $user_id; 1272 1273 wp_set_current_user( $user_id ); 1274 1275 do_action( 'personal_options_update' ); 1276 1277 if ( ! empty( $GLOBALS['phpmailer']->mock_sent ) ) { 1278 $was_confirmation_email_sent = ( isset( $GLOBALS['phpmailer']->mock_sent[0] ) && 'arthur@battlefield5.com' == $GLOBALS['phpmailer']->mock_sent[0]['to'][0][0] ); 1279 } 1280 1281 // No confirmation email is sent. 1282 $this->assertFalse( $was_confirmation_email_sent ); 1283 1284 // No usermeta is created. 1285 $new_email_meta = get_user_meta( $user_id, '_new_email', true ); 1286 $this->assertEmpty( $new_email_meta ); 1287 1288 // $_POST['email'] should be the email address posted from the form. 1289 $this->assertEquals( $_POST['email'], 'arthur@battlefield5.com' ); 1290 1291 } 1210 1292 }