| /* Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| /** |
| * @fileoverview |
| * A class that loads a WCS IQ client and constructs remoting.wcs as a |
| * wrapper for it. |
| */ |
| |
| 'use strict'; |
| |
| /** @suppress {duplicate} */ |
| var remoting = remoting || {}; |
| |
| /** @type {remoting.WcsLoader} */ |
| remoting.wcsLoader = null; |
| |
| /** |
| * @constructor |
| */ |
| remoting.WcsLoader = function() { |
| /** |
| * The WCS client that will be downloaded. This variable is initialized (via |
| * remoting.wcsLoader) by the downloaded Javascript. |
| * @type {remoting.WcsIqClient} |
| */ |
| this.wcsIqClient = null; |
| }; |
| |
| /** |
| * The id of the script node. |
| * @type {string} |
| * @private |
| */ |
| remoting.WcsLoader.prototype.SCRIPT_NODE_ID_ = 'wcs-script-node'; |
| |
| /** |
| * Starts loading the WCS IQ client. |
| * |
| * When it's loaded, construct remoting.wcs as a wrapper for it. |
| * When the WCS connection is ready, or on error, call |onReady| or |onError|, |
| * respectively. |
| * |
| * @param {string} token An OAuth2 access token. |
| * @param {function(string): void} onReady The callback function, called with |
| * a client JID when WCS has been loaded. |
| * @param {function(remoting.Error):void} onError Function to invoke with an |
| * error code on failure. |
| * @return {void} Nothing. |
| */ |
| remoting.WcsLoader.prototype.start = function(token, onReady, onError) { |
| var node = document.getElementById(this.SCRIPT_NODE_ID_); |
| if (node) { |
| console.error('Multiple calls to WcsLoader.start are not allowed.'); |
| onError(remoting.Error.UNEXPECTED); |
| return; |
| } |
| |
| // Create a script node to load the WCS driver. |
| node = document.createElement('script'); |
| node.id = this.SCRIPT_NODE_ID_; |
| node.src = remoting.settings.TALK_GADGET_URL + 'iq?access_token=' + token; |
| node.type = 'text/javascript'; |
| document.body.insertBefore(node, document.body.firstChild); |
| |
| /** @type {remoting.WcsLoader} */ |
| var that = this; |
| var onLoad = function() { |
| that.constructWcs_(token, onReady); |
| }; |
| var onLoadError = function(event) { |
| // The DOM Event object has no detail on the nature of the error, so try to |
| // validate the token to get a better idea. |
| /** @param {remoting.Error} error Error code. */ |
| var onValidateError = function(error) { |
| var typedNode = /** @type {Element} */ (node); |
| typedNode.parentNode.removeChild(node); |
| onError(error); |
| }; |
| var onValidateOk = function() { |
| // We can reach the authentication server and validate the token. Either |
| // there's something wrong with the talkgadget service, or there is a |
| // cookie problem. Only the cookie problem can be fixed by the user, so |
| // suggest that fix. |
| onValidateError(remoting.Error.AUTHENTICATION_FAILED); |
| } |
| that.validateToken(token, onValidateOk, onValidateError); |
| } |
| node.addEventListener('load', onLoad, false); |
| node.addEventListener('error', onLoadError, false); |
| }; |
| |
| /** |
| * Constructs the remoting.wcs object. |
| * |
| * @param {string} token An OAuth2 access token. |
| * @param {function(string): void} onReady The callback function, called with |
| * an OAuth2 access token when WCS has been loaded. |
| * @return {void} Nothing. |
| * @private |
| */ |
| remoting.WcsLoader.prototype.constructWcs_ = function(token, onReady) { |
| remoting.wcs = new remoting.Wcs( |
| remoting.wcsLoader.wcsIqClient, token, onReady); |
| }; |
| |
| /** |
| * Validates an OAuth2 access token. |
| * |
| * @param {string} token The access token. |
| * @param {function():void} onOk Callback to invoke if the token is valid. |
| * @param {function(remoting.Error):void} onError Function to invoke with an |
| * error code on failure. |
| * @return {void} Nothing. |
| */ |
| remoting.WcsLoader.prototype.validateToken = function(token, onOk, onError) { |
| /** @type {XMLHttpRequest} */ |
| var xhr = new XMLHttpRequest(); |
| xhr.onreadystatechange = function() { |
| if (xhr.readyState != 4) { |
| return; |
| } |
| if (xhr.status == 200) { |
| onOk(); |
| } else { |
| var error = remoting.Error.AUTHENTICATION_FAILED; |
| switch (xhr.status) { |
| case 0: |
| error = remoting.Error.NETWORK_FAILURE; |
| break; |
| case 502: // No break |
| case 503: |
| error = remoting.Error.SERVICE_UNAVAILABLE; |
| break; |
| } |
| onError(error); |
| } |
| }; |
| var parameters = '?access_token=' + encodeURIComponent(token); |
| xhr.open('GET', |
| remoting.settings.OAUTH2_API_BASE_URL + '/v1/tokeninfo' + parameters, |
| true); |
| xhr.send(null); |
| }; |