From 529611285456d699a652f46b5cf2154a728693cb Mon Sep 17 00:00:00 2001 From: timujeen Date: Tue, 17 Mar 2026 04:58:32 +0000 Subject: [PATCH 1/3] Exclude /newsletters/unsubscribe from sitemap router discovery MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Functional page that requires a token query param — not suitable for search engine indexing. Added alongside /checkout and /cart in @default_exclude_patterns. --- lib/modules/sitemap/sources/router_discovery.ex | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/modules/sitemap/sources/router_discovery.ex b/lib/modules/sitemap/sources/router_discovery.ex index 2ad50ce63..9d144b869 100644 --- a/lib/modules/sitemap/sources/router_discovery.ex +++ b/lib/modules/sitemap/sources/router_discovery.ex @@ -90,6 +90,7 @@ defmodule PhoenixKit.Modules.Sitemap.Sources.RouterDiscovery do # Internal/functional pages - not for search engine indexing "/checkout", "/cart", + "/newsletters/unsubscribe", "/health", "/ready", # Infrastructure From a17d04d467ab5734eaf41eb87f45a22119a75276 Mon Sep 17 00:00:00 2001 From: timujeen Date: Tue, 17 Mar 2026 10:22:22 +0000 Subject: [PATCH 2/3] Fix Modules page: replace hardcoded newsletters card with generic external module rendering - Remove hardcoded Newsletters card from modules.html.heex (was causing double-render when phoenix_kit_newsletters package is installed) - Enrich load_external_modules/1 with required_modules and admin_links fields - External module card now shows "Requires X" badges for unmet dependencies - External module card shows action link buttons when module is enabled - Add not_installed_keys MapSet assign to guard against double-render - Add key field to known_external_packages entry for newsletters --- lib/phoenix_kit/module_registry.ex | 1 + lib/phoenix_kit_web/live/modules.ex | 18 +++++- lib/phoenix_kit_web/live/modules.html.heex | 67 ++++++++-------------- 3 files changed, 41 insertions(+), 45 deletions(-) diff --git a/lib/phoenix_kit/module_registry.ex b/lib/phoenix_kit/module_registry.ex index 485af648d..64b9314cd 100644 --- a/lib/phoenix_kit/module_registry.ex +++ b/lib/phoenix_kit/module_registry.ex @@ -431,6 +431,7 @@ defmodule PhoenixKit.ModuleRegistry do [ %{ module: PhoenixKit.Newsletters, + key: "newsletters", hex_package: "phoenix_kit_newsletters", name: "Newsletters", description: diff --git a/lib/phoenix_kit_web/live/modules.ex b/lib/phoenix_kit_web/live/modules.ex index 985bcd526..8eaabf201 100644 --- a/lib/phoenix_kit_web/live/modules.ex +++ b/lib/phoenix_kit_web/live/modules.ex @@ -32,6 +32,7 @@ defmodule PhoenixKitWeb.Live.Modules do external_modules = load_external_modules(module_configs) dep_warnings = ModuleRegistry.dependency_warnings() not_installed = ModuleRegistry.not_installed_packages() + not_installed_keys = not_installed |> Enum.map(& &1.key) |> MapSet.new() socket = socket @@ -42,6 +43,7 @@ defmodule PhoenixKitWeb.Live.Modules do |> assign(:external_modules, external_modules) |> assign(:dep_warnings, dep_warnings) |> assign(:not_installed_packages, not_installed) + |> assign(:not_installed_keys, not_installed_keys) {:ok, socket} end @@ -458,9 +460,23 @@ defmodule PhoenixKitWeb.Live.Modules do icon: (perm && perm[:icon]) || "hero-puzzle-piece", description: (perm && perm[:description]) || "External module", enabled: config[:enabled] || false, - version: if(function_exported?(mod, :version, 0), do: mod.version(), else: "0.0.0") + version: if(function_exported?(mod, :version, 0), do: mod.version(), else: "0.0.0"), + required_modules: + if(function_exported?(mod, :required_modules, 0), do: mod.required_modules(), else: []), + admin_links: extract_admin_links(mod) } end) |> Enum.sort_by(& &1.name) end + + defp extract_admin_links(mod) do + if Code.ensure_loaded?(mod) and function_exported?(mod, :admin_tabs, 0) do + mod.admin_tabs() + |> Enum.filter(fn tab -> tab.live_view != nil and tab.visible != false end) + |> Enum.take(3) + |> Enum.map(fn tab -> %{label: tab.label, path: "/admin/" <> tab.path, icon: tab.icon} end) + else + [] + end + end end diff --git a/lib/phoenix_kit_web/live/modules.html.heex b/lib/phoenix_kit_web/live/modules.html.heex index d1bcf1570..003a3926c 100644 --- a/lib/phoenix_kit_web/live/modules.html.heex +++ b/lib/phoenix_kit_web/live/modules.html.heex @@ -211,50 +211,6 @@ <% end %> - <%!-- Newsletters Module --%> - <%= if "newsletters" in @accessible_modules do %> - <% cfg = @module_configs["newsletters"] || %{} %> - - <:status_badges> - - {if cfg[:enabled], do: "Enabled", else: "Disabled"} - - <%= unless mcfg(@module_configs, "emails", :enabled, false) do %> - Requires Emails - <% end %> - - - <:action_buttons> - <%= if cfg[:enabled] do %> -
- <.link - navigate={PhoenixKit.Utils.Routes.path("/admin/newsletters/broadcasts")} - class="btn btn-outline btn-sm flex-1" - > - <.icon name="hero-paper-airplane" class="w-4 h-4 mr-1" /> Broadcasts - - <.link - navigate={PhoenixKit.Utils.Routes.path("/admin/newsletters/lists")} - class="btn btn-outline btn-sm flex-1" - > - <.icon name="hero-list-bullet" class="w-4 h-4 mr-1" /> Lists - -
- <% end %> - -
- <% end %> - <%!-- Languages Module --%> <%= if "languages" in @accessible_modules do %> <% cfg = @module_configs["languages"] || %{} %> @@ -1412,11 +1368,34 @@ v{ext.version} External + <%= for req_mod <- ext.required_modules do %> + <%= unless mcfg(@module_configs, req_mod, :enabled, false) do %> + + Requires {String.capitalize(req_mod)} + + <% end %> + <% end %> {if ext.enabled, do: "Module is active", else: "Enable to activate"} + + <%= if ext.enabled and ext.admin_links != [] do %> +
+ <%= for link <- ext.admin_links do %> + <.link + navigate={PhoenixKit.Utils.Routes.path(link.path)} + class="btn btn-outline btn-sm flex-1" + > + <%= if link.icon do %> + <.icon name={link.icon} class="w-4 h-4 mr-1" /> + <% end %> + {link.label} + + <% end %> +
+ <% end %> <% end %> From e3e74f8788f937d158c9b36276de0ce2bbc9bb9e Mon Sep 17 00:00:00 2001 From: timujeen Date: Tue, 17 Mar 2026 10:41:09 +0000 Subject: [PATCH 3/3] Fix Magic Link registration ignoring allow_registration setting - Block Magic Link registration page when allow_registration is disabled - Redirect to login with flash error message - Disable Magic Link checkbox in authorization settings when registration is off - Show visual hint "(registration disabled)" on disabled checkbox --- .../live/settings/authorization.html.heex | 16 +++++++-- .../users/magic_link_registration_request.ex | 33 +++++++++++++------ 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/lib/phoenix_kit_web/live/settings/authorization.html.heex b/lib/phoenix_kit_web/live/settings/authorization.html.heex index 8c36bb9f6..d46c4697e 100644 --- a/lib/phoenix_kit_web/live/settings/authorization.html.heex +++ b/lib/phoenix_kit_web/live/settings/authorization.html.heex @@ -274,10 +274,22 @@ name="settings[magic_link_registration_enabled]" type="checkbox" value="true" - checked={@settings["magic_link_registration_enabled"] == "true"} + checked={ + @settings["magic_link_registration_enabled"] == "true" and + @settings["allow_registration"] == "true" + } + disabled={@settings["allow_registration"] != "true"} class="checkbox checkbox-primary" /> - Enable Magic Link for registration + + Enable Magic Link for registration + <%= if @settings["allow_registration"] != "true" do %> + (registration disabled) + <% end %> + diff --git a/lib/phoenix_kit_web/users/magic_link_registration_request.ex b/lib/phoenix_kit_web/users/magic_link_registration_request.ex index 9941edbd7..8c2d4d1f6 100644 --- a/lib/phoenix_kit_web/users/magic_link_registration_request.ex +++ b/lib/phoenix_kit_web/users/magic_link_registration_request.ex @@ -8,6 +8,7 @@ defmodule PhoenixKitWeb.Users.MagicLinkRegistrationRequest do use PhoenixKitWeb, :live_view alias Phoenix.LiveView.JS + alias PhoenixKit.Settings alias PhoenixKit.Users.MagicLinkRegistration alias PhoenixKit.Utils.Routes alias PhoenixKitWeb.Users.Auth @@ -19,17 +20,29 @@ defmodule PhoenixKitWeb.Users.MagicLinkRegistrationRequest do {:ok, socket} :cont -> - # Get project title from settings (with Config fallback) - project_title = PhoenixKit.Settings.get_project_title() + if Settings.get_boolean_setting("allow_registration", true) do + # Get project title from settings (with Config fallback) + project_title = PhoenixKit.Settings.get_project_title() - {:ok, - socket - |> assign(:page_title, "Register via Magic Link") - |> assign(:project_title, project_title) - |> assign(:email, "") - |> assign(:email_sent, false) - |> assign(:error_message, nil) - |> assign(:loading, false)} + {:ok, + socket + |> assign(:page_title, "Register via Magic Link") + |> assign(:project_title, project_title) + |> assign(:email, "") + |> assign(:email_sent, false) + |> assign(:error_message, nil) + |> assign(:loading, false)} + else + socket = + socket + |> put_flash( + :error, + "User registration is currently disabled. Please contact an administrator." + ) + |> redirect(to: Routes.path("/users/log-in")) + + {:ok, socket} + end end end