fix: prevent autofilled TOTP codes from being wiped on login#904
fix: prevent autofilled TOTP codes from being wiped on login#904faisalahammad wants to merge 2 commits into
Conversation
- Removed autocomplete=off from the 2FA login form so browser autofill can reach the per-input one-time-code hints - Added autocomplete=one-time-code to the backup-codes input (TOTP and Email already had it) - Removed two-factor-login.js registration and enqueues: this script blanked the authcode value 200ms after load, destroying any code autofilled by Apple Passwords or Google Password Manager - Rewrote authcode space-insertion logic to be stateless: deriving midpoint from the current value (not a flag) so autofilled codes arriving in a single input event are handled correctly Fixes WordPress#880
|
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. |
There was a problem hiding this comment.
Pull request overview
This PR addresses issue #880 by making the 2FA login experience compatible with password-manager autofill (notably Apple Passwords) so one-time codes aren’t prevented from autofilling or cleared shortly after page load.
Changes:
- Removes the form-level
autocomplete="off"override so per-inputautocomplete="one-time-code"can work. - Deletes the legacy
two-factor-login.js“blank after 200ms” script and stops enqueuing it from providers. - Updates
two-factor-login-authcode.jsto insert midpoint spacing using value-derived logic that works for autofill/paste as well as manual typing.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
TESTING_INSTRUCTIONS.md |
Adds manual testing steps for reproducing/verifying #880. |
providers/js/two-factor-login.js |
Removes the 200ms field-blanking script that could wipe autofilled codes. |
providers/js/two-factor-login-authcode.js |
Reworks authcode sanitization/spacing logic to be stateless and autofill-friendly. |
providers/class-two-factor-totp.php |
Stops enqueuing the removed blanker script on the TOTP prompt. |
providers/class-two-factor-email.php |
Stops enqueuing the removed blanker script on the Email prompt. |
providers/class-two-factor-backup-codes.php |
Adds autocomplete="one-time-code" to the backup codes input. |
class-two-factor-core.php |
Removes the autocomplete="off" form attribute and unregisters the removed blanker script. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Collapse the ?><?php pair between do_action() and submit_button() in the TOTP authentication_page() template now that wp_enqueue_script no longer sits between them. - Remove TESTING_INSTRUCTIONS.md from the source tree. It was a local manual-QA artifact that should never have been committed. Addresses PR WordPress#904 review feedback from Copilot and masteradhoc. Fixes WordPress#880
|
Pushed 039c5af addressing both review comments:
Verification: PHPUnit 184/184 pass, PHPStan clean, PHPCS clean on the changed file, CodeRabbit 0 findings. Both review threads resolved. @masteradhoc ready for another look when you have time. |
Summary
Apple Passwords and other platform password managers autofill TOTP codes into the 2FA verification field, but three things cause the code to disappear and the form to submit empty: the form has autocomplete="off" (blocking autofill), a 200ms JS timeout blanks the field, and the space-insertion flag doesn't reset when a full code arrives at once.
Fixes #880
Changes
Login form autocomplete
Removed
autocomplete="off"from the validate_2fa_form in class-two-factor-core.php:1130.Why: The form-level override disabled the per-input
autocomplete="one-time-code"hints that TOTP and Email providers already set. Removing it lets password managers deliver codes into the field.Backup codes input
Added
autocomplete="one-time-code"to the backup-codes input (providers/class-two-factor-backup-codes.php:394). TOTP and Email inputs already had this attribute.Dead blanker script removed
Removed
two-factor-login.js(the file) and itswp_register_script/wp_enqueue_scriptcalls across class-two-factor-core.php, the TOTP provider, and the Email provider.Why: This script ran
d.value = ''200ms after page load. It existed to clear+focus the field on render — already empty on load — but it destroyed codes autofilled between page load and the 200ms timer. The backup-codes provider never enqueued it.Authcode JS rewritten
Replaced the stateful
spaceInsertedboolean with value-derived logic.Why: The old flag only reset when the field was cleared. Autofilled codes arriving in one event never triggered the reset path. Now a space is inserted at the midpoint if: the length matches half of expected, digit count matches, and no space already exists. Same effect for manual typing, works for autofill and paste too.
Testing
Test 1: Autofill with TOTP
Test 2: Manual typing still works
Test 3: All providers accept autofilled codes
Build
two-factor-fix-880.zipavailable for manual testing.Verification