WIP framing refactor
This commit is contained in:
		
							parent
							
								
									bbc557c349
								
							
						
					
					
						commit
						4acad44297
					
				@ -4,10 +4,13 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  var OAUTH3 = exports.OAUTH3 = {
 | 
					  var OAUTH3 = exports.OAUTH3 = {
 | 
				
			||||||
    utils: {
 | 
					    utils: {
 | 
				
			||||||
      atob: function (base64) {
 | 
					      clientUri: function (location) {
 | 
				
			||||||
 | 
					        return OAUTH3.utils.uri.normalize(location.host + location.pathname);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    , atob: function (base64) {
 | 
				
			||||||
        return (exports.atob || require('atob'))(base64);
 | 
					        return (exports.atob || require('atob'))(base64);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    , urlSafeBase64ToBase64: function (b64) {
 | 
					    , _urlSafeBase64ToBase64: function (b64) {
 | 
				
			||||||
        // URL-safe Base64 to Base64
 | 
					        // URL-safe Base64 to Base64
 | 
				
			||||||
        // https://en.wikipedia.org/wiki/Base64
 | 
					        // https://en.wikipedia.org/wiki/Base64
 | 
				
			||||||
        // https://gist.github.com/catwell/3046205
 | 
					        // https://gist.github.com/catwell/3046205
 | 
				
			||||||
@ -43,13 +46,6 @@
 | 
				
			|||||||
            ;
 | 
					            ;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      , getDefaultAppUrl: function () {
 | 
					 | 
				
			||||||
        console.warn('[deprecated] using window.location.{protocol, host, pathname} when opts.client_id should be used');
 | 
					 | 
				
			||||||
        return window.location.protocol
 | 
					 | 
				
			||||||
          + '//' + window.location.host
 | 
					 | 
				
			||||||
          + (window.location.pathname).replace(/\/?$/, '')
 | 
					 | 
				
			||||||
          ;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    , query: {
 | 
					    , query: {
 | 
				
			||||||
        stringify: function (params) {
 | 
					        stringify: function (params) {
 | 
				
			||||||
          var qs = [];
 | 
					          var qs = [];
 | 
				
			||||||
@ -163,11 +159,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      return OAUTH3.PromiseA.resolve(OAUTH3.hooks.directives.get(providerUri)).then(function (directives) {
 | 
					      return OAUTH3.PromiseA.resolve(OAUTH3.hooks.directives.get(providerUri)).then(function (directives) {
 | 
				
			||||||
        if (directives && directives.issuer) {
 | 
					        if (directives && directives.issuer) {
 | 
				
			||||||
          return OAUTH3.PromiseA.resolve(directives);
 | 
					          return directives;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return OAUTH3._discoverHelper(providerUri, opts).then(function (directives) {
 | 
					        return OAUTH3._discoverHelper(providerUri, opts).then(function (directives) {
 | 
				
			||||||
          directives.issuer = directives.issuer || OAUTH3.utils.url.normalize(providerUri);
 | 
					          directives.issuer = directives.issuer || OAUTH3.utils.url.normalize(providerUri);
 | 
				
			||||||
          console.log('discoverHelper', directives);
 | 
					 | 
				
			||||||
          // OAUTH3.PromiseA.resolve() is taken care of because this is wrapped
 | 
					          // OAUTH3.PromiseA.resolve() is taken care of because this is wrapped
 | 
				
			||||||
          return OAUTH3.hooks.directives.set(providerUri, directives);
 | 
					          return OAUTH3.hooks.directives.set(providerUri, directives);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
@ -177,12 +172,181 @@
 | 
				
			|||||||
  , _discoverHelper: function (providerUri, opts) {
 | 
					  , _discoverHelper: function (providerUri, opts) {
 | 
				
			||||||
      return OAUTH3._browser.discover(providerUri, opts);
 | 
					      return OAUTH3._browser.discover(providerUri, opts);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					  , request: function (preq) {
 | 
				
			||||||
 | 
					      return OAUTH3._browser.request(preq);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  , implicitGrant: function(providerUri, opts) {
 | 
				
			||||||
 | 
					      var promise;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (opts.broker) {
 | 
				
			||||||
 | 
					        promise = OAUTH3._discoverThenImplicitGrant(providerUri, opts);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      else {
 | 
				
			||||||
 | 
					        promise = OAUTH3._implicitGrant(providerUri, opts);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return promise.then(function (tokens) {
 | 
				
			||||||
 | 
					        return OAUTH3.hooks.refreshSession(
 | 
				
			||||||
 | 
					          opts.session || {
 | 
				
			||||||
 | 
					            provider_uri: providerUri
 | 
				
			||||||
 | 
					          , client_id: opts.client_id
 | 
				
			||||||
 | 
					          , client_uri: opts.client_uri || opts.clientUri
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        , tokens
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  , _discoverThenImplicitGrant: function(providerUri, opts) {
 | 
				
			||||||
 | 
					      opts.windowType = opts.windowType || 'popup';
 | 
				
			||||||
 | 
					      return OAUTH3._discover(providerUri, opts).then(function (directives) {
 | 
				
			||||||
 | 
					        return OAUTH3._implicitGrant(directives, opts).then(function (tokens) {
 | 
				
			||||||
 | 
					          OAUTH3._browser.closeFrame(tokens.state || opts._state);
 | 
				
			||||||
 | 
					          opts._state = undefined;
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  , _discover: function(providerUri, opts) {
 | 
				
			||||||
 | 
					      providerUri = OAUTH3.utils.url.normalize(providerUri);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (providerUri.match(OAUTH3._browser.window.location.hostname)) {
 | 
				
			||||||
 | 
					        console.warn("It looks like you're a provider checking for your own directive,"
 | 
				
			||||||
 | 
					          + " so we we're just gonna use"
 | 
				
			||||||
 | 
					          + " OAUTH3.request({ method: 'GET', url: '.well-known/oauth3/directive.json' })");
 | 
				
			||||||
 | 
					        return OAUTH3.request({
 | 
				
			||||||
 | 
					          method: 'GET'
 | 
				
			||||||
 | 
					        , url: OAUTH3.utils.url.normalize(providerUri) + '/.well-known/oauth3/directives.json'
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (!(opts.client_id || opts.client_uri).match(OAUTH3._browser.window.location.hostname)) {
 | 
				
			||||||
 | 
					        console.warn("It looks like your client_id doesn't match your current window..."
 | 
				
			||||||
 | 
					          + " this probably won't end well");
 | 
				
			||||||
 | 
					        console.warn(opts.client_id || opts.client_uri, OAUTH3._browser.window.location.hostname);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      var discReq = OAUTH3.urls.discover(
 | 
				
			||||||
 | 
					        providerUri
 | 
				
			||||||
 | 
					      , { client_id: (opts.client_id || opts.client_uri || OAUTH3.clientUri(OAUTH3._browser.window.location))
 | 
				
			||||||
 | 
					        , windowType: opts.broker && opts.windowType || 'background'
 | 
				
			||||||
 | 
					        , broker: opts.broker
 | 
				
			||||||
 | 
					        , debug: opts.debug
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					      opts._state = discReq.state;
 | 
				
			||||||
 | 
					      //var discReq = OAUTH3.urls.discover(providerUri, opts);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // hmm... we're gonna need a broker for this since switching windows is distracting,
 | 
				
			||||||
 | 
					      // popups are obnoxious, iframes are sometimes blocked, and most servers don't implement CORS
 | 
				
			||||||
 | 
					      // eventually it should be the browser (and postMessage may be a viable option now), but whatever...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // TODO allow postMessage from providerUri in addition to callback
 | 
				
			||||||
 | 
					      // TODO allow node to open a desktop browser window
 | 
				
			||||||
 | 
					      return OAUTH3._browser.frameRequest(
 | 
				
			||||||
 | 
					        discReq.url
 | 
				
			||||||
 | 
					      , discReq.state
 | 
				
			||||||
 | 
					      , { windowType: opts.windowType
 | 
				
			||||||
 | 
					        , reuseWindow: opts.broker && '-broker'
 | 
				
			||||||
 | 
					        , debug: opts.debug
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      ).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)));
 | 
				
			||||||
 | 
					        return OAUTH3.hooks.directives.set(providerUri, directives);
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  , _implicitGrant: function(providerUri, opts) {
 | 
				
			||||||
 | 
					      // TODO this may need to be synchronous for browser security policy
 | 
				
			||||||
 | 
					      return OAUTH3.PromiseA.resolve(OAUTH3.hooks.directives.get(providerUri)).then(function (directives) {
 | 
				
			||||||
 | 
					        // Do some stuff
 | 
				
			||||||
 | 
					        var authReq = OAUTH3.urls.implicitGrant(
 | 
				
			||||||
 | 
					          directives
 | 
				
			||||||
 | 
					        , { redirect_uri: opts.redirect_uri
 | 
				
			||||||
 | 
					          , client_id: opts.client_id || opts.client_uri
 | 
				
			||||||
 | 
					          , client_uri: opts.client_uri || opts.client_id
 | 
				
			||||||
 | 
					          , state: opts._state
 | 
				
			||||||
 | 
					          , debug: opts.debug
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (opts.debug) {
 | 
				
			||||||
 | 
					          window.alert("DEBUG MODE: Pausing so you can look at logs and whatnot :) Fire at will!");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return new OAUTH3.PromiseA(function (resolve, reject) {
 | 
				
			||||||
 | 
					          return OAUTH3._browser.frameRequest(
 | 
				
			||||||
 | 
					            authReq.url
 | 
				
			||||||
 | 
					          , authReq.state // state should recycle params
 | 
				
			||||||
 | 
					          , { windowType: opts.windowType
 | 
				
			||||||
 | 
					            , reuseWindow: opts.broker && '-broker'
 | 
				
			||||||
 | 
					            , debug: opts.debug
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          ).then(function (tokens) {
 | 
				
			||||||
 | 
					            if (tokens.error) {
 | 
				
			||||||
 | 
					              return reject(OAUTH3.utils._formatError(tokens.error));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            OAUTH3._browser.closeFrame(authReq.state, { debug: opts.debug || tokens.debug });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return tokens;
 | 
				
			||||||
 | 
					          });
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    // Let the Code Waste begin!!
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
  , _browser: {
 | 
					  , _browser: {
 | 
				
			||||||
      discover: function (providerUri, opts) {
 | 
					      window: window
 | 
				
			||||||
 | 
					      // TODO we don't need to include this if we're using jQuery or angular
 | 
				
			||||||
 | 
					    , request: function (preq, _sys) {
 | 
				
			||||||
 | 
					        return new OAUTH3.PromiseA(function (resolve, reject) {
 | 
				
			||||||
 | 
					          var xhr;
 | 
				
			||||||
 | 
					          try {
 | 
				
			||||||
 | 
					            xhr = new XMLHttpRequest(_sys);
 | 
				
			||||||
 | 
					          } catch(e) {
 | 
				
			||||||
 | 
					            xhr = new XMLHttpRequest();
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          xhr.onreadystatechange = function () {
 | 
				
			||||||
 | 
					            console.error('state change');
 | 
				
			||||||
 | 
					            var data;
 | 
				
			||||||
 | 
					            if (xhr.readyState !== XMLHttpRequest.DONE) {
 | 
				
			||||||
 | 
					              // nothing to do here
 | 
				
			||||||
 | 
					              return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (xhr.status !== 200) {
 | 
				
			||||||
 | 
					              reject(new Error('bad status code: ' + xhr.status));
 | 
				
			||||||
 | 
					              return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					              data = JSON.parse(xhr.responseText);
 | 
				
			||||||
 | 
					            } catch(e) {
 | 
				
			||||||
 | 
					              data = xhr.responseText;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            resolve({
 | 
				
			||||||
 | 
					              request: xhr
 | 
				
			||||||
 | 
					            , data: data
 | 
				
			||||||
 | 
					            , status: xhr.status
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					          };
 | 
				
			||||||
 | 
					          xhr.open(preq.method, preq.url, true);
 | 
				
			||||||
 | 
					          var headers = preq.headers || {};
 | 
				
			||||||
 | 
					          Object.keys(headers).forEach(function (key) {
 | 
				
			||||||
 | 
					            xhr.setRequestHeader(key, headers[key]);
 | 
				
			||||||
 | 
					          });
 | 
				
			||||||
 | 
					          xhr.send();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    , discover: function (providerUri, opts) {
 | 
				
			||||||
        opts = opts || {};
 | 
					        opts = opts || {};
 | 
				
			||||||
        //opts.debug = true;
 | 
					        //opts.debug = true;
 | 
				
			||||||
        providerUri = OAUTH3.utils.url.normalize(providerUri);
 | 
					        providerUri = OAUTH3.utils.url.normalize(providerUri);
 | 
				
			||||||
        if (window.location.hostname.match(providerUri)) {
 | 
					        if (providerUri.match(OAUTH3._browser.window.location.hostname)) {
 | 
				
			||||||
          console.warn("It looks like you're a provider checking for your own directive,"
 | 
					          console.warn("It looks like you're a provider checking for your own directive,"
 | 
				
			||||||
            + " so we we're just gonna use OAUTH3.request({ method: 'GET', url: '.well-known/oauth3/directive.json' })");
 | 
					            + " so we we're just gonna use OAUTH3.request({ method: 'GET', url: '.well-known/oauth3/directive.json' })");
 | 
				
			||||||
          return OAUTH3.request({
 | 
					          return OAUTH3.request({
 | 
				
			||||||
@ -191,81 +355,195 @@
 | 
				
			|||||||
          });
 | 
					          });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!window.location.hostname.match(opts.client_id || opts.client_uri)) {
 | 
					        if (!(opts.client_id || opts.client_uri).match(OAUTH3._browser.window.location.hostname)) {
 | 
				
			||||||
          console.warn("It looks like your client_id doesn't match your current window... this probably won't end well");
 | 
					          console.warn("It looks like your client_id doesn't match your current window... this probably won't end well");
 | 
				
			||||||
          console.warn(opts.client_id || opts.client_uri, window.location.hostname);
 | 
					          console.warn(opts.client_id || opts.client_uri, OAUTH3._browser.window.location.hostname);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        var discObj = OAUTH3.urls.discover(
 | 
					        var discObj = OAUTH3.urls.discover(
 | 
				
			||||||
          providerUri
 | 
					          providerUri
 | 
				
			||||||
        , { client_id: (opts.client_id || opts.client_uri || OAUTH3.utils.getDefaultAppUrl()), debug: opts.debug }
 | 
					        , { client_id: (opts.client_id || opts.client_uri || OAUTH3.clientUri(OAUTH3._browser.window.location)), debug: opts.debug }
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // TODO ability to reuse iframe instead of closing
 | 
					        // TODO ability to reuse iframe instead of closing
 | 
				
			||||||
        return OAUTH3._browser.iframe.insert(discObj.url, discObj.state, opts).then(function (params) {
 | 
					        return OAUTH3._browser._iframe.insert(discObj.url, discObj.state, opts).then(function (params) {
 | 
				
			||||||
          OAUTH3._browser.iframe.remove(discObj.state);
 | 
					          OAUTH3._browser.closeFrame(discObj.state, { debug: opts.debug || params.debug });
 | 
				
			||||||
          if (params.error) {
 | 
					          if (params.error) {
 | 
				
			||||||
            return OAUTH3.utils._formatError(providerUri, params.error);
 | 
					            return OAUTH3.utils._formatError(providerUri, params.error);
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
          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 directives;
 | 
					          return directives;
 | 
				
			||||||
        }, function (err) {
 | 
					        }, function (err) {
 | 
				
			||||||
          OAUTH3._browser.iframe.remove(discObj.state);
 | 
					          OAUTH3._browser.closeFrame(discObj.state, { debug: opts.debug || err.debug });
 | 
				
			||||||
          return OAUTH3.PromiseA.reject(err);
 | 
					          return OAUTH3.PromiseA.reject(err);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					    , frameRequest: function (url, state, opts) {
 | 
				
			||||||
 | 
					        var previousFrame = OAUTH3._browser._frames[state];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!opts.windowType) {
 | 
				
			||||||
 | 
					          opts.windowType = 'popup';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        opts = opts || {};
 | 
				
			||||||
 | 
					        if (opts.debug) {
 | 
				
			||||||
 | 
					          opts.timeout = opts.timeout || 15 * 60 * 1000;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return new OAUTH3.PromiseA(function (resolve, reject) {
 | 
				
			||||||
 | 
					          var tok;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          function cleanup() {
 | 
				
			||||||
 | 
					            delete window['--oauth3-callback-' + state];
 | 
				
			||||||
 | 
					            clearTimeout(tok);
 | 
				
			||||||
 | 
					            tok = null;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          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");
 | 
				
			||||||
 | 
					            err.code = "E_TIMEOUT";
 | 
				
			||||||
 | 
					            reject(err);
 | 
				
			||||||
 | 
					            cleanup();
 | 
				
			||||||
 | 
					          }, opts.timeout || 15 * 1000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          if ('background' === opts.windowType) {
 | 
				
			||||||
 | 
					            if (previousFrame) {
 | 
				
			||||||
 | 
					              previousFrame.location = url;
 | 
				
			||||||
 | 
					              //promise = previousFrame.promise;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else {
 | 
				
			||||||
 | 
					              OAUTH3._browser._iframe.insert(url, state, opts);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          } else if ('popup' === opts.windowType) {
 | 
				
			||||||
 | 
					            if (previousFrame) {
 | 
				
			||||||
 | 
					              previousFrame.location = url;
 | 
				
			||||||
 | 
					              if (opts.debug) {
 | 
				
			||||||
 | 
					                previousFrame.focus();
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else {
 | 
				
			||||||
 | 
					              OAUTH3._browser.frame.open(url, state, opts);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          } else if ('inline' === opts.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;
 | 
				
			||||||
 | 
					            OAUTH3._browser.window.location = url;
 | 
				
			||||||
 | 
					            //promise = OAUTH3.PromiseA.resolve({ url: url });
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            throw new Error("login framing method options.windowType="
 | 
				
			||||||
 | 
					              + opts.windowType + " not type yet implemented");
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }).then(function (params) {
 | 
				
			||||||
 | 
					          var err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          if (params.error || params.error_description) {
 | 
				
			||||||
 | 
					            err = new Error(params.error_description || "Unknown response error");
 | 
				
			||||||
 | 
					            err.code = params.error || "E_UKNOWN_ERROR";
 | 
				
			||||||
 | 
					            err.params = params;
 | 
				
			||||||
 | 
					            //_formatError
 | 
				
			||||||
 | 
					            return OAUTH3.PromiseA.reject(err);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          return params;
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    , closeFrame: function (state, opts) {
 | 
				
			||||||
 | 
					        function close() {
 | 
				
			||||||
 | 
					          try {
 | 
				
			||||||
 | 
					            OAUTH3._browser._frames[state].close();
 | 
				
			||||||
 | 
					          } catch(e) {
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					              OAUTH3._browser._frames[state].remove();
 | 
				
			||||||
 | 
					            } catch(e) {
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          delete OAUTH3._browser._frames[state];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (opts.debug) {
 | 
				
			||||||
 | 
					          if (window.confirm("DEBUG MODE: okay to close oauth3 window?")) {
 | 
				
			||||||
 | 
					            close();
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
 | 
					          close();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    , _frames: {}
 | 
				
			||||||
    , iframe: {
 | 
					    , iframe: {
 | 
				
			||||||
        _frames: {}
 | 
					        insert: function (url, state, opts) {
 | 
				
			||||||
      , insert: function (url, state, opts) {
 | 
					          // TODO hidden / non-hidden (via directive even)
 | 
				
			||||||
          opts = opts || {};
 | 
					          var framesrc = '<iframe class="js-oauth3-iframe" src="' + url + '" ';
 | 
				
			||||||
 | 
					          if (opts.debug) {
 | 
				
			||||||
 | 
					            framesrc += ' width="800px" height="800px" style="opacity: 0.8;" frameborder="1"';
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          else {
 | 
				
			||||||
 | 
					            framesrc += ' width="1px" height="1px" frameborder="0"';
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          framesrc += '></iframe>';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          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;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    , frame: {
 | 
				
			||||||
 | 
					        open: function (url, state, opts) {
 | 
				
			||||||
          if (opts.debug) {
 | 
					          if (opts.debug) {
 | 
				
			||||||
            opts.timeout = opts.timeout || 15 * 60 * 1000;
 | 
					            opts.timeout = opts.timeout || 15 * 60 * 1000;
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          var promise = new OAUTH3.PromiseA(function (resolve, reject) {
 | 
					          var promise = new OAUTH3.PromiseA(function (resolve, reject) {
 | 
				
			||||||
            var tok;
 | 
					            var tok;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            function cleanup() {
 | 
					            function cleanup() {
 | 
				
			||||||
              delete window['--oauth3-callback-' + state];
 | 
					 | 
				
			||||||
              clearTimeout(tok);
 | 
					              clearTimeout(tok);
 | 
				
			||||||
              tok = null;
 | 
					              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) {
 | 
					            window['--oauth3-callback-' + state] = function (params) {
 | 
				
			||||||
 | 
					              console.log('YOLO!!');
 | 
				
			||||||
              resolve(params);
 | 
					              resolve(params);
 | 
				
			||||||
              cleanup();
 | 
					              cleanup();
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            tok = setTimeout(function () {
 | 
					            tok = setTimeout(function () {
 | 
				
			||||||
              var err = new Error("the iframe request did not complete within 15 seconds");
 | 
					              var err = new Error("the windowed request did not complete within 3 minutes");
 | 
				
			||||||
              err.code = "E_TIMEOUT";
 | 
					              err.code = "E_TIMEOUT";
 | 
				
			||||||
              reject(err);
 | 
					              reject(err);
 | 
				
			||||||
              cleanup();
 | 
					              cleanup();
 | 
				
			||||||
            }, opts.timeout || 15 * 1000);
 | 
					            }, opts.timeout || 3 * 60 * 1000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // TODO hidden / non-hidden (via directive even)
 | 
					            setTimeout(function () {
 | 
				
			||||||
            var framesrc = '<iframe class="js-oauth3-iframe" src="' + url + '" ';
 | 
					              if (!promise.child) {
 | 
				
			||||||
            if (opts.debug) {
 | 
					                reject("TODO: open the iframe first and discover oauth3 directives before popup");
 | 
				
			||||||
              framesrc += ' width="800px" height="800px" style="opacity: 0.8;" frameborder="1"';
 | 
					                cleanup();
 | 
				
			||||||
            }
 | 
					              }
 | 
				
			||||||
            else {
 | 
					            }, 0);
 | 
				
			||||||
              framesrc += ' width="1px" height="1px" frameborder="0"';
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            framesrc += '></iframe>';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            OAUTH3._browser.iframe._frames[state] = window.document.createElement('div');
 | 
					 | 
				
			||||||
            OAUTH3._browser.iframe._frames[state].innerHTML = framesrc;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            window.document.body.appendChild(OAUTH3._browser.iframe._frames[state]);
 | 
					 | 
				
			||||||
          });
 | 
					          });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          // 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
 | 
					          // TODO periodically garbage collect expired handlers from window object
 | 
				
			||||||
          return promise;
 | 
					          return promise;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      , remove: function (state) {
 | 
					 | 
				
			||||||
          if (OAUTH3._browser.iframe._frames[state]) {
 | 
					 | 
				
			||||||
            OAUTH3._browser.iframe._frames[state].remove();
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          delete OAUTH3._browser.iframe._frames[state];
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user