-
Notifications
You must be signed in to change notification settings - Fork 186
fix: reword mixed-audience login failure notice to be informational #922
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 3 commits
2cb9233
907c16e
b294cb0
ad1ea7f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -808,9 +808,10 @@ public function test_maybe_show_last_login_failure_notice() { | |
| $contents = ob_get_clean(); | ||
|
|
||
| $this->assertNotEmpty( $contents ); | ||
| $this->assertStringNotContainsString( '1 times', $contents ); | ||
| $this->assertStringContainsString( 'attempted to login', $contents ); | ||
| $this->assertStringContainsString( 'without providing a valid two factor token', $contents ); | ||
| // A single failure uses the singular form; assert the plural is absent, since | ||
| // "attempt" alone also matches "attempts". | ||
| $this->assertStringContainsString( '1 failed verification code attempt on this account', $contents ); | ||
| $this->assertStringNotContainsString( 'failed verification code attempts', $contents ); | ||
|
|
||
| // 5 failed login attempts 5 hours ago - User should be informed. | ||
| $five_hours_ago = time() - 5 * HOUR_IN_SECONDS; | ||
|
|
@@ -821,10 +822,31 @@ public function test_maybe_show_last_login_failure_notice() { | |
| $contents = ob_get_clean(); | ||
|
|
||
| $this->assertNotEmpty( $contents ); | ||
| $this->assertStringContainsString( '5 times', $contents ); | ||
| $this->assertStringContainsString( '5 failed verification code attempts on this account', $contents ); | ||
| $this->assertStringContainsString( human_time_diff( $five_hours_ago ), $contents ); | ||
| } | ||
|
|
||
| /** | ||
| * Test that the login failure notice uses calm, informational language. | ||
| * | ||
| * @covers Two_Factor_Core::maybe_show_last_login_failure_notice() | ||
| */ | ||
| public function test_login_failure_notice_language_is_calm_and_informational() { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @dknauss
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right — the test seeded the timestamp a minute back but never checked the rendered output. Added an assertion that the string contains |
||
| $user = $this->get_dummy_user(); | ||
| update_user_meta( $user->ID, Two_Factor_Core::USER_FAILED_LOGIN_ATTEMPTS_KEY, 3 ); | ||
| update_user_meta( $user->ID, Two_Factor_Core::USER_RATE_LIMIT_KEY, time() - MINUTE_IN_SECONDS ); | ||
|
|
||
| ob_start(); | ||
| Two_Factor_Core::maybe_show_last_login_failure_notice( $user ); | ||
| $contents = ob_get_clean(); | ||
|
|
||
| $this->assertStringNotContainsString( 'WARNING', $contents ); | ||
| $this->assertStringNotContainsString( "wasn't you", $contents ); | ||
| $this->assertStringNotContainsString( 'reset your password', $contents ); | ||
| $this->assertStringContainsString( 'failed verification code', $contents ); | ||
| $this->assertStringContainsString( 'review your account security', $contents ); | ||
| } | ||
|
|
||
| /** | ||
| * Test no reset notice when no errors. | ||
| * | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dknauss didnt test it on my side yet - but im not sure how clear "review your account security after logging in" is. Can we be more clear on what we actually would suggest the user?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@masteradhoc Your question sent me back to trace when this notice actually fires, and it turned up a mistake in my own reasoning. (It's quite a confusing trail to keep track of!)
The failed-attempt counter only increments after
verify_login_nonce()passes inprocess_provider()— meaning this screen is only reachable after a correct password submission. So if the account holder didn't make those attempts, someone else submitted their correct password. "Review your account security" wasn't just vague, it was not appropriately flagging the urgency of this situation.The right remedy is a password change, since that invalidates the password the other party (an assumed attacker) already has.
New wording: "If you did not make these attempts, someone else may know your password. Change your password after you log in."
(Deferred to after login because they can't change it mid-flow.) I also corrected the PR description, which had argued this backwards — it claimed a reset "doesn't help when the password is already known," which is exactly wrong. Pushed in ad1ea7f.