| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 /** @suppress {duplicate} */ | |
| 6 var remoting = remoting || {}; | |
| 7 | |
| 8 (function() { | |
| 9 | |
| 10 'use strict'; | |
| 11 | |
| 12 // Length of the various components of the access code in number of digits. | |
| 13 var SUPPORT_ID_LENGTH = 7; | |
| 14 var HOST_SECRET_LENGTH = 5; | |
| 15 var ACCESS_CODE_LENGTH = SUPPORT_ID_LENGTH + HOST_SECRET_LENGTH; | |
| 16 | |
| 17 /** | |
| 18 * @param {remoting.SessionConnector} sessionConnector | |
| 19 * @constructor | |
| 20 */ | |
| 21 remoting.It2MeConnectFlow = function(sessionConnector) { | |
| 22 /** @private */ | |
| 23 this.sessionConnector_ = sessionConnector; | |
| 24 /** @private */ | |
| 25 this.hostId_ = ''; | |
| 26 /** @private */ | |
| 27 this.passCode_ = ''; | |
| 28 | |
| 29 var form = document.getElementById('access-code-form'); | |
| 30 /** @private */ | |
| 31 this.accessCodeDialog_ = new remoting.InputDialog( | |
| 32 remoting.AppMode.CLIENT_UNCONNECTED, | |
| 33 form, | |
| 34 form.querySelector('#access-code-entry'), | |
| 35 form.querySelector('#cancel-access-code-button')); | |
| 36 }; | |
| 37 | |
| 38 | |
| 39 remoting.It2MeConnectFlow.prototype.start = function() { | |
| 40 var that = this; | |
| 41 | |
| 42 this.accessCodeDialog_.show().then(function(/** string */ accessCode) { | |
| 43 remoting.setMode(remoting.AppMode.CLIENT_CONNECTING); | |
| 44 return that.verifyAccessCode_(accessCode); | |
| 45 }).then(function() { | |
| 46 return remoting.identity.getToken(); | |
| 47 }).then(function(/** string */ token) { | |
| 48 return that.getHostInfo_(token); | |
| 49 }).then(function(/** !remoting.Xhr.Response */ response) { | |
| 50 return that.onHostInfo_(response); | |
| 51 }).then(function(/** remoting.Host */ host) { | |
| 52 that.sessionConnector_.connect( | |
| 53 remoting.Application.Mode.IT2ME, | |
| 54 host, | |
| 55 new remoting.CredentialsProvider({ accessCode: that.passCode_ })); | |
| 56 }).catch(function(/** remoting.Error */ error) { | |
| 57 if (error.hasTag(remoting.Error.Tag.CANCELLED)) { | |
| 58 remoting.setMode(remoting.AppMode.HOME); | |
| 59 } else { | |
| 60 var errorDiv = document.getElementById('connect-error-message'); | |
| 61 l10n.localizeElementFromTag(errorDiv, error.getTag()); | |
| 62 remoting.setMode(remoting.AppMode.CLIENT_CONNECT_FAILED_IT2ME); | |
| 63 } | |
| 64 }); | |
| 65 }; | |
| 66 | |
| 67 /** | |
| 68 * @param {string} accessCode | |
| 69 * @return {Promise} Promise that resolves if the access code is valid. | |
| 70 * @private | |
| 71 */ | |
| 72 remoting.It2MeConnectFlow.prototype.verifyAccessCode_ = function(accessCode) { | |
| 73 var normalizedAccessCode = accessCode.replace(/\s/g, ''); | |
| 74 if (normalizedAccessCode.length !== ACCESS_CODE_LENGTH) { | |
| 75 return Promise.reject(new remoting.Error( | |
| 76 remoting.Error.Tag.INVALID_ACCESS_CODE)); | |
| 77 } | |
| 78 | |
| 79 this.hostId_ = normalizedAccessCode.substring(0, SUPPORT_ID_LENGTH); | |
| 80 this.passCode_ = normalizedAccessCode; | |
| 81 | |
| 82 return Promise.resolve(); | |
| 83 }; | |
| 84 | |
| 85 /** | |
| 86 * Continues an IT2Me connection once an access token has been obtained. | |
| 87 * | |
| 88 * @param {string} token An OAuth2 access token. | |
| 89 * @return {Promise<!remoting.Xhr.Response>} | |
| 90 * @private | |
| 91 */ | |
| 92 remoting.It2MeConnectFlow.prototype.getHostInfo_ = function(token) { | |
| 93 var that = this; | |
| 94 return new remoting.Xhr({ | |
| 95 method: 'GET', | |
| 96 url: remoting.settings.DIRECTORY_API_BASE_URL + '/support-hosts/' + | |
| 97 encodeURIComponent(that.hostId_), | |
| 98 oauthToken: token | |
| 99 }).start(); | |
| 100 }; | |
| 101 | |
| 102 /** | |
| 103 * Continues an IT2Me connection once the host JID has been looked up. | |
| 104 * | |
| 105 * @param {!remoting.Xhr.Response} xhrResponse The server response to the | |
| 106 * support-hosts query. | |
| 107 * @return {!Promise<!remoting.Host>} Rejects on error. | |
| 108 * @private | |
| 109 */ | |
| 110 remoting.It2MeConnectFlow.prototype.onHostInfo_ = function(xhrResponse) { | |
| 111 if (xhrResponse.status == 200) { | |
| 112 var response = /** @type {{data: {jabberId: string, publicKey: string}}} */ | |
| 113 (base.jsonParseSafe(xhrResponse.getText())); | |
| 114 if (response && response.data && | |
| 115 response.data.jabberId && response.data.publicKey) { | |
| 116 var host = new remoting.Host(this.hostId_); | |
| 117 host.jabberId = response.data.jabberId; | |
| 118 host.publicKey = response.data.publicKey; | |
| 119 host.hostName = response.data.jabberId.split('/')[0]; | |
| 120 return Promise.resolve(host); | |
| 121 } else { | |
| 122 console.error('Invalid "support-hosts" response from server.'); | |
| 123 return Promise.reject(remoting.Error.unexpected()); | |
| 124 } | |
| 125 } else { | |
| 126 return Promise.reject(translateSupportHostsError(xhrResponse.status)); | |
| 127 } | |
| 128 }; | |
| 129 | |
| 130 /** | |
| 131 * TODO(jrw): Replace with remoting.Error.fromHttpStatus. | |
| 132 * @param {number} error An HTTP error code returned by the support-hosts | |
| 133 * endpoint. | |
| 134 * @return {remoting.Error} The equivalent remoting.Error code. | |
| 135 */ | |
| 136 function translateSupportHostsError(error) { | |
| 137 switch (error) { | |
| 138 case 0: return new remoting.Error(remoting.Error.Tag.NETWORK_FAILURE); | |
| 139 case 404: return new remoting.Error(remoting.Error.Tag.INVALID_ACCESS_CODE); | |
| 140 case 502: // No break | |
| 141 case 503: return new remoting.Error(remoting.Error.Tag.SERVICE_UNAVAILABLE); | |
| 142 default: return remoting.Error.unexpected(); | |
| 143 } | |
| 144 } | |
| 145 | |
| 146 })(); | |
| OLD | NEW |