/* 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); };