diff --git a/elixir/apps/web/lib/web/controllers/auth_controller.ex b/elixir/apps/web/lib/web/controllers/auth_controller.ex index 7ba80ca13..1f6421c78 100644 --- a/elixir/apps/web/lib/web/controllers/auth_controller.ex +++ b/elixir/apps/web/lib/web/controllers/auth_controller.ex @@ -207,6 +207,7 @@ defmodule Web.AuthController do with {:ok, provider} <- Domain.Auth.fetch_active_provider_by_id(provider_id), {:ok, identity, encoded_fragment} <- Domain.Auth.sign_in(provider, identity_id, nonce, secret, context) do + :ok = Web.Mailer.RateLimiter.reset_rate_limit({:sign_in_link, identity.id}) Web.Auth.signed_in(conn, provider, identity, context, encoded_fragment, redirect_params) else {:error, :not_found} -> diff --git a/elixir/apps/web/lib/web/mailer/rate_limiter.ex b/elixir/apps/web/lib/web/mailer/rate_limiter.ex index fab61e41f..15930a063 100644 --- a/elixir/apps/web/lib/web/mailer/rate_limiter.ex +++ b/elixir/apps/web/lib/web/mailer/rate_limiter.ex @@ -81,6 +81,11 @@ defmodule Web.Mailer.RateLimiter do end end + def reset_rate_limit(key, ets_table_name \\ @default_ets_table_name) do + _ = delete_counter(ets_table_name, key) + :ok + end + defp delete_counter(ets_table_name, key) do :ets.delete(ets_table_name, key) 1 diff --git a/elixir/apps/web/test/web/controllers/auth_controller_test.exs b/elixir/apps/web/test/web/controllers/auth_controller_test.exs index bac23e1c7..262b46498 100644 --- a/elixir/apps/web/test/web/controllers/auth_controller_test.exs +++ b/elixir/apps/web/test/web/controllers/auth_controller_test.exs @@ -770,6 +770,30 @@ defmodule Web.AuthControllerTest do assert %{"fz_recent_account_ids" => fz_recent_account_ids} = conn.cookies assert :erlang.binary_to_term(fz_recent_account_ids) == [identity.account_id] end + + test "resets the rate limit for signed in identity", %{ + conn_with_cookie: conn, + account: account, + provider: provider, + identity: identity, + email_secret: email_secret + } do + key = {:sign_in_link, identity.id} + Web.Mailer.RateLimiter.rate_limit(key, 3, 60_000, fn -> :ok end) + + conn = + conn + |> get(~p"/#{account}/sign_in/providers/#{provider}/verify_sign_in_token", %{ + "identity_id" => identity.id, + "secret" => String.upcase(email_secret) + }) + + assert conn.assigns.flash == %{} + assert redirected_to(conn) == ~p"/#{account}/sites" + + refute :ets.tab2list(Web.Mailer.RateLimiter.ETS) + |> Enum.any?(fn {ets_key, _, _} -> ets_key == key end) + end end describe "redirect_to_idp/2" do