merge rpc
This commit is contained in:
commit
9f48a44958
102
oauth3.core.js
102
oauth3.core.js
|
@ -1,4 +1,4 @@
|
||||||
/* global Promise */
|
/ * global Promise */
|
||||||
;(function (exports) {
|
;(function (exports) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
@ -294,34 +294,41 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
, urls: {
|
, urls: {
|
||||||
discover: function (providerUri, opts) {
|
, rpc: function (providerUri, opts) {
|
||||||
if (!providerUri) {
|
if (!providerUri) {
|
||||||
throw new Error("cannot discover without providerUri");
|
throw new Error("cannot run rpc without providerUri");
|
||||||
}
|
}
|
||||||
if (!opts.client_id) {
|
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);
|
var clientId = OAUTH3.url.normalize(opts.client_id || opts.client_uri);
|
||||||
providerUri = OAUTH3.url.normalize(providerUri);
|
providerUri = OAUTH3.url.normalize(providerUri);
|
||||||
|
|
||||||
var params = {
|
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#/')
|
, redirect_uri: clientId + (opts.client_callback_path || '/.well-known/oauth3/callback.html#/')
|
||||||
, response_type: 'rpc'
|
, response_type: 'rpc'
|
||||||
, _method: 'GET'
|
, _method: 'GET'
|
||||||
, _pathname: '.well-known/oauth3/directives.json'
|
, _scheme: opts._scheme
|
||||||
|
, _pathname: opts._pathname
|
||||||
, debug: opts.debug || undefined
|
, debug: opts.debug || undefined
|
||||||
};
|
};
|
||||||
|
|
||||||
var result = {
|
var toRequest = {
|
||||||
url: providerUri + '/.well-known/oauth3/#/?' + OAUTH3.query.stringify(params)
|
url: providerUri + '/.well-known/oauth3/#/?' + OAUTH3.query.stringify(params)
|
||||||
, state: params.state
|
, state: params.state
|
||||||
, method: 'GET'
|
, method: 'GET'
|
||||||
, query: params
|
, 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) {
|
, implicitGrant: function (directive, opts) {
|
||||||
//
|
//
|
||||||
|
@ -530,6 +537,14 @@
|
||||||
return OAUTH3.PromiseA.resolve(OAUTH3._hooks.directives.clear());
|
return OAUTH3.PromiseA.resolve(OAUTH3._hooks.directives.clear());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
, scopes: {
|
||||||
|
get: function(providerUri) {
|
||||||
|
//TODO: retrieve cached scopes
|
||||||
|
}
|
||||||
|
, set: function(providerUri, scopes) {
|
||||||
|
//TODO: cache scopes
|
||||||
|
}
|
||||||
|
}
|
||||||
, session: {
|
, session: {
|
||||||
refresh: function (oldSession, newSession) {
|
refresh: function (oldSession, newSession) {
|
||||||
var providerUri = oldSession.provider_uri;
|
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) {
|
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) {
|
return OAUTH3.hooks.directives.get(providerUri).then(function (directives) {
|
||||||
|
@ -668,7 +703,8 @@
|
||||||
return directives;
|
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.azp = directives.azp || OAUTH3.url.normalize(providerUri);
|
||||||
directives.issuer = directives.issuer || 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)));
|
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) {
|
, _rpcHelper: function(providerUri, opts) {
|
||||||
return OAUTH3._browser.discover(providerUri, opts);
|
return OAUTH3._browser.rpc(providerUri, opts);
|
||||||
}
|
}
|
||||||
, request: function (preq, opts) {
|
, request: function (preq, opts) {
|
||||||
function fetch() {
|
function fetch() {
|
||||||
|
@ -858,21 +894,28 @@
|
||||||
//
|
//
|
||||||
, _browser: {
|
, _browser: {
|
||||||
window: 'undefined' !== typeof window ? window : null
|
window: 'undefined' !== typeof window ? window : null
|
||||||
// TODO we don't need to include this if we're using jQuery or angular
|
, rpc: function(providerUri, opts) {
|
||||||
, discover: function(providerUri, opts) {
|
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
providerUri = OAUTH3.url.normalize(providerUri);
|
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)) {
|
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"
|
+ " so we we're just gonna use"
|
||||||
+ " OAUTH3.request({ method: 'GET', url: '.well-known/oauth3/directive.json' })");
|
+ " OAUTH3.request({ method: 'GET', url: "
|
||||||
return OAUTH3.request({
|
+ "'" + opts._pathname + "' })");
|
||||||
method: 'GET'
|
|
||||||
, url: OAUTH3.url.normalize(providerUri) + '/.well-known/oauth3/directives.json'
|
if (/localstorage/i.test(opts._scheme)) {
|
||||||
}).then(function (resp) {
|
return OAUTH3.PromiseA.resolve(localStorage.getItem(opts._pathname));
|
||||||
return resp.data;
|
}
|
||||||
});
|
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)) {
|
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);
|
console.warn(opts.client_id || opts.client_uri, OAUTH3._browser.window.location.hostname);
|
||||||
}
|
}
|
||||||
|
|
||||||
var discReq = OAUTH3.urls.discover(
|
var discReq = OAUTH3.urls.rpc(
|
||||||
providerUri
|
providerUri
|
||||||
, { client_id: (opts.client_id || opts.client_uri || OAUTH3.clientUri(OAUTH3._browser.window.location))
|
, { client_id: (opts.client_id || opts.client_uri || OAUTH3.clientUri(OAUTH3._browser.window.location))
|
||||||
, windowType: opts.broker && opts.windowType || 'background'
|
, windowType: opts.broker && opts.windowType || 'background'
|
||||||
, broker: opts.broker
|
, broker: opts.broker
|
||||||
, state: opts._state || undefined
|
, state: opts._state || undefined
|
||||||
, debug: opts.debug
|
, debug: opts.debug
|
||||||
|
, _scheme: opts._scheme
|
||||||
|
, _pathname: opts._pathname
|
||||||
|
, _method: opts._method
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
opts._state = discReq.state;
|
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,
|
// 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
|
// 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
|
// 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);
|
// caller will call OAUTH3.hooks.directives.set(providerUri, directives);
|
||||||
return directives;
|
return result;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,40 +20,20 @@
|
||||||
// TODO what about search within hash?
|
// TODO what about search within hash?
|
||||||
var prefix = "(" + window.location.hostname + ") [.well-known/oauth3/]";
|
var prefix = "(" + window.location.hostname + ") [.well-known/oauth3/]";
|
||||||
var params = OAUTH3.query.parse(window.location.hash || window.location.search);
|
var params = OAUTH3.query.parse(window.location.hash || window.location.search);
|
||||||
if (params.debug) {
|
var urlsafe64;
|
||||||
console.warn(prefix, "DEBUG MODE ENABLED. Automatic redirects disabled.");
|
var redirect;
|
||||||
}
|
var err;
|
||||||
|
var oldRpc;
|
||||||
|
var sub = params.sub || params.subject;
|
||||||
|
var subData;
|
||||||
|
|
||||||
console.log(prefix, 'hash||search:');
|
function doRedirect(redirect) {
|
||||||
console.log(window.location.hash || window.location.search);
|
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) {
|
if (!params.debug) {
|
||||||
window.location = redirect;
|
window.location = redirect;
|
||||||
} else {
|
} else {
|
||||||
|
@ -63,6 +43,93 @@
|
||||||
+ ' to let you look at logs or whatever it is that you intended to do.'
|
+ ' 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>';
|
+ '<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);
|
||||||
});
|
});
|
||||||
|
|
||||||
}());
|
}());
|
||||||
|
|
|
@ -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"
|
||||||
|
}
|
Loading…
Reference in New Issue