From 1cbbb70a03c5115dba65008299e5163ff2f756e7 Mon Sep 17 00:00:00 2001 From: Mykyta Synelnikov Date: Fri, 11 Oct 2024 18:47:40 +0300 Subject: [PATCH] * added security condition to check that one logged-in user cannot activate another one user via email activation link; * fixed double handler of email activation link (wp_die doesn't stop the script for some reason); * added redirects to login page with error notices instead of wp_die text; --- includes/common/class-users.php | 2 ++ includes/core/class-permalinks.php | 22 +++++++++++----------- includes/core/class-user.php | 2 +- includes/core/um-actions-misc.php | 6 ++++++ 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/includes/common/class-users.php b/includes/common/class-users.php index 4bde40df..9884efa8 100644 --- a/includes/common/class-users.php +++ b/includes/common/class-users.php @@ -279,6 +279,8 @@ class Users { * @param {int} $expiration Expiration timestamp. Since 2.8.7. */ do_action( 'um_after_user_hash_is_changed', $user_id, $hash, $expiration ); + + $this->remove_cache( $user_id ); // Don't remove this line. It's required removing cache duplicate for the force case when re-send activation email. } /** diff --git a/includes/core/class-permalinks.php b/includes/core/class-permalinks.php index 3e494d16..1ce98f72 100644 --- a/includes/core/class-permalinks.php +++ b/includes/core/class-permalinks.php @@ -113,16 +113,24 @@ if ( ! class_exists( 'um\core\Permalinks' ) ) { isset( $_REQUEST['user_id'] ) && is_numeric( $_REQUEST['user_id'] ) ) { // valid token $user_id = absint( $_REQUEST['user_id'] ); + if ( is_user_logged_in() && get_current_user_id() !== $user_id ) { + // Cannot activate another user account. Please log out and try again. + wp_safe_redirect( um_user_profile_url( get_current_user_id() ) ); + exit; + } + delete_option( "um_cache_userdata_{$user_id}" ); $account_secret_hash = get_user_meta( $user_id, 'account_secret_hash', true ); if ( empty( $account_secret_hash ) || strtolower( sanitize_text_field( $_REQUEST['hash'] ) ) !== strtolower( $account_secret_hash ) ) { - wp_die( esc_html__( 'This activation link is expired or have already been used.', 'ultimate-member' ) ); + wp_safe_redirect( add_query_arg( 'err', 'activation_link_used', um_get_core_page( 'login' ) ) ); + exit; } $account_secret_hash_expiry = get_user_meta( $user_id, 'account_secret_hash_expiry', true ); if ( ! empty( $account_secret_hash_expiry ) && time() > $account_secret_hash_expiry ) { - wp_die( esc_html__( 'This activation link is expired.', 'ultimate-member' ) ); + wp_safe_redirect( add_query_arg( 'err', 'activation_link_expired', um_get_core_page( 'login' ) ) ); + exit; } $redirect = um_get_core_page( 'login', 'account_active' ); @@ -141,15 +149,7 @@ if ( ! class_exists( 'um\core\Permalinks' ) ) { // log in automatically $login = ! empty( $user_role_data['login_email_activate'] ); // Role setting "Login user after validating the activation link?" if ( ! is_user_logged_in() && $login ) { - $user = get_userdata( $user_id ); - - // update wp user - wp_set_current_user( $user_id, $user->user_login ); - wp_set_auth_cookie( $user_id ); - - ob_start(); - do_action( 'wp_login', $user->user_login, $user ); - ob_end_clean(); + UM()->user()->auto_login( $user_id ); } /** diff --git a/includes/core/class-user.php b/includes/core/class-user.php index 545d5434..f304d364 100644 --- a/includes/core/class-user.php +++ b/includes/core/class-user.php @@ -1362,7 +1362,7 @@ if ( ! class_exists( 'um\core\User' ) ) { user()->auto_login( 10, true ); ?> * */ - function auto_login( $user_id, $rememberme = 0 ) { + public function auto_login( $user_id, $rememberme = 0 ) { wp_set_current_user( $user_id ); diff --git a/includes/core/um-actions-misc.php b/includes/core/um-actions-misc.php index 9525b5a1..4c49617c 100644 --- a/includes/core/um-actions-misc.php +++ b/includes/core/um-actions-misc.php @@ -176,6 +176,12 @@ function um_add_update_notice( $args ) { case 'invalid_nonce': $err = __( 'An error has been encountered. Probably page was cached. Please try again.', 'ultimate-member' ); break; + case 'activation_link_used': + $err = __( 'This activation link is expired or have already been used.', 'ultimate-member' ); + break; + case 'activation_link_expired': + $err = __( 'This activation link is expired.', 'ultimate-member' ); + break; } } // phpcs:enable WordPress.Security.NonceVerification -- used for echo and already verified here.