From ea101b2a8398d13b80b44aff99b0cde624a82ea7 Mon Sep 17 00:00:00 2001 From: "construct.d" Date: Tue, 18 Nov 2025 19:06:27 +0000 Subject: [PATCH 1/4] Refactor ueberauth config usage --- lib/phoenix_kit/{ => config}/config.ex | 22 +- lib/phoenix_kit/config/ueber_auth.ex | 323 ++++++++++++++++++ lib/phoenix_kit/users/oauth_config.ex | 19 +- .../plugs/ensure_oauth_config.ex | 8 +- lib/phoenix_kit_web/users/oauth.ex | 2 +- 5 files changed, 354 insertions(+), 20 deletions(-) rename lib/phoenix_kit/{ => config}/config.ex (97%) create mode 100644 lib/phoenix_kit/config/ueber_auth.ex diff --git a/lib/phoenix_kit/config.ex b/lib/phoenix_kit/config/config.ex similarity index 97% rename from lib/phoenix_kit/config.ex rename to lib/phoenix_kit/config/config.ex index 32cccb378..cd189a912 100644 --- a/lib/phoenix_kit/config.ex +++ b/lib/phoenix_kit/config/config.ex @@ -61,9 +61,7 @@ defmodule PhoenixKit.Config do secret_key_base: nil, oauth_base_url: nil, # Module-specific settings - blogging_settings_module: PhoenixKit.Settings, - # OAuth and third-party settings - ueberauth: [] + blogging_settings_module: PhoenixKit.Settings ] @doc """ @@ -107,6 +105,24 @@ defmodule PhoenixKit.Config do end end + @doc """ + Sets a configuration value. + + ## Examples + + iex> PhoenixKit.Config.set(:repo, MyApp.Repo) + :ok + + iex> PhoenixKit.Config.set(:custom_option, "custom_value") + :ok + + """ + @spec set(atom(), any()) :: :ok + def set(key, value) when is_atom(key) do + Application.put_env(:phoenix_kit, key, value) + :ok + end + @doc """ Gets a configuration value as a list with type validation. diff --git a/lib/phoenix_kit/config/ueber_auth.ex b/lib/phoenix_kit/config/ueber_auth.ex new file mode 100644 index 000000000..358deb598 --- /dev/null +++ b/lib/phoenix_kit/config/ueber_auth.ex @@ -0,0 +1,323 @@ +defmodule PhoenixKit.Config.UeberAuth do + @moduledoc """ + Ueberauth configuration management for PhoenixKit. + + This module provides a centralized way to manage Ueberauth OAuth configuration + with type-safe getter and setter functions for different data types. + + ## Usage + + # Get all Ueberauth configuration + config = PhoenixKit.Config.UeberAuth.get_all() + + # Get specific values + providers = PhoenixKit.Config.UeberAuth.get_providers() + base_path = PhoenixKit.Config.UeberAuth.get_base_path() + + # Set configuration + PhoenixKit.Config.UeberAuth.set_providers(%{google: {Ueberauth.Strategy.Google, []}}) + PhoenixKit.Config.UeberAuth.set_base_path("/custom/auth") + + ## Configuration Keys + + - `:base_path` - Base path for OAuth routes (default: calculated from URL prefix) + - `:providers` - Map of OAuth providers and their strategies + + ## Provider Management + + Functions are provided for adding, removing, and checking individual providers: + - `update_provider/2` - Add or update a provider + - `remove_provider/1` - Remove a provider + - `has_provider?/1` - Check if a provider is configured + - `get_provider_names/0` - Get list of all provider names + - `get_provider/1` - Get specific provider configuration + """ + + alias PhoenixKit.Config + + @doc """ + Gets the full Ueberauth configuration from the application environment. + + This function retrieves the complete Ueberauth configuration including + providers, base path, and other Ueberauth-specific settings. + + ## Examples + + iex> PhoenixKit.Config.UeberAuth.get_all() + [base_path: "/users/auth", providers: %{google: {Ueberauth.Strategy.Google, []}}] + + iex> PhoenixKit.Config.UeberAuth.get_all() + [] + + """ + @spec get_all() :: Keyword.t() + def get_all do + Config.get_list(:ueberauth, []) + end + + @doc """ + Gets specific Ueberauth configuration options by key. + + ## Examples + + iex> PhoenixKit.Config.UeberAuth.get_option(:providers) + %{google: {Ueberauth.Strategy.Google, []}} + + iex> PhoenixKit.Config.UeberAuth.get_option(:base_path) + "/users/auth" + + iex> PhoenixKit.Config.UeberAuth.get_option(:nonexistent) + nil + + """ + @spec get_option(atom()) :: any() | nil + def get_option(key) when is_atom(key) do + config = get_all() + Keyword.get(config, key) + end + + @doc """ + Gets specific Ueberauth configuration options by key with a default value. + + ## Examples + + iex> PhoenixKit.Config.UeberAuth.get_option(:base_path, "/auth") + "/users/auth" + + iex> PhoenixKit.Config.UeberAuth.get_option(:nonexistent, "default") + "default" + + """ + @spec get_option(atom(), any()) :: any() + def get_option(key, default) when is_atom(key) do + config = get_all() + Keyword.get(config, key, default) + end + + @doc """ + Gets Ueberauth providers configuration. + + Returns the configured providers map or list, or an empty map if none configured. + + ## Examples + + iex> PhoenixKit.Config.UeberAuth.get_providers() + %{google: {Ueberauth.Strategy.Google, []}, apple: {Ueberauth.Strategy.Apple, []}} + + iex> PhoenixKit.Config.UeberAuth.get_providers() + %{} + + """ + @spec get_providers() :: map() | list() + def get_providers do + case get_option(:providers) do + providers when is_map(providers) or is_list(providers) -> providers + _ -> %{} + end + end + + @doc """ + Gets Ueberauth base path configuration. + + Returns the configured base path for OAuth routes or a default based on URL prefix. + + ## Examples + + iex> PhoenixKit.Config.UeberAuth.get_base_path() + "/users/auth" + + iex> PhoenixKit.Config.UeberAuth.get_base_path() + "/phoenix_kit/users/auth" + + """ + @spec get_base_path() :: String.t() + def get_base_path do + case get_option(:base_path) do + base_path when is_binary(base_path) and base_path != "" -> base_path + _ -> get_default_base_path() + end + end + + @doc """ + Sets Ueberauth configuration options. + + Updates the Ueberauth configuration in the application environment. + + ## Examples + + iex> PhoenixKit.Config.UeberAuth.set_all([providers: %{google: {Ueberauth.Strategy.Google, []}}]) + :ok + + iex> PhoenixKit.Config.UeberAuth.set_all([base_path: "/custom/auth"]) + :ok + + """ + @spec set_all(Keyword.t()) :: :ok + def set_all(options) when is_list(options) do + current_config = get_all() + new_config = Keyword.merge(current_config, options) + Config.set(:ueberauth, new_config) + :ok + end + + @doc """ + Sets specific Ueberauth configuration option. + + Updates a single key in the Ueberauth configuration. + + ## Examples + + iex> PhoenixKit.Config.UeberAuth.set_option(:base_path, "/custom/auth") + :ok + + iex> PhoenixKit.Config.UeberAuth.set_option(:providers, %{google: {Ueberauth.Strategy.Google, []}}) + :ok + + """ + @spec set_option(atom(), any()) :: :ok + def set_option(key, value) when is_atom(key) do + set_all([{key, value}]) + end + + @doc """ + Sets Ueberauth providers configuration. + + Updates the providers map in Ueberauth configuration. + + ## Examples + + iex> PhoenixKit.Config.UeberAuth.set_providers(%{google: {Ueberauth.Strategy.Google, []}}) + :ok + + """ + @spec set_providers(map() | list()) :: :ok + def set_providers(providers) when is_map(providers) or is_list(providers) do + set_option(:providers, providers) + end + + @doc """ + Sets Ueberauth base path configuration. + + Updates the base path for OAuth routes. + + ## Examples + + iex> PhoenixKit.Config.UeberAuth.set_base_path("/custom/auth") + :ok + + """ + @spec set_base_path(String.t()) :: :ok + def set_base_path(base_path) when is_binary(base_path) do + set_option(:base_path, base_path) + end + + @doc """ + Updates Ueberauth providers by adding or updating a specific provider. + + Adds a new provider or updates an existing one in the providers configuration. + + ## Examples + + iex> PhoenixKit.Config.UeberAuth.update_provider(:google, {Ueberauth.Strategy.Google, []}) + :ok + + """ + @spec update_provider(atom(), tuple()) :: :ok + def update_provider(provider, strategy_config) + when is_atom(provider) and is_tuple(strategy_config) do + providers = get_providers() + updated_providers = Map.put(providers, provider, strategy_config) + set_providers(updated_providers) + end + + @doc """ + Removes a specific Ueberauth provider from the configuration. + + ## Examples + + iex> PhoenixKit.Config.UeberAuth.remove_provider(:google) + :ok + + """ + @spec remove_provider(atom()) :: :ok + def remove_provider(provider) when is_atom(provider) do + providers = get_providers() + updated_providers = Map.delete(providers, provider) + set_providers(updated_providers) + end + + @doc """ + Checks if a specific Ueberauth provider is configured. + + ## Examples + + iex> PhoenixKit.Config.UeberAuth.has_provider?(:google) + true + + iex> PhoenixKit.Config.UeberAuth.has_provider?(:facebook) + false + + """ + @spec has_provider?(atom()) :: boolean() + def has_provider?(provider) when is_atom(provider) do + providers = get_providers() + Map.has_key?(providers, provider) + end + + @doc """ + Gets a list of all configured Ueberauth provider names. + + ## Examples + + iex> PhoenixKit.Config.UeberAuth.get_provider_names() + [:google, :apple, :github] + + iex> PhoenixKit.Config.UeberAuth.get_provider_names() + [] + + """ + @spec get_provider_names() :: [atom()] + def get_provider_names do + providers = get_providers() + + case providers do + p when is_map(p) -> Map.keys(p) + p when is_list(p) -> Keyword.keys(p) + _ -> [] + end + end + + @doc """ + Gets the Ueberauth provider configuration for a specific provider. + + ## Examples + + iex> PhoenixKit.Config.UeberAuth.get_provider(:google) + {Ueberauth.Strategy.Google, []} + + iex> PhoenixKit.Config.UeberAuth.get_provider(:nonexistent) + nil + + """ + @spec get_provider(atom()) :: tuple() | nil + def get_provider(provider) when is_atom(provider) do + providers = get_providers() + + case providers do + p when is_map(p) -> Map.get(p, provider) + p when is_list(p) -> Keyword.get(p, provider) + _ -> nil + end + end + + # Helper function to get the default base path based on URL prefix + defp get_default_base_path do + url_prefix = Config.get_url_prefix() + + case url_prefix do + "" -> "/users/auth" + "/" -> "/users/auth" + prefix -> "#{prefix}/users/auth" + end + end +end diff --git a/lib/phoenix_kit/users/oauth_config.ex b/lib/phoenix_kit/users/oauth_config.ex index 338786baf..6d4c79418 100644 --- a/lib/phoenix_kit/users/oauth_config.ex +++ b/lib/phoenix_kit/users/oauth_config.ex @@ -59,21 +59,16 @@ defmodule PhoenixKit.Users.OAuthConfig do defp configure_ueberauth_base do providers = build_provider_list() - # FIXED: Preserve existing base_path or set default based on PhoenixKit URL prefix - # Get current config to preserve any existing settings - current_config = Application.get_env(:ueberauth, Ueberauth, []) + # Preserve existing base_path or set default based on PhoenixKit URL prefix + # Get current config from PhoenixKit.Config.UeberAuth to preserve any existing settings + current_base_path = PhoenixKit.Config.UeberAuth.get_base_path() + base_path = current_base_path || get_oauth_base_path() - # Preserve base_path if it exists, or set default based on PhoenixKit URL prefix - base_path = Keyword.get(current_config, :base_path) || get_oauth_base_path() - - config = [ + # Use PhoenixKit.Config.UeberAuth to set the configuration + PhoenixKit.Config.UeberAuth.set_all( base_path: base_path, providers: providers - ] - - # Always update Ueberauth configuration, even if providers list is empty - # This ensures Ueberauth has a valid configuration at all times - Application.put_env(:ueberauth, Ueberauth, config) + ) if providers != %{} do Logger.info( diff --git a/lib/phoenix_kit_web/plugs/ensure_oauth_config.ex b/lib/phoenix_kit_web/plugs/ensure_oauth_config.ex index ec592f448..86a2fe584 100644 --- a/lib/phoenix_kit_web/plugs/ensure_oauth_config.ex +++ b/lib/phoenix_kit_web/plugs/ensure_oauth_config.ex @@ -60,14 +60,14 @@ defmodule PhoenixKitWeb.Plugs.EnsureOAuthConfig do end defp ensure_oauth_config do - config = Application.get_env(:ueberauth, Ueberauth, []) + providers = PhoenixKit.Config.UeberAuth.get_providers() - case Keyword.fetch(config, :providers) do - {:ok, _providers} -> + case providers do + providers when is_map(providers) or is_list(providers) -> # Configuration exists, all good :ok - :error -> + _ -> # Configuration missing, try to load it Logger.warning("Ueberauth :providers missing, attempting to load OAuth configuration") load_oauth_config() diff --git a/lib/phoenix_kit_web/users/oauth.ex b/lib/phoenix_kit_web/users/oauth.ex index 47c1fb1a0..a7f2b60c8 100644 --- a/lib/phoenix_kit_web/users/oauth.ex +++ b/lib/phoenix_kit_web/users/oauth.ex @@ -124,7 +124,7 @@ if Code.ensure_loaded?(Ueberauth) do end defp get_ueberauth_providers do - providers = Application.get_env(:ueberauth, Ueberauth, [])[:providers] || [] + providers = PhoenixKit.Config.UeberAuth.get_providers() # Normalize Map or List to list of {provider_atom, strategy} tuples case providers do From b20f6d6e947c767001b564783da36accff590ed9 Mon Sep 17 00:00:00 2001 From: "construct.d" Date: Tue, 18 Nov 2025 19:43:28 +0000 Subject: [PATCH 2/4] Change module usage --- lib/phoenix_kit/users/oauth_config.ex | 3 ++- lib/phoenix_kit_web/plugs/ensure_oauth_config.ex | 4 +++- lib/phoenix_kit_web/users/oauth.ex | 3 ++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/phoenix_kit/users/oauth_config.ex b/lib/phoenix_kit/users/oauth_config.ex index 6d4c79418..4b3f205c3 100644 --- a/lib/phoenix_kit/users/oauth_config.ex +++ b/lib/phoenix_kit/users/oauth_config.ex @@ -7,6 +7,7 @@ defmodule PhoenixKit.Users.OAuthConfig do configuration dynamically. """ + alias PhoenixKit.Config alias PhoenixKit.Settings require Logger @@ -65,7 +66,7 @@ defmodule PhoenixKit.Users.OAuthConfig do base_path = current_base_path || get_oauth_base_path() # Use PhoenixKit.Config.UeberAuth to set the configuration - PhoenixKit.Config.UeberAuth.set_all( + Config.UeberAuth.set_all( base_path: base_path, providers: providers ) diff --git a/lib/phoenix_kit_web/plugs/ensure_oauth_config.ex b/lib/phoenix_kit_web/plugs/ensure_oauth_config.ex index 86a2fe584..caceb6bb1 100644 --- a/lib/phoenix_kit_web/plugs/ensure_oauth_config.ex +++ b/lib/phoenix_kit_web/plugs/ensure_oauth_config.ex @@ -33,6 +33,8 @@ defmodule PhoenixKitWeb.Plugs.EnsureOAuthConfig do import Plug.Conn require Logger + alias PhoenixKit.Config + def init(opts), do: opts def call(conn, _opts) do @@ -60,7 +62,7 @@ defmodule PhoenixKitWeb.Plugs.EnsureOAuthConfig do end defp ensure_oauth_config do - providers = PhoenixKit.Config.UeberAuth.get_providers() + providers = Config.UeberAuth.get_providers() case providers do providers when is_map(providers) or is_list(providers) -> diff --git a/lib/phoenix_kit_web/users/oauth.ex b/lib/phoenix_kit_web/users/oauth.ex index a7f2b60c8..9041b8fc1 100644 --- a/lib/phoenix_kit_web/users/oauth.ex +++ b/lib/phoenix_kit_web/users/oauth.ex @@ -19,6 +19,7 @@ if Code.ensure_loaded?(Ueberauth) do plug PhoenixKitWeb.Plugs.EnsureOAuthConfig plug Ueberauth + alias PhoenixKit.Config alias PhoenixKit.Settings alias PhoenixKit.Users.OAuth alias PhoenixKit.Utils.IpAddress @@ -124,7 +125,7 @@ if Code.ensure_loaded?(Ueberauth) do end defp get_ueberauth_providers do - providers = PhoenixKit.Config.UeberAuth.get_providers() + providers = Config.UeberAuth.get_providers() # Normalize Map or List to list of {provider_atom, strategy} tuples case providers do From ff6c1489275b26b5f3b5f19bc4a300a047a769f0 Mon Sep 17 00:00:00 2001 From: "construct.d" Date: Wed, 19 Nov 2025 15:39:06 +0000 Subject: [PATCH 3/4] Fix code type warnings --- lib/phoenix_kit/config/ueber_auth.ex | 2 -- lib/phoenix_kit/users/oauth_config.ex | 15 +-------------- lib/phoenix_kit_web/users/oauth.ex | 1 - 3 files changed, 1 insertion(+), 17 deletions(-) diff --git a/lib/phoenix_kit/config/ueber_auth.ex b/lib/phoenix_kit/config/ueber_auth.ex index 358deb598..b4bd286e4 100644 --- a/lib/phoenix_kit/config/ueber_auth.ex +++ b/lib/phoenix_kit/config/ueber_auth.ex @@ -283,7 +283,6 @@ defmodule PhoenixKit.Config.UeberAuth do case providers do p when is_map(p) -> Map.keys(p) p when is_list(p) -> Keyword.keys(p) - _ -> [] end end @@ -306,7 +305,6 @@ defmodule PhoenixKit.Config.UeberAuth do case providers do p when is_map(p) -> Map.get(p, provider) p when is_list(p) -> Keyword.get(p, provider) - _ -> nil end end diff --git a/lib/phoenix_kit/users/oauth_config.ex b/lib/phoenix_kit/users/oauth_config.ex index 4b3f205c3..94a954620 100644 --- a/lib/phoenix_kit/users/oauth_config.ex +++ b/lib/phoenix_kit/users/oauth_config.ex @@ -60,10 +60,7 @@ defmodule PhoenixKit.Users.OAuthConfig do defp configure_ueberauth_base do providers = build_provider_list() - # Preserve existing base_path or set default based on PhoenixKit URL prefix - # Get current config from PhoenixKit.Config.UeberAuth to preserve any existing settings - current_base_path = PhoenixKit.Config.UeberAuth.get_base_path() - base_path = current_base_path || get_oauth_base_path() + base_path = PhoenixKit.Config.UeberAuth.get_base_path() # Use PhoenixKit.Config.UeberAuth to set the configuration Config.UeberAuth.set_all( @@ -82,16 +79,6 @@ defmodule PhoenixKit.Users.OAuthConfig do end end - # Helper to get OAuth base path from PhoenixKit URL prefix - defp get_oauth_base_path do - url_prefix = PhoenixKit.Config.get_url_prefix() - - case url_prefix do - "" -> "/users/auth" - prefix -> "#{prefix}/users/auth" - end - end - # Build the list of available providers based on configured credentials defp build_provider_list do providers = %{} diff --git a/lib/phoenix_kit_web/users/oauth.ex b/lib/phoenix_kit_web/users/oauth.ex index 9041b8fc1..6315b0199 100644 --- a/lib/phoenix_kit_web/users/oauth.ex +++ b/lib/phoenix_kit_web/users/oauth.ex @@ -131,7 +131,6 @@ if Code.ensure_loaded?(Ueberauth) do case providers do p when is_map(p) -> Map.to_list(p) p when is_list(p) -> p - _ -> [] end end From 6217b6c9cf4282d946ba5ee1e9ff299165bbdefa Mon Sep 17 00:00:00 2001 From: "construct.d" Date: Wed, 19 Nov 2025 15:40:29 +0000 Subject: [PATCH 4/4] Fix require usage --- lib/phoenix_kit/pages.ex | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/phoenix_kit/pages.ex b/lib/phoenix_kit/pages.ex index 169ba1265..d69a53719 100644 --- a/lib/phoenix_kit/pages.ex +++ b/lib/phoenix_kit/pages.ex @@ -87,8 +87,6 @@ defmodule PhoenixKit.Pages do def ensure_not_found_page_exists do relative_path = not_found_file_path() - require Logger - if FileOperations.file_exists?(relative_path) do Logger.debug("Pages 404 already exists at #{FileOperations.absolute_path(relative_path)}") else