No match of right side value

if want to implement a password recovery in my app. but i get the following errors

no match of right hand side value: {:error, #Ecto.Changeset<action: :update, changes: %{password_reset_code: “voXaXWLUGOfeBsJ7Sd4EhNcz5YtMt3So”}, errors: [password: {“can’t be blank”, [validation: :required]}, password_confirmation: {“can’t be blank”, [validation: :required]}], data: #JavsalynnSmanager.Administration.User<>, valid?: false>}

def recover_password_submit(conn, %{“session” => session_params}) do

    conn
    |> clear_session()

    case  Administration.get_user_by_email(session_params["email"]) do
    
        :nil -> conn
                |> put_flash(:error, "There is no account with the provided email!")
                |> render("forgot_password.html")
    
        user ->
        
            {:ok, updated_user} = Administration.generate_password_reset_code(user)
        
        
            updated_user.email
            |> Email.send_html_email(
            
                   "Password Reset link",
                   "#{updated_user.firstname} #{updated_user.lastname}",
                   "password_reset_email",
                   updated_user.password_reset_code
               )
            |> Mailer.deliver_later
            conn
            |> put_flash(:info, "Password Recovery email has been sent to you. Please check your email.")
            |> redirect(to: Routes.page_path(conn, :index))
    end




end

Show us the code of Administration.generate_password_reset_code/1 and probably the changeset function it is using, as problem is there.

1 Like

:warning: Disclaimer: I’m new to Elixir, Phoenix, and Ecto.

I noticed this particular part of the error:

# {:error, #Ecto.Changeset<action: :update, ...
                                   ^^^^^^^

So it looks like Ecto is perhaps interpreting whatever’s happening in Administration.get_user_by_email/1 as an update instead of a query.

EDIT: nevermind, I was on the wrong track.

By the way, something to consider about the following:

:nil -> conn
  |> put_flash(:error, "There is no account with the provided email!")
  |> render("forgot_password.html")

This approach of stating “no account” is indeed helpful to honest users but can divulge details to an attacker, e.g., “ok, that email address definitely didn’t work; let’s try another. :077:

Granted, this is subject to the context of policies and other security mechanisms, and might not even be that big of a risk (I’m no expert), but it always gives me pause when I’m tempted to do it in my code. :slightly_smiling_face:

Depending on the situation, sometimes I simply return the same message in all cases, something along the lines of: “A reminder email has been sent to the account, if registered.”

2 Likes
def generate_password_reset_code(%User{} = user) do
    reset_pin = Generator.randstring(32)
    update_user(user, %{password_reset_code: reset_pin})

  end

May we see the code for update_user/2?

Also, showing us the changeset def and perhaps the schema for User might be helpful.

1 Like