diff --git a/.changeset/chilly-coats-sniff.md b/.changeset/chilly-coats-sniff.md new file mode 100644 index 000000000..3597299a7 --- /dev/null +++ b/.changeset/chilly-coats-sniff.md @@ -0,0 +1,5 @@ +--- +"@near-js/biometric-ed25519": patch +--- + +Bug fix on createKey and getKeys diff --git a/packages/biometric-ed25519/package.json b/packages/biometric-ed25519/package.json index 402bbc59c..3af8b50e5 100644 --- a/packages/biometric-ed25519/package.json +++ b/packages/biometric-ed25519/package.json @@ -7,7 +7,8 @@ "scripts": { "build": "tsc -p ./tsconfig.json", "lint:ts": "eslint -c ../../.eslintrc.ts.yml src/**/*.ts --no-eslintrc", - "lint:ts:fix": "eslint -c ../../.eslintrc.ts.yml src/**/*.ts --no-eslintrc --fix" + "lint:ts:fix": "eslint -c ../../.eslintrc.ts.yml src/**/*.ts --no-eslintrc --fix", + "test": "jest test" }, "keywords": [], "author": "Pagoda", @@ -24,6 +25,7 @@ "fido2-lib": "3.4.1" }, "devDependencies": { - "@types/node": "18.11.18" + "@types/node": "18.11.18", + "jest": "26.0.1" } } diff --git a/packages/biometric-ed25519/src/index.ts b/packages/biometric-ed25519/src/index.ts index 6835b159b..0478701af 100644 --- a/packages/biometric-ed25519/src/index.ts +++ b/packages/biometric-ed25519/src/index.ts @@ -13,7 +13,8 @@ import { publicKeyCredentialToJSON, recoverPublicKey, uint8ArrayToBigInt, - convertToArrayBuffer + sanitizeCreateKeyResponse, + sanitizeGetKeyResponse } from './utils'; import { Fido2 } from './fido2'; import { AssertionResponse } from './index.d'; @@ -64,7 +65,7 @@ export const createKey = async (username: string): Promise => { throw new PasskeyProcessCanceled('Failed to retrieve response from navigator.credentials.create'); } - const sanitizedResponse = convertToArrayBuffer(res); + const sanitizedResponse = sanitizeCreateKeyResponse(res); const result = await f2l.attestation({ clientAttestationResponse: sanitizedResponse, @@ -95,8 +96,8 @@ export const getKeys = async (username: string): Promise<[KeyPair, KeyPair]> => setBufferIfUndefined(); return navigator.credentials.get({ publicKey }) - .then(async (response: Credential) => { - const sanitizedResponse = convertToArrayBuffer(response); + .then(async (response) => { + const sanitizedResponse = sanitizeGetKeyResponse(response); const getAssertionResponse: AssertionResponse = publicKeyCredentialToJSON(sanitizedResponse); const signature = base64.toArrayBuffer(getAssertionResponse.response.signature, true); diff --git a/packages/biometric-ed25519/src/utils.ts b/packages/biometric-ed25519/src/utils.ts index b5f48bcf7..217db8da4 100644 --- a/packages/biometric-ed25519/src/utils.ts +++ b/packages/biometric-ed25519/src/utils.ts @@ -92,17 +92,75 @@ export const uint8ArrayToBigInt = (uint8Array: Uint8Array) => { return BigInt('0x' + array.map(byte => byte.toString(16).padStart(2, '0')).join('')); }; -// This function is tries converts Uint8Array, Array or object to ArrayBuffer. Returns the original object if it doesn't match any of the aforementioned types. -export const convertToArrayBuffer = (obj) => { +const convertUint8ArrayToArrayBuffer = (obj: any) => { if (obj instanceof Uint8Array) { return obj.buffer.slice(obj.byteOffset, obj.byteOffset + obj.byteLength); - } else if (Array.isArray(obj)) { - return obj.map(convertToArrayBuffer); - } else if (obj !== null && typeof obj === 'object') { - return Object.keys(obj).reduce((acc, key) => { - acc[key] = convertToArrayBuffer(obj[key]); - return acc; - }, {}); } return obj; +}; + +// This function is used to sanitize the response from navigator.credentials.create(), seeking for any Uint8Array and converting them to ArrayBuffer +// This function has multiple @ts-ignore because types are not up to date with standard type below: +// https://developer.mozilla.org/en-US/docs/Web/API/AuthenticatorAttestationResponse +// an AuthenticatorAttestationResponse (when the PublicKeyCredential is created via CredentialsContainer.create()) +export const sanitizeCreateKeyResponse = (res: Credential) => { + if (res instanceof PublicKeyCredential && ( + res.rawId instanceof Uint8Array || + res.response.clientDataJSON instanceof Uint8Array || + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore - attestationObject is not defined in Credential + res.response.attestationObject instanceof Uint8Array + )) { + return { + ...res, + rawId: convertUint8ArrayToArrayBuffer(res.rawId), + response: { + ...res.response, + clientDataJSON: convertUint8ArrayToArrayBuffer(res.response.clientDataJSON), + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore - attestationObject is not defined in Credential + attestationObject: convertUint8ArrayToArrayBuffer(res.response.attestationObject), + } + }; + } + return res; +}; + +// This function is used to sanitize the response from navigator.credentials.get(), seeking for any Uint8Array and converting them to ArrayBuffer +// This function has multiple @ts-ignore because types are not up to date with standard type below: +// https://developer.mozilla.org/en-US/docs/Web/API/AuthenticatorAssertionResponse +// an AuthenticatorAssertionResponse (when the PublicKeyCredential is obtained via CredentialsContainer.get()). +export const sanitizeGetKeyResponse = (res: Credential) => { + if (res instanceof PublicKeyCredential && ( + res.rawId instanceof Uint8Array || + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore - authenticatorData is not defined in Credential + res.response.authenticatorData instanceof Uint8Array || + res.response.clientDataJSON instanceof Uint8Array || + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore - signature is not defined in Credential + res.response.signature instanceof Uint8Array || + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore - userHandle is not defined in Credential + res.response.userHandle instanceof Uint8Array + )) { + return { + ...res, + rawId: convertUint8ArrayToArrayBuffer(res.rawId), + response: { + ...res.response, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore - authenticatorData is not defined in Credential + authenticatorData: convertUint8ArrayToArrayBuffer(res.response.authenticatorData), + clientDataJSON: convertUint8ArrayToArrayBuffer(res.response.clientDataJSON), + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore - signature is not defined in Credential + signature: convertUint8ArrayToArrayBuffer(res.response.signature), + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore - userHandle is not defined in Credential + userHandle: convertUint8ArrayToArrayBuffer(res.response.userHandle), + } + }; + } + return res; }; \ No newline at end of file diff --git a/packages/biometric-ed25519/test/utils.test.js b/packages/biometric-ed25519/test/utils.test.js new file mode 100644 index 000000000..aac7c58b2 --- /dev/null +++ b/packages/biometric-ed25519/test/utils.test.js @@ -0,0 +1,111 @@ +const { sanitizeCreateKeyResponse, sanitizeGetKeyResponse } = require("../lib/utils"); + +// Define a mock PublicKeyCredential +class PublicKeyCredentialMock { +constructor({ + rawId, + clientDataJSON, + attestationObject, + authenticatorData, + signature, + userHandle +}) { + this.rawId = rawId; + this.response = { + clientDataJSON, + ...(attestationObject ? { attestationObject } : {}), + ...(signature ? { signature } : {}), + ...(userHandle ? { userHandle } : {}), + ...(authenticatorData ? { authenticatorData } : {}), + }; + } +} + +// Define global PublicKeyCredential to make it available during tests +global.PublicKeyCredential = PublicKeyCredentialMock; + +jest.mock('../lib/utils', () => { + const originalModule = jest.requireActual('../lib/utils'); + return { + ...originalModule, + convertUint8ArrayToArrayBuffer: jest.fn().mockImplementation(input => input.buffer), + }; +}); + +describe('sanitizeCreateKeyResponse', () => { + it('should convert Uint8Array properties to ArrayBuffer for PublicKeyCredential', () => { + const mockCredential = new PublicKeyCredentialMock({ + rawId: new Uint8Array([10, 20, 30]), + clientDataJSON: new Uint8Array([40, 50, 60]), + attestationObject: new Uint8Array([70, 80, 90]), + }); + + + const result = sanitizeCreateKeyResponse(mockCredential); + expect(result.rawId.constructor.name).toBe('ArrayBuffer'); + expect(result.response.clientDataJSON.constructor.name).toBe('ArrayBuffer'); + expect(result.response.attestationObject.constructor.name).toBe('ArrayBuffer'); + }); + + it('should return the input unchanged if not PublicKeyCredential or without Uint8Arrays', () => { + const mockCredential = new PublicKeyCredentialMock({ + rawId: [10, 20, 30], + clientDataJSON: [40, 50, 60], + attestationObject: [70, 80, 90], + }); + + const result = sanitizeCreateKeyResponse(mockCredential); + expect(result).toEqual(mockCredential); + }); + + it('should handle non-PublicKeyCredential input gracefully', () => { + const nonPublicKeyCredential = { + someProp: 'test' + }; // No casting needed + + const result = sanitizeCreateKeyResponse(nonPublicKeyCredential); + expect(result).toEqual(nonPublicKeyCredential); + }); +}); + +describe('sanitizeGetKeyResponse', () => { + it('should convert Uint8Array properties to ArrayBuffer in PublicKeyCredential', () => { + const mockCredential = new PublicKeyCredentialMock({ + rawId: new Uint8Array([10, 20, 30]), + clientDataJSON: new Uint8Array([40, 50, 60]), + authenticatorData: new Uint8Array([70, 80, 90]), + signature: new Uint8Array([100, 110, 120]), + userHandle: new Uint8Array([130, 140, 150]) + }); + + const result = sanitizeGetKeyResponse(mockCredential); + expect(result.rawId.constructor.name).toBe('ArrayBuffer'); + expect(result.response.clientDataJSON.constructor.name).toBe('ArrayBuffer'); + expect(result.response.authenticatorData.constructor.name).toBe('ArrayBuffer'); + expect(result.response.signature.constructor.name).toBe('ArrayBuffer'); + expect(result.response.userHandle.constructor.name).toBe('ArrayBuffer'); + }); + + it('should return the input unchanged if it does not meet conversion criteria', () => { + const mockCredential = new PublicKeyCredentialMock({ + rawId: [10, 20, 30], + clientDataJSON: [40, 50, 60], + authenticatorData: [70, 80, 90], + signature: [100, 110, 120], + userHandle: [130, 140, 150] + }); + + + const result = sanitizeGetKeyResponse(mockCredential); + expect(result).toEqual(mockCredential); + }); + + it('should handle non-PublicKeyCredential input gracefully', () => { + const nonPublicKeyCredential = { + someProp: 'test value' + }; + + const result = sanitizeGetKeyResponse(nonPublicKeyCredential); + expect(result).toEqual(nonPublicKeyCredential); + }); +}); \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4535a32cc..67cfd9d5a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -95,7 +95,7 @@ importers: version: 4.0.0 jest: specifier: 26.0.1 - version: 26.0.1 + version: 26.0.1(ts-node@10.9.1) near-hello: specifier: 0.5.1 version: 0.5.1 @@ -142,6 +142,9 @@ importers: '@types/node': specifier: 18.11.18 version: 18.11.18 + jest: + specifier: 26.0.1 + version: 26.0.1(ts-node@10.9.1) packages/cookbook: dependencies: @@ -193,7 +196,7 @@ importers: version: 18.11.18 jest: specifier: 26.0.1 - version: 26.0.1 + version: 26.0.1(ts-node@10.9.1) ts-jest: specifier: 26.5.6 version: 26.5.6(jest@26.0.1)(typescript@4.9.4) @@ -225,7 +228,7 @@ importers: version: 18.11.18 jest: specifier: 26.0.1 - version: 26.0.1 + version: 26.0.1(ts-node@10.9.1) ts-jest: specifier: 26.5.6 version: 26.5.6(jest@26.0.1)(typescript@4.9.4) @@ -244,7 +247,7 @@ importers: devDependencies: jest: specifier: 26.0.1 - version: 26.0.1 + version: 26.0.1(ts-node@10.9.1) ts-jest: specifier: 26.5.6 version: 26.5.6(jest@26.0.1)(typescript@4.9.4) @@ -266,7 +269,7 @@ importers: version: 18.11.18 jest: specifier: 26.0.1 - version: 26.0.1 + version: 26.0.1(ts-node@10.9.1) ts-jest: specifier: 26.5.6 version: 26.5.6(jest@26.0.1)(typescript@4.9.4) @@ -357,7 +360,7 @@ importers: version: 2.0.0 jest: specifier: 26.0.1 - version: 26.0.1 + version: 26.0.1(ts-node@10.9.1) localstorage-memory: specifier: 1.0.3 version: 1.0.3 @@ -375,7 +378,7 @@ importers: version: 7.1.1 ts-jest: specifier: 26.5.6 - version: 26.5.6(jest@26.0.1) + version: 26.5.6(jest@26.0.1)(typescript@4.9.4) uglifyify: specifier: 5.0.1 version: 5.0.1 @@ -407,7 +410,7 @@ importers: version: 18.11.18 jest: specifier: 26.0.1 - version: 26.0.1 + version: 26.0.1(ts-node@10.9.1) near-workspaces: specifier: 3.4.0 version: 3.4.0 @@ -435,7 +438,7 @@ importers: version: 18.11.18 jest: specifier: 26.0.1 - version: 26.0.1 + version: 26.0.1(ts-node@10.9.1) ts-jest: specifier: 26.5.6 version: 26.5.6(jest@26.0.1)(typescript@4.9.4) @@ -472,7 +475,7 @@ importers: version: 18.11.18 jest: specifier: 26.0.1 - version: 26.0.1 + version: 26.0.1(ts-node@10.9.1) ts-jest: specifier: 26.5.6 version: 26.5.6(jest@26.0.1)(typescript@4.9.4) @@ -487,7 +490,7 @@ importers: version: 18.11.18 jest: specifier: 26.0.1 - version: 26.0.1 + version: 26.0.1(ts-node@10.9.1) ts-jest: specifier: 26.5.6 version: 26.5.6(jest@26.0.1)(typescript@4.9.4) @@ -515,7 +518,7 @@ importers: version: 18.11.18 jest: specifier: 26.0.1 - version: 26.0.1 + version: 26.0.1(ts-node@10.9.1) ts-jest: specifier: 26.5.6 version: 26.5.6(jest@26.0.1)(typescript@4.9.4) @@ -558,7 +561,7 @@ importers: version: 18.11.18 jest: specifier: 26.0.1 - version: 26.0.1 + version: 26.0.1(ts-node@10.9.1) localstorage-memory: specifier: 1.0.3 version: 1.0.3 @@ -1412,7 +1415,7 @@ packages: slash: 3.0.0 dev: true - /@jest/core@26.6.3: + /@jest/core@26.6.3(ts-node@10.9.1): resolution: {integrity: sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==} engines: {node: '>= 10.14.2'} dependencies: @@ -1427,14 +1430,14 @@ packages: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 26.6.2 - jest-config: 26.6.3 + jest-config: 26.6.3(ts-node@10.9.1) jest-haste-map: 26.6.2 jest-message-util: 26.6.2 jest-regex-util: 26.0.0 jest-resolve: 26.6.2 jest-resolve-dependencies: 26.6.3 - jest-runner: 26.6.3 - jest-runtime: 26.6.3 + jest-runner: 26.6.3(ts-node@10.9.1) + jest-runtime: 26.6.3(ts-node@10.9.1) jest-snapshot: 26.6.2 jest-util: 26.6.2 jest-validate: 26.6.2 @@ -1536,15 +1539,15 @@ packages: collect-v8-coverage: 1.0.2 dev: true - /@jest/test-sequencer@26.6.3: + /@jest/test-sequencer@26.6.3(ts-node@10.9.1): resolution: {integrity: sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==} engines: {node: '>= 10.14.2'} dependencies: '@jest/test-result': 26.6.2 graceful-fs: 4.2.11 jest-haste-map: 26.6.2 - jest-runner: 26.6.3 - jest-runtime: 26.6.3 + jest-runner: 26.6.3(ts-node@10.9.1) + jest-runtime: 26.6.3(ts-node@10.9.1) transitivePeerDependencies: - bufferutil - canvas @@ -1663,7 +1666,7 @@ packages: '@near-js/types': 0.0.4 '@near-js/utils': 0.0.4 ajv: 8.11.2 - ajv-formats: 2.1.1 + ajv-formats: 2.1.1(ajv@8.11.2) bn.js: 5.2.1 borsh: 0.7.0 depd: 2.0.0 @@ -2317,8 +2320,10 @@ packages: - supports-color dev: true - /ajv-formats@2.1.1: + /ajv-formats@2.1.1(ajv@8.11.2): resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependencies: + ajv: ^8.0.0 peerDependenciesMeta: ajv: optional: true @@ -5509,12 +5514,12 @@ packages: throat: 5.0.0 dev: true - /jest-cli@26.6.3: + /jest-cli@26.6.3(ts-node@10.9.1): resolution: {integrity: sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==} engines: {node: '>= 10.14.2'} hasBin: true dependencies: - '@jest/core': 26.6.3 + '@jest/core': 26.6.3(ts-node@10.9.1) '@jest/test-result': 26.6.2 '@jest/types': 26.6.2 chalk: 4.1.1 @@ -5522,7 +5527,7 @@ packages: graceful-fs: 4.2.11 import-local: 3.1.0 is-ci: 2.0.0 - jest-config: 26.6.3 + jest-config: 26.6.3(ts-node@10.9.1) jest-util: 26.6.2 jest-validate: 26.6.2 prompts: 2.4.2 @@ -5535,7 +5540,7 @@ packages: - utf-8-validate dev: true - /jest-config@26.6.3: + /jest-config@26.6.3(ts-node@10.9.1): resolution: {integrity: sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==} engines: {node: '>= 10.14.2'} peerDependencies: @@ -5545,7 +5550,7 @@ packages: optional: true dependencies: '@babel/core': 7.22.9 - '@jest/test-sequencer': 26.6.3 + '@jest/test-sequencer': 26.6.3(ts-node@10.9.1) '@jest/types': 26.6.2 babel-jest: 26.6.3(@babel/core@7.22.9) chalk: 4.1.1 @@ -5555,13 +5560,14 @@ packages: jest-environment-jsdom: 26.6.2 jest-environment-node: 26.6.2 jest-get-type: 26.3.0 - jest-jasmine2: 26.6.3 + jest-jasmine2: 26.6.3(ts-node@10.9.1) jest-regex-util: 26.0.0 jest-resolve: 26.6.2 jest-util: 26.6.2 jest-validate: 26.6.2 micromatch: 4.0.5 pretty-format: 26.6.2 + ts-node: 10.9.1(@types/node@18.11.18)(typescript@4.9.4) transitivePeerDependencies: - bufferutil - canvas @@ -5655,7 +5661,7 @@ packages: - supports-color dev: true - /jest-jasmine2@26.6.3: + /jest-jasmine2@26.6.3(ts-node@10.9.1): resolution: {integrity: sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==} engines: {node: '>= 10.14.2'} dependencies: @@ -5672,7 +5678,7 @@ packages: jest-each: 26.6.2 jest-matcher-utils: 26.6.2 jest-message-util: 26.6.2 - jest-runtime: 26.6.3 + jest-runtime: 26.6.3(ts-node@10.9.1) jest-snapshot: 26.6.2 jest-util: 26.6.2 pretty-format: 26.6.2 @@ -5768,7 +5774,7 @@ packages: slash: 3.0.0 dev: true - /jest-runner@26.6.3: + /jest-runner@26.6.3(ts-node@10.9.1): resolution: {integrity: sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==} engines: {node: '>= 10.14.2'} dependencies: @@ -5781,13 +5787,13 @@ packages: emittery: 0.7.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 26.6.3 + jest-config: 26.6.3(ts-node@10.9.1) jest-docblock: 26.0.0 jest-haste-map: 26.6.2 jest-leak-detector: 26.6.2 jest-message-util: 26.6.2 jest-resolve: 26.6.2 - jest-runtime: 26.6.3 + jest-runtime: 26.6.3(ts-node@10.9.1) jest-util: 26.6.2 jest-worker: 26.6.2 source-map-support: 0.5.21 @@ -5800,7 +5806,7 @@ packages: - utf-8-validate dev: true - /jest-runtime@26.6.3: + /jest-runtime@26.6.3(ts-node@10.9.1): resolution: {integrity: sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==} engines: {node: '>= 10.14.2'} hasBin: true @@ -5820,7 +5826,7 @@ packages: exit: 0.1.2 glob: 7.2.3 graceful-fs: 4.2.11 - jest-config: 26.6.3 + jest-config: 26.6.3(ts-node@10.9.1) jest-haste-map: 26.6.2 jest-message-util: 26.6.2 jest-mock: 26.6.2 @@ -5918,14 +5924,14 @@ packages: supports-color: 7.2.0 dev: true - /jest@26.0.1: + /jest@26.0.1(ts-node@10.9.1): resolution: {integrity: sha512-29Q54kn5Bm7ZGKIuH2JRmnKl85YRigp0o0asTc6Sb6l2ch1DCXIeZTLLFy9ultJvhkTqbswF5DEx4+RlkmCxWg==} engines: {node: '>= 10.14.2'} hasBin: true dependencies: - '@jest/core': 26.6.3 + '@jest/core': 26.6.3(ts-node@10.9.1) import-local: 3.1.0 - jest-cli: 26.6.3 + jest-cli: 26.6.3(ts-node@10.9.1) transitivePeerDependencies: - bufferutil - canvas @@ -6685,7 +6691,7 @@ packages: '@near-js/utils': 0.0.4 '@near-js/wallet-account': 0.0.7 ajv: 8.11.2 - ajv-formats: 2.1.1 + ajv-formats: 2.1.1(ajv@8.11.2) bn.js: 5.2.1 borsh: 0.7.0 depd: 2.0.0 @@ -8327,27 +8333,6 @@ packages: engines: {node: '>=8'} dev: true - /ts-jest@26.5.6(jest@26.0.1): - resolution: {integrity: sha512-rua+rCP8DxpA8b4DQD/6X2HQS8Zy/xzViVYfEs2OQu68tkCuKLV0Md8pmX55+W24uRIyAsf/BajRfxOs+R2MKA==} - engines: {node: '>= 10'} - hasBin: true - peerDependencies: - jest: '>=26 <27' - typescript: '>=3.8 <5.0' - dependencies: - bs-logger: 0.2.6 - buffer-from: 1.1.2 - fast-json-stable-stringify: 2.1.0 - jest: 26.0.1 - jest-util: 26.6.2 - json5: 2.2.3 - lodash: 4.17.21 - make-error: 1.3.6 - mkdirp: 1.0.4 - semver: 7.1.1 - yargs-parser: 20.2.9 - dev: true - /ts-jest@26.5.6(jest@26.0.1)(typescript@4.9.4): resolution: {integrity: sha512-rua+rCP8DxpA8b4DQD/6X2HQS8Zy/xzViVYfEs2OQu68tkCuKLV0Md8pmX55+W24uRIyAsf/BajRfxOs+R2MKA==} engines: {node: '>= 10'} @@ -8359,7 +8344,7 @@ packages: bs-logger: 0.2.6 buffer-from: 1.1.2 fast-json-stable-stringify: 2.1.0 - jest: 26.0.1 + jest: 26.0.1(ts-node@10.9.1) jest-util: 26.6.2 json5: 2.2.3 lodash: 4.17.21