Selaa lähdekoodia

Move OMEMO-related message parsing to utils/stanza.js

JC Brand 5 vuotta sitten
vanhempi
commit
a1d5563963

+ 0 - 1
spec/omemo.js

@@ -381,7 +381,6 @@
                 async function (done, _converse) {
 
             await test_utils.waitUntilDiscoConfirmed(_converse, _converse.bare_jid, [], [Strophe.NS.SID]);
-
             await test_utils.waitForRoster(_converse, 'current', 1);
             const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
             await u.waitUntil(() => initializedOMEMO(_converse));

+ 0 - 31
src/converse-omemo.js

@@ -169,18 +169,6 @@ converse.plugins.add('converse-omemo', {
         },
 
         ChatBox: {
-            async parseMessage (stanza, original_stanza) {
-                const { _converse } = this.__super__;
-                const encrypted = sizzle(`encrypted[xmlns="${Strophe.NS.OMEMO}"]`, original_stanza).pop(),
-                      attrs = await this.__super__.parseMessage.apply(this, arguments);
-
-                if (!encrypted || !_converse.config.get('trusted')) {
-                    return attrs;
-                } else {
-                    return this.getEncryptionAttributesfromStanza(stanza, original_stanza, attrs);
-                }
-            },
-
             async sendMessage (text, spoiler_hint) {
                 if (this.get('omemo_active') && text) {
                     const { _converse } = this.__super__;
@@ -368,25 +356,6 @@ converse.plugins.add('converse-omemo', {
                 }
             },
 
-            getEncryptionAttributesfromStanza (stanza, original_stanza, attrs) {
-                const encrypted = sizzle(`encrypted[xmlns="${Strophe.NS.OMEMO}"]`, original_stanza).pop(),
-                      header = encrypted.querySelector('header'),
-                      key = sizzle(`key[rid="${_converse.omemo_store.get('device_id')}"]`, encrypted).pop();
-                if (key) {
-                    attrs['is_encrypted'] = true;
-                    attrs['encrypted'] = {
-                        'device_id': header.getAttribute('sid'),
-                        'iv': header.querySelector('iv').textContent,
-                        'key': key.textContent,
-                        'payload': encrypted.querySelector('payload')?.textContent || null,
-                        'prekey': ['true', '1'].includes(key.getAttribute('prekey'))
-                    }
-                    return this.decrypt(attrs);
-                } else {
-                    return Promise.resolve(attrs);
-                }
-            },
-
             getSessionCipher (jid, id) {
                 const address = new libsignal.SignalProtocolAddress(jid, id);
                 this.session_cipher = new window.libsignal.SessionCipher(_converse.omemo_store, address);

+ 2 - 18
src/headless/converse-chat.js

@@ -411,7 +411,7 @@ converse.plugins.add('converse-chat', {
             },
 
             async onMessage (stanza, original_stanza, from_jid) {
-                const attrs = await this.parseMessage(stanza, original_stanza);
+                const attrs = await st.parseMessage(stanza, original_stanza, this, _converse);
                 const message = this.getDuplicateMessage(attrs);
                 if (message) {
                     this.updateMessage(message, original_stanza);
@@ -1081,22 +1081,6 @@ converse.plugins.add('converse-chat', {
                 });
             },
 
-            /**
-             * Parses a passed in message stanza and returns an object of attributes.
-             * @private
-             * @method _converse.ChatBox#parseMessage
-             * @param { XMLElement } stanza - The message stanza
-             * @param { XMLElement } original_stanza - The original stanza, that contains the
-             *  message stanza, if it was contained, otherwise it's the message stanza itself.
-             * @returns { Object }
-             */
-            parseMessage (stanza, original_stanza) {
-                // XXX: Eventually we want to get rid of this pass-through
-                // method but currently we still need it because converse-omemo
-                // overrides it.
-                return st.parseMessage(stanza, original_stanza, this, _converse);
-            },
-
             maybeShow () {
                 return this.trigger("show");
             },
@@ -1169,7 +1153,7 @@ converse.plugins.add('converse-chat', {
             if (!should_show) {
                 return;
             }
-            const attrs = await chatbox.parseMessage(stanza, stanza);
+            const attrs = await st.parseMessage(stanza, stanza, chatbox, _converse);
             await chatbox.createMessage(attrs);
         }
 

+ 8 - 7
src/headless/converse-headlines.js

@@ -3,8 +3,9 @@
  * @copyright 2020, the Converse.js contributors
  * @description XEP-0045 Multi-User Chat Views
  */
-import converse from "@converse/headless/converse-core";
 import { isString } from "lodash";
+import converse from "@converse/headless/converse-core";
+import st from "./utils/stanza";
 
 const u = converse.env.utils;
 
@@ -80,16 +81,16 @@ converse.plugins.add('converse-headlines', {
             }
         });
 
-        async function onHeadlineMessage (message) {
+        async function onHeadlineMessage (stanza) {
             // Handler method for all incoming messages of type "headline".
-            if (u.isHeadlineMessage(_converse, message)) {
-                const from_jid = message.getAttribute('from');
+            if (u.isHeadlineMessage(_converse, stanza)) {
+                const from_jid = stanza.getAttribute('from');
                 if (from_jid.includes('@') &&
                         !_converse.roster.get(from_jid) &&
                         !api.settings.get("allow_non_roster_messaging")) {
                     return;
                 }
-                if (message.querySelector('body') === null) {
+                if (stanza.querySelector('body') === null) {
                     // Avoid creating a chat box if we have nothing to show inside it.
                     return;
                 }
@@ -99,9 +100,9 @@ converse.plugins.add('converse-headlines', {
                     'type': _converse.HEADLINES_TYPE,
                     'from': from_jid
                 });
-                const attrs = await chatbox.parseMessage(message, message);
+                const attrs = await st.parseMessage(stanza, stanza, chatbox, _converse);
                 await chatbox.createMessage(attrs);
-                api.trigger('message', {'chatbox': chatbox, 'stanza': message});
+                api.trigger('message', {'chatbox': chatbox, 'stanza': stanza});
             }
         }
 

+ 1 - 1
src/headless/converse-muc.js

@@ -2026,7 +2026,7 @@ converse.plugins.add('converse-muc', {
                 await this.createInfoMessages(stanza);
                 this.fetchFeaturesIfConfigurationChanged(stanza);
 
-                const attrs = await this.parseMessage(stanza, original_stanza);
+                const attrs = await st.parseMessage(stanza, original_stanza, this, _converse);
                 const message = this.getDuplicateMessage(attrs);
                 if (message) {
                     this.updateMessage(message, original_stanza);

+ 97 - 72
src/headless/utils/stanza.js

@@ -7,6 +7,97 @@ import u from '@converse/headless/utils/core';
 
 const Strophe = strophe.default.Strophe;
 
+
+function getSenderAttributes (stanza, chatbox, _converse) {
+    if (u.isChatRoom(chatbox)) {
+        const from = stanza.getAttribute('from');
+        const nick = Strophe.unescapeNode(Strophe.getResourceFromJid(from));
+        return {
+            'from':  from,
+            'from_muc': Strophe.getBareJidFromJid(from),
+            'nick': nick,
+            'sender': nick === chatbox.get('nick') ? 'me': 'them',
+            'received': (new Date()).toISOString(),
+        }
+    } else {
+        const from = Strophe.getBareJidFromJid(stanza.getAttribute('from'));
+        if (from === _converse.bare_jid) {
+            return {
+                from,
+                'sender': 'me',
+                'fullname': _converse.xmppstatus.get('fullname')
+            }
+        } else {
+            return {
+                from,
+                'sender': 'them',
+                'fullname': chatbox.get('fullname')
+            }
+        }
+    }
+}
+
+function getSpoilerAttributes (stanza) {
+    const spoiler = sizzle(`spoiler[xmlns="${Strophe.NS.SPOILER}"]`, stanza).pop();
+    return {
+        'is_spoiler': !!spoiler,
+        'spoiler_hint': spoiler?.textContent
+    }
+}
+
+function getOutOfBandAttributes (stanza) {
+    const xform = sizzle(`x[xmlns="${Strophe.NS.OUTOFBAND}"]`, stanza).pop();
+    if (xform) {
+        return {
+            'oob_url': xform.querySelector('url')?.textContent,
+            'oob_desc': xform.querySelector('desc')?.textContent
+        }
+    }
+    return {};
+}
+
+function getCorrectionAttributes (stanza, original_stanza) {
+    const el = sizzle(`replace[xmlns="${Strophe.NS.MESSAGE_CORRECT}"]`, stanza).pop();
+    if (el) {
+        const replaced_id = el.getAttribute('id');
+        const msgid = replaced_id;
+        if (replaced_id) {
+            const delay = sizzle(`delay[xmlns="${Strophe.NS.DELAY}"]`, original_stanza).pop();
+            const time = delay ? dayjs(delay.getAttribute('stamp')).toISOString() : (new Date()).toISOString();
+            return {
+                msgid,
+                replaced_id,
+                'edited': time
+            }
+        }
+    }
+    return {};
+}
+
+function getEncryptionAttributes (stanza, original_stanza, attrs, chatbox, _converse) {
+    const encrypted = sizzle(`encrypted[xmlns="${Strophe.NS.OMEMO}"]`, original_stanza).pop();
+    if (!encrypted || !_converse.config.get('trusted')) {
+        return attrs;
+    }
+    const key = sizzle(`key[rid="${_converse.omemo_store.get('device_id')}"]`, encrypted).pop();
+    if (key) {
+        const header = encrypted.querySelector('header');
+        attrs['is_encrypted'] = true;
+        attrs['encrypted'] = {
+            'device_id': header.getAttribute('sid'),
+            'iv': header.querySelector('iv').textContent,
+            'key': key.textContent,
+            'payload': encrypted.querySelector('payload')?.textContent || null,
+            'prekey': ['true', '1'].includes(key.getAttribute('prekey'))
+        }
+        // Returns a promise
+        return chatbox.decrypt(attrs);
+    } else {
+        return attrs;
+    }
+}
+
+
 /**
  * The stanza utils object. Contains utility functions related to stanza
  * processing.
@@ -168,73 +259,6 @@ const stanza_utils = {
         });
     },
 
-
-    getSenderAttributes (stanza, chatbox, _converse) {
-        if (u.isChatRoom(chatbox)) {
-            const from = stanza.getAttribute('from');
-            const nick = Strophe.unescapeNode(Strophe.getResourceFromJid(from));
-            return {
-                'from':  from,
-                'from_muc': Strophe.getBareJidFromJid(from),
-                'nick': nick,
-                'sender': nick === chatbox.get('nick') ? 'me': 'them',
-                'received': (new Date()).toISOString(),
-            }
-        } else {
-            const from = Strophe.getBareJidFromJid(stanza.getAttribute('from'));
-            if (from === _converse.bare_jid) {
-                return {
-                    from,
-                    'sender': 'me',
-                    'fullname': _converse.xmppstatus.get('fullname')
-                }
-            } else {
-                return {
-                    from,
-                    'sender': 'them',
-                    'fullname': chatbox.get('fullname')
-                }
-            }
-        }
-    },
-
-    getSpoilerAttributes (stanza) {
-        const spoiler = sizzle(`spoiler[xmlns="${Strophe.NS.SPOILER}"]`, stanza).pop();
-        return {
-            'is_spoiler': !!spoiler,
-            'spoiler_hint': spoiler?.textContent
-        }
-    },
-
-    getOutOfBandAttributes (stanza) {
-        const xform = sizzle(`x[xmlns="${Strophe.NS.OUTOFBAND}"]`, stanza).pop();
-        if (xform) {
-            return {
-                'oob_url': xform.querySelector('url')?.textContent,
-                'oob_desc': xform.querySelector('desc')?.textContent
-            }
-        }
-        return {};
-    },
-
-    getCorrectionAttributes (stanza, original_stanza) {
-        const el = sizzle(`replace[xmlns="${Strophe.NS.MESSAGE_CORRECT}"]`, stanza).pop();
-        if (el) {
-            const replaced_id = el.getAttribute('id');
-            const msgid = replaced_id;
-            if (replaced_id) {
-                const delay = sizzle(`delay[xmlns="${Strophe.NS.DELAY}"]`, original_stanza).pop();
-                const time = delay ? dayjs(delay.getAttribute('stamp')).toISOString() : (new Date()).toISOString();
-                return {
-                    msgid,
-                    replaced_id,
-                    'edited': time
-                }
-            }
-        }
-        return {};
-    },
-
     getErrorMessage (stanza, is_muc, _converse) {
         const { __ } = _converse;
         if (is_muc) {
@@ -292,7 +316,7 @@ const stanza_utils = {
      * @param { _converse } _converse
      * @returns { Object }
      */
-    parseMessage (stanza, original_stanza, chatbox, _converse) {
+    async parseMessage (stanza, original_stanza, chatbox, _converse) {
         const is_muc = u.isChatRoom(chatbox);
         let attrs = Object.assign(
             stanza_utils.getStanzaIDs(stanza, original_stanza),
@@ -316,11 +340,12 @@ const stanza_utils = {
                 'type': stanza.getAttribute('type')
             },
             attrs,
-            stanza_utils.getSenderAttributes(stanza, chatbox, _converse),
-            stanza_utils.getOutOfBandAttributes(stanza),
-            stanza_utils.getSpoilerAttributes(stanza),
-            stanza_utils.getCorrectionAttributes(stanza, original_stanza)
+            getSenderAttributes(stanza, chatbox, _converse),
+            getOutOfBandAttributes(stanza),
+            getSpoilerAttributes(stanza),
+            getCorrectionAttributes(stanza, original_stanza),
         )
+       attrs = await getEncryptionAttributes(stanza, original_stanza, attrs, chatbox, _converse)
         // We prefer to use one of the XEP-0359 unique and stable stanza IDs
         // as the Model id, to avoid duplicates.
         attrs['id'] = attrs['origin_id'] || attrs[`stanza_id ${(attrs.from_muc || attrs.from)}`] || u.getUniqueId();