WIP refactor (refreshToken works)
This commit is contained in:
parent
7ae4d83cfe
commit
9af2f574c0
|
@ -14,11 +14,14 @@
|
||||||
|
|
||||||
var browser = exports.OAUTH3_BROWSER = {
|
var browser = exports.OAUTH3_BROWSER = {
|
||||||
discover: function (providerUri, opts) {
|
discover: function (providerUri, opts) {
|
||||||
|
if (!providerUri) {
|
||||||
|
throw new Error('oauth3.discover(providerUri, opts) received providerUri as ' + providerUri);
|
||||||
|
}
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
opts.debug = true;
|
opts.debug = true;
|
||||||
console.log('discover providerUri', providerUri);
|
console.log('discover providerUri', providerUri);
|
||||||
providerUri = OAUTH3_CORE.normalizeUrl(providerUri);
|
providerUri = OAUTH3_CORE.normalizeUrl(providerUri);
|
||||||
var discObj = OAUTH3_CORE.discover(providerUri, { appUrl: (opts.appUrl || getDefaultAppUrl()), debug: opts.debug });
|
var discObj = OAUTH3_CORE.urls.discover(providerUri, { appUrl: (opts.appUrl || getDefaultAppUrl()), debug: opts.debug });
|
||||||
|
|
||||||
return browser.insertIframe(discObj.url, discObj.state, opts).then(function (params) {
|
return browser.insertIframe(discObj.url, discObj.state, opts).then(function (params) {
|
||||||
if (params.error) {
|
if (params.error) {
|
||||||
|
@ -147,12 +150,12 @@
|
||||||
//
|
//
|
||||||
// Logins
|
// Logins
|
||||||
//
|
//
|
||||||
, logins: {
|
, requests: {
|
||||||
authorizationRedirect: function (providerUri, opts) {
|
authorizationRedirect: function (providerUri, opts) {
|
||||||
// TODO get own directives
|
// TODO get own directives
|
||||||
|
|
||||||
return OAUTH3.discover(providerUri, opts).then(function (directive) {
|
return OAUTH3.discover(providerUri, opts).then(function (directive) {
|
||||||
var prequest = OAUTH3_CORE.authorizationRedirect(
|
var prequest = OAUTH3_CORE.urls.authorizationRedirect(
|
||||||
directive
|
directive
|
||||||
, opts
|
, opts
|
||||||
);
|
);
|
||||||
|
@ -169,7 +172,7 @@
|
||||||
, implicitGrant: function (providerUri, opts) {
|
, implicitGrant: function (providerUri, opts) {
|
||||||
// TODO OAuth3 provider should use the redirect URI as the appId?
|
// TODO OAuth3 provider should use the redirect URI as the appId?
|
||||||
return OAUTH3.discover(providerUri, opts).then(function (directive) {
|
return OAUTH3.discover(providerUri, opts).then(function (directive) {
|
||||||
var prequest = OAUTH3_CORE.implicitGrant(
|
var prequest = OAUTH3_CORE.urls.implicitGrant(
|
||||||
directive
|
directive
|
||||||
// TODO OAuth3 provider should referrer / referer / origin as the appId?
|
// TODO OAuth3 provider should referrer / referer / origin as the appId?
|
||||||
, opts
|
, opts
|
||||||
|
@ -188,7 +191,7 @@
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
|
|
||||||
return OAUTH3.discover(providerUri, opts).then(function (directive) {
|
return OAUTH3.discover(providerUri, opts).then(function (directive) {
|
||||||
var prequest = OAUTH3_CORE.logout(
|
var prequest = OAUTH3_CORE.urls.logout(
|
||||||
directive
|
directive
|
||||||
, opts
|
, opts
|
||||||
);
|
);
|
||||||
|
@ -228,6 +231,12 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
Object.keys(browser).forEach(function (key) {
|
Object.keys(browser).forEach(function (key) {
|
||||||
|
if ('requests' === key) {
|
||||||
|
Object.keys(browser.requests).forEach(function (key) {
|
||||||
|
OAUTH3.requests[key] = browser.requests[key];
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
OAUTH3[key] = browser[key];
|
OAUTH3[key] = browser[key];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
// NOTE: we assume that directive.provider_uri exists
|
// NOTE: we assume that directive.provider_uri exists
|
||||||
|
|
||||||
var core = {};
|
var core = {};
|
||||||
|
core.urls = core;
|
||||||
|
|
||||||
function getDefaultAppApiBase() {
|
function getDefaultAppApiBase() {
|
||||||
console.warn('[deprecated] using window.location.host when opts.appApiBase should be used');
|
console.warn('[deprecated] using window.location.host when opts.appApiBase should be used');
|
||||||
|
@ -76,9 +77,9 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
core.formatError = function (providerUri, params) {
|
core.formatError = function (providerUri, params) {
|
||||||
var err = new Error(params.error_description || "Unknown error when discoving provider '" + providerUri + "'");
|
var err = new Error(params.error_description || params.error.message || "Unknown error when discoving provider '" + providerUri + "'");
|
||||||
err.uri = params.error_uri;
|
err.uri = params.error_uri || params.error.uri;
|
||||||
err.code = params.error;
|
err.code = params.error.code || params.error;
|
||||||
return err;
|
return err;
|
||||||
};
|
};
|
||||||
core.normalizeUri = function (providerUri) {
|
core.normalizeUri = function (providerUri) {
|
||||||
|
@ -104,7 +105,7 @@
|
||||||
;
|
;
|
||||||
};
|
};
|
||||||
|
|
||||||
core.discover = function (providerUri, opts) {
|
core.urls.discover = function (providerUri, opts) {
|
||||||
if (!providerUri) {
|
if (!providerUri) {
|
||||||
throw new Error("cannot discover without providerUri");
|
throw new Error("cannot discover without providerUri");
|
||||||
}
|
}
|
||||||
|
@ -196,6 +197,21 @@
|
||||||
, signature: parts[2] // should remain url-safe base64
|
, signature: parts[2] // should remain url-safe base64
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
, getFreshness: function (meta, staletime, now) {
|
||||||
|
staletime = staletime || (15 * 60);
|
||||||
|
now = now || Date.now();
|
||||||
|
var fresh = ((parseInt(meta.exp, 10) || 0) - (now / 1000));
|
||||||
|
|
||||||
|
if (fresh >= staletime) {
|
||||||
|
return 'fresh';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fresh <= 0) {
|
||||||
|
return 'expired';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'stale';
|
||||||
|
}
|
||||||
// encode-only (no signature)
|
// encode-only (no signature)
|
||||||
, encode: function (parts) {
|
, encode: function (parts) {
|
||||||
parts.header = parts.header || { alg: 'none', typ: 'jwt' };
|
parts.header = parts.header || { alg: 'none', typ: 'jwt' };
|
||||||
|
@ -212,7 +228,7 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
core.authorizationCode = function (/*directive, scope, redirectUri, clientId*/) {
|
core.urls.authorizationCode = function (/*directive, scope, redirectUri, clientId*/) {
|
||||||
//
|
//
|
||||||
// Example Authorization Code Request
|
// Example Authorization Code Request
|
||||||
// (not for use in the browser)
|
// (not for use in the browser)
|
||||||
|
@ -234,7 +250,7 @@
|
||||||
throw new Error("not implemented");
|
throw new Error("not implemented");
|
||||||
};
|
};
|
||||||
|
|
||||||
core.authorizationRedirect = function (directive, opts) {
|
core.urls.authorizationRedirect = function (directive, opts) {
|
||||||
//console.log('[authorizationRedirect]');
|
//console.log('[authorizationRedirect]');
|
||||||
//
|
//
|
||||||
// Example Authorization Redirect - from Browser to Consumer API
|
// Example Authorization Redirect - from Browser to Consumer API
|
||||||
|
@ -293,7 +309,7 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
core.implicitGrant = function (directive, opts) {
|
core.urls.implicitGrant = function (directive, opts) {
|
||||||
//console.log('[implicitGrant]');
|
//console.log('[implicitGrant]');
|
||||||
//
|
//
|
||||||
// Example Implicit Grant Request
|
// Example Implicit Grant Request
|
||||||
|
@ -357,7 +373,7 @@
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
core.loginCode = function (directive, opts) {
|
core.urls.loginCode = function (directive, opts) {
|
||||||
//
|
//
|
||||||
// Example Resource Owner Password Request
|
// Example Resource Owner Password Request
|
||||||
// (generally for 1st party and direct-partner mobile apps, and webapps)
|
// (generally for 1st party and direct-partner mobile apps, and webapps)
|
||||||
|
@ -404,7 +420,7 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
core.resourceOwnerPassword = function (directive, opts) {
|
core.urls.resourceOwnerPassword = function (directive, opts) {
|
||||||
//
|
//
|
||||||
// Example Resource Owner Password Request
|
// Example Resource Owner Password Request
|
||||||
// (generally for 1st party and direct-partner mobile apps, and webapps)
|
// (generally for 1st party and direct-partner mobile apps, and webapps)
|
||||||
|
@ -479,7 +495,7 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
core.refreshToken = function (directive, opts) {
|
core.urls.refreshToken = function (directive, opts) {
|
||||||
// grant_type=refresh_token
|
// grant_type=refresh_token
|
||||||
|
|
||||||
// Example Refresh Token Request
|
// Example Refresh Token Request
|
||||||
|
@ -494,15 +510,14 @@
|
||||||
var grantType = 'refresh_token';
|
var grantType = 'refresh_token';
|
||||||
|
|
||||||
var scope = opts.scope || directive.authn_scope;
|
var scope = opts.scope || directive.authn_scope;
|
||||||
var clientId = opts.appId || opts.clientId;
|
|
||||||
var clientSecret = opts.appSecret || opts.clientSecret;
|
var clientSecret = opts.appSecret || opts.clientSecret;
|
||||||
var args = directive[type];
|
var args = directive[type];
|
||||||
var params = {
|
var params = {
|
||||||
"grant_type": grantType
|
"grant_type": grantType
|
||||||
, "refresh_token": opts.refreshToken
|
, "refresh_token": opts.refresh_token || opts.refreshToken || (opts.session && opts.session.refresh_token)
|
||||||
, "response_type": 'token'
|
, "response_type": 'token'
|
||||||
//, "client_id": undefined
|
, "client_id": opts.appId || opts.app_id || opts.client_id || opts.clientId || opts.client_id || opts.clientId
|
||||||
//, "client_uri": undefined
|
, "client_uri": opts.client_uri || opts.clientUri
|
||||||
//, "scope": undefined
|
//, "scope": undefined
|
||||||
//, "client_secret": undefined
|
//, "client_secret": undefined
|
||||||
, debug: opts.debug || undefined
|
, debug: opts.debug || undefined
|
||||||
|
@ -510,14 +525,7 @@
|
||||||
var uri = args.url;
|
var uri = args.url;
|
||||||
var body;
|
var body;
|
||||||
|
|
||||||
if (opts.clientUri) {
|
// TODO not allowed in the browser
|
||||||
params.client_uri = opts.clientUri;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (clientId) {
|
|
||||||
params.client_id = clientId;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (clientSecret) {
|
if (clientSecret) {
|
||||||
params.client_secret = clientSecret;
|
params.client_secret = clientSecret;
|
||||||
}
|
}
|
||||||
|
@ -539,7 +547,7 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
core.logout = function (directive, opts) {
|
core.urls.logout = function (directive, opts) {
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
var type = 'logout';
|
var type = 'logout';
|
||||||
var clientId = opts.appId || opts.clientId || opts.client_id;
|
var clientId = opts.appId || opts.clientId || opts.client_id;
|
||||||
|
|
210
oauth3.js
210
oauth3.js
|
@ -3,11 +3,10 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var oauth3 = {};
|
var oauth3 = {};
|
||||||
var logins = {};
|
|
||||||
|
|
||||||
var core = exports.OAUTH3_CORE || require('./oauth3.core.js');
|
var core = exports.OAUTH3_CORE || require('./oauth3.core.js');
|
||||||
|
|
||||||
oauth3.requests = logins;
|
oauth3.requests = {};
|
||||||
|
|
||||||
if ('undefined' !== typeof Promise) {
|
if ('undefined' !== typeof Promise) {
|
||||||
oauth3.PromiseA = Promise;
|
oauth3.PromiseA = Promise;
|
||||||
|
@ -27,6 +26,7 @@
|
||||||
return PromiseA.resolve();
|
return PromiseA.resolve();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO move recase out
|
||||||
oauth3._recaseRequest = function (recase, req) {
|
oauth3._recaseRequest = function (recase, req) {
|
||||||
// convert JavaScript camelCase to oauth3/ruby snake_case
|
// convert JavaScript camelCase to oauth3/ruby snake_case
|
||||||
if (req.data && 'object' === typeof req.data) {
|
if (req.data && 'object' === typeof req.data) {
|
||||||
|
@ -44,64 +44,90 @@
|
||||||
}
|
}
|
||||||
return resp;
|
return resp;
|
||||||
};
|
};
|
||||||
oauth3._lintRequest = function (preq, opts) {
|
|
||||||
var providerUri;
|
|
||||||
var fresh;
|
|
||||||
|
|
||||||
console.log('[os] request meta opts', opts);
|
oauth3.hooks = {
|
||||||
|
checkSession: function (preq, opts) {
|
||||||
// check that the JWT is not expired
|
if (!preq.session) {
|
||||||
// TODO check that this request applies to the aud and azp
|
console.error('NO SESSION to consider');
|
||||||
if (!(preq.session && preq.session.accessToken)) {
|
return oauth3.PromiseA.resolve(null);
|
||||||
console.log('[os] no session/accessTokenData');
|
|
||||||
return oauth3.PromiseA.resolve(preq);
|
|
||||||
}
|
}
|
||||||
|
var freshness = oauth3.core.jwt.getFreshness(preq.session.meta, opts.staletime);
|
||||||
|
console.log('checkSession', freshness, preq.session);
|
||||||
|
|
||||||
preq.headers = preq.headers || {};
|
switch (freshness) {
|
||||||
preq.headers.Authorization = 'Bearer ' + preq.session.accessToken;
|
case 'stale':
|
||||||
|
return oauth3.hooks.sessionStale(preq.session);
|
||||||
if (!preq.session._accessTokenData) {
|
case 'expired':
|
||||||
console.log('[os] no _accessTokenData');
|
console.log('expired checkSession', preq.session);
|
||||||
preq.session._accessTokenData = core.jwt.decode(preq.session.accessToken).payload;
|
return oauth3.hooks.sessionExpired(preq.session).then(function (newSession) {
|
||||||
}
|
preq.session = newSession;
|
||||||
|
return newSession;
|
||||||
if (!preq.url.match(preq.session._accessTokenData.aud)) {
|
|
||||||
console.log("[os] doesn't match audience", preq.session._accessTokenData.aud);
|
|
||||||
return oauth3.PromiseA.resolve(preq);
|
|
||||||
}
|
|
||||||
|
|
||||||
fresh = (Date.now() / 1000) >= (parseInt(preq.session._accessTokenData.exp) || 0);
|
|
||||||
if (!fresh) {
|
|
||||||
console.log("[os] isn't fresh", preq.session._accessTokenData.exp);
|
|
||||||
return oauth3.PromiseA.resolve(preq);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!preq.session.refreshToken) {
|
|
||||||
console.log("[os] cann't refresh", preq.session);
|
|
||||||
return oauth3.PromiseA.resolve(preq);
|
|
||||||
}
|
|
||||||
|
|
||||||
opts.refreshToken = preq.session.refreshToken;
|
|
||||||
console.log('[oauth3.js] refreshToken attempt');
|
|
||||||
|
|
||||||
// TODO include directive?
|
|
||||||
providerUri = preq.session.providerUri || preq.session._accessTokenData.iss;
|
|
||||||
//opts.
|
|
||||||
return oauth3.refreshToken(providerUri, opts).then(function (res) {
|
|
||||||
console.log('[oauth3.js] refreshToken result:', res);
|
|
||||||
|
|
||||||
if (!res.data.accessToken) {
|
|
||||||
return preq;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO fire session update event
|
|
||||||
res.data.providerUri = preq.session.providerUri;
|
|
||||||
preq.session = res.data;
|
|
||||||
preq.headers.Authorization = 'Bearer ' + preq.session.accessToken;
|
|
||||||
return preq;
|
|
||||||
});
|
});
|
||||||
};
|
//case 'fresh':
|
||||||
|
default:
|
||||||
|
return oauth3.PromiseA.resolve(preq.session);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
, sessionStale: function (staleSession) {
|
||||||
|
if (oauth3.hooks._stalePromise) {
|
||||||
|
return oauth3.PromiseA.resolve(staleSession);
|
||||||
|
}
|
||||||
|
|
||||||
|
oauth3.hooks._stalePromise = oauth3.requests.refreshToken(
|
||||||
|
staleSession.provider_uri
|
||||||
|
, staleSession
|
||||||
|
).then(function (newSession) {
|
||||||
|
oauth3.hooks._stalePromise = null;
|
||||||
|
return newSession; // oauth3.hooks.refreshSession(staleSession, newSession);
|
||||||
|
}, function () {
|
||||||
|
oauth3.hooks._stalePromise = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
return oauth3.PromiseA.resolve(staleSession);
|
||||||
|
}
|
||||||
|
, sessionExpired: function (expiredSession) {
|
||||||
|
console.log('expiredSession');
|
||||||
|
console.log(expiredSession);
|
||||||
|
return oauth3.requests.refreshToken(expiredSession.provider_uri, expiredSession).then(function (newSession) {
|
||||||
|
return newSession; // oauth3.hooks.refreshSession(expiredSession, newSession);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
, refreshSession: function (oldSession, newSession) {
|
||||||
|
var providerUri = oldSession.provider_uri;
|
||||||
|
var clientUri = oldSession.client_uri;
|
||||||
|
|
||||||
|
Object.keys(oldSession).forEach(function (key) {
|
||||||
|
oldSession[key] = undefined;
|
||||||
|
});
|
||||||
|
Object.keys(newSession).forEach(function (key) {
|
||||||
|
oldSession[key] = newSession[key];
|
||||||
|
});
|
||||||
|
|
||||||
|
console.info('refreshSession', oldSession, newSession);
|
||||||
|
oldSession.meta = core.jwt.decode(oldSession.access_token).payload;
|
||||||
|
oldSession.meta.sub = oldSession.meta.sub || oldSession.meta.acx.id;
|
||||||
|
oldSession.client_uri = clientUri;
|
||||||
|
oldSession.meta.client_uri = clientUri;
|
||||||
|
oldSession.provider_uri = providerUri;
|
||||||
|
oldSession.meta.provider_uri = providerUri;
|
||||||
|
|
||||||
|
oldSession._accessTokenData = oldSession.data = oldSession.meta;
|
||||||
|
|
||||||
|
if (oldSession.refresh_token || oldSession.refreshToken) {
|
||||||
|
oldSession.refresh = core.jwt.decode(oldSession.refresh_token || oldSession.refreshToken).payload;
|
||||||
|
oldSession.refresh.sub = oldSession.refresh.sub || oldSession.refresh.acx.id;
|
||||||
|
oldSession.refresh.provider_uri = providerUri;
|
||||||
|
}
|
||||||
|
|
||||||
|
return oauth3.PromiseA.resolve(oauth3.hooks.setSession(oldSession));
|
||||||
|
}
|
||||||
|
, setSession: function (newSession) {
|
||||||
|
console.warn('oauth3.hooks.setSession is not implemented');
|
||||||
|
//console.warn(JSON.parse(JSON.stringify(oldSession)));
|
||||||
|
console.warn(newSession);
|
||||||
|
return newSession;
|
||||||
|
}
|
||||||
|
};
|
||||||
oauth3.provideRequest = function (rawRequest, opts) {
|
oauth3.provideRequest = function (rawRequest, opts) {
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
var Recase = exports.Recase || require('recase');
|
var Recase = exports.Recase || require('recase');
|
||||||
|
@ -109,11 +135,27 @@
|
||||||
var recase = Recase.create({ exceptions: {} });
|
var recase = Recase.create({ exceptions: {} });
|
||||||
|
|
||||||
function lintAndRequest(preq) {
|
function lintAndRequest(preq) {
|
||||||
|
function goGetHer() {
|
||||||
|
if (!oauth3._lintRequest) {
|
||||||
|
return rawRequest(preq);
|
||||||
|
}
|
||||||
return oauth3._lintRequest(preq, opts).then(function (preq) {
|
return oauth3._lintRequest(preq, opts).then(function (preq) {
|
||||||
return rawRequest(preq);
|
return rawRequest(preq);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!preq.session) {
|
||||||
|
return goGetHer();
|
||||||
|
}
|
||||||
|
|
||||||
|
preq.headers = preq.headers || {};
|
||||||
|
preq.headers.Authorization = 'Bearer ' + (preq.session.access_token || preq.session.accessToken);
|
||||||
|
|
||||||
|
console.warn('lintAndRequest checkSession', preq);
|
||||||
|
return oauth3.hooks.checkSession(preq, opts).then(goGetHer);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (opts.rawCase) {
|
if (opts.rawCase) {
|
||||||
oauth3.request = lintAndRequest;
|
oauth3.request = lintAndRequest;
|
||||||
return;
|
return;
|
||||||
|
@ -141,9 +183,9 @@
|
||||||
*/
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
oauth3.loginCode = function (providerUri, opts) {
|
oauth3.requests.loginCode = function (providerUri, opts) {
|
||||||
return oauth3.discover(providerUri, opts).then(function (directive) {
|
return oauth3.discover(providerUri, opts).then(function (directive) {
|
||||||
var prequest = core.loginCode(directive, opts);
|
var prequest = core.urls.loginCode(directive, opts);
|
||||||
|
|
||||||
console.log('[DEBUG] [core] loginCode URL', prequest);
|
console.log('[DEBUG] [core] loginCode URL', prequest);
|
||||||
|
|
||||||
|
@ -157,13 +199,14 @@
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
oauth3.loginCode = oauth3.requests.loginCode;
|
||||||
|
|
||||||
oauth3.resourceOwnerPassword = function (providerUri, username, passphrase, opts) {
|
oauth3.requests.resourceOwnerPassword = function (providerUri, opts) {
|
||||||
console.log('DEBUG oauth3.resourceOwnerPassword opts', opts);
|
console.log('DEBUG oauth3.resourceOwnerPassword opts', opts);
|
||||||
//var scope = opts.scope;
|
//var scope = opts.scope;
|
||||||
//var appId = opts.appId;
|
//var appId = opts.appId;
|
||||||
return oauth3.discover(providerUri, opts).then(function (directive) {
|
return oauth3.discover(providerUri, opts).then(function (directive) {
|
||||||
var prequest = core.resourceOwnerPassword(directive, opts);
|
var prequest = core.urls.resourceOwnerPassword(directive, opts);
|
||||||
|
|
||||||
console.log('[DEBUG] [core] resourceOwnerPassword URL', prequest);
|
console.log('[DEBUG] [core] resourceOwnerPassword URL', prequest);
|
||||||
|
|
||||||
|
@ -171,13 +214,25 @@
|
||||||
url: prequest.url
|
url: prequest.url
|
||||||
, method: prequest.method
|
, method: prequest.method
|
||||||
, data: prequest.data
|
, data: prequest.data
|
||||||
|
}).then(function (req) {
|
||||||
|
var data = (req.originalData || req.data);
|
||||||
|
data.provider_uri = providerUri;
|
||||||
|
if (data.error) {
|
||||||
|
return oauth3.PromiseA.reject(oauth3.core.formatError(providerUri, data.error));
|
||||||
|
}
|
||||||
|
return oauth3.hooks.refreshSession(
|
||||||
|
opts.session || { provider_uri: providerUri, client_uri: opts.client_uri || opts.clientUri }
|
||||||
|
, data
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
oauth3.resourceOwnerPassword = oauth3.requests.resourceOwnerPassword;
|
||||||
|
|
||||||
oauth3.refreshToken = function (providerUri, opts) {
|
oauth3.requests.refreshToken = function (providerUri, opts) {
|
||||||
|
console.warn('oauth3.requests.refreshToken', providerUri, opts);
|
||||||
return oauth3.discover(providerUri, opts).then(function (directive) {
|
return oauth3.discover(providerUri, opts).then(function (directive) {
|
||||||
var prequest = core.refreshToken(directive, opts);
|
var prequest = core.urls.refreshToken(directive, opts);
|
||||||
|
|
||||||
console.log('[DEBUG] [core] refreshToken URL', prequest);
|
console.log('[DEBUG] [core] refreshToken URL', prequest);
|
||||||
|
|
||||||
|
@ -185,20 +240,28 @@
|
||||||
url: prequest.url
|
url: prequest.url
|
||||||
, method: prequest.method
|
, method: prequest.method
|
||||||
, data: prequest.data
|
, data: prequest.data
|
||||||
|
}).then(function (req) {
|
||||||
|
var data = (req.originalData || req.data);
|
||||||
|
data.provider_uri = providerUri;
|
||||||
|
if (data.error) {
|
||||||
|
return oauth3.PromiseA.reject(oauth3.core.formatError(providerUri, data));
|
||||||
|
}
|
||||||
|
return oauth3.hooks.refreshSession(opts, data);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
oauth3.refreshToken = oauth3.requests.refreshToken;
|
||||||
|
|
||||||
// TODO It'll be very interesting to see if we can do some browser popup stuff from the CLI
|
// TODO It'll be very interesting to see if we can do some browser popup stuff from the CLI
|
||||||
logins._error_description = 'Not Implemented: Please override by including <script src="oauth3.browser.js"></script>';
|
oauth3.requests._error_description = 'Not Implemented: Please override by including <script src="oauth3.browser.js"></script>';
|
||||||
logins.authorizationRedirect = function (/*providerUri, opts*/) {
|
oauth3.requests.authorizationRedirect = function (/*providerUri, opts*/) {
|
||||||
throw new Error(logins._error_description);
|
throw new Error(oauth3.requests._error_description);
|
||||||
};
|
};
|
||||||
logins.implicitGrant = function (/*providerUri, opts*/) {
|
oauth3.requests.implicitGrant = function (/*providerUri, opts*/) {
|
||||||
throw new Error(logins._error_description);
|
throw new Error(oauth3.requests._error_description);
|
||||||
};
|
};
|
||||||
logins.logout = function (/*providerUri, opts*/) {
|
oauth3.requests.logout = function (/*providerUri, opts*/) {
|
||||||
throw new Error(logins._error_description);
|
throw new Error(oauth3.requests._error_description);
|
||||||
};
|
};
|
||||||
|
|
||||||
oauth3.login = function (providerUri, opts) {
|
oauth3.login = function (providerUri, opts) {
|
||||||
|
@ -226,12 +289,7 @@
|
||||||
}
|
}
|
||||||
/* jshint ignore:end */
|
/* jshint ignore:end */
|
||||||
|
|
||||||
var username = opts.username;
|
return oauth3.requests.resourceOwnerPassword(providerUri, opts).then(function (resp) {
|
||||||
var password = opts.password;
|
|
||||||
delete opts.username;
|
|
||||||
delete opts.password;
|
|
||||||
|
|
||||||
return oauth3.resourceOwnerPassword(providerUri, username, password, opts).then(function (resp) {
|
|
||||||
if (!resp || !resp.data) {
|
if (!resp || !resp.data) {
|
||||||
var err = new Error("bad response");
|
var err = new Error("bad response");
|
||||||
err.response = resp;
|
err.response = resp;
|
||||||
|
@ -254,10 +312,10 @@
|
||||||
opts.popup = true;
|
opts.popup = true;
|
||||||
}
|
}
|
||||||
if (opts.authorizationRedirect) {
|
if (opts.authorizationRedirect) {
|
||||||
promise = logins.authorizationRedirect(providerUri, opts);
|
promise = oauth3.requests.authorizationRedirect(providerUri, opts);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
promise = logins.implicitGrant(providerUri, opts);
|
promise = oauth3.requests.implicitGrant(providerUri, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
return promise;
|
return promise;
|
||||||
|
|
|
@ -90,3 +90,69 @@
|
||||||
return OAUTH3.PromiseA.reject(err);
|
return OAUTH3.PromiseA.reject(err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
core.tokenState = function (session) {
|
||||||
|
var fresh;
|
||||||
|
fresh = (Date.now() / 1000) >= (parseInt(session._accessTokenData.exp) || 0);
|
||||||
|
if (!fresh) {
|
||||||
|
console.log("[os] isn't fresh", session._accessTokenData.exp);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
oauth3._lintRequest = function (preq, opts) {
|
||||||
|
var providerUri;
|
||||||
|
|
||||||
|
console.log('[os] request meta opts', opts);
|
||||||
|
|
||||||
|
// check that the JWT is not expired
|
||||||
|
// TODO check that this request applies to the aud and azp
|
||||||
|
if (!(preq.session && preq.session.accessToken)) {
|
||||||
|
console.log('[os] no session/accessTokenData');
|
||||||
|
return oauth3.PromiseA.resolve(preq);
|
||||||
|
}
|
||||||
|
|
||||||
|
preq.headers = preq.headers || {};
|
||||||
|
preq.headers.Authorization = 'Bearer ' + preq.session.accessToken;
|
||||||
|
|
||||||
|
if (!preq.session._accessTokenData) {
|
||||||
|
console.log('[os] no _accessTokenData');
|
||||||
|
preq.session._accessTokenData = core.jwt.decode(preq.session.accessToken).payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!preq.url.match(preq.session._accessTokenData.aud)) {
|
||||||
|
console.log("[os] doesn't match audience", preq.session._accessTokenData.aud);
|
||||||
|
return oauth3.PromiseA.resolve(preq);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (core.tokenState(session)) {
|
||||||
|
case 'fresh':
|
||||||
|
return oauth3.PromiseA.resolve(preq);
|
||||||
|
case 'stale':
|
||||||
|
case 'useless':
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!preq.session.refreshToken) {
|
||||||
|
console.log("[os] can't refresh", preq.session);
|
||||||
|
return oauth3.PromiseA.resolve(preq);
|
||||||
|
}
|
||||||
|
|
||||||
|
opts.refreshToken = preq.session.refreshToken;
|
||||||
|
console.log('[oauth3.js] refreshToken attempt');
|
||||||
|
|
||||||
|
// TODO include directive?
|
||||||
|
providerUri = preq.session.providerUri || preq.session._accessTokenData.iss;
|
||||||
|
//opts.
|
||||||
|
return oauth3.refreshToken(providerUri, opts).then(function (res) {
|
||||||
|
console.log('[oauth3.js] refreshToken result:', res);
|
||||||
|
|
||||||
|
if (!res.data.accessToken) {
|
||||||
|
return preq;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO fire session update event
|
||||||
|
res.data.providerUri = preq.session.providerUri;
|
||||||
|
preq.session = res.data;
|
||||||
|
preq.headers.Authorization = 'Bearer ' + preq.session.accessToken;
|
||||||
|
return preq;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in New Issue