Kaynağa Gözat

Fixes #1193 Properly handle OMEMO messages without `body` tag

JC Brand 6 yıl önce
ebeveyn
işleme
a5a600bade
6 değiştirilmiş dosya ile 37 ekleme ve 14 silme
  1. 1 0
      CHANGES.md
  2. 7 6
      dist/converse.js
  3. 24 4
      spec/omemo.js
  4. 4 3
      src/converse-chatboxes.js
  5. 1 0
      src/converse-core.js
  6. 0 1
      src/converse-omemo.js

+ 1 - 0
CHANGES.md

@@ -11,6 +11,7 @@
 - #1140 Add support for destroyed chatrooms
 - #1169 Non-joined participants display an unwanted status message
 - #1190 MUC Participants column disappears in certain viewport widths
+- #1193 OMEMO messages without a `<body>` fallback are ignored
 - #1199 Can't get back from to login screen from registration screen
 - #1204 Link encoding issue
 - #1214 Setting `allow_contact_requests` to `false` has no effect

+ 7 - 6
dist/converse.js

@@ -60428,7 +60428,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
               // XXX: MUC leakage
               // No need showing delayed or our own CSN messages
               return;
-            } else if (!is_csn && !attrs.file && !attrs.message && !attrs.oob_url && attrs.type !== 'error') {
+            } else if (!is_csn && !attrs.file && !attrs.plaintext && !attrs.message && !attrs.oob_url && attrs.type !== 'error') {
               // TODO: handle <subject> messages (currently being done by ChatRoom)
               return;
             } else {
@@ -60618,13 +60618,14 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
             contact_jid = Strophe.getBareJidFromJid(to_jid);
           } else {
             contact_jid = from_bare_jid;
-          } // Get chat box, but only create a new one when the message has a body.
-
+          }
 
           const attrs = {
-            'fullname': _.get(_converse.api.contacts.get(contact_jid), 'attributes.fullname')
+            'fullname': _.get(_converse.api.contacts.get(contact_jid), 'attributes.fullname') // Get chat box, but only create a new one when the message has a body.
+
           };
-          const chatbox = this.getChatBox(contact_jid, attrs, !_.isNull(stanza.querySelector('body')));
+          const has_body = sizzle(`body, encrypted[xmlns="${Strophe.NS.OMEMO}`).length > 0;
+          const chatbox = this.getChatBox(contact_jid, attrs, has_body);
 
           if (chatbox && !chatbox.handleMessageCorrection(stanza)) {
             const msgid = stanza.getAttribute('id'),
@@ -63170,6 +63171,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
   Strophe.addNamespace('HTTPUPLOAD', 'urn:xmpp:http:upload:0');
   Strophe.addNamespace('MAM', 'urn:xmpp:mam:2');
   Strophe.addNamespace('NICK', 'http://jabber.org/protocol/nick');
+  Strophe.addNamespace('OMEMO', "eu.siacs.conversations.axolotl");
   Strophe.addNamespace('OUTOFBAND', 'jabber:x:oob');
   Strophe.addNamespace('PUBSUB', 'http://jabber.org/protocol/pubsub');
   Strophe.addNamespace('REGISTER', 'jabber:iq:register');
@@ -72526,7 +72528,6 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
         f = _converse$env.f,
         b64_sha1 = _converse$env.b64_sha1;
   const u = converse.env.utils;
-  Strophe.addNamespace('OMEMO', "eu.siacs.conversations.axolotl");
   Strophe.addNamespace('OMEMO_DEVICELIST', Strophe.NS.OMEMO + ".devicelist");
   Strophe.addNamespace('OMEMO_VERIFICATION', Strophe.NS.OMEMO + ".verification");
   Strophe.addNamespace('OMEMO_WHITELISTED', Strophe.NS.OMEMO + ".whitelisted");

+ 24 - 4
spec/omemo.js

@@ -182,8 +182,9 @@
                     `</encrypted>`+
                     `<store xmlns="urn:xmpp:hints"/>`+
                 `</message>`);
+
             // Test reception of an encrypted message
-            const obj = await view.model.encryptMessage('This is an encrypted message from the contact')
+            let obj = await view.model.encryptMessage('This is an encrypted message from the contact')
             // XXX: Normally the key will be encrypted via libsignal.
             // However, we're mocking libsignal in the tests, so we include
             // it as plaintext in the message.
@@ -191,7 +192,7 @@
                     'from': contact_jid,
                     'to': _converse.connection.jid,
                     'type': 'chat',
-                    'id': 'qwerty'
+                    'id': _converse.connection.getUniqueId()
                 }).c('body').t('This is a fallback message').up()
                     .c('encrypted', {'xmlns': Strophe.NS.OMEMO})
                         .c('header', {'sid':  '555'})
