Skip to content

Commit 81633e1

Browse files
authored
Merge pull request #927 from humanmade/backport-922-to-v26-branch
[Backport v26-branch] Remove plaintext passwords from multisite activation flow
2 parents b55f5cb + c3a2b5e commit 81633e1

File tree

1 file changed

+88
-2
lines changed

1 file changed

+88
-2
lines changed

inc/signup_notification/namespace.php

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ function bootstrap() {
2020

2121
add_action( 'after_signup_user', __NAMESPACE__ . '\\altis_signup_user_notification', 10, 4 );
2222
add_action( 'wpmu_activate_user', __NAMESPACE__ . '\\altis_welcome_user_notification', 10, 3 );
23+
24+
// Redirect to password reset after activation (priority 20, after welcome emails at 10).
25+
add_action( 'wpmu_activate_user', __NAMESPACE__ . '\\redirect_to_password_reset', 20, 3 );
26+
add_action( 'wpmu_activate_blog', __NAMESPACE__ . '\\redirect_blog_user_to_password_reset', 20, 5 );
2327
}
2428

2529
/**
@@ -374,7 +378,7 @@ function altis_welcome_notification( $blog_id, $user_id, $password, $title, $met
374378
$welcome_email = str_replace( 'BLOG_TITLE', $title, $welcome_email );
375379
$welcome_email = str_replace( 'BLOG_URL', $url, $welcome_email );
376380
$welcome_email = str_replace( 'USERNAME', $user->user_login, $welcome_email );
377-
$welcome_email = str_replace( 'PASSWORD', $password, $welcome_email );
381+
$welcome_email = str_replace( 'PASSWORD', __( 'Please set your password by visiting the login page.' ), $welcome_email );
378382

379383
/**
380384
* Filters the content of the welcome email sent to the site administrator after site activation.
@@ -483,7 +487,7 @@ function altis_welcome_user_notification( $user_id, $password, $meta = [] ) {
483487
$welcome_email = apply_filters( 'update_welcome_user_email', $welcome_email, $user_id, $password, $meta );
484488
$welcome_email = str_replace( 'SITE_NAME', $current_network->site_name, $welcome_email );
485489
$welcome_email = str_replace( 'USERNAME', $user->user_login, $welcome_email );
486-
$welcome_email = str_replace( 'PASSWORD', $password, $welcome_email );
490+
$welcome_email = str_replace( 'PASSWORD', __( 'Please set your password by visiting the login page.' ), $welcome_email );
487491
$welcome_email = str_replace( 'LOGINLINK', wp_login_url(), $welcome_email );
488492

489493
$admin_email = get_site_option( 'admin_email' );
@@ -522,3 +526,85 @@ function altis_welcome_user_notification( $user_id, $password, $meta = [] ) {
522526

523527
return true;
524528
}
529+
530+
/**
531+
* Redirect a user to the password reset page after account activation.
532+
*
533+
* Fires on `wpmu_activate_user` at priority 20, after the welcome email
534+
* has been sent at priority 10. This prevents the plaintext password from
535+
* being displayed on the wp-activate.php page.
536+
*
537+
* @param int $user_id User ID.
538+
* @param string $password User password.
539+
* @param array $meta Signup meta data.
540+
*/
541+
function redirect_to_password_reset( $user_id, $password, $meta ) {
542+
$user = get_userdata( $user_id );
543+
if ( ! $user ) {
544+
return;
545+
}
546+
547+
$reset_key = get_password_reset_key( $user );
548+
if ( is_wp_error( $reset_key ) ) {
549+
return;
550+
}
551+
552+
$login_url = network_site_url( 'wp-login.php', 'login' );
553+
$redirect_url = add_query_arg( [
554+
'action' => 'rp',
555+
'key' => $reset_key,
556+
'login' => rawurlencode( $user->user_login ),
557+
], $login_url );
558+
559+
// Invalidate the wp-user-signups cache so the admin list table reflects
560+
// the updated activation status. Core's wpmu_activate_signup() updates
561+
// the DB directly but doesn't clean the plugin's object cache.
562+
wp_cache_set( 'last_changed', microtime(), 'signups' );
563+
564+
wp_safe_redirect( $redirect_url );
565+
exit;
566+
}
567+
568+
/**
569+
* Redirect a blog signup user to the password reset page after activation.
570+
*
571+
* Fires on `wpmu_activate_blog` at priority 20, after the welcome email
572+
* has been sent at priority 10. This prevents the plaintext password from
573+
* being displayed on the wp-activate.php page.
574+
*
575+
* @param int $blog_id Blog ID.
576+
* @param int $user_id User ID.
577+
* @param string $password User password.
578+
* @param string $title Site title.
579+
* @param array $meta Signup meta data.
580+
*/
581+
function redirect_blog_user_to_password_reset( $blog_id, $user_id, $password, $title, $meta ) {
582+
$user = get_userdata( $user_id );
583+
if ( ! $user ) {
584+
return;
585+
}
586+
587+
$reset_key = get_password_reset_key( $user );
588+
if ( is_wp_error( $reset_key ) ) {
589+
return;
590+
}
591+
592+
// Use the network login URL rather than the new blog's login URL.
593+
// The password reset key works network-wide, and wp_safe_redirect()
594+
// may reject cross-host redirects to the new blog's subdomain.
595+
$login_url = network_site_url( 'wp-login.php', 'login' );
596+
597+
$redirect_url = add_query_arg( [
598+
'action' => 'rp',
599+
'key' => $reset_key,
600+
'login' => rawurlencode( $user->user_login ),
601+
], $login_url );
602+
603+
// Invalidate the wp-user-signups cache so the admin list table reflects
604+
// the updated activation status. Core's wpmu_activate_signup() updates
605+
// the DB directly but doesn't clean the plugin's object cache.
606+
wp_cache_set( 'last_changed', microtime(), 'signups' );
607+
608+
wp_safe_redirect( $redirect_url );
609+
exit;
610+
}

0 commit comments

Comments
 (0)