diff --git a/assets/css/app.css b/assets/css/app.css index 21b1b25..1d82f73 100644 --- a/assets/css/app.css +++ b/assets/css/app.css @@ -369,4 +369,37 @@ left: 0 !important; } +/* Sign-in: hide SSO button and "or" divider when OIDC is not configured. + Use .divider (DaisyUI HorizontalRule) because LiveView does not set id on component root. */ +[data-oidc-configured="false"] [id*="oidc"] { + display: none !important; +} +[data-oidc-configured="false"] a[href*="oidc"] { + display: none !important; +} +[data-oidc-configured="false"] .divider { + display: none !important; +} + +/* Sign-in: when OIDC-only mode is on, hide password form and "or" divider (show only SSO). */ +[data-oidc-configured="true"][data-oidc-only="true"] [id*="password"] { + display: none !important; +} +[data-oidc-configured="true"][data-oidc-only="true"] .divider { + display: none !important; +} + +/* Sign-in: show "oder" instead of "or" when locale is German (override is compile-time only). + Target div.contents so ::after has a box (span may have display:contents). */ +[data-locale="de"] .divider div.contents { + display: block !important; +} +[data-locale="de"] .divider div.contents > span { + font-size: 0; +} +[data-locale="de"] .divider div.contents::after { + content: "oder"; + font-size: 1rem; +} + /* This file is for your main application CSS */ diff --git a/lib/mv_web/auth_overrides.ex b/lib/mv_web/auth_overrides.ex index b121c4e..f28d81f 100644 --- a/lib/mv_web/auth_overrides.ex +++ b/lib/mv_web/auth_overrides.ex @@ -38,12 +38,10 @@ defmodule MvWeb.AuthOverrides do set :image_url, nil end - # Translate the or in the horizontal rule to German + # Translate the "or" in the horizontal rule (between password form and SSO). + # Uses auth domain so it respects the current locale (e.g. "oder" in German). override AshAuthentication.Phoenix.Components.HorizontalRule do - set :text, - Gettext.with_locale(MvWeb.Gettext, "de", fn -> - Gettext.gettext(MvWeb.Gettext, "or") - end) + set :text, dgettext("auth", "or") end # Hide AshAuthentication's Flash component since we use flash_group in root layout diff --git a/lib/mv_web/live/auth/sign_in_live.ex b/lib/mv_web/live/auth/sign_in_live.ex new file mode 100644 index 0000000..5d2a0dc --- /dev/null +++ b/lib/mv_web/live/auth/sign_in_live.ex @@ -0,0 +1,105 @@ +defmodule MvWeb.SignInLive do + @moduledoc """ + Custom sign-in page with language selector and conditional Single Sign-On button. + + - Renders a language selector (same pattern as LinkOidcAccountLive). + - Wraps the default AshAuthentication SignIn component in a container with + `data-oidc-configured` so that CSS can hide the SSO button when OIDC is not configured. + """ + use Phoenix.LiveView + use Gettext, backend: MvWeb.Gettext + + alias AshAuthentication.Phoenix.Components + alias Mv.Config + + @impl true + def mount(_params, session, socket) do + overrides = + session + |> Map.get("overrides", [AshAuthentication.Phoenix.Overrides.Default]) + + # Locale from session (set by set_locale plug / LiveUserAuth); default "de" + locale = session["locale"] || "de" + Gettext.put_locale(MvWeb.Gettext, locale) + + socket = + socket + |> assign(overrides: overrides) + |> assign_new(:otp_app, fn -> nil end) + |> assign(:path, session["path"] || "/") + |> assign(:reset_path, session["reset_path"]) + |> assign(:register_path, session["register_path"]) + |> assign(:current_tenant, session["tenant"]) + |> assign(:resources, session["resources"]) + |> assign(:context, session["context"] || %{}) + |> assign(:auth_routes_prefix, session["auth_routes_prefix"]) + |> assign(:gettext_fn, session["gettext_fn"]) + |> assign(:live_action, :sign_in) + |> assign(:oidc_configured, Config.oidc_configured?()) + |> assign(:oidc_only, Config.oidc_only?()) + |> assign(:root_class, "grid h-screen place-items-center bg-base-100") + |> assign(:sign_in_id, "sign-in") + |> assign(:locale, locale) + + {:ok, socket} + end + + @impl true + def handle_params(_, _uri, socket) do + {:noreply, socket} + end + + @impl true + def render(assigns) do + ~H""" +