소스 검색

Fixes #1481

For OMEMO in MUC, use the real JID of the user, not the MUC JID
JC Brand 4 년 전
부모
커밋
a0ae8135ce
4개의 변경된 파일29개의 추가작업 그리고 5개의 파일을 삭제
  1. 2 1
      CHANGES.md
  2. 11 1
      src/converse-omemo.js
  3. 10 1
      src/headless/converse-muc.js
  4. 6 2
      src/headless/utils/stanza.js

+ 2 - 1
CHANGES.md

@@ -6,14 +6,15 @@
 configuration settings should now be accessed via `_converse.api.settings.get` and not directly on the `_converse` object.
 Soon we'll deprecate the latter, so prepare now.
 
-- #515 Add support for XEP-0050 Ad-Hoc commands
 - #1313: Stylistic improvements to the send button
+- #1481: MUC OMEMO: Error No record for device
 - #1490: Busy-loop when fetching registration form fails
 - #1535: Add option to destroy a MUC
 - #1715: Update chat state notification after receiving a message correction.
 - #1793: Send button doesn't appear in Firefox in 1:1 chats
 - #1820: Set focus on jid field after controlbox is loaded
 - #1822: Don't log error if user has no bookmarks
+- #515 Add support for XEP-0050 Ad-Hoc commands
 - #1823: New config options [muc_roomid_policy](https://conversejs.org/docs/html/configuration.html#muc-roomid-policy)
     and [muc_roomid_policy_hint](https://conversejs.org/docs/html/configuration.html#muc-roomid-policy-hint)
 - #1826: A user can now add himself as a contact

+ 11 - 1
src/converse-omemo.js

@@ -172,7 +172,17 @@ async function decryptPrekeyWhisperMessage (attrs) {
 }
 
 async function decryptWhisperMessage (attrs) {
-    const session_cipher = getSessionCipher(attrs.from, parseInt(attrs.encrypted.device_id, 10));
+    const from_jid = attrs.from_muc ? attrs.from_real_jid : attrs.from;
+    if (!from_jid) {
+        Object.assign(attrs, {
+            'error_text': __("Sorry, could not decrypt a received OMEMO because we don't have the JID for that user."),
+            'error_type': 'Decryption',
+            'is_ephemeral': false,
+            'is_error': true,
+            'type': 'error',
+        });
+    }
+    const session_cipher = getSessionCipher(from_jid, parseInt(attrs.encrypted.device_id, 10));
     const key = u.base64ToArrayBuffer(attrs.encrypted.key);
     try {
         const key_and_tag = await session_cipher.decryptWhisperMessage(key, 'binary')

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

@@ -2069,6 +2069,10 @@ converse.plugins.add('converse-muc', {
                 }
             },
 
+            /**
+             * Handle a presence stanza that disconnects the user from the MUC
+             * @param { XMLElement } stanza
+             */
             handleDisconnection (stanza) {
                 const is_self = stanza.querySelector("status[code='110']") !== null;
                 const x = sizzle(`x[xmlns="${Strophe.NS.MUC_USER}"]`, stanza).pop();
@@ -2600,6 +2604,11 @@ converse.plugins.add('converse-muc', {
                 api.trigger('membersFetched');
             },
 
+            /**
+             * @typedef { Object} OccupantData
+             * @property { String } [jid]
+             * @property { String } [nick]
+             */
             /**
              * Try to find an existing occupant based on the passed in
              * data object.
@@ -2609,7 +2618,7 @@ converse.plugins.add('converse-muc', {
              * but should have at least one or the other.
              * @private
              * @method _converse.ChatRoomOccupants#findOccupant
-             * @param { Object } data
+             * @param { OccupantData } data
              */
             findOccupant (data) {
                 const jid = Strophe.getBareJidFromJid(data.jid);

+ 6 - 2
src/headless/utils/stanza.js

@@ -567,6 +567,7 @@ const st = {
         }
         const delay = sizzle(`delay[xmlns="${Strophe.NS.DELAY}"]`, original_stanza).pop();
         const from = stanza.getAttribute('from');
+        const nick = Strophe.unescapeNode(Strophe.getResourceFromJid(from));
         const marker = st.getChatMarker(stanza);
         const now =  (new Date()).toISOString();
         /**
@@ -594,8 +595,9 @@ const st = {
          * @property { String } error_condition - The defined error condition
          * @property { String } error_text - The error text received from the server
          * @property { String } error_type - The type of error received from the server
-         * @property { String } from - The sender JID
+         * @property { String } from - The sender JID (${muc_jid}/${nick})
          * @property { String } from_muc - The JID of the MUC from which this message was sent
+         * @property { String } from_real_jid - The real JID of the sender, if available
          * @property { String } fullname - The full name of the sender
          * @property { String } marker - The XEP-0333 Chat Marker value
          * @property { String } marker_id - The `id` attribute of a XEP-0333 chat marker
@@ -623,9 +625,11 @@ const st = {
          */
         let attrs = Object.assign({
                 from,
+                nick,
                 'body': stanza.querySelector('body')?.textContent?.trim(),
                 'chat_state': getChatState(stanza),
                 'from_muc': Strophe.getBareJidFromJid(from),
+                'from_real_jid': chatbox.occupants.findOccupant({nick})?.get('jid'),
                 'is_archived': st.isArchived(original_stanza),
                 'is_carbon': isCarbon(original_stanza),
                 'is_delayed': !!delay,
@@ -634,7 +638,6 @@ const st = {
                 'is_marker': !!marker,
                 'marker_id': marker && marker.getAttribute('id'),
                 'msgid': stanza.getAttribute('id') || original_stanza.getAttribute('id'),
-                'nick': Strophe.unescapeNode(Strophe.getResourceFromJid(from)),
                 'receipt_id': getReceiptId(stanza),
                 'received': (new Date()).toISOString(),
                 'references': getReferences(stanza),
@@ -654,6 +657,7 @@ const st = {
             getEncryptionAttributes(stanza, _converse)
         );
 
+
         await api.emojis.initialize();
         attrs = Object.assign({
             'is_only_emojis': attrs.body ? u.isOnlyEmojis(attrs.body) : false,