Socket
Socket
Sign inDemoInstall

jsonwebtoken

Package Overview
Dependencies
Maintainers
8
Versions
81
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

jsonwebtoken - npm Package Compare versions

Comparing version 8.2.2 to 8.3.0

8

CHANGELOG.md

@@ -7,2 +7,10 @@ # Change Log

## 8.3.0 - 2018-06-11
- docs: add some clarifications (#473) ([cd33cc81f06068b9df6c224d300dc6f70d8904ab](https://github.com/auth0/node-jsonwebtoken/commit/cd33cc81f06068b9df6c224d300dc6f70d8904ab)), closes [#473](https://github.com/auth0/node-jsonwebtoken/issues/473)
- ci: fix ci execution, remove not needed script (#472) ([c8ff7b2c3ffcd954a64a0273c20a7d1b22339aa5](https://github.com/auth0/node-jsonwebtoken/commit/c8ff7b2c3ffcd954a64a0273c20a7d1b22339aa5)), closes [#472](https://github.com/auth0/node-jsonwebtoken/issues/472)
- new feature: Secret callback revisited (#480) ([d01cc7bcbdeb606d997a580f967b3169fcc622ba](https://github.com/auth0/node-jsonwebtoken/commit/d01cc7bcbdeb606d997a580f967b3169fcc622ba)), closes [#480](https://github.com/auth0/node-jsonwebtoken/issues/480)
- docs:Update README.md (#461) ([f0e0954505f274da95a8d9603598e455b4d2c894](https://github.com/auth0/node-jsonwebtoken/commit/f0e0954505f274da95a8d9603598e455b4d2c894)), closes [#461](https://github.com/auth0/node-jsonwebtoken/issues/461)
## 8.2.2 - 2018-05-30

@@ -9,0 +17,0 @@

5

package.json
{
"name": "jsonwebtoken",
"version": "8.2.2",
"version": "8.3.0",
"description": "JSON Web Token implementation (symmetric and asymmetric)",

@@ -30,4 +30,3 @@ "main": "index.js",

"lodash.once": "^4.0.0",
"ms": "^2.1.1",
"xtend": "^4.0.1"
"ms": "^2.1.1"
},

@@ -34,0 +33,0 @@ "devDependencies": {

@@ -125,2 +125,3 @@ # jsonwebtoken

encoded public key for RSA and ECDSA.
If `jwt.verify` is called asynchronous, `secretOrPublicKey` can be a function that should fetch the secret or public key. See below for a detailed example

@@ -201,2 +202,19 @@ As mentioned in [this comment](https://github.com/auth0/node-jsonwebtoken/issues/208#issuecomment-231861138), there are other libraries that expect base64 encoded secrets (random bytes encoded using base64), if that is your case you can pass `Buffer.from(secret, 'base64')`, by doing this the secret will be decoded using base64 and the token verification will use the original random bytes.

// Verify using getKey callback
// Example uses https://github.com/auth0/node-jwks-rsa as a way to fetch the keys.
var jwksClient = require('jwks-rsa');
var client = jwksClient({
jwksUri: 'https://sandrino.auth0.com/.well-known/jwks.json'
});
function getKey(header, callback){
client.getSigningKey(header.kid, function(err, key) {
var signingKey = key.publicKey || key.rsaPublicKey;
callback(null, signingKey);
});
}
jwt.verify(token, getKey, options, function(err, decoded) {
console.log(decoded.foo) // bar
});
```

@@ -203,0 +221,0 @@

var timespan = require('./lib/timespan');
var xtend = require('xtend');
var jws = require('jws');

@@ -88,3 +87,3 @@ var includes = require('lodash.includes');

var header = xtend({
var header = Object.assign({
alg: options.algorithm || 'HS256',

@@ -116,3 +115,3 @@ typ: isObjectPayload ? 'JWT' : undefined,

if (!options.mutatePayload) {
payload = xtend(payload);
payload = Object.assign({},payload);
}

@@ -119,0 +118,0 @@ } else {

201

verify.js

@@ -7,3 +7,2 @@ var JsonWebTokenError = require('./lib/JsonWebTokenError');

var jws = require('jws');
var xtend = require('xtend');

@@ -21,3 +20,4 @@ module.exports = function (jwtString, secretOrPublicKey, options, callback) {

//clone this object since we are going to mutate it.
options = xtend(options);
options = Object.assign({}, options);
var done;

@@ -54,29 +54,6 @@

var hasSignature = parts[2].trim() !== '';
var decodedToken;
if (!hasSignature && secretOrPublicKey){
return done(new JsonWebTokenError('jwt signature is required'));
}
if (hasSignature && !secretOrPublicKey) {
return done(new JsonWebTokenError('secret or public key must be provided'));
}
if (!hasSignature && !options.algorithms) {
options.algorithms = ['none'];
}
if (!options.algorithms) {
options.algorithms = ~secretOrPublicKey.toString().indexOf('BEGIN CERTIFICATE') ||
~secretOrPublicKey.toString().indexOf('BEGIN PUBLIC KEY') ?
[ 'RS256','RS384','RS512','ES256','ES384','ES512' ] :
~secretOrPublicKey.toString().indexOf('BEGIN RSA PUBLIC KEY') ?
[ 'RS256','RS384','RS512' ] :
[ 'HS256','HS384','HS512' ];
}
var decodedToken;
try {
decodedToken = jws.decode(jwtString);
decodedToken = decode(jwtString, { complete: true });
} catch(err) {

@@ -91,95 +68,135 @@ return done(err);

var header = decodedToken.header;
var getSecret;
if (!~options.algorithms.indexOf(header.alg)) {
return done(new JsonWebTokenError('invalid algorithm'));
}
if(typeof secretOrPublicKey === 'function') {
if(!callback) {
return done(new JsonWebTokenError('verify must be called asynchronous if secret or public key is provided as a callback'));
}
var valid;
try {
valid = jws.verify(jwtString, header.alg, secretOrPublicKey);
} catch (e) {
return done(e);
getSecret = secretOrPublicKey;
}
else {
getSecret = function(header, secretCallback) {
return secretCallback(null, secretOrPublicKey);
};
}
if (!valid)
return done(new JsonWebTokenError('invalid signature'));
return getSecret(header, function(err, secretOrPublicKey) {
if(err) {
return done(new JsonWebTokenError('error in secret or public key callback: ' + err.message));
}
var payload;
var hasSignature = parts[2].trim() !== '';
try {
payload = decode(jwtString);
} catch(err) {
return done(err);
}
if (!hasSignature && secretOrPublicKey){
return done(new JsonWebTokenError('jwt signature is required'));
}
if (typeof payload.nbf !== 'undefined' && !options.ignoreNotBefore) {
if (typeof payload.nbf !== 'number') {
return done(new JsonWebTokenError('invalid nbf value'));
if (hasSignature && !secretOrPublicKey) {
return done(new JsonWebTokenError('secret or public key must be provided'));
}
if (payload.nbf > clockTimestamp + (options.clockTolerance || 0)) {
return done(new NotBeforeError('jwt not active', new Date(payload.nbf * 1000)));
if (!hasSignature && !options.algorithms) {
options.algorithms = ['none'];
}
}
if (typeof payload.exp !== 'undefined' && !options.ignoreExpiration) {
if (typeof payload.exp !== 'number') {
return done(new JsonWebTokenError('invalid exp value'));
if (!options.algorithms) {
options.algorithms = ~secretOrPublicKey.toString().indexOf('BEGIN CERTIFICATE') ||
~secretOrPublicKey.toString().indexOf('BEGIN PUBLIC KEY') ?
['RS256', 'RS384', 'RS512', 'ES256', 'ES384', 'ES512'] :
~secretOrPublicKey.toString().indexOf('BEGIN RSA PUBLIC KEY') ?
['RS256', 'RS384', 'RS512'] :
['HS256', 'HS384', 'HS512'];
}
if (clockTimestamp >= payload.exp + (options.clockTolerance || 0)) {
return done(new TokenExpiredError('jwt expired', new Date(payload.exp * 1000)));
if (!~options.algorithms.indexOf(decodedToken.header.alg)) {
return done(new JsonWebTokenError('invalid algorithm'));
}
}
if (options.audience) {
var audiences = Array.isArray(options.audience)? options.audience : [options.audience];
var target = Array.isArray(payload.aud) ? payload.aud : [payload.aud];
var valid;
var match = target.some(function(targetAudience) {
return audiences.some(function(audience) {
return audience instanceof RegExp ? audience.test(targetAudience) : audience === targetAudience;
});
});
try {
valid = jws.verify(jwtString, decodedToken.header.alg, secretOrPublicKey);
} catch (e) {
return done(e);
}
if (!match)
return done(new JsonWebTokenError('jwt audience invalid. expected: ' + audiences.join(' or ')));
}
if (!valid) {
return done(new JsonWebTokenError('invalid signature'));
}
if (options.issuer) {
var invalid_issuer =
(typeof options.issuer === 'string' && payload.iss !== options.issuer) ||
(Array.isArray(options.issuer) && options.issuer.indexOf(payload.iss) === -1);
var payload = decodedToken.payload;
if (invalid_issuer) {
return done(new JsonWebTokenError('jwt issuer invalid. expected: ' + options.issuer));
if (typeof payload.nbf !== 'undefined' && !options.ignoreNotBefore) {
if (typeof payload.nbf !== 'number') {
return done(new JsonWebTokenError('invalid nbf value'));
}
if (payload.nbf > clockTimestamp + (options.clockTolerance || 0)) {
return done(new NotBeforeError('jwt not active', new Date(payload.nbf * 1000)));
}
}
}
if (options.subject) {
if (payload.sub !== options.subject) {
return done(new JsonWebTokenError('jwt subject invalid. expected: ' + options.subject));
if (typeof payload.exp !== 'undefined' && !options.ignoreExpiration) {
if (typeof payload.exp !== 'number') {
return done(new JsonWebTokenError('invalid exp value'));
}
if (clockTimestamp >= payload.exp + (options.clockTolerance || 0)) {
return done(new TokenExpiredError('jwt expired', new Date(payload.exp * 1000)));
}
}
}
if (options.jwtid) {
if (payload.jti !== options.jwtid) {
return done(new JsonWebTokenError('jwt jwtid invalid. expected: ' + options.jwtid));
if (options.audience) {
var audiences = Array.isArray(options.audience) ? options.audience : [options.audience];
var target = Array.isArray(payload.aud) ? payload.aud : [payload.aud];
var match = target.some(function (targetAudience) {
return audiences.some(function (audience) {
return audience instanceof RegExp ? audience.test(targetAudience) : audience === targetAudience;
});
});
if (!match) {
return done(new JsonWebTokenError('jwt audience invalid. expected: ' + audiences.join(' or ')));
}
}
}
if (options.maxAge) {
if (typeof payload.iat !== 'number') {
return done(new JsonWebTokenError('iat required when maxAge is specified'));
if (options.issuer) {
var invalid_issuer =
(typeof options.issuer === 'string' && payload.iss !== options.issuer) ||
(Array.isArray(options.issuer) && options.issuer.indexOf(payload.iss) === -1);
if (invalid_issuer) {
return done(new JsonWebTokenError('jwt issuer invalid. expected: ' + options.issuer));
}
}
var maxAgeTimestamp = timespan(options.maxAge, payload.iat);
if (typeof maxAgeTimestamp === 'undefined') {
return done(new JsonWebTokenError('"maxAge" should be a number of seconds or string representing a timespan eg: "1d", "20h", 60'));
if (options.subject) {
if (payload.sub !== options.subject) {
return done(new JsonWebTokenError('jwt subject invalid. expected: ' + options.subject));
}
}
if (clockTimestamp >= maxAgeTimestamp + (options.clockTolerance || 0)) {
return done(new TokenExpiredError('maxAge exceeded', new Date(maxAgeTimestamp * 1000)));
if (options.jwtid) {
if (payload.jti !== options.jwtid) {
return done(new JsonWebTokenError('jwt jwtid invalid. expected: ' + options.jwtid));
}
}
}
return done(null, payload);
if (options.maxAge) {
if (typeof payload.iat !== 'number') {
return done(new JsonWebTokenError('iat required when maxAge is specified'));
}
var maxAgeTimestamp = timespan(options.maxAge, payload.iat);
if (typeof maxAgeTimestamp === 'undefined') {
return done(new JsonWebTokenError('"maxAge" should be a number of seconds or string representing a timespan eg: "1d", "20h", 60'));
}
if (clockTimestamp >= maxAgeTimestamp + (options.clockTolerance || 0)) {
return done(new TokenExpiredError('maxAge exceeded', new Date(maxAgeTimestamp * 1000)));
}
}
return done(null, payload);
});
};
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc