From dba41ee4dc90c6d1b2f00826526a8c4a4e742092 Mon Sep 17 00:00:00 2001 From: David Barrat Date: Mon, 1 Jan 2024 04:13:07 +0100 Subject: [PATCH] reenable nock tests --- package.json | 1 + src/vendors/jwks/jwks.test.ts | 22 ++- src/vendors/jwt/jwt-verify.test.ts | 220 +++++++++++++++-------------- yarn.lock | 2 +- 4 files changed, 132 insertions(+), 113 deletions(-) diff --git a/package.json b/package.json index 7cec9b1..4775ce8 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "husky": "^7.0.0", "jest": "^27.0.6", "nock": "^13.4.0", + "node-fetch": "2.7.0", "prettier": "2.3.2", "raw-loader": "^4.0.2", "ts-jest": "^27.0.3", diff --git a/src/vendors/jwks/jwks.test.ts b/src/vendors/jwks/jwks.test.ts index ec432ca..ad517e8 100644 --- a/src/vendors/jwks/jwks.test.ts +++ b/src/vendors/jwks/jwks.test.ts @@ -8,6 +8,15 @@ import { import { JwtAlgorithmsEnum as Algs, JwtKeyTypes as Kty } from "../../enums"; import { default as nock } from "nock"; +// TODO: move this to jest config +import fetch, { Headers } from "node-fetch"; + +// https://stackoverflow.com/a/75956506/8483084 +if (!globalThis.fetch) { + globalThis.fetch = fetch + globalThis.Headers = Headers +} + import * as c from "../../constants"; import { SignJWT, jwtVerify } from "jose"; const AUTHDOG_API_ROOT = "https://api.authdog.xyz"; @@ -488,6 +497,9 @@ it("verifies Ed448 Key pair", async () => { it("verifies correctly token with public uri", async () => { + + + const tenantUuid2 = "d84ddef4-81dd-4ce6-9594-03ac52cac367"; const applicationUuid2 = "b867db48-4e11-4cae-bb03-086dc97c8ddd"; const keyPairES512 = await getKeyPair({ @@ -523,21 +535,19 @@ it("verifies correctly token with public uri", async () => { let verified: ITokenExtractedWithPubKey | undefined; - try { verified = await verifyTokenWithPublicKey(signedPayloadEs512, null, { jwksUri }); - } catch (e) { - // TODO: fix [ ReferenceError: Headers is not defined] - //console.error(e); - } - if (verified) { + expect(verified.protectedHeader).toEqual({ alg: "ES512", type: "jwt" }); expect(verified.payload).toEqual({ urn: "urn:test:test", kid: keyPairES512?.kid }); + + if (verified) { + } scopeNock.persist(false); diff --git a/src/vendors/jwt/jwt-verify.test.ts b/src/vendors/jwt/jwt-verify.test.ts index 3466dea..b026e48 100644 --- a/src/vendors/jwt/jwt-verify.test.ts +++ b/src/vendors/jwt/jwt-verify.test.ts @@ -3,6 +3,7 @@ import { verifyHSTokenWithSecretString, checkJwtFields, parseJwt, + checkTokenValidness, // checkTokenValidness } from "./jwt-verify"; import { @@ -11,7 +12,18 @@ import { JwtKeyTypes as Kty } from "../../enums"; import * as c from "../../constants"; -import { signJwtWithPrivateKey } from "./jwt-sign"; +import { getKeyPair, signJwtWithPrivateKey } from "./jwt-sign"; +import nock from "nock"; + +// TODO: move this to jest config +import fetch, { Headers } from "node-fetch"; + +// https://stackoverflow.com/a/75956506/8483084 +if (!globalThis.fetch) { + globalThis.fetch = fetch + globalThis.Headers = Headers +} + const DUMMY_HS256_TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"; @@ -251,109 +263,105 @@ it("parses token (payload and header)", async () => { }); }); -// it("verifies a token with checkTokenValidness signed with ES512 key - jwk", async () => { - -// const keyPairES512 = await getKeyPair({ -// algorithmIdentifier: Algs.ES512, -// keySize: 4096 -// }); - -// // const regExpPathAppJwks = new RegExp( -// // `api\/${c.AUTHDOG_JWKS_API_ID}\/${tenantUuid2}\/${applicationUuid2}\/.well-known\/jwks.json*` -// // ); - -// const keys = [keyPairES512.publicKey]; - -// const jwks = { -// keys: [ -// { -// crv: 'P-256', -// x: 'fqCXPnWs3sSfwztvwYU9SthmRdoT4WCXxS8eD8icF6U', -// y: 'nP6GIc42c61hoKqPcZqkvzhzIJkBV3Jw3g8sGG7UeP8', -// kty: 'EC', -// kid: 'one', -// }, -// ...keys -// ], -// } +it("verifies a token with checkTokenValidness signed with ES512 key - jwk", async () => { + + const keyPairES512 = await getKeyPair({ + algorithmIdentifier: Algs.ES512, + keySize: 4096 + }); + + // const regExpPathAppJwks = new RegExp( + // `api\/${c.AUTHDOG_JWKS_API_ID}\/${tenantUuid2}\/${applicationUuid2}\/.well-known\/jwks.json*` + // ); + + const keys = [keyPairES512.publicKey]; + + const jwks = { + keys: [ + { + crv: 'P-256', + x: 'fqCXPnWs3sSfwztvwYU9SthmRdoT4WCXxS8eD8icF6U', + y: 'nP6GIc42c61hoKqPcZqkvzhzIJkBV3Jw3g8sGG7UeP8', + kty: 'EC', + kid: 'one', + }, + ...keys + ], + } -// const scopeNock = nock('https://as.example.com').get('/jwks').once().reply(200, jwks) - -// const signedPayloadEs512 = await signJwtWithPrivateKey( -// { -// urn: "urn:test:test" -// }, -// Algs.ES512, -// keyPairES512.privateKey, -// { -// kid: keyPairES512?.kid -// } -// ); - -// const jwksUri = `https://as.example.com/jwks`; - -// const tokenInJwksStoreValidness = await checkTokenValidness( -// signedPayloadEs512, -// { -// jwksUri -// } -// ); - -// expect(tokenInJwksStoreValidness).toBeTruthy(); - -// scopeNock.persist(false); -// }); - -// it("throws an error while verifying token with public uri whose key is missing from set", async () => { -// const tenantUuid2 = "d84ddef4-81dd-4ce6-9594-03ac52cac367"; -// const applicationUuid2 = "b867db48-4e11-4cae-bb03-086dc97c8ddd"; -// const keyPairES512 = await getKeyPair({ -// algorithmIdentifier: Algs.ES512, -// keySize: 4096 -// }); - -// const regExpPathAppJwks = new RegExp( -// `api\/${c.AUTHDOG_JWKS_API_ID}\/${tenantUuid2}\/${applicationUuid2}\/.well-known\/jwks.json*` -// ); - -// const keys = [keyPairES512.publicKey]; -// const AUTHDOG_API_ROOT = "https://api.authdog.xyz"; - -// const scopeNock = nock(AUTHDOG_API_ROOT, { -// reqheaders: { -// 'x-custom': 'foo', -// }, -// }) -// .persist() -// .get(regExpPathAppJwks) -// .reply(200, { -// keys -// }); - -// const jwksUri = `${AUTHDOG_API_ROOT}/api/${c.AUTHDOG_JWKS_API_ID}/${tenantUuid2}/${applicationUuid2}/.well-known/jwks.json`; - -// // test with a token that is not in jwks store -// const keyPairES256K = await getKeyPair({ -// algorithmIdentifier: Algs.ES256K, -// keySize: 4096 -// }); - -// const signedPayloadEs256k = await signJwtWithPrivateKey( -// { -// urn: "urn:test:test" -// }, -// Algs.ES256K, -// keyPairES256K.privateKey, -// { -// kid: keyPairES256K?.kid -// } -// ); - -// await expect( -// checkTokenValidness(signedPayloadEs256k, { -// jwksUri -// }) -// ).rejects.toThrow(c.JWK_NO_APPLICABLE_KEY); - -// scopeNock.persist(false); -// }); + const scopeNock = nock('https://as.example.com').get('/jwks').once().reply(200, jwks) + + const signedPayloadEs512 = await signJwtWithPrivateKey( + { + urn: "urn:test:test" + }, + Algs.ES512, + keyPairES512.privateKey, + { + kid: keyPairES512?.kid + } + ); + + const jwksUri = `https://as.example.com/jwks`; + + const tokenInJwksStoreValidness = await checkTokenValidness( + signedPayloadEs512, + { + jwksUri + } + ); + + expect(tokenInJwksStoreValidness).toBeTruthy(); + + scopeNock.persist(false); +}); + +it("throws an error while verifying token with public uri whose key is missing from set", async () => { + const tenantUuid2 = "d84ddef4-81dd-4ce6-9594-03ac52cac367"; + const applicationUuid2 = "b867db48-4e11-4cae-bb03-086dc97c8ddd"; + const keyPairES512 = await getKeyPair({ + algorithmIdentifier: Algs.ES512, + keySize: 4096 + }); + + const regExpPathAppJwks = new RegExp( + `api\/${c.AUTHDOG_JWKS_API_ID}\/${tenantUuid2}\/${applicationUuid2}\/.well-known\/jwks.json*` + ); + + const keys = [keyPairES512.publicKey]; + const AUTHDOG_API_ROOT = "https://api.authdog.xyz"; + + const scopeNock = nock(AUTHDOG_API_ROOT) + .persist() + .get(regExpPathAppJwks) + .reply(200, { + keys + }); + + const jwksUri = `${AUTHDOG_API_ROOT}/api/${c.AUTHDOG_JWKS_API_ID}/${tenantUuid2}/${applicationUuid2}/.well-known/jwks.json`; + + // test with a token that is not in jwks store + const keyPairES256K = await getKeyPair({ + algorithmIdentifier: Algs.ES256K, + keySize: 4096 + }); + + const signedPayloadEs256k = await signJwtWithPrivateKey( + { + urn: "urn:test:test" + }, + Algs.ES256K, + keyPairES256K.privateKey, + { + kid: keyPairES256K?.kid + } + ); + + await expect( + checkTokenValidness(signedPayloadEs256k, { + jwksUri + }) + ).rejects.toThrow(c.JWK_NO_APPLICABLE_KEY); + + scopeNock.persist(false); +}); \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index abcc7f0..fd5a131 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2555,7 +2555,7 @@ nock@^13.4.0: json-stringify-safe "^5.0.1" propagate "^2.0.0" -node-fetch@^2.6.1: +node-fetch@2.7.0, node-fetch@^2.6.1: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==