merge rpc

This commit is contained in:
AJ ONeal 2017-11-25 08:15:44 +00:00
commit 9f48a44958
3 changed files with 199 additions and 60 deletions

View File

@ -1,4 +1,4 @@
/* global Promise */
/ * global Promise */
;(function (exports) {
'use strict';
@ -294,34 +294,41 @@
}
}
, urls: {
discover: function (providerUri, opts) {
, rpc: function (providerUri, opts) {
if (!providerUri) {
throw new Error("cannot discover without providerUri");
throw new Error("cannot run rpc without providerUri");
}
if (!opts.client_id) {
throw new Error("cannot discover without options.client_id");
throw new Error("cannot run rpc without options.client_id");
}
var clientId = OAUTH3.url.normalize(opts.client_id || opts.client_uri);
providerUri = OAUTH3.url.normalize(providerUri);
var params = {
action: 'directives'
, state: opts.state || OAUTH3.utils.randomState()
state: opts.state || OAUTH3.utils.randomState()
, redirect_uri: clientId + (opts.client_callback_path || '/.well-known/oauth3/callback.html#/')
, response_type: 'rpc'
, _method: 'GET'
, _pathname: '.well-known/oauth3/directives.json'
, _scheme: opts._scheme
, _pathname: opts._pathname
, debug: opts.debug || undefined
};
var result = {
var toRequest = {
url: providerUri + '/.well-known/oauth3/#/?' + OAUTH3.query.stringify(params)
, state: params.state
, method: 'GET'
, query: params
};
return result;
return toRequest;
}
, discover: function (providerUri, opts) {
return OAUTH3.urls.directives(providerUri, opts);
}
, directives: function (providerUri, opts) {
opts._pathname = ".well-known/oauth3/scopes.json";
return OAUTH3.urls.rpc(providerUri, opts);
}
, implicitGrant: function (directive, opts) {
//
@ -530,6 +537,14 @@
return OAUTH3.PromiseA.resolve(OAUTH3._hooks.directives.clear());
}
}
, scopes: {
get: function(providerUri) {
//TODO: retrieve cached scopes
}
, set: function(providerUri, scopes) {
//TODO: cache scopes
}
}
, session: {
refresh: function (oldSession, newSession) {
var providerUri = oldSession.provider_uri;
@ -658,9 +673,29 @@
}
}
}
, discover: function (providerUri, opts) {
, discoverScopes: function (providerUri, opts) {
return OAUTH.scopes(providerUri, opts);
}
, scopes: function (providerUri, opts) {
if (!providerUri) {
throw new Error('oauth3.discover(providerUri, opts) received providerUri as ' + providerUri);
throw new Error('oauth3.discoverScopes(providerUri, opts) received providerUri as :', providerUri);
}
opts = opts || {};
opts._pathname = ".well-known/oauth3/scopes.json";
//TODO: add caching
return OAUTH3._rpcHelper(providerUri, opts).then(function(scopes) {
return scopes;
});
}
, discover: function (providerUri, opts) {
return OAUTH3.directives(providerUri, opts);
}
, directives: function (providerUri, opts) {
if (!providerUri) {
throw new Error('oauth3.discover(providerUri, opts) received providerUri as :', providerUri);
}
return OAUTH3.hooks.directives.get(providerUri).then(function (directives) {
@ -668,7 +703,8 @@
return directives;
}
return OAUTH3._discoverHelper(providerUri, opts).then(function (directives) {
opts._pathname = ".well-known/oauth3/directives.json";
return OAUTH3._rpcHelper(providerUri, opts).then(function (directives) {
directives.azp = directives.azp || OAUTH3.url.normalize(providerUri);
directives.issuer = directives.issuer || OAUTH3.url.normalize(providerUri);
directives.api = OAUTH3.url.normalize((directives.api||':hostname').replace(/:hostname/, OAUTH3.uri.normalize(directives.issuer) || OAUTH3.uri.normalize(providerUri)));
@ -677,8 +713,8 @@
});
});
}
, _discoverHelper: function(providerUri, opts) {
return OAUTH3._browser.discover(providerUri, opts);
, _rpcHelper: function(providerUri, opts) {
return OAUTH3._browser.rpc(providerUri, opts);
}
, request: function (preq, opts) {
function fetch() {
@ -858,21 +894,28 @@
//
, _browser: {
window: 'undefined' !== typeof window ? window : null
// TODO we don't need to include this if we're using jQuery or angular
, discover: function(providerUri, opts) {
, rpc: function(providerUri, opts) {
opts = opts || {};
providerUri = OAUTH3.url.normalize(providerUri);
// TODO SECURITY should we whitelist our own self?
if (OAUTH3.uri.normalize(providerUri).replace(/\/.*/, '') === OAUTH3.uri.normalize(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 trying to run rpc on yourself,"
+ " so we we're just gonna use"
+ " OAUTH3.request({ method: 'GET', url: '.well-known/oauth3/directive.json' })");
return OAUTH3.request({
method: 'GET'
, url: OAUTH3.url.normalize(providerUri) + '/.well-known/oauth3/directives.json'
}).then(function (resp) {
return resp.data;
});
+ " OAUTH3.request({ method: 'GET', url: "
+ "'" + opts._pathname + "' })");
if (/localstorage/i.test(opts._scheme)) {
return OAUTH3.PromiseA.resolve(localStorage.getItem(opts._pathname));
}
else {
return OAUTH3.request({
method: 'GET'
, url: OAUTH3.url.normalize(providerUri) + opts._pathname // '/.well-known/oauth3/' + discoverFile
}).then(function (resp) {
return resp.data;
});
}
}
if (!(opts.client_id || opts.client_uri).match(OAUTH3._browser.window.location.hostname)) {
@ -881,17 +924,20 @@
console.warn(opts.client_id || opts.client_uri, OAUTH3._browser.window.location.hostname);
}
var discReq = OAUTH3.urls.discover(
var discReq = OAUTH3.urls.rpc(
providerUri
, { client_id: (opts.client_id || opts.client_uri || OAUTH3.clientUri(OAUTH3._browser.window.location))
, windowType: opts.broker && opts.windowType || 'background'
, broker: opts.broker
, state: opts._state || undefined
, debug: opts.debug
, _scheme: opts._scheme
, _pathname: opts._pathname
, _method: opts._method
}
);
opts._state = discReq.state;
//var discReq = OAUTH3.urls.discover(providerUri, opts);
//var discReq = OAUTH3.urls.rpc(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
@ -920,9 +966,9 @@
}
// TODO params should have response_type indicating json, binary, etc
var directives = JSON.parse(OAUTH3._base64.decodeUrlSafe(params.result || params.directives));
var result = JSON.parse(OAUTH3._base64.decodeUrlSafe(params.data || params.result || params.directives));
// caller will call OAUTH3.hooks.directives.set(providerUri, directives);
return directives;
return result;
});
});
}

View File

@ -20,40 +20,20 @@
// TODO what about search within hash?
var prefix = "(" + window.location.hostname + ") [.well-known/oauth3/]";
var params = OAUTH3.query.parse(window.location.hash || window.location.search);
if (params.debug) {
console.warn(prefix, "DEBUG MODE ENABLED. Automatic redirects disabled.");
}
var urlsafe64;
var redirect;
var err;
var oldRpc;
var sub = params.sub || params.subject;
var subData;
console.log(prefix, 'hash||search:');
console.log(window.location.hash || window.location.search);
function doRedirect(redirect) {
if (params.debug) {
console.log(prefix, 'params.redirect_uri:', params.redirect_uri);
console.log(prefix, 'redirect');
console.log(redirect);
}
console.log(prefix, 'params:');
console.log(params);
OAUTH3.request({ url: 'directives.json' }).then(function (resp) {
var urlsafe64 = OAUTH3._base64.encodeUrlSafe(JSON.stringify(resp.data, null, 0));
var redirect;
console.log(prefix, 'directives');
console.log(resp);
console.log(prefix, 'base64');
console.log(urlsafe64);
// TODO try postMessage back to redirect_uri domain right here
// window.postMessage();
// TODO make sure it's https NOT http
// NOTE: this can be only up to 2,083 characters
console.log(prefix, 'params.redirect_uri:', params.redirect_uri);
redirect = params.redirect_uri + '?' + OAUTH3.query.stringify({
state: params.state
, directives: urlsafe64
, debug: params.debug || undefined
})
console.log(prefix, 'redirect');
console.log(redirect);
if (!params.debug) {
window.location = redirect;
} else {
@ -63,6 +43,93 @@
+ ' to let you look at logs or whatever it is that you intended to do.'
+ '<br/><br/>Continue with redirect: <a href="' + redirect + '">' + redirect + '</' + 'a>';
}
}
function onError(err) {
var redirect = params.redirect_uri + '?' + OAUTH3.query.stringify({
state: params.state
, error: err.code
, error_description: err.message
, error_uri: err.uri
, debug: params.debug || undefined
});
doRedirect(redirect);
}
function onSuccess(urlsafe64, hasSub) {
if (params.debug) {
console.log(prefix, 'directives');
console.log(resp);
console.log(prefix, 'base64');
console.log(urlsafe64);
}
// TODO try postMessage back to redirect_uri domain right here
// window.postMessage();
// TODO SECURITY make sure it's https NOT http
// NOTE: this can be only up to 2,083 characters
redirect = params.redirect_uri + '?' + OAUTH3.query.stringify({
state: params.state
, directives: oldRpc ? urlsafe64 : undefined
, data: !oldRpc ? urlsafe64 : undefined
, sub: hasSub && sub || undefined
, debug: params.debug || undefined
});
doRedirect(redirect);
}
if (params.debug) {
console.warn(prefix, "DEBUG MODE ENABLED. Automatic redirects disabled.");
console.log(prefix, 'hash||search:');
console.log(window.location.hash || window.location.search);
console.log(prefix, 'params:');
console.log(params);
}
if ('rpc' !== params.response_type) {
err = new Error("response_type '" + params.response_type + "' is not supported");
err.code = "E_RESPONSE_TYPE";
// TODO err.uri
onError(err);
return;
}
if (params.action) {
oldRpc = true;
}
if (/localstorage/i.test(params._scheme)) {
if (sub) {
subData = localStorage.getItem(sub + '@oauth3.org:issuer');
onSuccess(subData || localStorage.getItem('oauth3.org:issuer'), subData && true);
return;
}
onSuccess(localStorage.getItem('oauth3.org:issuer'));
return;
}
var fileWhiteList = [
'.well-known/oauth3/directives.json'
, '.well-known/oauth3/scopes.json'
];
if (-1 === fileWhiteList.indexOf(params._pathname)) {
err = new Error("No access to requested file: " + params._pathname);
err.code = "E_ACCESS_DENIED"
// TODO err.uri
onError(err);
}
OAUTH3.request({ url: 'directives.json' }).then(function (resp) {
urlsafe64 = OAUTH3._base64.encodeUrlSafe(JSON.stringify(resp.data, null, 0));
onSuccess(urlsafe64);
});
}());

View File

@ -0,0 +1,26 @@
{
"oauth3_authn": "Basic secure authentication"
, "auth@oauth3.org": "Basic secure authentication"
, "wallet": "Access to payments and subscriptions"
, "bucket": "Access to file storage"
, "db": "Access to app data"
, "domains": "Domain registration (and Glue and NS records)"
, "domains@oauth3.org": "Domain registration (and Glue and NS records)"
, "domains:glue": "Glue Record management (for vanity nameservers)"
, "domains:ns": "Name Server management"
, "dns": "DNS records (A/AAAA, TXT, SRV, MX, etc)"
, "hello@example.com": "Hello World Example Access"
, "authn@oauth3.org": "Basic secure authentication"
, "wallet@oauth3.org": "Access to payments and subscriptions"
, "bucket@oauth3.org": "Access to file storage"
, "db@oauth3.org": "Access to app data"
, "domains@oauth3.org": "Domain registration (and Glue and NS records)"
, "domains:glue@oauth3.org": "Glue Record management (for vanity nameservers)"
, "domains:ns@oauth3.org": "Name Server management"
, "dns@oauth3.org": "DNS records (A/AAAA, TXT, SRV, MX, etc)"
, "www@daplie.com": "Websites and webapps"
, "*": "FULL ACCOUNT ACCESS"
}