From a0ebf0f52a586f6ab276cd468a8adc709b03ed0c Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 4 May 2026 13:44:52 +0200 Subject: [PATCH 1/4] replace wp-login.php to wp_login_url --- class-two-factor-core.php | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/class-two-factor-core.php b/class-two-factor-core.php index d98cbfe6..5d19513b 100644 --- a/class-two-factor-core.php +++ b/class-two-factor-core.php @@ -984,7 +984,9 @@ public static function show_two_factor_login( $user ) { wp_die( esc_html__( 'Failed to create a login nonce.', 'two-factor' ) ); } - $redirect_to = isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : admin_url(); + $redirect_to = isset( $_REQUEST['redirect_to'] ) + ? wp_unslash( $_REQUEST['redirect_to'] ) + : apply_filters( 'login_redirect', admin_url(), '', null ); self::login_html( $user, $login_nonce['key'], $redirect_to ); } @@ -1252,11 +1254,21 @@ public static function login_url( $params = array(), $scheme = 'login' ) { $params = urlencode_deep( $params ); - // Compat: Match WordPress's usage of `site_url( wp-login.php )` by always passing the action if known. - if ( isset( $params['action'] ) ) { - $url = site_url( 'wp-login.php?action=' . $params['action'], $scheme ); - } else { - $url = site_url( 'wp-login.php', $scheme ); + // Use WordPress's own wp_login_url() so that plugins like WPML which + // hook the `login_url` filter can translate or rewrite the URL correctly. + // wp_login_url() calls site_url( 'wp-login.php', $scheme ) internally and + // applies the `login_url` filter — giving multilingual plugins a chance to + // redirect to a translated login page. + $action = isset( $params['action'] ) ? $params['action'] : ''; + $url = wp_login_url( '', false ); + + // Re-apply the scheme since wp_login_url() doesn't expose it as a parameter. + $url = set_url_scheme( $url, $scheme ); + + // Compat: WordPress core passes action directly in the path for certain actions + // (e.g. wp-login.php?action=validate_2fa). Preserve that behaviour. + if ( $action ) { + $url = add_query_arg( 'action', $action, $url ); } if ( $params ) { From d0ea302839fb85cedd248a3f2bcc83e00eaacdd4 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 4 May 2026 22:28:53 +0200 Subject: [PATCH 2/4] Apply suggestions from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- class-two-factor-core.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/class-two-factor-core.php b/class-two-factor-core.php index 5d19513b..8478b7c0 100644 --- a/class-two-factor-core.php +++ b/class-two-factor-core.php @@ -986,7 +986,7 @@ public static function show_two_factor_login( $user ) { $redirect_to = isset( $_REQUEST['redirect_to'] ) ? wp_unslash( $_REQUEST['redirect_to'] ) - : apply_filters( 'login_redirect', admin_url(), '', null ); + : apply_filters( 'login_redirect', admin_url(), '', $user ); self::login_html( $user, $login_nonce['key'], $redirect_to ); } @@ -1256,9 +1256,9 @@ public static function login_url( $params = array(), $scheme = 'login' ) { // Use WordPress's own wp_login_url() so that plugins like WPML which // hook the `login_url` filter can translate or rewrite the URL correctly. - // wp_login_url() calls site_url( 'wp-login.php', $scheme ) internally and - // applies the `login_url` filter — giving multilingual plugins a chance to - // redirect to a translated login page. + // wp_login_url() applies the `login_url` filter, giving multilingual + // plugins a chance to redirect to a translated login page. Any requested + // scheme is applied below with set_url_scheme(). $action = isset( $params['action'] ) ? $params['action'] : ''; $url = wp_login_url( '', false ); From 472230970c63711d3bfb58a21e403f9916016e5c Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 4 May 2026 22:30:37 +0200 Subject: [PATCH 3/4] remove double encoding --- class-two-factor-core.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/class-two-factor-core.php b/class-two-factor-core.php index 8478b7c0..e2ccb062 100644 --- a/class-two-factor-core.php +++ b/class-two-factor-core.php @@ -1252,8 +1252,6 @@ public static function login_url( $params = array(), $scheme = 'login' ) { $params = array(); } - $params = urlencode_deep( $params ); - // Use WordPress's own wp_login_url() so that plugins like WPML which // hook the `login_url` filter can translate or rewrite the URL correctly. // wp_login_url() applies the `login_url` filter, giving multilingual From 4548fafeea787dc2474614642c9571e356f96feb Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 4 May 2026 22:36:11 +0200 Subject: [PATCH 4/4] Apply suggestions from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- class-two-factor-core.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/class-two-factor-core.php b/class-two-factor-core.php index e2ccb062..e78f43c0 100644 --- a/class-two-factor-core.php +++ b/class-two-factor-core.php @@ -1263,8 +1263,8 @@ public static function login_url( $params = array(), $scheme = 'login' ) { // Re-apply the scheme since wp_login_url() doesn't expose it as a parameter. $url = set_url_scheme( $url, $scheme ); - // Compat: WordPress core passes action directly in the path for certain actions - // (e.g. wp-login.php?action=validate_2fa). Preserve that behaviour. + // Compat: WordPress core passes action as a query argument on the login URL + // for certain actions (e.g. wp-login.php?action=validate_2fa). Preserve that behaviour. if ( $action ) { $url = add_query_arg( 'action', $action, $url ); }