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
				
			
		| 
						 | 
					@ -69,12 +69,6 @@
 | 
				
			||||||
    "identityChanged": {
 | 
					    "identityChanged": {
 | 
				
			||||||
      "message": "Your safety number with this contact has changed. This could either mean that someone is trying to intercept your communication, or this contact simply reinstalled Signal. You may wish to verify the new safety number below."
 | 
					      "message": "Your safety number with this contact has changed. This could either mean that someone is trying to intercept your communication, or this contact simply reinstalled Signal. You may wish to verify the new safety number below."
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "outgoingKeyConflict": {
 | 
					 | 
				
			||||||
      "message": "Your safety number with this contact has changed. Click to process and display."
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "incomingKeyConflict": {
 | 
					 | 
				
			||||||
      "message": "Received message with a new safety number. Click to process and display."
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "incomingError": {
 | 
					    "incomingError": {
 | 
				
			||||||
      "message": "Error handling incoming message."
 | 
					      "message": "Error handling incoming message."
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -280,12 +280,6 @@
 | 
				
			||||||
  </script>
 | 
					  </script>
 | 
				
			||||||
  <script type='text/x-tmpl-mustache' id='message-detail'>
 | 
					  <script type='text/x-tmpl-mustache' id='message-detail'>
 | 
				
			||||||
    <div class='container'>
 | 
					    <div class='container'>
 | 
				
			||||||
      {{ #hasConflict }}
 | 
					 | 
				
			||||||
        <div class='hasConflict clearfix'>
 | 
					 | 
				
			||||||
          <div class='conflicts'>
 | 
					 | 
				
			||||||
          </div>
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
      {{ /hasConflict }}
 | 
					 | 
				
			||||||
      <div class='message-container'></div>
 | 
					      <div class='message-container'></div>
 | 
				
			||||||
      <div class='info'>
 | 
					      <div class='info'>
 | 
				
			||||||
        <table>
 | 
					        <table>
 | 
				
			||||||
| 
						 | 
					@ -315,13 +309,8 @@
 | 
				
			||||||
  <script type='text/x-tmpl-mustache' id='group-member-list'>
 | 
					  <script type='text/x-tmpl-mustache' id='group-member-list'>
 | 
				
			||||||
    <div class='container'></div>
 | 
					    <div class='container'></div>
 | 
				
			||||||
  </script>
 | 
					  </script>
 | 
				
			||||||
  <script type='text/x-tmpl-mustache' id='key_verification_panel'>
 | 
					  <script type='text/x-tmpl-mustache' id='key-verification'>
 | 
				
			||||||
    <div class='container'>
 | 
					    <div class='container'>
 | 
				
			||||||
      {{> key_verification }}
 | 
					 | 
				
			||||||
      <p> {{> link_to_support }} </p>
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
  </script>
 | 
					 | 
				
			||||||
  <script type='text/x-tmpl-mustache' id='key_verification'>
 | 
					 | 
				
			||||||
      {{ ^has_their_key }}
 | 
					      {{ ^has_their_key }}
 | 
				
			||||||
        <div class='placeholder'>{{ their_key_unknown }}</div>
 | 
					        <div class='placeholder'>{{ their_key_unknown }}</div>
 | 
				
			||||||
      {{ /has_their_key }}
 | 
					      {{ /has_their_key }}
 | 
				
			||||||
| 
						 | 
					@ -332,6 +321,8 @@
 | 
				
			||||||
          {{ #chunks }} <span>{{ . }}</span> {{ /chunks }}
 | 
					          {{ #chunks }} <span>{{ . }}</span> {{ /chunks }}
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      {{ /has_their_key }}
 | 
					      {{ /has_their_key }}
 | 
				
			||||||
 | 
					      <p> {{> link_to_support }} </p>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
  </script>
 | 
					  </script>
 | 
				
			||||||
  <!-- index -->
 | 
					  <!-- index -->
 | 
				
			||||||
  <script type='text/x-tmpl-mustache' id='group_info_input'>
 | 
					  <script type='text/x-tmpl-mustache' id='group_info_input'>
 | 
				
			||||||
| 
						 | 
					@ -400,24 +391,6 @@
 | 
				
			||||||
      {{ learnMore }}
 | 
					      {{ learnMore }}
 | 
				
			||||||
    </a>
 | 
					    </a>
 | 
				
			||||||
  </script>
 | 
					  </script>
 | 
				
			||||||
  <script type='text/x-tmpl-mustache' id='key-conflict-dialogue'>
 | 
					 | 
				
			||||||
    <h3 class='header'>{{ newIdentity }}</h3>
 | 
					 | 
				
			||||||
    <div class='content clearfix'>
 | 
					 | 
				
			||||||
      <div class='clearfix'>
 | 
					 | 
				
			||||||
        {{> avatar }}
 | 
					 | 
				
			||||||
        <span class='name'>{{ name }}</span>
 | 
					 | 
				
			||||||
        <button class='resolve'>{{ resolve }}</button>
 | 
					 | 
				
			||||||
        <a href='#' class='hideKeys hide'> {{ hideKeys }} </a>
 | 
					 | 
				
			||||||
        <a href='#' class='showKeys'> {{ showKeys }} </a>
 | 
					 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
      <div class='keys hide'>
 | 
					 | 
				
			||||||
        <p>
 | 
					 | 
				
			||||||
          {{ message }}
 | 
					 | 
				
			||||||
          {{> link_to_support }}
 | 
					 | 
				
			||||||
        </p>
 | 
					 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
  </script>
 | 
					 | 
				
			||||||
  <script type='text/x-tmpl-mustache' id='debug-log'>
 | 
					  <script type='text/x-tmpl-mustache' id='debug-log'>
 | 
				
			||||||
    <div class='content'>
 | 
					    <div class='content'>
 | 
				
			||||||
      <div>
 | 
					      <div>
 | 
				
			||||||
| 
						 | 
					@ -656,7 +629,6 @@
 | 
				
			||||||
  <script type='text/javascript' src='js/views/contact_list_view.js'></script>
 | 
					  <script type='text/javascript' src='js/views/contact_list_view.js'></script>
 | 
				
			||||||
  <script type='text/javascript' src='js/views/new_group_update_view.js'></script>
 | 
					  <script type='text/javascript' src='js/views/new_group_update_view.js'></script>
 | 
				
			||||||
  <script type='text/javascript' src='js/views/attachment_view.js'></script>
 | 
					  <script type='text/javascript' src='js/views/attachment_view.js'></script>
 | 
				
			||||||
  <script type='text/javascript' src='js/views/key_conflict_dialogue_view.js'></script>
 | 
					 | 
				
			||||||
  <script type='text/javascript' src='js/views/error_view.js'></script>
 | 
					  <script type='text/javascript' src='js/views/error_view.js'></script>
 | 
				
			||||||
  <script type='text/javascript' src='js/views/timestamp_view.js'></script>
 | 
					  <script type='text/javascript' src='js/views/timestamp_view.js'></script>
 | 
				
			||||||
  <script type='text/javascript' src='js/views/message_view.js'></script>
 | 
					  <script type='text/javascript' src='js/views/message_view.js'></script>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -512,39 +512,6 @@
 | 
				
			||||||
        }.bind(this));
 | 
					        }.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) {
 | 
					    notify: function(message) {
 | 
				
			||||||
        if (!message.isIncoming()) {
 | 
					        if (!message.isIncoming()) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -88,9 +88,6 @@
 | 
				
			||||||
            if (this.isEndSession()) {
 | 
					            if (this.isEndSession()) {
 | 
				
			||||||
                return i18n('sessionEnded');
 | 
					                return i18n('sessionEnded');
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if (this.isIncoming() && this.hasKeyConflicts()) {
 | 
					 | 
				
			||||||
                return i18n('incomingKeyConflict');
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            if (this.isIncoming() && this.hasErrors()) {
 | 
					            if (this.isIncoming() && this.hasErrors()) {
 | 
				
			||||||
                return i18n('incomingError');
 | 
					                return i18n('incomingError');
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					@ -191,26 +188,6 @@
 | 
				
			||||||
        hasErrors: function() {
 | 
					        hasErrors: function() {
 | 
				
			||||||
            return _.size(this.get('errors')) > 0;
 | 
					            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) {
 | 
					        send: function(promise) {
 | 
				
			||||||
            this.trigger('pending');
 | 
					            this.trigger('pending');
 | 
				
			||||||
| 
						 | 
					@ -281,15 +258,6 @@
 | 
				
			||||||
            return this.save({errors : errors});
 | 
					            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) {
 | 
					        hasNetworkError: function(number) {
 | 
				
			||||||
            var error = _.find(this.get('errors'), function(e) {
 | 
					            var error = _.find(this.get('errors'), function(e) {
 | 
				
			||||||
                return (e.name === 'MessageError' ||
 | 
					                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) {
 | 
					        handleDataMessage: function(dataMessage) {
 | 
				
			||||||
            // This function can be called from the background script on an
 | 
					            // This function can be called from the background script on an
 | 
				
			||||||
            // incoming message or from the frontend after the user accepts an
 | 
					            // incoming message or from the frontend after the user accepts an
 | 
				
			||||||
| 
						 | 
					@ -640,10 +584,6 @@
 | 
				
			||||||
                conditions: { expires_at: { $lte: Date.now() } },
 | 
					                conditions: { expires_at: { $lte: Date.now() } },
 | 
				
			||||||
                addIndividually: true
 | 
					                addIndividually: true
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        hasKeyConflicts: function() {
 | 
					 | 
				
			||||||
            return this.any(function(m) { return m.hasKeyConflicts(); });
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
})();
 | 
					})();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,6 +5,7 @@
 | 
				
			||||||
    'use strict';
 | 
					    'use strict';
 | 
				
			||||||
    window.Whisper = window.Whisper || {};
 | 
					    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({
 | 
					    Whisper.ContactListView = Whisper.ListView.extend({
 | 
				
			||||||
        tagName: 'div',
 | 
					        tagName: 'div',
 | 
				
			||||||
        itemView: Whisper.View.extend({
 | 
					        itemView: Whisper.View.extend({
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,48 +13,4 @@
 | 
				
			||||||
            return this.model;
 | 
					            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';
 | 
					    'use strict';
 | 
				
			||||||
    window.Whisper = window.Whisper || {};
 | 
					    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({
 | 
					    Whisper.GroupMemberList = Whisper.View.extend({
 | 
				
			||||||
        className: 'group-member-list panel',
 | 
					        className: 'group-member-list panel',
 | 
				
			||||||
        templateName: 'group-member-list',
 | 
					        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';
 | 
					    'use strict';
 | 
				
			||||||
    window.Whisper = window.Whisper || {};
 | 
					    window.Whisper = window.Whisper || {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // TODO; find all uses of that removed panel
 | 
				
			||||||
 | 
					    // Add the Verify functionality to this view
 | 
				
			||||||
    Whisper.KeyVerificationView = Whisper.View.extend({
 | 
					    Whisper.KeyVerificationView = Whisper.View.extend({
 | 
				
			||||||
        className: 'key-verification',
 | 
					        className: 'key-verification panel',
 | 
				
			||||||
        templateName: 'key_verification',
 | 
					        templateName: 'key-verification',
 | 
				
			||||||
        initialize: function(options) {
 | 
					        initialize: function(options) {
 | 
				
			||||||
            this.our_number = textsecure.storage.user.getNumber();
 | 
					            this.our_number = textsecure.storage.user.getNumber();
 | 
				
			||||||
            if (options.newKey) {
 | 
					            if (options.newKey) {
 | 
				
			||||||
| 
						 | 
					@ -21,6 +23,8 @@
 | 
				
			||||||
              //.then(this.makeQRCode.bind(this));
 | 
					              //.then(this.makeQRCode.bind(this));
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        makeQRCode: function() {
 | 
					        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(
 | 
					            new QRCode(this.$('.qr')[0]).makeCode(
 | 
				
			||||||
                dcodeIO.ByteBuffer.wrap(this.our_key).toString('base64')
 | 
					                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',
 | 
					        className: 'contact-detail',
 | 
				
			||||||
        templateName: 'contact-detail',
 | 
					        templateName: 'contact-detail',
 | 
				
			||||||
        initialize: function(options) {
 | 
					        initialize: function(options) {
 | 
				
			||||||
            this.conflict = options.conflict;
 | 
					 | 
				
			||||||
            this.errors = _.reject(options.errors, function(e) {
 | 
					            this.errors = _.reject(options.errors, function(e) {
 | 
				
			||||||
                return (e.name === 'IncomingIdentityKeyError' ||
 | 
					                return (e.name === 'IncomingIdentityKeyError' ||
 | 
				
			||||||
                        e.name === 'OutgoingIdentityKeyError' ||
 | 
					                        e.name === 'OutgoingIdentityKeyError' ||
 | 
				
			||||||
| 
						 | 
					@ -51,19 +50,6 @@
 | 
				
			||||||
                errors: this.errors[contact.id]
 | 
					                errors: this.errors[contact.id]
 | 
				
			||||||
            }).render();
 | 
					            }).render();
 | 
				
			||||||
            this.$('.contacts').append(view.el);
 | 
					            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() {
 | 
					        render: function() {
 | 
				
			||||||
            this.errors = _.groupBy(this.model.get('errors'), 'number');
 | 
					            this.errors = _.groupBy(this.model.get('errors'), 'number');
 | 
				
			||||||
| 
						 | 
					@ -81,8 +67,7 @@
 | 
				
			||||||
                title       : i18n('messageDetail'),
 | 
					                title       : i18n('messageDetail'),
 | 
				
			||||||
                sent        : i18n('sent'),
 | 
					                sent        : i18n('sent'),
 | 
				
			||||||
                received    : i18n('received'),
 | 
					                received    : i18n('received'),
 | 
				
			||||||
                errorLabel  : i18n('error'),
 | 
					                errorLabel  : i18n('error')
 | 
				
			||||||
                hasConflict : this.model.hasKeyConflicts()
 | 
					 | 
				
			||||||
            }));
 | 
					            }));
 | 
				
			||||||
            this.view.$el.prependTo(this.$('.message-container'));
 | 
					            this.view.$el.prependTo(this.$('.message-container'));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,6 +5,7 @@
 | 
				
			||||||
    'use strict';
 | 
					    'use strict';
 | 
				
			||||||
    window.Whisper = window.Whisper || {};
 | 
					    window.Whisper = window.Whisper || {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // When is this used?
 | 
				
			||||||
    Whisper.NewGroupUpdateView = Whisper.View.extend({
 | 
					    Whisper.NewGroupUpdateView = Whisper.View.extend({
 | 
				
			||||||
        tagName:   "div",
 | 
					        tagName:   "div",
 | 
				
			||||||
        className: 'new-group-update',
 | 
					        className: 'new-group-update',
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -106,40 +106,6 @@
 | 
				
			||||||
.message-detail {
 | 
					.message-detail {
 | 
				
			||||||
  background-color: #eee;
 | 
					  background-color: #eee;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  .key-conflict-dialogue {
 | 
					 | 
				
			||||||
    border-radius: $border-radius;
 | 
					 | 
				
			||||||
    margin: 20px 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .header {
 | 
					 | 
				
			||||||
      border-radius: $border-radius $border-radius 0 0;
 | 
					 | 
				
			||||||
      background: #F3F3A7;
 | 
					 | 
				
			||||||
      margin: 0;
 | 
					 | 
				
			||||||
      padding: 10px 20px
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    .content {
 | 
					 | 
				
			||||||
      padding: 20px;
 | 
					 | 
				
			||||||
      border: 2px solid #F3F3A7;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    button.resolve {
 | 
					 | 
				
			||||||
      outline: none;
 | 
					 | 
				
			||||||
      border: none;
 | 
					 | 
				
			||||||
      border-radius: $border-radius;
 | 
					 | 
				
			||||||
      color: white;
 | 
					 | 
				
			||||||
      font-weight: bold;
 | 
					 | 
				
			||||||
      line-height: 36px;
 | 
					 | 
				
			||||||
      padding: 0 20px;
 | 
					 | 
				
			||||||
      float: right;
 | 
					 | 
				
			||||||
      background: $blue;
 | 
					 | 
				
			||||||
      margin-left: 20px;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .hideKeys, .showKeys {
 | 
					 | 
				
			||||||
      float: right;
 | 
					 | 
				
			||||||
      line-height: 36px;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  .message-container {
 | 
					  .message-container {
 | 
				
			||||||
    padding: 20px 0;
 | 
					    padding: 20px 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -192,10 +158,6 @@
 | 
				
			||||||
    padding: 5px;
 | 
					    padding: 5px;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  button.conflict {
 | 
					 | 
				
			||||||
    float: right;
 | 
					 | 
				
			||||||
    background: #d00;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  button.cancel {
 | 
					  button.cancel {
 | 
				
			||||||
    float: right;
 | 
					    float: right;
 | 
				
			||||||
    color: $grey_d;
 | 
					    color: $grey_d;
 | 
				
			||||||
| 
						 | 
					@ -533,19 +495,10 @@ li.entry .error-icon-container {
 | 
				
			||||||
    cursor: pointer;
 | 
					    cursor: pointer;
 | 
				
			||||||
    font-style: italic;
 | 
					    font-style: italic;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					 | 
				
			||||||
  .key-conflict {
 | 
					 | 
				
			||||||
    padding: 15px 10px;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    button {
 | 
					 | 
				
			||||||
      margin-top: 5px;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.message-list,
 | 
					.message-list,
 | 
				
			||||||
.message-container,
 | 
					.message-container {
 | 
				
			||||||
.key-conflict-dialogue {
 | 
					 | 
				
			||||||
  .avatar {
 | 
					  .avatar {
 | 
				
			||||||
    height: 36px;
 | 
					    height: 36px;
 | 
				
			||||||
    width: 36px;
 | 
					    width: 36px;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1055,31 +1055,6 @@ input.search {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.message-detail {
 | 
					.message-detail {
 | 
				
			||||||
  background-color: #eee; }
 | 
					  background-color: #eee; }
 | 
				
			||||||
  .message-detail .key-conflict-dialogue {
 | 
					 | 
				
			||||||
    border-radius: 5px;
 | 
					 | 
				
			||||||
    margin: 20px 0; }
 | 
					 | 
				
			||||||
    .message-detail .key-conflict-dialogue .header {
 | 
					 | 
				
			||||||
      border-radius: 5px 5px 0 0;
 | 
					 | 
				
			||||||
      background: #F3F3A7;
 | 
					 | 
				
			||||||
      margin: 0;
 | 
					 | 
				
			||||||
      padding: 10px 20px; }
 | 
					 | 
				
			||||||
    .message-detail .key-conflict-dialogue .content {
 | 
					 | 
				
			||||||
      padding: 20px;
 | 
					 | 
				
			||||||
      border: 2px solid #F3F3A7; }
 | 
					 | 
				
			||||||
    .message-detail .key-conflict-dialogue button.resolve {
 | 
					 | 
				
			||||||
      outline: none;
 | 
					 | 
				
			||||||
      border: none;
 | 
					 | 
				
			||||||
      border-radius: 5px;
 | 
					 | 
				
			||||||
      color: white;
 | 
					 | 
				
			||||||
      font-weight: bold;
 | 
					 | 
				
			||||||
      line-height: 36px;
 | 
					 | 
				
			||||||
      padding: 0 20px;
 | 
					 | 
				
			||||||
      float: right;
 | 
					 | 
				
			||||||
      background: #2090ea;
 | 
					 | 
				
			||||||
      margin-left: 20px; }
 | 
					 | 
				
			||||||
    .message-detail .key-conflict-dialogue .hideKeys, .message-detail .key-conflict-dialogue .showKeys {
 | 
					 | 
				
			||||||
      float: right;
 | 
					 | 
				
			||||||
      line-height: 36px; }
 | 
					 | 
				
			||||||
  .message-detail .message-container {
 | 
					  .message-detail .message-container {
 | 
				
			||||||
    padding: 20px 0; }
 | 
					    padding: 20px 0; }
 | 
				
			||||||
    .message-detail .message-container .sender {
 | 
					    .message-detail .message-container .sender {
 | 
				
			||||||
| 
						 | 
					@ -1111,9 +1086,6 @@ input.search {
 | 
				
			||||||
  .message-detail h3 {
 | 
					  .message-detail h3 {
 | 
				
			||||||
    font-size: 1em;
 | 
					    font-size: 1em;
 | 
				
			||||||
    padding: 5px; }
 | 
					    padding: 5px; }
 | 
				
			||||||
  .message-detail button.conflict {
 | 
					 | 
				
			||||||
    float: right;
 | 
					 | 
				
			||||||
    background: #d00; }
 | 
					 | 
				
			||||||
  .message-detail button.cancel {
 | 
					  .message-detail button.cancel {
 | 
				
			||||||
    float: right;
 | 
					    float: right;
 | 
				
			||||||
    color: #454545;
 | 
					    color: #454545;
 | 
				
			||||||
| 
						 | 
					@ -1408,16 +1380,9 @@ li.entry .error-icon-container {
 | 
				
			||||||
  .message-list .bubble .content.error-message {
 | 
					  .message-list .bubble .content.error-message {
 | 
				
			||||||
    cursor: pointer;
 | 
					    cursor: pointer;
 | 
				
			||||||
    font-style: italic; }
 | 
					    font-style: italic; }
 | 
				
			||||||
  .message-container .key-conflict,
 | 
					 | 
				
			||||||
  .message-list .key-conflict {
 | 
					 | 
				
			||||||
    padding: 15px 10px; }
 | 
					 | 
				
			||||||
    .message-container .key-conflict button,
 | 
					 | 
				
			||||||
    .message-list .key-conflict button {
 | 
					 | 
				
			||||||
      margin-top: 5px; }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
.message-list .avatar,
 | 
					.message-list .avatar,
 | 
				
			||||||
.message-container .avatar,
 | 
					.message-container .avatar {
 | 
				
			||||||
.key-conflict-dialogue .avatar {
 | 
					 | 
				
			||||||
  height: 36px;
 | 
					  height: 36px;
 | 
				
			||||||
  width: 36px;
 | 
					  width: 36px;
 | 
				
			||||||
  line-height: 36px; }
 | 
					  line-height: 36px; }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -264,12 +264,6 @@
 | 
				
			||||||
  </script>
 | 
					  </script>
 | 
				
			||||||
  <script type='text/x-tmpl-mustache' id='message-detail'>
 | 
					  <script type='text/x-tmpl-mustache' id='message-detail'>
 | 
				
			||||||
    <div class='container'>
 | 
					    <div class='container'>
 | 
				
			||||||
      {{ #hasConflict }}
 | 
					 | 
				
			||||||
        <div class='hasConflict clearfix'>
 | 
					 | 
				
			||||||
          <div class='conflicts'>
 | 
					 | 
				
			||||||
          </div>
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
      {{ /hasConflict }}
 | 
					 | 
				
			||||||
      <div class='message-container'></div>
 | 
					      <div class='message-container'></div>
 | 
				
			||||||
      <div class='info'>
 | 
					      <div class='info'>
 | 
				
			||||||
        <table>
 | 
					        <table>
 | 
				
			||||||
| 
						 | 
					@ -299,33 +293,20 @@
 | 
				
			||||||
  <script type='text/x-tmpl-mustache' id='group-member-list'>
 | 
					  <script type='text/x-tmpl-mustache' id='group-member-list'>
 | 
				
			||||||
    <div class='container'></div>
 | 
					    <div class='container'></div>
 | 
				
			||||||
  </script>
 | 
					  </script>
 | 
				
			||||||
  <script type='text/x-tmpl-mustache' id='key_verification_panel'>
 | 
					  <script type='text/x-tmpl-mustache' id='key-verification'>
 | 
				
			||||||
    <div class='container'>
 | 
					    <div class='container'>
 | 
				
			||||||
      {{> key_verification }}
 | 
					      {{ ^has_their_key }}
 | 
				
			||||||
      <p> {{> link_to_support }} </p>
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
  </script>
 | 
					 | 
				
			||||||
  <script type='text/x-tmpl-mustache' id='key_verification'>
 | 
					 | 
				
			||||||
      <label> {{theirIdentity}} </label>
 | 
					 | 
				
			||||||
      {{ ^their_key }}
 | 
					 | 
				
			||||||
        <div class='placeholder'>{{ their_key_unknown }}</div>
 | 
					        <div class='placeholder'>{{ their_key_unknown }}</div>
 | 
				
			||||||
      {{ /their_key }}
 | 
					      {{ /has_their_key }}
 | 
				
			||||||
      {{ #has_their_key }}
 | 
					      {{ #has_their_key }}
 | 
				
			||||||
 | 
					        <label> {{ yourSafetyNumberWith }} </label>
 | 
				
			||||||
 | 
					        <!--<div class='qr'></div>-->
 | 
				
			||||||
        <div class='key'>
 | 
					        <div class='key'>
 | 
				
			||||||
          {{ #their_key }} <span>{{ . }}</span> {{ /their_key }}
 | 
					          {{ #chunks }} <span>{{ . }}</span> {{ /chunks }}
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      {{ /has_their_key }}
 | 
					      {{ /has_their_key }}
 | 
				
			||||||
      <label> {{yourIdentity}} </label>
 | 
					      <p> {{> link_to_support }} </p>
 | 
				
			||||||
      <div class='key'>
 | 
					    </div>
 | 
				
			||||||
        {{ #your_key  }} <span>{{ . }}</span> {{ /your_key  }}
 | 
					 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
      <div class='securityNumber'></div>
 | 
					 | 
				
			||||||
  </script>
 | 
					 | 
				
			||||||
  <script type='text/x-tmpl-mustache' id='security_number'>
 | 
					 | 
				
			||||||
      <label> Security number </label>
 | 
					 | 
				
			||||||
      <div class='key'>
 | 
					 | 
				
			||||||
        {{ #chunks }} <span>{{ . }}</span> {{ /chunks }}
 | 
					 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
  </script>
 | 
					  </script>
 | 
				
			||||||
  <!-- index -->
 | 
					  <!-- index -->
 | 
				
			||||||
  <script type='text/x-tmpl-mustache' id='group_info_input'>
 | 
					  <script type='text/x-tmpl-mustache' id='group_info_input'>
 | 
				
			||||||
| 
						 | 
					@ -394,24 +375,6 @@
 | 
				
			||||||
      {{ learnMore }}
 | 
					      {{ learnMore }}
 | 
				
			||||||
    </a>
 | 
					    </a>
 | 
				
			||||||
  </script>
 | 
					  </script>
 | 
				
			||||||
  <script type='text/x-tmpl-mustache' id='key-conflict-dialogue'>
 | 
					 | 
				
			||||||
    <h3 class='header'>{{ newIdentity }}</h3>
 | 
					 | 
				
			||||||
    <div class='content clearfix'>
 | 
					 | 
				
			||||||
      <div class='clearfix'>
 | 
					 | 
				
			||||||
        {{> avatar }}
 | 
					 | 
				
			||||||
        <span class='name'>{{ name }}</span>
 | 
					 | 
				
			||||||
        <button class='resolve'>{{ resolve }}</button>
 | 
					 | 
				
			||||||
        <a href='#' class='hideKeys hide'> {{ hideKeys }} </a>
 | 
					 | 
				
			||||||
        <a href='#' class='showKeys'> {{ showKeys }} </a>
 | 
					 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
      <div class='keys hide'>
 | 
					 | 
				
			||||||
        <p>
 | 
					 | 
				
			||||||
          {{ message }}
 | 
					 | 
				
			||||||
          {{> link_to_support }}
 | 
					 | 
				
			||||||
        </p>
 | 
					 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
  </script>
 | 
					 | 
				
			||||||
  <script type='text/x-tmpl-mustache' id='debug-log'>
 | 
					  <script type='text/x-tmpl-mustache' id='debug-log'>
 | 
				
			||||||
    <div class='content'>
 | 
					    <div class='content'>
 | 
				
			||||||
      <div>
 | 
					      <div>
 | 
				
			||||||
| 
						 | 
					@ -559,7 +522,6 @@
 | 
				
			||||||
  <script type='text/javascript' src='../js/views/new_group_update_view.js' data-cover></script>
 | 
					  <script type='text/javascript' src='../js/views/new_group_update_view.js' data-cover></script>
 | 
				
			||||||
  <script type="text/javascript" src="../js/views/group_update_view.js"></script>
 | 
					  <script type="text/javascript" src="../js/views/group_update_view.js"></script>
 | 
				
			||||||
  <script type='text/javascript' src='../js/views/attachment_view.js' data-cover></script>
 | 
					  <script type='text/javascript' src='../js/views/attachment_view.js' data-cover></script>
 | 
				
			||||||
  <script type='text/javascript' src='../js/views/key_conflict_dialogue_view.js' data-cover></script>
 | 
					 | 
				
			||||||
  <script type='text/javascript' src='../js/views/error_view.js' data-cover></script>
 | 
					  <script type='text/javascript' src='../js/views/error_view.js' data-cover></script>
 | 
				
			||||||
  <script type='text/javascript' src='../js/views/timestamp_view.js' data-cover></script>
 | 
					  <script type='text/javascript' src='../js/views/timestamp_view.js' data-cover></script>
 | 
				
			||||||
  <script type='text/javascript' src='../js/views/message_view.js' data-cover></script>
 | 
					  <script type='text/javascript' src='../js/views/message_view.js' data-cover></script>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -136,27 +136,11 @@
 | 
				
			||||||
            assert.ok(message.isGroupUpdate());
 | 
					            assert.ok(message.isGroupUpdate());
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        it('checks if there are any key conflicts', function() {
 | 
					 | 
				
			||||||
            var messages = new Whisper.MessageCollection();
 | 
					 | 
				
			||||||
            var message = messages.add(attributes);
 | 
					 | 
				
			||||||
            assert.notOk(message.hasKeyConflicts());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            message = messages.add({errors: [{name: 'OutgoingIdentityKeyError'}]});
 | 
					 | 
				
			||||||
            assert.ok(message.hasKeyConflicts());
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it('returns a description of key conflicts', function() {
 | 
					 | 
				
			||||||
            var messages = new Whisper.MessageCollection();
 | 
					 | 
				
			||||||
            var message = messages.add({errors: [{name: 'IncomingIdentityKeyError'}]});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            assert.deepEqual(message.getKeyConflict(), {name: 'IncomingIdentityKeyError'});
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it('returns an accurate description', function() {
 | 
					        it('returns an accurate description', function() {
 | 
				
			||||||
            var messages = new Whisper.MessageCollection();
 | 
					            var messages = new Whisper.MessageCollection();
 | 
				
			||||||
            var message = messages.add(attributes);
 | 
					            var message = messages.add(attributes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            assert.equal(message.getDescription(), 'hi', 'If no group updates, key conflicts, or end session flags, return message body.');
 | 
					            assert.equal(message.getDescription(), 'hi', 'If no group updates or end session flags, return message body.');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            message = messages.add({group_update: {left: 'Alice'}});
 | 
					            message = messages.add({group_update: {left: 'Alice'}});
 | 
				
			||||||
            assert.equal(message.getDescription(), 'Alice left the group.', 'Notes one person leaving the group.');
 | 
					            assert.equal(message.getDescription(), 'Alice left the group.', 'Notes one person leaving the group.');
 | 
				
			||||||
| 
						 | 
					@ -175,10 +159,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            message = messages.add({flags: true});
 | 
					            message = messages.add({flags: true});
 | 
				
			||||||
            assert.equal(message.getDescription(), i18n('sessionEnded'));
 | 
					            assert.equal(message.getDescription(), i18n('sessionEnded'));
 | 
				
			||||||
 | 
					 | 
				
			||||||
            message = messages.add({type: 'incoming', errors: [{name: 'OutgoingIdentityKeyError'}]});
 | 
					 | 
				
			||||||
            assert.equal(message.getDescription(), i18n('incomingKeyConflict'));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        it('checks if it is end of the session', function() {
 | 
					        it('checks if it is end of the session', function() {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue