summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2009-07-24 22:03:53 -0700
committerAndrew Arnott <andrewarnott@gmail.com>2009-07-24 22:03:53 -0700
commit2867e881214a8f58f8405b58d19eeb05fb18dda3 (patch)
tree735da501f7354159249a3df94fcf6e0f68d5cd06
parentb3086860a2f285cf4b40526b9d49c85cf1451268 (diff)
downloadDotNetOpenAuth-2867e881214a8f58f8405b58d19eeb05fb18dda3.zip
DotNetOpenAuth-2867e881214a8f58f8405b58d19eeb05fb18dda3.tar.gz
DotNetOpenAuth-2867e881214a8f58f8405b58d19eeb05fb18dda3.tar.bz2
Fixed the remaining apparent problems with the new OpenIdAjaxTextBox control.
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxTextBox.js43
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.js491
2 files changed, 280 insertions, 254 deletions
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxTextBox.js b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxTextBox.js
index c549b17..531748a 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxTextBox.js
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxTextBox.js
@@ -146,13 +146,13 @@ function initAjaxOpenId(box, openid_logo_url, dotnetopenid_logo_url, spinner_url
box.dnoi_internal.op_logo.title = box.dnoi_internal.op_logo.originalTitle.replace('{0}', authenticatedBy.getHost());
}
//trace("OP icon size: " + box.dnoi_internal.op_logo.fileSize);
- // This just doesn't seem to work any more.
-// if (opLogo == null || box.dnoi_internal.op_logo.fileSize == -1 /*IE*/ || box.dnoi_internal.op_logo.fileSize === undefined /* FF */) {
-// trace('recovering from missing OP icon');
-// box.dnoi_internal.op_logo.style.visibility = 'hidden';
-// box.dnoi_internal.openid_logo.style.visibility = 'visible';
-// box.dnoi_internal.openid_logo.title = box.dnoi_internal.op_logo.originalTitle.replace('{0}', authenticatedBy.getHost());
-// }
+ // The filesize check just doesn't seem to work any more.
+ if (opLogo == null) {// || box.dnoi_internal.op_logo.fileSize == -1 /*IE*/ || box.dnoi_internal.op_logo.fileSize === undefined /* FF */) {
+ trace('recovering from missing OP icon');
+ box.dnoi_internal.op_logo.style.visibility = 'hidden';
+ box.dnoi_internal.openid_logo.style.visibility = 'visible';
+ box.dnoi_internal.openid_logo.title = box.dnoi_internal.op_logo.originalTitle.replace('{0}', authenticatedBy.getHost());
+ }
box.dnoi_internal.success_icon.style.visibility = 'visible';
box.dnoi_internal.success_icon.title = box.dnoi_internal.success_icon.originalTitle.replace('{0}', authenticatedAs);
box.title = box.dnoi_internal.claimedIdentifier;
@@ -350,8 +350,9 @@ function initAjaxOpenId(box, openid_logo_url, dotnetopenid_logo_url, spinner_url
box.dnoi_internal.onAuthSuccess = function(discoveryResult, respondingEndpoint) {
// visual cue that auth was successful
- box.dnoi_internal.claimedIdentifier = discoveryResult.claimedIdentifier;
- box.dnoi_internal.setVisualCue('authenticated', respondingEndpoint.endpoint, discoveryResult.claimedIdentifier);
+ var parsedPositiveAssertion = new window.dnoa_internal.PositiveAssertion(discoveryResult.successAuthData);
+ box.dnoi_internal.claimedIdentifier = parsedPositiveAssertion.claimedIdentifier;
+ box.dnoi_internal.setVisualCue('authenticated', parsedPositiveAssertion.endpoint, parsedPositiveAssertion.claimedIdentifier);
if (box.dnoi_internal.onauthenticated) {
box.dnoi_internal.onauthenticated(box);
}
@@ -389,27 +390,5 @@ function initAjaxOpenId(box, openid_logo_url, dotnetopenid_logo_url, spinner_url
box.getClaimedIdentifier = function() { return box.dnoi_internal.claimedIdentifier; };
// Restore a previously achieved state (from pre-postback) if it is given.
- var oldAuth = findOrCreateHiddenField().value;
- if (oldAuth.length > 0) {
- var oldAuthResult = new window.dnoa_internal.Uri(oldAuth);
- // The control ensures that we ALWAYS have an OpenID 2.0-style claimed_id attribute, even against
- // 1.0 Providers via the return_to URL mechanism.
- var claimedId = oldAuthResult.getQueryArgValue("dnoa.claimed_id");
- var endpoint = oldAuthResult.getQueryArgValue("dnoa.op_endpoint");
- var userSuppliedIdentifier = oldAuthResult.getQueryArgValue('dnoa.userSuppliedIdentifier');
-
-// TODO:
- // We weren't given a full discovery history, but we can spoof this much from the
- // authentication assertion.
- //new window.OpenIdIdentifier(userSuppliedIdentifier).discover
- var discoveryResult = {
- claimedIdentifier: claimedId,
- requests: [{ endpoint: endpoint }]
- };
-
- // window.dnoa_internal.discoveryResults[box.value] = discoveryResult;
-
- // restore old state from before postback
- //window.dnoa_internal.processAuthorizationResult(oldAuthResult.toString());
- }
+ window.dnoa_internal.deserializePreviousAuthentication(findOrCreateHiddenField().value, box.dnoi_internal.onAuthSuccess);
}
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.js b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.js
index e0fcd98..c6f6a75 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.js
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.js
@@ -107,222 +107,6 @@ window.OpenIdIdentifier = function(identifier) {
/// <param name="onDiscoverSuccess">A function(DiscoveryResult) callback to be called when discovery has completed successfully.</param>
/// <param name="onDiscoverFailure">A function callback to be called when discovery has completed in failure.</param>
this.discover = function(onDiscoverSuccess, onDiscoverFailure) {
- /// <summary>Instantiates an object that stores discovery results of some identifier.</summary>
- function DiscoveryResult(identifier, discoveryInfo) {
- var thisDiscoveryResult = this;
-
- /// <summary>
- /// Instantiates an object that describes an OpenID service endpoint and facilitates
- /// initiating and tracking an authentication request.
- /// </summary>
- function ServiceEndpoint(requestInfo, userSuppliedIdentifier) {
- this.immediate = requestInfo.immediate ? new window.dnoa_internal.Uri(requestInfo.immediate) : null;
- this.setup = requestInfo.setup ? new window.dnoa_internal.Uri(requestInfo.setup) : null;
- this.endpoint = new window.dnoa_internal.Uri(requestInfo.endpoint);
- this.host = this.endpoint.getHost();
- this.userSuppliedIdentifier = userSuppliedIdentifier;
- var thisServiceEndpoint = this; // closure so that delegates have the right instance
- this.loginPopup = function(onAuthSuccess, onAuthFailed) {
- thisServiceEndpoint.abort(); // ensure no concurrent attempts
- thisDiscoveryResult.onAuthSuccess = onAuthSuccess;
- thisDiscoveryResult.onAuthFailed = onAuthFailed;
- var width = 800;
- var height = 600;
- if (thisServiceEndpoint.setup.getQueryArgValue("openid.return_to").indexOf("dnoa.popupUISupported") >= 0) {
- trace('This OP supports the UI extension. Using smaller window size.');
- width = 450;
- height = 500;
- } else {
- trace("This OP doesn't appear to support the UI extension. Using larger window size.");
- }
-
- var left = (screen.width - width) / 2;
- var top = (screen.height - height) / 2;
- thisServiceEndpoint.popup = window.open(thisServiceEndpoint.setup, 'opLogin', 'status=0,toolbar=0,location=1,resizable=1,scrollbars=1,left=' + left + ',top=' + top + ',width=' + width + ',height=' + height);
-
- // If the OP supports the UI extension it MAY close its own window
- // for a negative assertion. We must be able to recover from that scenario.
- var thisServiceEndpointLocal = thisServiceEndpoint;
- thisServiceEndpoint.popupCloseChecker = window.setInterval(function() {
- if (thisServiceEndpointLocal.popup && thisServiceEndpointLocal.popup.closed) {
- // The window closed, either because the user closed it, canceled at the OP,
- // or approved at the OP and the popup window closed itself due to our script.
- // If we were graying out the entire page while the child window was up,
- // we would probably revert that here.
- window.clearInterval(thisServiceEndpointLocal.popupCloseChecker);
- thisServiceEndpointLocal.popup = null;
-
- // The popup may have managed to inform us of the result already,
- // so check whether the callback method was cleared already, which
- // would indicate we've already processed this.
- if (window.dnoa_internal.processAuthorizationResult) {
- trace('User or OP canceled by closing the window.');
- if (thisDiscoveryResult.onAuthFailed) {
- thisDiscoveryResult.onAuthFailed(thisDiscoveryResult, thisServiceEndpoint);
- }
- window.dnoa_internal.processAuthorizationResult = null;
- }
- }
- }, 250);
- };
-
- this.loginBackgroundJob = function(iframe, timeout) {
- thisServiceEndpoint.abort(); // ensure no concurrent attempts
- if (timeout) {
- thisServiceEndpoint.timeout = setTimeout(function() { thisServiceEndpoint.onAuthenticationTimedOut(); }, timeout);
- }
- trace('iframe hosting ' + thisServiceEndpoint.endpoint + ' now OPENING (timeout ' + timeout + ').');
- //trace('initiating auth attempt with: ' + thisServiceEndpoint.immediate);
- thisServiceEndpoint.iframe = iframe;
- return thisServiceEndpoint.immediate.toString();
- };
-
- this.busy = function() {
- return thisServiceEndpoint.iframe != null || thisServiceEndpoint.popup != null;
- };
-
- this.completeAttempt = function(successful) {
- if (!thisServiceEndpoint.busy()) return false;
- window.clearInterval(thisServiceEndpoint.timeout);
- if (thisServiceEndpoint.iframe) {
- trace('iframe hosting ' + thisServiceEndpoint.endpoint + ' now CLOSING.');
- thisDiscoveryResult.frameManager.closeFrame(thisServiceEndpoint.iframe);
- thisServiceEndpoint.iframe = null;
- }
- if (thisServiceEndpoint.popup) {
- thisServiceEndpoint.popup.close();
- thisServiceEndpoint.popup = null;
- }
- if (thisServiceEndpoint.timeout) {
- window.clearTimeout(thisServiceEndpoint.timeout);
- thisServiceEndpoint.timeout = null;
- }
-
- if (!successful && !thisDiscoveryResult.busy() && thisDiscoveryResult.findSuccessfulRequest() == null) {
- if (thisDiscoveryResult.onLastAttemptFailed) {
- thisDiscoveryResult.onLastAttemptFailed();
- }
- }
-
- return true;
- };
-
- this.onAuthenticationTimedOut = function() {
- if (thisServiceEndpoint.completeAttempt()) {
- trace(thisServiceEndpoint.host + " timed out");
- thisServiceEndpoint.result = window.dnoa_internal.timedOut;
- }
- };
-
- this.onAuthSuccess = function(authUri) {
- if (thisServiceEndpoint.completeAttempt(true)) {
- trace(thisServiceEndpoint.host + " authenticated!");
- thisServiceEndpoint.result = window.dnoa_internal.authSuccess;
- thisServiceEndpoint.response = authUri;
- thisDiscoveryResult.abortAll();
- if (thisDiscoveryResult.onAuthSuccess) {
- thisDiscoveryResult.onAuthSuccess(thisDiscoveryResult, thisServiceEndpoint);
- }
- }
- };
-
- this.onAuthFailed = function() {
- if (thisServiceEndpoint.completeAttempt()) {
- trace(thisServiceEndpoint.host + " failed authentication");
- thisServiceEndpoint.result = window.dnoa_internal.authRefused;
- if (thisDiscoveryResult.onAuthFailed) {
- thisDiscoveryResult.onAuthFailed(thisDiscoveryResult, thisServiceEndpoint);
- }
- }
- };
-
- this.abort = function() {
- if (thisServiceEndpoint.completeAttempt()) {
- trace(thisServiceEndpoint.host + " aborted");
- // leave the result as whatever it was before.
- }
- };
-
- };
-
- this.userSuppliedIdentifier = identifier;
-
- if (discoveryInfo) {
- this.claimedIdentifier = discoveryInfo.claimedIdentifier; // The claimed identifier may be null if the user provided an OP Identifier.
- this.length = discoveryInfo.requests.length;
- for (var i = 0; i < discoveryInfo.requests.length; i++) {
- this[i] = new ServiceEndpoint(discoveryInfo.requests[i], identifier);
- }
- } else {
- this.length = 0;
- }
-
- trace('Discovered claimed identifier: ' + (this.claimedIdentifier ? this.claimedIdentifier : "(directed identity)"));
-
- // Add extra tracking bits and behaviors.
- this.findByEndpoint = function(opEndpoint) {
- for (var i = 0; i < thisDiscoveryResult.length; i++) {
- if (thisDiscoveryResult[i].endpoint == opEndpoint) {
- return thisDiscoveryResult[i];
- }
- }
- };
-
- this.busy = function() {
- for (var i = 0; i < thisDiscoveryResult.length; i++) {
- if (thisDiscoveryResult[i].busy()) {
- return true;
- }
- }
- };
-
- // Add extra tracking bits and behaviors.
- this.findSuccessfulRequest = function() {
- for (var i = 0; i < thisDiscoveryResult.length; i++) {
- if (thisDiscoveryResult[i].result === window.dnoa_internal.authSuccess) {
- return thisDiscoveryResult[i];
- }
- }
- };
-
- this.abortAll = function() {
- if (thisDiscoveryResult.frameManager) {
- // Abort all other asynchronous authentication attempts that may be in progress.
- thisDiscoveryResult.frameManager.cancelAllWork();
- for (var i = 0; i < thisDiscoveryResult.length; i++) {
- thisDiscoveryResult[i].abort();
- }
- } else {
- trace('abortAll called without a frameManager being previously set.');
- }
- };
-
- /// <summary>Initiates an asynchronous checkid_immediate login attempt against all possible service endpoints for an Identifier.</summary>
- /// <param name="frameManager">The work queue for authentication iframes.</param>
- /// <param name="onAuthSuccess">Fired when an endpoint responds affirmatively.</param>
- /// <param name="onAuthFailed">Fired when an endpoint responds negatively.</param>
- /// <param name="onLastAuthFailed">Fired when all authentication attempts have responded negatively or timed out.</param>
- /// <param name="timeout">Timeout for an individual service endpoint to respond before the iframe closes.</param>
- this.loginBackground = function(frameManager, onAuthSuccess, onAuthFailed, onLastAuthFailed, timeout) {
- if (!frameManager) {
- throw "No frameManager specified.";
- }
- if (thisDiscoveryResult.findSuccessfulRequest() != null) {
- onAuthSuccess(thisDiscoveryResult, thisDiscoveryResult.findSuccessfulRequest());
- } else {
- thisDiscoveryResult.frameManager = frameManager;
- thisDiscoveryResult.onAuthSuccess = onAuthSuccess;
- thisDiscoveryResult.onAuthFailed = onAuthFailed;
- thisDiscoveryResult.onLastAttemptFailed = onLastAuthFailed;
- if (thisDiscoveryResult.length > 0) {
- for (var i = 0; i < thisDiscoveryResult.length; i++) {
- thisDiscoveryResult.frameManager.enqueueWork(thisDiscoveryResult[i].loginBackgroundJob, timeout);
- }
- }
- }
- };
- };
-
/// <summary>Receives the results of a successful discovery (even if it yielded 0 results).</summary>
function discoverSuccessCallback(discoveryResult, identifier) {
trace('Discovery completed for: ' + identifier);
@@ -331,7 +115,7 @@ window.OpenIdIdentifier = function(identifier) {
discoveryResult = eval('(' + discoveryResult + ')');
// Add behavior for later use.
- discoveryResult = new DiscoveryResult(identifier, discoveryResult);
+ discoveryResult = new window.dnoa_internal.DiscoveryResult(identifier, discoveryResult);
window.dnoa_internal.discoveryResults[identifier] = discoveryResult;
if (onDiscoverSuccess) {
@@ -415,16 +199,16 @@ window.dnoa_internal.processAuthorizationResult = function(resultUrl) {
var opEndpoint = resultUri.getQueryArgValue("openid.op_endpoint") ? resultUri.getQueryArgValue("openid.op_endpoint") : resultUri.getQueryArgValue("dnoa.op_endpoint");
var respondingEndpoint = discoveryResult.findByEndpoint(opEndpoint);
- trace('Auth result for ' + respondingEndpoint.host + ' received.');//: ' + resultUrl);
+ trace('Auth result for ' + respondingEndpoint.host + ' received.'); //: ' + resultUrl);
if (window.dnoa_internal.isAuthSuccessful(resultUri)) {
discoveryResult.successAuthData = resultUrl;
respondingEndpoint.onAuthSuccess(resultUri);
- var claimed_id = resultUri.getQueryArgValue("openid.claimed_id");
- if (claimed_id && claimed_id != discoveryResult.claimedIdentifier) {
- discoveryResult.claimedIdentifier = resultUri.getQueryArgValue("openid.claimed_id");
- trace('Authenticated as ' + claimed_id);
+ var parsedPositiveAssertion = new window.dnoa_internal.PositiveAssertion(resultUri);
+ if (parsedPositiveAssertion.claimedIdentifier && parsedPositiveAssertion.claimedIdentifier != discoveryResult.claimedIdentifier) {
+ discoveryResult.claimedIdentifier = parsedPositiveAssertion.claimedIdentifier;
+ trace('Authenticated as ' + parsedPositiveAssertion.claimedIdentifier);
}
} else {
respondingEndpoint.onAuthFailed();
@@ -443,3 +227,266 @@ window.dnoa_internal.isOpenID2Response = function(resultUri) {
return resultUri.containsQueryArg("openid.ns");
};
+/// <summary>Instantiates an object that stores discovery results of some identifier.</summary>
+window.dnoa_internal.DiscoveryResult = function(identifier, discoveryInfo) {
+ var thisDiscoveryResult = this;
+
+ /// <summary>
+ /// Instantiates an object that describes an OpenID service endpoint and facilitates
+ /// initiating and tracking an authentication request.
+ /// </summary>
+ function ServiceEndpoint(requestInfo, userSuppliedIdentifier) {
+ this.immediate = requestInfo.immediate ? new window.dnoa_internal.Uri(requestInfo.immediate) : null;
+ this.setup = requestInfo.setup ? new window.dnoa_internal.Uri(requestInfo.setup) : null;
+ this.endpoint = new window.dnoa_internal.Uri(requestInfo.endpoint);
+ this.host = this.endpoint.getHost();
+ this.userSuppliedIdentifier = userSuppliedIdentifier;
+ var thisServiceEndpoint = this; // closure so that delegates have the right instance
+ this.loginPopup = function(onAuthSuccess, onAuthFailed) {
+ thisServiceEndpoint.abort(); // ensure no concurrent attempts
+ thisDiscoveryResult.onAuthSuccess = onAuthSuccess;
+ thisDiscoveryResult.onAuthFailed = onAuthFailed;
+ var width = 800;
+ var height = 600;
+ if (thisServiceEndpoint.setup.getQueryArgValue("openid.return_to").indexOf("dnoa.popupUISupported") >= 0) {
+ trace('This OP supports the UI extension. Using smaller window size.');
+ width = 450;
+ height = 500;
+ } else {
+ trace("This OP doesn't appear to support the UI extension. Using larger window size.");
+ }
+
+ var left = (screen.width - width) / 2;
+ var top = (screen.height - height) / 2;
+ thisServiceEndpoint.popup = window.open(thisServiceEndpoint.setup, 'opLogin', 'status=0,toolbar=0,location=1,resizable=1,scrollbars=1,left=' + left + ',top=' + top + ',width=' + width + ',height=' + height);
+
+ // If the OP supports the UI extension it MAY close its own window
+ // for a negative assertion. We must be able to recover from that scenario.
+ var thisServiceEndpointLocal = thisServiceEndpoint;
+ thisServiceEndpoint.popupCloseChecker = window.setInterval(function() {
+ if (thisServiceEndpointLocal.popup && thisServiceEndpointLocal.popup.closed) {
+ // The window closed, either because the user closed it, canceled at the OP,
+ // or approved at the OP and the popup window closed itself due to our script.
+ // If we were graying out the entire page while the child window was up,
+ // we would probably revert that here.
+ window.clearInterval(thisServiceEndpointLocal.popupCloseChecker);
+ thisServiceEndpointLocal.popup = null;
+
+ // The popup may have managed to inform us of the result already,
+ // so check whether the callback method was cleared already, which
+ // would indicate we've already processed this.
+ if (window.dnoa_internal.processAuthorizationResult) {
+ trace('User or OP canceled by closing the window.');
+ if (thisDiscoveryResult.onAuthFailed) {
+ thisDiscoveryResult.onAuthFailed(thisDiscoveryResult, thisServiceEndpoint);
+ }
+ window.dnoa_internal.processAuthorizationResult = null;
+ }
+ }
+ }, 250);
+ };
+
+ this.loginBackgroundJob = function(iframe, timeout) {
+ thisServiceEndpoint.abort(); // ensure no concurrent attempts
+ if (timeout) {
+ thisServiceEndpoint.timeout = setTimeout(function() { thisServiceEndpoint.onAuthenticationTimedOut(); }, timeout);
+ }
+ trace('iframe hosting ' + thisServiceEndpoint.endpoint + ' now OPENING (timeout ' + timeout + ').');
+ //trace('initiating auth attempt with: ' + thisServiceEndpoint.immediate);
+ thisServiceEndpoint.iframe = iframe;
+ return thisServiceEndpoint.immediate.toString();
+ };
+
+ this.busy = function() {
+ return thisServiceEndpoint.iframe != null || thisServiceEndpoint.popup != null;
+ };
+
+ this.completeAttempt = function(successful) {
+ if (!thisServiceEndpoint.busy()) return false;
+ window.clearInterval(thisServiceEndpoint.timeout);
+ if (thisServiceEndpoint.iframe) {
+ trace('iframe hosting ' + thisServiceEndpoint.endpoint + ' now CLOSING.');
+ thisDiscoveryResult.frameManager.closeFrame(thisServiceEndpoint.iframe);
+ thisServiceEndpoint.iframe = null;
+ }
+ if (thisServiceEndpoint.popup) {
+ thisServiceEndpoint.popup.close();
+ thisServiceEndpoint.popup = null;
+ }
+ if (thisServiceEndpoint.timeout) {
+ window.clearTimeout(thisServiceEndpoint.timeout);
+ thisServiceEndpoint.timeout = null;
+ }
+
+ if (!successful && !thisDiscoveryResult.busy() && thisDiscoveryResult.findSuccessfulRequest() == null) {
+ if (thisDiscoveryResult.onLastAttemptFailed) {
+ thisDiscoveryResult.onLastAttemptFailed();
+ }
+ }
+
+ return true;
+ };
+
+ this.onAuthenticationTimedOut = function() {
+ if (thisServiceEndpoint.completeAttempt()) {
+ trace(thisServiceEndpoint.host + " timed out");
+ thisServiceEndpoint.result = window.dnoa_internal.timedOut;
+ }
+ };
+
+ this.onAuthSuccess = function(authUri) {
+ if (thisServiceEndpoint.completeAttempt(true)) {
+ trace(thisServiceEndpoint.host + " authenticated!");
+ thisServiceEndpoint.result = window.dnoa_internal.authSuccess;
+ thisServiceEndpoint.claimedIdentifier = authUri//////////////////////////////////
+ thisServiceEndpoint.response = authUri;
+ thisDiscoveryResult.abortAll();
+ if (thisDiscoveryResult.onAuthSuccess) {
+ thisDiscoveryResult.onAuthSuccess(thisDiscoveryResult, thisServiceEndpoint);
+ }
+ }
+ };
+
+ this.onAuthFailed = function() {
+ if (thisServiceEndpoint.completeAttempt()) {
+ trace(thisServiceEndpoint.host + " failed authentication");
+ thisServiceEndpoint.result = window.dnoa_internal.authRefused;
+ if (thisDiscoveryResult.onAuthFailed) {
+ thisDiscoveryResult.onAuthFailed(thisDiscoveryResult, thisServiceEndpoint);
+ }
+ }
+ };
+
+ this.abort = function() {
+ if (thisServiceEndpoint.completeAttempt()) {
+ trace(thisServiceEndpoint.host + " aborted");
+ // leave the result as whatever it was before.
+ }
+ };
+
+ };
+
+ this.userSuppliedIdentifier = identifier;
+
+ if (discoveryInfo) {
+ this.claimedIdentifier = discoveryInfo.claimedIdentifier; // The claimed identifier may be null if the user provided an OP Identifier.
+ this.length = discoveryInfo.requests.length;
+ for (var i = 0; i < discoveryInfo.requests.length; i++) {
+ this[i] = new ServiceEndpoint(discoveryInfo.requests[i], identifier);
+ }
+ } else {
+ this.length = 0;
+ }
+
+ trace('Discovered claimed identifier: ' + (this.claimedIdentifier ? this.claimedIdentifier : "(directed identity)"));
+
+ // Add extra tracking bits and behaviors.
+ this.findByEndpoint = function(opEndpoint) {
+ for (var i = 0; i < thisDiscoveryResult.length; i++) {
+ if (thisDiscoveryResult[i].endpoint == opEndpoint) {
+ return thisDiscoveryResult[i];
+ }
+ }
+ };
+
+ this.busy = function() {
+ for (var i = 0; i < thisDiscoveryResult.length; i++) {
+ if (thisDiscoveryResult[i].busy()) {
+ return true;
+ }
+ }
+ };
+
+ // Add extra tracking bits and behaviors.
+ this.findSuccessfulRequest = function() {
+ for (var i = 0; i < thisDiscoveryResult.length; i++) {
+ if (thisDiscoveryResult[i].result === window.dnoa_internal.authSuccess) {
+ return thisDiscoveryResult[i];
+ }
+ }
+ };
+
+ this.abortAll = function() {
+ if (thisDiscoveryResult.frameManager) {
+ // Abort all other asynchronous authentication attempts that may be in progress.
+ thisDiscoveryResult.frameManager.cancelAllWork();
+ for (var i = 0; i < thisDiscoveryResult.length; i++) {
+ thisDiscoveryResult[i].abort();
+ }
+ } else {
+ trace('abortAll called without a frameManager being previously set.');
+ }
+ };
+
+ /// <summary>Initiates an asynchronous checkid_immediate login attempt against all possible service endpoints for an Identifier.</summary>
+ /// <param name="frameManager">The work queue for authentication iframes.</param>
+ /// <param name="onAuthSuccess">Fired when an endpoint responds affirmatively.</param>
+ /// <param name="onAuthFailed">Fired when an endpoint responds negatively.</param>
+ /// <param name="onLastAuthFailed">Fired when all authentication attempts have responded negatively or timed out.</param>
+ /// <param name="timeout">Timeout for an individual service endpoint to respond before the iframe closes.</param>
+ this.loginBackground = function(frameManager, onAuthSuccess, onAuthFailed, onLastAuthFailed, timeout) {
+ if (!frameManager) {
+ throw "No frameManager specified.";
+ }
+ if (thisDiscoveryResult.findSuccessfulRequest() != null) {
+ onAuthSuccess(thisDiscoveryResult, thisDiscoveryResult.findSuccessfulRequest());
+ } else {
+ thisDiscoveryResult.frameManager = frameManager;
+ thisDiscoveryResult.onAuthSuccess = onAuthSuccess;
+ thisDiscoveryResult.onAuthFailed = onAuthFailed;
+ thisDiscoveryResult.onLastAttemptFailed = onLastAuthFailed;
+ if (thisDiscoveryResult.length > 0) {
+ for (var i = 0; i < thisDiscoveryResult.length; i++) {
+ thisDiscoveryResult.frameManager.enqueueWork(thisDiscoveryResult[i].loginBackgroundJob, timeout);
+ }
+ }
+ }
+ };
+};
+
+/// <summary>
+/// Called in a page had an AJAX control that had already obtained a positive assertion
+/// when a postback occurred, and now that control wants to restore its 'authenticated' state.
+/// </summary>
+/// <param name="positiveAssertion">The string form of the URI that contains the positive assertion.</param>
+/// <param name="onAuthSuccess">Fired if the positive assertion is successfully processed, as if it had just come in.</param>
+window.dnoa_internal.deserializePreviousAuthentication = function(positiveAssertion, onAuthSuccess) {
+ if (!positiveAssertion || positiveAssertion.length === 0) {
+ return;
+ }
+
+ trace('Revitalizing an old positive assertion from a prior postback.');
+ var oldAuthResult = new window.dnoa_internal.Uri(positiveAssertion);
+
+ // The control ensures that we ALWAYS have an OpenID 2.0-style claimed_id attribute, even against
+ // 1.0 Providers via the return_to URL mechanism.
+ var parsedPositiveAssertion = new window.dnoa_internal.PositiveAssertion(positiveAssertion);
+
+ // We weren't given a full discovery history, but we can spoof this much from the
+ // authentication assertion.
+ trace('Deserialized claimed_id: ' + parsedPositiveAssertion.claimedIdentifier + ' and endpoint: ' + parsedPositiveAssertion.endpoint);
+ var discoveryInfo = {
+ claimedIdentifier: parsedPositiveAssertion.claimedIdentifier,
+ requests: [{ endpoint: parsedPositiveAssertion.endpoint }]
+ };
+
+ window.dnoa_internal.discoveryResults[box.value] = discoveryResult = new window.dnoa_internal.DiscoveryResult(parsedPositiveAssertion.userSuppliedIdentifier, discoveryInfo);
+ discoveryResult[0].result = window.dnoa_internal.authSuccess;
+ discoveryResult.successAuthData = positiveAssertion;
+
+ // restore old state from before postback
+ if (onAuthSuccess) {
+ onAuthSuccess(discoveryResult, discoveryResult[0]);
+ }
+};
+
+window.dnoa_internal.PositiveAssertion = function(uri) {
+ uri = new window.dnoa_internal.Uri(uri.toString());
+ this.endpoint = new window.dnoa_internal.Uri(uri.getQueryArgValue("dnoa.op_endpoint"));
+ this.userSuppliedIdentifier = uri.getQueryArgValue('dnoa.userSuppliedIdentifier');
+ this.claimedIdentifier = uri.getQueryArgValue('openid.claimed_id');
+ if (!this.claimedIdentifier) {
+ this.claimedIdentifier = uri.getQueryArgValue('dnoa.claimed_id');
+ }
+ this.toString = function() { return uri.toString(); };
+};