Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: upgrade to verified routes #535

Merged
merged 2 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 7 additions & 16 deletions lib/atomic/accounts.ex
Original file line number Diff line number Diff line change
Expand Up @@ -252,15 +252,15 @@ defmodule Atomic.Accounts do
|> Ecto.Multi.delete_all(:tokens, UserToken.user_and_contexts_query(user, [context]))
end

@doc """
@doc ~S"""
Delivers the update email instructions to the given user.

## Examples

iex> deliver_update_email_instructions(
...> user,
...> current_email,
...> &Routes.user_update_email_url(conn, :edit, &1)
...> &url(~p"/users/settings/confirm_email/#{&1}")
...> )
{:ok, %{to: ..., body: ...}}

Expand Down Expand Up @@ -348,21 +348,15 @@ defmodule Atomic.Accounts do

## Confirmation

@doc """
@doc ~S"""
Delivers the confirmation email instructions to the given user.

## Examples

iex> deliver_user_confirmation_instructions(
...> user,
...> &Routes.user_confirmation_url(conn, :edit, &1)
...> )
iex> deliver_user_confirmation_instructions(user, &url(~p"/users/confirm/#{&1}"))
{:ok, %{to: ..., body: ...}}

iex> deliver_user_confirmation_instructions(
...> confirmed_user,
...> &Routes.user_confirmation_url(conn, :edit, &1)
...> )
iex> deliver_user_confirmation_instructions(confirmed_user, &url(~p"/users/confirm/#{&1}"))
{:error, :already_confirmed}

"""
Expand Down Expand Up @@ -401,15 +395,12 @@ defmodule Atomic.Accounts do

## Reset password

@doc """
@doc ~S"""
Delivers the reset password email to the given user.

## Examples

iex> deliver_user_reset_password_instructions(
...> user,
...> &Routes.user_reset_password_url(conn, :edit, &1)
...> )
iex> deliver_user_reset_password_instructions(user, &url(~p"/users/reset_password/#{&1}"))
{:ok, %{to: ..., body: ...}}

"""
Expand Down
24 changes: 17 additions & 7 deletions lib/atomic_web.ex
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,16 @@ defmodule AtomicWeb do
and import those modules here.
"""

def static_paths, do: ~w(assets fonts images favicon.ico robots.txt)

def controller do
quote do
use Phoenix.Controller, namespace: AtomicWeb
use Gettext, backend: AtomicWeb.Gettext

import Plug.Conn

alias AtomicWeb.Router.Helpers, as: Routes
unquote(verified_routes())
end
end

Expand Down Expand Up @@ -85,29 +87,37 @@ defmodule AtomicWeb do
end
end

def verified_routes do
quote do
use Phoenix.VerifiedRoutes,
endpoint: AtomicWeb.Endpoint,
router: AtomicWeb.Router,
statics: AtomicWeb.static_paths()
end
end

defp view_helpers do
quote do
# Use all HTML functionality (forms, tags, etc)
use Phoenix.HTML

# Import LiveView and .heex helpers (live_render, live_patch, <.form>, etc)
# Import LiveView and .heex helpers (<.link>, <.form>, etc)
import Phoenix.LiveView.Helpers
import Phoenix.Component

# Import commonly used components
unquote(components())

# Import basic rendering functionality (render, render_layout, etc)
import Phoenix.View

# Custom imports
# Custom uses, imports and aliases
unquote(components())

use AtomicWeb, :verified_routes
use Gettext, backend: AtomicWeb.Gettext

import AtomicWeb.ErrorHelpers
import AtomicWeb.Helpers

alias Atomic.Uploaders
alias AtomicWeb.Router.Helpers, as: Routes
end
end

Expand Down
2 changes: 1 addition & 1 deletion lib/atomic_web/components/activity.ex
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ defmodule AtomicWeb.Components.Activity do
</div>
<div class="min-w-0 flex-1">
<object>
<.link navigate={Routes.organization_show_path(AtomicWeb.Endpoint, :show, @activity.organization.id)}>
<.link navigate={~p"/organizations/#{@activity.organization.id}"}>
<span class="text-sm font-medium text-gray-900 hover:underline focus:outline-none">
<%= @activity.organization.name %>
</span>
Expand Down
2 changes: 1 addition & 1 deletion lib/atomic_web/components/announcement.ex
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ defmodule AtomicWeb.Components.Announcement do
</div>
<div class="min-w-0 flex-1">
<object>
<.link navigate={Routes.organization_show_path(AtomicWeb.Endpoint, :show, @announcement.organization.id)} class="hover:underline focus:outline-none">
<.link navigate={~p"/organizations/#{@announcement.organization.id}"} class="hover:underline focus:outline-none">
<p class="text-sm font-medium text-gray-900">
<%= @announcement.organization.name %>
</p>
Expand Down
4 changes: 2 additions & 2 deletions lib/atomic_web/components/organizations.ex
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ defmodule AtomicWeb.Components.Organizations do
socket
|> assign(current_organization: nil)
|> put_flash(:info, gettext("Now viewing as yourself"))
|> push_navigate(to: Routes.home_index_path(socket, :index))}
|> push_navigate(to: ~p"/")}
else
organization = Organizations.get_organization!(organization_id)

Expand All @@ -64,7 +64,7 @@ defmodule AtomicWeb.Components.Organizations do
socket
|> assign(current_organization: organization)
|> put_flash(:info, "#{gettext("Now editing as")} #{organization.name}")
|> push_navigate(to: Routes.organization_show_path(socket, :show, organization))}
|> push_navigate(to: ~p"/organizations/#{organization}")}
end
end
end
16 changes: 8 additions & 8 deletions lib/atomic_web/components/sidebar.ex
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ defmodule AtomicWeb.Components.Sidebar do
defp sidebar_list(assigns) do
~H"""
<ul role="list" class="-mx-2 space-y-1">
<%= for page <- AtomicWeb.Config.pages(AtomicWeb.Endpoint, @current_user, @current_organization) do %>
<%= for page <- AtomicWeb.Config.pages(@current_user, @current_organization) do %>
<li class="select-none">
<.link navigate={page.url} class={"#{if @current_page == page.key do "bg-zinc-50 text-orange-500" else "text-zinc-700 hover:text-orange-500 hover:bg-zinc-50" end} group flex gap-x-3 rounded-md p-2 text-sm font-semibold leading-6"}>
<.icon name={page.icon} class={
Expand All @@ -123,14 +123,14 @@ defmodule AtomicWeb.Components.Sidebar do
<:wrapper>
<button class="flex w-full select-none flex-row items-center gap-x-2 px-4 py-3 text-sm font-semibold leading-6 text-zinc-700 lg:px-0">
<AtomicWeb.Components.Avatar.avatar name={@current_user.name} src={user_image(@current_user)} size={:xs} color={:light_gray} class="!text-sm" />
<span class="text-sm font-semibold leading-6" aria-hidden="true"><%= @current_user.name %></span>
<span class="text-sm font-semibold leading-6"><%= @current_user.name %></span>
<.icon name="hero-chevron-right-solid" class="size-5" />
</button>
</:wrapper>
</AtomicWeb.Components.Dropdown.dropdown>
<% else %>
<.link navigate={Routes.user_session_path(AtomicWeb.Endpoint, :new)} class="flex select-none items-center space-x-2 px-4 py-3 text-sm font-semibold leading-6 text-zinc-700 lg:px-0">
<span class="text-sm font-semibold leading-6" aria-hidden="true">Sign in</span>
<.link navigate={~p"/users/log_in"} class="flex select-none items-center space-x-2 px-4 py-3 text-sm font-semibold leading-6 text-zinc-700 lg:px-0">
<span class="text-sm font-semibold leading-6">Log in</span>
<.icon name="hero-arrow-right-end-on-rectangle-solid" class="size-5" />
</.link>
<% end %>
Expand All @@ -139,8 +139,8 @@ defmodule AtomicWeb.Components.Sidebar do

defp sidebar_header(assigns) do
~H"""
<.link navigate={Routes.home_index_path(AtomicWeb.Endpoint, :index)} class="flex h-16 shrink-0 select-none items-center gap-x-4 pt-4">
<img src={Routes.static_path(AtomicWeb.Endpoint, "/images/atomic.svg")} class="h-14 w-auto" />
<.link navigate={~p"/"} class="flex h-16 shrink-0 select-none items-center gap-x-4 pt-4">
<img src={~p"/images/atomic.svg"} class="h-14 w-auto" />
<p class="text-2xl font-semibold text-zinc-400">Atomic</p>
</.link>
"""
Expand All @@ -153,11 +153,11 @@ defmodule AtomicWeb.Components.Sidebar do
[
%{
name: gettext("Your profile"),
navigate: Routes.profile_show_path(AtomicWeb.Endpoint, :show, current_user)
navigate: ~p"/profile/#{current_user}"
},
%{
name: gettext("Sign out"),
href: Routes.user_session_path(AtomicWeb.Endpoint, :delete),
href: ~p"/users/log_out",
method: "delete"
}
]
Expand Down
41 changes: 21 additions & 20 deletions lib/atomic_web/config.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,98 +2,99 @@ defmodule AtomicWeb.Config do
@moduledoc """
Web configuration for our pages.
"""
use AtomicWeb, :verified_routes

alias Atomic.Accounts
alias AtomicWeb.Router.Helpers, as: Routes

# User is not logged in
def pages(conn, nil, _current_organization) do
default_pages(conn)
def pages(nil, _current_organization) do
default_pages()
end

# User is logged in
def pages(conn, current_user, current_organization) do
def pages(current_user, current_organization) do
if has_permissions?(current_user, current_organization) do
admin_pages(conn, current_organization)
admin_pages(current_organization)
else
user_pages(conn)
user_pages()
end
end

def user_pages(conn) do
default_pages(conn) ++
def user_pages do
default_pages() ++
[
%{
key: :scanner,
title: "Scanner",
icon: "hero-qr-code",
url: Routes.scanner_index_path(conn, :index),
url: ~p"/scanner",
tabs: []
}
]
end

def admin_pages(conn, current_organization) do
default_pages(conn) ++
def admin_pages(current_organization) do
default_pages() ++
[
%{
key: :departments,
title: "Departments",
icon: "hero-cube",
url: Routes.department_index_path(conn, :index, current_organization.id),
url: ~p"/organizations/#{current_organization}/departments",
tabs: []
},
%{
key: :partners,
title: "Partners",
icon: "hero-user-group",
url: Routes.partner_index_path(conn, :index, current_organization.id),
url: ~p"/organizations/#{current_organization}/partners",
tabs: []
},
%{
key: :scanner,
title: "Scanner",
icon: "hero-qr-code",
url: Routes.scanner_index_path(conn, :index),
url: ~p"/scanner",
tabs: []
}
]
end

def default_pages(conn) do
def default_pages do
[
%{
key: :home,
title: "Home",
icon: "hero-home",
url: Routes.home_index_path(conn, :index),
url: ~p"/",
tabs: []
},
%{
key: :calendar,
title: "Calendar",
icon: "hero-calendar",
url: Routes.calendar_show_path(conn, :show),
url: ~p"/calendar",
tabs: []
},
%{
key: :activities,
title: "Activities",
icon: "hero-academic-cap",
url: Routes.activity_index_path(conn, :index),
url: ~p"/activities",
tabs: []
},
%{
key: :announcements,
title: "Announcements",
icon: "hero-newspaper",
url: Routes.announcement_index_path(conn, :index),
url: ~p"/announcements",
tabs: []
},
%{
key: :organizations,
title: "Organizations",
icon: "tabler-affiliate",
url: Routes.organization_index_path(conn, :index),
url: ~p"/organizations",
tabs: []
}
]
Expand Down
7 changes: 4 additions & 3 deletions lib/atomic_web/controllers/user_auth.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ defmodule AtomicWeb.UserAuth do
@moduledoc """
This module contains functions to log users in and out.
"""
use AtomicWeb, :verified_routes

import Plug.Conn
import Phoenix.Controller

alias Atomic.Accounts
alias AtomicWeb.Router.Helpers, as: Routes

# Make the remember me cookie valid for 60 days.
# If you want bump or reduce this value, also change
Expand Down Expand Up @@ -95,7 +96,7 @@ defmodule AtomicWeb.UserAuth do
conn
|> renew_session()
|> delete_resp_cookie(@remember_me_cookie)
|> redirect(to: Routes.user_session_path(conn, :new))
|> redirect(to: ~p"/users/log_in")
end

@doc """
Expand Down Expand Up @@ -163,7 +164,7 @@ defmodule AtomicWeb.UserAuth do
conn
|> put_flash(:error, "You must log in to access this page.")
|> maybe_store_return_to()
|> redirect(to: Routes.user_session_path(conn, :new))
|> redirect(to: ~p"/users/log_in")
|> halt()
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ defmodule AtomicWeb.UserChangePasswordController do
{:ok, user} ->
conn
|> put_flash(:info, "Password updated successfully.")
|> put_session(:user_return_to, Routes.user_change_password_path(conn, :edit))
|> put_session(:user_return_to, ~p"/users/change_password")
|> UserAuth.log_in_user(user)

{:error, changeset} ->
Expand Down
2 changes: 1 addition & 1 deletion lib/atomic_web/controllers/user_confirmation_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ defmodule AtomicWeb.UserConfirmationController do
if user = Accounts.get_user_by_email(email) do
Accounts.deliver_user_confirmation_instructions(
user,
&Routes.user_confirmation_url(conn, :edit, &1)
&url(~p"/users/confirm/#{&1}")
)
end

Expand Down
2 changes: 1 addition & 1 deletion lib/atomic_web/controllers/user_registration_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ defmodule AtomicWeb.UserRegistrationController do
{:ok, _} =
Accounts.deliver_user_confirmation_instructions(
user,
&Routes.user_confirmation_url(conn, :edit, &1)
&url(~p"/users/confirm/#{&1}")
)

conn
Expand Down
Loading