Add option to deregister nickname when closing a MUC
By setting `auto_register_muc_nickname` to `'unregister'`
This commit is contained in:
parent
0756af2b30
commit
59d55b3526
@ -24,6 +24,7 @@
|
||||
- Use the MUC stanza id when sending XEP-0333 markers
|
||||
- Add support for rendering unfurls via [mod_ogp](https://modules.prosody.im/mod_ogp.html)
|
||||
- Add a Description Of A Project (DOAP) file
|
||||
- Add ability to deregister nickname when closing a MUC by setting `auto_register_muc_nickname` to `'unregister'`.
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
|
@ -435,12 +435,17 @@ auto_register_muc_nickname
|
||||
--------------------------
|
||||
|
||||
* Default: ``false``
|
||||
* Allowed values: ``false``, ``true``, ``'unregister'``
|
||||
|
||||
Determines whether Converse should automatically register a user's nickname
|
||||
when they enter a groupchat.
|
||||
If truthy, Converse will automatically register a user's nickname upon entering
|
||||
a groupchat.
|
||||
|
||||
See here fore more details: https://xmpp.org/extensions/xep-0045.html#register
|
||||
|
||||
If set to ``'unregister'``, then the user's nickname will be registered
|
||||
(because it's a truthy value) and also be unregistered when the user
|
||||
permanently leaves the MUC by closing it.
|
||||
|
||||
auto_subscribe
|
||||
--------------
|
||||
|
||||
|
@ -33,6 +33,7 @@ module.exports = function(config) {
|
||||
{ pattern: "src/headless/plugins/chat/tests/api.js", type: 'module' },
|
||||
{ pattern: "src/headless/plugins/disco/tests/disco.js", type: 'module' },
|
||||
{ pattern: "src/headless/plugins/muc/tests/affiliations.js", type: 'module' },
|
||||
{ pattern: "src/headless/plugins/muc/tests/registration.js", type: 'module' },
|
||||
{ pattern: "src/headless/plugins/ping/tests/ping.js", type: 'module' },
|
||||
{ pattern: "src/headless/plugins/roster/tests/presence.js", type: 'module' },
|
||||
{ pattern: "src/headless/plugins/smacks/tests/smacks.js", type: 'module' },
|
||||
|
@ -322,7 +322,8 @@ mock.openAndEnterChatRoom = async function (_converse, muc_jid, nick, features=[
|
||||
const affs = _converse.muc_fetch_members;
|
||||
const all_affiliations = Array.isArray(affs) ? affs : (affs ? ['member', 'admin', 'owner'] : []);
|
||||
await mock.returnMemberLists(_converse, muc_jid, members, all_affiliations);
|
||||
return model.messages.fetched;
|
||||
await model.messages.fetched;
|
||||
return model;
|
||||
};
|
||||
|
||||
mock.createContact = async function (_converse, name, ask, requesting, subscription) {
|
||||
|
@ -845,6 +845,12 @@ const ChatRoomMixin = {
|
||||
|
||||
async close (ev) {
|
||||
await this.leave();
|
||||
if (
|
||||
api.settings.get('auto_register_muc_nickname') === 'unregister' &&
|
||||
(await api.disco.supports(Strophe.NS.MUC_REGISTER, this.get('jid')))
|
||||
) {
|
||||
this.unregisterNickname();
|
||||
}
|
||||
this.occupants.clearStore();
|
||||
|
||||
if (ev?.name !== 'closeAllChatBoxes' && api.settings.get('muc_clear_messages_on_leave')) {
|
||||
@ -1533,7 +1539,7 @@ const ChatRoomMixin = {
|
||||
|
||||
async registerNickname () {
|
||||
// See https://xmpp.org/extensions/xep-0045.html#register
|
||||
const __ = _converse.__;
|
||||
const { __ } = _converse;
|
||||
const nick = this.get('nick');
|
||||
const jid = this.get('jid');
|
||||
let iq, err_msg;
|
||||
@ -1541,7 +1547,6 @@ const ChatRoomMixin = {
|
||||
iq = await api.sendIQ(
|
||||
$iq({
|
||||
'to': jid,
|
||||
'from': _converse.connection.jid,
|
||||
'type': 'get'
|
||||
}).c('query', { 'xmlns': Strophe.NS.MUC_REGISTER })
|
||||
);
|
||||
@ -1562,19 +1567,13 @@ const ChatRoomMixin = {
|
||||
await api.sendIQ(
|
||||
$iq({
|
||||
'to': jid,
|
||||
'from': _converse.connection.jid,
|
||||
'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('field', { 'var': 'FORM_TYPE' })
|
||||
.c('value')
|
||||
.t('http://jabber.org/protocol/muc#register')
|
||||
.up()
|
||||
.up()
|
||||
.c('field', { 'var': 'muc#register_roomnick' })
|
||||
.c('value')
|
||||
.t(nick)
|
||||
.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(nick)
|
||||
);
|
||||
} catch (e) {
|
||||
if (sizzle(`service-unavailable[xmlns="${Strophe.NS.STANZAS}"]`, e).length) {
|
||||
@ -1588,6 +1587,28 @@ const ChatRoomMixin = {
|
||||
}
|
||||
},
|
||||
|
||||
async unregisterNickname () {
|
||||
const jid = this.get('jid');
|
||||
let iq;
|
||||
try {
|
||||
iq = await api.sendIQ(
|
||||
$iq({
|
||||
'to': jid,
|
||||
'type': 'set'
|
||||
}).c('query', { 'xmlns': Strophe.NS.MUC_REGISTER })
|
||||
);
|
||||
} catch (e) {
|
||||
log.error(e);
|
||||
return e;
|
||||
}
|
||||
if (sizzle(`query[xmlns="${Strophe.NS.MUC_REGISTER}"] registered`, iq).pop()) {
|
||||
const iq = $iq({ 'to': jid, 'type': 'set' })
|
||||
.c('query', { 'xmlns': Strophe.NS.MUC_REGISTER })
|
||||
.c('remove');
|
||||
return api.sendIQ(iq).catch(e => log.error(e));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Given a presence stanza, update the occupant model based on its contents.
|
||||
* @private
|
||||
|
116
src/headless/plugins/muc/tests/registration.js
Normal file
116
src/headless/plugins/muc/tests/registration.js
Normal file
@ -0,0 +1,116 @@
|
||||
/*global mock, converse */
|
||||
|
||||
const { $iq, Strophe, sizzle, u } = converse.env;
|
||||
|
||||
describe("Chatrooms", function () {
|
||||
|
||||
describe("The auto_register_muc_nickname option", function () {
|
||||
|
||||
it("allows you to automatically register your nickname when joining a room",
|
||||
mock.initConverse(['chatBoxesFetched'], {'auto_register_muc_nickname': true},
|
||||
async function (done, _converse) {
|
||||
|
||||
const muc_jid = 'coven@chat.shakespeare.lit';
|
||||
const room = await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
|
||||
|
||||
let stanza = await u.waitUntil(() => _converse.connection.IQ_stanzas.filter(
|
||||
iq => sizzle(`iq[to="${muc_jid}"][type="get"] query[xmlns="jabber:iq:register"]`, iq).length
|
||||
).pop());
|
||||
|
||||
expect(Strophe.serialize(stanza))
|
||||
.toBe(`<iq id="${stanza.getAttribute('id')}" to="${muc_jid}" `+
|
||||
`type="get" xmlns="jabber:client">`+
|
||||
`<query xmlns="jabber:iq:register"/></iq>`);
|
||||
const result = $iq({
|
||||
'from': room.get('jid'),
|
||||
'id': stanza.getAttribute('id'),
|
||||
'to': _converse.bare_jid,
|
||||
'type': 'result',
|
||||
}).c('query', {'xmlns': '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(mock.createRequest(result));
|
||||
stanza = await u.waitUntil(() => _converse.connection.IQ_stanzas.filter(
|
||||
iq => sizzle(`iq[to="${muc_jid}"][type="set"] query[xmlns="jabber:iq:register"]`, iq).length
|
||||
).pop());
|
||||
|
||||
expect(Strophe.serialize(stanza)).toBe(
|
||||
`<iq id="${stanza.getAttribute('id')}" to="${muc_jid}" type="set" xmlns="jabber:client">`+
|
||||
`<query xmlns="jabber:iq:register">`+
|
||||
`<x type="submit" xmlns="jabber:x:data">`+
|
||||
`<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();
|
||||
}));
|
||||
|
||||
it("allows you to automatically deregister your nickname when closing a room",
|
||||
mock.initConverse(['chatBoxesFetched'], {'auto_register_muc_nickname': 'unregister'},
|
||||
async function (done, _converse) {
|
||||
|
||||
const muc_jid = 'coven@chat.shakespeare.lit';
|
||||
const room = await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
|
||||
|
||||
let stanza = await u.waitUntil(() => _converse.connection.IQ_stanzas.filter(
|
||||
iq => sizzle(`iq[to="${muc_jid}"][type="get"] query[xmlns="jabber:iq:register"]`, iq).length
|
||||
).pop());
|
||||
let result = $iq({
|
||||
'from': room.get('jid'),
|
||||
'id': stanza.getAttribute('id'),
|
||||
'to': _converse.bare_jid,
|
||||
'type': 'result',
|
||||
}).c('query', {'xmlns': '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(mock.createRequest(result));
|
||||
await u.waitUntil(() => _converse.connection.IQ_stanzas.filter(
|
||||
iq => sizzle(`iq[to="${muc_jid}"][type="set"] query[xmlns="jabber:iq:register"]`, iq).length
|
||||
).pop());
|
||||
|
||||
_converse.connection.IQ_stanzas = [];
|
||||
room.close();
|
||||
stanza = await u.waitUntil(() => _converse.connection.IQ_stanzas.filter(
|
||||
iq => sizzle(`iq[to="${muc_jid}"][type="set"] query[xmlns="jabber:iq:register"]`, iq).length
|
||||
).pop());
|
||||
_converse.connection.IQ_stanzas = [];
|
||||
|
||||
result = $iq({
|
||||
'from': room.get('jid'),
|
||||
'id': stanza.getAttribute('id'),
|
||||
'to': _converse.bare_jid,
|
||||
'type': 'result',
|
||||
}).c('query', {'xmlns': 'jabber:iq:register'})
|
||||
.c('registered').up()
|
||||
.c('username').t('romeo');
|
||||
_converse.connection._dataRecv(mock.createRequest(result));
|
||||
|
||||
stanza = await u.waitUntil(() => _converse.connection.IQ_stanzas.filter(
|
||||
iq => sizzle(`iq[to="${muc_jid}"][type="set"] query[xmlns="jabber:iq:register"]`, iq).length
|
||||
).pop());
|
||||
expect(Strophe.serialize(stanza)).toBe(
|
||||
`<iq id="${stanza.getAttribute('id')}" to="${muc_jid}" type="set" xmlns="jabber:client">`+
|
||||
`<query xmlns="jabber:iq:register"><remove/></query>`+
|
||||
`</iq>`);
|
||||
|
||||
result = $iq({
|
||||
'from': room.get('jid'),
|
||||
'id': stanza.getAttribute('id'),
|
||||
'to': _converse.bare_jid,
|
||||
'type': 'result',
|
||||
}).c('query', {'xmlns': 'jabber:iq:register'});
|
||||
_converse.connection._dataRecv(mock.createRequest(result));
|
||||
|
||||
done();
|
||||
}));
|
||||
});
|
||||
});
|
@ -1,9 +1,6 @@
|
||||
/*global mock, converse, _ */
|
||||
/*global mock, converse */
|
||||
|
||||
const $iq = converse.env.$iq,
|
||||
Strophe = converse.env.Strophe,
|
||||
sizzle = converse.env.sizzle,
|
||||
u = converse.env.utils;
|
||||
const { $iq, Strophe, sizzle, u } = converse.env;
|
||||
|
||||
describe("Chatrooms", function () {
|
||||
|
||||
@ -24,12 +21,11 @@ describe("Chatrooms", function () {
|
||||
preventDefault: function preventDefault () {},
|
||||
keyCode: 13
|
||||
});
|
||||
let stanza = await u.waitUntil(() => _.filter(
|
||||
_converse.connection.IQ_stanzas,
|
||||
let stanza = await u.waitUntil(() => _converse.connection.IQ_stanzas.filter(
|
||||
iq => sizzle(`iq[to="${muc_jid}"][type="get"] query[xmlns="jabber:iq:register"]`, iq).length
|
||||
).pop());
|
||||
expect(Strophe.serialize(stanza))
|
||||
.toBe(`<iq from="romeo@montague.lit/orchard" id="${stanza.getAttribute('id')}" to="coven@chat.shakespeare.lit" `+
|
||||
.toBe(`<iq id="${stanza.getAttribute('id')}" to="coven@chat.shakespeare.lit" `+
|
||||
`type="get" xmlns="jabber:client">`+
|
||||
`<query xmlns="jabber:iq:register"/></iq>`);
|
||||
const result = $iq({
|
||||
@ -45,64 +41,12 @@ describe("Chatrooms", function () {
|
||||
'var': 'muc#register_roomnick'
|
||||
}).c('required');
|
||||
_converse.connection._dataRecv(mock.createRequest(result));
|
||||
stanza = await u.waitUntil(() => _.filter(
|
||||
_converse.connection.IQ_stanzas,
|
||||
stanza = await u.waitUntil(() => _converse.connection.IQ_stanzas.filter(
|
||||
iq => sizzle(`iq[to="${muc_jid}"][type="set"] query[xmlns="jabber:iq:register"]`, iq).length
|
||||
).pop());
|
||||
|
||||
expect(Strophe.serialize(stanza)).toBe(
|
||||
`<iq from="romeo@montague.lit/orchard" id="${stanza.getAttribute('id')}" to="coven@chat.shakespeare.lit" type="set" xmlns="jabber:client">`+
|
||||
`<query xmlns="jabber:iq:register">`+
|
||||
`<x type="submit" xmlns="jabber:x:data">`+
|
||||
`<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();
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
describe("The auto_register_muc_nickname option", function () {
|
||||
|
||||
it("allows you to automatically register your nickname when joining a room",
|
||||
mock.initConverse(['chatBoxesFetched'], {'auto_register_muc_nickname': true},
|
||||
async function (done, _converse) {
|
||||
|
||||
const muc_jid = 'coven@chat.shakespeare.lit';
|
||||
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
|
||||
const view = _converse.chatboxviews.get(muc_jid);
|
||||
|
||||
let stanza = await u.waitUntil(() => _.filter(
|
||||
_converse.connection.IQ_stanzas,
|
||||
iq => sizzle(`iq[to="coven@chat.shakespeare.lit"][type="get"] query[xmlns="jabber:iq:register"]`, iq).length
|
||||
).pop());
|
||||
|
||||
expect(Strophe.serialize(stanza))
|
||||
.toBe(`<iq from="romeo@montague.lit/orchard" id="${stanza.getAttribute('id')}" to="coven@chat.shakespeare.lit" `+
|
||||
`type="get" xmlns="jabber:client">`+
|
||||
`<query xmlns="jabber:iq:register"/></iq>`);
|
||||
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(mock.createRequest(result));
|
||||
stanza = await u.waitUntil(() => _.filter(
|
||||
_converse.connection.IQ_stanzas,
|
||||
iq => sizzle(`iq[to="coven@chat.shakespeare.lit"][type="set"] query[xmlns="jabber:iq:register"]`, iq).length
|
||||
).pop());
|
||||
|
||||
expect(Strophe.serialize(stanza)).toBe(
|
||||
`<iq from="romeo@montague.lit/orchard" id="${stanza.getAttribute('id')}" to="coven@chat.shakespeare.lit" type="set" xmlns="jabber:client">`+
|
||||
`<iq id="${stanza.getAttribute('id')}" to="coven@chat.shakespeare.lit" type="set" xmlns="jabber:client">`+
|
||||
`<query xmlns="jabber:iq:register">`+
|
||||
`<x type="submit" xmlns="jabber:x:data">`+
|
||||
`<field var="FORM_TYPE"><value>http://jabber.org/protocol/muc#register</value></field>`+
|
||||
|
Loading…
Reference in New Issue
Block a user