Socket
Socket
Sign inDemoInstall

jsonwebtoken

Package Overview
Dependencies
10
Maintainers
10
Versions
81
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 8.5.1 to 9.0.0

lib/asymmetricKeyDetailsSupported.js

6

index.js
module.exports = {
decode: require('./decode'),
verify: require('./verify'),

@@ -9,1 +8,6 @@ sign: require('./sign'),

};
Object.defineProperty(module.exports, 'decode', {
enumerable: false,
value: require('./decode'),
});

16

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

@@ -40,11 +40,5 @@ "main": "index.js",

"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
"lodash.isboolean": "^3.0.3",
"lodash.isinteger": "^4.0.4",
"lodash.isnumber": "^3.0.3",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"lodash.once": "^4.0.0",
"lodash": "^4.17.21",
"ms": "^2.1.1",
"semver": "^5.6.0"
"semver": "^7.3.8"
},

@@ -63,4 +57,4 @@ "devDependencies": {

"engines": {
"npm": ">=1.4.28",
"node": ">=4"
"npm": ">=6",
"node": ">=12"
},

@@ -67,0 +61,0 @@ "files": [

# jsonwebtoken
| **Build** | **Dependency** |
|-----------|---------------|
| **Build** | **Dependency** |
|-----------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------|
| [![Build Status](https://secure.travis-ci.org/auth0/node-jsonwebtoken.svg?branch=master)](http://travis-ci.org/auth0/node-jsonwebtoken) | [![Dependency Status](https://david-dm.org/auth0/node-jsonwebtoken.svg)](https://david-dm.org/auth0/node-jsonwebtoken) |

@@ -20,2 +20,3 @@

* [From v8 to v9](https://github.com/auth0/node-jsonwebtoken/wiki/Migration-Notes:-v8-to-v9)
* [From v7 to v8](https://github.com/auth0/node-jsonwebtoken/wiki/Migration-Notes:-v7-to-v8)

@@ -36,4 +37,5 @@

`secretOrPrivateKey` is a string, buffer, or object containing either the secret for HMAC algorithms or the PEM
`secretOrPrivateKey` is a string (utf-8 encoded), buffer, object, or KeyObject containing either the secret for HMAC algorithms or the PEM
encoded private key for RSA and ECDSA. In case of a private key with passphrase an object `{ key, passphrase }` can be used (based on [crypto documentation](https://nodejs.org/api/crypto.html#crypto_sign_sign_private_key_output_format)), in this case be sure you pass the `algorithm` option.
When signing with RSA algorithms the minimum modulus length is 2048 except when the allowInsecureKeySizes option is set to true. Private keys below this size will be rejected with an error.

@@ -43,5 +45,5 @@ `options`:

* `algorithm` (default: `HS256`)
* `expiresIn`: expressed in seconds or a string describing a time span [zeit/ms](https://github.com/zeit/ms).
* `expiresIn`: expressed in seconds or a string describing a time span [vercel/ms](https://github.com/vercel/ms).
> Eg: `60`, `"2 days"`, `"10h"`, `"7d"`. A numeric value is interpreted as a seconds count. If you use a string be sure you provide the time units (days, hours, etc), otherwise milliseconds unit is used by default (`"120"` is equal to `"120ms"`).
* `notBefore`: expressed in seconds or a string describing a time span [zeit/ms](https://github.com/zeit/ms).
* `notBefore`: expressed in seconds or a string describing a time span [vercel/ms](https://github.com/vercel/ms).
> Eg: `60`, `"2 days"`, `"10h"`, `"7d"`. A numeric value is interpreted as a seconds count. If you use a string be sure you provide the time units (days, hours, etc), otherwise milliseconds unit is used by default (`"120"` is equal to `"120ms"`).

@@ -56,2 +58,4 @@ * `audience`

* `mutatePayload`: if true, the sign function will modify the payload object directly. This is useful if you need a raw reference to the payload after claims have been applied to it but before it has been encoded into a token.
* `allowInsecureKeySizes`: if true allows private keys with a modulus below 2048 to be used for RSA
* `allowInvalidAsymmetricKeyTypes`: if true, allows asymmetric keys which do not match the specified algorithm. This option is intended only for backwards compatability and should be avoided.

@@ -80,3 +84,3 @@

var privateKey = fs.readFileSync('private.key');
var token = jwt.sign({ foo: 'bar' }, privateKey, { algorithm: 'RS256'});
var token = jwt.sign({ foo: 'bar' }, privateKey, { algorithm: 'RS256' });
```

@@ -133,5 +137,7 @@

> __Warning:__ When the token comes from an untrusted source (e.g. user input or external requests), the returned decoded payload should be treated like any other user input; please make sure to sanitize and only work with properties that are expected
`token` is the JsonWebToken string
`secretOrPublicKey` is a string or buffer containing either the secret for HMAC algorithms, or the PEM
`secretOrPublicKey` is a string (utf-8 encoded), buffer, or KeyObject containing either the secret for HMAC algorithms, or the PEM
encoded public key for RSA and ECDSA.

@@ -144,3 +150,8 @@ 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

* `algorithms`: List of strings with the names of the allowed algorithms. For instance, `["HS256", "HS384"]`.
* `algorithms`: List of strings with the names of the allowed algorithms. For instance, `["HS256", "HS384"]`.
> If not specified a defaults will be used based on the type of key provided
> * secret - ['HS256', 'HS384', 'HS512']
> * rsa - ['RS256', 'RS384', 'RS512']
> * ec - ['ES256', 'ES384', 'ES512']
> * default - ['RS256', 'RS384', 'RS512']
* `audience`: if you want to check audience (`aud`), provide a value here. The audience can be checked against a string, a regular expression or a list of strings and/or regular expressions.

@@ -150,2 +161,3 @@ > Eg: `"urn:foo"`, `/urn:f[o]{2}/`, `[/urn:f[o]{2}/, "urn:bar"]`

* `issuer` (optional): string or array of strings of valid values for the `iss` field.
* `jwtid` (optional): if you want to check JWT ID (`jti`), provide a string value here.
* `ignoreExpiration`: if `true` do not validate the expiration of the token.

@@ -155,8 +167,8 @@ * `ignoreNotBefore`...

* `clockTolerance`: number of seconds to tolerate when checking the `nbf` and `exp` claims, to deal with small clock differences among different servers
* `maxAge`: the maximum allowed age for tokens to still be valid. It is expressed in seconds or a string describing a time span [zeit/ms](https://github.com/zeit/ms).
* `maxAge`: the maximum allowed age for tokens to still be valid. It is expressed in seconds or a string describing a time span [vercel/ms](https://github.com/vercel/ms).
> Eg: `1000`, `"2 days"`, `"10h"`, `"7d"`. A numeric value is interpreted as a seconds count. If you use a string be sure you provide the time units (days, hours, etc), otherwise milliseconds unit is used by default (`"120"` is equal to `"120ms"`).
* `clockTimestamp`: the time in seconds that should be used as the current time for all necessary comparisons.
* `nonce`: if you want to check `nonce` claim, provide a string value here. It is used on Open ID for the ID Tokens. ([Open ID implementation notes](https://openid.net/specs/openid-connect-core-1_0.html#NonceNotes))
* `allowInvalidAsymmetricKeyTypes`: if true, allows asymmetric keys which do not match the specified algorithm. This option is intended only for backwards compatability and should be avoided.
```js

@@ -240,2 +252,5 @@ // verify a token symmetric - synchronous

<details>
<summary><em></em>Need to peek into a JWT without verifying it? (Click to expand)</summary>
### jwt.decode(token [, options])

@@ -247,2 +262,5 @@

> __Warning:__ When the token comes from an untrusted source (e.g. user input or external request), the returned decoded payload should be treated like any other user input; please make sure to sanitize and only work with properties that are expected
`token` is the JsonWebToken string

@@ -267,2 +285,4 @@

</details>
## Errors & Codes

@@ -301,3 +321,4 @@ Possible thrown errors during verification.

* message:
* 'jwt malformed'
* 'invalid token' - the header or payload could not be parsed
* 'jwt malformed' - the token does not have three components (delimited by a `.`)
* 'jwt signature is required'

@@ -351,17 +372,17 @@ * 'invalid signature'

alg Parameter Value | Digital Signature or MAC Algorithm
----------------|----------------------------
HS256 | HMAC using SHA-256 hash algorithm
HS384 | HMAC using SHA-384 hash algorithm
HS512 | HMAC using SHA-512 hash algorithm
RS256 | RSASSA-PKCS1-v1_5 using SHA-256 hash algorithm
RS384 | RSASSA-PKCS1-v1_5 using SHA-384 hash algorithm
RS512 | RSASSA-PKCS1-v1_5 using SHA-512 hash algorithm
PS256 | RSASSA-PSS using SHA-256 hash algorithm (only node ^6.12.0 OR >=8.0.0)
PS384 | RSASSA-PSS using SHA-384 hash algorithm (only node ^6.12.0 OR >=8.0.0)
PS512 | RSASSA-PSS using SHA-512 hash algorithm (only node ^6.12.0 OR >=8.0.0)
ES256 | ECDSA using P-256 curve and SHA-256 hash algorithm
ES384 | ECDSA using P-384 curve and SHA-384 hash algorithm
ES512 | ECDSA using P-521 curve and SHA-512 hash algorithm
none | No digital signature or MAC value included
| alg Parameter Value | Digital Signature or MAC Algorithm |
|---------------------|------------------------------------------------------------------------|
| HS256 | HMAC using SHA-256 hash algorithm |
| HS384 | HMAC using SHA-384 hash algorithm |
| HS512 | HMAC using SHA-512 hash algorithm |
| RS256 | RSASSA-PKCS1-v1_5 using SHA-256 hash algorithm |
| RS384 | RSASSA-PKCS1-v1_5 using SHA-384 hash algorithm |
| RS512 | RSASSA-PKCS1-v1_5 using SHA-512 hash algorithm |
| PS256 | RSASSA-PSS using SHA-256 hash algorithm (only node ^6.12.0 OR >=8.0.0) |
| PS384 | RSASSA-PSS using SHA-384 hash algorithm (only node ^6.12.0 OR >=8.0.0) |
| PS512 | RSASSA-PSS using SHA-512 hash algorithm (only node ^6.12.0 OR >=8.0.0) |
| ES256 | ECDSA using P-256 curve and SHA-256 hash algorithm |
| ES384 | ECDSA using P-384 curve and SHA-384 hash algorithm |
| ES512 | ECDSA using P-521 curve and SHA-512 hash algorithm |
| none | No digital signature or MAC value included |

@@ -368,0 +389,0 @@ ## Refreshing JWTs

@@ -1,13 +0,9 @@

var timespan = require('./lib/timespan');
var PS_SUPPORTED = require('./lib/psSupported');
var jws = require('jws');
var includes = require('lodash.includes');
var isBoolean = require('lodash.isboolean');
var isInteger = require('lodash.isinteger');
var isNumber = require('lodash.isnumber');
var isPlainObject = require('lodash.isplainobject');
var isString = require('lodash.isstring');
var once = require('lodash.once');
const timespan = require('./lib/timespan');
const PS_SUPPORTED = require('./lib/psSupported');
const validateAsymmetricKey = require('./lib/validateAsymmetricKey');
const jws = require('jws');
const {includes, isBoolean, isInteger, isNumber, isPlainObject, isString, once} = require('lodash')
const { KeyObject, createSecretKey, createPrivateKey } = require('crypto')
var SUPPORTED_ALGS = ['RS256', 'RS384', 'RS512', 'ES256', 'ES384', 'ES512', 'HS256', 'HS384', 'HS512', 'none']
const SUPPORTED_ALGS = ['RS256', 'RS384', 'RS512', 'ES256', 'ES384', 'ES512', 'HS256', 'HS384', 'HS512', 'none'];
if (PS_SUPPORTED) {

@@ -17,3 +13,3 @@ SUPPORTED_ALGS.splice(3, 0, 'PS256', 'PS384', 'PS512');

var sign_options_schema = {
const sign_options_schema = {
expiresIn: { isValid: function(value) { return isInteger(value) || (isString(value) && value); }, message: '"expiresIn" should be a number of seconds or string representing a timespan' },

@@ -30,6 +26,8 @@ notBefore: { isValid: function(value) { return isInteger(value) || (isString(value) && value); }, message: '"notBefore" should be a number of seconds or string representing a timespan' },

keyid: { isValid: isString, message: '"keyid" must be a string' },
mutatePayload: { isValid: isBoolean, message: '"mutatePayload" must be a boolean' }
mutatePayload: { isValid: isBoolean, message: '"mutatePayload" must be a boolean' },
allowInsecureKeySizes: { isValid: isBoolean, message: '"allowInsecureKeySizes" must be a boolean'},
allowInvalidAsymmetricKeyTypes: { isValid: isBoolean, message: '"allowInvalidAsymmetricKeyTypes" must be a boolean'}
};
var registered_claims_schema = {
const registered_claims_schema = {
iat: { isValid: isNumber, message: '"iat" should be a number of seconds' },

@@ -46,3 +44,3 @@ exp: { isValid: isNumber, message: '"exp" should be a number of seconds' },

.forEach(function(key) {
var validator = schema[key];
const validator = schema[key];
if (!validator) {

@@ -68,3 +66,3 @@ if (!allowUnknown) {

var options_to_payload = {
const options_to_payload = {
'audience': 'aud',

@@ -76,3 +74,3 @@ 'issuer': 'iss',

var options_for_objects = [
const options_for_objects = [
'expiresIn',

@@ -95,6 +93,6 @@ 'notBefore',

var isObjectPayload = typeof payload === 'object' &&
const isObjectPayload = typeof payload === 'object' &&
!Buffer.isBuffer(payload);
var header = Object.assign({
const header = Object.assign({
alg: options.algorithm || 'HS256',

@@ -116,2 +114,28 @@ typ: isObjectPayload ? 'JWT' : undefined,

if (secretOrPrivateKey != null && !(secretOrPrivateKey instanceof KeyObject)) {
try {
secretOrPrivateKey = createPrivateKey(secretOrPrivateKey)
} catch (_) {
try {
secretOrPrivateKey = createSecretKey(typeof secretOrPrivateKey === 'string' ? Buffer.from(secretOrPrivateKey) : secretOrPrivateKey)
} catch (_) {
return failure(new Error('secretOrPrivateKey is not valid key material'));
}
}
}
if (header.alg.startsWith('HS') && secretOrPrivateKey.type !== 'secret') {
return failure(new Error((`secretOrPrivateKey must be a symmetric key when using ${header.alg}`)))
} else if (/^(?:RS|PS|ES)/.test(header.alg)) {
if (secretOrPrivateKey.type !== 'private') {
return failure(new Error((`secretOrPrivateKey must be an asymmetric key when using ${header.alg}`)))
}
if (!options.allowInsecureKeySizes &&
!header.alg.startsWith('ES') &&
secretOrPrivateKey.asymmetricKeyDetails !== undefined && //KeyObject.asymmetricKeyDetails is supported in Node 15+
secretOrPrivateKey.asymmetricKeyDetails.modulusLength < 2048) {
return failure(new Error(`secretOrPrivateKey has a minimum key size of 2048 bits for ${header.alg}`));
}
}
if (typeof payload === 'undefined') {

@@ -130,3 +154,3 @@ return failure(new Error('payload is required'));

} else {
var invalid_options = options_for_objects.filter(function (opt) {
const invalid_options = options_for_objects.filter(function (opt) {
return typeof options[opt] !== 'undefined';

@@ -155,4 +179,12 @@ });

var timestamp = payload.iat || Math.floor(Date.now() / 1000);
if (!options.allowInvalidAsymmetricKeyTypes) {
try {
validateAsymmetricKey(header.alg, secretOrPrivateKey);
} catch (error) {
return failure(error);
}
}
const timestamp = payload.iat || Math.floor(Date.now() / 1000);
if (options.noTimestamp) {

@@ -189,3 +221,3 @@ delete payload.iat;

Object.keys(options_to_payload).forEach(function (key) {
var claim = options_to_payload[key];
const claim = options_to_payload[key];
if (typeof options[key] !== 'undefined') {

@@ -199,3 +231,3 @@ if (typeof payload[claim] !== 'undefined') {

var encoding = options.encoding || 'utf8';
const encoding = options.encoding || 'utf8';

@@ -212,7 +244,16 @@ if (typeof callback === 'function') {

.once('done', function (signature) {
// TODO: Remove in favor of the modulus length check before signing once node 15+ is the minimum supported version
if(!options.allowInsecureKeySizes && /^(?:RS|PS)/.test(header.alg) && signature.length < 256) {
return callback(new Error(`secretOrPrivateKey has a minimum key size of 2048 bits for ${header.alg}`))
}
callback(null, signature);
});
} else {
return jws.sign({header: header, payload: payload, secret: secretOrPrivateKey, encoding: encoding});
let signature = jws.sign({header: header, payload: payload, secret: secretOrPrivateKey, encoding: encoding});
// TODO: Remove in favor of the modulus length check before signing once node 15+ is the minimum supported version
if(!options.allowInsecureKeySizes && /^(?:RS|PS)/.test(header.alg) && signature.length < 256) {
throw new Error(`secretOrPrivateKey has a minimum key size of 2048 bits for ${header.alg}`)
}
return signature
}
};

@@ -1,16 +0,19 @@

var JsonWebTokenError = require('./lib/JsonWebTokenError');
var NotBeforeError = require('./lib/NotBeforeError');
var TokenExpiredError = require('./lib/TokenExpiredError');
var decode = require('./decode');
var timespan = require('./lib/timespan');
var PS_SUPPORTED = require('./lib/psSupported');
var jws = require('jws');
const JsonWebTokenError = require('./lib/JsonWebTokenError');
const NotBeforeError = require('./lib/NotBeforeError');
const TokenExpiredError = require('./lib/TokenExpiredError');
const decode = require('./decode');
const timespan = require('./lib/timespan');
const validateAsymmetricKey = require('./lib/validateAsymmetricKey');
const PS_SUPPORTED = require('./lib/psSupported');
const jws = require('jws');
const {KeyObject, createSecretKey, createPublicKey} = require("crypto");
var PUB_KEY_ALGS = ['RS256', 'RS384', 'RS512', 'ES256', 'ES384', 'ES512'];
var RSA_KEY_ALGS = ['RS256', 'RS384', 'RS512'];
var HS_ALGS = ['HS256', 'HS384', 'HS512'];
const PUB_KEY_ALGS = ['RS256', 'RS384', 'RS512'];
const EC_KEY_ALGS = ['ES256', 'ES384', 'ES512'];
const RSA_KEY_ALGS = ['RS256', 'RS384', 'RS512'];
const HS_ALGS = ['HS256', 'HS384', 'HS512'];
if (PS_SUPPORTED) {
PUB_KEY_ALGS.splice(3, 0, 'PS256', 'PS384', 'PS512');
RSA_KEY_ALGS.splice(3, 0, 'PS256', 'PS384', 'PS512');
PUB_KEY_ALGS.splice(PUB_KEY_ALGS.length, 0, 'PS256', 'PS384', 'PS512');
RSA_KEY_ALGS.splice(RSA_KEY_ALGS.length, 0, 'PS256', 'PS384', 'PS512');
}

@@ -31,3 +34,3 @@

var done;
let done;

@@ -51,4 +54,8 @@ if (callback) {

var clockTimestamp = options.clockTimestamp || Math.floor(Date.now() / 1000);
if (options.allowInvalidAsymmetricKeyTypes !== undefined && typeof options.allowInvalidAsymmetricKeyTypes !== 'boolean') {
return done(new JsonWebTokenError('allowInvalidAsymmetricKeyTypes must be a boolean'));
}
const clockTimestamp = options.clockTimestamp || Math.floor(Date.now() / 1000);
if (!jwtString){

@@ -62,3 +69,3 @@ return done(new JsonWebTokenError('jwt must be provided'));

var parts = jwtString.split('.');
const parts = jwtString.split('.');

@@ -69,3 +76,3 @@ if (parts.length !== 3){

var decodedToken;
let decodedToken;

@@ -82,4 +89,4 @@ try {

var header = decodedToken.header;
var getSecret;
const header = decodedToken.header;
let getSecret;

@@ -104,3 +111,3 @@ if(typeof secretOrPublicKey === 'function') {

var hasSignature = parts[2].trim() !== '';
const hasSignature = parts[2].trim() !== '';

@@ -116,18 +123,49 @@ if (!hasSignature && secretOrPublicKey){

if (!hasSignature && !options.algorithms) {
options.algorithms = ['none'];
return done(new JsonWebTokenError('please specify "none" in "algorithms" to verify unsigned tokens'));
}
if (secretOrPublicKey != null && !(secretOrPublicKey instanceof KeyObject)) {
try {
secretOrPublicKey = createPublicKey(secretOrPublicKey);
} catch (_) {
try {
secretOrPublicKey = createSecretKey(typeof secretOrPublicKey === 'string' ? Buffer.from(secretOrPublicKey) : secretOrPublicKey);
} catch (_) {
return done(new JsonWebTokenError('secretOrPublicKey is not valid key material'))
}
}
}
if (!options.algorithms) {
options.algorithms = ~secretOrPublicKey.toString().indexOf('BEGIN CERTIFICATE') ||
~secretOrPublicKey.toString().indexOf('BEGIN PUBLIC KEY') ? PUB_KEY_ALGS :
~secretOrPublicKey.toString().indexOf('BEGIN RSA PUBLIC KEY') ? RSA_KEY_ALGS : HS_ALGS;
if (secretOrPublicKey.type === 'secret') {
options.algorithms = HS_ALGS;
} else if (['rsa', 'rsa-pss'].includes(secretOrPublicKey.asymmetricKeyType)) {
options.algorithms = RSA_KEY_ALGS
} else if (secretOrPublicKey.asymmetricKeyType === 'ec') {
options.algorithms = EC_KEY_ALGS
} else {
options.algorithms = PUB_KEY_ALGS
}
}
if (!~options.algorithms.indexOf(decodedToken.header.alg)) {
if (options.algorithms.indexOf(decodedToken.header.alg) === -1) {
return done(new JsonWebTokenError('invalid algorithm'));
}
var valid;
if (header.alg.startsWith('HS') && secretOrPublicKey.type !== 'secret') {
return done(new JsonWebTokenError((`secretOrPublicKey must be a symmetric key when using ${header.alg}`)))
} else if (/^(?:RS|PS|ES)/.test(header.alg) && secretOrPublicKey.type !== 'public') {
return done(new JsonWebTokenError((`secretOrPublicKey must be an asymmetric key when using ${header.alg}`)))
}
if (!options.allowInvalidAsymmetricKeyTypes) {
try {
validateAsymmetricKey(header.alg, secretOrPublicKey);
} catch (e) {
return done(e);
}
}
let valid;
try {

@@ -143,3 +181,3 @@ valid = jws.verify(jwtString, decodedToken.header.alg, secretOrPublicKey);

var payload = decodedToken.payload;
const payload = decodedToken.payload;

@@ -165,6 +203,6 @@ if (typeof payload.nbf !== 'undefined' && !options.ignoreNotBefore) {

if (options.audience) {
var audiences = Array.isArray(options.audience) ? options.audience : [options.audience];
var target = Array.isArray(payload.aud) ? payload.aud : [payload.aud];
const audiences = Array.isArray(options.audience) ? options.audience : [options.audience];
const target = Array.isArray(payload.aud) ? payload.aud : [payload.aud];
var match = target.some(function (targetAudience) {
const match = target.some(function (targetAudience) {
return audiences.some(function (audience) {

@@ -181,3 +219,3 @@ return audience instanceof RegExp ? audience.test(targetAudience) : audience === targetAudience;

if (options.issuer) {
var invalid_issuer =
const invalid_issuer =
(typeof options.issuer === 'string' && payload.iss !== options.issuer) ||

@@ -214,3 +252,3 @@ (Array.isArray(options.issuer) && options.issuer.indexOf(payload.iss) === -1);

var maxAgeTimestamp = timespan(options.maxAge, payload.iat);
const maxAgeTimestamp = timespan(options.maxAge, payload.iat);
if (typeof maxAgeTimestamp === 'undefined') {

@@ -225,3 +263,3 @@ return done(new JsonWebTokenError('"maxAge" should be a number of seconds or string representing a timespan eg: "1d", "20h", 60'));

if (options.complete === true) {
var signature = decodedToken.signature;
const signature = decodedToken.signature;

@@ -228,0 +266,0 @@ return done(null, {

SocketSocket SOC 2 Logo

Product

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc