From a9c6df198cbbc0b8f5bf5b7de42e71c2cdf3d150 Mon Sep 17 00:00:00 2001 From: Arpit Jalan Date: Tue, 7 Jun 2016 01:06:59 +0530 Subject: [PATCH] FEATURE: rate limit resend invites --- .../discourse/controllers/user-invited-show.js.es6 | 3 ++- app/assets/javascripts/discourse/models/invite.js.es6 | 10 +++++++--- app/controllers/invites_controller.rb | 11 ++++++++++- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/app/assets/javascripts/discourse/controllers/user-invited-show.js.es6 b/app/assets/javascripts/discourse/controllers/user-invited-show.js.es6 index ed5e0d94788..cf58bce112e 100644 --- a/app/assets/javascripts/discourse/controllers/user-invited-show.js.es6 +++ b/app/assets/javascripts/discourse/controllers/user-invited-show.js.es6 @@ -1,5 +1,6 @@ import Invite from 'discourse/models/invite'; import debounce from 'discourse/lib/debounce'; +import { popupAjaxError } from 'discourse/lib/ajax-error'; // This controller handles actions related to a user's invitations export default Ember.Controller.extend({ @@ -96,7 +97,7 @@ export default Ember.Controller.extend({ const self = this; Invite.reinviteAll().then(function() { self.set('reinvitedAll', true); - }); + }).catch(popupAjaxError); }, loadMore() { diff --git a/app/assets/javascripts/discourse/models/invite.js.es6 b/app/assets/javascripts/discourse/models/invite.js.es6 index 9b4b6c8091f..2d5197de0d9 100644 --- a/app/assets/javascripts/discourse/models/invite.js.es6 +++ b/app/assets/javascripts/discourse/models/invite.js.es6 @@ -1,3 +1,5 @@ +import { popupAjaxError } from 'discourse/lib/ajax-error'; + const Invite = Discourse.Model.extend({ rescind() { @@ -9,11 +11,13 @@ const Invite = Discourse.Model.extend({ }, reinvite() { - Discourse.ajax('/invites/reinvite', { + const self = this; + return Discourse.ajax('/invites/reinvite', { type: 'POST', data: { email: this.get('email') } - }); - this.set('reinvited', true); + }).then(function() { + self.set('reinvited', true); + }).catch(popupAjaxError); } }); diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb index e20fc825440..2311ab82624 100644 --- a/app/controllers/invites_controller.rb +++ b/app/controllers/invites_controller.rb @@ -1,3 +1,5 @@ +require_dependency 'rate_limiter' + class InvitesController < ApplicationController # TODO tighten this, why skip check on everything? @@ -127,19 +129,26 @@ class InvitesController < ApplicationController def resend_invite params.require(:email) + RateLimiter.new(current_user, "resend-invite-per-hour", 10, 1.hour).performed! invite = Invite.find_by(invited_by_id: current_user.id, email: params[:email]) raise Discourse::InvalidParameters.new(:email) if invite.blank? invite.resend_invite - render nothing: true + + rescue RateLimiter::LimitExceeded + render_json_error(I18n.t("rate_limiter.slow_down")) end def resend_all_invites guardian.ensure_can_invite_to_forum! + RateLimiter.new(current_user, "resend-all-invites-per-day", 1, 1.day).performed! Invite.resend_all_invites_from(current_user.id) render nothing: true + + rescue RateLimiter::LimitExceeded + render_json_error(I18n.t("rate_limiter.slow_down")) end def check_csv_chunk