Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Require password only when changing password devise registration

I have a registration/edit form that is rendered through a Devise::RegistrationsController within my application. The way it works now you must provide your current password when making any updates to the form. They way I want it to work is that the current_passwordis only required when you are updating the password field... or you must repeat the "new_password" as a means of confirmation. I have done some reading on the Devise Wiki, mainly the following links and they don't seem to list a solution for this. If anyone has some insight on how this might be achieved I would appreciate it.

https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-edit-their-password

https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-edit-their-account-without-providing-a-password

like image 672
Zack Herbert Avatar asked Mar 09 '23 10:03

Zack Herbert


2 Answers

So I've been digging on trying to solve this I have found the solution.

In my model (user.rb) I added :validatable to the following snippet of code:

  devise :omniauthable, :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable,
     :confirmable, :trackable, reset_password_keys:[:email, :company_id],
     request_keys: [:host, :params], omniauth_providers: [:auth0]

Then in my registration controller, I added the following:

def update_resource(resource, params)
  if !params[:password].blank?
    resource.password = params[:password]
    resource.password_confirmation = params[:password_confirmation]
  end

  resource.update_without_password(params)
end

And finally in my application controller, I added :password_confirmation to the following snippet:

devise_parameter_sanitizer.permit(:account_update) do |u|
  u.permit(:first_name, :last_name, :email, :password, :password_confirmation, :phone_number, :receive_emails,
           location_attributes: [:id, :street, :city, :state, :zip, :country])
end

With this combination, once the form gets submitted it will fall into the update_resource block that I have overwritten. It will check to make sure that resource.password and password_confirmation are the same. On top of that now that current_password is out of the equation, you no longer have to enter your password everytime to save changes.

like image 140
Zack Herbert Avatar answered Mar 11 '23 22:03

Zack Herbert


What you can do is to validate at the time that the user do the update to its account, through the params params[:user][:password] and params[:user][:password_confirmation]:

This way if there are no password nor password_confirmation then use the update_without_password method passing the user_params, the other way do it just using the update_attributes method

  def update
    ...
    if params[:user][:password].blank? && params[:user][:password_confirmation].blank?
      if @user.update_without_password(user_params)
        flash[:notice] = 'User updated successfully'
        redirect_to some_path
      else
        render :edit
      end
    else
      if @user.update_attributes(user_params)
        # login before update passing the current user
        sign_in(User.find(current_user.id), :bypass => true) 
        flash[:notice] = 'User updated successfully'
        redirect_to some_path
      else
        render :edit
      end
    end
    ...
  end
like image 40
Sebastian Palma Avatar answered Mar 11 '23 23:03

Sebastian Palma