'use strict';
var _ = require('underscore'),
jwt = require('jwt-simple'),
Request = require('./Request'),
BEARER_REGEX = /^Bearer /;
module.exports = Request.extend({
init: function(evt, context) {
this._super(evt, context);
this._token = false;
},
getToken: function() {
return this._token;
},
validateAuthorizationHeader: function(publicKey, validationUserOpts) {
var rawHeader = this.header('Authorization') || '',
rawToken = rawHeader.replace(BEARER_REGEX, ''),
validationOpts = _.isObject(validationUserOpts) ? validationUserOpts : {},
decoded;
if (_.isEmpty(rawHeader) || _.isEmpty(rawToken)) {
this._token = false;
return { isValid: false, msg: 'No token supplied in Authorization header' };
}
if (!BEARER_REGEX.test(rawHeader)) {
this._token = false;
return { isValid: false, msg: 'Authorization header not in correct format' };
}
try {
decoded = jwt.decode(rawToken, publicKey, false, 'RS256');
} catch(err) {
this._token = false;
return { isValid: false, msg: 'Invalid authorization token', err: err.message };
}
decoded = this._validateTokenAudience(decoded, validationOpts.audience);
decoded = this._validateTokenIssuer(decoded, validationOpts.issuer);
decoded = this._validateRevocationList(decoded, validationOpts.revokedTokenIDs);
this._token = decoded;
if (this._token === false) {
// TODO: add an err message here, which will require changing all the
// _validate* functions
return { isValid: false, msg: 'Invalid authorization token', err: 'TODO' };
}
return { isValid: true };
},
_validateTokenIssuer: function(token, issuer) {
if (_.isEmpty(issuer)) {
return token;
} else if (!_.isObject(token)) {
return token;
}
return token.iss === issuer ? token : false;
},
_validateTokenAudience: function(token, intendedAudience) {
if (_.isEmpty(intendedAudience)) {
return token;
} else if (!_.isObject(token)) {
return token;
}
if (_.isArray(token.aud)) {
return _.contains(token.aud, intendedAudience) ? token : false;
}
// audience is a single value:
return token.aud === intendedAudience ? token : false;
},
_validateRevocationList: function(token, revokedTokenIDs) {
if (_.isEmpty(revokedTokenIDs)) {
return token;
} else if (!_.isObject(token)) {
return token;
}
return _.contains(revokedTokenIDs, token.jti) ? false : token;
},
});
|