user11027203
user11027203

Reputation:

rails how to validate old password before update new password

I don't understand how to do that implementation. I want to check old password before update old password. What I should be doing? I don't understand. How to password convert to password_digest. and how to check something like a

if @user.user_params(:old_password) == @user(:password_digest)
  @user.update attributes

but it's didn't checked because password digest cannot be checked.

I have a controller : users_controller.rb

# PATCH/PUT /users/1
def update
  @user.update_attributes!(user_params)
  head :no_content
end

private
def user_params
  PrettyApi.with_nested_attributes(pretty_user_params, :worker)
end

# Only allow a trusted parameter "white list" through.
def pretty_user_params
  params.require(:user).permit(
  :email,
  :first_name,
  :last_name,
  :phone_number,
  :password,
  :password_confirmation,
  roles: [],
  worker: [
    :id,
    :rate,
    :crew_leader,
    :_destroy
  ]
)
end

user.rb

has_secure_password

schema.rb

  create_table "users", force: :cascade do |t|
t.bigint "company_id"
t.string "first_name"
t.string "last_name"
t.string "email"
t.string "password_digest"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "roles", default: [], array: true
t.string "reset_token"
t.string "phone_number"
t.datetime "reset_sent_at"
t.index ["company_id"], name: "index_users_on_company_id"
t.index ["email"], name: "index_users_on_email"
t.index ["first_name"], name: "index_users_on_first_name"
t.index ["last_name"], name: "index_users_on_last_name"
end

authenticate_user.rb

class AuthenticateUser
  def initialize(email, password, remember_me=nil, fcm_token=nil, platform=nil)
    @email = email
    @password = password
    @remember_me = remember_me
    @fcm_token = fcm_token
    @platform = platform
  end

  # Service entry point
  def call
    return unless user

    if is_remember_me_active?
      JsonWebToken.encode(encode_fields, 120.days.from_now)
    else
      JsonWebToken.encode(encode_fields)
    end
  end

  private

  attr_reader :email, :password, :remember_me, :fcm_token, :platform

  # verify user credentials
  def user
    user = User.find_by(email: email)
    if user && user.authenticate(password)
      if fcm_token.present? && platform.present?
        firebase_token = FirebaseToken.find_by(user: user, platform: platform)
        if firebase_token.present?
          firebase_token.update(token: fcm_token)
        else
          FirebaseToken.create(
            user: user,
            platform: platform,
            token: fcm_token
         )
        end
      end
      return user
    end
    # raise Authentication error if credentials are invalid
    raise(ExceptionHandler::AuthenticationError, Message.invalid_credentials)
  end

  def encode_fields
    {
      user_id: user.id,
      roles: user.roles
    }
  end

  def is_remember_me_active?
    remember_me.eql?('true')
  end
end

Upvotes: 1

Views: 969

Answers (2)

Nandhini
Nandhini

Reputation: 665

Devise supports valid_password method to check if the given password matches the current password. In order to verify old password :

@user = User.find_by_email(params[:email])
if @user.valid_password?(params[:old_password])
   @user.password = params[:password]
   @user.password_confirmation = params[:password_confirmation]
   if @user.save!
     render json: "password updated successfully", status: :accepted
   else
     render json: "could not update password", status: :not_acceptable
   end
end

Upvotes: 0

Vasfed
Vasfed

Reputation: 18504

has_secure_password provides authenticate method to check if password is correct, you can:

if @user.authenticate(params[:old_password])
  @user.update!(...)
else
  # handle incorrect old password
end

Upvotes: 2

Related Questions