From a52d35bb1bda7f93ec25446cfbd5cbe1c44d925f Mon Sep 17 00:00:00 2001 From: lilia Date: Tue, 3 Nov 2015 16:13:19 -0800 Subject: [PATCH] Refactor and fixup key requests Fix a bad loop scope bug in getKeysForNumber by using forEach. Refactor the initial process of establishing key material for devices that do not have open sessions. // FREEBIE --- js/libtextsecure.js | 64 +++++++++++++------------------ libtextsecure/outgoing_message.js | 37 ++++-------------- libtextsecure/storage/devices.js | 27 ++++++++----- 3 files changed, 52 insertions(+), 76 deletions(-) diff --git a/js/libtextsecure.js b/js/libtextsecure.js index 492ed169..36a64012 100644 --- a/js/libtextsecure.js +++ b/js/libtextsecure.js @@ -38140,16 +38140,25 @@ axolotlInternal.RecipientRecord = function() { delete tempKeys[encodedNumber]; return Promise.resolve(); }, - needKeysForDevice: function(encodedNumber) { - if (tempKeys[encodedNumber] !== undefined) { - return Promise.resolve(false); - } else { - return textsecure.protocol_wrapper.hasOpenSession(encodedNumber).then(function(result) { - return !result; - }); - } - }, + getStaleDeviceIdsForNumber: function(number) { + return textsecure.storage.axolotl.getDeviceIds(number).then(function(deviceIds) { + if (deviceIds.length === 0) { + return [1]; + } + var updateDevices = []; + return Promise.all(deviceIds.map(function(deviceId) { + var encodedNumber = number + '.' + deviceId; + return textsecure.protocol_wrapper.hasOpenSession(encodedNumber).then(function(hasSession) { + if (!hasSession && !tempKeys[encodedNumber]) { + updateDevices.push(deviceId); + } + }); + })).then(function() { + return updateDevices; + }); + }); + }, getDeviceObjectsForNumber: function(number) { return textsecure.storage.axolotl.getIdentityKey(number).then(function(identityKey) { if (identityKey === undefined) { @@ -39767,11 +39776,11 @@ OutgoingMessage.prototype = { return this.server.getKeysForNumber(number).then(handleResult); } else { var promise = Promise.resolve(); - for (var i in updateDevices) { + updateDevices.forEach(function(device) { promise = promise.then(function() { - return this.server.getKeysForNumber(number, updateDevices[i]).then(handleResult); + return this.server.getKeysForNumber(number, device).then(handleResult); }.bind(this)); - } + }.bind(this)); return promise; } @@ -39812,33 +39821,12 @@ OutgoingMessage.prototype = { }, sendToNumber: function(number) { - return textsecure.storage.devices.getDeviceObjectsForNumber(number).then(function(devicesForNumber) { - return Promise.all(devicesForNumber.map(function(device) { - return textsecure.storage.devices.needKeysForDevice(device.encodedNumber).then(function(result) { - if (result) { - return this.getKeysForNumber(number, - [parseInt(textsecure.utils.unencodeNumber(device.encodedNumber)[1])] - ).catch(function(error) { - if (error.name !== 'OutgoingIdentityKeyError') { - this.registerError(number, "Failed to retreive new device keys for " + device.encodedNumber, error); - } - return Promise.reject(); - }.bind(this)); - } + return textsecure.storage.devices.getStaleDeviceIdsForNumber(number).then(function(updateDevices) { + return this.getKeysForNumber(number, updateDevices) + .then(this.reloadDevicesAndSend(number, true)) + .catch(function(error) { + this.registerError(number, "Failed to retreive new device keys for number " + number, error); }.bind(this)); - }.bind(this))).then(function() { - return textsecure.storage.devices.getDeviceObjectsForNumber(number).then(function(devicesForNumber) { - if (devicesForNumber.length == 0) { - return this.getKeysForNumber(number, [1]) - .then(this.reloadDevicesAndSend(number, true)) - .catch(function(error) { - this.registerError(number, "Failed to retreive new device keys for number " + number, error); - }.bind(this)); - } else { - return this.doSendMessage(number, devicesForNumber, true); - } - }.bind(this)); - }.bind(this)); }.bind(this)); }, diff --git a/libtextsecure/outgoing_message.js b/libtextsecure/outgoing_message.js index d501409f..aa124a09 100644 --- a/libtextsecure/outgoing_message.js +++ b/libtextsecure/outgoing_message.js @@ -69,11 +69,11 @@ OutgoingMessage.prototype = { return this.server.getKeysForNumber(number).then(handleResult); } else { var promise = Promise.resolve(); - for (var i in updateDevices) { + updateDevices.forEach(function(device) { promise = promise.then(function() { - return this.server.getKeysForNumber(number, updateDevices[i]).then(handleResult); + return this.server.getKeysForNumber(number, device).then(handleResult); }.bind(this)); - } + }.bind(this)); return promise; } @@ -114,33 +114,12 @@ OutgoingMessage.prototype = { }, sendToNumber: function(number) { - return textsecure.storage.devices.getDeviceObjectsForNumber(number).then(function(devicesForNumber) { - return Promise.all(devicesForNumber.map(function(device) { - return textsecure.storage.devices.needKeysForDevice(device.encodedNumber).then(function(result) { - if (result) { - return this.getKeysForNumber(number, - [parseInt(textsecure.utils.unencodeNumber(device.encodedNumber)[1])] - ).catch(function(error) { - if (error.name !== 'OutgoingIdentityKeyError') { - this.registerError(number, "Failed to retreive new device keys for " + device.encodedNumber, error); - } - return Promise.reject(); - }.bind(this)); - } + return textsecure.storage.devices.getStaleDeviceIdsForNumber(number).then(function(updateDevices) { + return this.getKeysForNumber(number, updateDevices) + .then(this.reloadDevicesAndSend(number, true)) + .catch(function(error) { + this.registerError(number, "Failed to retreive new device keys for number " + number, error); }.bind(this)); - }.bind(this))).then(function() { - return textsecure.storage.devices.getDeviceObjectsForNumber(number).then(function(devicesForNumber) { - if (devicesForNumber.length == 0) { - return this.getKeysForNumber(number, [1]) - .then(this.reloadDevicesAndSend(number, true)) - .catch(function(error) { - this.registerError(number, "Failed to retreive new device keys for number " + number, error); - }.bind(this)); - } else { - return this.doSendMessage(number, devicesForNumber, true); - } - }.bind(this)); - }.bind(this)); }.bind(this)); }, diff --git a/libtextsecure/storage/devices.js b/libtextsecure/storage/devices.js index 4ba78299..3f7b6a93 100644 --- a/libtextsecure/storage/devices.js +++ b/libtextsecure/storage/devices.js @@ -40,16 +40,25 @@ delete tempKeys[encodedNumber]; return Promise.resolve(); }, - needKeysForDevice: function(encodedNumber) { - if (tempKeys[encodedNumber] !== undefined) { - return Promise.resolve(false); - } else { - return textsecure.protocol_wrapper.hasOpenSession(encodedNumber).then(function(result) { - return !result; - }); - } - }, + getStaleDeviceIdsForNumber: function(number) { + return textsecure.storage.axolotl.getDeviceIds(number).then(function(deviceIds) { + if (deviceIds.length === 0) { + return [1]; + } + var updateDevices = []; + return Promise.all(deviceIds.map(function(deviceId) { + var encodedNumber = number + '.' + deviceId; + return textsecure.protocol_wrapper.hasOpenSession(encodedNumber).then(function(hasSession) { + if (!hasSession && !tempKeys[encodedNumber]) { + updateDevices.push(deviceId); + } + }); + })).then(function() { + return updateDevices; + }); + }); + }, getDeviceObjectsForNumber: function(number) { return textsecure.storage.axolotl.getIdentityKey(number).then(function(identityKey) { if (identityKey === undefined) {