blonk is a radar for your web, where you follow vibes for cool blips on the radar
1defmodule ElixirBlonkWeb.UserResetPasswordController do
2 use ElixirBlonkWeb, :controller
3
4 alias ElixirBlonk.Accounts
5
6 plug :get_user_by_reset_password_token when action in [:edit, :update]
7
8 def new(conn, _params) do
9 render(conn, :new)
10 end
11
12 def create(conn, %{"user" => %{"email" => email}}) do
13 if user = Accounts.get_user_by_email(email) do
14 Accounts.deliver_user_reset_password_instructions(
15 user,
16 &url(~p"/users/reset_password/#{&1}")
17 )
18 end
19
20 conn
21 |> put_flash(
22 :info,
23 "If your email is in our system, you will receive instructions to reset your password shortly."
24 )
25 |> redirect(to: ~p"/")
26 end
27
28 def edit(conn, _params) do
29 render(conn, :edit, changeset: Accounts.change_user_password(conn.assigns.user))
30 end
31
32 # Do not log in the user after reset password to avoid a
33 # leaked token giving the user access to the account.
34 def update(conn, %{"user" => user_params}) do
35 case Accounts.reset_user_password(conn.assigns.user, user_params) do
36 {:ok, _} ->
37 conn
38 |> put_flash(:info, "Password reset successfully.")
39 |> redirect(to: ~p"/users/log_in")
40
41 {:error, changeset} ->
42 render(conn, :edit, changeset: changeset)
43 end
44 end
45
46 defp get_user_by_reset_password_token(conn, _opts) do
47 %{"token" => token} = conn.params
48
49 if user = Accounts.get_user_by_reset_password_token(token) do
50 conn |> assign(:user, user) |> assign(:token, token)
51 else
52 conn
53 |> put_flash(:error, "Reset password link is invalid or it has expired.")
54 |> redirect(to: ~p"/")
55 |> halt()
56 end
57 end
58end