signing the token for the client in the browser

This commit is contained in:
tigerbot 2017-08-01 14:21:11 -06:00
parent 5d42f3e2cc
commit 516eda4ea6
1 changed files with 95 additions and 18 deletions

View File

@ -437,6 +437,39 @@ OAUTH3.authz.grants = function (providerUri, opts) {
};
});
};
function calcExpiration(exp, now) {
if (!exp) {
return;
}
if (typeof exp === 'string') {
var match = /^(\d+\.?\d*) *(seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(exp);
if (!match) {
return now;
}
var num = parseFloat(match[1]);
var type = (match[2] || 's').toLowerCase()[0];
switch (type) {
case 'y': num *= 365.25; /* falls through */
case 'd': num *= 24; /* falls through */
case 'h': num *= 60; /* falls through */
case 'm': num *= 60; /* falls through */
case 's': exp = num;
}
}
if (typeof exp !== 'number') {
throw new Error('invalid expiration provided: '+exp);
}
now = now || Math.floor(Date.now() / 1000);
if (exp > now) {
return exp;
} else if (exp > 31557600) {
console.warn('tried to set expiration to more that a year');
exp = 31557600;
}
return now + exp;
}
OAUTH3.authz.redirectWithToken = function (providerUri, session, clientParams, scopes) {
if (!OAUTH3.url.checkRedirect(clientParams.client_uri, clientParams)) {
return;
@ -466,25 +499,66 @@ OAUTH3.authz.redirectWithToken = function (providerUri, session, clientParams, s
}
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) {
return OAUTH3.hooks.keyPairs.get(session.token.sub);
}).then(function (keyPair) {
if (!keyPair) {
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 (result) {
return result.originalData || result.data;
});
});
}
return OAUTH3.hooks.grants.get(keyPair.sub, clientParams.client_uri).then(function (grant) {
var now = Math.floor(Date.now()/1000);
var payload = {
iat: now
, iss: providerUri
, aud: clientParams.aud || providerUri
, azp: clientParams.client_uri
, sub: grant.azpSub
, scope: OAUTH3.scope.stringify(grant.scope)
, };
var signProms = [];
signProms.push(OAUTH3.jwt.sign(Object.assign({
exp: calcExpiration(clientParams.exp || '1h', now)
}, payload)));
// if (clientParams.refresh_token) {
signProms.push(OAUTH3.jwt.sign(Object.assign({
exp: calcExpiration(clientParams.refresh_exp, now)
}, payload)));
// }
return OAUTH3.PromiseA.all(signProms).then(function (tokens) {
return {
access_token: tokens[0]
, refresh_token: tokens[1]
, scope: OAUTH3.scope.stringify(grant.scope)
, token_type: 'bearer'
};
});
});
}).then(function (session) {
// 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.url.redirect(clientParams, scopes, session);
}, function (err) {
OAUTH3.url.redirect(clientParams, scopes, {error: err});
});
};
@ -650,12 +724,15 @@ OAUTH3.hooks.session.get = function (providerUri, id) {
return null;
}
var now = Math.floor(Date.now()/1000);
var payload = {
iss: providerUri
iat: now
, iss: providerUri
, aud: providerUri
, azp: providerUri
, sub: pair.sub || id
, scope: ''
, exp: now + 3600
};
return OAUTH3.jwt.sign(payload, pair.privateKey).then(function (token) {
return OAUTH3.hooks.session.refresh(