From 5c6cef2227568e0f666677590d03131c425d45c2 Mon Sep 17 00:00:00 2001 From: Graham McInitre Date: Tue, 21 Jul 2026 11:18:15 -0500 Subject: [PATCH] =?UTF-8?q?refactor:=20DRY=20token=20verification=20?= =?UTF-8?q?=E2=80=94=20extract=20shared=20verify=5Fhashed=5Ftoken=5Fquery?= =?UTF-8?q?=20helper?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Consolidate verify_magic_link/confirm/password_reset_token_query into one-line delegations to a private helper, removing 29 lines of duplicated decode/hash/query logic. --- lib/microwaveprop/accounts/user_token.ex | 78 ++++++++---------------- 1 file changed, 24 insertions(+), 54 deletions(-) diff --git a/lib/microwaveprop/accounts/user_token.ex b/lib/microwaveprop/accounts/user_token.ex index 8d40b79e..db7c3905 100644 --- a/lib/microwaveprop/accounts/user_token.ex +++ b/lib/microwaveprop/accounts/user_token.ex @@ -117,6 +117,25 @@ defmodule Microwaveprop.Accounts.UserToken do }} end + defp verify_hashed_token_query(token, context, validity, unit) do + case Base.url_decode64(token, padding: false) do + {:ok, decoded_token} -> + hashed_token = :crypto.hash(@hash_algorithm, decoded_token) + + query = + from token in by_token_and_context_query(hashed_token, context), + join: user in assoc(token, :user), + where: token.inserted_at > ago(^validity, ^unit), + where: token.sent_to == user.email, + select: {user, token} + + {:ok, query} + + :error -> + :error + end + end + @doc """ Checks if the token is valid and returns its underlying lookup query. @@ -127,24 +146,8 @@ defmodule Microwaveprop.Accounts.UserToken do of a magic link token is always "login". """ @spec verify_magic_link_token_query(String.t()) :: {:ok, Ecto.Query.t()} | :error - def verify_magic_link_token_query(token) do - case Base.url_decode64(token, padding: false) do - {:ok, decoded_token} -> - hashed_token = :crypto.hash(@hash_algorithm, decoded_token) - - query = - from token in by_token_and_context_query(hashed_token, "login"), - join: user in assoc(token, :user), - where: token.inserted_at > ago(^@magic_link_validity_in_minutes, "minute"), - where: token.sent_to == user.email, - select: {user, token} - - {:ok, query} - - :error -> - :error - end - end + def verify_magic_link_token_query(token), + do: verify_hashed_token_query(token, "login", @magic_link_validity_in_minutes, "minute") @doc """ Checks if the token is valid and returns its underlying lookup query. @@ -153,24 +156,7 @@ defmodule Microwaveprop.Accounts.UserToken do "confirm" and the token is valid for @confirm_validity_in_days days. """ @spec verify_confirm_token_query(String.t()) :: {:ok, Ecto.Query.t()} | :error - def verify_confirm_token_query(token) do - case Base.url_decode64(token, padding: false) do - {:ok, decoded_token} -> - hashed_token = :crypto.hash(@hash_algorithm, decoded_token) - - query = - from token in by_token_and_context_query(hashed_token, "confirm"), - join: user in assoc(token, :user), - where: token.inserted_at > ago(^@confirm_validity_in_days, "day"), - where: token.sent_to == user.email, - select: {user, token} - - {:ok, query} - - :error -> - :error - end - end + def verify_confirm_token_query(token), do: verify_hashed_token_query(token, "confirm", @confirm_validity_in_days, "day") @doc """ Checks if the token is valid and returns its underlying lookup query. @@ -179,24 +165,8 @@ defmodule Microwaveprop.Accounts.UserToken do "reset_password" and the token is valid for @reset_password_validity_in_days. """ @spec verify_password_reset_token_query(String.t()) :: {:ok, Ecto.Query.t()} | :error - def verify_password_reset_token_query(token) do - case Base.url_decode64(token, padding: false) do - {:ok, decoded_token} -> - hashed_token = :crypto.hash(@hash_algorithm, decoded_token) - - query = - from token in by_token_and_context_query(hashed_token, "reset_password"), - join: user in assoc(token, :user), - where: token.inserted_at > ago(^@reset_password_validity_in_days, "day"), - where: token.sent_to == user.email, - select: {user, token} - - {:ok, query} - - :error -> - :error - end - end + def verify_password_reset_token_query(token), + do: verify_hashed_token_query(token, "reset_password", @reset_password_validity_in_days, "day") @doc """ Checks if the token is valid and returns its underlying lookup query.