OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 function initParams() { | 5 var BAD_AUTH_TOKEN = 'bad_token'; |
6 var hash; | |
7 var hashes = window.location.href.slice( | |
8 window.location.href.indexOf('?') + 1).split('&'); | |
9 | 6 |
10 // Prepopulate via cookies first. | 7 function init() { |
11 document.getElementById('xmpp_auth').value = getCookie('xmpp_auth'); | 8 updateLoginStatus(); |
12 document.getElementById('chromoting_auth').value = | |
13 getCookie('chromoting_auth'); | |
14 document.getElementById('username').value = getCookie('username'); | |
15 | 9 |
16 for(var i = 0; i < hashes.length; i++) | 10 // Defer getting the host list for a little bit so that we don't |
17 { | 11 // block the display of the extension popup. |
18 hash = hashes[i].split('='); | 12 window.setTimeout(listHosts, 100); |
19 if (hash[0] == 'xmpp_auth') { | 13 } |
20 document.getElementById('xmpp_auth').value = hash[1]; | |
21 setCookie('xmpp_auth', hash[1]); | |
22 | 14 |
23 } else if (hash[0] == "chromoting_auth") { | 15 // Update the login status region (at the bottom of the popup) with the |
24 document.getElementById('chromoting_auth').value = hash[1]; | 16 // current account and links to sign in/out. |
25 setCookie('chromoting_auth', hash[1]); | 17 function updateLoginStatus() { |
| 18 var username = getCookie('username'); |
26 | 19 |
27 } else if (hash[0] == 'username') { | 20 var loginDiv = document.getElementById('login_div'); |
28 document.getElementById('username').value = hash[1]; | 21 clear(loginDiv); |
29 setCookie('username', hash[1]); | |
30 | 22 |
31 } else if (hash[0] == 'password') { | 23 if (!username) { |
32 document.getElementById('password').value = hash[1]; | 24 var signinLink = document.createElement('a'); |
| 25 signinLink.setAttribute('href', |
| 26 "javascript:window.open('login.html', 'Sign In', " + |
| 27 "'width=400,height=200,scrollbars=no'); return false;"); |
| 28 signinLink.appendChild(document.createTextNode('Sign In')); |
| 29 loginDiv.appendChild(signinLink); |
| 30 } else { |
| 31 var email = document.createElement('span'); |
| 32 email.setAttribute('class', 'login_email'); |
| 33 email.appendChild(document.createTextNode(username)); |
| 34 loginDiv.appendChild(email); |
33 | 35 |
34 } else if (hash[0] == 'host_jid') { | 36 loginDiv.appendChild(document.createTextNode(' | ')); |
35 document.getElementById('host_jid').value = hash[1]; | 37 |
36 } | 38 var signoutLink = document.createElement('a'); |
| 39 signoutLink.setAttribute('href', 'javascript:logout(this.form);'); |
| 40 signoutLink.appendChild(document.createTextNode('Sign Out')); |
| 41 loginDiv.appendChild(signoutLink); |
37 } | 42 } |
38 } | 43 } |
39 | 44 |
40 function findHosts(form) { | 45 // Sign out the current user by erasing the auth cookies. |
41 // If either cookie is missing, login first. | 46 function logout(form) { |
42 if (getCookie('chromoting_auth') == null || | 47 setCookie('username', '', 100); |
43 getCookie('xmpp_auth') == null) { | 48 setCookie('chromoting_auth', '', 100); |
44 doLogin(form.username.value, form.username.password, doListHosts); | 49 setCookie('xmpp_auth', '', 100); |
| 50 |
| 51 updateLoginStatus(); |
| 52 listHosts(); |
| 53 } |
| 54 |
| 55 function login(form) { |
| 56 var status = document.getElementById('login_status'); |
| 57 clear(status); |
| 58 doLogin(form.username.value, form.password.value, checkLogin); |
| 59 } |
| 60 |
| 61 // Check to see if the login was successful. |
| 62 function checkLogin() { |
| 63 var username = getCookie('username'); |
| 64 var cauth = getCookie('chromoting_auth'); |
| 65 var xauth = getCookie('xmpp_auth'); |
| 66 |
| 67 // Verify login and show login status. |
| 68 var status = document.getElementById('login_status'); |
| 69 if (cauth == BAD_AUTH_TOKEN || xauth == BAD_AUTH_TOKEN) { |
| 70 appendMessage(status, '', 'Sign in failed!'); |
| 71 if (username) { |
| 72 setCookie('username', '', 100); |
| 73 } |
45 } else { | 74 } else { |
46 doListHosts(); | 75 appendMessage(status, '', 'Successfully signed in as ' + username); |
47 } | 76 } |
48 } | 77 } |
49 | 78 |
50 function login(form) { | 79 function doLogin(username, password, done) { |
51 doLogin(form.username.value, form.password.value); | 80 // Don't call |done| callback until both login requests have completed. |
52 } | 81 var count = 2; |
53 | 82 var barrier = function() { |
54 function extractAuthToken(message) { | 83 count--; |
55 var lines = message.split('\n'); | 84 if (done && count == 0) { |
56 for (var i = 0; i < lines.length; i++) { | 85 done(); |
57 if (lines[i].match('^Auth=.*')) { | |
58 return lines[i].split('=')[1]; | |
59 } | 86 } |
60 } | 87 } |
61 | 88 setCookie('username', username, 100); |
62 console.log('Could not parse auth token in : "' + message + '"'); | 89 doGaiaLogin(username, password, 'chromoting', |
63 return 'bad_token'; | 90 function(cAuthToken) { |
| 91 setCookie('chromoting_auth', cAuthToken, 100); |
| 92 barrier(); |
| 93 }); |
| 94 doGaiaLogin(username, password, 'chromiumsync', |
| 95 function(xAuthToken) { |
| 96 setCookie('xmpp_auth', xAuthToken, 100); |
| 97 barrier(); |
| 98 }); |
64 } | 99 } |
65 | 100 |
66 function doGaiaLogin(username, password, service, done) { | 101 function doGaiaLogin(username, password, service, done) { |
67 var xhr = new XMLHttpRequest(); | 102 var xhr = new XMLHttpRequest(); |
68 xhr.open('POST', 'https://www.google.com/accounts/ClientLogin', true); | 103 xhr.open('POST', 'https://www.google.com/accounts/ClientLogin', true); |
69 xhr.onreadystatechange = function() { | 104 xhr.onreadystatechange = function() { |
70 if (xhr.readyState != 4) { | 105 if (xhr.readyState != 4) { |
71 return; | 106 return; |
72 } | 107 } |
73 if (xhr.status = 200) { | 108 if (xhr.status = 200) { |
74 done(extractAuthToken(xhr.responseText)); | 109 done(extractAuthToken(xhr.responseText)); |
75 } else { | 110 } else { |
76 console.log('Bad status on auth: ' + xhr.statusText); | 111 console.log('Bad status on auth: ' + xhr.statusText); |
77 } | 112 } |
78 }; | 113 }; |
79 | 114 |
80 xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); | 115 xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); |
81 xhr.send('accountType=HOSTED_OR_GOOGLE&Email=' + username + '&Passwd=' + | 116 xhr.send('accountType=HOSTED_OR_GOOGLE&Email=' + username + '&Passwd=' + |
82 password + '&service=' + service + '&source=chromoclient'); | 117 password + '&service=' + service + '&source=chromoclient'); |
83 } | 118 } |
84 | 119 |
85 function doLogin(username, password, done) { | 120 function extractAuthToken(message) { |
86 var count = 2; | 121 var lines = message.split('\n'); |
87 var barrier = function() { | 122 for (var i = 0; i < lines.length; i++) { |
88 count--; | 123 if (lines[i].match('^Auth=.*')) { |
89 if (done && count == 0) { | 124 return lines[i].split('=')[1]; |
90 done(); | |
91 } | 125 } |
92 } | 126 } |
93 setCookie('username', username, 100); | 127 |
94 doGaiaLogin(username, password, 'chromoting', | 128 console.log('Could not parse auth token in : "' + message + '"'); |
95 function(token1) { | 129 return BAD_AUTH_TOKEN; |
96 setCookie('chromoting_auth', token1, 100); | |
97 document.getElementById('chromoting_auth').value = token1; | |
98 barrier(); | |
99 }); | |
100 doGaiaLogin(username, password, 'chromiumsync', | |
101 function(token) { | |
102 setCookie('xmpp_auth', token, 100); | |
103 document.getElementById('xmpp_auth').value = token; | |
104 barrier(); | |
105 }); | |
106 } | 130 } |
107 | 131 |
108 function doListHosts() { | 132 // Open a chromoting connection in a new tab. |
| 133 function openChromotingTab(host_jid) { |
| 134 var background = chrome.extension.getBackgroundPage(); |
| 135 background.openChromotingTab(host_jid); |
| 136 } |
| 137 |
| 138 // Erase the content of the specified element. |
| 139 function clear(e) { |
| 140 e.innerHTML = ''; |
| 141 } |
| 142 |
| 143 // Clear out the specified element and show the message to the user. |
| 144 function displayMessage(e, classname, message) { |
| 145 clear(e); |
| 146 appendMessage(e, classname, message); |
| 147 } |
| 148 |
| 149 // Append the message text to the specified element. |
| 150 function appendMessage(e, classname, message) { |
| 151 var p = document.createElement('p'); |
| 152 if (classname.length != 0) { |
| 153 p.setAttribute('class', classname); |
| 154 } |
| 155 |
| 156 p.appendChild(document.createTextNode(message)); |
| 157 |
| 158 e.appendChild(p); |
| 159 } |
| 160 |
| 161 function listHosts() { |
| 162 var username = getCookie('username'); |
| 163 |
| 164 var hostlistDiv = document.getElementById('hostlist_div'); |
| 165 if (!username) { |
| 166 displayMessage(hostlistDiv, 'message', |
| 167 'Please sign in to see a list of available hosts.'); |
| 168 return; |
| 169 } |
| 170 |
109 var xhr = new XMLHttpRequest(); | 171 var xhr = new XMLHttpRequest(); |
110 var token = getCookie('chromoting_auth'); | 172 var token = getCookie('chromoting_auth'); |
111 | 173 |
112 // Unhide host list. | 174 // Unhide host list. |
113 var hostlist_div = document.getElementById('hostlist_div'); | 175 hostlistDiv.style.display = "block"; |
114 hostlist_div.style.display = "block"; | |
115 | 176 |
116 xhr.onreadystatechange = function() { | 177 xhr.onreadystatechange = function() { |
117 if (xhr.readyState == 1) { | 178 if (xhr.readyState == 1) { |
118 hostlist_div.appendChild(document.createTextNode('Finding..')); | 179 displayMessage(hostlistDiv, 'message', 'Loading host list for ' + |
119 hostlist_div.appendChild(document.createElement('br')); | 180 username); |
120 } | 181 } |
121 if (xhr.readyState != 4) { | 182 if (xhr.readyState != 4) { |
122 return; | 183 return; |
123 } | 184 } |
124 if (xhr.status == 200) { | 185 if (xhr.status == 200) { |
125 parsed_response = JSON.parse(xhr.responseText); | 186 var parsed_response = JSON.parse(xhr.responseText); |
126 hostlist_div.appendChild(document.createTextNode('--Found Hosts--')); | |
127 hostlist_div.appendChild(document.createElement('br')); | |
128 appendHostLinks(parsed_response.data.items); | 187 appendHostLinks(parsed_response.data.items); |
129 } else { | 188 } else { |
130 console.log('bad status on host list query: "' + xhr.status + ' ' + | 189 var errorResponse = JSON.parse(xhr.responseText); |
131 xhr.statusText); | 190 |
132 hostlist_div.appendChild(document.createTextNode('!! Failed !!. :\'(')); | 191 console.log('Error: Bad status on host list query: "' + |
| 192 xhr.status + ' ' + xhr.statusText); |
| 193 console.log('Error code ' + errorResponse.error.code); |
| 194 console.log('Error message ' + errorResponse.error.message); |
| 195 |
| 196 clear(hostlistDiv); |
| 197 appendMessage(hostlistDiv, 'message', |
| 198 'Unable to load host list for ' + username + '. ' + |
| 199 'Please try again later.'); |
| 200 appendMessage(hostlistDiv, 'message', |
| 201 'Error code: ' + errorResponse.error.code); |
| 202 appendMessage(hostlistDiv, 'message', |
| 203 'Message: ' + errorResponse.error.message); |
133 } | 204 } |
134 }; | 205 }; |
135 | 206 |
136 xhr.open('GET', 'https://www.googleapis.com/chromoting/v1/@me/hosts'); | 207 xhr.open('GET', 'https://www.googleapis.com/chromoting/v1/@me/hosts'); |
137 xhr.setRequestHeader('Content-Type', 'text/plain;charset=UTF-8'); | 208 xhr.setRequestHeader('Content-Type', 'text/plain;charset=UTF-8'); |
138 xhr.setRequestHeader('Authorization', 'GoogleLogin auth=' + token); | 209 xhr.setRequestHeader('Authorization', 'GoogleLogin auth=' + token); |
139 xhr.send(null); | 210 xhr.send(null); |
140 } | 211 } |
141 | 212 |
| 213 // Populate the 'hostlist_div' element with the list of hosts for this user. |
142 function appendHostLinks(hostlist) { | 214 function appendHostLinks(hostlist) { |
143 // A host link entry should look like: | 215 var hostlistDiv = document.getElementById('hostlist_div'); |
144 // - Host: <a onclick="openChromotingTab(host_jid); return false;"> | |
145 // NAME (JID) </a> <br /> | |
146 var host; | |
147 var host_link; | |
148 var hostlist_div = document.getElementById('hostlist_div'); | |
149 | 216 |
150 // Cleanup the div | 217 // Clear the div before adding the host info. |
151 hostlist_div.innerHTML = ""; | 218 clear(hostlistDiv); |
152 | 219 |
153 // Add the hosts. | 220 // Add the hosts. |
154 for(var i = 0; i < hostlist.length; ++i) { | 221 // TODO(garykac): We should have some sort of MRU list here. |
155 hostlist_div.appendChild(document.createTextNode('-*- Host: ')); | 222 // First, add all of the connected hosts. |
156 host = hostlist[i]; | 223 for (var i = 0; i < hostlist.length; ++i) { |
157 host_link = document.createElement('a'); | 224 if (hostlist[i].status == "ONLINE") { |
158 // TODO(ajwong): Reenable once we figure out how to control a new tab. | 225 hostlistDiv.appendChild(addHostInfo(hostlist[i])); |
159 host_link.setAttribute('onclick', 'openChromotingTab(\'' + host.jabberId + | 226 } |
160 '\'); return false;'); | 227 } |
161 host_link.setAttribute('href', 'javascript:void(0)'); | 228 // Add non-online hosts at the end. |
162 host_link.appendChild( | 229 for (var i = 0; i < hostlist.length; ++i) { |
163 document.createTextNode(host.hostName + ' (' + host.hostId + ', ' + | 230 if (hostlist[i].status != "ONLINE") { |
164 host.jabberId + ')')); | 231 hostlistDiv.appendChild(addHostInfo(hostlist[i])); |
165 hostlist_div.appendChild(host_link); | 232 } |
166 hostlist_div.appendChild(document.createElement('br')); | |
167 } | 233 } |
168 } | 234 } |
169 | 235 |
170 function connect(form) { | 236 // Create a single host description element. |
171 openChromotingTab(form.host_jid); | 237 function addHostInfo(host) { |
| 238 var hostEntry = document.createElement('div'); |
| 239 hostEntry.setAttribute('class', 'hostentry'); |
| 240 |
| 241 var hostIcon = document.createElement('img'); |
| 242 hostIcon.setAttribute('src', 'machine.png'); |
| 243 hostIcon.setAttribute('class', 'hosticon'); |
| 244 hostEntry.appendChild(hostIcon); |
| 245 |
| 246 var span = document.createElement('span'); |
| 247 span.setAttribute('class', 'connect'); |
| 248 var connect = document.createElement('input'); |
| 249 connect.setAttribute('type', 'button'); |
| 250 connect.setAttribute('value', 'Connect'); |
| 251 connect.setAttribute('onclick', 'openChromotingTab(\'' + host.jabberId + |
| 252 '\'); return false;'); |
| 253 span.appendChild(connect); |
| 254 hostEntry.appendChild(span); |
| 255 |
| 256 var hostName = document.createElement('p'); |
| 257 hostName.setAttribute('class', 'hostname'); |
| 258 hostName.appendChild(document.createTextNode(host.hostName)); |
| 259 hostEntry.appendChild(hostName); |
| 260 |
| 261 var hostStatus = document.createElement('p'); |
| 262 hostStatus.setAttribute('class', 'hostinfo hoststatus_' + |
| 263 ((host.status == 'ONLINE') ? 'good' : 'bad')); |
| 264 hostStatus.appendChild(document.createTextNode(host.status)); |
| 265 hostEntry.appendChild(hostStatus); |
| 266 |
| 267 var hostInfo = document.createElement('p'); |
| 268 hostInfo.setAttribute('class', 'hostinfo'); |
| 269 hostInfo.appendChild(document.createTextNode(host.jabberId)); |
| 270 hostEntry.appendChild(hostInfo); |
| 271 |
| 272 return hostEntry; |
172 } | 273 } |
173 | |
174 function openChromotingTab(host_jid) { | |
175 var background = chrome.extension.getBackgroundPage(); | |
176 background.openChromotingTab(host_jid); | |
177 } | |
178 | |
179 function setAuthCookies(form) { | |
180 var now = new Date(); | |
181 now.setTime(now.getTime() + 1000 * 60 * 60 * 24 * 365) | |
182 | |
183 setCookie('xmpp_auth', form.xmpp_auth.value, 100); | |
184 setCookie('chromoting_auth', form.chromoting_auth.value, 100); | |
185 } | |
OLD | NEW |