Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Socket
Sign inDemoInstall

express-oauth2-jwt-bearer

Package Overview
Dependencies
Maintainers
43
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

express-oauth2-jwt-bearer - npm Package Compare versions

Comparing version 1.3.0 to 1.4.0

44

dist/index.d.ts

@@ -98,6 +98,14 @@ /// <reference types="node" />

interface JWTPayload {
/** JWT Issuer - [RFC7519#section-4.1.1](https://www.rfc-editor.org/rfc/rfc7519#section-4.1.1). */
/**
* JWT Issuer
*
* @see [RFC7519#section-4.1.1](https://www.rfc-editor.org/rfc/rfc7519#section-4.1.1)
*/
iss?: string
/** JWT Subject - [RFC7519#section-4.1.2](https://www.rfc-editor.org/rfc/rfc7519#section-4.1.2). */
/**
* JWT Subject
*
* @see [RFC7519#section-4.1.2](https://www.rfc-editor.org/rfc/rfc7519#section-4.1.2)
*/
sub?: string

@@ -108,12 +116,28 @@

/** JWT ID - [RFC7519#section-4.1.7](https://www.rfc-editor.org/rfc/rfc7519#section-4.1.7). */
/**
* JWT ID
*
* @see [RFC7519#section-4.1.7](https://www.rfc-editor.org/rfc/rfc7519#section-4.1.7)
*/
jti?: string
/** JWT Not Before - [RFC7519#section-4.1.5](https://www.rfc-editor.org/rfc/rfc7519#section-4.1.5). */
/**
* JWT Not Before
*
* @see [RFC7519#section-4.1.5](https://www.rfc-editor.org/rfc/rfc7519#section-4.1.5)
*/
nbf?: number
/** JWT Expiration Time - [RFC7519#section-4.1.4](https://www.rfc-editor.org/rfc/rfc7519#section-4.1.4). */
/**
* JWT Expiration Time
*
* @see [RFC7519#section-4.1.4](https://www.rfc-editor.org/rfc/rfc7519#section-4.1.4)
*/
exp?: number
/** JWT Issued At - [RFC7519#section-4.1.6](https://www.rfc-editor.org/rfc/rfc7519#section-4.1.6). */
/**
* JWT Issued At
*
* @see [RFC7519#section-4.1.6](https://www.rfc-editor.org/rfc/rfc7519#section-4.1.6)
*/
iat?: number

@@ -148,2 +172,3 @@

timeoutDuration?: number;
cacheMaxAge?: number;
validators?: Partial<Validators>;

@@ -196,2 +221,5 @@ clockTolerance?: number;

interface AuthOptions extends JwtVerifierOptions {
authRequired?: boolean;
}
declare global {

@@ -204,3 +232,3 @@ namespace Express {

}
declare const auth: (opts?: JwtVerifierOptions) => Handler;
declare const auth: (opts?: AuthOptions) => Handler;
declare const claimCheck: ClaimCheck<Handler>;

@@ -212,2 +240,2 @@ declare const claimEquals: ClaimEquals<Handler>;

export { JwtVerifierOptions as AuthOptions, VerifyJwtResult as AuthResult, FunctionValidator, InsufficientScopeError, InvalidRequestError, InvalidTokenError, JSONPrimitive, JWSHeaderParameters as JWTHeader, JWTPayload, UnauthorizedError, Validator, Validators, auth, claimCheck, claimEquals, claimIncludes, requiredScopes, scopeIncludesAny };
export { AuthOptions, VerifyJwtResult as AuthResult, FunctionValidator, InsufficientScopeError, InvalidRequestError, InvalidTokenError, JSONPrimitive, JWSHeaderParameters as JWTHeader, JWTPayload, UnauthorizedError, Validator, Validators, auth, claimCheck, claimEquals, claimIncludes, requiredScopes, scopeIncludesAny };

91

dist/index.js

@@ -6,6 +6,4 @@ 'use strict';

var assert = require('assert');
var buffer = require('buffer');
var crypto = require('crypto');
var jose = require('jose');
var url = require('url');
var jose = require('jose');
var http = require('http');

@@ -15,2 +13,3 @@ var https = require('https');

var util = require('util');
var crypto = require('crypto');

@@ -132,3 +131,3 @@ class UnauthorizedError extends Error {

const assertIssuer = (data) => assert.strict(data.issuer, `'issuer' not found in authorization server metadata`);
const discover = async (uri, { agent, timeoutDuration } = {}) => {
const discover = async ({ issuerBaseURL: uri, agent, timeoutDuration, }) => {
const url$1 = new url.URL(uri);

@@ -168,3 +167,37 @@ if (url$1.pathname.includes('/.well-known/')) {

};
var discovery = (opts) => {
let discovery;
let timestamp = 0;
return () => {
const now = Date.now();
if (!discovery || now > timestamp + opts.cacheMaxAge) {
timestamp = now;
discovery = discover(opts).catch((e) => {
discovery = undefined;
throw e;
});
}
return discovery;
};
};
var getKeyFn = ({ secret, cooldownDuration, timeoutDuration, cacheMaxAge, }) => {
let getKeyFn;
let prevjwksUri;
const secretKey = secret && crypto.createSecretKey(Buffer.from(secret));
return (jwksUri) => {
if (secretKey)
return () => secretKey;
if (!getKeyFn || prevjwksUri !== jwksUri) {
prevjwksUri = jwksUri;
getKeyFn = jose.createRemoteJWKSet(new URL(jwksUri), {
cooldownDuration,
timeoutDuration,
cacheMaxAge,
});
}
return getKeyFn;
};
};
var validate = (payload, header, validators) => Promise.all(Object.entries(validators).map(async ([key, validator]) => {

@@ -231,5 +264,3 @@ const value = key === 'alg' || key === 'typ' ? header[key] : payload[key];

const SYMMETRIC_ALGS = ['HS256', 'HS384', 'HS512'];
const jwtVerifier = ({ issuerBaseURL = process.env.ISSUER_BASE_URL, jwksUri = process.env.JWKS_URI, issuer = process.env.ISSUER, audience = process.env.AUDIENCE, secret = process.env.SECRET, tokenSigningAlg = process.env.TOKEN_SIGNING_ALG, agent, cooldownDuration = 30000, timeoutDuration = 5000, clockTolerance = 5, maxTokenAge, strict = false, validators: customValidators, }) => {
let origJWKS;
let discovery;
const jwtVerifier = ({ issuerBaseURL = process.env.ISSUER_BASE_URL, jwksUri = process.env.JWKS_URI, issuer = process.env.ISSUER, audience = process.env.AUDIENCE, secret = process.env.SECRET, tokenSigningAlg = process.env.TOKEN_SIGNING_ALG, agent, cooldownDuration = 30000, timeoutDuration = 5000, cacheMaxAge = 600000, clockTolerance = 5, maxTokenAge, strict = false, validators: customValidators, }) => {
let validators;

@@ -243,25 +274,22 @@ let allowedSigningAlgs;

assert.strict(!secret || (tokenSigningAlg && SYMMETRIC_ALGS.includes(tokenSigningAlg)), `You must supply one of ${SYMMETRIC_ALGS.join(', ')} for 'tokenSigningAlg' to validate symmetrically signed tokens`);
const secretKey = secret && crypto.createSecretKey(buffer.Buffer.from(secret));
const JWKS = async (...args) => {
if (secretKey)
return secretKey;
if (!origJWKS) {
origJWKS = jose.createRemoteJWKSet(new url.URL(jwksUri), {
agent,
cooldownDuration,
timeoutDuration,
});
}
return origJWKS(...args);
};
const getDiscovery = discovery({
issuerBaseURL,
agent,
timeoutDuration,
cacheMaxAge,
});
const getKeyFnGetter = getKeyFn({
agent,
cooldownDuration,
timeoutDuration,
cacheMaxAge,
secret,
});
return async (jwt) => {
try {
if (issuerBaseURL) {
discovery =
discovery || discover(issuerBaseURL, { agent, timeoutDuration });
({
jwks_uri: jwksUri,
issuer,
id_token_signing_alg_values_supported: allowedSigningAlgs,
} = await discovery);
const { jwks_uri: discoveredJwksUri, issuer: discoveredIssuer, id_token_signing_alg_values_supported: idTokenSigningAlgValuesSupported, } = await getDiscovery();
jwksUri = jwksUri || discoveredJwksUri;
issuer = issuer || discoveredIssuer;
allowedSigningAlgs = idTokenSigningAlgValuesSupported;
}

@@ -272,3 +300,3 @@ validators || (validators = {

});
const { payload, protectedHeader: header } = await jose.jwtVerify(jwt, JWKS);
const { payload, protectedHeader: header } = await jose.jwtVerify(jwt, getKeyFnGetter(jwksUri));
await validate(payload, header, validators);

@@ -385,3 +413,8 @@ return { payload, header, token: jwt };

catch (e) {
next(e);
if (opts.authRequired === false) {
next();
}
else {
next(e);
}
}

@@ -388,0 +421,0 @@ };

{
"name": "express-oauth2-jwt-bearer",
"description": "Authentication middleware for Express.js that validates JWT bearer access tokens.",
"version": "1.3.0",
"version": "1.4.0",
"main": "dist/index.js",

@@ -20,26 +20,26 @@ "types": "dist/index.d.ts",

"devDependencies": {
"@rollup/plugin-node-resolve": "^13.1.1",
"@tsconfig/node12": "^1.0.9",
"@types/express": "^4.17.13",
"@types/jest": "^27.0.3",
"@types/node": "^14.18.0",
"@typescript-eslint/eslint-plugin": "^5.7.0",
"@typescript-eslint/parser": "^5.7.0",
"eslint": "^8.4.1",
"express": "^4.17.1",
"got": "^11.8.5",
"jest": "^27.4.5",
"jest-junit": "^13.0.0",
"nock": "^13.2.1",
"@rollup/plugin-node-resolve": "^13.3.0",
"@tsconfig/node12": "^1.0.11",
"@types/express": "^4.17.17",
"@types/jest": "^27.5.2",
"@types/node": "^14.18.42",
"@typescript-eslint/eslint-plugin": "^5.57.0",
"@typescript-eslint/parser": "^5.57.0",
"eslint": "^8.37.0",
"express": "^4.18.2",
"got": "^11.8.6",
"jest": "^29.5.0",
"jest-junit": "^13.2.0",
"nock": "^13.3.0",
"prettier": "~2.5.1",
"rimraf": "^3.0.2",
"rollup": "^2.61.1",
"rollup-plugin-dts": "^4.0.1",
"rollup-plugin-typescript2": "^0.31.1",
"ts-jest": "^27.1.1",
"tslib": "^2.3.1",
"typescript": "^4.5.4"
"rollup": "^2.79.1",
"rollup-plugin-dts": "^4.2.3",
"rollup-plugin-typescript2": "^0.31.2",
"ts-jest": "^29.0.5",
"tslib": "^2.5.0",
"typescript": "^5.0.2"
},
"dependencies": {
"jose": "^4.9.2"
"jose": "^4.13.1"
},

@@ -46,0 +46,0 @@ "engines": {

@@ -16,2 +16,3 @@ ![Authentication middleware for Express.js that validates JWT Bearer Access Tokens](https://cdn.auth0.com/website/sdks/banners/express-oauth2-jwt-bearer-banner.png)

## Getting started
### Requirements

@@ -21,3 +22,3 @@

- Node.js: `^12.19.0 || ^14.15.0 || ^16.13.0`
- Node.js: `^12.19.0 || ^14.15.0 || ^16.13.0` || ^18.12.0

@@ -36,3 +37,3 @@ ### Installation

The library requires [issuerBaseURL](https://auth0.github.io/node-oauth2-jwt-bearer/interfaces/authoptions.html#issuerbaseurl) and [audience](https://auth0.github.io/node-oauth2-jwt-bearer/interfaces/authoptions.html#audience).
The library requires [issuerBaseURL](https://auth0.github.io/node-oauth2-jwt-bearer/interfaces/AuthOptions.html#issuerBaseURL) and [audience](https://auth0.github.io/node-oauth2-jwt-bearer/interfaces/AuthOptions.html#audience).

@@ -56,6 +57,6 @@ #### Environment Variables

app.use(
auth({
issuerBaseURL: 'https://YOUR_ISSUER_DOMAIN',
audience: 'https://my-api.com'
})
auth({
issuerBaseURL: 'https://YOUR_ISSUER_DOMAIN',
audience: 'https://my-api.com',
})
);

@@ -69,8 +70,8 @@ ```

app.use(
auth({
issuer: 'https://YOUR_ISSUER_DOMAIN',
audience: 'https://my-api.com',
secret: 'YOUR SECRET',
tokenSigningAlg: 'HS256'
})
auth({
issuer: 'https://YOUR_ISSUER_DOMAIN',
audience: 'https://my-api.com',
secret: 'YOUR SECRET',
tokenSigningAlg: 'HS256',
})
);

@@ -84,10 +85,8 @@ ```

```js
app.get('/api/messages',
(req, res, next) => {
const auth = req.auth;
auth.header; // The decoded JWT header.
auth.payload; // The decoded JWT payload.
auth.token; // The raw JWT token.
}
);
app.get('/api/messages', (req, res, next) => {
const auth = req.auth;
auth.header; // The decoded JWT header.
auth.payload; // The decoded JWT payload.
auth.token; // The raw JWT token.
});
```

@@ -114,10 +113,11 @@

- [auth](https://auth0.github.io/node-oauth2-jwt-bearer#auth) - Middleware that will return a 401 if a valid Access token JWT bearer token is not provided in the request.
- [AuthResult](https://auth0.github.io/node-oauth2-jwt-bearer/interfaces/authresult.html) - The properties added to `req.auth` upon successful authorization.
- [requiredScopes](https://auth0.github.io/node-oauth2-jwt-bearer#requiredscopes) - Check a token's scope claim to include a number of given scopes, raises a 403 `insufficient_scope` error if the value of the scope claim does not include all the given scopes.
- [claimEquals](https://auth0.github.io/node-oauth2-jwt-bearer#claimequals) - Check a token's claim to be equal a given JSONPrimitive (string, number, boolean or null) raises a 401 `invalid_token` error if the value of the claim does not match.
- [claimIncludes](https://auth0.github.io/node-oauth2-jwt-bearer#claimincludes) - Check a token's claim to include a number of given JSONPrimitives (string, number, boolean or null) raises a 401 `invalid_token` error if the value of the claim does not include all the given values.
- [claimCheck](https://auth0.github.io/node-oauth2-jwt-bearer#claimcheck) - Check the token's claims using a custom method that receives the JWT Payload and should return `true` if the token is valid. Raises a 401 `invalid_token` error if the function returns `false`.
- [auth](https://auth0.github.io/node-oauth2-jwt-bearer/functions/auth.html) - Middleware that will return a 401 if a valid Access token JWT bearer token is not provided in the request.
- [AuthResult](https://auth0.github.io/node-oauth2-jwt-bearer/interfaces/AuthResult.html) - The properties added to `req.auth` upon successful authorization.
- [requiredScopes](https://auth0.github.io/node-oauth2-jwt-bearer/functions/requiredScopes.html) - Check a token's scope claim to include a number of given scopes, raises a 403 `insufficient_scope` error if the value of the scope claim does not include all the given scopes.
- [claimEquals](https://auth0.github.io/node-oauth2-jwt-bearer/functions/claimEquals.html) - Check a token's claim to be equal a given JSONPrimitive (string, number, boolean or null) raises a 401 `invalid_token` error if the value of the claim does not match.
- [claimIncludes](https://auth0.github.io/node-oauth2-jwt-bearer/functions/claimIncludes.html) - Check a token's claim to include a number of given JSONPrimitives (string, number, boolean or null) raises a 401 `invalid_token` error if the value of the claim does not include all the given values.
- [claimCheck](https://auth0.github.io/node-oauth2-jwt-bearer/functions/claimCheck.html) - Check the token's claims using a custom method that receives the JWT Payload and should return `true` if the token is valid. Raises a 401 `invalid_token` error if the function returns `false`.
## Feedback
### Contributing

@@ -153,2 +153,2 @@

This project is licensed under the MIT license. See the <a href="https://github.com/auth0/node-oauth2-jwt-bearer/blob/main/packages/express-oauth2-jwt-bearer/LICENSE"> LICENSE</a> file for more info.
</p>
</p>
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