class PasswordChangeController

Public Instance Methods

create() click to toggle source
# File lib/generators/authkit/templates/app/controllers/password_change_controller.rb, line 13
def create
  if email_user.change_password(params[:password], params[:password_confirmation])
    # Do not automatically log in the user
    respond_to do |format|
      format.json { head :no_content }
      format.html {
        flash.now[:notice] = "Password updated successfully"
        redirect_to(login_path)
      }
    end
  else
    respond_to do |format|
      format.json { render json: { status: 'error', errors: email_user.errors }.to_json, status: 422 }
      format.html { render :show }
    end
  end
end
show() click to toggle source
# File lib/generators/authkit/templates/app/controllers/password_change_controller.rb, line 6
def show
  respond_to do |format|
    format.json { head :no_content }
    format.html
  end
end

Protected Instance Methods

email_user() click to toggle source
# File lib/generators/authkit/templates/app/controllers/password_change_controller.rb, line 47
def email_user
  return @user if defined?(@user)
  @user = User.where(email: params[:email]).first || raise(ActiveRecord::RecordNotFound)
end
require_email_user() click to toggle source

The token is paired with an email parameter so that the user can be found in the database. Once found the tokens can be securely compared to prevent timing attacks. The email address is chosen over the id because the reset was generated using the email address and thus is already known. Using the id would increase information leakage.

# File lib/generators/authkit/templates/app/controllers/password_change_controller.rb, line 43
def require_email_user
  deny_user("Invalid email address", root_path) if params[:email].blank? || email_user.blank?
end
require_no_user() click to toggle source

Any existing user should be logged out to prevent session leakage

# File lib/generators/authkit/templates/app/controllers/password_change_controller.rb, line 34
def require_no_user
  logout
end
require_token() click to toggle source

Reset password tokens expire after 1 day

# File lib/generators/authkit/templates/app/controllers/password_change_controller.rb, line 53
def require_token
  valid = params[:token].present?
  valid = valid && ActiveSupport::SecurityUtils.secure_compare(params[:token], email_user.reset_password_token)
  valid = valid && !email_user.reset_password_token_expired?
  deny_user("Invalid token", root_path) unless valid
end