Pārlūkot izejas kodu

Don't re-initialize OMEMO on reconnection

Promises only get recreated upon logout, not reconnection.

However OMEMO was getting re-initialized on reconnection and
`_converse.omemo_store` was also deleted.

This caused a race condition where an incoming MAM message would cause
`parseEncryptedMessage` that then throws an AttributeError because
`_converse.omemo_store` is undefined because OMEMO isn't yet
initialized.

Waiting for the `OMEMOInitialized` promise doesn't help because it's
still the old (already resolved) promise from before the reconnection.
JC Brand 3 gadi atpakaļ
vecāks
revīzija
0f648ed1eb

+ 1 - 0
CHANGES.md

@@ -5,6 +5,7 @@
 - Updated translations: lt
 - Increased stanza timeout from 10 to 20 seconds
 - Replace various font icons with SVG icons
+- Fix OMEMO race condition related to automatic reconnection
 - #1761: Add a new dark theme based on the [Dracula](https://draculatheme.com/) theme
 - #2751: Media not rendered when Converse runs in a browser extension
 - #2786: Fix webpack configuration not working on Windows OS

+ 1 - 1
src/headless/plugins/chat/parsers.js

@@ -215,7 +215,7 @@ export async function parseMessage (stanza, _converse) {
      */
     attrs = await api.hook('parseMessage', stanza, attrs);
 
-    // We call this after the hook, to allow plugins to decrypt encrypted
+    // We call this after the hook, to allow plugins (like omemo) to decrypt encrypted
     // messages, since we need to parse the message text to determine whether
     // there are media urls.
     return Object.assign(attrs, getMediaURLsMetadata(attrs.is_encrypted ? attrs.plaintext : attrs.body));

+ 1 - 2
src/plugins/omemo/index.js

@@ -99,9 +99,8 @@ converse.plugins.add('converse-omemo', {
             _converse.generateFingerprints(_converse.bare_jid).catch(e => log.error(e));
         });
 
-        api.listen.on('afterTearDown', () => delete _converse.omemo_store);
-
         api.listen.on('clearSession', () => {
+            delete _converse.omemo_store
             if (_converse.shouldClearCache() && _converse.devicelists) {
                 _converse.devicelists.clearStore();
                 delete _converse.devicelists;

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

@@ -609,7 +609,10 @@ async function fetchDeviceLists () {
     return Promise.all(promises);
 }
 
-export async function initOMEMO () {
+export async function initOMEMO (reconnecting) {
+    if (reconnecting) {
+        return;
+    }
     if (!_converse.config.get('trusted') || api.settings.get('clear_cache_on_logout')) {
         log.warn('Not initializing OMEMO, since this browser is not trusted or clear_cache_on_logout is set to true');
         return;