[PR #7231] [MERGED] fix(two-factor): updated backup codes respect storeBackupCodes option #15409

Closed
opened 2026-04-13 10:01:11 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/better-auth/better-auth/pull/7231
Author: @Byte-Biscuit
Created: 1/9/2026
Status: Merged
Merged: 4/11/2026
Merged by: @gustavovalverde

Base: mainHead: fix/two-factor-backup-codes-update


📝 Commits (2)

  • f785093 fix(two-factor): preserve backup codes storage format after verification
  • c88f45e fix(two-factor): use optional chaining consistently in encodeBackupCodes

📊 Changes

3 files changed (+151 additions, -25 deletions)

View changed files

.changeset/fix-backup-codes-storage.md (+7 -0)
📝 packages/better-auth/src/plugins/two-factor/backup-codes/index.ts (+23 -25)
📝 packages/better-auth/src/plugins/two-factor/two-factor.test.ts (+121 -0)

📄 Description

Summary

After using a backup code, the remaining codes were always re-saved with the built-in symmetricEncrypt, ignoring the storeBackupCodes configuration. If a developer configured "plain" or a custom { encrypt, decrypt } pair, the first successful verification would silently corrupt the storage format, making all remaining codes unusable.

Fix

Extracted a new encodeBackupCodes helper that handles the 3-way storage branch (plain, encrypted, custom) in one place. Both generateBackupCodes and the verify endpoint now call it, so the encode logic can't drift out of sync.

Parameterized integration tests cover all three storage modes through a full generate/verify/re-verify cycle.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/better-auth/better-auth/pull/7231 **Author:** [@Byte-Biscuit](https://github.com/Byte-Biscuit) **Created:** 1/9/2026 **Status:** ✅ Merged **Merged:** 4/11/2026 **Merged by:** [@gustavovalverde](https://github.com/gustavovalverde) **Base:** `main` ← **Head:** `fix/two-factor-backup-codes-update` --- ### 📝 Commits (2) - [`f785093`](https://github.com/better-auth/better-auth/commit/f7850930a129bcc3458eeb292fa4dfbdf000a8e9) fix(two-factor): preserve backup codes storage format after verification - [`c88f45e`](https://github.com/better-auth/better-auth/commit/c88f45ec3c940557c925beaaef643d1d42aaac03) fix(two-factor): use optional chaining consistently in encodeBackupCodes ### 📊 Changes **3 files changed** (+151 additions, -25 deletions) <details> <summary>View changed files</summary> ➕ `.changeset/fix-backup-codes-storage.md` (+7 -0) 📝 `packages/better-auth/src/plugins/two-factor/backup-codes/index.ts` (+23 -25) 📝 `packages/better-auth/src/plugins/two-factor/two-factor.test.ts` (+121 -0) </details> ### 📄 Description ## Summary After using a backup code, the remaining codes were always re-saved with the built-in `symmetricEncrypt`, ignoring the `storeBackupCodes` configuration. If a developer configured `"plain"` or a custom `{ encrypt, decrypt }` pair, the first successful verification would silently corrupt the storage format, making all remaining codes unusable. ## Fix Extracted a new `encodeBackupCodes` helper that handles the 3-way storage branch (plain, encrypted, custom) in one place. Both `generateBackupCodes` and the verify endpoint now call it, so the encode logic can't drift out of sync. Parameterized integration tests cover all three storage modes through a full generate/verify/re-verify cycle. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-04-13 10:01:11 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#15409