From bfae4696bbbde70ba08d8fa5bb60e2079e2cc24d Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Thu, 14 Oct 2021 20:16:29 +0200 Subject: [PATCH] refactor: use jose@4 --- package-lock.json | 79 +++---------------- packages/access-token-jwt/jest.config.js | 1 - packages/access-token-jwt/package.json | 3 +- packages/access-token-jwt/resolver.js | 24 ------ packages/access-token-jwt/src/claim-check.ts | 2 +- packages/access-token-jwt/src/fetch.ts | 1 + packages/access-token-jwt/src/jwt-verifier.ts | 10 +-- packages/access-token-jwt/src/validate.ts | 5 +- packages/access-token-jwt/test/helpers.ts | 6 +- packages/examples/package.json | 2 +- packages/examples/playground.ts | 8 +- packages/express-oauth2-jwt-bearer/README.md | 8 -- .../express-oauth2-jwt-bearer/jest.config.js | 1 - .../express-oauth2-jwt-bearer/package.json | 2 +- .../rollup.config.js | 2 +- .../express-oauth2-jwt-bearer/src/index.ts | 2 +- 16 files changed, 30 insertions(+), 126 deletions(-) delete mode 100644 packages/access-token-jwt/resolver.js diff --git a/package-lock.json b/package-lock.json index 4ae3def..f3c3406 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2938,19 +2938,6 @@ "once": "^1.4.0" } }, - "node_modules/enhanced-resolve": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.0.tgz", - "integrity": "sha512-Sl3KRpJA8OpprrtaIswVki3cWPiPKxXuFxJXBp+zNb6s6VwNWwFRUdtmzd2ReUut8n+sCPx7QCtQ7w5wfJhSgQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, "node_modules/enquirer": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", @@ -5403,18 +5390,9 @@ } }, "node_modules/jose": { - "version": "3.11.6", - "resolved": "https://registry.npmjs.org/jose/-/jose-3.11.6.tgz", - "integrity": "sha512-h/qTZ80NygTGeNA6ok9KIz5N6GFrNzlnchSmFrtPzeTMvYN7mDJ2Z2QMKKp/9rrqPW1BVeBiu0KQkdYDUx2DSw==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/panva" - } - }, - "node_modules/jose-node-cjs-runtime": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/jose-node-cjs-runtime/-/jose-node-cjs-runtime-3.12.1.tgz", - "integrity": "sha512-z0GhaE1NGHcTb/l9p1TajtHDQELd5tfCfSE0cSbtBbnUJriabMe+ggHCzWhit+DJH5xMrC2fiOoFsOaPVXffBA==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.0.1.tgz", + "integrity": "sha512-Tz17vs6DvREa8VvaPk830vtZuuKO+kWJVeZyz/cwrHi359fb8MRAlln6vOcYd58Whpz/uELcOR1nKg2wKz1TYw==", "funding": { "url": "https://github.com/sponsors/panva" } @@ -8503,15 +8481,6 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, - "node_modules/tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/terminal-link": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", @@ -9475,7 +9444,7 @@ "version": "0.0.1", "license": "MIT", "dependencies": { - "jose-node-cjs-runtime": "^3.12.1" + "jose": "^4.0.1" }, "devDependencies": { "@tsconfig/node12": "^1.0.7", @@ -9484,7 +9453,6 @@ "@types/sinon": "^9.0.11", "@typescript-eslint/eslint-plugin": "^4.19.0", "@typescript-eslint/parser": "^4.19.0", - "enhanced-resolve": "^5.7.0", "eslint": "^7.23.0", "jest": "^26.6.3", "jest-junit": "^12.0.0", @@ -9525,7 +9493,7 @@ "ejs": "^3.1.6", "eslint": "^7.23.0", "express": "^4.17.1", - "jose": "^3.11.6", + "jose": "^4.0.1", "prettier": "~2.2.1", "ts-node-dev": "^1.1.6", "tslib": "^2.1.0", @@ -9551,7 +9519,7 @@ "version": "0.2.0", "license": "MIT", "dependencies": { - "jose-node-cjs-runtime": "^3.12.1" + "jose": "^4.0.1" }, "devDependencies": { "@rollup/plugin-node-resolve": "^11.2.1", @@ -11239,11 +11207,10 @@ "@types/sinon": "^9.0.11", "@typescript-eslint/eslint-plugin": "^4.19.0", "@typescript-eslint/parser": "^4.19.0", - "enhanced-resolve": "^5.7.0", "eslint": "^7.23.0", "jest": "^26.6.3", "jest-junit": "^12.0.0", - "jose-node-cjs-runtime": "^3.12.1", + "jose": "^4.0.1", "nock": "^13.0.11", "prettier": "~2.2.1", "rimraf": "^3.0.2", @@ -12345,16 +12312,6 @@ "once": "^1.4.0" } }, - "enhanced-resolve": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.0.tgz", - "integrity": "sha512-Sl3KRpJA8OpprrtaIswVki3cWPiPKxXuFxJXBp+zNb6s6VwNWwFRUdtmzd2ReUut8n+sCPx7QCtQ7w5wfJhSgQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - } - }, "enquirer": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", @@ -12633,7 +12590,7 @@ "ejs": "^3.1.6", "eslint": "^7.23.0", "express": "^4.17.1", - "jose": "^3.11.6", + "jose": "^4.0.1", "prettier": "~2.2.1", "ts-node-dev": "^1.1.6", "tslib": "^2.1.0", @@ -12885,7 +12842,7 @@ "got": "^11.8.2", "jest": "^26.6.3", "jest-junit": "^12.0.0", - "jose-node-cjs-runtime": "^3.12.1", + "jose": "^4.0.1", "nock": "^13.0.11", "prettier": "~2.2.1", "rimraf": "^3.0.2", @@ -14450,15 +14407,9 @@ } }, "jose": { - "version": "3.11.6", - "resolved": "https://registry.npmjs.org/jose/-/jose-3.11.6.tgz", - "integrity": "sha512-h/qTZ80NygTGeNA6ok9KIz5N6GFrNzlnchSmFrtPzeTMvYN7mDJ2Z2QMKKp/9rrqPW1BVeBiu0KQkdYDUx2DSw==", - "dev": true - }, - "jose-node-cjs-runtime": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/jose-node-cjs-runtime/-/jose-node-cjs-runtime-3.12.1.tgz", - "integrity": "sha512-z0GhaE1NGHcTb/l9p1TajtHDQELd5tfCfSE0cSbtBbnUJriabMe+ggHCzWhit+DJH5xMrC2fiOoFsOaPVXffBA==" + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.0.1.tgz", + "integrity": "sha512-Tz17vs6DvREa8VvaPk830vtZuuKO+kWJVeZyz/cwrHi359fb8MRAlln6vOcYd58Whpz/uELcOR1nKg2wKz1TYw==" }, "js-tokens": { "version": "4.0.0", @@ -17027,12 +16978,6 @@ } } }, - "tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", - "dev": true - }, "terminal-link": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", diff --git a/packages/access-token-jwt/jest.config.js b/packages/access-token-jwt/jest.config.js index 117e24f..bc13be1 100644 --- a/packages/access-token-jwt/jest.config.js +++ b/packages/access-token-jwt/jest.config.js @@ -10,7 +10,6 @@ module.exports = { }, ], ], - resolver: './resolver.js', testEnvironment: 'node', collectCoverageFrom: ['src/*'], coverageThreshold: { diff --git a/packages/access-token-jwt/package.json b/packages/access-token-jwt/package.json index 8d5f11a..bbd234d 100644 --- a/packages/access-token-jwt/package.json +++ b/packages/access-token-jwt/package.json @@ -21,7 +21,6 @@ "@types/sinon": "^9.0.11", "@typescript-eslint/eslint-plugin": "^4.19.0", "@typescript-eslint/parser": "^4.19.0", - "enhanced-resolve": "^5.7.0", "eslint": "^7.23.0", "jest": "^26.6.3", "jest-junit": "^12.0.0", @@ -34,7 +33,7 @@ "typescript": "^4.2.3" }, "dependencies": { - "jose-node-cjs-runtime": "^3.12.1" + "jose": "^4.0.1" }, "engines": { "node": "^12.19.0 || ^14.15.0" diff --git a/packages/access-token-jwt/resolver.js b/packages/access-token-jwt/resolver.js deleted file mode 100644 index 7f8b3bb..0000000 --- a/packages/access-token-jwt/resolver.js +++ /dev/null @@ -1,24 +0,0 @@ -const fs = require('fs'); -const { ResolverFactory } = require('enhanced-resolve'); - -// Use a special resolver for jose as it uses named and conditional exports which aren't -// supported by the default jest resolver yet facebook/jest#9771 -module.exports = function enhancedResolve(modulePath, opts) { - if (!modulePath.startsWith('jose-node-cjs-runtime/')) { - return opts.defaultResolver(modulePath, opts); - } - - let wpResolver = ResolverFactory.createResolver({ - fileSystem: fs, - useSyncFileSystemCalls: true, - conditionNames: ['require'], - }); - - let result = wpResolver.resolveSync({}, opts.basedir, modulePath); - - if (result) { - result = fs.realpathSync(result); - } - - return result; -}; diff --git a/packages/access-token-jwt/src/claim-check.ts b/packages/access-token-jwt/src/claim-check.ts index 4014e12..89a1c80 100644 --- a/packages/access-token-jwt/src/claim-check.ts +++ b/packages/access-token-jwt/src/claim-check.ts @@ -3,7 +3,7 @@ import { InsufficientScopeError, UnauthorizedError, } from 'oauth2-bearer'; -import { JWTPayload } from 'jose-node-cjs-runtime/jwt/verify'; +import type { JWTPayload } from 'jose'; export type JSONPrimitive = string | number | boolean | null; diff --git a/packages/access-token-jwt/src/fetch.ts b/packages/access-token-jwt/src/fetch.ts index 3435a6d..4c03a8e 100644 --- a/packages/access-token-jwt/src/fetch.ts +++ b/packages/access-token-jwt/src/fetch.ts @@ -3,6 +3,7 @@ import { Agent as HttpAgent, get as getHttp } from 'http'; import { Agent as HttpsAgent, get as getHttps } from 'https'; import { once } from 'events'; import type { ClientRequest, IncomingMessage } from 'http'; +import { TextDecoder } from 'util'; const decoder = new TextDecoder(); diff --git a/packages/access-token-jwt/src/jwt-verifier.ts b/packages/access-token-jwt/src/jwt-verifier.ts index f8e578d..12948fb 100644 --- a/packages/access-token-jwt/src/jwt-verifier.ts +++ b/packages/access-token-jwt/src/jwt-verifier.ts @@ -4,11 +4,8 @@ import { createSecretKey } from 'crypto'; import { Agent as HttpAgent } from 'http'; import { Agent as HttpsAgent } from 'https'; import { URL } from 'url'; -import createRemoteJWKSet from 'jose-node-cjs-runtime/jwks/remote'; -import jwtVerify, { - JWTPayload, - JWSHeaderParameters, -} from 'jose-node-cjs-runtime/jwt/verify'; +import { createRemoteJWKSet, jwtVerify } from 'jose'; +import type { JWTPayload, JWSHeaderParameters } from 'jose' import { InvalidTokenError } from 'oauth2-bearer'; import discover, { IssuerMetadata } from './discovery'; import validate, { defaultValidators, Validators } from './validate'; @@ -208,6 +205,7 @@ const jwtVerifier = ({ const secretKey = secret && createSecretKey(Buffer.from(secret)); const JWKS = async (...args: Parameters) => { + if (secretKey) return secretKey; if (!origJWKS) { origJWKS = createRemoteJWKSet(new URL(jwksUri), { agent, @@ -243,7 +241,7 @@ const jwtVerifier = ({ }; const { payload, protectedHeader: header } = await jwtVerify( jwt, - secretKey || JWKS + JWKS, ); await validate(payload, header, validators); return { payload, header, token: jwt }; diff --git a/packages/access-token-jwt/src/validate.ts b/packages/access-token-jwt/src/validate.ts index 4f80ab1..fe159c5 100644 --- a/packages/access-token-jwt/src/validate.ts +++ b/packages/access-token-jwt/src/validate.ts @@ -1,7 +1,4 @@ -import { - JWTPayload, - JWSHeaderParameters, -} from 'jose-node-cjs-runtime/jwt/verify'; +import type { JWTPayload, JWSHeaderParameters } from 'jose'; /** * @ignore diff --git a/packages/access-token-jwt/test/helpers.ts b/packages/access-token-jwt/test/helpers.ts index 8155613..efdad60 100644 --- a/packages/access-token-jwt/test/helpers.ts +++ b/packages/access-token-jwt/test/helpers.ts @@ -1,8 +1,6 @@ import { Buffer } from 'buffer'; import { createSecretKey } from 'crypto'; -import SignJWT from 'jose-node-cjs-runtime/jwt/sign'; -import { generateKeyPair } from 'jose-node-cjs-runtime/util/generate_key_pair'; -import { fromKeyLike } from 'jose-node-cjs-runtime/jwk/from_key_like'; +import { SignJWT, generateKeyPair, exportJWK } from 'jose'; import nock = require('nock'); export const now = (Date.now() / 1000) | 0; @@ -39,7 +37,7 @@ export const createJwt = async ({ secret, }: CreateJWTOptions = {}): Promise => { const { publicKey, privateKey } = await generateKeyPair('RS256'); - const publicJwk = await fromKeyLike(publicKey); + const publicJwk = await exportJWK(publicKey); nock(issuer) .persist() .get(jwksUri) diff --git a/packages/examples/package.json b/packages/examples/package.json index 48cbe66..e19d2f5 100644 --- a/packages/examples/package.json +++ b/packages/examples/package.json @@ -22,7 +22,7 @@ "ejs": "^3.1.6", "eslint": "^7.23.0", "express": "^4.17.1", - "jose": "^3.11.6", + "jose": "^4.0.1", "prettier": "~2.2.1", "ts-node-dev": "^1.1.6", "tslib": "^2.1.0", diff --git a/packages/examples/playground.ts b/packages/examples/playground.ts index fd4de9c..d83c4f0 100644 --- a/packages/examples/playground.ts +++ b/packages/examples/playground.ts @@ -1,6 +1,6 @@ import express = require('express'); -import { generateKeyPair } from 'jose/util/generate_key_pair'; -import { fromKeyLike, JWK } from 'jose/jwk/from_key_like'; +import { generateKeyPair, exportJWK } from 'jose'; +import type { JWK } from 'jose'; import secret from './secret'; const app = express(); @@ -16,8 +16,8 @@ const keys = async () => { return { publicJwk, privateJwk }; } const { publicKey, privateKey } = await generateKeyPair('RS256'); - publicJwk = await fromKeyLike(publicKey); - privateJwk = await fromKeyLike(privateKey); + publicJwk = await exportJWK(publicKey); + privateJwk = await exportJWK(privateKey); return { publicJwk, privateJwk }; }; diff --git a/packages/express-oauth2-jwt-bearer/README.md b/packages/express-oauth2-jwt-bearer/README.md index af4d6ad..f0f6fb2 100644 --- a/packages/express-oauth2-jwt-bearer/README.md +++ b/packages/express-oauth2-jwt-bearer/README.md @@ -147,14 +147,6 @@ See the Express.js [docs on error handling](https://expressjs.com/en/guide/error ## Troubleshooting -### Getting `Error: Cannot find module 'jose-node-cjs-runtime/jwks/remote'` when I run the SDK - -This package takes a dependency on [jose](https://github.com/panva/jose) which uses [package exports](https://nodejs.org/api/packages.html#packages_exports) which requires Node `^12.19.0 || ^14.15.0`. - -Even if you are using the correct version of Node, you may still run into this in some tooling that does not yet support package exports, like [jest](https://github.com/facebook/jest/issues/9771) or Webpack 4. - -To workaround this issue in jest, see how we use a [custom resolver](../../packages/access-token-jwt/resolver.js) for this project. - ## Contributing See monorepo's [contributing guidelines](../../README.md#contributing). diff --git a/packages/express-oauth2-jwt-bearer/jest.config.js b/packages/express-oauth2-jwt-bearer/jest.config.js index a6b7bf2..72e9402 100644 --- a/packages/express-oauth2-jwt-bearer/jest.config.js +++ b/packages/express-oauth2-jwt-bearer/jest.config.js @@ -1,6 +1,5 @@ module.exports = { preset: 'ts-jest/presets/js-with-ts', - resolver: '../access-token-jwt/resolver.js', testEnvironment: 'node', collectCoverageFrom: ['src/*'], coverageThreshold: { diff --git a/packages/express-oauth2-jwt-bearer/package.json b/packages/express-oauth2-jwt-bearer/package.json index b5b3281..a9813fa 100644 --- a/packages/express-oauth2-jwt-bearer/package.json +++ b/packages/express-oauth2-jwt-bearer/package.json @@ -40,7 +40,7 @@ "typescript": "^4.2.3" }, "dependencies": { - "jose-node-cjs-runtime": "^3.12.1" + "jose": "^4.0.1" }, "engines": { "node": "^12.19.0 || ^14.15.0" diff --git a/packages/express-oauth2-jwt-bearer/rollup.config.js b/packages/express-oauth2-jwt-bearer/rollup.config.js index b58d7a0..22145fe 100644 --- a/packages/express-oauth2-jwt-bearer/rollup.config.js +++ b/packages/express-oauth2-jwt-bearer/rollup.config.js @@ -7,7 +7,7 @@ export default { dir: 'dist', format: 'cjs', }, - external: [/^jose-node-cjs-runtime\//], + external: ["jose"], plugins: [ nodeResolve(), typescript({ tsconfigOverride: { compilerOptions: { module: 'ES2015' } } }), diff --git a/packages/express-oauth2-jwt-bearer/src/index.ts b/packages/express-oauth2-jwt-bearer/src/index.ts index 3b4b206..3d97f7b 100644 --- a/packages/express-oauth2-jwt-bearer/src/index.ts +++ b/packages/express-oauth2-jwt-bearer/src/index.ts @@ -11,8 +11,8 @@ import { requiredScopes as _requiredScopes, RequiredScopes, VerifyJwtResult as AuthResult, - JWTPayload, } from 'access-token-jwt'; +import type { JWTPayload } from 'access-token-jwt'; import { getToken } from 'oauth2-bearer'; declare global {