diff --git a/app/assets/javascripts/discourse/controllers/preferences/email.js.es6 b/app/assets/javascripts/discourse/controllers/preferences/email.js.es6 index c5edaef1991..50ee7857d2c 100644 --- a/app/assets/javascripts/discourse/controllers/preferences/email.js.es6 +++ b/app/assets/javascripts/discourse/controllers/preferences/email.js.es6 @@ -34,8 +34,13 @@ export default ObjectController.extend({ this.set('saving', true); return this.get('content').changeEmail(this.get('newEmail')).then(function() { self.set('success', true); - }, function() { + }, function(data) { self.setProperties({ error: true, saving: false }); + if (data.responseJSON && data.responseJSON.errors && data.responseJSON.errors[0]) { + self.set('errorMessage', data.responseJSON.errors[0]); + } else { + self.set('errorMessage', I18n.t('user.change_email.error')); + } }); } } diff --git a/app/assets/javascripts/discourse/templates/user/email.js.handlebars b/app/assets/javascripts/discourse/templates/user/email.js.handlebars index 266d2afd384..8503485d140 100644 --- a/app/assets/javascripts/discourse/templates/user/email.js.handlebars +++ b/app/assets/javascripts/discourse/templates/user/email.js.handlebars @@ -17,7 +17,7 @@ {{#if error}}
-
{{i18n user.change_email.error}}
+
{{errorMessage}}
{{/if}} diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index b7f1fc73276..8fb55cacbcd 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,6 +1,7 @@ require_dependency 'discourse_hub' require_dependency 'user_name_suggester' require_dependency 'avatar_upload_service' +require_dependency 'rate_limiter' class UsersController < ApplicationController @@ -261,6 +262,9 @@ class UsersController < ApplicationController guardian.ensure_can_edit_email!(user) lower_email = Email.downcase(params[:email]).strip + RateLimiter.new(user, "change-email-hr-#{request.remote_ip}", 6, 1.hour).performed! + RateLimiter.new(user, "change-email-min-#{request.remote_ip}", 3, 1.minute).performed! + # Raise an error if the email is already in use if User.find_by_email(lower_email) raise Discourse::InvalidParameters.new(:email) @@ -276,6 +280,8 @@ class UsersController < ApplicationController ) render nothing: true + rescue RateLimiter::LimitExceeded + render_json_error(I18n.t("rate_limiter.slow_down")) end def authorize_email