ashok

ashok

I have used Pow for user authentication and successfully created login & logout feature using custom controller (Custom controllers — Pow v1.0.39 ) Now I want to create Forgot Password feature. Pow provides reset password extension “PowResetPassword”. I have install Pow extension by reading the documentation (PowResetPassword — Pow v1.0.39)

I have created a new controller for reset password “WEB_PATH/controllers/reset_password/reset_password_controller.ex”

The controller code is shown below.

def new(conn, _params) do
changeset = Pow.Plug.change_user(conn)

render(conn, "new.html", changeset: changeset)

end

def create(conn, %{“user” => user_params}) do

conn
|> PowResetPassword.Plug.create_reset_token(user_params)
|> case do
     {:ok, conn} ->
     conn
     |> put_flash(:info, 'Check your email to reset password')
     |> redirect(to: Routes.reset_password_path(conn, :new))

     {:error, conn} ->
        conn
        |> put_flash(:info, "Error resetting")
        |> redirect(to: Routes.reset_password_path(conn, :new))

   end

end

def update(conn, %{“user” => user_params}) do

PowResetPassword.Plug.update_user_password(conn, user_params)
# {:ok, conn} = Pow.Plug.clear_authenticated_user(conn)

redirect(conn, to: Routes.login_path(conn, :new))

end

My reset password view is:

<%= form_for @changeset, Routes.reset_password_path(@conn, :create), [class: “form-wrap login-form w-100”], fn f → %>

Reset password

<%= label f, :email, "" %> <%= text_input f, :email, class: "form-control", id: "email", placeholder: "Email" %>
<%= submit "Continue", class: "btn btn-primary w-100" %>

<% end %>

My routes are

signup_path GET / MyAppWeb.RegistrationController :new
signup_path POST / MyAppWeb.RegistrationController :create
login_path GET /login MyAppWeb.SessionController :new
login_path POST /login MyAppWeb.SessionController :create
reset_password_path GET /reset-password/new MyAppWeb.ResetPasswordController :new
reset_password_path POST /reset-password MyAppWeb.ResetPasswordController :create
reset_password_path PATCH /reset-password/:id MyAppWeb.ResetPasswordController :update
PUT /reset-password/:id MyAppWeb.ResetPasswordController :update
reset_password_path GET /reset-password/:id MyAppWeb.ResetPasswordController :edit
logout_path DELETE /logout MyAppWeb.SessionController :delete
game_path GET /game MyAppWeb.PageController :index
websocket WS /socket/websocket MyAppWeb.UserSocket

When I hit submit ‘continue’ button in reset password page with or without entring any email I am getting error as shown below:

