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 the router.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 theredirect` function to do a redirect.