Improve rate-limit UX: calm error message and hide resend button during lockout#921
Open
dknauss wants to merge 1 commit into
Open
Improve rate-limit UX: calm error message and hide resend button during lockout#921dknauss wants to merge 1 commit into
dknauss wants to merge 1 commit into
Conversation
|
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. |
This was referenced Jul 3, 2026
dknauss
added a commit
to dknauss/two-factor
that referenced
this pull request
Jul 3, 2026
Seeded demo: 4 failed verification attempts 1 second ago, shows the rate-limit error message in context. Landing page: /wp-login.php?action=two_factor_demo Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…n during lockout Addresses WordPress#918 and WordPress#920. The rate-limit error message previously read "ERROR: Too many invalid verification codes... This limit protects your account against automated attacks." For a legitimate user who mistyped their code, this is alarming and inaccurate. Replaced with a calm, actionable message that tells the user to wait and reload. The email provider's authentication_page() now checks is_user_rate_limited() before rendering the Resend Code button or the "A verification code has been sent" prompt. Showing an interactive resend button during a lockout misled users into thinking it would work; clicking it only returned the rate-limit error again. The button is hidden until the lockout expires. The rate-limit check in authentication_page() also prevents token regeneration while locked out, which complements the existing test added in the rate-limit gate PR.
dknauss
force-pushed
the
ux/rate-limit-messaging
branch
2 times, most recently
from
July 10, 2026 01:12
d95103e to
b6aafe6
Compare
7 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Companion to PR #917. Addresses #918 and #920.
What changed
Error message wording (
class-two-factor-core.php)Before:
After:
The old message used an
ERROR:severity prefix appropriate for system failures, not a temporary delay. "Automated attacks" frames a lockout caused by mistyped codes as a security incident, which is alarming and inaccurate for the legitimate user almost always reading it. The new message is calm, drops the attack framing, and tells the user what to do (wait and reload).Resend Code button (
providers/class-two-factor-email.php)authentication_page()now checksTwo_Factor_Core::is_user_rate_limited()before rendering the resend button and the "A verification code has been sent" prompt. While rate-limited, both are suppressed.Showing an interactive resend button during a lockout implied it would work. Clicking it only returned the same rate-limit error. The button reappears normally once the lockout expires.
The rate-limit check in
authentication_page()also prevents token regeneration while locked out — a user without a token will not receive a new email until the lockout expires and they reload.Tests
Three new tests, all passing:
test_rate_limit_error_message_is_calm_and_actionable— asserts noERROR:prefix and no "automated attacks"test_authentication_page_hides_resend_button_when_rate_limited— assertsINPUT_NAME_RESEND_CODEabsent from outputtest_authentication_page_does_not_send_email_when_rate_limited_and_no_token— asserts no email sent when called without a token during lockoutNot addressed here
Issue #919 (the "if this wasn't you, reset your password" warning that addresses two mutually exclusive audiences) is a separate concern affecting all providers, handled in PR #922.
Closes #918
Closes #920
Try it in Playground
Try this change in WordPress Playground — boots a locked-out 2FA login showing the calm rate-limit message with the Resend button suppressed.