소스 검색

Support for XEP-0223

JC Brand 6 달 전
부모
커밋
81de942942

+ 5 - 0
conversejs.doap

@@ -146,6 +146,11 @@
         <xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0206.html"/>
       </xmpp:SupportedXep>
     </implements>
+    <implements>
+      <xmpp:SupportedXep>
+        <xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0223.html"/>
+      </xmpp:SupportedXep>
+    </implements>
     <implements>
       <xmpp:SupportedXep>
         <xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0245.html"/>

+ 37 - 14
src/headless/plugins/pubsub/api.js

@@ -37,26 +37,16 @@ export default {
         async publish(jid, node, item, options, strict_options = true) {
             const bare_jid = _converse.session.get('bare_jid');
             const entity_jid = jid || bare_jid;
-            const supports_publish_options = await api.disco.supports(
-                Strophe.NS.PUBSUB + '#publish-options',
-                entity_jid
-            );
-            if (!supports_publish_options) {
-                log.warn(
-                    `api.pubsub.publish: ${entity_jid} does not support #publish-options, ` +
-                        `so we didn't set them even though they were provided.`
-                );
-            }
 
             const stanza = stx`
                 <iq xmlns="jabber:client"
-                        from="${bare_jid}"
-                        type="set"
-                        ${entity_jid !== bare_jid ? `to="${entity_jid}"` : ''}>
+                    from="${bare_jid}"
+                    type="set"
+                    ${entity_jid !== bare_jid ? `to="${entity_jid}"` : ''}>
                 <pubsub xmlns="${Strophe.NS.PUBSUB}">
                     <publish node="${node}">${item}</publish>
                     ${
-                        options && supports_publish_options
+                        options
                             ? stx`<publish-options>
                     <x xmlns="${Strophe.NS.XFORM}" type="submit">
                         <field var="FORM_TYPE" type="hidden">
@@ -69,6 +59,39 @@ export default {
                 </pubsub>
                 </iq>`;
 
+            if (entity_jid === bare_jid) {
+                // This is PEP, check for support
+                const supports_pep =
+                    (await api.disco.getIdentity('pubsub', 'pep', bare_jid)) ||
+                    (await api.disco.getIdentity('pubsub', 'pep', Strophe.getDomainFromJid(bare_jid)));
+
+                if (!supports_pep) {
+                    log.warn(`api.pubsub.publish: Not publishing via PEP because it's not supported!`);
+                    log.warn(stanza);
+                    return;
+                }
+            }
+
+            // Check for #publish-options support.
+            // XEP-0223 says we need to check the server for support,
+            // but Prosody returns it on the bare jid.
+            const supports_publish_options =
+                (await api.disco.supports(Strophe.NS.PUBSUB + '#publish-options', entity_jid)) ||
+                (await api.disco.supports(
+                    Strophe.NS.PUBSUB + '#publish-options',
+                    Strophe.getDomainFromJid(entity_jid)
+                ));
+
+            if (!supports_publish_options) {
+                if (strict_options) {
+                    log.warn(`api.pubsub.publish: #publish-options not supported, refusing to publish item.`);
+                    log.warn(stanza);
+                    return;
+                } else {
+                    log.warn(`api.pubsub.publish: #publish-options not supported, publishing anyway.`);
+                }
+            }
+
             try {
                 await api.sendIQ(stanza);
             } catch (iq) {

+ 1 - 0
src/headless/types/plugins/muc/message.d.ts

@@ -1,5 +1,6 @@
 export default MUCMessage;
 declare class MUCMessage extends Message {
+    get occupants(): any;
     /**
      * Determines whether this messsage may be moderated,
      * based on configuration settings and server support.

+ 5 - 5
src/plugins/omemo/api.js

@@ -10,7 +10,7 @@ export default {
      * @namespace _converse.api.omemo
      * @memberOf _converse.api
      */
-    'omemo': {
+    omemo: {
         /**
          * Returns the device ID of the current device.
          */
@@ -19,7 +19,7 @@ export default {
             return _converse.state.omemo_store.get('device_id');
         },
 
-        'session': {
+        session: {
             async restore () {
                 const { state } = _converse;
                 if (state.omemo_store === undefined) {
@@ -38,7 +38,7 @@ export default {
          * @namespace _converse.api.omemo.devicelists
          * @memberOf _converse.api.omemo
          */
-        'devicelists': {
+        devicelists: {
             /**
              * Returns the {@link _converse.DeviceList} for a particular JID.
              * The device list will be created if it doesn't exist already.
@@ -62,14 +62,14 @@ export default {
          * @namespace _converse.api.omemo.bundle
          * @memberOf _converse.api.omemo
          */
-        'bundle': {
+        bundle: {
             /**
              * Lets you generate a new OMEMO device bundle
              *
              * @method _converse.api.omemo.bundle.generate
              * @returns {promise} Promise which resolves once we have a result from the server.
              */
-            'generate': async () => {
+            async generate () {
                 await api.waitUntil('OMEMOInitialized');
                 // Remove current device
                 const bare_jid = _converse.session.get('bare_jid');

+ 8 - 3
src/plugins/omemo/tests/omemo.js

@@ -249,11 +249,17 @@ describe("The OMEMO module", function() {
     it("will create a new device based on a received carbon message",
             mock.initConverse(['chatBoxesFetched'], {}, async function (_converse) {
 
+        await mock.initializedOMEMO(
+            _converse,
+            [{'category': 'pubsub', 'type': 'pep'}],
+            [
+                Strophe.NS.SID,
+                'http://jabber.org/protocol/pubsub#publish-options'
+            ]
+        );
 
-        await mock.waitUntilDiscoConfirmed(_converse, _converse.bare_jid, [], [Strophe.NS.SID]);
         await mock.waitForRoster(_converse, 'current', 1);
         const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
-        await u.waitUntil(() => mock.initializedOMEMO(_converse));
         await mock.openChatBoxFor(_converse, contact_jid);
 
         let iq_stanza = await u.waitUntil(() => mock.deviceListFetched(_converse, contact_jid));
@@ -1101,7 +1107,6 @@ describe("The OMEMO module", function() {
             mock.initConverse(['chatBoxesFetched'], {}, async function (_converse) {
 
         await mock.waitForRoster(_converse, 'current', 1);
-
         await mock.waitUntilDiscoConfirmed(
             _converse, _converse.bare_jid,
             [{'category': 'pubsub', 'type': 'pep'}],

+ 1 - 1
src/plugins/omemo/utils.js

@@ -743,7 +743,7 @@ async function checkOMEMOSupported (chatbox) {
     } else if (chatbox.get('type') === PRIVATE_CHAT_TYPE) {
         supported = await contactHasOMEMOSupport(chatbox.get('jid'));
     }
-    chatbox.set('omemo_supported', supported);
+    chatbox.set('omemo_supported', !!supported);
     if (supported && api.settings.get('omemo_default')) {
         chatbox.set('omemo_active', true);
     }

+ 20 - 16
src/shared/tests/mock.js

@@ -784,40 +784,44 @@ function bundleFetched (_converse, jid, device_id) {
     ).pop();
 }
 
-async function initializedOMEMO (_converse) {
-    await waitUntilDiscoConfirmed(
-        _converse, _converse.bare_jid,
-        [{'category': 'pubsub', 'type': 'pep'}],
-        ['http://jabber.org/protocol/pubsub#publish-options']
-    );
-    let iq_stanza = await u.waitUntil(() => deviceListFetched(_converse, _converse.bare_jid));
+async function initializedOMEMO(
+    _converse,
+    identities = [{ 'category': 'pubsub', 'type': 'pep' }],
+    features = ['http://jabber.org/protocol/pubsub#publish-options']
+) {
+    await waitUntilDiscoConfirmed(_converse, _converse.bare_jid, identities, features);
+    let iq_stanza = await deviceListFetched(_converse, _converse.bare_jid);
     let stanza = $iq({
         'from': _converse.bare_jid,
         'id': iq_stanza.getAttribute('id'),
         'to': _converse.bare_jid,
         'type': 'result',
-    }).c('pubsub', {'xmlns': "http://jabber.org/protocol/pubsub"})
-        .c('items', {'node': "eu.siacs.conversations.axolotl.devicelist"})
-            .c('item', {'xmlns': "http://jabber.org/protocol/pubsub"}) // TODO: must have an id attribute
-                .c('list', {'xmlns': "eu.siacs.conversations.axolotl"})
-                    .c('device', {'id': '482886413b977930064a5888b92134fe'});
+    })
+        .c('pubsub', { 'xmlns': 'http://jabber.org/protocol/pubsub' })
+        .c('items', { 'node': 'eu.siacs.conversations.axolotl.devicelist' })
+        .c('item', { 'xmlns': 'http://jabber.org/protocol/pubsub' }) // TODO: must have an id attribute
+        .c('list', { 'xmlns': 'eu.siacs.conversations.axolotl' })
+        .c('device', { 'id': '482886413b977930064a5888b92134fe' });
     _converse.api.connection.get()._dataRecv(createRequest(stanza));
-    iq_stanza = await u.waitUntil(() => ownDeviceHasBeenPublished(_converse))
+
+    iq_stanza = await u.waitUntil(() => ownDeviceHasBeenPublished(_converse));
 
     stanza = $iq({
         'from': _converse.bare_jid,
         'id': iq_stanza.getAttribute('id'),
         'to': _converse.bare_jid,
-        'type': 'result'});
+        'type': 'result',
+    });
     _converse.api.connection.get()._dataRecv(createRequest(stanza));
 
-    iq_stanza = await u.waitUntil(() => bundleHasBeenPublished(_converse))
+    iq_stanza = await u.waitUntil(() => bundleHasBeenPublished(_converse));
 
     stanza = $iq({
         'from': _converse.bare_jid,
         'id': iq_stanza.getAttribute('id'),
         'to': _converse.bare_jid,
-        'type': 'result'});
+        'type': 'result',
+    });
     _converse.api.connection.get()._dataRecv(createRequest(stanza));
     await _converse.api.waitUntil('OMEMOInitialized');
 }

+ 6 - 0
src/types/plugins/omemo/api.d.ts

@@ -19,6 +19,12 @@ declare namespace _default {
             function get(jid: string, create?: boolean): Promise<any>;
         }
         namespace bundle {
+            /**
+             * Lets you generate a new OMEMO device bundle
+             *
+             * @method _converse.api.omemo.bundle.generate
+             * @returns {promise} Promise which resolves once we have a result from the server.
+             */
             function generate(): Promise<any>;
         }
     }