diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index c54018f89d3..0940a32c760 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -524,20 +524,38 @@ class UsersController < ApplicationController end def check_email - RateLimiter.new(nil, "check-email-#{request.remote_ip}", 10, 1.minute).performed! - - if SiteSetting.hide_email_address_taken? + begin + RateLimiter.new(nil, "check-email-#{request.remote_ip}", 10, 1.minute).performed! + rescue RateLimiter::LimitExceeded return render json: success_json end - user_email = UserEmail.new(email: params[:email]) + email = Email.downcase((params[:email] || "").strip) - if user_email.valid? - render json: success_json - else - render json: failed_json.merge(errors: user_email.errors.full_messages) + if email.blank? || SiteSetting.hide_email_address_taken? + return render json: success_json end - rescue RateLimiter::LimitExceeded + + if !(email =~ EmailValidator.email_regex) + error = User.new.errors.full_message(:email, I18n.t(:'user.email.invalid')) + return render json: failed_json.merge(errors: [error]) + end + + if !EmailValidator.allowed?(email) + error = User.new.errors.full_message(:email, I18n.t(:'user.email.not_allowed')) + return render json: failed_json.merge(errors: [error]) + end + + if ScreenedEmail.should_block?(email) + error = User.new.errors.full_message(:email, I18n.t(:'user.email.blocked')) + return render json: failed_json.merge(errors: [error]) + end + + if User.where(staged: false).find_by_email(email).present? + error = User.new.errors.full_message(:email, I18n.t(:'errors.messages.taken')) + return render json: failed_json.merge(errors: [error]) + end + render json: success_json end diff --git a/spec/requests/users_controller_spec.rb b/spec/requests/users_controller_spec.rb index 2f8f5398e69..938a7d34caf 100644 --- a/spec/requests/users_controller_spec.rb +++ b/spec/requests/users_controller_spec.rb @@ -1592,6 +1592,11 @@ describe UsersController do expect(response.parsed_body["success"]).to be_present end + it 'returns success if email is empty' do + get "/u/check_email.json" + expect(response.parsed_body["success"]).to be_present + end + it 'returns failure if email is not valid' do get "/u/check_email.json", params: { email: "invalid" } expect(response.parsed_body["failed"]).to be_present @@ -1600,12 +1605,20 @@ describe UsersController do it 'returns failure if email exists' do get "/u/check_email.json", params: { email: user.email } expect(response.parsed_body["failed"]).to be_present + + get "/u/check_email.json", params: { email: user.email.upcase } + expect(response.parsed_body["failed"]).to be_present end it 'returns success if email does not exists' do get "/u/check_email.json", params: { email: "available@example.com" } expect(response.parsed_body["success"]).to be_present end + + it 'return success if user email is taken by staged user' do + get "/u/check_email.json", params: { email: Fabricate(:staged).email } + expect(response.parsed_body["success"]).to be_present + end end describe '#invited' do