From 6a56024c74767388fcafc6954661f285f0311dde Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Tue, 21 Feb 2017 16:54:37 -0700 Subject: [PATCH] bugfixes from file renames --- oauth3.core.js | 52 +++++++++++++++++++++++-- well-known/oauth3/callback.html | 69 ++++++++++++++++++++++++++++++++- well-known/oauth3/callback.js | 66 ------------------------------- well-known/oauth3/index.html | 15 ++++--- 4 files changed, 125 insertions(+), 77 deletions(-) delete mode 100644 well-known/oauth3/callback.js diff --git a/oauth3.core.js b/oauth3.core.js index 15b2432..cf82eb5 100644 --- a/oauth3.core.js +++ b/oauth3.core.js @@ -20,6 +20,11 @@ // http://stackoverflow.com/questions/9677985/uncaught-typeerror-illegal-invocation-in-chrome return (exports.atob || require('atob'))(base64); } + , btoa: function (b64) { + // for directive passing in .well-known/oauth3 + // http://stackoverflow.com/questions/9677985/uncaught-typeerror-illegal-invocation-in-chrome + return (exports.btoa || require('btoa'))(b64); + } , decodeUrlSafe: function (b64) { // URL-safe Base64 to Base64 // https://en.wikipedia.org/wiki/Base64 @@ -30,6 +35,13 @@ b64 = b64.replace(/-/g, '+').replace(/_/g, '/'); return OAUTH3._base64.atob(b64); } + , encodeUrlSafe: function (b64) { + // for directive passing in .well-known/oauth3 + // Base64 to URL-safe Base64 + b64 = b64.replace(/\+/g, '-').replace(/\//g, '_'); + b64 = b64.replace(/=+/g, ''); + return OAUTH3._base64.btoa(b64); + } } , uri: { normalize: function (uri) { @@ -73,7 +85,38 @@ } } , query: { - stringify: function (params) { + parse: function (search) { + // needed for .well-known/oauth3 + // parse a query or a hash + if (-1 !== ['#', '?'].indexOf(search[0])) { + search = search.substring(1); + } + // Solve for case of search within hash + // example: #/authorization_dialog/?state=...&redirect_uri=... + var queryIndex = search.indexOf('?'); + if (-1 !== queryIndex) { + search = search.substr(queryIndex + 1); + } + + var args = search.split('&'); + var argsParsed = {}; + var i, arg, kvp, key, value; + + for (i = 0; i < args.length; i += 1) { + arg = args[i]; + if (-1 === arg.indexOf('=')) { + argsParsed[decodeURIComponent(arg).trim()] = true; + } + else { + kvp = arg.split('='); + key = decodeURIComponent(kvp[0]).trim(); + value = decodeURIComponent(kvp[1]).trim(); + argsParsed[key] = value; + } + } + return argsParsed; + } + , stringify: function (params) { var qs = []; Object.keys(params).forEach(function (key) { @@ -522,8 +565,6 @@ return OAUTH3._requestHelper(preq, opts); } - OAUTH3.url.resolve(preq.providerUri || preq.provider_uri || preq.directives && preq.directives.issuer, preq.url); - if (!preq.session) { return fetch(); } @@ -757,7 +798,7 @@ , status: xhr.status }); }; - xhr.open(preq.method, preq.url, true); + xhr.open(preq.method || 'GET', preq.url, true); var headers = preq.headers || {}; Object.keys(headers).forEach(function (key) { xhr.setRequestHeader(key, headers[key]); @@ -989,9 +1030,12 @@ , request: function (preq) { preq.client_uri = this._clientUri; preq.client_id = this._clientUri; + preq.method = preq.method || 'GET'; if (this._session) { preq.session = preq.session || OAUTH3.hooks.session._getCached(this._providerUri); } + // TODO maybe use a baseUrl from the directives file? + preq.url = OAUTH3.url.resolve(this._providerUri, preq.url); return OAUTH3.request(preq); } , logout: function (opts) { diff --git a/well-known/oauth3/callback.html b/well-known/oauth3/callback.html index 6cea1d3..b44f95f 100644 --- a/well-known/oauth3/callback.html +++ b/well-known/oauth3/callback.html @@ -16,6 +16,73 @@ - + diff --git a/well-known/oauth3/callback.js b/well-known/oauth3/callback.js deleted file mode 100644 index 9a27470..0000000 --- a/well-known/oauth3/callback.js +++ /dev/null @@ -1,66 +0,0 @@ -;(function () { - 'use strict'; - - var loc = window.location; - var loginWinObj = window.OAUTH3.query.parse(loc.hash || loc.search); - var prefix = "(" + window.location.hostname + ") [.well-known/oauth3/callback.html]"; - - if (loginWinObj.debug) { - console.warn(prefix, "DEBUG MODE ENABLED. Automatic redirects disabled."); - } - // '--oauth3-callback-' prefix exist for security so that an attacker can't social engineer execution an arbitrary function - // TODO finalize name of '--oauth3-callback-', this will be a defacto standard - // TODO maybe call it 'self-xss-' or 'hack-my-account-' to discourage people from doing dumb things? - var callbackName = '--oauth3-callback-' + loginWinObj.state; - - console.log(prefix, loc.href); - console.log(prefix, 'Parsed URL Obj:', loginWinObj); - console.log(prefix, 'callbackName:', callbackName); - - window.oauth3complete = function () { - // The hacks that used to be necessary for this on iOS should no longer be necessary in iOS 9+ - // see https://bugs.chromium.org/p/chromium/issues/detail?id=136610 and https://crbug.com/423444 - // TODO Should we still create an abstraction for older versions? - if (window.parent) { - // iframe - try { - window.parent[callbackName](loginWinObj); - return; - } catch(e) { - console.warn(e); - } - } - - if (window.opener) { - try { - window.opener[callbackName](loginWinObj); - return; - } catch(e) { - console.warn(e); - } - } - - console.error("neither window.parent nor window.opener existed to complete callback"); - - /* - // the caller should close (or signal to close) the window - try { - window.close(); - } catch (err) { - console.log('Error: ', err); - } - */ - }; - - if (!loginWinObj.debug) { - window.oauth3complete(); - } - else { - document.body.innerHTML = window.location.hostname + window.location.pathname - + '

You\'ve passed the \'debug\' parameter so we\'re pausing' - + ' to let you look at logs or whatever it is that you intended to do.' - + '

Continue with callback: javascript:window.oauth3complete()'; - return; - } - -}()); diff --git a/well-known/oauth3/index.html b/well-known/oauth3/index.html index 81f4905..6da3e63 100644 --- a/well-known/oauth3/index.html +++ b/well-known/oauth3/index.html @@ -10,14 +10,16 @@ OAuth3 RPC -