Skip to content

Keep revalidation on the current site when the login URL is filtered - #1029

Merged
masteradhoc merged 2 commits into
WordPress:masterfrom
obenland:revalidate-current-site
Oct 20, 2026
Merged

masteradhoc merged 2 commits into
WordPress:masterfrom
obenland:revalidate-current-site

Conversation

@obenland

@obenland obenland commented Oct 20, 2026 •

Copy link
Copy Markdown
Member

What?

Follow-up to #1000. Revalidation URLs from Two_Factor_Core::login_url() are built from the current site's wp-login.php again. All other login URLs keep going through wp_login_url().

Why?

#1000 switched login_url() to wp_login_url() so that plugins filtering login_url can rewrite the 2FA URLs (#885). That's right for logging in, but revalidation isn't a login: it confirms a user who is already logged in on the current site, often from an iframe modal.

Sites that move logins to a separate host broke after #1000. WordPress.org, for example, sends every login to login.wordpress.org. The revalidation iframe on other subdomains now loads login.wordpress.org, which is blocked by core's frame-ancestors 'self' header from send_frame_options_header(). Even when the page loads, the form posts to a host whose cookies don't belong to the current site's session.

See https://wordpress.slack.com/archives/C02QB8GMM/p1792530424151129.

How?

  • login_url() uses site_url( 'wp-login.php?action=revalidate_2fa', $scheme ) when the action is revalidate_2fa, and wp_login_url() otherwise.
  • The other params are still added with add_query_arg(). Revalidation URLs therefore match what they were before Use wp_login_url() for login URLs and defer the redirect decision to core logic #1000, e.g. wp-login.php?action=revalidate_2fa&interim-login=1.
  • The action is part of the site_url() path, as in core's own wp-login.php?action=… calls. That lets site_url filters tell the revalidation form apart from the login form.
  • A new test filters login_url to another host. It checks that validate_2fa follows the filter, while revalidate_2fa stays on the site URL and keeps its other params.

Use of AI Tools

AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Opus 5.5
Used for: Investigating the regression, implementation, and test; reviewed by me.

Testing Instructions

  1. npm run env start, then npm test. All tests should pass.
  2. Add a login_url filter that returns a URL on another host.
  3. As a 2FA user whose revalidation window has expired (10 minutes by default), trigger revalidation. The revalidation form should load from and post to the current site's wp-login.php?action=revalidate_2fa.
  4. Log out and log in again. The 2FA login form should follow the filtered login URL.

Changelog Entry

Fixed - Keep two-factor revalidation on the current site when the login URL is filtered to another host.

🤖 Generated with Claude Code

Open WordPress Playground Preview

Revalidation confirms a user who is already logged in to this site, often
from an iframe, so its links no longer follow the login URL filter to another
host. Logins still go through the filtered login URL.
Copilot AI lite review requested due to automatic review settings October 20, 2026 21:35
@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

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 props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: obenland <obenland@git.wordpress.org>
Co-authored-by: masteradhoc <masteradhoc@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

No unresolved review issues remain, and all reviewed changes have regression coverage.

No open issues 🎉

What changed in this PR

Updates 2FA URL generation so revalidation stays on the current site while normal login URLs honor login_url filters.

Changes:

  • Uses site_url() for revalidation URLs.
  • Preserves filtered login behavior for other actions.
  • Adds regression tests for both flows.
File Description
tests/​class-two-factor-core.php Tests filtered login and current-site revalidation behavior.
class-two-factor-core.php Separates revalidation URL generation from normal login URLs.

Review effort: Lite

@masteradhoc

Copy link
Copy Markdown
Collaborator

Thank you @obenland and sorry for the trouble! We'll take a look at it asap and get it merged.

@masteradhoc masteradhoc added this to the 0.18.0 milestone Oct 20, 2026

@masteradhoc masteradhoc left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@masteradhoc
masteradhoc merged commit 9db3a16 into WordPress:master Oct 20, 2026
36 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants