Remove all concept of 'key conflict' from the app
This commit is contained in:
parent
51080141cd
commit
ee0b0f5ffb
15 changed files with 28 additions and 400 deletions
|
@ -512,39 +512,6 @@
|
|||
}.bind(this));
|
||||
},
|
||||
|
||||
resolveConflicts: function(conflict) {
|
||||
var number = conflict.number;
|
||||
var identityKey = conflict.identityKey;
|
||||
if (this.isPrivate()) {
|
||||
number = this.id;
|
||||
} else if (!_.include(this.get('members'), number)) {
|
||||
throw 'Tried to resolve conflicts for a unknown group member';
|
||||
}
|
||||
|
||||
if (!this.messageCollection.hasKeyConflicts()) {
|
||||
throw 'No conflicts to resolve';
|
||||
}
|
||||
|
||||
return textsecure.storage.protocol.saveIdentity(number, identityKey, true).then(function() {
|
||||
var promise = Promise.resolve();
|
||||
var conflicts = this.messageCollection.filter(function(message) {
|
||||
return message.hasKeyConflict(number);
|
||||
});
|
||||
// group incoming & outgoing
|
||||
conflicts = _.groupBy(conflicts, function(m) { return m.get('type'); });
|
||||
// sort each group by date and concatenate outgoing after incoming
|
||||
conflicts = _.flatten([
|
||||
_.sortBy(conflicts.incoming, function(m) { return m.get('received_at'); }),
|
||||
_.sortBy(conflicts.outgoing, function(m) { return m.get('received_at'); }),
|
||||
]).forEach(function(message) {
|
||||
var resolveConflict = function() {
|
||||
return message.resolveConflict(number);
|
||||
};
|
||||
promise = promise.then(resolveConflict, resolveConflict);
|
||||
});
|
||||
return promise;
|
||||
}.bind(this));
|
||||
},
|
||||
notify: function(message) {
|
||||
if (!message.isIncoming()) {
|
||||
return;
|
||||
|
|
|
@ -88,9 +88,6 @@
|
|||
if (this.isEndSession()) {
|
||||
return i18n('sessionEnded');
|
||||
}
|
||||
if (this.isIncoming() && this.hasKeyConflicts()) {
|
||||
return i18n('incomingKeyConflict');
|
||||
}
|
||||
if (this.isIncoming() && this.hasErrors()) {
|
||||
return i18n('incomingError');
|
||||
}
|
||||
|
@ -191,26 +188,6 @@
|
|||
hasErrors: function() {
|
||||
return _.size(this.get('errors')) > 0;
|
||||
},
|
||||
hasKeyConflicts: function() {
|
||||
return _.any(this.get('errors'), function(e) {
|
||||
return (e.name === 'IncomingIdentityKeyError' ||
|
||||
e.name === 'OutgoingIdentityKeyError');
|
||||
});
|
||||
},
|
||||
hasKeyConflict: function(number) {
|
||||
return _.any(this.get('errors'), function(e) {
|
||||
return (e.name === 'IncomingIdentityKeyError' ||
|
||||
e.name === 'OutgoingIdentityKeyError') &&
|
||||
e.number === number;
|
||||
});
|
||||
},
|
||||
getKeyConflict: function(number) {
|
||||
return _.find(this.get('errors'), function(e) {
|
||||
return (e.name === 'IncomingIdentityKeyError' ||
|
||||
e.name === 'OutgoingIdentityKeyError') &&
|
||||
e.number === number;
|
||||
});
|
||||
},
|
||||
|
||||
send: function(promise) {
|
||||
this.trigger('pending');
|
||||
|
@ -281,15 +258,6 @@
|
|||
return this.save({errors : errors});
|
||||
},
|
||||
|
||||
removeConflictFor: function(number) {
|
||||
var errors = _.reject(this.get('errors'), function(e) {
|
||||
return e.number === number &&
|
||||
(e.name === 'IncomingIdentityKeyError' ||
|
||||
e.name === 'OutgoingIdentityKeyError');
|
||||
});
|
||||
this.set({errors: errors});
|
||||
},
|
||||
|
||||
hasNetworkError: function(number) {
|
||||
var error = _.find(this.get('errors'), function(e) {
|
||||
return (e.name === 'MessageError' ||
|
||||
|
@ -325,30 +293,6 @@
|
|||
}
|
||||
},
|
||||
|
||||
resolveConflict: function(number) {
|
||||
var error = this.getKeyConflict(number);
|
||||
if (error) {
|
||||
this.removeConflictFor(number);
|
||||
var promise = new textsecure.ReplayableError(error).replay();
|
||||
if (this.isIncoming()) {
|
||||
promise = promise.then(function(dataMessage) {
|
||||
this.removeConflictFor(number);
|
||||
this.handleDataMessage(dataMessage);
|
||||
}.bind(this));
|
||||
} else {
|
||||
promise = this.send(promise).then(function() {
|
||||
this.removeConflictFor(number);
|
||||
this.save();
|
||||
}.bind(this));
|
||||
}
|
||||
promise.catch(function(e) {
|
||||
this.removeConflictFor(number);
|
||||
this.saveErrors(e);
|
||||
}.bind(this));
|
||||
|
||||
return promise;
|
||||
}
|
||||
},
|
||||
handleDataMessage: function(dataMessage) {
|
||||
// This function can be called from the background script on an
|
||||
// incoming message or from the frontend after the user accepts an
|
||||
|
@ -640,10 +584,6 @@
|
|||
conditions: { expires_at: { $lte: Date.now() } },
|
||||
addIndividually: true
|
||||
});
|
||||
},
|
||||
|
||||
hasKeyConflicts: function() {
|
||||
return this.any(function(m) { return m.hasKeyConflicts(); });
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
'use strict';
|
||||
window.Whisper = window.Whisper || {};
|
||||
|
||||
// Contact list view is used in the list group members senario, as well as the NewGroupUpdate view
|
||||
Whisper.ContactListView = Whisper.ListView.extend({
|
||||
tagName: 'div',
|
||||
itemView: Whisper.View.extend({
|
||||
|
|
|
@ -13,48 +13,4 @@
|
|||
return this.model;
|
||||
}
|
||||
});
|
||||
|
||||
var KeyConflictView = ErrorView.extend({
|
||||
className: 'key-conflict',
|
||||
templateName: 'key-conflict',
|
||||
initialize: function(options) {
|
||||
this.message = options.message;
|
||||
},
|
||||
events: {
|
||||
'click': 'select'
|
||||
},
|
||||
render_attributes: function() {
|
||||
var errorMessage;
|
||||
if (this.message.isIncoming()) {
|
||||
errorMessage = 'incomingKeyConflict';
|
||||
} else {
|
||||
errorMessage = 'outgoingKeyConflict';
|
||||
}
|
||||
return { message: i18n(errorMessage) };
|
||||
},
|
||||
select: function() {
|
||||
this.$el.trigger('select', {message: this.message});
|
||||
},
|
||||
});
|
||||
|
||||
Whisper.MessageErrorView = Backbone.View.extend({
|
||||
className: 'error',
|
||||
initialize: function(options) {
|
||||
if (this.model.name === 'IncomingIdentityKeyError' ||
|
||||
this.model.name === 'OutgoingIdentityKeyError') {
|
||||
this.view = new KeyConflictView({
|
||||
model : this.model,
|
||||
message : options.message
|
||||
});
|
||||
} else {
|
||||
this.view = new ErrorView({ model: this.model });
|
||||
}
|
||||
this.$el.append(this.view.el);
|
||||
this.view.render();
|
||||
},
|
||||
render: function() {
|
||||
this.view.render();
|
||||
return this;
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
|
|
@ -5,6 +5,11 @@
|
|||
'use strict';
|
||||
window.Whisper = window.Whisper || {};
|
||||
|
||||
// This needs to make each member link to their verification view - except for yourself
|
||||
// Do we update the display of each user to add Verified to their name if verified?
|
||||
// What about the case where we're brought here because there are multiple users in the no-longer-verified state?
|
||||
// We probably want to display some sort of helper text in that case at the least
|
||||
// Or do we show only the problematic users in that case?
|
||||
Whisper.GroupMemberList = Whisper.View.extend({
|
||||
className: 'group-member-list panel',
|
||||
templateName: 'group-member-list',
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
* vim: ts=4:sw=4:expandtab
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
window.Whisper = window.Whisper || {};
|
||||
|
||||
Whisper.KeyConflictDialogueView = Whisper.View.extend({
|
||||
templateName: 'key-conflict-dialogue',
|
||||
className: 'key-conflict-dialogue clearfix',
|
||||
initialize: function(options) {
|
||||
this.contact = options.contact;
|
||||
this.conversation = options.conversation;
|
||||
this.render();
|
||||
var view = new Whisper.KeyVerificationView({
|
||||
model : this.contact,
|
||||
newKey : this.model.identityKey
|
||||
});
|
||||
view.$el.appendTo(this.$('.keys'));
|
||||
},
|
||||
events: {
|
||||
'click .showKeys': 'showKeys',
|
||||
'click .hideKeys': 'hideKeys',
|
||||
'click .resolve' : 'resolve'
|
||||
},
|
||||
hideKeys: function() {
|
||||
this.$('.keys, .hideKeys').hide();
|
||||
this.$('.showKeys').show();
|
||||
},
|
||||
showKeys: function() {
|
||||
this.$('.keys, .hideKeys').show();
|
||||
this.$('.showKeys').hide();
|
||||
},
|
||||
resolve: function() {
|
||||
this.remove();
|
||||
this.conversation.resolveConflicts(this.model);
|
||||
},
|
||||
render_attributes: function() {
|
||||
return {
|
||||
name : this.contact.getTitle(),
|
||||
avatar : this.contact.getAvatar(),
|
||||
conflict : this.model,
|
||||
newIdentity : i18n('newIdentity'),
|
||||
message : i18n('identityChanged'),
|
||||
resolve : i18n('acceptNewKey'),
|
||||
showKeys : i18n('showMore'),
|
||||
hideKeys : i18n('showLess'),
|
||||
learnMore : i18n('learnMore')
|
||||
};
|
||||
}
|
||||
});
|
||||
})();
|
|
@ -5,9 +5,11 @@
|
|||
'use strict';
|
||||
window.Whisper = window.Whisper || {};
|
||||
|
||||
// TODO; find all uses of that removed panel
|
||||
// Add the Verify functionality to this view
|
||||
Whisper.KeyVerificationView = Whisper.View.extend({
|
||||
className: 'key-verification',
|
||||
templateName: 'key_verification',
|
||||
className: 'key-verification panel',
|
||||
templateName: 'key-verification',
|
||||
initialize: function(options) {
|
||||
this.our_number = textsecure.storage.user.getNumber();
|
||||
if (options.newKey) {
|
||||
|
@ -21,6 +23,8 @@
|
|||
//.then(this.makeQRCode.bind(this));
|
||||
},
|
||||
makeQRCode: function() {
|
||||
// Per Lilia: We can't turn this on until it geneates a Latin1 string, as is
|
||||
// required by the mobile clients.
|
||||
new QRCode(this.$('.qr')[0]).makeCode(
|
||||
dcodeIO.ByteBuffer.wrap(this.our_key).toString('base64')
|
||||
);
|
||||
|
@ -72,8 +76,4 @@
|
|||
};
|
||||
}
|
||||
});
|
||||
Whisper.KeyVerificationPanelView = Whisper.KeyVerificationView.extend({
|
||||
className: 'key-verification panel',
|
||||
templateName: 'key_verification_panel',
|
||||
});
|
||||
})();
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
className: 'contact-detail',
|
||||
templateName: 'contact-detail',
|
||||
initialize: function(options) {
|
||||
this.conflict = options.conflict;
|
||||
this.errors = _.reject(options.errors, function(e) {
|
||||
return (e.name === 'IncomingIdentityKeyError' ||
|
||||
e.name === 'OutgoingIdentityKeyError' ||
|
||||
|
@ -51,19 +50,6 @@
|
|||
errors: this.errors[contact.id]
|
||||
}).render();
|
||||
this.$('.contacts').append(view.el);
|
||||
|
||||
var conflict = this.model.getKeyConflict(contact.id);
|
||||
if (conflict) {
|
||||
this.renderConflict(contact, conflict);
|
||||
}
|
||||
},
|
||||
renderConflict: function(contact, conflict) {
|
||||
var view = new Whisper.KeyConflictDialogueView({
|
||||
model: conflict,
|
||||
contact: contact,
|
||||
conversation: this.conversation
|
||||
});
|
||||
this.$('.conflicts').append(view.el);
|
||||
},
|
||||
render: function() {
|
||||
this.errors = _.groupBy(this.model.get('errors'), 'number');
|
||||
|
@ -81,8 +67,7 @@
|
|||
title : i18n('messageDetail'),
|
||||
sent : i18n('sent'),
|
||||
received : i18n('received'),
|
||||
errorLabel : i18n('error'),
|
||||
hasConflict : this.model.hasKeyConflicts()
|
||||
errorLabel : i18n('error')
|
||||
}));
|
||||
this.view.$el.prependTo(this.$('.message-container'));
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
'use strict';
|
||||
window.Whisper = window.Whisper || {};
|
||||
|
||||
// When is this used?
|
||||
Whisper.NewGroupUpdateView = Whisper.View.extend({
|
||||
tagName: "div",
|
||||
className: 'new-group-update',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue