| 
									
										
										
										
											2018-07-06 17:48:14 -07:00
										 |  |  | /* global Whisper, textsecure, QRCode, dcodeIO, libsignal, i18n, _ */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* eslint-disable more/no-then */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // eslint-disable-next-line func-names
 | 
					
						
							| 
									
										
										
										
											2018-04-27 17:25:04 -04:00
										 |  |  | (function() { | 
					
						
							|  |  |  |   'use strict'; | 
					
						
							| 
									
										
										
										
											2018-07-06 17:48:14 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-27 17:25:04 -04:00
										 |  |  |   window.Whisper = window.Whisper || {}; | 
					
						
							| 
									
										
										
										
											2015-02-26 18:10:04 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-27 17:25:04 -04:00
										 |  |  |   Whisper.KeyVerificationPanelView = Whisper.View.extend({ | 
					
						
							|  |  |  |     className: 'key-verification panel', | 
					
						
							|  |  |  |     templateName: 'key-verification', | 
					
						
							|  |  |  |     events: { | 
					
						
							|  |  |  |       'click button.verify': 'toggleVerified', | 
					
						
							|  |  |  |     }, | 
					
						
							| 
									
										
										
										
											2018-07-06 17:48:14 -07:00
										 |  |  |     initialize(options) { | 
					
						
							| 
									
										
										
										
											2018-04-27 17:25:04 -04:00
										 |  |  |       this.ourNumber = textsecure.storage.user.getNumber(); | 
					
						
							| 
									
										
										
										
											2020-03-05 13:14:58 -08:00
										 |  |  |       this.ourUuid = textsecure.storage.user.getUuid(); | 
					
						
							| 
									
										
										
										
											2018-04-27 17:25:04 -04:00
										 |  |  |       if (options.newKey) { | 
					
						
							|  |  |  |         this.theirKey = options.newKey; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2017-06-10 12:18:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-09 16:35:09 -07:00
										 |  |  |       this.loadTheirKey(); | 
					
						
							|  |  |  |       this.loadOurKey(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       this.render(); | 
					
						
							|  |  |  |       if (options.onLoad) { | 
					
						
							| 
									
										
										
										
											2019-09-05 11:18:44 -07:00
										 |  |  |         options.onLoad(this); | 
					
						
							| 
									
										
										
										
											2019-08-09 16:35:09 -07:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-06 17:48:14 -07:00
										 |  |  |       this.loadKeys().then(() => { | 
					
						
							|  |  |  |         this.listenTo(this.model, 'change', this.render); | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2018-04-27 17:25:04 -04:00
										 |  |  |     }, | 
					
						
							| 
									
										
										
										
											2019-08-09 16:35:09 -07:00
										 |  |  |     async loadKeys() { | 
					
						
							|  |  |  |       await this.generateSecurityNumber(); | 
					
						
							|  |  |  |       this.render(); | 
					
						
							| 
									
										
										
										
											2018-04-27 17:25:04 -04:00
										 |  |  |     }, | 
					
						
							| 
									
										
										
										
											2018-07-06 17:48:14 -07:00
										 |  |  |     makeQRCode() { | 
					
						
							| 
									
										
										
										
											2018-04-27 17:25:04 -04:00
										 |  |  |       // 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.ourKey).toString('base64') | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |     }, | 
					
						
							| 
									
										
										
										
											2018-07-06 17:48:14 -07:00
										 |  |  |     loadTheirKey() { | 
					
						
							| 
									
										
										
										
											2020-03-05 13:14:58 -08:00
										 |  |  |       const item = textsecure.storage.protocol.getIdentityRecord( | 
					
						
							|  |  |  |         this.model.get('id') | 
					
						
							|  |  |  |       ); | 
					
						
							| 
									
										
										
										
											2019-08-09 16:35:09 -07:00
										 |  |  |       this.theirKey = item ? item.publicKey : null; | 
					
						
							| 
									
										
										
										
											2018-04-27 17:25:04 -04:00
										 |  |  |     }, | 
					
						
							| 
									
										
										
										
											2018-07-06 17:48:14 -07:00
										 |  |  |     loadOurKey() { | 
					
						
							| 
									
										
										
										
											2020-03-05 13:14:58 -08:00
										 |  |  |       const item = textsecure.storage.protocol.getIdentityRecord( | 
					
						
							|  |  |  |         this.ourUuid || this.ourNumber | 
					
						
							|  |  |  |       ); | 
					
						
							| 
									
										
										
										
											2019-08-09 16:35:09 -07:00
										 |  |  |       this.ourKey = item ? item.publicKey : null; | 
					
						
							| 
									
										
										
										
											2018-04-27 17:25:04 -04:00
										 |  |  |     }, | 
					
						
							| 
									
										
										
										
											2018-07-06 17:48:14 -07:00
										 |  |  |     generateSecurityNumber() { | 
					
						
							| 
									
										
										
										
											2018-04-27 17:25:04 -04:00
										 |  |  |       return new libsignal.FingerprintGenerator(5200) | 
					
						
							| 
									
										
										
										
											2020-03-05 13:14:58 -08:00
										 |  |  |         .createFor( | 
					
						
							|  |  |  |           // TODO: we cannot use UUIDs for safety numbers yet
 | 
					
						
							|  |  |  |           // this.ourUuid || this.ourNumber,
 | 
					
						
							|  |  |  |           this.ourNumber, | 
					
						
							|  |  |  |           this.ourKey, | 
					
						
							|  |  |  |           // TODO: we cannot use UUIDs for safety numbers yet
 | 
					
						
							|  |  |  |           // this.model.get('uuid') || this.model.get('e164'),
 | 
					
						
							|  |  |  |           this.model.get('e164'), | 
					
						
							|  |  |  |           this.theirKey | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2018-07-06 17:48:14 -07:00
										 |  |  |         .then(securityNumber => { | 
					
						
							|  |  |  |           this.securityNumber = securityNumber; | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2018-04-27 17:25:04 -04:00
										 |  |  |     }, | 
					
						
							| 
									
										
										
										
											2018-07-06 17:48:14 -07:00
										 |  |  |     onSafetyNumberChanged() { | 
					
						
							| 
									
										
										
										
											2018-04-27 17:25:04 -04:00
										 |  |  |       this.model.getProfiles().then(this.loadKeys.bind(this)); | 
					
						
							| 
									
										
										
										
											2017-07-11 15:54:46 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-06 17:48:14 -07:00
										 |  |  |       const dialog = new Whisper.ConfirmationDialogView({ | 
					
						
							| 
									
										
										
										
											2018-04-27 17:25:04 -04:00
										 |  |  |         message: i18n('changedRightAfterVerify', [ | 
					
						
							|  |  |  |           this.model.getTitle(), | 
					
						
							|  |  |  |           this.model.getTitle(), | 
					
						
							|  |  |  |         ]), | 
					
						
							|  |  |  |         hideCancel: true, | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2017-07-11 15:54:46 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-27 17:25:04 -04:00
										 |  |  |       dialog.$el.insertBefore(this.el); | 
					
						
							|  |  |  |       dialog.focusCancel(); | 
					
						
							|  |  |  |     }, | 
					
						
							| 
									
										
										
										
											2018-07-06 17:48:14 -07:00
										 |  |  |     toggleVerified() { | 
					
						
							| 
									
										
										
										
											2018-04-27 17:25:04 -04:00
										 |  |  |       this.$('button.verify').attr('disabled', true); | 
					
						
							|  |  |  |       this.model | 
					
						
							|  |  |  |         .toggleVerified() | 
					
						
							| 
									
										
										
										
											2018-07-06 17:48:14 -07:00
										 |  |  |         .catch(result => { | 
					
						
							|  |  |  |           if (result instanceof Error) { | 
					
						
							|  |  |  |             if (result.name === 'OutgoingIdentityKeyError') { | 
					
						
							|  |  |  |               this.onSafetyNumberChanged(); | 
					
						
							| 
									
										
										
										
											2018-04-27 17:25:04 -04:00
										 |  |  |             } else { | 
					
						
							| 
									
										
										
										
											2018-07-21 12:00:08 -07:00
										 |  |  |               window.log.error( | 
					
						
							|  |  |  |                 'failed to toggle verified:', | 
					
						
							|  |  |  |                 result && result.stack ? result.stack : result | 
					
						
							|  |  |  |               ); | 
					
						
							| 
									
										
										
										
											2018-07-06 17:48:14 -07:00
										 |  |  |             } | 
					
						
							|  |  |  |           } else { | 
					
						
							|  |  |  |             const keyError = _.some( | 
					
						
							|  |  |  |               result.errors, | 
					
						
							|  |  |  |               error => error.name === 'OutgoingIdentityKeyError' | 
					
						
							|  |  |  |             ); | 
					
						
							|  |  |  |             if (keyError) { | 
					
						
							|  |  |  |               this.onSafetyNumberChanged(); | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |               _.forEach(result.errors, error => { | 
					
						
							| 
									
										
										
										
											2018-07-21 12:00:08 -07:00
										 |  |  |                 window.log.error( | 
					
						
							|  |  |  |                   'failed to toggle verified:', | 
					
						
							|  |  |  |                   error && error.stack ? error.stack : error | 
					
						
							|  |  |  |                 ); | 
					
						
							| 
									
										
										
										
											2018-04-27 17:25:04 -04:00
										 |  |  |               }); | 
					
						
							| 
									
										
										
										
											2016-09-18 15:16:39 -07:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2018-07-06 17:48:14 -07:00
										 |  |  |           } | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |         .then(() => { | 
					
						
							|  |  |  |           this.$('button.verify').removeAttr('disabled'); | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2018-04-27 17:25:04 -04:00
										 |  |  |     }, | 
					
						
							| 
									
										
										
										
											2018-07-06 17:48:14 -07:00
										 |  |  |     render_attributes() { | 
					
						
							|  |  |  |       const s = this.securityNumber; | 
					
						
							|  |  |  |       const chunks = []; | 
					
						
							| 
									
										
										
										
											2019-08-09 16:35:09 -07:00
										 |  |  |       if (s) { | 
					
						
							|  |  |  |         for (let i = 0; i < s.length; i += 5) { | 
					
						
							|  |  |  |           chunks.push(s.substring(i, i + 5)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         for (let i = 0; i < 12; i += 1) { | 
					
						
							|  |  |  |           chunks.push('XXXXX'); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-04-27 17:25:04 -04:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2018-07-06 17:48:14 -07:00
										 |  |  |       const name = this.model.getTitle(); | 
					
						
							|  |  |  |       const yourSafetyNumberWith = i18n( | 
					
						
							|  |  |  |         'yourSafetyNumberWith', | 
					
						
							|  |  |  |         this.model.getTitle() | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |       const isVerified = this.model.isVerified(); | 
					
						
							|  |  |  |       const verifyButton = isVerified ? i18n('unverify') : i18n('verify'); | 
					
						
							|  |  |  |       const verifiedStatus = isVerified | 
					
						
							| 
									
										
										
										
											2018-04-27 17:25:04 -04:00
										 |  |  |         ? i18n('isVerified', name) | 
					
						
							|  |  |  |         : i18n('isNotVerified', name); | 
					
						
							| 
									
										
										
										
											2017-06-10 12:18:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-27 17:25:04 -04:00
										 |  |  |       return { | 
					
						
							|  |  |  |         learnMore: i18n('learnMore'), | 
					
						
							|  |  |  |         theirKeyUnknown: i18n('theirIdentityUnknown'), | 
					
						
							| 
									
										
										
										
											2018-07-06 17:48:14 -07:00
										 |  |  |         yourSafetyNumberWith, | 
					
						
							| 
									
										
										
										
											2018-04-27 17:25:04 -04:00
										 |  |  |         verifyHelp: i18n('verifyHelp', this.model.getTitle()), | 
					
						
							| 
									
										
										
										
											2018-07-06 17:48:14 -07:00
										 |  |  |         verifyButton, | 
					
						
							| 
									
										
										
										
											2018-04-27 17:25:04 -04:00
										 |  |  |         hasTheirKey: this.theirKey !== undefined, | 
					
						
							| 
									
										
										
										
											2018-07-06 17:48:14 -07:00
										 |  |  |         chunks, | 
					
						
							|  |  |  |         isVerified, | 
					
						
							|  |  |  |         verifiedStatus, | 
					
						
							| 
									
										
										
										
											2018-04-27 17:25:04 -04:00
										 |  |  |       }; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2015-02-26 18:10:04 -08:00
										 |  |  | })(); |