From 857eee5003238444015f6b1c25101a85410d0e2a Mon Sep 17 00:00:00 2001 From: lilia Date: Mon, 23 Feb 2015 16:23:22 -0800 Subject: [PATCH] Divorce identity wipe from tryAgain functions We'd like to live in a world where we can retry all the pending conflicts in a conversation as a batch, which means we don't want to wipe the identity key before processing each message. Thus, remove that step from these handlers and encapsulate in a method on the conversation model. --- js/libtextsecure.js | 11 ++++------- js/models/conversations.js | 29 +++++++++++++++++++++++++++++ js/models/messages.js | 9 +++++++++ libtextsecure/axolotl_wrapper.js | 6 ++---- libtextsecure/sendmessage.js | 5 ++--- 5 files changed, 46 insertions(+), 14 deletions(-) diff --git a/js/libtextsecure.js b/js/libtextsecure.js index 36aa17be..59733965 100644 --- a/js/libtextsecure.js +++ b/js/libtextsecure.js @@ -37819,13 +37819,11 @@ window.axolotl.sessions = { } }; - var wipeIdentityAndTryMessageAgain = function(from, encodedMessage) { - // Wipe identity key! - textsecure.storage.devices.removeIdentityKeyForNumber(from.split('.')[0]); + var tryMessageAgain = function(from, encodedMessage) { //TODO: Probably breaks with a devicecontrol message return textsecure.protocol_wrapper.handlePreKeyWhisperMessage(from, encodedMessage).then(decodeMessageContents); } - textsecure.replay.registerFunction(wipeIdentityAndTryMessageAgain, textsecure.replay.Type.INIT_SESSION); + textsecure.replay.registerFunction(tryMessageAgain, textsecure.replay.Type.INIT_SESSION); })(); /* vim: ts=4:sw=4:expandtab @@ -39445,8 +39443,7 @@ window.textsecure.messaging = function() { } var tryMessageAgain = function(number, encodedMessage, timestamp) { - textsecure.storage.devices.removeIdentityKeyForNumber(number); - var proto = textsecure.protobuf.PushMessageContent.decode(encodedMessage, 'binary'); + var proto = textsecure.protobuf.PushMessageContent.decode(encodedMessage); return new Promise(function(resolve, reject) { sendMessageProto(timestamp, [number], proto, function(res) { if (res.failure.length > 0) @@ -39513,7 +39510,7 @@ window.textsecure.messaging = function() { if (error.message !== "Identity key changed") registerError(number, "Failed to reload device keys", error); else { - error = new textsecure.OutgoingIdentityKeyError(number, getString(message.encode()), timestamp); + error = new textsecure.OutgoingIdentityKeyError(number, message.toArrayBuffer(), timestamp); registerError(number, "Identity key changed", error); } }); diff --git a/js/models/conversations.js b/js/models/conversations.js index 0f8cb3bb..5512955b 100644 --- a/js/models/conversations.js +++ b/js/models/conversations.js @@ -190,6 +190,7 @@ return ''; } }, + isPrivate: function() { return this.get('type') === 'private'; }, @@ -218,7 +219,35 @@ this.updateAvatarUrl(); } return this.avatarUrl || '/images/default.png'; + }, + + resolveConflicts: function() { + if (!this.isPrivate()) { + throw "Can't call resolveConflicts on non-private conversation"; + } + + if (!this.messageCollection.find(function(m) { return m.getKeyConflict(); })) { + throw "No conflicts to resolve"; + } + + textsecure.storage.devices.removeIdentityKeyForNumber(this.get('id')); + this.messageCollection.each(function(message) { + var conflict = message.getKeyConflict(); + if (conflict) { + new textsecure.ReplayableError(conflict).replay(). + then(function(pushMessageContent) { + message.save('errors', []); + if (message.isIncoming()) { + extension.trigger('message:decrypted', { + message_id: message.id, + data: pushMessageContent + }); + } + }); + } + }); } + }); Whisper.ConversationCollection = Backbone.Collection.extend({ diff --git a/js/models/messages.js b/js/models/messages.js index 4e320fe9..2b13e2ec 100644 --- a/js/models/messages.js +++ b/js/models/messages.js @@ -47,6 +47,15 @@ if (this.collection) { return this.collection.conversation.contactCollection.get(this.get('source')); } + }, + isOutgoing: function() { + return this.get('type') === 'outgoing'; + }, + getKeyConflict: function() { + return _.find(this.get('errors'), function(e) { + return ( e.name === 'IncomingIdentityKeyError' || + e.name === 'OutgoingIdentityKeyError'); + }); } }); diff --git a/libtextsecure/axolotl_wrapper.js b/libtextsecure/axolotl_wrapper.js index 888b265b..571b95eb 100644 --- a/libtextsecure/axolotl_wrapper.js +++ b/libtextsecure/axolotl_wrapper.js @@ -119,11 +119,9 @@ } }; - var wipeIdentityAndTryMessageAgain = function(from, encodedMessage) { - // Wipe identity key! - textsecure.storage.devices.removeIdentityKeyForNumber(from.split('.')[0]); + var tryMessageAgain = function(from, encodedMessage) { //TODO: Probably breaks with a devicecontrol message return textsecure.protocol_wrapper.handlePreKeyWhisperMessage(from, encodedMessage).then(decodeMessageContents); } - textsecure.replay.registerFunction(wipeIdentityAndTryMessageAgain, textsecure.replay.Type.INIT_SESSION); + textsecure.replay.registerFunction(tryMessageAgain, textsecure.replay.Type.INIT_SESSION); })(); diff --git a/libtextsecure/sendmessage.js b/libtextsecure/sendmessage.js index beac7f80..98dd9256 100644 --- a/libtextsecure/sendmessage.js +++ b/libtextsecure/sendmessage.js @@ -128,8 +128,7 @@ window.textsecure.messaging = function() { } var tryMessageAgain = function(number, encodedMessage, timestamp) { - textsecure.storage.devices.removeIdentityKeyForNumber(number); - var proto = textsecure.protobuf.PushMessageContent.decode(encodedMessage, 'binary'); + var proto = textsecure.protobuf.PushMessageContent.decode(encodedMessage); return new Promise(function(resolve, reject) { sendMessageProto(timestamp, [number], proto, function(res) { if (res.failure.length > 0) @@ -196,7 +195,7 @@ window.textsecure.messaging = function() { if (error.message !== "Identity key changed") registerError(number, "Failed to reload device keys", error); else { - error = new textsecure.OutgoingIdentityKeyError(number, getString(message.encode()), timestamp); + error = new textsecure.OutgoingIdentityKeyError(number, message.toArrayBuffer(), timestamp); registerError(number, "Identity key changed", error); } });