From a7ad60805138cfc64ea1b548d7514ff11d2964ec Mon Sep 17 00:00:00 2001 From: Moritz Date: Tue, 2 Jun 2026 12:19:21 +0200 Subject: [PATCH] fix(auth): redirect a live-view socket in the user-required guard LiveSession.assign_new_resources/2 is typed to return a Phoenix.Socket, which made the on_mount redirect type-incompatible. The authenticated-routes live_session already assigns current_user, so the guard reads it from socket.assigns directly. Also assign the locale into the socket actually used by the no-user redirect instead of discarding it. --- lib/mv_web/live_user_auth.ex | 13 +++++------ test/mv_web/live_user_auth_test.exs | 35 +++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 8 deletions(-) create mode 100644 test/mv_web/live_user_auth_test.exs diff --git a/lib/mv_web/live_user_auth.ex b/lib/mv_web/live_user_auth.ex index f3f3fc9..617b079 100644 --- a/lib/mv_web/live_user_auth.ex +++ b/lib/mv_web/live_user_auth.ex @@ -31,27 +31,24 @@ defmodule MvWeb.LiveUserAuth do end end - def on_mount(:live_user_required, _params, session, socket) do - socket = LiveSession.assign_new_resources(socket, session) - + def on_mount(:live_user_required, _params, _session, socket) do case socket.assigns do %{current_user: %{} = user} -> {:cont, assign(socket, :current_user, user)} _ -> - socket = LiveView.redirect(socket, to: ~p"/sign-in") - {:halt, socket} + {:halt, LiveView.redirect(socket, to: ~p"/sign-in")} end end def on_mount(:live_no_user, _params, session, socket) do # Set the locale for not logged in user (default from config, "de" in dev/prod). locale = session["locale"] || Application.get_env(:mv, :default_locale, "de") - Gettext.put_locale(MvWeb.Gettext, locale) - {:cont, assign(socket, :locale, locale)} + _ = Gettext.put_locale(MvWeb.Gettext, locale) + socket = assign(socket, :locale, locale) if socket.assigns[:current_user] do - {:halt, Phoenix.LiveView.redirect(socket, to: ~p"/")} + {:halt, LiveView.redirect(socket, to: ~p"/")} else {:cont, assign(socket, :current_user, nil)} end diff --git a/test/mv_web/live_user_auth_test.exs b/test/mv_web/live_user_auth_test.exs new file mode 100644 index 0000000..0f0e1ae --- /dev/null +++ b/test/mv_web/live_user_auth_test.exs @@ -0,0 +1,35 @@ +defmodule MvWeb.LiveUserAuthTest do + @moduledoc """ + Regression tests for the `MvWeb.LiveUserAuth` on_mount guards: + the unauthenticated `:live_user_required` redirect to the sign-in page and + the authenticated `:live_no_user` redirect away from the sign-in page. + """ + use MvWeb.ConnCase, async: false + + import Phoenix.LiveViewTest + + describe ":live_user_required" do + @tag role: :unauthenticated + test "unauthenticated request to a protected route is redirected to sign-in", %{conn: conn} do + assert {:error, {:redirect, %{to: to}}} = live(conn, "/members") + assert to == "/sign-in" + end + + @tag role: :admin + test "authenticated user can mount a protected route", %{conn: conn} do + assert {:ok, _view, _html} = live(conn, "/members") + end + end + + describe ":live_no_user" do + @tag role: :admin + test "authenticated user visiting the sign-in page is redirected to root", %{conn: conn} do + assert {:error, {:redirect, %{to: "/"}}} = live(conn, "/sign-in") + end + + @tag role: :unauthenticated + test "unauthenticated user can reach the sign-in page", %{conn: conn} do + assert {:ok, _view, _html} = live(conn, "/sign-in") + end + end +end