Skip to content

fix(auth): add self-service 2FA recovery for lost devices#914

Open
faisalahammad wants to merge 1 commit into
WordPress:masterfrom
faisalahammad:fix/621-self-service-recovery
Open

fix(auth): add self-service 2FA recovery for lost devices#914
faisalahammad wants to merge 1 commit into
WordPress:masterfrom
faisalahammad:fix/621-self-service-recovery

Conversation

@faisalahammad

@faisalahammad faisalahammad commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Summary

Add email-based self-service recovery for users who lost their 2FA device and have no backup codes. Uses a two-step email confirmation with a configurable delay period (default 24 hours) before 2FA is disabled.

Fixes #909 (sub-issue #621)

Changes

class-two-factor-core.php

Added:

  • Recovery constants (RECOVERY_TOKEN_META_KEY, RECOVERY_CANCEL_TOKEN_META_KEY, etc.)
  • Token generation/validation methods with hashed storage
  • Email sending methods for confirmation and cancel notifications
  • Rate limiting (12 hours between requests)
  • 4 new login_form_* action handlers for the recovery flow
  • Form rendering methods for each step
  • maybe_show_recovery_options() to show recovery link on 2FA login page
  • cancel_pending_recovery() called after successful 2FA login
  • Recovery meta cleanup in uninstall()

Why: Issue #909 identifies that users locked out of their account with no 2FA device and no backup codes have no self-service path. This is especially critical for single-user sites.

tests/class-two-factor-core.php

Added: 14 test methods covering token generation, validation, expiry, rate limiting, wait period, email sending, recovery cancellation, and provider disabling.

Testing

Test 1: Recovery link visibility

  1. Enable 2FA for a user
  2. Log in with username/password
  3. On 2FA page, verify "Lost your two-factor device?" link appears
    Result: link visible when recovery is enabled

Test 2: Recovery flow

  1. Click recovery link
  2. Submit form (sends confirmation email)
  3. Click confirmation link in email
  4. Verify cancel email sent and countdown message shown
    Result: recovery confirmed, wait period starts

Test 3: Cancellation

  1. Start recovery, get cancel email
  2. Click cancel link
    Result: "Recovery cancelled" message, pending request cleared

Test 4: Auto-cancel on 2FA login

  1. Start recovery and confirm it
  2. Log in with valid 2FA token before delay expires
    Result: recovery cancelled automatically

Test 5: Feature disable

  1. Add define('TWO_FACTOR_DISABLE_RECOVERY', true) to wp-config.php
    Result: recovery link hidden, direct URL access blocked
Open WordPress Playground Preview
- Add email-based recovery flow with confirmation and cancel emails
- Implement 24-hour wait period before recovery can be completed
- Add rate limiting (12 hours) between recovery requests
- Add TWO_FACTOR_DISABLE_RECOVERY constant to opt out
- Add filters for delay period and rate limit
- Cancel recovery automatically on successful 2FA login
- Clean up recovery meta on uninstall

Fixes WordPress#909
@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant