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 |