Insert keychange advisories
On click, these open a verification panel for the relevant contact, within this conversation. // FREEBIE
This commit is contained in:
parent
1f0a93bf70
commit
7fe708d195
10 changed files with 93 additions and 13 deletions
|
@ -458,5 +458,15 @@
|
|||
"safetyNumbersSettingDescription": {
|
||||
"message": "Require approval of new safety numbers when they change.",
|
||||
"description": "Description for safety numbers setting"
|
||||
},
|
||||
"keychanged": {
|
||||
"message": "$name$'s safety numbers have changed",
|
||||
"description": "",
|
||||
"placeholders": {
|
||||
"name": {
|
||||
"content": "$1",
|
||||
"example": "John"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -155,6 +155,9 @@
|
|||
{{ messageNotSent }}
|
||||
<span href='#' class='retry'>{{ resend }}</span>
|
||||
</script>
|
||||
<script type='text/x-tmpl-mustache' id='keychange'>
|
||||
<span class='content' dir='auto'>{{ content }}</span>
|
||||
</script>
|
||||
<script type='text/x-tmpl-mustache' id='message'>
|
||||
{{> avatar }}
|
||||
<div class='bubble {{ avatar.color }}'>
|
||||
|
|
|
@ -41,6 +41,25 @@
|
|||
this.on('change:avatar', this.updateAvatarUrl);
|
||||
this.on('destroy', this.revokeAvatarUrl);
|
||||
this.on('read', this.onReadMessage);
|
||||
this.fetchContacts().then(function() {
|
||||
this.contactCollection.each(function(contact) {
|
||||
textsecure.storage.protocol.on('keychange:' + contact.id, function() {
|
||||
this.addKeyChange(contact.id);
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
addKeyChange: function(id) {
|
||||
var now = Date.now();
|
||||
var message = this.messageCollection.add({
|
||||
conversationId : this.id,
|
||||
type : 'keychange',
|
||||
sent_at : now,
|
||||
received_at : now,
|
||||
key_changed : id
|
||||
});
|
||||
message.save();
|
||||
},
|
||||
|
||||
onReadMessage: function(message) {
|
||||
|
|
|
@ -132,6 +132,15 @@
|
|||
}
|
||||
return c;
|
||||
},
|
||||
getModelForKeyChange: function() {
|
||||
var id = this.get('key_changed');
|
||||
var c = ConversationController.get(id);
|
||||
if (!c) {
|
||||
c = ConversationController.create({ id: id, type: 'private' });
|
||||
c.fetch();
|
||||
}
|
||||
return c;
|
||||
},
|
||||
isOutgoing: function() {
|
||||
return this.get('type') === 'outgoing';
|
||||
},
|
||||
|
|
|
@ -261,20 +261,15 @@
|
|||
var identityKey = new IdentityKey({id: number});
|
||||
identityKey.fetch().always(function() {
|
||||
var oldpublicKey = identityKey.get('publicKey');
|
||||
var matches = equalArrayBuffers(oldpublicKey, publicKey);
|
||||
var changed = !!oldpublicKey && !matches;
|
||||
if (changed) {
|
||||
console.log('Key changed for', identifier);
|
||||
this.trigger('keychange', identifier);
|
||||
}
|
||||
var trusted = !oldpublicKey || matches;
|
||||
if (trusted) {
|
||||
if (!oldpublicKey || equalArrayBuffers(oldpublicKey, publicKey)) {
|
||||
resolve(true);
|
||||
} else if (!storage.get('safety-numbers-approval', true)) {
|
||||
this.removeIdentityKey(identifier).then(function() {
|
||||
this.saveIdentity(identifier, publicKey).then(function() {
|
||||
console.log('Key changed for', identifier);
|
||||
this.trigger('keychange:' + identifier);
|
||||
resolve(true);
|
||||
});
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
} else {
|
||||
resolve(false);
|
||||
|
|
|
@ -149,7 +149,8 @@
|
|||
'loadMore .message-list': 'fetchMessages',
|
||||
'close .menu': 'closeMenu',
|
||||
'select .message-list .entry': 'messageDetail',
|
||||
'force-resize': 'forceUpdateMessageFieldSize'
|
||||
'force-resize': 'forceUpdateMessageFieldSize',
|
||||
'verify-identity': 'verifyIdentity'
|
||||
},
|
||||
enableDisappearingMessages: function() {
|
||||
if (!this.model.get('expireTimer')) {
|
||||
|
@ -252,10 +253,13 @@
|
|||
this.model.markRead();
|
||||
},
|
||||
|
||||
verifyIdentity: function() {
|
||||
if (this.model.isPrivate()) {
|
||||
verifyIdentity: function(ev, model) {
|
||||
if (!model && this.model.isPrivate()) {
|
||||
model = this.model;
|
||||
}
|
||||
if (model) {
|
||||
var view = new Whisper.KeyVerificationPanelView({
|
||||
model: { their_number: this.model.id }
|
||||
model: { their_number: model.id }
|
||||
});
|
||||
this.listenBack(view);
|
||||
}
|
||||
|
|
|
@ -46,6 +46,8 @@
|
|||
var view;
|
||||
if (model.isExpirationTimerUpdate()) {
|
||||
view = new Whisper.ExpirationTimerUpdateView({model: model}).render();
|
||||
} else if (model.get('type') === 'keychange') {
|
||||
view = new Whisper.KeyChangeView({model: model}).render();
|
||||
} else {
|
||||
view = new this.itemView({model: model}).render();
|
||||
this.listenTo(view, 'beforeChangeHeight', this.measureScrollPosition);
|
||||
|
|
|
@ -67,6 +67,27 @@
|
|||
}
|
||||
});
|
||||
|
||||
Whisper.KeyChangeView = Whisper.View.extend({
|
||||
tagName: 'li',
|
||||
className: 'keychange',
|
||||
templateName: 'keychange',
|
||||
initialize: function() {
|
||||
this.conversation = this.model.getModelForKeyChange();
|
||||
this.listenTo(this.conversation, 'change', this.render);
|
||||
},
|
||||
events: {
|
||||
'click .content': 'verifyIdentity'
|
||||
},
|
||||
render_attributes: function() {
|
||||
return {
|
||||
content: i18n('keychanged', this.conversation.getTitle())
|
||||
};
|
||||
},
|
||||
verifyIdentity: function() {
|
||||
this.$el.trigger('verify-identity', this.conversation);
|
||||
}
|
||||
});
|
||||
|
||||
Whisper.MessageView = Whisper.View.extend({
|
||||
tagName: 'li',
|
||||
templateName: 'message',
|
||||
|
|
|
@ -601,3 +601,12 @@ li.entry .error-icon-container {
|
|||
}
|
||||
}
|
||||
}
|
||||
.message-list li.keychange {
|
||||
text-align: center;
|
||||
.content {
|
||||
display: inline-block;
|
||||
padding: 5px 10px;
|
||||
background: #fff5c4;
|
||||
border-radius: $border-radius;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1380,6 +1380,14 @@ li.entry .error-icon-container {
|
|||
background-color: #d9d9d9;
|
||||
border-color: silver; }
|
||||
|
||||
.message-list li.keychange {
|
||||
text-align: center; }
|
||||
.message-list li.keychange .content {
|
||||
display: inline-block;
|
||||
padding: 5px 10px;
|
||||
background: #fff5c4;
|
||||
border-radius: 5px; }
|
||||
|
||||
.ios #header {
|
||||
height: 64px;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
||||
|
|
Loading…
Reference in a new issue