Skip to content

Fix empty backup code when appending codes for a user with none - #958

Open
faithcoder wants to merge 1 commit into
WordPress:masterfrom
faithcoder:fix/956-generate-codes-with-method-append-stores-an-empty
Open

Fix empty backup code when appending codes for a user with none#958
faithcoder wants to merge 1 commit into
WordPress:masterfrom
faithcoder:fix/956-generate-codes-with-method-append-stores-an-empty

Conversation

@faithcoder

@faithcoder faithcoder commented Aug 12, 2026

Copy link
Copy Markdown

What?

Generating backup codes with 'method' => 'append' for a user who has no existing codes no longer stores an extra, empty code that can never be validated or removed.

Fixes #956

Why?

generate_codes() cast get_user_meta( ..., true ) directly to an array. For a user with no stored codes that meta value is '', and (array) '' evaluates to array( '' ) rather than an empty array, so an empty string was permanently appended ahead of the real hashes. codes_remaining_for_user() then reports one more code than the user actually holds, causing two problems:

  • A user with zero usable codes is still offered recovery codes at login.
  • The low-codes warning reports one code too many.

How?

Replaced the bare (array) cast with an is_array() guard before assigning the existing hashes, matching the pattern already used by codes_remaining_for_user() and validate_code(). Added a regression test for the append-with-no-existing-codes case.

Use of AI Tools

AI assistance: Yes
Tool(s): OpenCode
Model(s): deepseek-v4-pro
Used for: Root-cause analysis, fix implementation, and test authoring; the final diff and validation were reviewed by the contributor.

Testing Instructions

  1. npm run composer -- test -- --filter Tests_Two_Factor_Backup_Codes
  2. npm test (full suite)
  3. Manual reproduction from the issue:
$user  = get_user_by( 'login', 'someone' ); // no backup codes yet
$codes = Two_Factor_Backup_Codes::get_instance()->generate_codes( $user, array( 'method' => 'append' ) );

count( $codes );                                              // 10
count( get_user_meta( $user->ID, '_two_factor_backup_codes', true ) ); // 10 (was 11)
Two_Factor_Backup_Codes::codes_remaining_for_user( $user );   // 10 (was 11)

Screenshots or screencast

Not applicable (no UI changes).

Changelog Entry

Fixed - Generating backup codes with the append method no longer stores an empty entry for users with no existing codes.

@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: faithcoder <faithcoder@git.wordpress.org>
Co-authored-by: dknauss <dpknauss@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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

generate_codes() with 'method' => 'append' stores an empty code when the user has none

1 participant