From 7caecc564d3f3028cbf9d3ab4c13f3fc3a59e1d0 Mon Sep 17 00:00:00 2001 From: lilia Date: Thu, 26 May 2016 17:21:50 -0700 Subject: [PATCH] Process all incoming conflicts before outgoing ones Fixes a session management problem where, after resolving a conflict with some contact, that contact would get bad mac as a result of us sending them a new prekey message before processing a pending conflicted prekey message received from them earlier. Fixes #806 // FREEBIE --- js/models/conversations.js | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/js/models/conversations.js b/js/models/conversations.js index 31d6c305..b6b8dcc2 100644 --- a/js/models/conversations.js +++ b/js/models/conversations.js @@ -405,13 +405,20 @@ return textsecure.storage.protocol.removeIdentityKey(number).then(function() { return textsecure.storage.protocol.saveIdentity(number, identityKey).then(function() { var promise = Promise.resolve(); - this.messageCollection.each(function(message) { - if (message.hasKeyConflict(number)) { - var resolveConflict = function() { - return message.resolveConflict(number); - }; - promise = promise.then(resolveConflict, resolveConflict); - } + var conflicts = this.messageCollection.filter(function(message) { + return message.hasKeyConflict(number); + }); + // group incoming & outgoing + conflicts = _.groupBy(conflicts, function(m) { return m.get('type'); }); + // sort each group by date and concatenate outgoing after incoming + conflicts = _.flatten([ + _.sortBy(conflicts.incoming, function(m) { return m.get('received_at'); }), + _.sortBy(conflicts.outgoing, function(m) { return m.get('received_at'); }), + ]).forEach(function(message) { + var resolveConflict = function() { + return message.resolveConflict(number); + }; + promise = promise.then(resolveConflict, resolveConflict); }); return promise; }.bind(this));