changed how grants are saved and how tokens are created for other clients
This commit is contained in:
parent
1ca6f0a324
commit
28dbf9ab23
|
@ -78,7 +78,7 @@
|
|||
, uri: {
|
||||
normalize: function (uri) {
|
||||
if ('string' !== typeof uri) {
|
||||
console.error((new Error('stack')).stack);
|
||||
throw new Error("attempted to normalize non-string URI: "+JSON.stringify(uri));
|
||||
}
|
||||
// tested with
|
||||
// example.com
|
||||
|
@ -94,7 +94,7 @@
|
|||
, url: {
|
||||
normalize: function (url) {
|
||||
if ('string' !== typeof url) {
|
||||
console.error((new Error('stack')).stack);
|
||||
throw new Error("attempted to normalize non-string URL: "+JSON.stringify(url));
|
||||
}
|
||||
// tested with
|
||||
// example.com
|
||||
|
|
145
oauth3.issuer.js
145
oauth3.issuer.js
|
@ -102,8 +102,6 @@ OAUTH3.urls.resourceOwnerPassword = function (directive, opts) {
|
|||
// , "username": "<<username>>", "password": "password" }
|
||||
//
|
||||
opts = opts || {};
|
||||
var type = 'access_token';
|
||||
var grantType = 'password';
|
||||
|
||||
if (!opts.password) {
|
||||
if (opts.otp) {
|
||||
|
@ -112,16 +110,13 @@ OAUTH3.urls.resourceOwnerPassword = function (directive, opts) {
|
|||
}
|
||||
}
|
||||
|
||||
var scope = opts.scope || directive.authn_scope;
|
||||
var clientAgreeTos = 'oauth3.org/tos/draft'; // opts.clientAgreeTos || opts.client_agree_tos;
|
||||
var clientUri = opts.client_uri;
|
||||
var args = directive[type];
|
||||
var args = directive.access_token;
|
||||
var otpCode = opts.otp || opts.otpCode || opts.otp_code || opts.otpToken || opts.otp_token || undefined;
|
||||
// TODO require user agent
|
||||
var params = {
|
||||
client_id: opts.client_id || opts.client_uri
|
||||
, client_uri: opts.client_uri
|
||||
, grant_type: grantType
|
||||
, grant_type: 'password'
|
||||
, username: opts.username
|
||||
, password: opts.password || otpCode || undefined
|
||||
, totp: opts.totp || opts.totpToken || opts.totp_token || undefined
|
||||
|
@ -136,23 +131,21 @@ OAUTH3.urls.resourceOwnerPassword = function (directive, opts) {
|
|||
//, "jwt": opts.jwt // TODO sign a proof with a previously loaded public_key
|
||||
, debug: opts.debug || undefined
|
||||
};
|
||||
var uri = args.url;
|
||||
var body;
|
||||
if (opts.totp) {
|
||||
params.totp = opts.totp;
|
||||
}
|
||||
|
||||
if (clientUri) {
|
||||
params.clientAgreeTos = clientAgreeTos;
|
||||
if (!clientAgreeTos) {
|
||||
if (opts.client_uri) {
|
||||
params.clientAgreeTos = 'oauth3.org/tos/draft'; // opts.clientAgreeTos || opts.client_agree_tos;
|
||||
if (!params.clientAgreeTos) {
|
||||
throw new Error('Developer Error: missing clientAgreeTos uri');
|
||||
}
|
||||
}
|
||||
|
||||
var scope = opts.scope || directive.authn_scope;
|
||||
if (scope) {
|
||||
params.scope = OAUTH3.scope.stringify(scope);
|
||||
}
|
||||
|
||||
var uri = args.url;
|
||||
var body;
|
||||
if ('GET' === args.method.toUpperCase()) {
|
||||
uri += '?' + OAUTH3.query.stringify(params);
|
||||
} else {
|
||||
|
@ -168,6 +161,10 @@ OAUTH3.urls.resourceOwnerPassword = function (directive, opts) {
|
|||
OAUTH3.urls.grants = function (directive, opts) {
|
||||
// directive = { issuer, authorization_decision }
|
||||
// opts = { response_type, scopes{ granted, requested, pending, accepted } }
|
||||
var grantsDir = directive.grants;
|
||||
if (!grantsDir) {
|
||||
throw new Error("provider doesn't support grants");
|
||||
}
|
||||
|
||||
if (!opts) {
|
||||
throw new Error("You must supply a directive and an options object.");
|
||||
|
@ -183,15 +180,18 @@ OAUTH3.urls.grants = function (directive, opts) {
|
|||
}
|
||||
if (!opts.method) {
|
||||
console.warn("You should supply options.method as either 'GET', or 'POST'");
|
||||
opts.method = 'GET';
|
||||
opts.method = grantsDir.method || 'GET';
|
||||
}
|
||||
if ('POST' === opts.method) {
|
||||
if ('string' !== typeof opts.scope) {
|
||||
throw new Error("You must supply options.scope as a comma-delimited string of scopes");
|
||||
}
|
||||
if ('string' !== typeof opts.sub) {
|
||||
console.log("provide 'sub' to urls.grants to specify the PPID for the client");
|
||||
}
|
||||
}
|
||||
|
||||
var url = OAUTH3.url.resolve(directive.api, directive.grants.url)
|
||||
var url = OAUTH3.url.resolve(directive.api, grantsDir.url)
|
||||
.replace(/(:azp|:client_id)/g, OAUTH3.uri.normalize(opts.client_id || opts.client_uri))
|
||||
.replace(/(:sub|:account_id)/g, opts.session.token.sub || 'ISSUER:GRANT:TOKEN_SUB:UNDEFINED')
|
||||
;
|
||||
|
@ -200,13 +200,13 @@ OAUTH3.urls.grants = function (directive, opts) {
|
|||
, client_uri: opts.client_uri
|
||||
, referrer: opts.referrer
|
||||
, scope: opts.scope
|
||||
, sub: opts.sub
|
||||
};
|
||||
|
||||
var body;
|
||||
if ('GET' === opts.method) {
|
||||
url += '?' + OAUTH3.query.stringify(data);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
body = data;
|
||||
}
|
||||
|
||||
|
@ -217,6 +217,50 @@ OAUTH3.urls.grants = function (directive, opts) {
|
|||
, session: opts.session
|
||||
};
|
||||
};
|
||||
OAUTH3.urls.clientToken = function (directive, opts) {
|
||||
var tokenDir = directive.access_token;
|
||||
if (!tokenDir) {
|
||||
throw new Error("provider doesn't support getting access tokens");
|
||||
}
|
||||
|
||||
if (!opts) {
|
||||
throw new Error("You must supply a directive and an options object.");
|
||||
}
|
||||
if (!(opts.azp || opts.client_id)) {
|
||||
throw new Error("You must supply options.client_id.");
|
||||
}
|
||||
if (!opts.session) {
|
||||
throw new Error("You must supply options.session.");
|
||||
}
|
||||
if (!opts.method) {
|
||||
opts.method = tokenDir.method || 'POST';
|
||||
}
|
||||
|
||||
var params = {
|
||||
grant_type: 'issuer_token'
|
||||
, client_id: opts.azp || opts.client_id
|
||||
, azp: opts.azp || opts.client_id
|
||||
, aud: opts.aud
|
||||
, exp: opts.exp
|
||||
, refresh_token: opts.refresh_token
|
||||
, refresh_exp: opts.refresh_exp
|
||||
};
|
||||
|
||||
var url = OAUTH3.url.resolve(directive.api, tokenDir.url);
|
||||
var body;
|
||||
if ('GET' === opts.method) {
|
||||
url += '?' + OAUTH3.query.stringify(params);
|
||||
} else {
|
||||
body = params;
|
||||
}
|
||||
|
||||
return {
|
||||
method: opts.method
|
||||
, url: url
|
||||
, data: body
|
||||
, session: opts.session
|
||||
};
|
||||
};
|
||||
|
||||
OAUTH3.authn = {};
|
||||
OAUTH3.authn.loginMeta = function (directive, opts) {
|
||||
|
@ -340,34 +384,51 @@ OAUTH3.authz.redirectWithToken = function (providerUri, session, clientParams, s
|
|||
if (!OAUTH3.url.checkRedirect(clientParams.client_uri, clientParams)) {
|
||||
return;
|
||||
}
|
||||
if ('token' !== clientParams.response_type) {
|
||||
var message;
|
||||
if ('code' === clientParams.response_type) {
|
||||
message = "Authorization Code Redirect NOT IMPLEMENTED";
|
||||
} else {
|
||||
message = "Authorization response type '"+clientParams.response_type+"' not supported";
|
||||
}
|
||||
window.alert(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
scopes.new = scopes.new || [];
|
||||
|
||||
if ('token' === clientParams.response_type) {
|
||||
// get token and redirect client-side
|
||||
return OAUTH3.authz.grants(providerUri, {
|
||||
method: 'POST'
|
||||
var prom;
|
||||
if (scopes.new) {
|
||||
prom = OAUTH3.authz.grants(providerUri, {
|
||||
session: session
|
||||
, method: 'POST'
|
||||
, client_id: clientParams.client_uri
|
||||
, client_uri: clientParams.client_uri
|
||||
, scope: scopes.granted.concat(scopes.new).join(',')
|
||||
, response_type: clientParams.response_type
|
||||
, referrer: clientParams.referrer
|
||||
, session: session
|
||||
, debug: clientParams.debug
|
||||
}).then(function (results) {
|
||||
|
||||
// TODO limit refresh token to an expirable token
|
||||
// TODO inform client not to persist token
|
||||
OAUTH3.url.redirect(clientParams, scopes, results);
|
||||
, scope: scopes.accepted.concat(scopes.new).join(',')
|
||||
});
|
||||
} else {
|
||||
prom = OAUTH3.PromiseA.resolve();
|
||||
}
|
||||
else if ('code' === clientParams.response_type) {
|
||||
// get token and redirect server-side
|
||||
// (requires insecure form post as per spec)
|
||||
//OAUTH3.requests.authorizationDecision();
|
||||
window.alert("Authorization Code Redirect NOT IMPLEMENTED");
|
||||
throw new Error("Authorization Code Redirect NOT IMPLEMENTED");
|
||||
}
|
||||
|
||||
return prom.then(function () {
|
||||
return OAUTH3.discover(providerUri, { client_id: providerUri, debug: clientParams.debug });
|
||||
}).then(function (directive) {
|
||||
return OAUTH3.request(OAUTH3.urls.clientToken(directive, {
|
||||
method: 'POST'
|
||||
, session: session
|
||||
, referrer: clientParams.referrer
|
||||
, response_type: clientParams.response_type
|
||||
, client_id: clientParams.client_uri
|
||||
, azp: clientParams.client_uri
|
||||
, aud: clientParams.aud
|
||||
, exp: clientParams.exp
|
||||
, refresh_token: clientParams.refresh_token
|
||||
, refresh_exp: clientParams.refresh_exp
|
||||
, debug: clientParams.debug
|
||||
}));
|
||||
}).then(function (results) {
|
||||
// TODO limit refresh token to an expirable token
|
||||
// TODO inform client not to persist token
|
||||
OAUTH3.url.redirect(clientParams, scopes, results.originalData || results.data);
|
||||
});
|
||||
};
|
||||
|
||||
OAUTH3.requests = {};
|
||||
|
|
Loading…
Reference in New Issue