| 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 |