From e56baeb272f9f2a9364828737f415f92a633acba Mon Sep 17 00:00:00 2001 From: Adam Rutkowski Date: Mon, 23 Jun 2025 12:28:27 +0200 Subject: [PATCH] Persist login type preference (SSO/standard) (#5520) * First pass: store login preference * Only set login preference if SSO is used * Change mock DNS to use port 5354 and `domain_id` for parameter * Make login forms use flash message for error passing --------- Co-authored-by: Adrian Gruntkowski --- Makefile | 8 +- config/.env.dev | 2 +- extra/fixture/Corefile.template | 2 +- .../controllers/sso_controller.ex | 16 +++- .../plausible_web/sso/fake_saml_adapter.ex | 10 +-- .../plausible_web/sso/real_saml_adapter.ex | 26 +++--- .../templates/sso/login_form.html.heex | 9 +- .../controllers/auth_controller.ex | 37 +++++++-- lib/plausible_web/login_preference.ex | 40 +++++++++ .../templates/auth/login_form.html.heex | 9 +- lib/plausible_web/user_auth.ex | 8 +- .../controllers/auth_controller_test.exs | 14 ++++ .../controllers/sso_controller_sync_test.exs | 82 +++++++++---------- .../controllers/sso_controller_test.exs | 30 +++++-- test/plausible_web/user_auth_test.exs | 16 ++-- 15 files changed, 208 insertions(+), 101 deletions(-) create mode 100644 lib/plausible_web/login_preference.ex diff --git a/Makefile b/Makefile index d0e6124aac..6b9f995b4a 100644 --- a/Makefile +++ b/Makefile @@ -94,12 +94,12 @@ sso-stop: docker remove idp generate-corefile: - $(call require, integration_id) - integration_id=$(integration_id) envsubst < $(PWD)/extra/fixture/Corefile.template > $(PWD)/extra/fixture/Corefile.gen.$(integration_id) + $(call require, domain_id) + domain_id=$(domain_id) envsubst < $(PWD)/extra/fixture/Corefile.template > $(PWD)/extra/fixture/Corefile.gen.$(domain_id) mock-dns: generate-corefile - $(call require, integration_id) - docker run --rm -p 5353:53/udp -v $(PWD)/extra/fixture/Corefile.gen.$(integration_id):/Corefile coredns/coredns:latest -conf Corefile + $(call require, domain_id) + docker run --rm -p 5354:53/udp -v $(PWD)/extra/fixture/Corefile.gen.$(domain_id):/Corefile coredns/coredns:latest -conf Corefile loadtest-server: @echo "Ensure your OTP installation is built with --enable-lock-counter" diff --git a/config/.env.dev b/config/.env.dev index a2122f288d..6295c57bdf 100644 --- a/config/.env.dev +++ b/config/.env.dev @@ -15,7 +15,7 @@ SHOW_CITIES=true PADDLE_VENDOR_AUTH_CODE=895e20d4efaec0575bb857f44b183217b332d9592e76e69b8a PADDLE_VENDOR_ID=3942 SSO_ENABLED=true -SSO_VERIFICATION_NAMESERVERS=0.0.0.0:5353 +SSO_VERIFICATION_NAMESERVERS=0.0.0.0:5354 GOOGLE_CLIENT_ID=875387135161-l8tp53dpt7fdhdg9m1pc3vl42si95rh0.apps.googleusercontent.com GOOGLE_CLIENT_SECRET=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 diff --git a/extra/fixture/Corefile.template b/extra/fixture/Corefile.template index c7decfab01..361d96bb70 100644 --- a/extra/fixture/Corefile.template +++ b/extra/fixture/Corefile.template @@ -1,7 +1,7 @@ . { bind 0.0.0.0 template IN TXT plausible.test { - answer "{{ .Name }} 60 IN TXT \"plausible-sso-verification=${integration_id}\"" + answer "{{ .Name }} 60 IN TXT \"plausible-sso-verification=${domain_id}\"" fallthrough } log diff --git a/extra/lib/plausible_web/controllers/sso_controller.ex b/extra/lib/plausible_web/controllers/sso_controller.ex index f56bca8037..5196c15d29 100644 --- a/extra/lib/plausible_web/controllers/sso_controller.ex +++ b/extra/lib/plausible_web/controllers/sso_controller.ex @@ -4,6 +4,7 @@ defmodule PlausibleWeb.SSOController do require Logger alias Plausible.Auth.SSO + alias PlausibleWeb.LoginPreference alias PlausibleWeb.Router.Helpers, as: Routes @@ -11,7 +12,16 @@ defmodule PlausibleWeb.SSOController do [:owner] when action in [:sso_settings] def login_form(conn, params) do - render(conn, "login_form.html", error: params["error"]) + login_preference = LoginPreference.get(conn) + error = Phoenix.Flash.get(conn.assigns.flash, :login_error) + + case {login_preference, params["prefer"], error} do + {nil, nil, nil} -> + redirect(conn, to: Routes.auth_path(conn, :login_form, return_to: params["return_to"])) + + _ -> + render(conn, "login_form.html") + end end def login(conn, %{"email" => email} = params) do @@ -29,7 +39,9 @@ defmodule PlausibleWeb.SSOController do ) {:error, :not_found} -> - render(conn, "login_form.html", error: "Wrong email.") + conn + |> put_flash(:login_error, "Wrong email.") + |> redirect(to: Routes.sso_path(conn, :login_form)) end end diff --git a/extra/lib/plausible_web/sso/fake_saml_adapter.ex b/extra/lib/plausible_web/sso/fake_saml_adapter.ex index 0e2033d6fb..328e94f270 100644 --- a/extra/lib/plausible_web/sso/fake_saml_adapter.ex +++ b/extra/lib/plausible_web/sso/fake_saml_adapter.ex @@ -48,12 +48,10 @@ defmodule PlausibleWeb.SSO.FakeSAMLAdapter do PlausibleWeb.UserAuth.log_in_user(conn, identity, params["return_to"]) {:error, :not_found} -> - Phoenix.Controller.redirect(conn, - to: - Routes.sso_path(conn, :login_form, - error: "Wrong email.", - return_to: params["return_to"] - ) + conn + |> Phoenix.Controller.put_flash(:login_error, "Wrong email.") + |> Phoenix.Controller.redirect( + to: Routes.sso_path(conn, :login_form, return_to: params["return_to"]) ) end end diff --git a/extra/lib/plausible_web/sso/real_saml_adapter.ex b/extra/lib/plausible_web/sso/real_saml_adapter.ex index 4579e962f9..da5480d3e1 100644 --- a/extra/lib/plausible_web/sso/real_saml_adapter.ex +++ b/extra/lib/plausible_web/sso/real_saml_adapter.ex @@ -50,12 +50,10 @@ defmodule PlausibleWeb.SSO.RealSAMLAdapter do |> Phoenix.Controller.redirect(external: url) {:error, :not_found} -> - Phoenix.Controller.redirect(conn, - to: - Routes.sso_path(conn, :login_form, - error: "Wrong email.", - return_to: return_to - ) + conn + |> Phoenix.Controller.put_flash(:login_error, "Wrong email.") + |> Phoenix.Controller.redirect( + to: Routes.sso_path(conn, :login_form, return_to: return_to) ) end end @@ -72,9 +70,9 @@ defmodule PlausibleWeb.SSO.RealSAMLAdapter do |> consume(integration_id, cookie, saml_response, relay_state) {:error, :session_expired} -> - Phoenix.Controller.redirect(conn, - to: Routes.sso_path(conn, :login_form, error: "Session expired.") - ) + conn + |> Phoenix.Controller.put_flash(:login_error, "Session expired.") + |> Phoenix.Controller.redirect(to: Routes.sso_path(conn, :login_form)) end end @@ -105,12 +103,10 @@ defmodule PlausibleWeb.SSO.RealSAMLAdapter do PlausibleWeb.UserAuth.log_in_user(conn, identity, cookie.return_to) else {:error, reason} -> - Phoenix.Controller.redirect(conn, - to: - Routes.sso_path(conn, :login_form, - error: error_by_reason(reason), - return_to: cookie.return_to - ) + conn + |> Phoenix.Controller.put_flash(:login_error, error_by_reason(reason)) + |> Phoenix.Controller.redirect( + to: Routes.sso_path(conn, :login_form, return_to: cookie.return_to) ) end end diff --git a/extra/lib/plausible_web/templates/sso/login_form.html.heex b/extra/lib/plausible_web/templates/sso/login_form.html.heex index 8e8aaeea08..3234d9a44a 100644 --- a/extra/lib/plausible_web/templates/sso/login_form.html.heex +++ b/extra/lib/plausible_web/templates/sso/login_form.html.heex @@ -19,8 +19,8 @@ /> - <%= if @conn.assigns[:error] do %> -
{@conn.assigns[:error]}
+ <%= if login_error = Phoenix.Flash.get(@flash, :login_error) do %> +
{login_error}
<% end %> <.input type="hidden" field={f[:return_to]} /> @@ -33,7 +33,10 @@ <:item> Have a standard account? <.styled_link href={ - Routes.auth_path(@conn, :login_form, return_to: @conn.params["return_to"]) + Routes.auth_path(@conn, :login_form, + return_to: @conn.params["return_to"], + prefer: "manual" + ) }> Log in here diff --git a/lib/plausible_web/controllers/auth_controller.ex b/lib/plausible_web/controllers/auth_controller.ex index afd442d6ad..38d7c31337 100644 --- a/lib/plausible_web/controllers/auth_controller.ex +++ b/lib/plausible_web/controllers/auth_controller.ex @@ -1,11 +1,13 @@ defmodule PlausibleWeb.AuthController do use PlausibleWeb, :controller use Plausible.Repo + use Plausible alias Plausible.Auth alias Plausible.Teams alias PlausibleWeb.TwoFactor alias PlausibleWeb.UserAuth + alias PlausibleWeb.LoginPreference require Logger @@ -227,8 +229,27 @@ defmodule PlausibleWeb.AuthController do |> redirect(to: Routes.auth_path(conn, :login_form)) end - def login_form(conn, _params) do - render(conn, "login_form.html") + on_ee do + def login_form(conn, params) do + login_preference = LoginPreference.get(conn) + error = Phoenix.Flash.get(conn.assigns.flash, :login_error) + + case {login_preference, params["prefer"], error} do + {"sso", nil, nil} -> + if Plausible.sso_enabled?() do + redirect(conn, to: Routes.sso_path(conn, :login_form, return_to: params["return_to"])) + else + render(conn, "login_form.html") + end + + _ -> + render(conn, "login_form.html") + end + end + else + def login_form(conn, _params) do + render(conn, "login_form.html") + end end def login(conn, %{"user" => params}) do @@ -268,18 +289,24 @@ defmodule PlausibleWeb.AuthController do params["return_to"] end - UserAuth.log_in_user(conn, user, redirect_path) + conn + |> LoginPreference.clear() + |> UserAuth.log_in_user(user, redirect_path) else {:error, :wrong_password} -> maybe_log_failed_login_attempts("wrong password for #{email}") - render(conn, "login_form.html", error: "Wrong email or password. Please try again.") + conn + |> put_flash(:login_error, "Wrong email or password. Please try again.") + |> render("login_form.html") {:error, :user_not_found} -> maybe_log_failed_login_attempts("user not found for #{email}") Plausible.Auth.Password.dummy_calculation() - render(conn, "login_form.html", error: "Wrong email or password. Please try again.") + conn + |> put_flash(:login_error, "Wrong email or password. Please try again.") + |> render("login_form.html") {:error, {:rate_limit, _}} -> maybe_log_failed_login_attempts("too many login attempts for #{email}") diff --git a/lib/plausible_web/login_preference.ex b/lib/plausible_web/login_preference.ex new file mode 100644 index 0000000000..3b88cfd5f2 --- /dev/null +++ b/lib/plausible_web/login_preference.ex @@ -0,0 +1,40 @@ +defmodule PlausibleWeb.LoginPreference do + @moduledoc """ + Functions for managing user login preference cookies. + + This module handles storing and retrieving the user's preferred login method + (standard or SSO) to provide a better user experience by showing their + preferred option first. + """ + + @cookie_name "login_preference" + @cookie_max_age 60 * 60 * 24 * 365 + + @spec set_sso(Plug.Conn.t()) :: Plug.Conn.t() + def set_sso(conn) do + secure_cookie = PlausibleWeb.Endpoint.secure_cookie?() + + Plug.Conn.put_resp_cookie(conn, @cookie_name, "sso", + http_only: true, + secure: secure_cookie, + max_age: @cookie_max_age, + same_site: "Lax" + ) + end + + @spec clear(Plug.Conn.t()) :: Plug.Conn.t() + def clear(conn) do + Plug.Conn.delete_resp_cookie(conn, @cookie_name) + end + + @spec get(Plug.Conn.t()) :: String.t() | nil + def get(conn) do + case Plug.Conn.fetch_cookies(conn) do + %{cookies: %{@cookie_name => "sso"}} -> + "sso" + + _ -> + nil + end + end +end diff --git a/lib/plausible_web/templates/auth/login_form.html.heex b/lib/plausible_web/templates/auth/login_form.html.heex index e064dfdcff..1a5d459d2e 100644 --- a/lib/plausible_web/templates/auth/login_form.html.heex +++ b/lib/plausible_web/templates/auth/login_form.html.heex @@ -29,8 +29,8 @@ /> - <%= if @conn.assigns[:error] do %> -
{@conn.assigns[:error]}
+ <%= if login_error = Phoenix.Flash.get(@flash, :login_error) do %> +
{login_error}
<% end %> <.input type="hidden" field={f[:return_to]} /> @@ -53,7 +53,10 @@ <%= on_ee do %> Have a Single Sign-on account? <.styled_link href={ - Routes.sso_path(@conn, :login_form, return_to: @conn.params["return_to"]) + Routes.sso_path(@conn, :login_form, + return_to: @conn.params["return_to"], + prefer: "manual" + ) }> Sign in here diff --git a/lib/plausible_web/user_auth.ex b/lib/plausible_web/user_auth.ex index 39dd6be60a..0f680e385c 100644 --- a/lib/plausible_web/user_auth.ex +++ b/lib/plausible_web/user_auth.ex @@ -44,15 +44,16 @@ defmodule PlausibleWeb.UserAuth do conn |> set_user_token(session.token) |> Plug.Conn.put_session("current_team_id", team.identifier) + |> PlausibleWeb.LoginPreference.set_sso() |> set_logged_in_cookie() |> Phoenix.Controller.redirect(to: redirect_to) {:error, :integration_not_found} -> conn |> log_out_user() + |> Phoenix.Controller.put_flash(:login_error, "Wrong email.") |> Phoenix.Controller.redirect( - to: - Routes.sso_path(conn, :login_form, error: "Wrong email.", return_to: redirect_path) + to: Routes.sso_path(conn, :login_form, return_to: redirect_path) ) {:error, :over_limit} -> @@ -60,8 +61,9 @@ defmodule PlausibleWeb.UserAuth do conn |> log_out_user() + |> Phoenix.Controller.put_flash(:login_error, error) |> Phoenix.Controller.redirect( - to: Routes.sso_path(conn, :login_form, error: error, return_to: redirect_path) + to: Routes.sso_path(conn, :login_form, return_to: redirect_path) ) {:error, reason, team, user} diff --git a/test/plausible_web/controllers/auth_controller_test.exs b/test/plausible_web/controllers/auth_controller_test.exs index ec4c8aaf8b..50c1ade085 100644 --- a/test/plausible_web/controllers/auth_controller_test.exs +++ b/test/plausible_web/controllers/auth_controller_test.exs @@ -488,6 +488,20 @@ defmodule PlausibleWeb.AuthControllerTest do assert input_value == "/dummy.site" end + + @tag :ee_only + test "redirects to sso login if preferred", %{conn: conn} do + conn = PlausibleWeb.LoginPreference.set_sso(conn) + conn = get(conn, "/login?return_to=foo") + assert redirected_to(conn, 302) == "/sso/login?return_to=foo" + end + + @tag :ee_only + test "keeps standard login form if preference manually overridden", %{conn: conn} do + conn = PlausibleWeb.LoginPreference.set_sso(conn) + conn = get(conn, "/login?prefer=manual") + assert html_response(conn, 200) =~ "Enter your account credentials" + end end describe "POST /login" do diff --git a/test/plausible_web/controllers/sso_controller_sync_test.exs b/test/plausible_web/controllers/sso_controller_sync_test.exs index 3c690ed38d..930a84975d 100644 --- a/test/plausible_web/controllers/sso_controller_sync_test.exs +++ b/test/plausible_web/controllers/sso_controller_sync_test.exs @@ -223,8 +223,9 @@ defmodule PlausibleWeb.SSOControllerSyncTest do ) ) - assert redirected_to(conn, 302) == - Routes.sso_path(conn, :login_form, error: "Wrong email.", return_to: "/sites") + assert redirected_to(conn, 302) == Routes.sso_path(conn, :login_form, return_to: "/sites") + + assert Phoenix.Flash.get(conn.assigns.flash, :login_error) == "Wrong email." end end @@ -341,8 +342,9 @@ defmodule PlausibleWeb.SSOControllerSyncTest do conn = post(conn, Routes.sso_path(conn, :saml_consume, Ecto.UUID.generate()), params) - assert redirected_to(conn, 302) == - Routes.sso_path(conn, :login_form, error: "Wrong email.", return_to: "/sites") + assert redirected_to(conn, 302) == Routes.sso_path(conn, :login_form, return_to: "/sites") + + assert Phoenix.Flash.get(conn.assigns.flash, :login_error) == "Wrong email." end test "redirects with error on mismatch of RelayState", %{ @@ -356,11 +358,10 @@ defmodule PlausibleWeb.SSOControllerSyncTest do conn = post(conn, Routes.sso_path(conn, :saml_consume, integration.identifier), params) - assert redirected_to(conn, 302) == - Routes.sso_path(conn, :login_form, - error: "Authentication failed (reason: :invalid_relay_state).", - return_to: "/sites" - ) + assert redirected_to(conn, 302) == Routes.sso_path(conn, :login_form, return_to: "/sites") + + assert Phoenix.Flash.get(conn.assigns.flash, :login_error) == + "Authentication failed (reason: :invalid_relay_state)." end test "redirects with error on missing relay state", %{ @@ -371,11 +372,10 @@ defmodule PlausibleWeb.SSOControllerSyncTest do conn = post(conn, Routes.sso_path(conn, :saml_consume, integration.identifier), params) - assert redirected_to(conn, 302) == - Routes.sso_path(conn, :login_form, - error: "Authentication failed (reason: :invalid_relay_state).", - return_to: "/sites" - ) + assert redirected_to(conn, 302) == Routes.sso_path(conn, :login_form, return_to: "/sites") + + assert Phoenix.Flash.get(conn.assigns.flash, :login_error) == + "Authentication failed (reason: :invalid_relay_state)." end test "redirects with error on malformed assertion", %{ @@ -390,11 +390,10 @@ defmodule PlausibleWeb.SSOControllerSyncTest do conn = post(conn, Routes.sso_path(conn, :saml_consume, integration.identifier), params) - assert redirected_to(conn, 302) == - Routes.sso_path(conn, :login_form, - error: "Authentication failed (reason: :base64_decoding_failed).", - return_to: "/sites" - ) + assert redirected_to(conn, 302) == Routes.sso_path(conn, :login_form, return_to: "/sites") + + assert Phoenix.Flash.get(conn.assigns.flash, :login_error) == + "Authentication failed (reason: :base64_decoding_failed)." end test "redirects with error on malformed certificate in config (should not happen)", %{ @@ -417,11 +416,10 @@ defmodule PlausibleWeb.SSOControllerSyncTest do conn = post(conn, Routes.sso_path(conn, :saml_consume, integration.identifier), params) - assert redirected_to(conn, 302) == - Routes.sso_path(conn, :login_form, - error: "Authentication failed (reason: :malformed_certificate).", - return_to: "/sites" - ) + assert redirected_to(conn, 302) == Routes.sso_path(conn, :login_form, return_to: "/sites") + + assert Phoenix.Flash.get(conn.assigns.flash, :login_error) == + "Authentication failed (reason: :malformed_certificate)." end test "redirects with error on mismatched certificate in config", %{ @@ -438,11 +436,10 @@ defmodule PlausibleWeb.SSOControllerSyncTest do conn = post(conn, Routes.sso_path(conn, :saml_consume, integration.identifier), params) - assert redirected_to(conn, 302) == - Routes.sso_path(conn, :login_form, - error: "Authentication failed (reason: :digest_verification_failed).", - return_to: "/sites" - ) + assert redirected_to(conn, 302) == Routes.sso_path(conn, :login_form, return_to: "/sites") + + assert Phoenix.Flash.get(conn.assigns.flash, :login_error) == + "Authentication failed (reason: :digest_verification_failed)." end test "redirects with error on missing email attribute in assertion", %{ @@ -457,11 +454,10 @@ defmodule PlausibleWeb.SSOControllerSyncTest do conn = post(conn, Routes.sso_path(conn, :saml_consume, integration.identifier), params) - assert redirected_to(conn, 302) == - Routes.sso_path(conn, :login_form, - error: "Authentication failed (reason: :missing_email_attribute).", - return_to: "/sites" - ) + assert redirected_to(conn, 302) == Routes.sso_path(conn, :login_form, return_to: "/sites") + + assert Phoenix.Flash.get(conn.assigns.flash, :login_error) == + "Authentication failed (reason: :missing_email_attribute)." end test "redirects with error on invalid email attribute in assertion", %{ @@ -476,11 +472,10 @@ defmodule PlausibleWeb.SSOControllerSyncTest do conn = post(conn, Routes.sso_path(conn, :saml_consume, integration.identifier), params) - assert redirected_to(conn, 302) == - Routes.sso_path(conn, :login_form, - error: "Authentication failed (reason: :invalid_email_attribute).", - return_to: "/sites" - ) + assert redirected_to(conn, 302) == Routes.sso_path(conn, :login_form, return_to: "/sites") + + assert Phoenix.Flash.get(conn.assigns.flash, :login_error) == + "Authentication failed (reason: :invalid_email_attribute)." end test "redirects with error on missing name attributes in assertion", %{ @@ -495,11 +490,10 @@ defmodule PlausibleWeb.SSOControllerSyncTest do conn = post(conn, Routes.sso_path(conn, :saml_consume, integration.identifier), params) - assert redirected_to(conn, 302) == - Routes.sso_path(conn, :login_form, - error: "Authentication failed (reason: :missing_name_attributes).", - return_to: "/sites" - ) + assert redirected_to(conn, 302) == Routes.sso_path(conn, :login_form, return_to: "/sites") + + assert Phoenix.Flash.get(conn.assigns.flash, :login_error) == + "Authentication failed (reason: :missing_name_attributes)." end end diff --git a/test/plausible_web/controllers/sso_controller_test.exs b/test/plausible_web/controllers/sso_controller_test.exs index bccbe1fafe..147ad2fce8 100644 --- a/test/plausible_web/controllers/sso_controller_test.exs +++ b/test/plausible_web/controllers/sso_controller_test.exs @@ -24,7 +24,7 @@ defmodule PlausibleWeb.SSOControllerTest do describe "login_form/2" do test "renders login view", %{conn: conn} do - conn = get(conn, Routes.sso_path(conn, :login_form)) + conn = get(conn, Routes.sso_path(conn, :login_form, prefer: "sso")) assert html = html_response(conn, 200) @@ -34,10 +34,27 @@ defmodule PlausibleWeb.SSOControllerTest do end test "passes return_to parameter to form", %{conn: conn} do + conn = get(conn, Routes.sso_path(conn, :login_form, return_to: "/sites", prefer: "sso")) + + assert html = html_response(conn, 200) + + assert text_of_attr(html, "input[name=return_to]", "value") == "/sites" + end + + test "renders error if provided in login_error flash message", %{conn: conn} do + conn = + conn + |> init_session() + |> fetch_session() + |> fetch_flash() + |> put_flash(:login_error, "Wrong email.") + conn = get(conn, Routes.sso_path(conn, :login_form, return_to: "/sites")) assert html = html_response(conn, 200) + assert html =~ "Wrong email." + assert element_exists?(html, "input[name=email]") assert text_of_attr(html, "input[name=return_to]", "value") == "/sites" end end @@ -83,11 +100,9 @@ defmodule PlausibleWeb.SSOControllerTest do "return_to" => "/sites" }) - assert html = html_response(conn, 200) + assert redirected_to(conn, 302) == Routes.sso_path(conn, :login_form) - assert html =~ "Wrong email." - assert element_exists?(html, "input[name=email]") - assert text_of_attr(html, "input[name=return_to]", "value") == "/sites" + assert Phoenix.Flash.get(conn.assigns.flash, :login_error) == "Wrong email." end end @@ -177,8 +192,9 @@ defmodule PlausibleWeb.SSOControllerTest do "return_to" => "/sites" }) - assert redirected_to(conn, 302) == - Routes.sso_path(conn, :login_form, error: "Wrong email.", return_to: "/sites") + assert redirected_to(conn, 302) == Routes.sso_path(conn, :login_form, return_to: "/sites") + + assert Phoenix.Flash.get(conn.assigns.flash, :login_error) == "Wrong email." end end diff --git a/test/plausible_web/user_auth_test.exs b/test/plausible_web/user_auth_test.exs index 46cf421897..421ae22f29 100644 --- a/test/plausible_web/user_auth_test.exs +++ b/test/plausible_web/user_auth_test.exs @@ -140,12 +140,14 @@ defmodule PlausibleWeb.UserAuthTest do conn = conn |> init_session() + |> fetch_flash() |> UserAuth.log_in_user(identity) assert %{sessions: []} = user |> Repo.reload!() |> Repo.preload(:sessions) - assert redirected_to(conn, 302) == - Routes.sso_path(conn, :login_form, error: "Wrong email.", return_to: "") + assert redirected_to(conn, 302) == Routes.sso_path(conn, :login_form, return_to: "") + + assert Phoenix.Flash.get(conn.assigns.flash, :login_error) == "Wrong email." assert conn.private[:plug_session_info] == :renew refute get_session(conn, :user_token) @@ -170,15 +172,15 @@ defmodule PlausibleWeb.UserAuthTest do conn = conn |> init_session() + |> fetch_flash() |> UserAuth.log_in_user(identity) assert %{sessions: []} = user |> Repo.reload!() |> Repo.preload(:sessions) - assert redirected_to(conn, 302) == - Routes.sso_path(conn, :login_form, - error: "Team can't accept more members. Please contact the owner.", - return_to: "" - ) + assert redirected_to(conn, 302) == Routes.sso_path(conn, :login_form, return_to: "") + + assert Phoenix.Flash.get(conn.assigns.flash, :login_error) == + "Team can't accept more members. Please contact the owner." assert conn.private[:plug_session_info] == :renew refute get_session(conn, :user_token)