Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expire password reset token after 15 minutes #1536

Merged
merged 1 commit into from
Jan 18, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/controllers/email_confirmations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ def create
user = User.find_by(email: confirmation_params[:email])

if user
user.regenerate_confirmation_token
user.generate_confirmation_token
Mailer.delay.email_confirmation(user) if user.save
end
redirect_to root_path, notice: t('.promise_resend')
end

# used to resend confirmation mail for unconfirmed_email validation
def unconfirmed
if current_user.regenerate_confirmation_token && current_user.save
if current_user.generate_confirmation_token && current_user.save
Mailer.delay.email_reset(current_user)
flash[:notice] = t('profiles.update.confirmation_mail_sent')
else
Expand Down
8 changes: 8 additions & 0 deletions app/controllers/passwords_controller.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
class PasswordsController < Clearance::PasswordsController
before_action :validate_confirmation_token, only: :edit

def find_user_for_create
Clearance.configuration.user_model
.find_by_normalized_email password_params[:email]
Expand All @@ -13,4 +15,10 @@ def url_after_update
def password_params
params.require(:password).permit(:email)
end

def validate_confirmation_token
user = find_user_for_edit
return if user&.valid_confirmation_token?
redirect_to root_path, alert: t('failure_when_forbidden')
end
end
6 changes: 3 additions & 3 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class User < ActiveRecord::Base
has_many :web_hooks

after_validation :set_unconfirmed_email, if: :email_changed?, on: :update
before_create :generate_api_key, :regenerate_confirmation_token
before_create :generate_api_key, :generate_confirmation_token

validates :handle, uniqueness: true, allow_nil: true
validates :handle, format: {
Expand Down Expand Up @@ -104,7 +104,7 @@ def encode_with(coder)

def set_unconfirmed_email
self.attributes = { unconfirmed_email: email, email: email_was }
regenerate_confirmation_token
generate_confirmation_token
end

def generate_api_key
Expand Down Expand Up @@ -133,7 +133,7 @@ def valid_confirmation_token?
token_expires_at > Time.zone.now
end

def regenerate_confirmation_token
def generate_confirmation_token
self.confirmation_token = Clearance::Token.new
self.token_expires_at = Time.zone.now + 15.minutes
end
Expand Down
38 changes: 38 additions & 0 deletions test/functional/passwords_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,43 @@ class PasswordsControllerTest < ActionController::TestCase
assert page.has_content?("Request is missing param 'password'")
end
end

context "with valid params" do
setup do
@user = create(:user)
get :create, password: { email: @user.email }
end

should "set a valid confirmation_token" do
assert @user.valid_confirmation_token?
end
end
end

context "on GET to edit" do
setup do
@user = create(:user)
@user.forgot_password!
end

context "with valid confirmation_token" do
setup do
get :edit, token: @user.confirmation_token, user_id: @user.id
end

should redirect_to("password edit page") { edit_user_password_path }
end

context "with expired confirmation_token" do
setup do
@user.update_attribute(:token_expires_at, 1.minute.ago)
get :edit, token: @user.confirmation_token, user_id: @user.id
end

should redirect_to("the home page") { root_path }
should "warn about invalid url" do
assert_equal flash[:alert], "Please double check the URL or try submitting it again."
end
end
end
end