Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RoR: Forgot Password & Sign In - in same page

I'm trying to put Forgot password field with the sign in page, but if user is not registered (and not in apps database), then it redirects to the original devise Forgot password page with errors (http://localhost:3000/users/password). How do I make the errors appear in the same page as the sign in page (http://localhost:3000/users/sign_in)?


In app/views/devise/sessions/new.html.erb file

<%= simple_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
  <%= f.email_field :email, required: false, autofocus: true, placeholder: "Username" %>
  <%= f.password_field :password, required: false, placeholder: "Password" %>
  <%= f.button :submit, "Sign In", class: "btn btn-success btn-sm" %>

  <div class="remember-forgot">
     <div class="row">
       <div class="col-md-6">
         <%= f.input :remember_me, as: :boolean if devise_mapping.rememberable? %>
       </div>
       <div class="col-md-6 forgot-pass-content">
         <a href="javascription:void(0)" class="forgot-pass">Forgot Password</a>
       </div>
     </div>
  </div>
<% end %>

<!-- where reset is -->

<div class="pass-reset">
  <%= simple_form_for(resource, as: resource_name, url: password_path(resource_name), namespace: 'forgot', html: { method: :post }) do |f| %>
    <%= f.error_notification %>
    <label>Enter the email you signed up with</label>
    <%= f.email_field :email, required: true, autofocus: true, placeholder: "Email" %>
    <%= f.submit "Submit", class: "pass-reset-submit btn btn-success btn-sm" %>
  <% end %> 
</div>

So there's a javascript link where an input field will show up if a user forgets their sign in credentials.

like image 759
hellomello Avatar asked Jul 17 '15 19:07

hellomello


People also ask

How do I reset my Rubys rails password?

The flow is simple, user that forgot his password clicks the “forgot password” link, then the user should input email address he was registered with. After that a token is sent to the email address. User then sends the token along with the new password, after it is successfuly sent, the password then resetted.

How can I find out what my email password is?

Gmail's Standard Recovery ProcedureHead to the Gmail sign-in page and click the “Forgot Password” link. Enter the last password you remember. If you can't remember one, click “Try a different question.” Enter the secondary email address you used when you set up your Gmail account to get a password reset email.


1 Answers

apparently two forms for same object having same fields should not be one page, one should stay with the new page. but still i have tried your question, and following things needs to be done

1) I have to override the passwords controller for devise under user scope.

class Users::PasswordsController < Devise::PasswordsController
  # GET /resource/password/new
  def new
    super
  end

  # POST /resource/password
  def create
  self.resource = resource_class.send_reset_password_instructions(resource_params)

    if successfully_sent?(resource)
      flash[:notice] = "sent password"
      redirect_to :root
    else
      render "devise/sessions/new"
    end
  end

  # GET /resource/password/edit?reset_password_token=abcdef
  def edit
    super
  end

  # PUT /resource/password
  def update
    super
  end

  protected

  def after_resetting_password_path_for(resource)
    super(resource)
  end

  # The path used after sending reset password instructions
  def after_sending_reset_password_instructions_path_for(resource_name)
    super(resource_name)
  end
end

then my devise/sessions/new page will look like this(you can add the logic of showing form only when one clicks he forget password button. that should be simple. just add hide class and on click remove hide class.)

Log in

<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
  <div class="field">
    <%= f.label :email %><br />
    <%= f.email_field :email, autofocus: true %>
  </div>

  <div class="field">
    <%= f.label :password %><br />
    <%= f.password_field :password, autocomplete: "off" %>
  </div>

  <% if devise_mapping.rememberable? -%>
    <div class="field">
      <%= f.check_box :remember_me %>
      <%= f.label :remember_me %>
    </div>
  <% end -%>

  <div class="actions">
    <%= f.submit "Log in" %>
  </div>
<% end %>

#assuming that devise_mapping has recoverable? option. you can also keep the below form in if condition

<h2>Forgot your password?</h2>

<%= form_for(resource, as: resource_name, url: password_path(resource_name), namespace: "forget", html: { method: :post }) do |f| %>
  <%= devise_error_messages! %>

  <div class="field">
    <%= f.label :email %><br />
    <%= f.email_field :email, autofocus: true %>
  </div>

  <div class="actions">
    <%= f.submit "Send me reset password instructions" %>
  </div>
<% end %>

need to tell the routes to use my my passwords controller.

devise_for :users, controllers: {
  passwords: 'users/passwords'
}

These things will result in showing the errors under the user sign in form but the path will remain http://localhost:3000/users/password. why because we are rendering the page and not redirecting. render just show the views without going to the controller action. now even if one tries to send the errors messages to the sessions controller somehow(after overriding that controller as well) somehow like this

    redirect_to new_user_session_path, :messages => resource.errors

still that wont help, why because in session#new we are re initializing the resource as it is new action and all the errors would be gone.

I'm not sure if this is satisfactory to you or if this is not even close to your requirements. i tried to cover all things. i would be glad if some credible or official sources will provide even better response. that would definitely increase my knowledge as well.

like image 168
Athar Avatar answered Oct 25 '22 03:10

Athar