Case-insensitive matching of moderation commands.

Also add `/subject` as alias to `/topic`
This commit is contained in:
JC Brand 2017-02-01 17:36:20 +00:00
parent 46e231b4b3
commit bcbeb8da6c
4 changed files with 73 additions and 31 deletions

View File

@ -2,6 +2,8 @@
## 3.0.0 (Unreleased)
- Use lodash instead of underscore.js [jcbrand]
- Case insensitive matching of moderation commands. [jcbrand]
- Add `/subject` as alias to `/topic` [jcbrand]
## 2.0.5 (2017-02-01)
- #743, #751, #753 Update to Strophe 1.2.12. SASL-EXTERNAL now has reduced priority, so it won't

View File

@ -1151,6 +1151,43 @@
test_utils.clearBrowserStorage();
});
it("to set the room subject", mock.initConverse(function (converse) {
var sent_stanza;
test_utils.openChatRoom(converse, 'lounge', 'localhost', 'dummy');
var view = converse.chatboxviews.get('lounge@localhost');
spyOn(view, 'onMessageSubmitted').andCallThrough();
spyOn(view, 'clearChatRoomMessages');
spyOn(converse.connection, 'send').andCallFake(function (stanza) {
sent_stanza = stanza;
});
// Check the alias /topic
var $textarea = view.$el.find('.chat-textarea');
$textarea.val('/topic This is the room subject');
$textarea.trigger($.Event('keypress', {keyCode: 13}));
expect(view.onMessageSubmitted).toHaveBeenCalled();
expect(converse.connection.send).toHaveBeenCalled();
expect(sent_stanza.outerHTML).toBe(
'<message to="lounge@localhost" from="dummy@localhost/resource" type="groupchat" xmlns="jabber:client">'+
'<subject xmlns="jabber:client">This is the room subject</subject>'+
'</message>');
// Check /subject
$textarea.val('/subject This is a new subject');
$textarea.trigger($.Event('keypress', {keyCode: 13}));
expect(sent_stanza.outerHTML).toBe(
'<message to="lounge@localhost" from="dummy@localhost/resource" type="groupchat" xmlns="jabber:client">'+
'<subject xmlns="jabber:client">This is a new subject</subject>'+
'</message>');
// Check case insensitivity
$textarea.val('/Subject This is yet another subject');
$textarea.trigger($.Event('keypress', {keyCode: 13}));
expect(sent_stanza.outerHTML).toBe(
'<message to="lounge@localhost" from="dummy@localhost/resource" type="groupchat" xmlns="jabber:client">'+
'<subject xmlns="jabber:client">This is yet another subject</subject>'+
'</message>');
}));
it("to clear messages", mock.initConverse(function (converse) {
test_utils.openChatRoom(converse, 'lounge', 'localhost', 'dummy');
var view = converse.chatboxviews.get('lounge@localhost');
@ -1160,7 +1197,6 @@
view.$el.find('textarea.chat-textarea').trigger($.Event('keypress', {keyCode: 13}));
expect(view.onMessageSubmitted).toHaveBeenCalled();
expect(view.clearChatRoomMessages).toHaveBeenCalled();
}));
it("to make a user an owner", mock.initConverse(function (converse) {

View File

@ -568,11 +568,12 @@
keyPressed: function (ev) {
/* Event handler for when a key is pressed in a chat box textarea.
*/
var $textarea = $(ev.target), message;
var textarea = ev.target, message;
if (ev.keyCode === KEY.ENTER) {
ev.preventDefault();
message = $textarea.val();
$textarea.val('').focus();
message = textarea.value;
textarea.value = '';
textarea.focus();
if (message !== '') {
this.onMessageSubmitted(message);
converse.emit('messageSend', message);

View File

@ -874,17 +874,18 @@
return this.sendChatRoomMessage(text);
}
var match = text.replace(/^\s*/, "").match(/^\/(.*?)(?: (.*))?$/) || [false, '', ''],
args = match[2] && match[2].splitOnce(' ') || [];
switch (match[1]) {
args = match[2] && match[2].splitOnce(' ') || [],
command = match[1].toLowerCase();
switch (command) {
case 'admin':
if (!this.validateRoleChangeCommand(match[1], args)) { break; }
if (!this.validateRoleChangeCommand(command, args)) { break; }
this.setAffiliation('admin',
[{ 'jid': args[0],
'reason': args[1]
}]).fail(this.onCommandError.bind(this));
break;
case 'ban':
if (!this.validateRoleChangeCommand(match[1], args)) { break; }
if (!this.validateRoleChangeCommand(command, args)) { break; }
this.setAffiliation('outcast',
[{ 'jid': args[0],
'reason': args[1]
@ -894,44 +895,45 @@
this.clearChatRoomMessages();
break;
case 'deop':
if (!this.validateRoleChangeCommand(match[1], args)) { break; }
if (!this.validateRoleChangeCommand(command, args)) { break; }
this.modifyRole(
this.model.get('jid'), args[0], 'occupant', args[1],
undefined, this.onCommandError.bind(this));
break;
case 'help':
this.showHelpMessages([
'<strong>/admin</strong>: ' +__("Change user's affiliation to admin"),
'<strong>/ban</strong>: ' +__('Ban user from room'),
'<strong>/clear</strong>: ' +__('Remove messages'),
'<strong>/deop</strong>: ' +__('Change user role to occupant'),
'<strong>/help</strong>: ' +__('Show this menu'),
'<strong>/kick</strong>: ' +__('Kick user from room'),
'<strong>/me</strong>: ' +__('Write in 3rd person'),
'<strong>/member</strong>: '+__('Grant membership to a user'),
'<strong>/mute</strong>: ' +__("Remove user's ability to post messages"),
'<strong>/nick</strong>: ' +__('Change your nickname'),
'<strong>/op</strong>: ' +__('Grant moderator role to user'),
'<strong>/owner</strong>: ' +__('Grant ownership of this room'),
'<strong>/revoke</strong>: '+__("Revoke user's membership"),
'<strong>/topic</strong>: ' +__('Set room topic'),
'<strong>/voice</strong>: ' +__('Allow muted user to post messages')
'<strong>/admin</strong>: ' +__("Change user's affiliation to admin"),
'<strong>/ban</strong>: ' +__('Ban user from room'),
'<strong>/clear</strong>: ' +__('Remove messages'),
'<strong>/deop</strong>: ' +__('Change user role to occupant'),
'<strong>/help</strong>: ' +__('Show this menu'),
'<strong>/kick</strong>: ' +__('Kick user from room'),
'<strong>/me</strong>: ' +__('Write in 3rd person'),
'<strong>/member</strong>: ' +__('Grant membership to a user'),
'<strong>/mute</strong>: ' +__("Remove user's ability to post messages"),
'<strong>/nick</strong>: ' +__('Change your nickname'),
'<strong>/op</strong>: ' +__('Grant moderator role to user'),
'<strong>/owner</strong>: ' +__('Grant ownership of this room'),
'<strong>/revoke</strong>: ' +__("Revoke user's membership"),
'<strong>/subject</strong>: ' +__('Set room subject'),
'<strong>/topic</strong>: ' +__('Set room subject (alias for /subject)'),
'<strong>/voice</strong>: ' +__('Allow muted user to post messages')
]);
break;
case 'kick':
if (!this.validateRoleChangeCommand(match[1], args)) { break; }
if (!this.validateRoleChangeCommand(command, args)) { break; }
this.modifyRole(
this.model.get('jid'), args[0], 'none', args[1],
undefined, this.onCommandError.bind(this));
break;
case 'mute':
if (!this.validateRoleChangeCommand(match[1], args)) { break; }
if (!this.validateRoleChangeCommand(command, args)) { break; }
this.modifyRole(
this.model.get('jid'), args[0], 'visitor', args[1],
undefined, this.onCommandError.bind(this));
break;
case 'member':
if (!this.validateRoleChangeCommand(match[1], args)) { break; }
if (!this.validateRoleChangeCommand(command, args)) { break; }
this.setAffiliation('member',
[{ 'jid': args[0],
'reason': args[1]
@ -945,26 +947,27 @@
}).tree());
break;
case 'owner':
if (!this.validateRoleChangeCommand(match[1], args)) { break; }
if (!this.validateRoleChangeCommand(command, args)) { break; }
this.setAffiliation('owner',
[{ 'jid': args[0],
'reason': args[1]
}]).fail(this.onCommandError.bind(this));
break;
case 'op':
if (!this.validateRoleChangeCommand(match[1], args)) { break; }
if (!this.validateRoleChangeCommand(command, args)) { break; }
this.modifyRole(
this.model.get('jid'), args[0], 'moderator', args[1],
undefined, this.onCommandError.bind(this));
break;
case 'revoke':
if (!this.validateRoleChangeCommand(match[1], args)) { break; }
if (!this.validateRoleChangeCommand(command, args)) { break; }
this.setAffiliation('none',
[{ 'jid': args[0],
'reason': args[1]
}]).fail(this.onCommandError.bind(this));
break;
case 'topic':
case 'subject':
converse.connection.send(
$msg({
to: this.model.get('jid'),
@ -974,7 +977,7 @@
);
break;
case 'voice':
if (!this.validateRoleChangeCommand(match[1], args)) { break; }
if (!this.validateRoleChangeCommand(command, args)) { break; }
this.modifyRole(
this.model.get('jid'), args[0], 'occupant', args[1],
undefined, this.onCommandError.bind(this));