From 0840a11c12daee94cf682f20b48a8810f4771959 Mon Sep 17 00:00:00 2001 From: "IceHe.xyz" Date: Fri, 21 Jan 2022 16:43:50 +0800 Subject: [PATCH 1/4] chore(js): add LogtoErrorCode.idToken.invalidToken --- packages/js/src/utils/errors.ts | 1 + packages/js/src/utils/id-token.test.ts | 2 +- packages/js/src/utils/id-token.ts | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/js/src/utils/errors.ts b/packages/js/src/utils/errors.ts index 01cbfc9d0..15197af96 100644 --- a/packages/js/src/utils/errors.ts +++ b/packages/js/src/utils/errors.ts @@ -16,6 +16,7 @@ const logtoErrorCodes = Object.freeze({ verification: { invalidIat: 'Invalid issued at time', }, + invalidToken: 'Invalid token', }, }); diff --git a/packages/js/src/utils/id-token.test.ts b/packages/js/src/utils/id-token.test.ts index e1441b634..971f72a2b 100644 --- a/packages/js/src/utils/id-token.test.ts +++ b/packages/js/src/utils/id-token.test.ts @@ -255,7 +255,7 @@ describe('decodeIdToken', () => { }); test('decoding invalid JWT string should throw Error', async () => { - expect(() => decodeIdToken('invalid-JWT')).toThrow('invalid token'); + expect(() => decodeIdToken('invalid-JWT')).toThrow(new LogtoError('idToken.invalidToken')); }); test('decoding valid JWT without issuer should throw StructError', async () => { diff --git a/packages/js/src/utils/id-token.ts b/packages/js/src/utils/id-token.ts index ef816c1dc..abe0a1c0c 100644 --- a/packages/js/src/utils/id-token.ts +++ b/packages/js/src/utils/id-token.ts @@ -35,7 +35,7 @@ export const verifyIdToken = async ( export const decodeIdToken = (token: string): IdTokenClaims => { const { 1: encodedPayload } = token.split('.'); if (!encodedPayload) { - throw new Error('invalid token'); + throw new LogtoError('idToken.invalidToken'); } const json = UrlSafeBase64.decode(encodedPayload); From 8895d8dfb25780a31ae46db87e57f1723df13234 Mon Sep 17 00:00:00 2001 From: "IceHe.xyz" Date: Fri, 21 Jan 2022 16:55:31 +0800 Subject: [PATCH 2/4] chore(js): simplify LogtoErrorCode.invalidIat --- packages/js/src/utils/errors.ts | 4 +--- packages/js/src/utils/id-token.test.ts | 2 +- packages/js/src/utils/id-token.ts | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/js/src/utils/errors.ts b/packages/js/src/utils/errors.ts index 15197af96..c536d4a7f 100644 --- a/packages/js/src/utils/errors.ts +++ b/packages/js/src/utils/errors.ts @@ -13,9 +13,7 @@ type Normalize = keyof T | Normalize2; const logtoErrorCodes = Object.freeze({ idToken: { - verification: { - invalidIat: 'Invalid issued at time', - }, + invalidIat: 'Invalid issued at time', invalidToken: 'Invalid token', }, }); diff --git a/packages/js/src/utils/id-token.test.ts b/packages/js/src/utils/id-token.test.ts index 971f72a2b..3ed226c60 100644 --- a/packages/js/src/utils/id-token.test.ts +++ b/packages/js/src/utils/id-token.test.ts @@ -206,7 +206,7 @@ describe('verifyIdToken', () => { const jwks = createDefaultJwks(); await expect(verifyIdToken(idToken, 'qux', 'foo', jwks)).rejects.toThrowError( - new LogtoError('idToken.verification.invalidIat') + new LogtoError('idToken.invalidIat') ); }); }); diff --git a/packages/js/src/utils/id-token.ts b/packages/js/src/utils/id-token.ts index abe0a1c0c..43c5fa65d 100644 --- a/packages/js/src/utils/id-token.ts +++ b/packages/js/src/utils/id-token.ts @@ -28,7 +28,7 @@ export const verifyIdToken = async ( ) => { const result = await jwtVerify(idToken, jwks, { audience: clientId, issuer }); if (Math.abs((result?.payload?.iat ?? 0) - Date.now() / 1000) > issuedAtTimeTolerance) { - throw new LogtoError('idToken.verification.invalidIat'); + throw new LogtoError('idToken.invalidIat'); } }; From f19c08df4b2e4dfa1cabaa92a02d62ba93894798 Mon Sep 17 00:00:00 2001 From: "IceHe.xyz" Date: Fri, 21 Jan 2022 20:39:38 +0800 Subject: [PATCH 3/4] chore(js): add devDependency jest-matcher-specific-error --- packages/js/jest.config.js | 2 +- packages/js/package.json | 1 + packages/js/tsconfig.json | 7 ++++++- pnpm-lock.yaml | 6 ++++++ 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/js/jest.config.js b/packages/js/jest.config.js index 7ca5759df..6c13d602f 100644 --- a/packages/js/jest.config.js +++ b/packages/js/jest.config.js @@ -2,7 +2,7 @@ module.exports = { coveragePathIgnorePatterns: ['/node_modules/', '/lib/'], coverageReporters: ['text-summary', 'lcov'], moduleFileExtensions: ['ts', 'js'], - setupFilesAfterEnv: ['./jest.setup.js'], + setupFilesAfterEnv: ['./jest.setup.js', 'jest-matcher-specific-error'], testPathIgnorePatterns: ['lib'], testRegex: '(/__tests__/.*|\\.(test|spec))\\.(ts|js)$', transform: { diff --git a/packages/js/package.json b/packages/js/package.json index 55cf632ae..81e5e65ad 100644 --- a/packages/js/package.json +++ b/packages/js/package.json @@ -32,6 +32,7 @@ "codecov": "^3.8.3", "eslint": "^8.1.0", "jest": "^27.0.6", + "jest-matcher-specific-error": "^1.0.0", "lint-staged": "^11.1.2", "nock": "^13.1.3", "node-fetch": "2.6.6", diff --git a/packages/js/tsconfig.json b/packages/js/tsconfig.json index 33524c13e..61740a924 100644 --- a/packages/js/tsconfig.json +++ b/packages/js/tsconfig.json @@ -2,7 +2,12 @@ "extends": "@silverhand/ts-config/tsconfig.base", "compilerOptions": { "outDir": "lib", - "target": "es5" + "target": "es5", + "types": [ + "node", + "jest", + "jest-matcher-specific-error" + ] }, "include": [ "src" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 98ab6e3ec..bb607dcf9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -84,6 +84,7 @@ importers: codecov: ^3.8.3 eslint: ^8.1.0 jest: ^27.0.6 + jest-matcher-specific-error: ^1.0.0 jose: ^4.3.8 js-base64: ^3.7.2 lint-staged: ^11.1.2 @@ -112,6 +113,7 @@ importers: codecov: 3.8.3 eslint: 8.2.0 jest: 27.0.6 + jest-matcher-specific-error: 1.0.0 lint-staged: 11.1.2 nock: 13.1.3 node-fetch: 2.6.6 @@ -10046,6 +10048,10 @@ packages: pretty-format: 27.0.6 dev: true + /jest-matcher-specific-error/1.0.0: + resolution: {integrity: sha512-thJdy9ibhDo8k+0arFalNCQBJ0u7eqTfpTzS2MzL3iCLmbRCkI+yhhKSiAxEi55e5ZUyf01ySa0fMqzF+sblAw==} + dev: true + /jest-matcher-utils/26.6.2: resolution: {integrity: sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==} engines: {node: '>= 10.14.2'} From 9db9632e431e1a7ef95f8ecf5088efbf9a2c5035 Mon Sep 17 00:00:00 2001 From: "IceHe.xyz" Date: Fri, 21 Jan 2022 20:40:40 +0800 Subject: [PATCH 4/4] test(js): replace toThrowError with toMatchError in id-token.test.ts --- packages/js/src/utils/id-token.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/js/src/utils/id-token.test.ts b/packages/js/src/utils/id-token.test.ts index 3ed226c60..b50188d17 100644 --- a/packages/js/src/utils/id-token.test.ts +++ b/packages/js/src/utils/id-token.test.ts @@ -205,7 +205,7 @@ describe('verifyIdToken', () => { const jwks = createDefaultJwks(); - await expect(verifyIdToken(idToken, 'qux', 'foo', jwks)).rejects.toThrowError( + await expect(verifyIdToken(idToken, 'qux', 'foo', jwks)).rejects.toMatchError( new LogtoError('idToken.invalidIat') ); }); @@ -255,7 +255,7 @@ describe('decodeIdToken', () => { }); test('decoding invalid JWT string should throw Error', async () => { - expect(() => decodeIdToken('invalid-JWT')).toThrow(new LogtoError('idToken.invalidToken')); + expect(() => decodeIdToken('invalid-JWT')).toMatchError(new LogtoError('idToken.invalidToken')); }); test('decoding valid JWT without issuer should throw StructError', async () => {