Skip to content

fix: prevent autofilled TOTP codes from being wiped on login#904

Open
faisalahammad wants to merge 2 commits into
WordPress:masterfrom
faisalahammad:fix/880-autofill-wiped-codes
Open

fix: prevent autofilled TOTP codes from being wiped on login#904
faisalahammad wants to merge 2 commits into
WordPress:masterfrom
faisalahammad:fix/880-autofill-wiped-codes

Conversation

@faisalahammad

@faisalahammad faisalahammad commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

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 its wp_register_script / wp_enqueue_script calls 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 spaceInserted boolean 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

  1. Enable TOTP for test user, save secret in password manager
  2. Log out, log in until 2FA prompt
  3. Autofill the TOTP code from password manager
  4. Result: code stays in field, form auto-submits

Test 2: Manual typing still works

  1. Type first 3 digits — space inserted at midpoint
  2. Type remaining digits — form auto-submits
  3. Clear field and retype — works correctly (no stale flag)

Test 3: All providers accept autofilled codes

  1. Repeat with Email provider and Backup Codes provider
  2. Result: all three accept autofilled codes

Build

two-factor-fix-880.zip available for manual testing.

Verification

  • 184/184 PHPUnit tests pass
  • Grunt build produces clean dist (deleted JS excluded)
  • CodeRabbit: 0 findings
  • PHPCS: no new errors
Open WordPress Playground Preview

- 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
@github-actions

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: faisalahammad <faisalahammad@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.

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-input autocomplete="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.js to 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.

Comment thread TESTING_INSTRUCTIONS.md Outdated
Comment thread providers/class-two-factor-totp.php Outdated
- 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
@faisalahammad

Copy link
Copy Markdown
Contributor Author

Pushed 039c5af addressing both review comments:

  • Removed TESTING_INSTRUCTIONS.md from the PR. It was a local manual-test note that should not have been committed.
  • Collapsed the redundant ?> / <?php pair in the TOTP provider so do_action() and submit_button() run in one PHP block.

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.

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.

TOTP codes from Apple Passwords are wiped on the login screen

3 participants