summaryrefslogtreecommitdiffstats
path: root/remoting/webapp
diff options
context:
space:
mode:
authorjamiewalch@google.com <jamiewalch@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-20 01:16:04 +0000
committerjamiewalch@google.com <jamiewalch@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-20 01:16:04 +0000
commitcdf68094a5f12691d5cfc3e4135787e45a16795a (patch)
tree4d7d405ac945dc877765b9e8362fafe53ca0a6ae /remoting/webapp
parent6b1d22a7653dcd9b0b26206133b1afb3b8372f89 (diff)
downloadchromium_src-cdf68094a5f12691d5cfc3e4135787e45a16795a.zip
chromium_src-cdf68094a5f12691d5cfc3e4135787e45a16795a.tar.gz
chromium_src-cdf68094a5f12691d5cfc3e4135787e45a16795a.tar.bz2
This CL cleans up error handling when fetching the user's email address. We do this once per login, immediately after getting the OAuth2 refresh token, so failures should be rare, but we've had at least one report of problems, and the current failure mode is to tell the user that the service is unavailable. Specifically, this CL:
* Adds an onError callback so that the caller can be notified of exactly what went wrong. * Makes sure that a valid email address exists before allowing the user to interact with the app (the alternative is to make accessing the email address asynchronous everywhere, which gets messy very quickly). BUG=137713 TEST= Review URL: https://chromiumcodereview.appspot.com/10807026 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@147588 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/webapp')
-rw-r--r--remoting/webapp/client_screen.js6
-rw-r--r--remoting/webapp/event_handlers.js2
-rw-r--r--remoting/webapp/host_list.js4
-rw-r--r--remoting/webapp/host_screen.js2
-rw-r--r--remoting/webapp/host_setup_dialog.js2
-rw-r--r--remoting/webapp/main.html8
-rw-r--r--remoting/webapp/oauth2.js38
-rw-r--r--remoting/webapp/remoting.js68
8 files changed, 55 insertions, 75 deletions
diff --git a/remoting/webapp/client_screen.js b/remoting/webapp/client_screen.js
index 808c825..9cdd87e 100644
--- a/remoting/webapp/client_screen.js
+++ b/remoting/webapp/client_screen.js
@@ -71,7 +71,7 @@ remoting.currentConnectionType = null;
remoting.connectIt2Me = function() {
remoting.currentConnectionType = remoting.ConnectionType.It2Me;
remoting.WcsLoader.load(connectIt2MeWithAccessToken_,
- remoting.defaultOAuthErrorHandler);
+ remoting.showErrorMessage);
};
/**
@@ -336,7 +336,7 @@ function startSession_() {
}
};
remoting.oauth2.callWithToken(createPluginAndConnect,
- remoting.defaultOAuthErrorHandler);
+ remoting.showErrorMessage);
}
/**
@@ -510,7 +510,7 @@ remoting.connectMe2MeWithPin = function() {
host.hostName;
remoting.WcsLoader.load(connectMe2MeWithAccessToken_,
- remoting.defaultOAuthErrorHandler);
+ remoting.showErrorMessage);
};
/**
diff --git a/remoting/webapp/event_handlers.js b/remoting/webapp/event_handlers.js
index 338bd1e..7f13e05 100644
--- a/remoting/webapp/event_handlers.js
+++ b/remoting/webapp/event_handlers.js
@@ -20,7 +20,7 @@ function onLoad() {
function(token) {
remoting.setMode(remoting.AppMode.CLIENT_UNCONNECTED);
},
- remoting.defaultOAuthErrorHandler);
+ remoting.showErrorMessage);
};
var goFinishedIt2Me = function() {
if (remoting.currentMode == remoting.AppMode.CLIENT_CONNECT_FAILED_IT2ME) {
diff --git a/remoting/webapp/host_list.js b/remoting/webapp/host_list.js
index 05f0373..b0f10d5 100644
--- a/remoting/webapp/host_list.js
+++ b/remoting/webapp/host_list.js
@@ -255,7 +255,7 @@ remoting.HostList.unregisterHostById = function(hostId) {
'https://www.googleapis.com/chromoting/v1/@me/hosts/' + hostId,
function() {}, '', headers);
}
- remoting.oauth2.callWithToken(deleteHost, remoting.defaultOAuthErrorHandler);
+ remoting.oauth2.callWithToken(deleteHost, remoting.showErrorMessage);
};
/**
@@ -295,7 +295,7 @@ remoting.HostList.prototype.renameHost = function(hostTableEntry) {
console.error('Could not rename host. Authentication failure.');
}
}
- remoting.oauth2.callWithToken(renameHost, remoting.defaultOAuthErrorHandler);
+ remoting.oauth2.callWithToken(renameHost, remoting.showErrorMessage);
};
/**
diff --git a/remoting/webapp/host_screen.js b/remoting/webapp/host_screen.js
index 7edb2f0..df36ee6 100644
--- a/remoting/webapp/host_screen.js
+++ b/remoting/webapp/host_screen.js
@@ -27,7 +27,7 @@ var lastShareWasCancelled_ = false;
remoting.tryShare = function() {
console.log('Attempting to share...');
remoting.oauth2.callWithToken(remoting.tryShareWithToken_,
- remoting.defaultOAuthErrorHandler);
+ remoting.showErrorMessage);
};
/**
diff --git a/remoting/webapp/host_setup_dialog.js b/remoting/webapp/host_setup_dialog.js
index 8ba3be2..810b6ee 100644
--- a/remoting/webapp/host_setup_dialog.js
+++ b/remoting/webapp/host_setup_dialog.js
@@ -154,7 +154,7 @@ remoting.HostSetupDialog.prototype.showForStart = function() {
// using callWithToken here ensures consistent error handling in the
// case where the refresh token is invalid.
remoting.oauth2.callWithToken(this.showForStartWithToken_.bind(this),
- remoting.defaultOAuthErrorHandler);
+ remoting.showErrorMessage);
};
/**
diff --git a/remoting/webapp/main.html b/remoting/webapp/main.html
index a607812..9cb104c 100644
--- a/remoting/webapp/main.html
+++ b/remoting/webapp/main.html
@@ -86,7 +86,9 @@ found in the LICENSE file.
<div>
<p class="infographic-description"
i18n-content="IT2ME_FIRST_RUN"></p>
- <button id="get-started-it2me" i18n-content="GET_STARTED"></button>
+ <button id="get-started-it2me"
+ i18n-content="GET_STARTED"
+ disabled></button>
</div>
<div class="infographic">
<img src="infographic_remote_assistance.png">
@@ -132,7 +134,9 @@ found in the LICENSE file.
<div>
<p class="infographic-description"
i18n-content="ME2ME_FIRST_RUN"></p>
- <button id="get-started-me2me" i18n-content="GET_STARTED"></button>
+ <button id="get-started-me2me"
+ i18n-content="GET_STARTED"
+ disabled></button>
</div>
<div class="infographic">
<img src="infographic_my_computers.png">
diff --git a/remoting/webapp/oauth2.js b/remoting/webapp/oauth2.js
index 50bc38b..b6f08e3 100644
--- a/remoting/webapp/oauth2.js
+++ b/remoting/webapp/oauth2.js
@@ -47,6 +47,7 @@ remoting.OAuth2.prototype.OAUTH2_TOKEN_ENDPOINT_ =
/** @private */
remoting.OAuth2.prototype.OAUTH2_REVOKE_TOKEN_ENDPOINT_ =
'https://accounts.google.com/o/oauth2/revoke';
+
/** @return {boolean} True if the app is already authenticated. */
remoting.OAuth2.prototype.isAuthenticated = function() {
if (this.getRefreshToken_()) {
@@ -381,24 +382,38 @@ remoting.OAuth2.prototype.onRefreshToken_ = function(onOk, onError, xhr,
/**
* Get the user's email address.
*
- * @param {function(?string):void} setEmail Callback invoked when the email
- * address is available, or on error.
+ * @param {function(string):void} onOk Callback invoked when the email
+ * address is available.
+ * @param {function(remoting.Error):void} onError Callback invoked if an
+ * error occurs.
* @return {void} Nothing.
*/
-remoting.OAuth2.prototype.getEmail = function(setEmail) {
+remoting.OAuth2.prototype.getEmail = function(onOk, onError) {
+ var cached = window.localStorage.getItem(this.KEY_EMAIL_);
+ if (typeof cached == 'string') {
+ onOk(cached);
+ return;
+ }
/** @type {remoting.OAuth2} */
var that = this;
/** @param {XMLHttpRequest} xhr The XHR response. */
var onResponse = function(xhr) {
- that.email = null;
+ var email = null;
if (xhr.status == 200) {
// TODO(ajwong): See if we can't find a JSON endpoint.
- that.email = xhr.responseText.split('&')[0].split('=')[1];
- window.localStorage.setItem(that.KEY_EMAIL_, that.email);
- } else {
- console.error('Unable to get email address:', xhr.status, xhr);
+ email = xhr.responseText.split('&')[0].split('=')[1];
+ window.localStorage.setItem(that.KEY_EMAIL_, email);
+ onOk(email);
+ return;
}
- setEmail(that.email);
+ console.error('Unable to get email address:', xhr.status, xhr);
+ var error = remoting.Error.UNEXPECTED;
+ if (xhr.status == 401) {
+ error = remoting.Error.AUTHENTICATION_FAILED;
+ } else if (xhr.status == 503) {
+ error = remoting.Error.SERVICE_UNAVAILABLE;
+ }
+ onError(error);
};
/** @param {string} token The access token. */
@@ -408,11 +423,6 @@ remoting.OAuth2.prototype.getEmail = function(setEmail) {
remoting.xhr.get('https://www.googleapis.com/userinfo/email',
onResponse, '', headers);
};
- /** @param {remoting.Error} error */
- var onError = function(error) {
- console.error('Unable to get email address: ' + error);
- setEmail(null);
- };
this.callWithToken(getEmailFromToken, onError);
};
diff --git a/remoting/webapp/remoting.js b/remoting/webapp/remoting.js
index b11f912..bcd29a2 100644
--- a/remoting/webapp/remoting.js
+++ b/remoting/webapp/remoting.js
@@ -47,11 +47,7 @@ remoting.init = function() {
document.getElementById('session-toolbar'));
remoting.clipboard = new remoting.Clipboard();
- refreshEmail_();
- var email = remoting.oauth2.getCachedEmail();
- if (email) {
- document.getElementById('current-email').innerText = email;
- }
+ remoting.oauth2.getEmail(remoting.onEmail, remoting.showErrorMessage);
remoting.showOrHideIt2MeUi();
remoting.showOrHideMe2MeUi();
@@ -85,6 +81,19 @@ remoting.init = function() {
remoting.initDaemonUi();
};
+/**
+ * Display the user's email address and allow access to the rest of the app,
+ * including parsing URL parameters.
+ *
+ * @param {string} email The user's email address.
+ * @return {void} Nothing.
+ */
+remoting.onEmail = function(email) {
+ document.getElementById('current-email').innerText = email;
+ document.getElementById('get-started-it2me').disabled = false;
+ document.getElementById('get-started-me2me').disabled = false;
+};
+
// initDaemonUi is called if the app is not starting up in session mode, and
// also if the user cancels pin entry or the connection in session mode.
remoting.initDaemonUi = function () {
@@ -212,48 +221,6 @@ function pluginGotCopy_(eventUncast) {
}
/**
- * If the user is authenticated, but there is no email address cached, get one.
- */
-function refreshEmail_() {
- if (!getEmail_() && remoting.oauth2.isAuthenticated()) {
- remoting.oauth2.getEmail(setEmail_);
- }
-}
-
-/**
- * The key under which the email address is stored.
- * @private
- */
-var KEY_EMAIL_ = 'remoting-email';
-
-/**
- * Save the user's email address in local storage.
- *
- * @param {?string} email The email address to place in local storage.
- * @return {void} Nothing.
- */
-function setEmail_(email) {
- if (email) {
- document.getElementById('current-email').innerText = email;
- } else {
- var e = document.getElementById('auth-error-message');
- e.innerText = chrome.i18n.getMessage(remoting.Error.SERVICE_UNAVAILABLE);
- e.classList.add('error-state');
- remoting.setMode(remoting.AppMode.UNAUTHENTICATED);
- }
-}
-
-/**
- * Read the user's email address from local storage.
- *
- * @return {?string} The email address associated with the auth credentials.
- */
-function getEmail_() {
- var result = window.localStorage.getItem(KEY_EMAIL_);
- return typeof result == 'string' ? result : null;
-}
-
-/**
* Gets the major-mode that this application should start up in.
*
* @return {remoting.AppMode} The mode to start in.
@@ -327,14 +294,13 @@ remoting.timestamp = function() {
};
/**
- * Default handler for OAuth token refresh failures. This switches the app mode
- * to display an error message, optionally including a short-cut for signing in
- * to Chromoting again.
+ * Show an error message, optionally including a short-cut for signing in to
+ * Chromoting again.
*
* @param {remoting.Error} error
* @return {void} Nothing.
*/
-remoting.defaultOAuthErrorHandler = function(error) {
+remoting.showErrorMessage = function(error) {
l10n.localizeElementFromTag(
document.getElementById('token-refresh-error-message'),
error);