ravel
Version:
Ravel Rapid Application Development Framework
54 lines (51 loc) • 2.82 kB
JavaScript
;
/**
* Factory for the TokenAuthenticater class, taking a reference to a Ravel app.
*
* @param {Ravel} ravelInstance - A Ravel app.
* @private
*/
module.exports = function (ravelInstance) {
/**
* Validates a user-supplied OAuth 2.0 token in the x-auth-token header
* and transforms it into a user profile
* This token must have been obtained using scopes which yield at least
* the basic user profile (name, etc.) and email address
*
* The token is verified with the appropriate auth provider,
* and then used to look up a user profile via the provider's base API.
* The result of this verification and lookup is cached in Redis for the
* duration of the validity of the token, so that subsequent lookups with
* the same token are faster.
*
* Auth providers may handle multiple client types, such as google-oauth2-ios,
* google-oauth2-android and google-oauth2-web
* @private
*/let
TokenAuthenticater = class TokenAuthenticater {
static credentialToProfile(token, client) {
return new Promise((resolve, reject) => {
const providers = ravelInstance.authenticationProviders();
const provider = providers.filter(p => p.handlesClient(client));
if (provider.length > 0) {
const profileCacheKey = `${provider[0].name}-${client}-profile-${token}`;
ravelInstance.kvstore.get(profileCacheKey, function (err, profileString) {// eslint-disable-line no-loop-func
if (err || !profileString) {
provider[0].credentialToProfile(token, client).
then(result => {
ravelInstance.kvstore.setex(profileCacheKey, result.expiry, JSON.stringify(result.profile));
resolve(result.profile);
}).
catch(reject);
} else {
resolve(JSON.parse(profileString));
}
});
} else {
reject(new ravelInstance.ApplicationError.NotFound(
'No registered authentication providers handle client type ' + client), null);
}
});
}};
return TokenAuthenticater;
};