defmodule Pow.Phoenix.Routes do
@moduledoc """
Module that handles routes.
## Usage
defmodule MyAppWeb.Pow.Routes do
use Pow.Phoenix.Routes
alias MyAppWeb.Router.Helpers, as: Routes
@impl true
def after_sign_out_path(conn), do: Routes.some_path(conn, :index)
end
Update configuration with `routes_backend: MyAppWeb.Pow.Routes`.
You can also customize path generation:
defmodule MyAppWeb.Pow.Routes do
use Pow.Phoenix.Routes
alias MyAppWeb.Router.Helpers, as: Routes
@impl true
def url_for(conn, verb, vars \\ [], query_params \\ [])
def url_for(conn, PowEmailConfirmation.Phoenix.ConfirmationController, :show, [token], _query_params),
do: Routes.custom_confirmation_url(conn, :new, token)
def url_for(conn, plug, verb, vars, query_params),
do: Pow.Phoenix.Routes.url_for(conn, plug, verb, vars, query_params)
end
"""
alias Plug.Conn
alias Pow.Phoenix.{Controller, RegistrationController, SessionController}
@callback user_not_authenticated_path(Conn.t()) :: binary()
@callback user_already_authenticated_path(Conn.t()) :: binary()
@callback after_sign_out_path(Conn.t()) :: binary()
@callback after_sign_in_path(Conn.t()) :: binary()
@callback after_registration_path(Conn.t()) :: binary()
@callback after_user_updated_path(Conn.t()) :: binary()
@callback after_user_deleted_path(Conn.t()) :: binary()
@callback session_path(Conn.t(), atom(), list()) :: binary()
@callback registration_path(Conn.t(), atom()) :: binary()
@callback path_for(Conn.t(), atom(), atom(), list(), Keyword.t()) :: binary()
@callback url_for(Conn.t(), atom(), atom(), list(), Keyword.t()) :: binary()
@doc false
defmacro __using__(_opts) do
quote do
@behaviour unquote(__MODULE__)
def user_not_authenticated_path(conn),
do: unquote(__MODULE__).user_not_authenticated_path(conn, __MODULE__)
def user_already_authenticated_path(conn),
do: unquote(__MODULE__).user_already_authenticated_path(conn, __MODULE__)
def after_sign_out_path(conn),
do: unquote(__MODULE__).after_sign_out_path(conn, __MODULE__)
def after_sign_in_path(conn),
do: unquote(__MODULE__).after_sign_in_path(conn, __MODULE__)
def after_registration_path(conn),
do: unquote(__MODULE__).after_registration_path(conn, __MODULE__)
def after_user_updated_path(conn),
do: unquote(__MODULE__).after_user_updated_path(conn, __MODULE__)
def after_user_deleted_path(conn),
do: unquote(__MODULE__).after_user_deleted_path(conn, __MODULE__)
def session_path(conn, verb, query_params \\ []),
do: unquote(__MODULE__).session_path(conn, verb, query_params, __MODULE__)
def registration_path(conn, verb),
do: unquote(__MODULE__).registration_path(conn, verb, __MODULE__)
def path_for(conn, plug, verb, vars \\ [], query_params \\ []),
do: unquote(__MODULE__).path_for(conn, plug, verb, vars, query_params)
def url_for(conn, plug, verb, vars \\ [], query_params \\ []),
do: unquote(__MODULE__).url_for(conn, plug, verb, vars, query_params)
defoverridable unquote(__MODULE__)
end
end
@doc """
Path to redirect user to when user is not authenticated.
This will put a `:request_path` param into the path that can be used to
redirect users back the the page they first attempted to visit. See
`after_sign_in_path/1` for how `:request_path` is handled.
The `:request_path` will only be added if the request uses "GET" method.
See `Pow.Phoenix.SessionController` for more on how this value is handled.
"""
def user_not_authenticated_path(conn, routes_module \\ __MODULE__) do
case conn.method do
"GET" -> routes_module.session_path(conn, :new, request_path: Phoenix.Controller.current_path(conn))
_method -> routes_module.session_path(conn, :new)
end
end
@doc """
Path to redirect user to when user has already been authenticated.
By default this is the same as `after_sign_in_path/1`.
"""
def user_already_authenticated_path(conn, routes_module \\ __MODULE__), do: routes_module.after_sign_in_path(conn)
@doc """
Path to redirect user to when user has signed out.
"""
def after_sign_out_path(conn, routes_module \\ __MODULE__), do: routes_module.session_path(conn, :new)
@doc """
Path to redirect user to when user has signed in.
This will look for a `:request_path` assigns key, and redirect to this value
if it exists.
"""
def after_sign_in_path(params, routes_module \\ __MODULE__)
def after_sign_in_path(%{assigns: %{request_path: request_path}}, _routes_module) when is_binary(request_path),
do: request_path
def after_sign_in_path(_params, _routes_module), do: "/"
@doc """
Path to redirect user to when user has signed up.
By default this is the same as `after_sign_in_path/1`.
"""
def after_registration_path(conn, routes_module \\ __MODULE__), do: routes_module.after_sign_in_path(conn)
@doc """
Path to redirect user to when user has updated their account.
"""
def after_user_updated_path(conn, routes_module \\ __MODULE__), do: routes_module.registration_path(conn, :edit)
@doc """
Path to redirect user to when user has deleted their account.
By default this is the same as `after_sign_out_path/1`.
"""
def after_user_deleted_path(conn, routes_module \\ __MODULE__), do: routes_module.after_sign_out_path(conn)
@doc false
def session_path(conn, verb, query_params \\ [], routes_module \\ __MODULE__), do: routes_module.path_for(conn, SessionController, verb, [], query_params)
@doc false
def registration_path(conn, verb, routes_module \\ __MODULE__), do: routes_module.path_for(conn, RegistrationController, verb)
@doc """
Generates a path route.
"""
@spec path_for(Conn.t(), atom(), atom(), list(), Keyword.t()) :: binary()
def path_for(conn, plug, verb, vars \\ [], query_params \\ []) do
gen_route(:path, conn, plug, verb, vars, query_params)
end
@doc """
Generates a url route.
"""
@spec url_for(Conn.t(), atom(), atom(), list(), Keyword.t()) :: binary()
def url_for(conn, plug, verb, vars \\ [], query_params \\ []) do
gen_route(:url, conn, plug, verb, vars, query_params)
end
defp gen_route(type, conn, plug, verb, vars, query_params) do
alias = Controller.route_helper(plug)
helper = :"#{alias}_#{type}"
router = Module.concat([conn.private.phoenix_router, Helpers])
args = [conn, verb] ++ vars ++ [query_params]
apply(router, helper, args)
end
end