defmodule Simpleshop.Printify.OAuth do require Logger alias Simpleshop.Printify.TokenStore @printify_auth_url "https://printify.com/app/authorize" @printify_token_url "https://api.printify.com/v1/app/oauth/tokens" @printify_refresh_url "https://api.printify.com/v1/app/oauth/tokens/refresh" def authorization_url do config = Application.get_env(:simpleshop, :printify) app_id = Keyword.fetch!(config, :app_id) redirect_uri = Keyword.fetch!(config, :redirect_uri) query = URI.encode_query(%{ app_id: app_id, accept_url: redirect_uri, decline_url: redirect_uri <> "?error=access_denied" }) "#{@printify_auth_url}?#{query}" end def exchange_code(code) do config = Application.get_env(:simpleshop, :printify) app_id = Keyword.fetch!(config, :app_id) body = %{ app_id: app_id, code: code } case Req.post(@printify_token_url, json: body) do {:ok, %{status: 200, body: response}} -> Logger.info("Successfully exchanged OAuth code for tokens") store_token_response(response) {:ok, %{status: status, body: body}} -> Logger.error("Failed to exchange OAuth code: #{status} - #{inspect(body)}") {:error, "Failed to get access token: #{inspect(body)}"} {:error, error} -> Logger.error("HTTP error during token exchange: #{inspect(error)}") {:error, "Network error: #{inspect(error)}"} end end def refresh_access_token do case TokenStore.get_refresh_token() do {:ok, refresh_token} -> config = Application.get_env(:simpleshop, :printify) app_id = Keyword.fetch!(config, :app_id) body = %{ app_id: app_id, refresh_token: refresh_token } case Req.post(@printify_refresh_url, json: body) do {:ok, %{status: 200, body: response}} -> Logger.info("Successfully refreshed access token") store_token_response(response) {:ok, %{status: status, body: body}} -> Logger.error("Failed to refresh access token: #{status} - #{inspect(body)}") {:error, "Failed to refresh token: #{inspect(body)}"} {:error, error} -> Logger.error("HTTP error during token refresh: #{inspect(error)}") {:error, "Network error: #{inspect(error)}"} end {:error, :not_found} -> Logger.error("No refresh token found") {:error, :no_refresh_token} end end defp store_token_response(response) do access_token = Map.get(response, "access_token") || Map.get(response, :access_token) refresh_token = Map.get(response, "refresh_token") || Map.get(response, :refresh_token) expires_in = Map.get(response, "expires_in") || Map.get(response, :expires_in) || 21_600 if access_token && refresh_token do TokenStore.store_tokens(access_token, refresh_token, expires_in) {:ok, access_token} else Logger.error("Missing tokens in response: #{inspect(response)}") {:error, "Invalid token response"} end end end