@@ -200,11 +201,30 @@
                             .up().up()
                         .c('payload').t(obj.payload);
             _converse.connection._dataRecv(test_utils.createRequest(stanza));
-            await test_utils.waitUntil(() => view.model.messages.length > 1);
+            await new Promise((resolve, reject) => view.once('messageInserted', resolve));
             expect(view.model.messages.length).toBe(2);
-            const last_msg = view.model.messages.at(1);
             expect(view.el.querySelectorAll('.chat-msg__body')[1].textContent.trim())
                 .toBe('This is an encrypted message from the contact');
+
+            // #1193 Check for a received message without <body> tag
+            obj = await view.model.encryptMessage('Another received encrypted message without fallback')
+            stanza = $msg({
+                    'from': contact_jid,
+                    'to': _converse.connection.jid,
+                    'type': 'chat',
+                    'id': _converse.connection.getUniqueId()
+                }).c('encrypted', {'xmlns': Strophe.NS.OMEMO})
+                    .c('header', {'sid':  '555'})
+                        .c('key', {'rid':  _converse.omemo_store.get('device_id')}).t(u.arrayBufferToBase64(obj.key_and_tag)).up()
+                        .c('iv').t(obj.iv)
+                        .up().up()
+                    .c('payload').t(obj.payload);
+            _converse.connection._dataRecv(test_utils.createRequest(stanza));
+            await new Promise((resolve, reject) => view.once('messageInserted', resolve));
+            await test_utils.waitUntil(() => view.model.messages.length > 1);
+            expect(view.model.messages.length).toBe(3);
+            expect(view.el.querySelectorAll('.chat-msg__body')[2].textContent.trim())
+                .toBe('Another received encrypted message without fallback');
             done();
         }));
 

+ 4 - 3
src/converse-chatboxes.js

@@ -540,7 +540,7 @@
                             // XXX: MUC leakage
                             // No need showing delayed or our own CSN messages
                             return;
-                        } else if (!is_csn && !attrs.file && !attrs.message && !attrs.oob_url && attrs.type !== 'error') {
+                        } else if (!is_csn && !attrs.file && !attrs.plaintext && !attrs.message && !attrs.oob_url && attrs.type !== 'error') {
                             // TODO: handle <subject> messages (currently being done by ChatRoom)
                             return;
                         } else {
@@ -721,11 +721,12 @@
                     } else {
                         contact_jid = from_bare_jid;
                     }
-                    // Get chat box, but only create a new one when the message has a body.
                     const attrs = {
                         'fullname': _.get(_converse.api.contacts.get(contact_jid), 'attributes.fullname')
                     }
-                    const chatbox = this.getChatBox(contact_jid, attrs, !_.isNull(stanza.querySelector('body')));
+                    // Get chat box, but only create a new one when the message has a body.
+                    const has_body = sizzle(`body, encrypted[xmlns="${Strophe.NS.OMEMO}`).length > 0;
+                    const chatbox = this.getChatBox(contact_jid, attrs, has_body);
                     if (chatbox && !chatbox.handleMessageCorrection(stanza)) {
                         const msgid = stanza.getAttribute('id'),
                               message = msgid && chatbox.messages.findWhere({msgid});

+ 1 - 0
src/converse-core.js

@@ -37,6 +37,7 @@
     Strophe.addNamespace('HTTPUPLOAD', 'urn:xmpp:http:upload:0');
     Strophe.addNamespace('MAM', 'urn:xmpp:mam:2');
     Strophe.addNamespace('NICK', 'http://jabber.org/protocol/nick');
+    Strophe.addNamespace('OMEMO', "eu.siacs.conversations.axolotl");
     Strophe.addNamespace('OUTOFBAND', 'jabber:x:oob');
     Strophe.addNamespace('PUBSUB', 'http://jabber.org/protocol/pubsub');
     Strophe.addNamespace('REGISTER', 'jabber:iq:register');

+ 0 - 1
src/converse-omemo.js

@@ -16,7 +16,6 @@
     const { Backbone, Promise, Strophe, moment, sizzle, $iq, $msg, _, f, b64_sha1 } = converse.env;
     const u = converse.env.utils;
 
-    Strophe.addNamespace('OMEMO', "eu.siacs.conversations.axolotl");
     Strophe.addNamespace('OMEMO_DEVICELIST', Strophe.NS.OMEMO+".devicelist");
     Strophe.addNamespace('OMEMO_VERIFICATION', Strophe.NS.OMEMO+".verification");
     Strophe.addNamespace('OMEMO_WHITELISTED', Strophe.NS.OMEMO+".whitelisted");