diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 9d9b49300..0382d3bd4 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -95,6 +95,16 @@ } } }, + "changedRightAfterVerify": { + "message": "Your verification has been cancelled; please review your new safety number with $name$. Remember, this change could mean that someone is trying to intercept your communication or that $name$ has simply reinstalled Signal.", + "description": "Shown on the safety number screen when the user has selected to verify/unverify a contact's safety number, and we immediately discover a safety number change", + "placeholders": { + "name": { + "content": "$1", + "example": "Bob" + } + } + }, "changedRecentlyMultiple": { "message": "Your safety numbers with multiple group members have changed recently. This could mean that someone is trying to intercept your communication or that they have simply reinstalled Signal.", "description": "Shown on confirmation dialog when user attempts to send a message" diff --git a/background.html b/background.html index a1129bb75..8f5c07c0c 100644 --- a/background.html +++ b/background.html @@ -169,7 +169,9 @@ <div class="content"> <div class='message'>{{ message }}</div> <div class='buttons'> - <button class='cancel' tabindex='2'>{{ cancel }}</button> + {{ #showCancel }} + <button class='cancel' tabindex='2'>{{ cancel }}</button> + {{ /showCancel }} <button class='ok' tabindex='1'>{{ ok }}</button> </div> </div> @@ -346,16 +348,16 @@ </script> <script type='text/x-tmpl-mustache' id='key-verification'> <div class='container'> - {{ ^has_their_key }} - <div class='placeholder'>{{ their_key_unknown }}</div> - {{ /has_their_key }} - {{ #has_their_key }} + {{ ^hasTheirKey }} + <div class='placeholder'>{{ theirKeyUnknown }}</div> + {{ /hasTheirKey }} + {{ #hasTheirKey }} <label> {{ yourSafetyNumberWith }} </label> <!--<div class='qr'></div>--> <div class='key'> {{ #chunks }} <span>{{ . }}</span> {{ /chunks }} </div> - {{ /has_their_key }} + {{ /hasTheirKey }} {{ verifyHelp }} <p> {{> link_to_support }} </p> <div class='summary'> diff --git a/js/views/confirmation_dialog_view.js b/js/views/confirmation_dialog_view.js index b13402f85..17d248f6a 100644 --- a/js/views/confirmation_dialog_view.js +++ b/js/views/confirmation_dialog_view.js @@ -27,6 +27,7 @@ render_attributes: function() { return { message: this.message, + showCancel: Boolean(this.reject), cancel: this.cancelText, ok: this.okText }; diff --git a/js/views/key_verification_view.js b/js/views/key_verification_view.js index e5ad2af27..1ea270b2b 100644 --- a/js/views/key_verification_view.js +++ b/js/views/key_verification_view.js @@ -12,18 +12,20 @@ 'click button.verify': 'toggleVerified', }, initialize: function(options) { - this.our_number = textsecure.storage.user.getNumber(); + this.ourNumber = textsecure.storage.user.getNumber(); if (options.newKey) { - this.their_key = options.newKey; + this.theirKey = options.newKey; } - Promise.all([ + this.loadKeys().then(function() { + this.listenTo(this.model, 'change', this.render); + }.bind(this)); + }, + loadKeys: function() { + return Promise.all([ this.loadTheirKey(), this.loadOurKey(), ]).then(this.generateSecurityNumber.bind(this)) - .then(function() { - this.listenTo(this.model, 'change', this.render); - }.bind(this)) .then(this.render.bind(this)); //.then(this.makeQRCode.bind(this)); }, @@ -31,40 +33,59 @@ // Per Lilia: We can't turn this on until it generates a Latin1 string, as is // required by the mobile clients. new QRCode(this.$('.qr')[0]).makeCode( - dcodeIO.ByteBuffer.wrap(this.our_key).toString('base64') + dcodeIO.ByteBuffer.wrap(this.ourKey).toString('base64') ); }, loadTheirKey: function() { - if (this.their_key) { - return Promise.resolve(this.their_key); - } else { - return textsecure.storage.protocol.loadIdentityKey( - this.model.id - ).then(function(their_key) { - this.their_key = their_key; - }.bind(this)); - } + return textsecure.storage.protocol.loadIdentityKey( + this.model.id + ).then(function(theirKey) { + this.theirKey = theirKey; + }.bind(this)); }, loadOurKey: function() { - if (this.our_key) { - return Promise.resolve(this.our_key); - } else { - return textsecure.storage.protocol.loadIdentityKey( - this.our_number - ).then(function(our_key) { - this.our_key = our_key; - }.bind(this)); - } + return textsecure.storage.protocol.loadIdentityKey( + this.ourNumber + ).then(function(ourKey) { + this.ourKey = ourKey; + }.bind(this)); }, generateSecurityNumber: function() { return new libsignal.FingerprintGenerator(5200).createFor( - this.our_number, this.our_key, this.model.id, this.their_key + this.ourNumber, this.ourKey, this.model.id, this.theirKey ).then(function(securityNumber) { this.securityNumber = securityNumber; }.bind(this)); }, + onSafetyNumberChanged: function() { + this.model.getProfiles().then(this.loadKeys.bind(this)); + + var dialog = new Whisper.ConfirmationDialogView({ + message: i18n('changedRightAfterVerify', this.model.getTitle(), this.model.getTitle()), + resolve: function() {}, + }); + + dialog.$el.insertBefore(this.el); + dialog.focusCancel(); + }, toggleVerified: function() { - this.model.toggleVerified(); + this.$('button.verify').attr('disabled', true); + this.model.toggleVerified().catch(function(result) { + if (result instanceof Error) { + if (result.name === 'OutgoingIdentityKeyError') { + this.onSafetyNumberChanged(); + } + } else { + var keyError = _.some(result.errors, function(error) { + return error.name === 'OutgoingIdentityKeyError'; + }); + if (keyError) { + this.onSafetyNumberChanged(); + } + } + }.bind(this)).then(function() { + this.$('button.verify').removeAttr('disabled'); + }.bind(this)); }, render_attributes: function() { var s = this.securityNumber; @@ -80,11 +101,11 @@ return { learnMore : i18n('learnMore'), - their_key_unknown : i18n('theirIdentityUnknown'), + theirKeyUnknown : i18n('theirIdentityUnknown'), yourSafetyNumberWith : i18n('yourSafetyNumberWith', this.model.getTitle()), verifyHelp : i18n('verifyHelp', this.model.getTitle()), verifyButton : verifyButton, - has_their_key : this.their_key !== undefined, + hasTheirKey : this.theirKey !== undefined, chunks : chunks, isVerified : isVerified, verifiedStatus : verifiedStatus diff --git a/test/index.html b/test/index.html index 2ea61e352..d5d2bf808 100644 --- a/test/index.html +++ b/test/index.html @@ -173,8 +173,10 @@ <div class="content"> <div class='message'>{{ message }}</div> <div class='buttons'> - <button class='cancel'>{{ cancel }}</button> - <button class='ok'>{{ ok }}</button> + {{ #showCancel }} + <button class='cancel' tabindex='2'>{{ cancel }}</button> + {{ /showCancel }} + <button class='ok' tabindex='1'>{{ ok }}</button> </div> </div> </script> @@ -337,16 +339,17 @@ </script> <script type='text/x-tmpl-mustache' id='key-verification'> <div class='container'> - {{ ^has_their_key }} - <div class='placeholder'>{{ their_key_unknown }}</div> - {{ /has_their_key }} - {{ #has_their_key }} + {{ ^hasTheirKey }} + <div class='placeholder'>{{ theirKeyUnknown }}</div> + {{ /hasTheirKey }} + {{ #hasTheirKey }} <label> {{ yourSafetyNumberWith }} </label> <!--<div class='qr'></div>--> <div class='key'> {{ #chunks }} <span>{{ . }}</span> {{ /chunks }} </div> - {{ /has_their_key }} + {{ /hasTheirKey }} + {{ verifyHelp }} <p> {{> link_to_support }} </p> <div class='summary'> {{ #isVerified }}