From 20451cc8278445c91bfc6a38e4bff1d4d8df7a73 Mon Sep 17 00:00:00 2001 From: Scott Nonnenberg Date: Mon, 3 Jul 2017 17:31:57 -0700 Subject: [PATCH] Show verified/keychange notifications when actually relevant FREEBIE --- js/background.js | 10 ++++++++-- js/libtextsecure.js | 8 ++++++-- js/models/conversations.js | 31 ++++++++++++++++++++++++++----- js/signal_protocol_store.js | 7 +++++-- libtextsecure/message_receiver.js | 8 ++++++-- test/storage_test.js | 2 +- 6 files changed, 52 insertions(+), 14 deletions(-) diff --git a/js/background.js b/js/background.js index 3373862b3..dea45238a 100644 --- a/js/background.js +++ b/js/background.js @@ -315,10 +315,16 @@ return; } + var options = { + viaSyncMessage: true, + viaContactSync: ev.viaContactSync, + key: key + }; + if (state === 'DEFAULT') { - contact.setVerifiedDefault({viaSyncMessage: true, key: key}); + contact.setVerifiedDefault(options); } else if (state === 'VERIFIED') { - contact.setVerified({viaSyncMessage: true, key: key}); + contact.setVerified(options); } } diff --git a/js/libtextsecure.js b/js/libtextsecure.js index 7337d7e65..243afaf37 100644 --- a/js/libtextsecure.js +++ b/js/libtextsecure.js @@ -38493,13 +38493,17 @@ MessageReceiver.prototype.extend({ throw new Error('Got empty SyncMessage'); } }, - handleVerified: function(verified) { + handleVerified: function(verified, options) { + options = options || {}; + _.defaults(options, {viaContactSync: false}); + var ev = new Event('verified'); ev.verified = { state: verified.state, destination: verified.destination, identityKey: verified.identityKey.toArrayBuffer() }; + ev.viaContactSync = options.viaContactSync; this.dispatchEvent(ev); }, handleRead: function(read, timestamp) { @@ -38526,7 +38530,7 @@ MessageReceiver.prototype.extend({ eventTarget.dispatchEvent(ev); if (contactDetails.verified) { - this.handleVerified(contactDetails.verified); + this.handleVerified(contactDetails.verified, {viaContactSync: true}); } contactDetails = contactBuffer.next(); diff --git a/js/models/conversations.js b/js/models/conversations.js index 9a6bceff2..c196821f1 100644 --- a/js/models/conversations.js +++ b/js/models/conversations.js @@ -82,23 +82,29 @@ }, setVerifiedDefault: function(options) { var DEFAULT = this.verifiedEnum.DEFAULT; - return this._setVerified(DEFAULT, options); + return this.queueJob(function() { + return this._setVerified(DEFAULT, options); + }.bind(this)); }, setVerified: function(options) { var VERIFIED = this.verifiedEnum.VERIFIED; - return this._setVerified(VERIFIED, options); + return this.queueJob(function() { + return this._setVerified(VERIFIED, options); + }.bind(this)); }, _setVerified: function(verified, options) { options = options || {}; - _.defaults(options, {viaSyncMessage: false, key: null}); + _.defaults(options, {viaSyncMessage: false, viaContactSync: false, key: null}); var VERIFIED = this.verifiedEnum.VERIFIED; + var DEFAULT = this.verifiedEnum.DEFAULT; if (!this.isPrivate()) { throw new Error('You cannot verify a group conversation. ' + 'You must verify individual contacts.'); } + var beginningVerified = this.get('verified'); var promise; if (options.viaSyncMessage) { // handle the incoming key from the sync messages - need different @@ -112,10 +118,25 @@ ); } - return promise.then(function() { + var keychange; + return promise.then(function(updatedKey) { + keychange = updatedKey; return this.save({verified: verified}); }.bind(this)).then(function() { - this.addVerifiedChange(this.id, verified === VERIFIED, {local: !options.viaSyncMessage}); + // Three situations result in a verification notice in the conversation: + // 1) The message came from an explicit verification in another client (not + // a contact sync) + // 2) The verification value received by the contact sync is different + // from what we have on record + // 3) Our local verification status is not DEFAULT and it hasn't changed, + // but the key did change (say from Key1/Verified to Key2/Verified) + if (!options.viaContactSync + || beginningVerified !== verified + || (keychange && verified !== DEFAULT)) { + + var local = !options.viaSyncMessage && !options.viaContactSync; + this.addVerifiedChange(this.id, verified === VERIFIED, {local: local}); + } if (!options.viaSyncMessage) { return this.sendVerifySyncMessage(this.id, verified); } diff --git a/js/signal_protocol_store.js b/js/signal_protocol_store.js index 5cfeaf2db..30d24c60f 100644 --- a/js/signal_protocol_store.js +++ b/js/signal_protocol_store.js @@ -625,9 +625,12 @@ timestamp : Date.now(), nonblockingApproval : true }).then(function() { - if (!isPresent || !isEqual) { + if (isPresent && !isEqual) { this.trigger('keychange', identifier); - return this.archiveAllSessions(identifier).then(resolve, reject); + return this.archiveAllSessions(identifier).then(function() { + // true signifies that we overwrote a previous key with a new one + return resolve(true); + }, reject); } return resolve(); diff --git a/libtextsecure/message_receiver.js b/libtextsecure/message_receiver.js index aac0d236f..633079410 100644 --- a/libtextsecure/message_receiver.js +++ b/libtextsecure/message_receiver.js @@ -284,13 +284,17 @@ MessageReceiver.prototype.extend({ throw new Error('Got empty SyncMessage'); } }, - handleVerified: function(verified) { + handleVerified: function(verified, options) { + options = options || {}; + _.defaults(options, {viaContactSync: false}); + var ev = new Event('verified'); ev.verified = { state: verified.state, destination: verified.destination, identityKey: verified.identityKey.toArrayBuffer() }; + ev.viaContactSync = options.viaContactSync; this.dispatchEvent(ev); }, handleRead: function(read, timestamp) { @@ -317,7 +321,7 @@ MessageReceiver.prototype.extend({ eventTarget.dispatchEvent(ev); if (contactDetails.verified) { - this.handleVerified(contactDetails.verified); + this.handleVerified(contactDetails.verified, {viaContactSync: true}); } contactDetails = contactBuffer.next(); diff --git a/test/storage_test.js b/test/storage_test.js index 61cd4d859..3475342d9 100644 --- a/test/storage_test.js +++ b/test/storage_test.js @@ -442,7 +442,7 @@ describe("SignalProtocolStore", function() { ).then(fetchRecord).then(function() { assert.strictEqual(record.get('verified'), store.VerifiedStatus.VERIFIED); assertEqualArrayBuffers(record.get('publicKey'), newIdentity); - assert.strictEqual(keychangeTriggered, 1); + assert.strictEqual(keychangeTriggered, 0); }); }); });