From a8d98ac40bb9d1ce7e0a74e4e58549fa25566d4f Mon Sep 17 00:00:00 2001 From: James Harton Date: Mon, 5 Aug 2024 15:34:55 +1200 Subject: [PATCH] improvement: validate that tokens are enabled when password resets are enabled. (#758) Closes #232. --- .../strategies/password/verifier.ex | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/lib/ash_authentication/strategies/password/verifier.ex b/lib/ash_authentication/strategies/password/verifier.ex index f7d48a6..f69dc85 100644 --- a/lib/ash_authentication/strategies/password/verifier.ex +++ b/lib/ash_authentication/strategies/password/verifier.ex @@ -11,7 +11,8 @@ defmodule AshAuthentication.Strategy.Password.Verifier do @spec verify(Password.t(), map) :: :ok | {:error, Exception.t()} def verify(strategy, dsl_state) do with :ok <- validate_behaviour(strategy.hash_provider, HashProvider), - :ok <- validate_tokens_enabled_for_sign_in_tokens(dsl_state, strategy) do + :ok <- validate_tokens_enabled_for_sign_in_tokens(dsl_state, strategy), + :ok <- validate_tokens_enabled_for_resettable(dsl_state, strategy) do maybe_validate_resettable_sender(dsl_state, strategy) end end @@ -69,6 +70,41 @@ defmodule AshAuthentication.Strategy.Password.Verifier do defp validate_tokens_enabled_for_sign_in_tokens(_, _), do: :ok + defp validate_tokens_enabled_for_resettable(dsl_state, %{resettable: resettable, name: name}) + when is_struct(resettable) do + resource = Verifier.get_persisted(dsl_state, :module) + + if Info.authentication_tokens_enabled?(dsl_state) do + :ok + else + {:error, + DslError.exception( + module: resource, + path: [ + :authentication, + :strategies, + :password, + name, + :resettable + ], + message: """ + The `resettable` option requires that tokens are enabled for your resource. For example: + + + authentication do + ... + + tokens do + enabled? true + end + end + """ + )} + end + end + + defp validate_tokens_enabled_for_resettable(_, _), do: :ok + defp maybe_validate_resettable_sender(dsl_state, %{resettable: resettable}) when is_struct(resettable) do with {:ok, {sender, _opts}} <- Map.fetch(resettable, :sender),