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.
This commit is contained in:
parent
6a4a99f638
commit
a7ad608051
2 changed files with 40 additions and 8 deletions
|
|
@ -31,27 +31,24 @@ defmodule MvWeb.LiveUserAuth do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def on_mount(:live_user_required, _params, session, socket) do
|
def on_mount(:live_user_required, _params, _session, socket) do
|
||||||
socket = LiveSession.assign_new_resources(socket, session)
|
|
||||||
|
|
||||||
case socket.assigns do
|
case socket.assigns do
|
||||||
%{current_user: %{} = user} ->
|
%{current_user: %{} = user} ->
|
||||||
{:cont, assign(socket, :current_user, user)}
|
{:cont, assign(socket, :current_user, user)}
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
socket = LiveView.redirect(socket, to: ~p"/sign-in")
|
{:halt, LiveView.redirect(socket, to: ~p"/sign-in")}
|
||||||
{:halt, socket}
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def on_mount(:live_no_user, _params, session, socket) do
|
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).
|
# 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")
|
locale = session["locale"] || Application.get_env(:mv, :default_locale, "de")
|
||||||
Gettext.put_locale(MvWeb.Gettext, locale)
|
_ = Gettext.put_locale(MvWeb.Gettext, locale)
|
||||||
{:cont, assign(socket, :locale, locale)}
|
socket = assign(socket, :locale, locale)
|
||||||
|
|
||||||
if socket.assigns[:current_user] do
|
if socket.assigns[:current_user] do
|
||||||
{:halt, Phoenix.LiveView.redirect(socket, to: ~p"/")}
|
{:halt, LiveView.redirect(socket, to: ~p"/")}
|
||||||
else
|
else
|
||||||
{:cont, assign(socket, :current_user, nil)}
|
{:cont, assign(socket, :current_user, nil)}
|
||||||
end
|
end
|
||||||
|
|
|
||||||
35
test/mv_web/live_user_auth_test.exs
Normal file
35
test/mv_web/live_user_auth_test.exs
Normal file
|
|
@ -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
|
||||||
Loading…
Add table
Add a link
Reference in a new issue