riverrun/one_time_pass_ecto

check_totp/3 always returns false

kwayebopp opened this issue · 1 comments

I think there may be a bug with check_totp/3. The call to check_token/4 always returns false and I'm not sure why. It appears that the first case clause in check_token/4 never gets hit. Is there a reason why this is happening?

Here is the part of the library code that I believe is the culprit.

  def check_totp(token, secret, opts \\ []) do
    valid_token(token, Keyword.get(opts, :token_length, 6)) and
      (
        {count, window} =
          {
            Keyword.get(opts, :interval_length, 30) |> interval_count,
            Keyword.get(opts, :window, 1)
          }

        check_token(token, secret, count - window, count + window, opts)
      )
  end

  defp interval_count(interval_length) do
    trunc(System.system_time(:second) / interval_length)
  end

  defp check_token(_token, _secret, current, last, _opts) when current > last do
    false
  end

  defp check_token(token, secret, current, last, opts) do
    case gen_hotp(secret, current, opts) do
      ^token ->  
         # never enters this clause
         current
      _ -> 
        # current will keep increasing until it is greater than last, 
        # which will lead to the preceding function clause always returning false
        check_token(token, secret, current + 1, last, opts) 
    end

First of all, sorry about the delay in getting back to you - I haven't felt well recently.

About the issue you have raised, I cannot replicate it. If you look at the test/base_test.exs "check totp" test, you will see that those two cases do return the latest otp value (it does enter the ^token -> clause).