fix: improve verify_totp_only validation logic

This commit is contained in:
Graham McIntire 2026-02-01 14:24:19 -06:00
parent 42565779bc
commit d7234e02a3
No known key found for this signature in database
2 changed files with 14 additions and 6 deletions

View file

@ -598,15 +598,13 @@ defmodule Towerops.Accounts do
def verify_totp_only(%User{} = user, code) when is_binary(code) do
# TOTP codes are exactly 6 numeric digits
# Recovery codes contain letters and/or are longer than 6 digits
numeric_only = String.replace(code, ~r/[^0-9]/, "")
cond do
# Code contains non-numeric characters (recovery codes have letters)
String.length(numeric_only) != String.length(code) ->
# Reject if code contains any non-numeric characters
not String.match?(code, ~r/^\d+$/) ->
{:error, :recovery_code_not_allowed}
# Code is longer than 6 digits
String.length(numeric_only) > 6 ->
# Reject if longer than 6 digits
String.length(code) > 6 ->
{:error, :recovery_code_not_allowed}
# Looks like a TOTP code, verify it

View file

@ -39,5 +39,15 @@ defmodule Towerops.Accounts.VerifyTotpOnlyTest do
assert {:error, :recovery_code_not_allowed} =
Accounts.verify_totp_only(user, "1234567890")
end
test "rejects codes with whitespace", %{user: user} do
assert {:error, :recovery_code_not_allowed} =
Accounts.verify_totp_only(user, " 123456 ")
end
test "rejects codes with hyphens", %{user: user} do
assert {:error, :recovery_code_not_allowed} =
Accounts.verify_totp_only(user, "123-456")
end
end
end