Commit 71370f5b authored by JC Brand's avatar JC Brand

Add the `/register` command for registering yourself

parent 17401cb9
...@@ -8,9 +8,73 @@ ...@@ -8,9 +8,73 @@
u = converse.env.utils; u = converse.env.utils;
describe("Chatrooms", function () { describe("Chatrooms", function () {
describe("The /register commmand", function () {
it("allows you to register your nickname in a room",
mock.initConverseWithPromises(
null, ['rosterGroupsFetched', 'chatBoxesFetched'], {'auto_register_muc_nickname': true},
function (done, _converse) {
let view;
const room_jid = 'coven@chat.shakespeare.lit';
test_utils.openAndEnterChatRoom(_converse, 'coven', 'chat.shakespeare.lit', 'romeo')
.then(() => {
view = _converse.chatboxviews.get(room_jid);
const textarea = view.el.querySelector('.chat-textarea')
textarea.value = '/register';
view.keyPressed({
target: textarea,
preventDefault: _.noop,
keyCode: 13
});
return test_utils.waitUntil(() => _.get(_.filter(
_converse.connection.IQ_stanzas,
iq => sizzle(`iq[to="coven@chat.shakespeare.lit"][type="get"] query[xmlns="jabber:iq:register"]`, iq.nodeTree).length
).pop(), 'nodeTree'));
}).then(stanza => {
expect(stanza.outerHTML)
.toBe(`<iq to="coven@chat.shakespeare.lit" from="dummy@localhost/resource" `+
`type="get" xmlns="jabber:client" id="${stanza.getAttribute('id')}">`+
`<query xmlns="jabber:iq:register"/></iq>`);
view = _converse.chatboxviews.get(room_jid);
const result = $iq({
'from': view.model.get('jid'),
'id': stanza.getAttribute('id'),
'to': _converse.bare_jid,
'type': 'result',
}).c('query', {'type': 'jabber:iq:register'})
.c('x', {'xmlns': 'jabber:x:data', 'type': 'form'})
.c('field', {
'label': 'Desired Nickname',
'type': 'text-single',
'var': 'muc#register_roomnick'
}).c('required');
_converse.connection._dataRecv(test_utils.createRequest(result));
return test_utils.waitUntil(() => _.get(_.filter(
_converse.connection.IQ_stanzas,
iq => sizzle(`iq[to="coven@chat.shakespeare.lit"][type="set"] query[xmlns="jabber:iq:register"]`, iq.nodeTree).length
).pop(), 'nodeTree'));
}).then(stanza => {
expect(stanza.outerHTML).toBe(
`<iq to="coven@chat.shakespeare.lit" from="dummy@localhost/resource" type="set" xmlns="jabber:client" id="${stanza.getAttribute('id')}">`+
`<query xmlns="jabber:iq:register">`+
`<x xmlns="jabber:x:data" type="submit">`+
`<field var="FORM_TYPE"><value>http://jabber.org/protocol/muc#register</value></field>`+
`<field var="muc#register_roomnick"><value>romeo</value></field>`+
`</x>`+
`</query>`+
`</iq>`);
done();
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
}));
});
describe("The auto_register_muc_nickname option", function () { describe("The auto_register_muc_nickname option", function () {
it("allows you to automatically register your nickname when joining a room", it("allows you to automatically register your nickname when joining a room",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched', 'chatBoxesFetched'], {'auto_register_muc_nickname': true}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {'auto_register_muc_nickname': true},
function (done, _converse) { function (done, _converse) {
......
...@@ -241,7 +241,7 @@ ...@@ -241,7 +241,7 @@
el.querySelector('span.spinner').remove(); el.querySelector('span.spinner').remove();
el.querySelector('a.room-info').classList.add('selected'); el.querySelector('a.room-info').classList.add('selected');
el.insertAdjacentHTML( el.insertAdjacentHTML(
'beforeEnd', 'beforeEnd',
tpl_room_description({ tpl_room_description({
'jid': stanza.getAttribute('from'), 'jid': stanza.getAttribute('from'),
'desc': _.get(_.head(sizzle('field[var="muc#roominfo_description"] value', stanza)), 'textContent'), 'desc': _.get(_.head(sizzle('field[var="muc#roominfo_description"] value', stanza)), 'textContent'),
...@@ -290,7 +290,7 @@ ...@@ -290,7 +290,7 @@
} }
} }
_converse.ListChatRoomsModal = _converse.BootstrapModal.extend({ _converse.ListChatRoomsModal = _converse.BootstrapModal.extend({
events: { events: {
...@@ -880,7 +880,7 @@ ...@@ -880,7 +880,7 @@
return false; return false;
} }
const match = text.replace(/^\s*/, "").match(/^\/(.*?)(?: (.*))?$/) || [false, '', ''], const match = text.replace(/^\s*/, "").match(/^\/(.*?)(?: (.*))?$/) || [false, '', ''],
args = match[2] && match[2].splitOnce(' ') || [], args = match[2] && match[2].splitOnce(' ').filter(s => s) || [],
command = match[1].toLowerCase(); command = match[1].toLowerCase();
switch (command) { switch (command) {
case 'admin': case 'admin':
...@@ -930,6 +930,7 @@ ...@@ -930,6 +930,7 @@
`<strong>/nick</strong>: ${__('Change your nickname')}`, `<strong>/nick</strong>: ${__('Change your nickname')}`,
`<strong>/op</strong>: ${__('Grant moderator role to user')}`, `<strong>/op</strong>: ${__('Grant moderator role to user')}`,
`<strong>/owner</strong>: ${__('Grant ownership of this groupchat')}`, `<strong>/owner</strong>: ${__('Grant ownership of this groupchat')}`,
`<strong>/register</strong>: ${__("Register a nickname for this room")}`,
`<strong>/revoke</strong>: ${__("Revoke user's membership")}`, `<strong>/revoke</strong>: ${__("Revoke user's membership")}`,
`<strong>/subject</strong>: ${__('Set groupchat subject')}`, `<strong>/subject</strong>: ${__('Set groupchat subject')}`,
`<strong>/topic</strong>: ${__('Set groupchat subject (alias for /subject)')}`, `<strong>/topic</strong>: ${__('Set groupchat subject (alias for /subject)')}`,
...@@ -997,6 +998,13 @@ ...@@ -997,6 +998,13 @@
this.model.get('jid'), args[0], 'moderator', args[1], this.model.get('jid'), args[0], 'moderator', args[1],
undefined, this.onCommandError.bind(this)); undefined, this.onCommandError.bind(this));
break; break;
case 'register':
if (args.length > 1) {
this.showErrorMessage(__(`Error: invalid number of arguments`))
} else {
this.model.registerNickname();
}
break;
case 'revoke': case 'revoke':
if (!this.verifyAffiliations(['admin', 'owner']) || !this.validateRoleChangeCommand(command, args)) { if (!this.verifyAffiliations(['admin', 'owner']) || !this.validateRoleChangeCommand(command, args)) {
break; break;
......
...@@ -810,45 +810,47 @@ ...@@ -810,45 +810,47 @@
}, },
async registerNickname () { async registerNickname () {
const nick = this.get('nick'),
jid = this.get('jid');
let iq; let iq;
try { try {
iq = await _converse.api.sendIQ( iq = await _converse.api.sendIQ(
$iq({ $iq({
'to': this.get('jid'), 'to': jid,
'from': _converse.connection.jid, 'from': _converse.connection.jid,
'type': 'get' 'type': 'get'
}).c('query', {'xmlns': Strophe.NS.MUC_REGISTER}) }).c('query', {'xmlns': Strophe.NS.MUC_REGISTER})
); );
} catch (e) { } catch (e) {
if (sizzle('item-not-found[xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"]', e).length) { if (sizzle('item-not-found[xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"]', e).length) {
_converse.log(`Can't register nickname ${this.get('nick')} in the groupchat ${this.get('jid')} which does not exist.`); _converse.log(`Can't register nickname ${nick} in the groupchat ${jid} which does not exist.`);
} else if (sizzle('not-allowed[xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"]', e).length) { } else if (sizzle('not-allowed[xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"]', e).length) {
_converse.log(`You're not allowed to register in the groupchat ${this.get('jid')}`); _converse.log(`You're not allowed to register in the groupchat ${jid}`);
} }
return _converse.log(e, Strophe.LogLevel.ERROR); return _converse.log(e, Strophe.LogLevel.ERROR);
} }
const required_fields = _.map(sizzle('field required', iq), 'parentElement'); const required_fields = _.map(sizzle('field required', iq), 'parentElement');
if (required_fields.length > 1 || required_fields[0].getAttribute('var') !== 'muc#register_roomnick') { if (required_fields.length > 1 || required_fields[0].getAttribute('var') !== 'muc#register_roomnick') {
return _converse.log(`Can't register the user register in the groupchat ${this.get('jid')} due to the required fields`); return _converse.log(`Can't register the user register in the groupchat ${jid} due to the required fields`);
} }
try { try {
await _converse.api.sendIQ($iq({ await _converse.api.sendIQ($iq({
'to': this.get('jid'), 'to': jid,
'from': _converse.connection.jid, 'from': _converse.connection.jid,
'type': 'set' 'type': 'set'
}).c('query', {'xmlns': Strophe.NS.MUC_REGISTER}) }).c('query', {'xmlns': Strophe.NS.MUC_REGISTER})
.c('x', {'xmlns': Strophe.NS.XFORM, 'type': 'submit'}) .c('x', {'xmlns': Strophe.NS.XFORM, 'type': 'submit'})
.c('field', {'var': 'FORM_TYPE'}).c('value').t('http://jabber.org/protocol/muc#register').up().up() .c('field', {'var': 'FORM_TYPE'}).c('value').t('http://jabber.org/protocol/muc#register').up().up()
.c('field', {'var': 'muc#register_roomnick'}).c('value').t(this.get('nick')) .c('field', {'var': 'muc#register_roomnick'}).c('value').t(nick)
); );
} catch (e) { } catch (e) {
if (sizzle('conflict[xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"]', e).length) { if (sizzle('conflict[xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"]', e).length) {
_converse.log(`Can't register nickname ${this.get('nick')} in the groupchat ${this.get('jid')}, it's already taken.`); _converse.log(`Can't register nickname ${nick} in the groupchat ${jid}, it's already taken.`);
} else if (sizzle('service-unavailable[xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"]', e).length) { } else if (sizzle('service-unavailable[xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"]', e).length) {
_converse.log(`Can't register nickname ${this.get('nick')} in the groupchat ${this.get('jid')}, it doesn't support registration.`); _converse.log(`Can't register nickname ${nick} in the groupchat ${jid}, it doesn't support registration.`);
} else if (sizzle('bad-request[xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"]', e).length) { } else if (sizzle('bad-request[xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"]', e).length) {
_converse.log(`Can't register nickname ${this.get('nick')} in the groupchat ${this.get('jid')}, invalid data form supplied.`); _converse.log(`Can't register nickname ${nick} in the groupchat ${jid}, invalid data form supplied.`);
} }
return _converse.log(e, Strophe.LogLevel.ERROR); return _converse.log(e, Strophe.LogLevel.ERROR);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment