Merge auth links into main nav and lower password min to 8
- Register/Log in (or callsign/Settings/Log out) now live next to the Map/Path/Rover links in the main header instead of a separate top menu bar - Add on_mount in UserAuth to assign current_scope on LiveView mount, and pass current_scope through to Layouts.app from every LiveView - Drop the old top <ul> from root.html.heex - Password minimum lowered from 12 to 8 characters
This commit is contained in:
parent
f75d0e7f54
commit
27170b5139
13 changed files with 50 additions and 34 deletions
|
|
@ -131,7 +131,7 @@ defmodule Microwaveprop.Accounts.User do
|
|||
defp validate_password(changeset, opts) do
|
||||
changeset
|
||||
|> validate_required([:password])
|
||||
|> validate_length(:password, min: 12, max: 72)
|
||||
|> validate_length(:password, min: 8, max: 72)
|
||||
# Examples of additional password validation:
|
||||
# |> validate_format(:password, ~r/[a-z]/, message: "at least one lower case character")
|
||||
# |> validate_format(:password, ~r/[A-Z]/, message: "at least one upper case character")
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@ defmodule MicrowavepropWeb do
|
|||
quote do
|
||||
use Phoenix.LiveView
|
||||
|
||||
on_mount MicrowavepropWeb.UserAuth
|
||||
|
||||
unquote(html_helpers())
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -46,6 +46,18 @@ defmodule MicrowavepropWeb.Layouts do
|
|||
<.link navigate="/contacts/map" class="btn btn-ghost btn-sm">Contact Map</.link>
|
||||
<.link navigate="/contacts" class="btn btn-ghost btn-sm">Contacts</.link>
|
||||
<.link navigate="/submit" class="btn btn-ghost btn-sm">Submit</.link>
|
||||
<%= if @current_scope && @current_scope.user do %>
|
||||
<span class="btn btn-ghost btn-sm pointer-events-none opacity-70">
|
||||
{@current_scope.user.callsign}
|
||||
</span>
|
||||
<.link href={~p"/users/settings"} class="btn btn-ghost btn-sm">Settings</.link>
|
||||
<.link href={~p"/users/log-out"} method="delete" class="btn btn-ghost btn-sm">
|
||||
Log out
|
||||
</.link>
|
||||
<% else %>
|
||||
<.link href={~p"/users/register"} class="btn btn-ghost btn-sm">Register</.link>
|
||||
<.link href={~p"/users/log-in"} class="btn btn-ghost btn-sm">Log in</.link>
|
||||
<% end %>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="flex-none">
|
||||
|
|
|
|||
|
|
@ -37,26 +37,6 @@
|
|||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<ul class="menu menu-horizontal w-full relative z-10 flex items-center gap-4 px-4 sm:px-6 lg:px-8 justify-end">
|
||||
<%= if @current_scope do %>
|
||||
<li>
|
||||
{@current_scope.user.email}
|
||||
</li>
|
||||
<li>
|
||||
<.link href={~p"/users/settings"}>Settings</.link>
|
||||
</li>
|
||||
<li>
|
||||
<.link href={~p"/users/log-out"} method="delete">Log out</.link>
|
||||
</li>
|
||||
<% else %>
|
||||
<li>
|
||||
<.link href={~p"/users/register"}>Register</.link>
|
||||
</li>
|
||||
<li>
|
||||
<.link href={~p"/users/log-in"}>Log in</.link>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
{@inner_content}
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ defmodule MicrowavepropWeb.AlgoLive do
|
|||
@impl true
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<Layouts.app flash={@flash}>
|
||||
<Layouts.app flash={@flash} current_scope={@current_scope}>
|
||||
<div class="markdown-content">
|
||||
{raw(@content)}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -311,7 +311,7 @@ defmodule MicrowavepropWeb.BackfillLive do
|
|||
@impl true
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<Layouts.app flash={@flash}>
|
||||
<Layouts.app flash={@flash} current_scope={@current_scope}>
|
||||
<.header>
|
||||
Backfill Dashboard
|
||||
<:subtitle>Enqueue and monitor contact enrichment jobs</:subtitle>
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ defmodule MicrowavepropWeb.ContactLive.Index do
|
|||
@impl true
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<Layouts.app flash={@flash} max_width="max-w-7xl">
|
||||
<Layouts.app flash={@flash} current_scope={@current_scope} max_width="max-w-7xl">
|
||||
<.header>
|
||||
Contacts
|
||||
<:subtitle>{@total_entries} contacts</:subtitle>
|
||||
|
|
|
|||
|
|
@ -435,7 +435,7 @@ defmodule MicrowavepropWeb.ContactLive.Show do
|
|||
@impl true
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<Layouts.app flash={@flash}>
|
||||
<Layouts.app flash={@flash} current_scope={@current_scope}>
|
||||
<.header>
|
||||
<span class={[@contact.flagged_invalid && "line-through opacity-50"]}>
|
||||
{@contact.station1} / {@contact.station2}
|
||||
|
|
|
|||
|
|
@ -466,7 +466,7 @@ defmodule MicrowavepropWeb.PathLive do
|
|||
@impl true
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<Layouts.app flash={@flash} max_width="max-w-6xl">
|
||||
<Layouts.app flash={@flash} current_scope={@current_scope} max_width="max-w-6xl">
|
||||
<.header>
|
||||
Path Calculator
|
||||
<:subtitle>Analyze microwave propagation between two points</:subtitle>
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ defmodule MicrowavepropWeb.SubmitLive do
|
|||
@impl true
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<Layouts.app flash={@flash}>
|
||||
<Layouts.app flash={@flash} current_scope={@current_scope}>
|
||||
<.header>
|
||||
Submit Contact
|
||||
<:subtitle>Help us build a better propagation model</:subtitle>
|
||||
|
|
|
|||
|
|
@ -18,6 +18,28 @@ defmodule MicrowavepropWeb.UserAuth do
|
|||
same_site: "Lax"
|
||||
]
|
||||
|
||||
@doc """
|
||||
LiveView `on_mount` callback that assigns `:current_scope` from the
|
||||
session token so LiveView templates can show auth-aware navigation.
|
||||
"""
|
||||
def on_mount(:default, _params, session, socket) do
|
||||
{:cont, mount_current_scope(socket, session)}
|
||||
end
|
||||
|
||||
defp mount_current_scope(socket, session) do
|
||||
Phoenix.Component.assign_new(socket, :current_scope, fn ->
|
||||
user =
|
||||
with token when is_binary(token) <- session["user_token"],
|
||||
{user, _inserted_at} <- Accounts.get_user_by_session_token(token) do
|
||||
user
|
||||
else
|
||||
_ -> nil
|
||||
end
|
||||
|
||||
Scope.for_user(user)
|
||||
end)
|
||||
end
|
||||
|
||||
# How old the session token should be before a new one is issued. When a request is made
|
||||
# with a session token older than this value, then a new session token will be created
|
||||
# and the session and remember-me cookies (if set) will be updated with the new token.
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ defmodule Microwaveprop.AccountsTest do
|
|||
{:error, changeset} =
|
||||
Accounts.register_user(valid_user_attributes(password: "short"))
|
||||
|
||||
assert "should be at least 12 character(s)" in errors_on(changeset).password
|
||||
assert "should be at least 8 character(s)" in errors_on(changeset).password
|
||||
end
|
||||
|
||||
test "registers a valid user but leaves them unconfirmed" do
|
||||
|
|
@ -323,12 +323,12 @@ defmodule Microwaveprop.AccountsTest do
|
|||
test "validates password", %{user: user} do
|
||||
{:error, changeset} =
|
||||
Accounts.update_user_password(user, %{
|
||||
password: "not valid",
|
||||
password_confirmation: "another"
|
||||
password: "short",
|
||||
password_confirmation: "other"
|
||||
})
|
||||
|
||||
assert %{
|
||||
password: ["should be at least 12 character(s)"],
|
||||
password: ["should be at least 8 character(s)"],
|
||||
password_confirmation: ["does not match password"]
|
||||
} = errors_on(changeset)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -56,14 +56,14 @@ defmodule MicrowavepropWeb.UserSettingsControllerTest do
|
|||
put(conn, ~p"/users/settings", %{
|
||||
"action" => "update_password",
|
||||
"user" => %{
|
||||
"password" => "too short",
|
||||
"password_confirmation" => "does not match"
|
||||
"password" => "short",
|
||||
"password_confirmation" => "nope"
|
||||
}
|
||||
})
|
||||
|
||||
response = html_response(old_password_conn, 200)
|
||||
assert response =~ "Settings"
|
||||
assert response =~ "should be at least 12 character(s)"
|
||||
assert response =~ "should be at least 8 character(s)"
|
||||
assert response =~ "does not match password"
|
||||
|
||||
assert get_session(old_password_conn, :user_token) == get_session(conn, :user_token)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue