From 6ee92c839be4496ddf72307cd82adc41292daf1a Mon Sep 17 00:00:00 2001 From: Ahmad Farhat Date: Tue, 26 Jan 2021 19:44:23 -0500 Subject: [PATCH] Added recaptcha to reset password if enabled (#2475) --- app/controllers/password_resets_controller.rb | 26 ++++++++----- app/views/password_resets/new.html.erb | 6 +++ config/locales/en.yml | 1 + .../password_resets_controller_spec.rb | 37 +++++++++++++++++++ 4 files changed, 60 insertions(+), 10 deletions(-) diff --git a/app/controllers/password_resets_controller.rb b/app/controllers/password_resets_controller.rb index 73ea364a..cd95b13c 100644 --- a/app/controllers/password_resets_controller.rb +++ b/app/controllers/password_resets_controller.rb @@ -23,22 +23,22 @@ class PasswordResetsController < ApplicationController before_action :find_user, only: [:edit, :update] before_action :check_expiration, only: [:edit, :update] - # POST /password_resets/new + # GET /password_resets/new def new end # POST /password_resets def create - begin - # Check if user exists and throw an error if he doesn't - @user = User.find_by!(email: params[:password_reset][:email].downcase, provider: @user_domain) + return redirect_to new_password_reset_path, flash: { alert: I18n.t("reset_password.captcha") } unless valid_captcha - send_password_reset_email(@user, @user.create_reset_digest) - redirect_to root_path - rescue - # User doesn't exist - redirect_to root_path, flash: { success: I18n.t("email_sent", email_type: t("reset_password.subtitle")) } - end + # Check if user exists and throw an error if he doesn't + @user = User.find_by!(email: params[:password_reset][:email].downcase, provider: @user_domain) + + send_password_reset_email(@user, @user.create_reset_digest) + redirect_to root_path + rescue + # User doesn't exist + redirect_to root_path, flash: { success: I18n.t("email_sent", email_type: t("reset_password.subtitle")) } end # GET /password_resets/:id/edit @@ -84,4 +84,10 @@ class PasswordResetsController < ApplicationController def disable_password_reset redirect_to '/404' end + + # Checks that the captcha passed is valid + def valid_captcha + return true unless Rails.configuration.recaptcha_enabled + verify_recaptcha + end end diff --git a/app/views/password_resets/new.html.erb b/app/views/password_resets/new.html.erb index 69a703a8..285d9d34 100644 --- a/app/views/password_resets/new.html.erb +++ b/app/views/password_resets/new.html.erb @@ -25,6 +25,12 @@ <%= f.label :email, t("forgot_password.email"), class: "form-label" %> <%= f.email_field :email, class: "form-control" %>
+ + <% if recaptcha_enabled? %> +
+ <%= recaptcha_tags %> +
+ <% end %> <%= f.submit t("forgot_password.submit"), class: "btn btn-primary" %> <% end %> diff --git a/config/locales/en.yml b/config/locales/en.yml index bfc1ae18..81bbc13c 100755 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -526,6 +526,7 @@ en: remove: Remove rename: Rename reset_password: + captcha: reCAPTCHA verification failed, please try again. invalid_token: Password reset token is invalid. Please try resetting your password again. subtitle: Reset Password password: New Password diff --git a/spec/controllers/password_resets_controller_spec.rb b/spec/controllers/password_resets_controller_spec.rb index 429b993b..e18dc1db 100644 --- a/spec/controllers/password_resets_controller_spec.rb +++ b/spec/controllers/password_resets_controller_spec.rb @@ -71,6 +71,43 @@ describe PasswordResetsController, type: :controller do expect(response).to redirect_to("/404") end end + + context "reCAPTCHA enabled" do + before do + allow(Rails.configuration).to receive(:enable_email_verification).and_return(true) + allow(Rails.configuration).to receive(:recaptcha_enabled).and_return(true) + end + + it "sends a reset email if the recaptcha was passed" do + allow(controller).to receive(:valid_captcha).and_return(true) + + user = create(:user, provider: "greenlight") + + params = { + password_reset: { + email: user.email, + }, + } + + expect { post :create, params: params }.to change { ActionMailer::Base.deliveries.count }.by(1) + end + + it "doesn't send an email if the recaptcha was failed" do + allow(controller).to receive(:valid_captcha).and_return(false) + + user = create(:user) + + params = { + password_reset: { + email: user.email, + }, + } + + post :create, params: params + expect(response).to redirect_to(new_password_reset_path) + expect(flash[:alert]).to be_present + end + end end describe "PATCH #update" do