CaseClauseError at POST /reset-password
no case clause matching: {:error, #Ecto.Changeset<action: :update, changes: %{}, errors: [password_hash: {“can’t be blank”, [validation: :required]}, password: {“can’t be blank”, [validation: :required]}], data: #MyApp.Users.User<>, valid?: false>, %Plug

I have taken reference from the Pow module PowResetPassword.Phoenix.ResetPasswordController present in my project “deps” folder but not sure which one to use in “create” , “edit” and “update”. please suggest how can I over come this issue.

Showing Posts 1 to 10

danschultzer

danschultzer

Pow Core Team

Your case statement is invalid. PowResetPassword.Plug.create_reset_token/2 returns {:ok, %{token: token, user: user}, conn} or {:error, changeset, conn}.

For security you should also respond with success no matter the result:

def create(conn, %{“user” => user_params}) do
  conn
  |> PowResetPassword.Plug.create_reset_token(user_params)
  |> case do
    {:ok, %{token: token, user: user}, conn} ->
      # Send e-mail

      conn
      |> put_flash(:info, 'Check your email to reset password')
      |> redirect(to: Routes.reset_password_path(conn, :new))

    {:error, conn} ->
      conn
      |> put_flash(:info, 'Check your email to reset password')
      |> redirect(to: Routes.reset_password_path(conn, :new))
  end
end

Take a look at the controller for more.

ashok

ashok OP

Thanks for the solution it works now I am not getting any error but still there is an issue I was assuming that there should be some entry in “user” table for the column “email_confirmation_token”, “email_confirmed_at” or in “unconfirmed_email”.

When run forgot password it works well showing me flash message “Check your email to reset password” and when I looked into the database for the corresponding user there is no update in the database column.

I had followed the documentation — Pow v1.0.39 to “Add extensions support” and install the PowResetPassword and PowEmailConfirmation extensions

Please help how to insert token data into my database?

danschultzer

danschultzer

Pow Core Team

Those columns will only be filled during registration create/update as they are part of the PowEmailConfirmation extension.

PowResetPassword stores the reset token in the cache store.

Muhammad

Muhammad

@danschultzer Thanks for your reply, but I have one more question

> def create(conn, %{“user” => user_params}) do
>   conn
>   |> PowResetPassword.Plug.create_reset_token(user_params)
>   |> case do
>     {:ok, %{token: token, user: user}, conn} ->
>       # How to send email here?
> 
>       conn
>       |> put_flash(:info, 'Check your email to reset password')
>       |> redirect(to: Routes.reset_password_path(conn, :new))
> 
>     {:error, conn} ->
>       conn
>       |> put_flash(:info, 'Check your email to reset password')
>       |> redirect(to: Routes.reset_password_path(conn, :new))
>   end
> end

How can I send email after reset token in the code above?

danschultzer

danschultzer

Pow Core Team

Just for anyone who’s reading, the question was answered on Github: Custom controller for reset password using pow · Issue #354 · pow-auth/pow · GitHub

sveredyuk

sveredyuk

I am using Pow and PowAssent for API-based app and always getting the result like:

{:error, changeset, _conn} = PowResetPassword.Plug.create_reset_token(conn, %{"email" => "user@example.com"})

changeset # => #Ecto.Changeset<action: nil,changes: %{},errors: [password: {"can't be blank", [validation: :required]}],data: #Handshake.Accounts.User<>,valid?: false

why it requires a password?

danschultzer

danschultzer

Pow Core Team

It’s because the same changeset is used as when the password gets changed. That’s a bug and it should just return a blank changeset. I’ve opened an issue on Github and will fix it promptly: Confusing changeset error when email can't be found in PowResetPassword · Issue #482 · pow-auth/pow · GitHub

sveredyuk

sveredyuk

@danschultzer I see. Thank you a lot for your amazing work.

Hossman333

Hossman333

Hi there! This is great. Thanks for this forum. I have everything working, except it’s giving me a false positive when I call “update_user_password”. It appears it never actually hashes the password in that function for me. I could hash the password and then pass it to that method, but for me to hash it I need to know the “secret”. “Pow.Ecto.Schema.Password.pbkdf2_hash()” Would the secret be something like the “SECRET_KEY_BASE” environment variable? Or how exactly does calling “PowResetPassword.Plug.update_user_password” supposed to work?

Basically I call “PowResetPassword.Plug.load_user_by_token” before and then pass the conn to “PowResetPassword.Plug.update_user_password”. Everything is great other than it not actually updating it in the DB field / hashing it.

Let me know. Thank you friends

Hossman333

Hossman333

Ahhhhhh. I figured it out. Haha. Whoops. I was using my own changeset instead of what I should have been doing. Inside the changeset is where the magic happens.

I now call these methods inside my changeset:

      |> Pow.Ecto.Schema.Changeset.confirm_password_changeset(attrs, @pow_config)
      |> Pow.Ecto.Schema.Changeset.new_password_changeset(attrs, @pow_config)

Thanks!

— All posts loaded —

Where Next? Top

Trending in Questions Top

katta
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
kpanic
Hi everyone, I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding. I sta...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
asweet-confluent
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
apz
I’m new to elixir and just tried to install the elixirLS extension for VScode(ium) and it is throwing some errors that I would like help ...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews