
Chrichton
Programming Phoenix LiveView: B03 (page 56-57) auth exercise
Dear Sophie.
I tried to do the “Authorization” exercise and have two questions:
-
When trying to plug in an email-service, I found the function “&Routes.user_confirmation_url(conn, :confirm, &1)” in “user_confirmation_controller.ex”.
I wasn’t able to find this function.
Where is it located or how is it created dynamically? -
I added the “username” field without problem, but when I set it to unique and made it safe with “unsafe_validate_unique(:username, Pento.Repo)” some tests failed. I tried to fix them via modifying the fixture()-Function, but still two test concerning the uniqueness of the “email” failed.
Is there an easy way to get the generated tests running, when adding a second unique field?
Thanks for your superb book.
I learned a lot from this exercise, especially the sending of the confirmation-email via Bamboo and Sendgrid.
Best wishes from Heiko
Most Liked

SophieDeBenedetto
Hi again @Chrichton!
So the Routes.user_confirmation_url/3
isn’t defined as such in your router. It’s defined under the hood of Phoenix by virtue of the user_confirmation_path
routes that were added to your router.ex
file by the Phoenix Auth generator. The function itself is passed as an argument to the Accounts.deliver_user_confirmation_instructions/3
function in the UserConfirmationController
controller. In that Accounts
function, the Routes.user_confirmation_url/3
is finally invoked to return the user confirmation URL, with the correct user token, to be rendered in the email sent to the user. I would trace the code flow in the Accounts.deliver_user_confirmation_instructions/3
to get a better understanding of how the Routes.user_confirmation_url/3
function is being used.
Re: your exercise solution:
It looks like your solution will ensure that a user is redirected to the "/guess"
route when the complete the log in process. But the challenge is actually asking you to ensure that if a user who is logged in visits /
, that they get automatically redirected to /guess
. You can solve this a few different ways.
- Add a function plug to the
:browser
pipeline in therouter.ex
to redirect the user from/
to/guess
if they are logged in. Like this:
#router.ex
defmodule PentoWeb.Router do
use PentoWeb, :router
import Phoenix.Controller
...
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_live_flash
plug :put_root_layout, {PentoWeb.LayoutView, :root}
plug :protect_from_forgery
plug :put_secure_browser_headers
plug :fetch_current_user
plug :redirect_if_logged_in # add me!
end
...
def redirect_if_logged_in(conn, _opts) do
if conn.assigns.current_user && conn.request_path == "/" do
redirect(conn, to: "/guess")
end
conn
end
end
This requires importing the Phoenix.Controller
module into the router to get the redirect/2
function, which I don’t love.
You could also add some logic to the PageLive
live view’s mount
function to do a redirect if there is a logged in user. This is the live view that handles the /
route. It would look something like this:
# lib/pento_web/live/page_live.ex
def mount(_params, %{"user_token" => _}, socket) do
{:ok, redirect(socket, to: "/guess")}
end
def mount(_params, session, socket) do
{:ok, assign(socket, query: "", results: %{})}
end
Here, you are checking to see if there is a logged in user based on whether or not the session
argument given to mount
has a "user_token"key present. If so, there is a logged in user and you can use the
redirect` function to do a redirect.
Popular Prag Prog topics










Other popular topics









Latest in PragProg
Latest (all)
Categories:
Popular Portals
- /elixir
- /rust
- /wasm
- /ruby
- /erlang
- /phoenix
- /keyboards
- /js
- /rails
- /python
- /security
- /go
- /swift
- /vim
- /clojure
- /java
- /haskell
- /emacs
- /svelte
- /onivim
- /typescript
- /crystal
- /c-plus-plus
- /tailwind
- /kotlin
- /gleam
- /react
- /flutter
- /elm
- /ocaml
- /vscode
- /opensuse
- /ash
- /centos
- /php
- /deepseek
- /zig
- /scala
- /html
- /debian
- /nixos
- /lisp
- /agda
- /textmate
- /sublime-text
- /react-native
- /kubuntu
- /arch-linux
- /revery
- /ubuntu
- /manjaro
- /spring
- /django
- /diversity
- /lua
- /nodejs
- /c
- /slackware
- /julia
- /neovim