From c88de65d3a15234a8af52ff7c10d6b4eb8514ff7 Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Thu, 5 Feb 2026 10:51:15 +1000 Subject: [PATCH] Fix #5274 2fa backup codes not validating properly --- backend/internal/2fa.js | 19 +++++++++++-------- backend/schema/paths/tokens/2fa/post.json | 2 +- .../users/userID/2fa/backup-codes/post.json | 4 ++-- .../paths/users/userID/2fa/enable/post.json | 4 ++-- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/backend/internal/2fa.js b/backend/internal/2fa.js index 279f551a..570cee99 100644 --- a/backend/internal/2fa.js +++ b/backend/internal/2fa.js @@ -198,20 +198,23 @@ const internal2fa = { return false; } - // Try TOTP code first - const result = await verify({ - token, - secret, - }); + // Try TOTP code first, if it's 6 chars. it will throw errors if it's not 6 chars + // and the backup codes are 8 chars. + if (token.length === 6) { + const result = await verify({ + token, + secret, + }); - if (result.valid) { - return true; + if (result.valid) { + return true; + } } // Try backup codes const backupCodes = auth?.meta?.backup_codes || []; for (let i = 0; i < backupCodes.length; i++) { - const match = await bcrypt.compare(code.toUpperCase(), backupCodes[i]); + const match = await bcrypt.compare(token.toUpperCase(), backupCodes[i]); if (match) { // Remove used backup code const updatedCodes = [...backupCodes]; diff --git a/backend/schema/paths/tokens/2fa/post.json b/backend/schema/paths/tokens/2fa/post.json index f6b50022..c37af8d3 100644 --- a/backend/schema/paths/tokens/2fa/post.json +++ b/backend/schema/paths/tokens/2fa/post.json @@ -17,7 +17,7 @@ }, "code": { "minLength": 6, - "maxLength": 6, + "maxLength": 8, "type": "string", "example": "012345" } diff --git a/backend/schema/paths/users/userID/2fa/backup-codes/post.json b/backend/schema/paths/users/userID/2fa/backup-codes/post.json index ebfc8c2a..00cb9d5f 100644 --- a/backend/schema/paths/users/userID/2fa/backup-codes/post.json +++ b/backend/schema/paths/users/userID/2fa/backup-codes/post.json @@ -16,7 +16,7 @@ } ], "requestBody": { - "description": "Verififcation Payload", + "description": "Verification Payload", "required": true, "content": { "application/json": { @@ -25,7 +25,7 @@ "properties": { "code": { "minLength": 6, - "maxLength": 6, + "maxLength": 8, "type": "string", "example": "123456" } diff --git a/backend/schema/paths/users/userID/2fa/enable/post.json b/backend/schema/paths/users/userID/2fa/enable/post.json index f08b681f..74c98540 100644 --- a/backend/schema/paths/users/userID/2fa/enable/post.json +++ b/backend/schema/paths/users/userID/2fa/enable/post.json @@ -16,7 +16,7 @@ } ], "requestBody": { - "description": "Verififcation Payload", + "description": "Verification Payload", "required": true, "content": { "application/json": { @@ -25,7 +25,7 @@ "properties": { "code": { "minLength": 6, - "maxLength": 6, + "maxLength": 8, "type": "string", "example": "123456" }