From dcc158821985dae7a6b90cc4e57b59128c79ec92 Mon Sep 17 00:00:00 2001 From: lilia Date: Thu, 26 Feb 2015 18:10:04 -0800 Subject: [PATCH] Add key verification screen Accessible from the menu on private conversations. --- conversation.html | 18 ++++++++++++ js/views/conversation_view.js | 21 ++++++++++++++ js/views/key_verification_view.js | 48 +++++++++++++++++++++++++++++++ js/views/message_detail_view.js | 19 +++++++++++- stylesheets/_conversation.scss | 16 ++++++++++- stylesheets/manifest.css | 13 ++++++++- 6 files changed, 132 insertions(+), 3 deletions(-) create mode 100644 js/views/key_verification_view.js diff --git a/conversation.html b/conversation.html index 5bb1d68e..f47eac8e 100644 --- a/conversation.html +++ b/conversation.html @@ -22,6 +22,7 @@ {{/group}} {{^group}}
  • End Session
  • +
  • Verify Identity
  • {{/group}}
  • Delete messages
  • @@ -116,6 +117,22 @@ + @@ -138,6 +155,7 @@ + diff --git a/js/views/conversation_view.js b/js/views/conversation_view.js index 95c4fd61..70ff6981 100644 --- a/js/views/conversation_view.js +++ b/js/views/conversation_view.js @@ -52,11 +52,32 @@ 'click .end-session': 'endSession', 'click .leave-group': 'leaveGroup', 'click .new-group-update': 'newGroupUpdate', + 'click .verify-identity': 'verifyIdentity', 'click .hamburger': 'toggleMenu', 'click' : 'closeMenu', 'select .entry': 'messageDetail' }, + verifyIdentity: function() { + if (this.model.isPrivate()) { + var number = this.model.id; + var view = new Whisper.KeyVerificationView({ + model: { + their_key: textsecure.storage.devices.getIdentityKeyForNumber(number), + your_key: textsecure.storage.devices.getIdentityKeyForNumber( + textsecure.utils.unencodeNumber(textsecure.storage.getUnencrypted("number_id"))[0] + ) + } + }); + this.$el.hide(); + view.render().$el.insertAfter(this.el); + this.listenTo(view, 'back', function() { + view.remove(); + this.$el.show(); + }); + } + }, + messageDetail: function(e, data) { var view = new Whisper.MessageDetailView({ model: data.message, conversation: this.model }); view.$el.insertAfter(this.$el); diff --git a/js/views/key_verification_view.js b/js/views/key_verification_view.js new file mode 100644 index 00000000..c500eae6 --- /dev/null +++ b/js/views/key_verification_view.js @@ -0,0 +1,48 @@ +/* vim: ts=4:sw=4:expandtab + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +(function () { + 'use strict'; + + window.Whisper = window.Whisper || {}; + + Whisper.KeyVerificationView = Backbone.View.extend({ + className: 'key-verification', + initialize: function(options) { + this.template = $('#key-verification').html(); + Mustache.parse(this.template); + }, + events: { + 'click .back': 'goBack' + }, + goBack: function() { + this.trigger('back'); + }, + splitKey: function(key) { + // key is a binary string + return _.map(key, function(chr, i) { + return ('0' + key.charCodeAt(i).toString(16)).slice(-2); + + }); + }, + render: function() { + this.$el.html(Mustache.render(this.template, { + your_key: this.splitKey(this.model.your_key), + their_key: this.splitKey(this.model.their_key) + })); + return this; + } + }); +})(); diff --git a/js/views/message_detail_view.js b/js/views/message_detail_view.js index f51cacc0..d52fee1f 100644 --- a/js/views/message_detail_view.js +++ b/js/views/message_detail_view.js @@ -27,11 +27,28 @@ this.conversation = options.conversation; }, events: { - 'click .back': 'goBack' + 'click .back': 'goBack', + 'verify': 'verify' }, goBack: function() { this.trigger('back'); }, + verify: function(number) { + var view = new Whisper.KeyVerificationView({ + model: { + their_key: textsecure.storage.devices.getIdentityKeyForNumber(number), + your_key: textsecure.storage.devices.getIdentityKeyForNumber( + textsecure.utils.unencodeNumber(textsecure.storage.getUnencrypted("number_id"))[0] + ) + } + }); + this.$el.hide(); + view.render().$el.insertAfter(this.el); + this.listenTo(view, 'back', function() { + view.remove(); + this.$el.show(); + }); + }, render: function() { this.$el.html(Mustache.render(this.template, { sent_at: moment(this.model.get('sent_at')).toString(), diff --git a/stylesheets/_conversation.scss b/stylesheets/_conversation.scss index afbf61e0..defa91be 100644 --- a/stylesheets/_conversation.scss +++ b/stylesheets/_conversation.scss @@ -2,10 +2,24 @@ padding: $header-height 0; } -.conversation, .discussion-container, .message-list, .message-detail { +.conversation, .discussion-container, .message-list, .message-detail, .key-verification { height: 100%; } +.key-verification { + padding: $header-height 0 0; + .container { + height: 100%; + overflow: auto; + } + p { + padding: 1em; + } + .key { + font-family: monospace; + padding: 0 1em; + } +} .message-detail { padding: $header-height 0 0; background: $grey_l; diff --git a/stylesheets/manifest.css b/stylesheets/manifest.css index 62d44187..30cad05e 100644 --- a/stylesheets/manifest.css +++ b/stylesheets/manifest.css @@ -280,9 +280,20 @@ input.new-message { .conversation { padding: 36px 0; } -.conversation, .discussion-container, .message-list, .message-detail { +.conversation, .discussion-container, .message-list, .message-detail, .key-verification { height: 100%; } +.key-verification { + padding: 36px 0 0; } + .key-verification .container { + height: 100%; + overflow: auto; } + .key-verification p { + padding: 1em; } + .key-verification .key { + font-family: monospace; + padding: 0 1em; } + .message-detail { padding: 36px 0 0; background: #f3f3f3; }