diff --git a/.well-known/oauth3/callback.html b/.well-known/oauth3/callback.html
new file mode 100644
index 0000000..6cea1d3
--- /dev/null
+++ b/.well-known/oauth3/callback.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+ Redirecting...
+
+
+
+ Redirecting...
+
+
+
+
+
+
+
diff --git a/.well-known/oauth3/callback.js b/.well-known/oauth3/callback.js
new file mode 100644
index 0000000..a9c7c88
--- /dev/null
+++ b/.well-known/oauth3/callback.js
@@ -0,0 +1,66 @@
+(function () {
+ "use strict";
+
+ var loc = window.location;
+ var loginWinObj = window.OAUTH3_CORE.queryparse(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('Parsed URL Obj: ', loginWinObj);
+ console.log('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()' + 'a>';
+ return;
+ }
+
+}());
diff --git a/.well-known/oauth3/crossdomain.html b/.well-known/oauth3/crossdomain.html
new file mode 100644
index 0000000..e69de29
diff --git a/.well-known/oauth3/crossdomain.js b/.well-known/oauth3/crossdomain.js
new file mode 100644
index 0000000..e69de29
diff --git a/.well-known/oauth3/directives.js b/.well-known/oauth3/directives.js
new file mode 100644
index 0000000..43e8efc
--- /dev/null
+++ b/.well-known/oauth3/directives.js
@@ -0,0 +1,330 @@
+(function () {
+ 'use strict';
+
+ console.log('[DAPLIE oauth3 directives.js]');
+ console.log(window.location);
+
+ var iter = 0;
+
+ function main() {
+
+ var rpc = {};
+ //var myself = location.protocol + '//' + location.host + location.pathname;
+ var incoming;
+ var forwarding = {};
+ var err;
+ var browserState;
+ var browserCallback;
+ var action;
+
+ function parseParams() {
+ var params = {};
+
+ function parseParamsString(str) {
+ str.substr(1).split('&').filter(function (el) { return el; }).forEach(function (pair) {
+ pair = pair.split('=');
+ var key = decodeURIComponent(pair[0]);
+ var val = decodeURIComponent(pair[1]);
+
+ if (params[key]) {
+ console.warn("overwriting key '" + key + "' '" + params[key] + "'");
+ }
+ params[key] = val;
+ });
+ }
+
+ parseParamsString(window.location.search);
+ // handle cases where hash is treated like it's own href
+ // TODO /#/?search=blah
+ parseParamsString(window.location.hash);
+
+ return params;
+ }
+
+ function querystringify(params) {
+ var arr = [];
+
+ Object.keys(params).forEach(function (k) {
+ arr.push(encodeURIComponent(k) + '=' + encodeURIComponent(params[k]));
+ });
+
+ return arr.join('&');
+ }
+
+ function phoneAway(/*redirectURi, params*/) {
+ // TODO test for ? / #
+ window.location.href = incoming.redirect_uri + '#' + querystringify(forwarding);
+ }
+
+ function lintAndSetRedirectable(browserState, params) {
+ if (!params.redirect_uri) {
+ window.alert('redirect_uri not defined');
+ err = new Error('redirect_uri not defined');
+ console.error(err.message);
+ console.warn(err.stack);
+ params.redirect_uri = document.referer;
+ return false;
+ }
+
+ if (!browserState) {
+ forwarding.error = "E_NO_BROWSER_STATE";
+ forwarding.error_description = "you must specify a state parameter";
+ return false;
+ }
+
+ localStorage.setItem('oauth3.states.' + browserState, JSON.stringify(params));
+ return true;
+ }
+
+ function redirectCallback() {
+ var redirect_uri = incoming.redirect_uri;
+ forwarding.callback = browserState;
+ forwarding.action = 'close';
+
+ var url = redirect_uri + '#' + querystringify(forwarding);
+
+ console.log('[debug] redirect_uri + params:', url);
+ window.location.href = url;
+ setTimeout(function () {
+ if (iter >= 3) {
+ console.log("dancing way too much... stopping now");
+ return;
+ }
+ iter += 1;
+ console.log("I'm dancing by myse-e-elf");
+ // in case I'm redirecting to myself
+ main();
+ }, 0);
+ }
+
+ rpc = {};
+
+ // Act as a provider and log the user out
+ rpc.logout = function (browserState, incoming) {
+ var url;
+ if (!lintAndSetRedirectable(browserState, incoming)) {
+ // TODO fail
+ }
+
+ localStorage.setItem('oauth3.states.' + browserState, JSON.stringify(incoming));
+ url = '/#/logout/' + browserState;
+
+ // TODO specify specific account or all?
+ window.location.href = url;
+ setTimeout(function () {
+ // in case I'm redirecting to myself
+ main();
+ }, 0);
+ };
+
+ // Act as a provider and inform the consumer the logout is complete
+ rpc.logout_callback = function (browserState/*, incoming*/) {
+ // TODO pass redirect_uri and state through here so we can avoid localStorage
+ var forwarding = {};
+ var originalRequest;
+
+ if (!browserState) {
+ forwarding.error = "E_NO_BROWSER_STATE";
+ forwarding.error_description = "you must specify a state parameter";
+ if (incoming.redirect_uri) {
+ phoneAway(incoming.redirect_uri, forwarding);
+ }
+ return;
+ }
+
+ originalRequest = JSON.parse(localStorage.getItem('oauth3.states.' + browserState));
+ forwarding.action = 'close';
+ forwarding.state = browserState;
+ //phoneAway(originalRequest.redirect_uri, forwarding);
+ window.location.href = originalRequest.redirect_uri + '#' + querystringify(forwarding);
+ };
+
+ rpc.directives = function (browserState, incoming) {
+ if (!lintAndSetRedirectable(browserState, incoming)) {
+ phoneAway();
+ return;
+ }
+
+ var updatedAt = new Date(localStorage.getItem('oauth3.directives.updated_at')).valueOf();
+ var fresh = (Date.now() - updatedAt) < (24 * 60 * 60 * 1000);
+ var directives = localStorage.getItem('oauth3.directives');
+ var redirected = false;
+
+ function redirectIf() {
+ if (redirected) {
+ return;
+ }
+
+ redirected = true;
+ redirectCallback();
+ }
+
+ if (directives) {
+ forwarding.directives = directives;
+ redirectIf();
+ if (fresh) {
+ return;
+ }
+ }
+
+ var req = new XMLHttpRequest();
+ req.open('GET', '.well-known/oauth3.json', true);
+ req.addEventListener('readystatechange', function () {
+ if (4 !== req.readyState) {
+ return;
+ }
+
+ if (200 !== req.status) {
+ forwarding.error = "E_STATUS_" + req.status;
+ forwarding.error_description = "expected 200 OK json or text response for oauth3.json but got '" + req.status + "'";
+ redirectIf();
+ return;
+ }
+
+ try {
+ directives = btoa(JSON.stringify(JSON.parse(req.responseText)));
+ forwarding.directives = directives;
+ forwarding.callback = browserState;
+ localStorage.setItem('oauth3.directives', directives);
+ localStorage.setItem('oauth3.directives.updated_at', new Date().toISOString());
+ } catch(e) {
+ forwarding.error = "E_PARSE_JSON";
+ forwarding.error_description = e.message;
+ console.error(forwarding.error);
+ console.error(forwarding.error_description);
+ console.error(req.responseText);
+ }
+
+ redirectIf();
+ });
+ req.send();
+ };
+
+ // the provider is contacting me
+ rpc.close = function (browserState, incoming) {
+ incoming.callback = browserState;
+ catchAll();
+ };
+ // the provider is contacting me
+ rpc.redirect = function (/*browserState, incoming*/) {
+ catchAll();
+ };
+
+ function catchAll() {
+ function phoneHome() {
+ if (browserCallback === 'completeLogin') {
+ // Deprecated
+ console.log('[deprecated] callback completeLogin');
+ (window.opener||window.parent).completeLogin(null, null, incoming);
+ } else {
+ console.log('[DEBUG] I would be closed by my parent now');
+ console.log('__oauth3_' + browserCallback);
+ console.log(window.opener && window.opener['__oauth3_' + browserCallback]);
+ console.log(window.parent && window.parent['__oauth3_' + browserCallback]);
+ console.log(incoming);
+ (window.opener||window.parent)['__oauth3_' + browserCallback](incoming);
+ }
+ }
+
+ if (!(incoming.browser_state || incoming.state)) {
+ window.alert("callback URLs should include 'browser_state' (authorization code)"
+ + " or 'state' (implicit grant))");
+ }
+
+ setTimeout(function () {
+ // opener is for popup window, new tab
+ // parent is for iframe
+ phoneHome();
+ }, 10);
+
+ // iOS Webview (namely Chrome) workaround
+ setTimeout(function () {
+ console.log('I would close now');
+ // XXX OAUTH3 DEBUG FRAME XXX // make this easy to find
+ window.open('', '_self', '');
+ window.close();
+ }, 50);
+
+ setTimeout(function () {
+ var i;
+ var len = localStorage.length;
+ var key;
+ var json;
+ var fresh;
+
+ for (i = 0; i < len; i += 1) {
+ key = localStorage.key(i);
+ // TODO check updatedAt
+ if (/^oauth3\./.test(key)) {
+ try {
+ json = localStorage.getItem(key);
+ if (json) {
+ json = JSON.parse(json);
+ }
+ } catch (e) {
+ // ignore
+ json = null;
+ }
+
+ fresh = json && (Date.now() - json.updatedAt < (5 * 60 * 1000));
+
+ if (!fresh) {
+ localStorage.removeItem(key);
+ }
+ }
+ }
+ forwarding.updatedAt = Date.now();
+ localStorage.setItem('oauth3.' + (forwarding.browser_state || forwarding.state), JSON.stringify(forwarding));
+ }, 0);
+
+ }
+
+ function parseAction(params) {
+ if (params.action) {
+ return params.action;
+ }
+
+ if (params.close) {
+ return 'close';
+ }
+ if (params.logout_callback) {
+ return 'logout_callback';
+ }
+ if (params.logout) {
+ return 'logout';
+ }
+ if (params.callback) {
+ return 'close';
+ }
+ if (params.directives) {
+ return 'directives';
+ }
+
+ return 'redirect';
+ }
+
+ incoming = parseParams();
+ browserState = incoming.browser_state || incoming.state;
+ action = parseAction(incoming);
+ forwarding.url = window.location.href;
+ forwarding.browser_state = browserState;
+ forwarding.state = browserState;
+
+ if (!incoming.provider_uri) {
+ browserCallback = incoming.callback || browserState;
+ } else {
+ // deprecated
+ browserCallback = 'completeLogin';
+ }
+
+ console.log('[debug]', action, incoming);
+
+ if (rpc[action]) {
+ rpc[action](browserState, incoming);
+ } else {
+ window.alert('unsupported action');
+ }
+ }
+
+ main();
+}());
diff --git a/.well-known/oauth3/directives.json b/.well-known/oauth3/directives.json
new file mode 100644
index 0000000..d482bc8
--- /dev/null
+++ b/.well-known/oauth3/directives.json
@@ -0,0 +1,9 @@
+{ "authorization_dialog": { "url": "#/authorization_dialog" }
+, "access_token": { "method": "POST", "url": "api/org.oauth3.provider/access_token" }
+, "otp": { "method": "POST" , "url": "api/org.oauth3.provider/otp" }
+, "credential_otp": { "method": "POST" , "url": "api/org.oauth3.provider/otp" }
+, "credential_meta": { "url": "api/org.oauth3.provider/logins/meta/:type/:id" }
+, "credential_create": { "method": "POST" , "url": "api/org.oauth3.provider/logins" }
+, "grants": { "method": "GET", "url": "api/org.oauth3.provider/grants/:azp/:sub" }
+, "authorization_decision": { "method": "POST", "url": "api/org.oauth3.provider/authorization_decision" }
+}
diff --git a/.well-known/oauth3/index.html b/.well-known/oauth3/index.html
new file mode 100644
index 0000000..81f4905
--- /dev/null
+++ b/.well-known/oauth3/index.html
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+ OAuth3 RPC
+
+
+
+
+
+
diff --git a/.well-known/oauth3/logout.html b/.well-known/oauth3/logout.html
new file mode 100644
index 0000000..e69de29
diff --git a/.well-known/oauth3/logout.js b/.well-known/oauth3/logout.js
new file mode 100644
index 0000000..e69de29
diff --git a/README.md b/README.md
index 5eda2ef..7026037 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,88 @@
oauth3.js
=========
+The world's smallest, fastest, and most secure OAuth3 (and OAuth2) JavaScript implementation
+(Yes! works in browsers and node.js with no extra dependencies or bloat and no hacks!)
+
+Instead of bloating your webapp and ruining the mobile experience,
+you can use a single, small javascript file for all OAuth3 providers
+(and almost all OAuth2 providers) with a seemless experience.
+
+Also, instead of complicated (or worse - insecure) CLI and Desktop login methods,
+you can easily integrate an OAuth3 flow (or broker) into any node.js app (i.e. Electron, Node-Webkit)
+with 0 pain.
+
+Installation
+------------
+
+**Easy Install** for Web Apps (including Mobile):
+
+1. In your web site / web app folder create a folder called `assets`
+2. Inside of `assets` create another folder called `org.oauth3`
+3. Download [oauth.js-v1.zip](https://git.daplie.com/Daplie/oauth3.js/repository/archive.zip?ref=v1)
+4. Double-click to unzip the folder.
+5. Copy `oauth3.js` and `oauth3.browser.js` to `assets/org.oauth3`
+
+**Advanced Installation with `git`**
+
+```
+# Navigate to your web site or web app
+pushd /path/to/your/web/app
+
+
+# clone the project as assets/org.oauth3
+mkdir -p assets
+git clone git@git.daplie.com:Daplie/oauth3.js.git assets/org.oauth3
+pushd assests/org.oauth3
+git checkout v1
+popd
+
+
+# symlink `.well-known/oauth3` to `assets/org.oauth3/.well-known/oauth3`
+mkdir -p .well-known
+ln -sf ../assets/org.oauth3/.well-known/oauth3 .well-known/oauth3
+```
+
+**Advanced Installation with `bower`**
+
+```
+# Install to bower_components
+bower install oauth3
+
+
+# create a `.well-known` folder and an `assets` folder
+mkdir -p .well-known assets
+
+
+# symlink `.well-known/oauth3` to `bower_components/oauth3/.well-known/oauth3`
+ln -sf ../bower_components/oauth3/.well-known/oauth3 .well-known/oauth3
+
+
+# symlink `assets/org.oauth3` to `bower_components/oauth3`
+ln -sf ../bower_components/oauth3/.well-known/oauth3 .well-known/oauth3
+ln -sf ../bower_components/oauth3 assets/org.oauth3
+```
+
+Usage
+-----
+
+Update your HTML to include the the following script tags:
+
+```
+
+
+```
+
+If you use jQuery you should also include
+
+```
+
+```
+
+
+Stable API
+----------
+
Public utilities for browser and node.js:
* `querystringify(query)`
@@ -14,6 +96,25 @@ URL generation:
* `loginCode`
* `resourceOwnerPassword`
+Roadmap
+-------
+
+* v1.0 - "implicit grant" authorization with examples
+ * popup
+ * iframe
+ * documentation
+* v1.1 - cleanup
+ * in-flow discovery
+ * smallest possible size
+ * inline windowing (non-promisable callback)
+ * async set/get
+ * logout
+* v1.2 - features
+ * "authorization code" flow
+ * "broker" flow
+* v1.3 - features
+ * remove grants
+
URI vs URL
----------
diff --git a/oauth3.browser.js b/oauth3.browser.js
index a8a9218..7805971 100644
--- a/oauth3.browser.js
+++ b/oauth3.browser.js
@@ -13,7 +13,8 @@
}
var browser = exports.OAUTH3_BROWSER = {
- clientUri: function (location) {
+ window: window
+ , clientUri: function (location) {
return OAUTH3_CORE.normalizeUri(location.host + location.pathname);
}
, discover: function (providerUri, opts) {
@@ -118,18 +119,36 @@
resolve(tokens);
};
});
+ }).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
+ );
});
}
, frameRequest: function (url, state, opts) {
var promise;
- if ('background' === opts.type) {
+ if (!opts.windowType) {
+ opts.windowType = 'popup';
+ }
+
+ if ('background' === opts.windowType) {
promise = browser.insertIframe(url, state, opts);
- } else if ('popup' === opts.type) {
+ } else if ('popup' === opts.windowType) {
promise = browser.openWindow(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=' + browser.window.location.href;
+ promise = browser.window.location = url;
} else {
- throw new Error("login framing method not specified or not type yet implemented");
+ throw new Error("login framing method options.windowType not specified or not type yet implemented");
}
return promise.then(function (params) {
@@ -245,7 +264,7 @@
//
// Logins
//
- , requests: {
+ , authn: {
authorizationRedirect: function (providerUri, opts) {
// TODO get own directives
@@ -260,9 +279,19 @@
}
return browser.frameRequest(prequest.url, prequest.state, opts);
+ }).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
+ );
});
}
, implicitGrant: function (providerUri, opts) {
+ // TODO let broker=true change behavior to open discover inline with frameRequest
// TODO OAuth3 provider should use the redirect URI as the appId?
return OAUTH3.discover(providerUri, opts).then(function (directive) {
var prequest = OAUTH3_CORE.urls.implicitGrant(
@@ -276,6 +305,15 @@
}
return browser.frameRequest(prequest.url, prequest.state, opts);
+ }).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
+ );
});
}
, logout: function (providerUri, opts) {
@@ -455,14 +493,14 @@
, code: data.code
- , access_token: data.accessToken
- , expires_at: data.expiresAt
- , expires_in: data.expiresIn
+ , access_token: data.access_token
+ , expires_at: data.expires_at
+ , expires_in: data.expires_in
, scope: data.scope
- , refresh_token: data.refreshToken
- , refresh_expires_at: data.refreshExpiresAt
- , refresh_expires_in: data.refreshExpiresIn
+ , refresh_token: data.refresh_token
+ , refresh_expires_at: data.refresh_expires_at
+ , refresh_expires_in: data.refresh_expires_in
});
if ('token' === scope.appQuery.response_type) {
@@ -507,6 +545,7 @@
}, 50);
}
};
+ browser.requests = browser.authn;
Object.keys(browser).forEach(function (key) {
if ('requests' === key) {
diff --git a/oauth3.core.js b/oauth3.core.js
index 0c2b426..a280465 100644
--- a/oauth3.core.js
+++ b/oauth3.core.js
@@ -175,10 +175,10 @@
, signature: parts[2] // should remain url-safe base64
};
}
- , getFreshness: function (meta, staletime, now) {
+ , getFreshness: function (tokenMeta, staletime, now) {
staletime = staletime || (15 * 60);
now = now || Date.now();
- var fresh = ((parseInt(meta.exp, 10) || 0) - Math.round(now / 1000));
+ var fresh = ((parseInt(tokenMeta.exp, 10) || 0) - Math.round(now / 1000));
if (fresh >= staletime) {
return 'fresh';
diff --git a/oauth3.core.provider.js b/oauth3.core.provider.js
index 6f657f8..4626d37 100644
--- a/oauth3.core.provider.js
+++ b/oauth3.core.provider.js
@@ -158,7 +158,7 @@
var url = core.urls.resolve(directive.issuer, directive.grants.url)
.replace(/(:azp|:client_id)/g, core.normalizeUri(opts.client_id || opts.client_uri))
- .replace(/(:sub|:account_id)/g, opts.session.meta.sub)
+ .replace(/(:sub|:account_id)/g, opts.session.token.sub)
;
var data = {
client_id: opts.client_id
@@ -206,12 +206,14 @@
//$('.js-user-avatar').attr('src', userAvatar);
+ /*
console.log('grants options');
console.log(loc.hash);
console.log(loc.search);
console.log(clientObj);
- console.log(session.meta);
+ console.log(session.token);
console.log(window.document.referrer);
+ */
return OAUTH3.requests.grants(CONFIG.host, {
method: 'GET'
@@ -231,7 +233,7 @@
console.log(grantResults);
if (grantResults.data.error) {
- window.alert('grantResults: ' + grantResults.data.errorDescription || grantResults.data.error.message);
+ window.alert('grantResults: ' + grantResults.data.error_description || grantResults.data.error.message);
return;
}
@@ -256,7 +258,7 @@
//return generateToken(session, clientObj);
}
- grants = grantResults.originalData.grants.filter(function (grant) {
+ grants = (grantResults.originalData||grantResults.data).grants.filter(function (grant) {
if (clientUri === (grant.azp || grant.oauth_client_id || grant.oauthClientId)) {
return true;
}
diff --git a/oauth3.js b/oauth3.js
index 8a58a2a..9208a47 100644
--- a/oauth3.js
+++ b/oauth3.js
@@ -27,6 +27,7 @@
};
// TODO move recase out
+ /*
oauth3._recaseRequest = function (recase, req) {
// convert JavaScript camelCase to oauth3/ruby snake_case
if (req.data && 'object' === typeof req.data) {
@@ -44,6 +45,7 @@
}
return resp;
};
+ */
oauth3.hooks = {
checkSession: function (preq, opts) {
@@ -51,7 +53,7 @@
console.warn('[oauth3.hooks.checkSession] no session');
return oauth3.PromiseA.resolve(null);
}
- var freshness = oauth3.core.jwt.getFreshness(preq.session.meta, opts.staletime);
+ var freshness = oauth3.core.jwt.getFreshness(preq.session.token, opts.staletime);
console.info('[oauth3.hooks.checkSession] freshness', freshness, preq.session);
switch (freshness) {
@@ -118,11 +120,11 @@
oldSession.client_uri = clientUri; // azp
// info about the newly-discovered token
- oldSession.meta = core.jwt.decode(oldSession.access_token).payload;
+ oldSession.token = oldSession.meta = core.jwt.decode(oldSession.access_token).payload;
- oldSession.meta.sub = oldSession.meta.sub || oldSession.meta.acx.id;
- oldSession.meta.client_uri = clientUri;
- oldSession.meta.provider_uri = providerUri;
+ oldSession.token.sub = oldSession.token.sub || oldSession.token.acx.id;
+ oldSession.token.client_uri = clientUri;
+ oldSession.token.provider_uri = providerUri;
if (oldSession.refresh_token || oldSession.refreshToken) {
oldSession.refresh = core.jwt.decode(oldSession.refresh_token || oldSession.refreshToken).payload;
@@ -193,14 +195,14 @@
// TODO simplify (nix recase)
oauth3.provideRequest = function (rawRequest, opts) {
opts = opts || {};
- var Recase = exports.Recase || require('recase');
+ //var Recase = exports.Recase || require('recase');
// TODO make insensitive to providing exceptions
- var recase = Recase.create({ exceptions: {} });
+ //var recase = Recase.create({ exceptions: {} });
function lintAndRequest(preq) {
function goGetHer() {
if (preq.session) {
- // TODO check session.meta.aud against preq.url to make sure they match
+ // TODO check session.token.aud against preq.url to make sure they match
console.warn("[security] session audience checking has not been implemented yet (it's up to you to check)");
preq.headers = preq.headers || {};
preq.headers.Authorization = 'Bearer ' + (preq.session.access_token || preq.session.accessToken);
@@ -236,9 +238,10 @@
return lintAndRequest(req, opts);
}
- req = oauth3._recaseRequest(recase, req);
+ //req = oauth3._recaseRequest(recase, req);
return lintAndRequest(req, opts).then(function (res) {
- return oauth3._recaseResponse(recase, res);
+ //return oauth3._recaseResponse(recase, res);
+ return res;
});
};
@@ -285,7 +288,7 @@
return {
client: oauth3.hooks.getGrants(opts.client_id + '-client')
- , grants: oauth3.hooks.getGrants(opts.client_id)
+ , grants: oauth3.hooks.getGrants(opts.client_id) || []
};
});
});
@@ -295,10 +298,10 @@
var prequest = core.urls.loginCode(directive, opts);
return oauth3.request(prequest).then(function (res) {
- // result = { uuid, expiresAt }
+ // result = { uuid, expires_at }
return {
otpUuid: res.data.uuid
- , otpExpires: res.data.expiresAt
+ , otpExpires: res.data.expires_at
};
});
});
diff --git a/oauth3.provider.js b/oauth3.provider.js
index 4af4083..dbaf8ea 100644
--- a/oauth3.provider.js
+++ b/oauth3.provider.js
@@ -47,6 +47,9 @@
return;
}
+ console.warn("What are grants? Baby don't hurt me. Don't hurt me. No more.");
+ console.warn(grants);
+
myGrants = grants.grants.filter(function (grant) {
if (clientUri === (grant.azp || grant.oauth_client_id || grant.oauthClientId)) {
return true;