diff --git a/oauth3.implicit.js b/oauth3.implicit.js
index fbcbc89..4494500 100644
--- a/oauth3.implicit.js
+++ b/oauth3.implicit.js
@@ -251,7 +251,7 @@
).then(function (params) {
// discWin.child.close()
// TODO params should have response_type indicating json, binary, etc
- var directives = JSON.parse(OAUTH3.utils.atob(OAUTH3.utils.urlSafeBase64ToBase64(params.result || params.directives)));
+ var directives = JSON.parse(OAUTH3.utils.atob(OAUTH3.utils._urlSafeBase64ToBase64(params.result || params.directives)));
return OAUTH3.hooks.directives.set(providerUri, directives);
});
}
@@ -310,7 +310,6 @@
xhr = new XMLHttpRequest();
}
xhr.onreadystatechange = function () {
- console.error('state change');
var data;
if (xhr.readyState !== XMLHttpRequest.DONE) {
// nothing to do here
@@ -365,7 +364,10 @@
);
// TODO ability to reuse iframe instead of closing
- return OAUTH3._browser._iframe.insert(discObj.url, discObj.state, opts).then(function (params) {
+ opts._windowType = opts.windowType;
+ opts.windowType = opts.windowType || 'background';
+ return OAUTH3._browser.frameRequest(discObj.url, discObj.state, opts).then(function (params) {
+ opts.windowType = opts._windowType;
OAUTH3._browser.closeFrame(discObj.state, { debug: opts.debug || params.debug });
if (params.error) {
return OAUTH3.utils._formatError(providerUri, params.error);
@@ -378,47 +380,67 @@
});
}
, frameRequest: function (url, state, opts) {
+ opts = opts || {};
var previousFrame = OAUTH3._browser._frames[state];
- if (!opts.windowType) {
- opts.windowType = 'popup';
+ var windowType = opts.windowType;
+ if (!windowType) {
+ windowType = 'popup';
}
- opts = opts || {};
+ var timeout = opts.timeout;
if (opts.debug) {
- opts.timeout = opts.timeout || 15 * 60 * 1000;
+ timeout = timeout || 3 * 60 * 1000;
+ }
+ else {
+ timeout = timeout || ('background' === windowType ? 15 * 1000 : 3 * 60 * 1000);
}
return new OAUTH3.PromiseA(function (resolve, reject) {
+ // TODO periodically garbage collect expired handlers from window object
var tok;
function cleanup() {
delete window['--oauth3-callback-' + state];
clearTimeout(tok);
tok = null;
+ // the actual close is done later (by the caller) so that the window/frame
+ // can be reused or self-closes synchronously itself / by parent
+ // (probably won't ever happen, but that's a negotiable implementation detail)
}
+
+ console.log('[oauth3.implicit.js] callbackName', '--oauth3-callback-' + state);
window['--oauth3-callback-' + state] = function (params) {
resolve(params);
cleanup();
};
tok = setTimeout(function () {
- var err = new Error("the iframe request did not complete within 15 seconds");
+ var err = new Error(
+ "the '" + windowType + "' request did not complete within " + Math.round(timeout / 1000) + "s"
+ );
err.code = "E_TIMEOUT";
reject(err);
cleanup();
- }, opts.timeout || 15 * 1000);
+ }, timeout);
- if ('background' === opts.windowType) {
+ setTimeout(function () {
+ if (!OAUTH3._browser._frames[state]) {
+ reject(new Error("TODO: open the iframe first and discover oauth3 directives before popup"));
+ cleanup();
+ }
+ }, 0);
+
+ if ('background' === windowType) {
if (previousFrame) {
previousFrame.location = url;
//promise = previousFrame.promise;
}
else {
- OAUTH3._browser._iframe.insert(url, state, opts);
+ OAUTH3._browser._frames[state] = OAUTH3._browser.iframe(url, state, opts);
}
- } else if ('popup' === opts.windowType) {
+ } else if ('popup' === windowType) {
if (previousFrame) {
previousFrame.location = url;
if (opts.debug) {
@@ -426,9 +448,9 @@
}
}
else {
- OAUTH3._browser.frame.open(url, state, opts);
+ OAUTH3._browser._frames[state] = OAUTH3._browser.frame(url, state, opts);
}
- } else if ('inline' === opts.windowType) {
+ } else if ('inline' === windowType) {
// callback function will never execute and would need to redirect back to current page
// rather than the callback.html
url += '&original_url=' + OAUTH3._browser.window.location.href;
@@ -478,72 +500,32 @@
}
}
, _frames: {}
- , iframe: {
- insert: function (url, state, opts) {
- // TODO hidden / non-hidden (via directive even)
- var framesrc = '';
-
- var frame = OAUTH3._browser._frames[state] = OAUTH3._browser.window.document.createElement('div');
- OAUTH3._browser._frames[state].innerHTML = framesrc;
- OAUTH3._browser.window.document.body.appendChild(OAUTH3._browser._frames[state]);
-
- return frame;
+ , iframe: function (url, state, opts) {
+ var framesrc = '';
+
+ var frame = OAUTH3._browser.window.document.createElement('div');
+ frame.innerHTML = framesrc;
+ OAUTH3._browser.window.document.body.appendChild(frame);
+
+ return frame;
}
- , frame: {
- open: function (url, state, opts) {
- if (opts.debug) {
- opts.timeout = opts.timeout || 15 * 60 * 1000;
- }
+ , frame: function (url, state, opts) {
- var promise = new OAUTH3.PromiseA(function (resolve, reject) {
- var tok;
-
- function cleanup() {
- clearTimeout(tok);
- tok = null;
- delete window['--oauth3-callback-' + state];
- // close is done later in case the window is reused or self-closes synchronously itself / by parent
- // (probably won't ever happen, but that's a negotiable implementation detail)
- }
-
- window['--oauth3-callback-' + state] = function (params) {
- console.log('YOLO!!');
- resolve(params);
- cleanup();
- };
-
- tok = setTimeout(function () {
- var err = new Error("the windowed request did not complete within 3 minutes");
- err.code = "E_TIMEOUT";
- reject(err);
- cleanup();
- }, opts.timeout || 3 * 60 * 1000);
-
- setTimeout(function () {
- if (!promise.child) {
- reject("TODO: open the iframe first and discover oauth3 directives before popup");
- cleanup();
- }
- }, 0);
- });
-
- // TODO allow size changes (via directive even)
- OAUTH3._browser._frames[state] = window.open(
- url
- , 'oauth3-login-' + (opts.reuseWindow || state)
- , 'height=' + (opts.height || 720) + ',width=' + (opts.width || 620)
- );
- // TODO periodically garbage collect expired handlers from window object
- return promise;
- }
+ // TODO allow size changes (via directive even)
+ return window.open(
+ url
+ , 'oauth3-login-' + (opts.reuseWindow || state)
+ , 'height=' + (opts.height || 720) + ',width=' + (opts.width || 620)
+ );
}
}
};