I am very new to Phoenix and Elixir, and thrilled by what can be achieved by LiveView without having to rely on JavaScript.
Here is my problem for a side project of mine.
- I have a registration page, powered by LiveView
- Registration page works properly, I am able to validate the user entries (like proper email address, …)
- In terms of flows, once the user has registered with email address, password and password confirmation I want to enable them to edit their profile
- The profile page is a normal page (without LiveView) and is protected by an authentication plug that requires the
:current_user
to be populated.
Below is what I have in the non LiveView version of this flow
router.ex
get "/me", ConstituentController, :edit
put "/me", ConstituentController, :update
resources "/sessions", SessionController, only: [:new, :create, :delete]
get "/signup", SignupController, :new
post "/signup", SignupController, :create
Controller
def create(conn, %{"user" => user_params}) do
case Accounts.register_user(user_params) do
{:ok, user} ->
conn
|> FrogzWeb.Auth.login(user)
|> redirect(to: Routes.constituent_path(conn, :edit))
{:error, %Ecto.Changeset{} = changeset} ->
render(conn, "new.html", changeset: changeset)
end
end
Auth.ex
def login(conn, user) do
conn
|> assign(:current_user, user)
|> put_session(:user_id, user.id)
|> configure_session(renew: true)
end
In the LiveView version, I have the following event_handler that creates the user and tries to redirect to the same page
def handle_event("save", %{"user" => user_params}, socket) do
case Accounts.register_user(user_params) do
{:ok, user} ->
{:stop,
socket
|> assign(:current_user, user)
|> assign(:user_id, user.id)
|> redirect(to: Routes.constituent_path(socket, :edit, user: user))
}
{_, %Ecto.Changeset{} = changeset} ->
IO.inspect(changeset)
{:noreply, assign(socket, changeset: changeset)}
end
end
Trying to call the Auth.login
function in my handler ends up with a pattern matching error.
My question is the following, how can I change the session in my liveview powered part so that the current_user
is appended, so that I can safely show the update profile page.
I tried using the user_id
in the session and fetching it from the “normal” page, but it does not feel like a very safe option as everybody would be able to change anybody’s profile.
Not sure if the solution is obvious, but would greatly appreciate any help.