2
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2025-09-06 10:50:21 +08:00
Arpit Jalan 2017-06-29 20:02:07 +05:30
parent c6b83f4714
commit e7b9b1312e
9 changed files with 58 additions and 3 deletions

View file

@ -12,6 +12,7 @@ export default Ember.Controller.extend({
canLoadMore: true, canLoadMore: true,
invitesLoading: false, invitesLoading: false,
reinvitedAll: false, reinvitedAll: false,
rescindedAll: false,
init: function() { init: function() {
this._super(); this._super();
@ -32,7 +33,7 @@ export default Ember.Controller.extend({
inviteRedeemed: Em.computed.equal('filter', 'redeemed'), inviteRedeemed: Em.computed.equal('filter', 'redeemed'),
showReinviteAllButton: function() { showBulkActionButtons: function() {
return (this.get('filter') === "pending" && this.get('model').invites.length > 4 && this.currentUser.get('staff')); return (this.get('filter') === "pending" && this.get('model').invites.length > 4 && this.currentUser.get('staff'));
}.property('filter'), }.property('filter'),
@ -86,6 +87,18 @@ export default Ember.Controller.extend({
return false; return false;
}, },
rescindAll() {
const self = this;
bootbox.confirm(I18n.t("user.invited.rescind_all_confirm"), confirm => {
if (confirm) {
Invite.rescindAll().then(function() {
self.set('rescindedAll', true);
self.get('model.invites').clear();
}).catch(popupAjaxError);
}
});
},
reinvite(invite) { reinvite(invite) {
invite.reinvite(); invite.reinvite();
return false; return false;

View file

@ -58,6 +58,10 @@ Invite.reopenClass({
reinviteAll() { reinviteAll() {
return ajax('/invites/reinvite-all', { type: 'POST' }); return ajax('/invites/reinvite-all', { type: 'POST' });
},
rescindAll() {
return ajax('/invites/rescind-all', { type: 'POST' });
} }
}); });

View file

@ -19,7 +19,12 @@
{{csv-uploader uploading=uploading}} {{csv-uploader uploading=uploading}}
<a href="https://meta.discourse.org/t/sending-bulk-user-invites/16468" target="_blank" style="color:black;">{{fa-icon "question-circle"}}</a> <a href="https://meta.discourse.org/t/sending-bulk-user-invites/16468" target="_blank" style="color:black;">{{fa-icon "question-circle"}}</a>
{{/if}} {{/if}}
{{#if showReinviteAllButton}} {{#if showBulkActionButtons}}
{{#if rescindedAll}}
{{i18n 'user.invited.rescinded_all'}}
{{else}}
{{d-button icon="times" action="rescindAll" class="btn" label="user.invited.rescind_all"}}
{{/if}}
{{#if reinvitedAll}} {{#if reinvitedAll}}
{{i18n 'user.invited.reinvited_all'}} {{i18n 'user.invited.reinvited_all'}}
{{else}} {{else}}

View file

@ -6,7 +6,7 @@ class InvitesController < ApplicationController
skip_before_filter :preload_json, except: [:show] skip_before_filter :preload_json, except: [:show]
skip_before_filter :redirect_to_login_if_required skip_before_filter :redirect_to_login_if_required
before_filter :ensure_logged_in, only: [:destroy, :create, :create_invite_link, :resend_invite, :resend_all_invites, :upload_csv] before_filter :ensure_logged_in, only: [:destroy, :create, :create_invite_link, :rescind_all_invites, :resend_invite, :resend_all_invites, :upload_csv]
before_filter :ensure_new_registrations_allowed, only: [:show, :perform_accept_invitation, :redeem_disposable_invite] before_filter :ensure_new_registrations_allowed, only: [:show, :perform_accept_invitation, :redeem_disposable_invite]
before_filter :ensure_not_logged_in, only: [:show, :perform_accept_invitation, :redeem_disposable_invite] before_filter :ensure_not_logged_in, only: [:show, :perform_accept_invitation, :redeem_disposable_invite]
@ -150,6 +150,13 @@ class InvitesController < ApplicationController
render nothing: true render nothing: true
end end
def rescind_all_invites
guardian.ensure_can_rescind_all_invites!(current_user)
Invite.rescind_all_invites_from(current_user)
render nothing: true
end
def resend_invite def resend_invite
params.require(:email) params.require(:email)
RateLimiter.new(current_user, "resend-invite-per-hour", 10, 1.hour).performed! RateLimiter.new(current_user, "resend-invite-per-hour", 10, 1.hour).performed!

View file

@ -256,6 +256,12 @@ class Invite < ActiveRecord::Base
end end
end end
def self.rescind_all_invites_from(user)
Invite.where('invites.user_id IS NULL AND invites.email IS NOT NULL AND invited_by_id = ?', user.id).find_each do |invite|
invite.trash!(user) unless invite.blank?
end
end
def limit_invites_per_day def limit_invites_per_day
RateLimiter.new(invited_by, "invites-per-day", SiteSetting.max_invites_per_day, 1.day.to_i) RateLimiter.new(invited_by, "invites-per-day", SiteSetting.max_invites_per_day, 1.day.to_i)
end end

View file

@ -836,6 +836,9 @@ en:
expired: "This invite has expired." expired: "This invite has expired."
rescind: "Remove" rescind: "Remove"
rescinded: "Invite removed" rescinded: "Invite removed"
rescind_all: "Remove all Invites"
rescinded_all: "All Invites removed!"
rescind_all_confirm: "Are you sure you want to remove all invites?"
reinvite: "Resend Invite" reinvite: "Resend Invite"
reinvite_all: "Resend all Invites" reinvite_all: "Resend all Invites"
reinvite_all_confirm: "Are you sure you want to resend all invites?" reinvite_all_confirm: "Are you sure you want to resend all invites?"

View file

@ -646,6 +646,7 @@ Discourse::Application.routes.draw do
resources :invites resources :invites
post "invites/upload_csv" => "invites#upload_csv" post "invites/upload_csv" => "invites#upload_csv"
post "invites/rescind-all" => "invites#rescind_all_invites"
post "invites/reinvite" => "invites#resend_invite" post "invites/reinvite" => "invites#resend_invite"
post "invites/reinvite-all" => "invites#resend_all_invites" post "invites/reinvite-all" => "invites#resend_all_invites"
post "invites/link" => "invites#create_invite_link" post "invites/link" => "invites#create_invite_link"

View file

@ -269,6 +269,10 @@ class Guardian
user.staff? user.staff?
end end
def can_rescind_all_invites?(user)
user.staff?
end
def can_see_private_messages?(user_id) def can_see_private_messages?(user_id)
is_admin? || (authenticated? && @user.id == user_id) is_admin? || (authenticated? && @user.id == user_id)
end end

View file

@ -484,4 +484,16 @@ describe Invite do
end end
describe '.rescind_all_invites_from' do
it 'removes all invites sent by a user' do
user = Fabricate(:user)
invite_1 = Fabricate(:invite, invited_by: user)
invite_2 = Fabricate(:invite, invited_by: user)
Invite.rescind_all_invites_from(user)
invite_1.reload
invite_2.reload
expect(invite_1.deleted_at).to be_present
expect(invite_2.deleted_at).to be_present
end
end
end end