replace wp-login.php to wp_login_url#886
Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes multi-domain/multilingual login issues (WPML/Polylang/TranslatePress, mapped domains) by updating Two-Factor’s login URL generation to use WordPress core’s wp_login_url() (so the core login_url filter can rewrite domains correctly) and by routing the default redirect_to through login_redirect.
Changes:
- Update
Two_Factor_Core::login_url()to build URLs starting fromwp_login_url()and then apply the requested scheme/query args. - Update
show_two_factor_login()so the fallback redirect target is derived via thelogin_redirectfilter rather than hardcodedadmin_url().
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
class-two-factor-core.php:1274
- The new behavior of delegating
Two_Factor_Core::login_url()towp_login_url()is important for multilingual/multi-domain setups, but there’s no unit test asserting that the WordPresslogin_urlfilter is actually respected (e.g., by adding a temporarylogin_urlfilter and confirming the returned URL includes the filtered domain/args). Adding a test would help prevent regressions back to manually constructed URLs.
// 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
// 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 );
// 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 ) {
$url = add_query_arg( $params, $url );
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| $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(), '', $user ); |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
What?
Fixes #885
Rewrites
login_url()to delegate to WordPress's nativewp_login_url()instead of constructing URLs directly fromsite_url( 'wp-login.php' ). Also updates theredirect_tofallback inshow_two_factor_login()to go through thelogin_redirectfilter instead of a hardcodedadmin_url().Why?
On WPML multi-domain setups (e.g.
site.com,en.site.com,fr.site.com), users on 0.15.0+ experience either "ERROR: Invalid verification code" on correct TOTP codes, or a session loop where every click after login logs them out again. Downgrading to 0.14.2 resolves both symptoms.The root cause is that
login_url()callssite_url( 'wp-login.php' )directly. WPML (and Polylang, TranslatePress) hook WordPress'slogin_urlfilter to rewrite login URLs per language/domain — but that filter only fires insidewp_login_url(), which this plugin never calls. As a result, the 2FA form action and all redirect URLs point to the wrong domain, breaking nonce validation and session continuity.Reference: https://wordpress.org/support/topic/two-factor-0-14-2-works-0-15-0-doesnt/
How?
No behaviour change on standard installs. WPML, Polylang, TranslatePress, and multisite mapped domains all benefit automatically.
Use of AI Tools
AI assistance: Yes
Tool(s): Claude (Anthropic)
Model(s): Claude Sonnet 4.6
Used for: Identifying root cause, drafting the code change. Final implementation reviewed and tested by me.
Testing Instructions
Standard single-site (regression check)
WPML multi-domain
en.site.com,fr.site.com)en.site.com— confirm the 2FA form action URL stays onen.site.comfr.site.comBackup provider links
domain/language URL
Revalidation
revalidate_2fa)Screenshots or screencast
No UI changes — not applicable.
Changelog Entry
Fixed -
login_url()now delegates towp_login_url()so the WordPresslogin_urlfilter is respected, fixing session loops and invalid verification code errors on WPML and other multi-domain setups.