converse-muc: Support for XEP-0410 to check whether we're joined

This commit is contained in:
JC Brand 2019-06-03 11:36:55 +02:00
parent 68d4a71c75
commit f2ac9ef4d7
6 changed files with 78 additions and 15 deletions

View File

@ -1,6 +1,7 @@
# Changelog # Changelog
## 5.0.0 (Unreleased) ## 5.0.0 (Unreleased)
- Support for XEP-0410 to check whether we're still present in a room
- Initial support for the [CredentialsContainer](https://developer.mozilla.org/en-US/docs/Web/API/CredentialsContainer) web API - Initial support for the [CredentialsContainer](https://developer.mozilla.org/en-US/docs/Web/API/CredentialsContainer) web API
- Allow for synchronous events. When a synchronous event is fired, Converse will - Allow for synchronous events. When a synchronous event is fired, Converse will
wait for all promises returned by the event's handlers to finish before continuing. wait for all promises returned by the event's handlers to finish before continuing.

4
package-lock.json generated
View File

@ -13716,8 +13716,8 @@
} }
}, },
"strophe.js": { "strophe.js": {
"version": "github:strophe/strophejs#bc8a6b62203a17ada6bd78945c993c6f7dccd1de", "version": "github:strophe/strophejs#c675bcfcf44527ba1cf844a1aaa68fe7003c6140",
"from": "github:strophe/strophejs#bc8a6b62203a17ada6bd78945c993c6f7dccd1de" "from": "github:strophe/strophejs#c675bcfcf44527ba1cf844a1aaa68fe7003c6140"
}, },
"style-loader": { "style-loader": {
"version": "0.23.1", "version": "0.23.1",

View File

@ -401,6 +401,11 @@ converse.plugins.add('converse-chatboxes', {
} }
}, },
shouldShowErrorMessage () {
// Gets overridden in ChatRoom
return true;
},
/** /**
* If the passed in `message` stanza contains an * If the passed in `message` stanza contains an
* [XEP-0308](https://xmpp.org/extensions/xep-0308.html#usecase) * [XEP-0308](https://xmpp.org/extensions/xep-0308.html#usecase)
@ -987,11 +992,10 @@ converse.plugins.add('converse-chatboxes', {
// We also ignore duplicate error messages. // We also ignore duplicate error messages.
return; return;
} }
} else { }
// An error message without id likely means that we const should_show = await chatbox.shouldShowErrorMessage(message);
// sent a message without id (which shouldn't happen). if (!should_show) {
_converse.log('Received an error message without id attribute!', Strophe.LogLevel.ERROR); return;
_converse.log(message, Strophe.LogLevel.ERROR);
} }
const attrs = await chatbox.getMessageAttributesFromStanza(message, message); const attrs = await chatbox.getMessageAttributesFromStanza(message, message);
chatbox.messages.create(attrs); chatbox.messages.create(attrs);

View File

@ -1350,7 +1350,7 @@ _converse.initialize = async function (settings, callback) {
} }
} else if (reconnecting) { } else if (reconnecting) {
this.autoLogin(); this.autoLogin();
} else if (window.PasswordCredential) { } else if (!isTestEnv() && window.PasswordCredential) {
const creds = await navigator.credentials.get({'password': true}); const creds = await navigator.credentials.get({'password': true});
if (creds && creds.type == 'password' && u.isValidJID(creds.id)) { if (creds && creds.type == 'password' && u.isValidJID(creds.id)) {
setUserJID(creds.id); setUserJID(creds.id);
@ -1514,7 +1514,7 @@ _converse.api = {
* @returns {string} The current user's full JID (Jabber ID) * @returns {string} The current user's full JID (Jabber ID)
* @example _converse.api.user.jid()) * @example _converse.api.user.jid())
*/ */
'jid' () { jid () {
return _converse.connection.jid; return _converse.connection.jid;
}, },
@ -1577,19 +1577,20 @@ _converse.api = {
*/ */
_converse.api.trigger('logout'); _converse.api.trigger('logout');
}, },
/** /**
* Set and get the user's chat status, also called their *availability*. * Set and get the user's chat status, also called their *availability*.
* *
* @namespace _converse.api.user.status * @namespace _converse.api.user.status
* @memberOf _converse.api.user * @memberOf _converse.api.user
*/ */
'status': { status: {
/** Return the current user's availability status. /** Return the current user's availability status.
* *
* @method _converse.api.user.status.get * @method _converse.api.user.status.get
* @example _converse.api.user.status.get(); * @example _converse.api.user.status.get();
*/ */
'get' () { get () {
return _converse.xmppstatus.get('status'); return _converse.xmppstatus.get('status');
}, },
/** /**
@ -1602,7 +1603,7 @@ _converse.api = {
* @example this._converse.api.user.status.set('dnd'); * @example this._converse.api.user.status.set('dnd');
* @example this._converse.api.user.status.set('dnd', 'In a meeting'); * @example this._converse.api.user.status.set('dnd', 'In a meeting');
*/ */
'set' (value, message) { set (value, message) {
const data = {'status': value}; const data = {'status': value};
if (!_.includes(Object.keys(_converse.STATUS_WEIGHTS), value)) { if (!_.includes(Object.keys(_converse.STATUS_WEIGHTS), value)) {
throw new Error('Invalid availability value. See https://xmpp.org/rfcs/rfc3921.html#rfc.section.2.2.2.1'); throw new Error('Invalid availability value. See https://xmpp.org/rfcs/rfc3921.html#rfc.section.2.2.2.1');
@ -1626,7 +1627,7 @@ _converse.api = {
* @returns {string} The status message * @returns {string} The status message
* @example const message = _converse.api.user.status.message.get() * @example const message = _converse.api.user.status.message.get()
*/ */
'get' () { get () {
return _converse.xmppstatus.get('status_message'); return _converse.xmppstatus.get('status_message');
}, },
/** /**
@ -1634,7 +1635,7 @@ _converse.api = {
* @param {string} status The status message * @param {string} status The status message
* @example _converse.api.user.status.message.set('In a meeting'); * @example _converse.api.user.status.message.set('In a meeting');
*/ */
'set' (status) { set (status) {
_converse.xmppstatus.save({'status_message': status}); _converse.xmppstatus.save({'status_message': status});
} }
} }

View File

@ -1224,9 +1224,66 @@ converse.plugins.add('converse-muc', {
return attrs; return attrs;
}, },
/**
* Send a MUC-0410 MUC Self-Ping stanza to room to determine
* whether we're still joined.
* @async
* @private
* @method _converse.ChatRoom#isJoined
* @returns {Promise<boolean>}
*/
async isJoined () {
const ping = $iq({
'to': `${this.get('jid')}/${this.get('nick')}`,
'type': "get"
}).c("ping", {'xmlns': Strophe.NS.PING});
let result;
try {
result = await _converse.api.sendIQ(ping);
} catch (e) {
const sel = `error[type="cancel"] not-acceptable[xmlns="${Strophe.NS.STANZAS}"]`;
if (_.isElement(e) && sizzle(sel, e).length) {
return false;
}
}
return true;
},
/**
* Check whether we're still joined and re-join if not
* @async
* @private
* @method _converse.ChatRoom#rejoinIfNecessary
*/
async rejoinIfNecessary () {
const is_joined = await this.isJoined();
if (!is_joined) {
this.save('connection_status', converse.ROOMSTATUS.DISCONNECTED);
this.enterRoom();
return true;
}
},
/**
* @async
* @private
* @method _converse.ChatRoom#shouldShowErrorMessage
* @returns {Promise<boolean>}
*/
async shouldShowErrorMessage (stanza) {
if (sizzle(`not-acceptable[xmlns="${Strophe.NS.STANZAS}"]`, stanza).length) {
if (await this.rejoinIfNecessary()) {
return false;
}
}
return true;
},
getErrorMessage (stanza) { getErrorMessage (stanza) {
if (sizzle(`forbidden[xmlns="${Strophe.NS.STANZAS}"]`, stanza).length) { if (sizzle(`forbidden[xmlns="${Strophe.NS.STANZAS}"]`, stanza).length) {
return __("Your message was not delivered because you're not allowed to send messages in this groupchat."); return __("Your message was not delivered because you're not allowed to send messages in this groupchat.");
} else if (sizzle(`not-acceptable[xmlns="${Strophe.NS.STANZAS}"]`, stanza).length) {
return __("Your message was not delivered because you're not present in the groupchat.");
} else { } else {
return _converse.ChatBox.prototype.getErrorMessage.apply(this, arguments); return _converse.ChatBox.prototype.getErrorMessage.apply(this, arguments);
} }

View File

@ -29,7 +29,7 @@
"jed": "1.1.1", "jed": "1.1.1",
"lodash": "^4.17.11", "lodash": "^4.17.11",
"pluggable.js": "2.0.1", "pluggable.js": "2.0.1",
"strophe.js": "strophe/strophejs#bc8a6b62203a17ada6bd78945c993c6f7dccd1de", "strophe.js": "strophe/strophejs#c675bcfcf44527ba1cf844a1aaa68fe7003c6140",
"twemoji": "^11.0.1", "twemoji": "^11.0.1",
"urijs": "^1.19.1" "urijs": "^1.19.1"
} }