FIX: Show error message if user is already silenced or suspended (#10988)
Users could be silenced or suspended by two staff members at the same time and would not be aware of it. This commit shows an error message if another penalty has been applied.
This commit is contained in:
parent
d384e744a8
commit
d2116f0029
|
@ -1,12 +1,13 @@
|
|||
import I18n from "I18n";
|
||||
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||
import { extractError } from "discourse/lib/ajax-error";
|
||||
import Mixin from "@ember/object/mixin";
|
||||
import { next } from "@ember/runloop";
|
||||
import { Promise } from "rsvp";
|
||||
import bootbox from "bootbox";
|
||||
|
||||
export default Mixin.create(ModalFunctionality, {
|
||||
errorMessage: null,
|
||||
reason: null,
|
||||
message: null,
|
||||
postEdit: null,
|
||||
|
@ -18,6 +19,7 @@ export default Mixin.create(ModalFunctionality, {
|
|||
|
||||
resetModal() {
|
||||
this.setProperties({
|
||||
errorMessage: null,
|
||||
reason: null,
|
||||
message: null,
|
||||
loadingUser: true,
|
||||
|
@ -66,6 +68,8 @@ export default Mixin.create(ModalFunctionality, {
|
|||
callback(result);
|
||||
}
|
||||
})
|
||||
.catch(popupAjaxError);
|
||||
.catch((error) => {
|
||||
this.set("errorMessage", extractError(error));
|
||||
});
|
||||
},
|
||||
});
|
||||
|
|
|
@ -352,28 +352,17 @@ const AdminUser = User.extend({
|
|||
type: "PUT",
|
||||
})
|
||||
.then((result) => this.setProperties(result.unsilence))
|
||||
.catch((e) => {
|
||||
const error = I18n.t("admin.user.unsilence_failed", {
|
||||
error: this._formatError(e),
|
||||
});
|
||||
bootbox.alert(error);
|
||||
})
|
||||
.finally(() => this.set("silencingUser", false));
|
||||
},
|
||||
|
||||
silence(data) {
|
||||
this.set("silencingUser", true);
|
||||
|
||||
return ajax(`/admin/users/${this.id}/silence`, {
|
||||
type: "PUT",
|
||||
data,
|
||||
})
|
||||
.then((result) => this.setProperties(result.silence))
|
||||
.catch((e) => {
|
||||
const error = I18n.t("admin.user.silence_failed", {
|
||||
error: this._formatError(e),
|
||||
});
|
||||
bootbox.alert(error);
|
||||
})
|
||||
.finally(() => this.set("silencingUser", false));
|
||||
},
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
{{#d-modal-body title="admin.user.silence_modal_title"}}
|
||||
{{#conditional-loading-spinner condition=loadingUser}}
|
||||
|
||||
{{#if errorMessage}}
|
||||
<div class="alert alert-error">{{errorMessage}}</div>
|
||||
{{/if}}
|
||||
|
||||
<div class="until-controls">
|
||||
<label>
|
||||
{{future-date-input
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
{{#d-modal-body title="admin.user.suspend_modal_title"}}
|
||||
{{#conditional-loading-spinner condition=loadingUser}}
|
||||
|
||||
{{#if errorMessage}}
|
||||
<div class="alert alert-error">{{errorMessage}}</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if user.canSuspend}}
|
||||
<div class="until-controls">
|
||||
<label>
|
||||
|
|
|
@ -93,6 +93,16 @@ class Admin::UsersController < Admin::AdminController
|
|||
|
||||
def suspend
|
||||
guardian.ensure_can_suspend!(@user)
|
||||
|
||||
if @user.suspended?
|
||||
suspend_record = @user.suspend_record
|
||||
message = I18n.t("user.already_suspended",
|
||||
staff: suspend_record.acting_user.username,
|
||||
time_ago: FreedomPatches::Rails4.time_ago_in_words(suspend_record.created_at, true, scope: :'datetime.distance_in_words_verbose')
|
||||
)
|
||||
return render json: failed_json.merge(message: message), status: 409
|
||||
end
|
||||
|
||||
params.require([:suspend_until, :reason])
|
||||
|
||||
@user.suspended_till = params[:suspend_until]
|
||||
|
@ -315,6 +325,15 @@ class Admin::UsersController < Admin::AdminController
|
|||
def silence
|
||||
guardian.ensure_can_silence_user! @user
|
||||
|
||||
if @user.silenced?
|
||||
silenced_record = @user.silenced_record
|
||||
message = I18n.t("user.already_silenced",
|
||||
staff: silenced_record.acting_user.username,
|
||||
time_ago: FreedomPatches::Rails4.time_ago_in_words(silenced_record.created_at, true, scope: :'datetime.distance_in_words_verbose')
|
||||
)
|
||||
return render json: failed_json.merge(message: message), status: 409
|
||||
end
|
||||
|
||||
message = params[:message]
|
||||
|
||||
silencer = UserSilencer.new(
|
||||
|
|
|
@ -2507,6 +2507,8 @@ en:
|
|||
same_ip_address: "Same IP address (%{ip_address}) as other users"
|
||||
inactive_user: "Inactive user"
|
||||
email_in_spam_header: "User's first email was flagged as spam"
|
||||
already_silenced: "User was already silenced by %{staff} %{time_ago}."
|
||||
already_suspended: "User was already suspended by %{staff} %{time_ago}."
|
||||
|
||||
reviewables_reminder:
|
||||
submitted:
|
||||
|
|
|
@ -149,6 +149,27 @@ RSpec.describe Admin::UsersController do
|
|||
expect(log.details).to match(/because I said so/)
|
||||
end
|
||||
|
||||
it "checks if user is suspended" do
|
||||
put "/admin/users/#{user.id}/suspend.json", params: {
|
||||
suspend_until: 5.hours.from_now,
|
||||
reason: "because I said so"
|
||||
}
|
||||
|
||||
put "/admin/users/#{user.id}/suspend.json", params: {
|
||||
suspend_until: 5.hours.from_now,
|
||||
reason: "because I said so too"
|
||||
}
|
||||
|
||||
expect(response.status).to eq(409)
|
||||
expect(response.parsed_body["message"]).to eq(
|
||||
I18n.t(
|
||||
"user.already_suspended",
|
||||
staff: admin.username,
|
||||
time_ago: FreedomPatches::Rails4.time_ago_in_words(user.suspend_record.created_at, true, scope: :'datetime.distance_in_words_verbose')
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
it "requires suspend_until and reason" do
|
||||
expect(user).not_to be_suspended
|
||||
put "/admin/users/#{user.id}/suspend.json", params: {}
|
||||
|
@ -749,6 +770,27 @@ RSpec.describe Admin::UsersController do
|
|||
reg_user.reload
|
||||
expect(reg_user).to be_silenced
|
||||
end
|
||||
|
||||
it "checks if user is silenced" do
|
||||
put "/admin/users/#{user.id}/silence.json", params: {
|
||||
silenced_till: 5.hours.from_now,
|
||||
reason: "because I said so"
|
||||
}
|
||||
|
||||
put "/admin/users/#{user.id}/silence.json", params: {
|
||||
silenced_till: 5.hours.from_now,
|
||||
reason: "because I said so too"
|
||||
}
|
||||
|
||||
expect(response.status).to eq(409)
|
||||
expect(response.parsed_body["message"]).to eq(
|
||||
I18n.t(
|
||||
"user.already_silenced",
|
||||
staff: admin.username,
|
||||
time_ago: FreedomPatches::Rails4.time_ago_in_words(user.silenced_record.created_at, true, scope: :'datetime.distance_in_words_verbose')
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#unsilence' do
|
||||
|
|
Loading…
Reference in New Issue