From d2aded1364076e7f462ccf97a010bfddde6a84ef Mon Sep 17 00:00:00 2001 From: Hez Ronningen Date: Tue, 28 Oct 2025 11:25:40 -0700 Subject: [PATCH] wip --- lib/shopify_api/plugs/admin_authenticator.ex | 9 +++++++++ lib/shopify_api/plugs/auth_shop_session_token.ex | 7 +++++++ lib/shopify_api/user_token_server.ex | 15 ++++++++++++++- 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/lib/shopify_api/plugs/admin_authenticator.ex b/lib/shopify_api/plugs/admin_authenticator.ex index c03727b7..660c51d1 100644 --- a/lib/shopify_api/plugs/admin_authenticator.ex +++ b/lib/shopify_api/plugs/admin_authenticator.ex @@ -35,6 +35,7 @@ defmodule ShopifyAPI.Plugs.AdminAuthenticator do alias Plug.Conn alias ShopifyAPI.JWTSessionToken + alias ShopifyAPI.UserTokenServer @defaults [shopify_mount_path: "/shop"] @@ -49,6 +50,8 @@ defmodule ShopifyAPI.Plugs.AdminAuthenticator do end # User auth + # Optional params + # - force_reauth: set to true if an upsert to offline user token is wanted, will delete existing token in UserTokenServer and re-request an upsert. defp do_authentication(%{params: %{"id_token" => token}} = conn, _options) when is_binary(token) do with {:ok, app} <- JWTSessionToken.app(token), @@ -57,6 +60,7 @@ defmodule ShopifyAPI.Plugs.AdminAuthenticator do {:ok, myshopify_domain} <- JWTSessionToken.myshopify_domain(jwt), {:ok, shop} <- ShopifyAPI.ShopServer.get_or_create(myshopify_domain, true), {:ok, auth_token} <- JWTSessionToken.get_offline_token(jwt, token), + :ok <- force_reauth(conn, jwt), {:ok, user_token} <- JWTSessionToken.get_user_token(jwt, token) do conn |> assign_app(app) @@ -131,4 +135,9 @@ defmodule ShopifyAPI.Plugs.AdminAuthenticator do _ -> {:error, :invalid_hmac} end) end + + defp force_reauth(%{params: %{"force_reauth" => "true"}}, jwt), + do: jwt |> JWTSessionToken.user_id() |> UserTokenServer.delete() + + defp force_reauth(_, _), do: :ok end diff --git a/lib/shopify_api/plugs/auth_shop_session_token.ex b/lib/shopify_api/plugs/auth_shop_session_token.ex index c2c5f9f3..b9b5dbae 100644 --- a/lib/shopify_api/plugs/auth_shop_session_token.ex +++ b/lib/shopify_api/plugs/auth_shop_session_token.ex @@ -21,6 +21,7 @@ defmodule ShopifyAPI.Plugs.AuthShopSessionToken do alias ShopifyAPI.AuthTokenServer alias ShopifyAPI.JWTSessionToken alias ShopifyAPI.ShopServer + alias ShopifyAPI.UserTokenServer def init(opts), do: opts @@ -32,6 +33,7 @@ defmodule ShopifyAPI.Plugs.AuthShopSessionToken do {:ok, user_id} <- JWTSessionToken.user_id(jwt), {:ok, shop} <- ShopServer.get(myshopify_domain), {:ok, auth_token} <- AuthTokenServer.get(myshopify_domain, app.name), + :ok <- force_reauth(conn, jwt), {:ok, user_token} <- JWTSessionToken.get_user_token(jwt, token) do conn |> assign(:app, app) @@ -48,4 +50,9 @@ defmodule ShopifyAPI.Plugs.AuthShopSessionToken do |> halt() end end + + defp force_reauth(%{params: %{"force_reauth" => "true"}}, jwt), + do: jwt |> JWTSessionToken.user_id() |> UserTokenServer.delete() + + defp force_reauth(_, _), do: :ok end diff --git a/lib/shopify_api/user_token_server.ex b/lib/shopify_api/user_token_server.ex index b7a5b88e..87d03ef0 100644 --- a/lib/shopify_api/user_token_server.ex +++ b/lib/shopify_api/user_token_server.ex @@ -66,12 +66,25 @@ defmodule ShopifyAPI.UserTokenServer do :ets.select(@table, match_spec) end + def get_for_id(user_id) when is_integer(user_id) do + match_spec = [{{{:_, :_, user_id}, :"$1"}, [], [:"$1"]}] + :ets.select(@table, match_spec) + end + @spec delete(UserToken.t()) :: :ok - def delete(token) do + @spec delete(integer()) :: :ok + def delete(%UserToken{} = token) do :ets.delete(@table, {token.shop_name, token.app_name, token.associated_user_id}) :ok end + def delete(user_id) when is_integer(user_id) do + case get_for_id(user_id) do + %UserToken{} = token -> delete(token) + _ -> :ok + end + end + @spec delete_for_shop(String.t()) :: :ok def delete_for_shop(myshopify_domain) when is_binary(myshopify_domain) do myshopify_domain |> get_for_shop() |> Enum.each(&delete/1)