From cec4e029f0c84b20ce1bdf74accae53ac81a4e46 Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Mon, 3 Apr 2023 15:45:23 +0200 Subject: [PATCH 001/201] Update web-stream-tools --- package-lock.json | 73 ++++++++++++++--------------------------------- package.json | 2 +- 2 files changed, 22 insertions(+), 53 deletions(-) diff --git a/package-lock.json b/package-lock.json index cefc5931..b568e01f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,7 @@ "@openpgp/pako": "^1.0.12", "@openpgp/seek-bzip": "^1.0.5-git", "@openpgp/tweetnacl": "^1.0.3", - "@openpgp/web-stream-tools": "0.0.11-patch-0", + "@openpgp/web-stream-tools": "^0.0.13", "@rollup/plugin-commonjs": "^11.1.0", "@rollup/plugin-node-resolve": "^7.1.3", "@rollup/plugin-replace": "^2.3.2", @@ -487,15 +487,6 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, - "node_modules/@mattiasbuelens/web-streams-adapter": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@mattiasbuelens/web-streams-adapter/-/web-streams-adapter-0.1.0.tgz", - "integrity": "sha512-oV4PyZfwJNtmFWhvlJLqYIX1Nn22ML8FZpS16ZUKv0hg7414xV1fjsGqxQzLT2dyK92TKxsJSwMOd7VNHAtPmA==", - "dev": true, - "engines": { - "node": ">= 12" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -627,22 +618,17 @@ "dev": true }, "node_modules/@openpgp/web-stream-tools": { - "version": "0.0.11-patch-0", - "resolved": "https://registry.npmjs.org/@openpgp/web-stream-tools/-/web-stream-tools-0.0.11-patch-0.tgz", - "integrity": "sha512-NrIF4DkCqC3WDcMDAgz17z+0Iik1fVrKuvdbjZXCnMZgYAWHpIG8CWnbp8yQRahAdF26jqCopA/qXrp8CYI2yw==", + "version": "0.0.13", + "resolved": "https://registry.npmjs.org/@openpgp/web-stream-tools/-/web-stream-tools-0.0.13.tgz", + "integrity": "sha512-VQ0O0lUcD9ilLcMLQMJMgPhp8fDgMd4copd+UhSBGjud0vbI1ONQ3ffAhixEMml/AApLJtqCpd7PJcccPliFSA==", "dev": true, - "dependencies": { - "@mattiasbuelens/web-streams-adapter": "~0.1.0", - "web-streams-polyfill": "~3.0.3" - } - }, - "node_modules/@openpgp/web-stream-tools/node_modules/web-streams-polyfill": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.0.3.tgz", - "integrity": "sha512-d2H/t0eqRNM4w2WvmTdoeIvzAUSpK7JmATB8Nr2lb7nQ9BTIJVjbQ/TRFVEh2gUH1HwclPdoPtfMoFfetXaZnA==", - "dev": true, - "engines": { - "node": ">= 8" + "peerDependencies": { + "typescript": ">=4.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@rollup/plugin-commonjs": { @@ -6980,9 +6966,9 @@ } }, "node_modules/typescript": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.2.tgz", - "integrity": "sha512-thGloWsGH3SOxv1SoY7QojKi0tc+8FnOmiarEGMbd/lar7QOEd3hvlx3Fp5y6FlDUGl9L+pd4n2e+oToGMmhRQ==", + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -7856,12 +7842,6 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, - "@mattiasbuelens/web-streams-adapter": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@mattiasbuelens/web-streams-adapter/-/web-streams-adapter-0.1.0.tgz", - "integrity": "sha512-oV4PyZfwJNtmFWhvlJLqYIX1Nn22ML8FZpS16ZUKv0hg7414xV1fjsGqxQzLT2dyK92TKxsJSwMOd7VNHAtPmA==", - "dev": true - }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -7967,22 +7947,11 @@ "dev": true }, "@openpgp/web-stream-tools": { - "version": "0.0.11-patch-0", - "resolved": "https://registry.npmjs.org/@openpgp/web-stream-tools/-/web-stream-tools-0.0.11-patch-0.tgz", - "integrity": "sha512-NrIF4DkCqC3WDcMDAgz17z+0Iik1fVrKuvdbjZXCnMZgYAWHpIG8CWnbp8yQRahAdF26jqCopA/qXrp8CYI2yw==", + "version": "0.0.13", + "resolved": "https://registry.npmjs.org/@openpgp/web-stream-tools/-/web-stream-tools-0.0.13.tgz", + "integrity": "sha512-VQ0O0lUcD9ilLcMLQMJMgPhp8fDgMd4copd+UhSBGjud0vbI1ONQ3ffAhixEMml/AApLJtqCpd7PJcccPliFSA==", "dev": true, - "requires": { - "@mattiasbuelens/web-streams-adapter": "~0.1.0", - "web-streams-polyfill": "~3.0.3" - }, - "dependencies": { - "web-streams-polyfill": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.0.3.tgz", - "integrity": "sha512-d2H/t0eqRNM4w2WvmTdoeIvzAUSpK7JmATB8Nr2lb7nQ9BTIJVjbQ/TRFVEh2gUH1HwclPdoPtfMoFfetXaZnA==", - "dev": true - } - } + "requires": {} }, "@rollup/plugin-commonjs": { "version": "11.1.0", @@ -12938,9 +12907,9 @@ } }, "typescript": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.2.tgz", - "integrity": "sha512-thGloWsGH3SOxv1SoY7QojKi0tc+8FnOmiarEGMbd/lar7QOEd3hvlx3Fp5y6FlDUGl9L+pd4n2e+oToGMmhRQ==", + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true }, "ua-parser-js": { diff --git a/package.json b/package.json index b4fd982e..6dc92a05 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "@openpgp/pako": "^1.0.12", "@openpgp/seek-bzip": "^1.0.5-git", "@openpgp/tweetnacl": "^1.0.3", - "@openpgp/web-stream-tools": "0.0.11-patch-0", + "@openpgp/web-stream-tools": "^0.0.13", "@rollup/plugin-commonjs": "^11.1.0", "@rollup/plugin-node-resolve": "^7.1.3", "@rollup/plugin-replace": "^2.3.2", From de5549ff690c6511101040423a04615bdf166ac8 Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Fri, 2 Sep 2022 22:20:33 +0200 Subject: [PATCH 002/201] Remove embedded Web Streams ponyfill Require the application to load a polyfill instead. --- src/message.js | 10 +--------- src/openpgp.js | 5 +---- src/packet/aead_encrypted_data.js | 2 +- src/packet/packet.js | 2 +- test/general/openpgp.js | 12 ++++++------ test/general/signature.js | 16 ++++++++-------- test/general/streaming.js | 11 ++++++----- test/unittests.js | 4 ++++ 8 files changed, 28 insertions(+), 34 deletions(-) diff --git a/src/message.js b/src/message.js index 186fec42..ce922dcc 100644 --- a/src/message.js +++ b/src/message.js @@ -877,10 +877,6 @@ export async function readMessage({ armoredMessage, binaryMessage, config, ...re const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`); const streamType = util.isStream(input); - if (streamType) { - await stream.loadStreamsPonyfill(); - input = stream.toStream(input); - } if (armoredMessage) { const { type, data } = await unarmor(input, config); if (type !== enums.armor.message) { @@ -907,7 +903,7 @@ export async function readMessage({ armoredMessage, binaryMessage, config, ...re * @static */ export async function createMessage({ text, binary, filename, date = new Date(), format = text !== undefined ? 'utf8' : 'binary', ...rest }) { - let input = text !== undefined ? text : binary; + const input = text !== undefined ? text : binary; if (input === undefined) { throw new Error('createMessage: must pass options object containing `text` or `binary`'); } @@ -920,10 +916,6 @@ export async function createMessage({ text, binary, filename, date = new Date(), const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`); const streamType = util.isStream(input); - if (streamType) { - await stream.loadStreamsPonyfill(); - input = stream.toStream(input); - } const literalDataPacket = new LiteralDataPacket(date); if (text !== undefined) { literalDataPacket.setText(input, enums.write(enums.literal, format)); diff --git a/src/openpgp.js b/src/openpgp.js index 4d11f0a8..28554e7b 100644 --- a/src/openpgp.js +++ b/src/openpgp.js @@ -663,7 +663,7 @@ function toArray(param) { /** * Convert data to or from Stream * @param {Object} data - the data to convert - * @param {'web'|'ponyfill'|'node'|false} streaming - Whether to return a ReadableStream, and of what type + * @param {'web'|'node'|false} streaming - Whether to return a ReadableStream, and of what type * @param {'utf8'|'binary'} [encoding] - How to return data in Node Readable streams * @returns {Promise} The data in the respective format. * @async @@ -679,9 +679,6 @@ async function convertStream(data, streaming, encoding = 'utf8') { if (encoding !== 'binary') data.setEncoding(encoding); return data; } - if (streaming === 'web' && streamType === 'ponyfill') { - return stream.toNativeReadable(data); - } return data; } diff --git a/src/packet/aead_encrypted_data.js b/src/packet/aead_encrypted_data.js index 3e24323b..5f42a8fb 100644 --- a/src/packet/aead_encrypted_data.js +++ b/src/packet/aead_encrypted_data.js @@ -152,7 +152,7 @@ class AEADEncryptedDataPacket { const iv = this.iv; return stream.transformPair(data, async (readable, writable) => { if (util.isStream(readable) !== 'array') { - const buffer = new stream.TransformStream({}, { + const buffer = new TransformStream({}, { highWaterMark: util.getHardwareConcurrency() * 2 ** (this.chunkSizeByte + 6), size: array => array.length }); diff --git a/src/packet/packet.js b/src/packet/packet.js index d18b6c28..b42e4edf 100644 --- a/src/packet/packet.js +++ b/src/packet/packet.js @@ -153,7 +153,7 @@ export async function readPackets(input, callback) { writer = stream.getWriter(arrayStream); packet = arrayStream; } else { - const transform = new stream.TransformStream(); + const transform = new TransformStream(); writer = stream.getWriter(transform.writable); packet = transform.readable; } diff --git a/test/general/openpgp.js b/test/general/openpgp.js index 0b59cc32..cfebc1e0 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -1,5 +1,5 @@ /* eslint-disable max-lines */ -/* globals tryTests: true */ +/* globals tryTests: true, loadStreamsPolyfill */ const spy = require('sinon/lib/sinon/spy'); const stream = require('@openpgp/web-stream-tools'); const { use: chaiUse, expect } = require('chai'); @@ -3000,20 +3000,20 @@ VFBLG8uc9IiaKann/DYBAJcZNZHRSfpDoV2pUA5EAEi2MdjxkRysFQnYPRAu throw new Error('Was not able to successfully modify checksum'); } const badBodyEncrypted = data.replace(/\n=([a-zA-Z0-9/+]{4})/, 'aaa\n=$1'); - await stream.loadStreamsPonyfill(); + loadStreamsPolyfill(); try { for (const allowStreaming of [true, false]) { openpgp.config.allowUnauthenticatedStream = allowStreaming; await Promise.all([badSumEncrypted, badBodyEncrypted].map(async (encrypted, i) => { await Promise.all([ encrypted, - new stream.ReadableStream({ + new ReadableStream({ start(controller) { controller.enqueue(encrypted); controller.close(); } }), - new stream.ReadableStream({ + new ReadableStream({ start() { this.remaining = encrypted.split('\n'); }, @@ -3265,7 +3265,7 @@ VFBLG8uc9IiaKann/DYBAJcZNZHRSfpDoV2pUA5EAEi2MdjxkRysFQnYPRAu const plaintext = []; let i = 0; const useNativeStream = (() => { try { new global.ReadableStream(); return true; } catch (e) { return false; } })(); // eslint-disable-line no-new - await stream.loadStreamsPonyfill(); + loadStreamsPolyfill(); const ReadableStream = useNativeStream ? global.ReadableStream : stream.ReadableStream; const data = new ReadableStream({ pull(controller) { @@ -3622,7 +3622,7 @@ VFBLG8uc9IiaKann/DYBAJcZNZHRSfpDoV2pUA5EAEi2MdjxkRysFQnYPRAu packets.push(message.packets.findPacket(openpgp.enums.packet.literalData)); verifyOpt.message = await openpgp.readMessage({ binaryMessage: stream[ - global.ReadableStream ? (global.ReadableStream === stream.ReadableStream ? 'toStream' : 'toNativeReadable') : 'webToNode' + global.ReadableStream ? 'toStream' : 'webToNode' ](packets.write()) }); return openpgp.verify(verifyOpt); diff --git a/test/general/signature.js b/test/general/signature.js index 914a13e3..5c123d7c 100644 --- a/test/general/signature.js +++ b/test/general/signature.js @@ -1,5 +1,5 @@ /* eslint-disable max-lines */ -/* globals tryTests: true */ +/* globals tryTests: true, loadStreamsPolyfill */ const stream = require('@openpgp/web-stream-tools'); const { use: chaiUse, expect } = require('chai'); chaiUse(require('chai-as-promised')); @@ -900,7 +900,7 @@ AkLaG/AkATpuH+DMkYDmKbDLGgD+N4yuxXBJmBfC2IBe4J1S2Gg= date: key.keyPacket.created, format: 'object' }); - await stream.loadStreamsPonyfill(); + loadStreamsPolyfill(); const { signatures: [sigInfo] } = await openpgp.verify({ verificationKeys: expiredKey, message: await openpgp.readMessage({ armoredMessage: stream.toStream(armoredMessage) }), @@ -931,7 +931,7 @@ aMsUdQBgnPAcSGVsbG8gV29ybGQgOik= date: key.keyPacket.created, format: 'object' }); - await stream.loadStreamsPonyfill(); + loadStreamsPolyfill(); const { signatures: [sigInfo] } = await openpgp.verify({ verificationKeys: expiredKey, message: await openpgp.readMessage({ armoredMessage: stream.toStream(armoredMessage) }), @@ -961,7 +961,7 @@ eSvSZutLuKKbidSYMLhWROPlwKc2GU2ws6PrLZAyCAel/lU= date: key.keyPacket.created, format: 'object' }); - await stream.loadStreamsPonyfill(); + loadStreamsPolyfill(); const { signatures: [sigInfo] } = await openpgp.verify({ verificationKeys: expiredKey, message: await openpgp.readMessage({ armoredMessage: stream.toStream(armoredMessage) }), @@ -1454,9 +1454,9 @@ yYDnCgA= -----END PGP MESSAGE-----`.split(''); const plaintext = 'space: \nspace and tab: \t\nno trailing space\n \ntab:\t\ntab and space:\t '; - await stream.loadStreamsPonyfill(); + loadStreamsPolyfill(); const message = await openpgp.readMessage({ - armoredMessage: new stream.ReadableStream({ + armoredMessage: new ReadableStream({ async pull(controller) { await new Promise(setTimeout); controller.enqueue(armoredMessage.shift()); @@ -1520,9 +1520,9 @@ hkJiXopCSWKSlQInL1devkJJUWJmTmZeugJYlpdLAagQJM0JpsCqIQZwKgAA -----END PGP MESSAGE-----`.split(''); const plaintext = 'space: \nspace and tab: \t\nno trailing space\n \ntab:\t\ntab and space:\t '; - await stream.loadStreamsPonyfill(); + loadStreamsPolyfill(); const message = await openpgp.readMessage({ - armoredMessage: new stream.ReadableStream({ + armoredMessage: new ReadableStream({ async pull(controller) { await new Promise(setTimeout); controller.enqueue(armoredMessage.shift()); diff --git a/test/general/streaming.js b/test/general/streaming.js index b604907a..41b73dc9 100644 --- a/test/general/streaming.js +++ b/test/general/streaming.js @@ -1,4 +1,5 @@ /* eslint-disable max-lines */ +/* globals loadStreamsPolyfill */ const stream = require('@openpgp/web-stream-tools'); const stub = require('sinon/lib/sinon/stub'); const { use: chaiUse, expect } = require('chai'); @@ -423,7 +424,7 @@ function tests() { expect(stream.isStream(encrypted)).to.equal(expectedType); const message = await openpgp.readMessage({ - armoredMessage: stream[expectedType === 'node' ? 'webToNode' : global.ReadableStream === stream.ReadableStream ? 'toStream' : 'toNativeReadable'](stream.transform(encrypted, value => { + armoredMessage: stream[expectedType === 'node' ? 'webToNode' : 'toStream'](stream.transform(encrypted, value => { value += ''; if (value === '=' || value.length === 5) return; // Remove checksum const newlineIndex = value.indexOf('\n', 500); @@ -461,7 +462,7 @@ function tests() { expect(stream.isStream(encrypted)).to.equal(expectedType); const message = await openpgp.readMessage({ - armoredMessage: stream[expectedType === 'node' ? 'webToNode' : global.ReadableStream === stream.ReadableStream ? 'toStream' : 'toNativeReadable'](stream.transform(encrypted, value => { + armoredMessage: stream[expectedType === 'node' ? 'webToNode' : 'toStream'](stream.transform(encrypted, value => { value += ''; const newlineIndex = value.indexOf('\n', 500); if (value.length > 1000) return value.slice(0, newlineIndex - 1) + (value[newlineIndex - 1] === 'a' ? 'b' : 'a') + value.slice(newlineIndex); @@ -498,7 +499,7 @@ function tests() { expect(stream.isStream(encrypted)).to.equal(expectedType); const message = await openpgp.readMessage({ - armoredMessage: stream[expectedType === 'node' ? 'webToNode' : global.ReadableStream === stream.ReadableStream ? 'toStream' : 'toNativeReadable'](stream.transform(encrypted, value => { + armoredMessage: stream[expectedType === 'node' ? 'webToNode' : 'toStream'](stream.transform(encrypted, value => { value += ''; const newlineIndex = value.indexOf('\n', 500); if (value.length > 1000) return value.slice(0, newlineIndex - 1) + (value[newlineIndex - 1] === 'a' ? 'b' : 'a') + value.slice(newlineIndex); @@ -531,7 +532,7 @@ function tests() { expect(stream.isStream(signed)).to.equal(expectedType); const message = await openpgp.readMessage({ - armoredMessage: stream[expectedType === 'node' ? 'webToNode' : global.ReadableStream === stream.ReadableStream ? 'toStream' : 'toNativeReadable'](stream.transform(signed, value => { + armoredMessage: stream[expectedType === 'node' ? 'webToNode' : 'toStream'](stream.transform(signed, value => { value += ''; const newlineIndex = value.indexOf('\n', 500); if (value.length > 1000) return value.slice(0, newlineIndex - 1) + (value[newlineIndex - 1] === 'a' ? 'b' : 'a') + value.slice(newlineIndex); @@ -956,7 +957,7 @@ module.exports = () => describe('Streaming', function() { passphrase: 'hello world' }); - await stream.loadStreamsPonyfill(); + loadStreamsPolyfill(); }); beforeEach(function() { diff --git a/test/unittests.js b/test/unittests.js index b8e43a1e..3b28d989 100644 --- a/test/unittests.js +++ b/test/unittests.js @@ -26,6 +26,10 @@ const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp } }; +(typeof window !== 'undefined' ? window : global).loadStreamsPolyfill = function() { + require('web-streams-polyfill/es2018'); // eslint-disable-line import/no-unassigned-import +}; + describe('Unit Tests', function () { openpgp.config.s2kIterationCountByte = 0; From 95c73738fabdc8986e21715c3d29478c60bcc9ef Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Fri, 2 Sep 2022 22:24:11 +0200 Subject: [PATCH 003/201] Update ESLint globals syntax --- test/general/brainpool.js | 2 +- test/general/key.js | 2 +- test/general/openpgp.js | 2 +- test/general/signature.js | 2 +- test/worker/application_worker.js | 2 +- test/worker/worker_example.js | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/general/brainpool.js b/test/general/brainpool.js index c432b766..fbcc9b94 100644 --- a/test/general/brainpool.js +++ b/test/general/brainpool.js @@ -1,4 +1,4 @@ -/* globals tryTests: true */ +/* globals tryTests */ const { use: chaiUse, expect } = require('chai'); chaiUse(require('chai-as-promised')); diff --git a/test/general/key.js b/test/general/key.js index c75aaa3e..7bf66805 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -1,5 +1,5 @@ /* eslint-disable max-lines */ -/* globals tryTests: true */ +/* globals tryTests */ const { use: chaiUse, expect } = require('chai'); chaiUse(require('chai-as-promised')); diff --git a/test/general/openpgp.js b/test/general/openpgp.js index cfebc1e0..1ae43b01 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -1,5 +1,5 @@ /* eslint-disable max-lines */ -/* globals tryTests: true, loadStreamsPolyfill */ +/* globals tryTests, loadStreamsPolyfill */ const spy = require('sinon/lib/sinon/spy'); const stream = require('@openpgp/web-stream-tools'); const { use: chaiUse, expect } = require('chai'); diff --git a/test/general/signature.js b/test/general/signature.js index 5c123d7c..75468fb8 100644 --- a/test/general/signature.js +++ b/test/general/signature.js @@ -1,5 +1,5 @@ /* eslint-disable max-lines */ -/* globals tryTests: true, loadStreamsPolyfill */ +/* globals tryTests, loadStreamsPolyfill */ const stream = require('@openpgp/web-stream-tools'); const { use: chaiUse, expect } = require('chai'); chaiUse(require('chai-as-promised')); diff --git a/test/worker/application_worker.js b/test/worker/application_worker.js index 0d096613..cbd1fa94 100644 --- a/test/worker/application_worker.js +++ b/test/worker/application_worker.js @@ -1,4 +1,4 @@ -/* globals tryTests: true */ +/* globals tryTests */ const { expect } = require('chai'); diff --git a/test/worker/worker_example.js b/test/worker/worker_example.js index b5b76341..fbd2cee1 100644 --- a/test/worker/worker_example.js +++ b/test/worker/worker_example.js @@ -1,4 +1,4 @@ -/* globals openpgp: true */ +/* globals openpgp */ importScripts('../../dist/openpgp.js'); From e1ba0b23737db149e4dadbda88864b98b6b90440 Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Fri, 2 Sep 2022 22:24:54 +0200 Subject: [PATCH 004/201] Use globalThis for setting test helper functions globals --- test/unittests.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/unittests.js b/test/unittests.js index 3b28d989..4bf00069 100644 --- a/test/unittests.js +++ b/test/unittests.js @@ -2,15 +2,15 @@ const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp (typeof window !== 'undefined' ? window : global).globalThis = (typeof window !== 'undefined' ? window : global); -(typeof window !== 'undefined' ? window : global).resolves = function(val) { +globalThis.resolves = function(val) { return new Promise(function(res) { res(val); }); }; -(typeof window !== 'undefined' ? window : global).rejects = function(val) { +globalThis.rejects = function(val) { return new Promise(function(res, rej) { rej(val); }); }; -(typeof window !== 'undefined' ? window : global).tryTests = function(name, tests, options) { +globalThis.tryTests = function(name, tests, options) { if (options.if) { describe(name, function() { if (options.before) { before(options.before); } @@ -26,7 +26,7 @@ const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp } }; -(typeof window !== 'undefined' ? window : global).loadStreamsPolyfill = function() { +globalThis.loadStreamsPolyfill = function() { require('web-streams-polyfill/es2018'); // eslint-disable-line import/no-unassigned-import }; From 204f32791d2c8f1276bc302711dc402cb15c7955 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Mon, 3 Apr 2023 17:52:21 +0200 Subject: [PATCH 005/201] CI: temporarily enable for PRs to v6 branch --- .github/workflows/benchmark.yml | 2 +- .github/workflows/docs.yml | 2 +- .github/workflows/sop-test-suite.yml | 2 +- .github/workflows/tests.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 8f537a60..7f3482e3 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -2,7 +2,7 @@ name: Performance Regression Test on: pull_request: - branches: [main] + branches: [main, v6] jobs: benchmark: diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 0a9e8c96..b0bc6afd 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -4,7 +4,7 @@ on: push: branches: [main] pull_request: - branches: [main] + branches: [main, v6] jobs: lint: diff --git a/.github/workflows/sop-test-suite.yml b/.github/workflows/sop-test-suite.yml index 39f26c1a..cf1701b4 100644 --- a/.github/workflows/sop-test-suite.yml +++ b/.github/workflows/sop-test-suite.yml @@ -2,7 +2,7 @@ name: SOP interoperability test suite on: pull_request: - branches: [ main ] + branches: [ main, v6 ] jobs: diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index feed0fbe..c816f93e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -4,7 +4,7 @@ on: push: branches: [main] pull_request: - branches: [main] + branches: [main, v6] jobs: build: # cache both dist and tests (non-lightweight only), based on commit hash From ebf22f2ee716f6dceb613dc4a59fb69b29664afa Mon Sep 17 00:00:00 2001 From: larabr Date: Tue, 4 Apr 2023 14:22:13 +0200 Subject: [PATCH 006/201] `crypto-refresh`: add support for Argon2 S2K (#1597) In terms of API, this feature is backwards compatible, no breaking changes. However, since a Wasm module is loaded for the Argon2 computation, browser apps might need to make changes to their CSP policy in order to use the feature. Newly introduced config fields: - `config.s2kType` (defaulting to `enums.s2k.iterated`): s2k to use on password-based encryption as well as private key encryption; - `config.s2kArgon2Params` (defaulting to "uniformly safe settings" from Argon RFC): parameters to use on encryption when `config.s2kType` is set to `enums.s2k.argon2`; --- openpgp.d.ts | 10 ++ package-lock.json | 38 +++++++ package.json | 2 + rollup.config.js | 31 ++++-- src/config/config.js | 33 +++++- src/enums.js | 1 + src/message.js | 4 + src/packet/secret_key.js | 11 +- src/packet/sym_encrypted_session_key.js | 9 +- src/type/s2k/argon2.js | 137 ++++++++++++++++++++++++ src/type/{s2k.js => s2k/generic.js} | 31 +++--- src/type/s2k/index.js | 46 ++++++++ test/general/openpgp.js | 64 +++++++++++ test/general/packet.js | 2 +- 14 files changed, 387 insertions(+), 32 deletions(-) create mode 100644 src/type/s2k/argon2.js rename src/type/{s2k.js => s2k/generic.js} (92%) create mode 100644 src/type/s2k/index.js diff --git a/openpgp.d.ts b/openpgp.d.ts index 56175b26..c161efac 100644 --- a/openpgp.d.ts +++ b/openpgp.d.ts @@ -332,7 +332,9 @@ interface Config { v5Keys: boolean; preferredAEADAlgorithm: enums.aead; aeadChunkSizeByte: number; + s2kType: enums.s2k.iterated | enums.s2k.argon2; s2kIterationCountByte: number; + s2kArgon2Params: { passes: number, parallelism: number; memoryExponent: number; }; minBytesForWebCrypto: number; maxUserIDLength: number; knownNotations: string[]; @@ -909,4 +911,12 @@ export namespace enums { utf8 = 117, mime = 109 } + + enum s2k { + simple = 0, + salted = 1, + iterated = 3, + argon2 = 4, + gnu = 101 + } } diff --git a/package-lock.json b/package-lock.json index b568e01f..0e86bc5c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,9 @@ "@rollup/plugin-commonjs": "^11.1.0", "@rollup/plugin-node-resolve": "^7.1.3", "@rollup/plugin-replace": "^2.3.2", + "@rollup/plugin-wasm": "^6.1.2", "@types/chai": "^4.2.14", + "argon2id": "^1.0.1", "benchmark": "^2.1.4", "bn.js": "^4.11.8", "chai": "^4.3.6", @@ -693,6 +695,23 @@ "rollup": "^1.20.0 || ^2.0.0" } }, + "node_modules/@rollup/plugin-wasm": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-wasm/-/plugin-wasm-6.1.2.tgz", + "integrity": "sha512-YdrQ7zfnZ54Y+6raCev3tR1PrhQGxYKSTajGylhyP0oBacouuNo6KcNCk+pYKw9M98jxRWLFFca/udi76IDXzg==", + "dev": true, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, "node_modules/@rollup/pluginutils": { "version": "3.0.9", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.0.9.tgz", @@ -952,6 +971,12 @@ "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", "dev": true }, + "node_modules/argon2id": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/argon2id/-/argon2id-1.0.1.tgz", + "integrity": "sha512-rsiD3lX+0L0CsiZARp3bf9EGxprtuWAT7PpiJd+Fk53URV0/USOQkBIP1dLTV8t6aui0ECbymQ9W9YCcTd6XgA==", + "dev": true + }, "node_modules/argparse": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", @@ -7999,6 +8024,13 @@ "magic-string": "^0.25.5" } }, + "@rollup/plugin-wasm": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-wasm/-/plugin-wasm-6.1.2.tgz", + "integrity": "sha512-YdrQ7zfnZ54Y+6raCev3tR1PrhQGxYKSTajGylhyP0oBacouuNo6KcNCk+pYKw9M98jxRWLFFca/udi76IDXzg==", + "dev": true, + "requires": {} + }, "@rollup/pluginutils": { "version": "3.0.9", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.0.9.tgz", @@ -8214,6 +8246,12 @@ "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", "dev": true }, + "argon2id": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/argon2id/-/argon2id-1.0.1.tgz", + "integrity": "sha512-rsiD3lX+0L0CsiZARp3bf9EGxprtuWAT7PpiJd+Fk53URV0/USOQkBIP1dLTV8t6aui0ECbymQ9W9YCcTd6XgA==", + "dev": true + }, "argparse": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", diff --git a/package.json b/package.json index 6dc92a05..b48b07fc 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,9 @@ "@rollup/plugin-commonjs": "^11.1.0", "@rollup/plugin-node-resolve": "^7.1.3", "@rollup/plugin-replace": "^2.3.2", + "@rollup/plugin-wasm": "^6.1.2", "@types/chai": "^4.2.14", + "argon2id": "^1.0.1", "benchmark": "^2.1.4", "bn.js": "^4.11.8", "chai": "^4.3.6", diff --git a/rollup.config.js b/rollup.config.js index 6e1b5104..97656497 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -6,10 +6,25 @@ import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; import replace from '@rollup/plugin-replace'; import { terser } from 'rollup-plugin-terser'; +import { wasm } from '@rollup/plugin-wasm'; + import pkg from './package.json'; const nodeDependencies = Object.keys(pkg.dependencies); +const wasmOptions = { + node: { targetEnv: 'node' }, + browser: { targetEnv: 'browser', maxFileSize: undefined } // always inlline (our wasm files are small) +}; + +const getChunkFileName = (chunkInfo, extension) => { + // index files result in chunks named simply 'index', so we rename them to include the package name + if (chunkInfo.name === 'index') { + const packageName = chunkInfo.facadeModuleId.split('/').at(-2); // assume index file is under the root folder + return `${packageName}.${extension}`; + } + return `[name].${extension}`; +}; const banner = `/*! OpenPGP.js v${pkg.version} - ` + @@ -50,7 +65,8 @@ export default Object.assign([ 'OpenPGP.js VERSION': `OpenPGP.js ${pkg.version}`, 'require(': 'void(', delimiters: ['', ''] - }) + }), + wasm(wasmOptions.browser) ] }, { @@ -68,14 +84,15 @@ export default Object.assign([ commonjs(), replace({ 'OpenPGP.js VERSION': `OpenPGP.js ${pkg.version}` - }) + }), + wasm(wasmOptions.node) ] }, { input: 'src/index.js', output: [ - { dir: 'dist/lightweight', entryFileNames: 'openpgp.mjs', chunkFileNames: '[name].mjs', format: 'es', banner, intro }, - { dir: 'dist/lightweight', entryFileNames: 'openpgp.min.mjs', chunkFileNames: '[name].min.mjs', format: 'es', banner, intro, plugins: [terser(terserOptions)], sourcemap: true } + { dir: 'dist/lightweight', entryFileNames: 'openpgp.mjs', chunkFileNames: chunkInfo => getChunkFileName(chunkInfo, 'mjs'), format: 'es', banner, intro }, + { dir: 'dist/lightweight', entryFileNames: 'openpgp.min.mjs', chunkFileNames: chunkInfo => getChunkFileName(chunkInfo, 'min.mjs'), format: 'es', banner, intro, plugins: [terser(terserOptions)], sourcemap: true } ], preserveEntrySignatures: 'allow-extension', plugins: [ @@ -89,7 +106,8 @@ export default Object.assign([ 'OpenPGP.js VERSION': `OpenPGP.js ${pkg.version}`, 'require(': 'void(', delimiters: ['', ''] - }) + }), + wasm(wasmOptions.browser) ] }, { @@ -110,7 +128,8 @@ export default Object.assign([ "import openpgpjs from '../../..';": `import * as openpgpjs from '/dist/${process.env.npm_config_lightweight ? 'lightweight/' : ''}openpgp.mjs'; window.openpgp = openpgpjs;`, 'require(': 'void(', delimiters: ['', ''] - }) + }), + wasm(wasmOptions.browser) ] } ].filter(config => { diff --git a/src/config/config.js b/src/config/config.js index ccfee7e1..6f2baadb 100644 --- a/src/config/config.js +++ b/src/config/config.js @@ -76,12 +76,41 @@ export default { */ v5Keys: false, /** - * {@link https://tools.ietf.org/html/rfc4880#section-3.7.1.3|RFC4880 3.7.1.3}: - * Iteration Count Byte for S2K (String to Key) + * S2K (String to Key) type, used for key derivation in the context of secret key encryption + * and password-encrypted data. Weaker s2k options are not allowed. + * Note: Argon2 is the strongest option but not all OpenPGP implementations are compatible with it + * (pending standardisation). + * @memberof module:config + * @property {enums.s2k.argon2|enums.s2k.iterated} s2kType {@link module:enums.s2k} + */ + s2kType: enums.s2k.iterated, + /** + * {@link https://tools.ietf.org/html/rfc4880#section-3.7.1.3| RFC4880 3.7.1.3}: + * Iteration Count Byte for Iterated and Salted S2K (String to Key). + * Only relevant if `config.s2kType` is set to `enums.s2k.iterated`. + * Note: this is the exponent value, not the final number of iterations (refer to specs for more details). * @memberof module:config * @property {Integer} s2kIterationCountByte */ s2kIterationCountByte: 224, + /** + * {@link https://tools.ietf.org/html/draft-ietf-openpgp-crypto-refresh-07.html#section-3.7.1.4| draft-crypto-refresh 3.7.1.4}: + * Argon2 parameters for S2K (String to Key). + * Only relevant if `config.s2kType` is set to `enums.s2k.argon2`. + * Default settings correspond to the second recommendation from RFC9106 ("uniformly safe option"), + * to ensure compatibility with memory-constrained environments. + * For more details on the choice of parameters, see https://tools.ietf.org/html/rfc9106#section-4. + * @memberof module:config + * @property {Object} params + * @property {Integer} params.passes - number of iterations t + * @property {Integer} params.parallelism - degree of parallelism p + * @property {Integer} params.memoryExponent - one-octet exponent indicating the memory size, which will be: 2**memoryExponent kibibytes. + */ + s2kArgon2Params: { + passes: 3, + parallelism: 4, // lanes + memoryExponent: 16 // 64 MiB of RAM + }, /** * Allow decryption of messages without integrity protection. * This is an **insecure** setting: diff --git a/src/enums.js b/src/enums.js index 220ed807..33982062 100644 --- a/src/enums.js +++ b/src/enums.js @@ -91,6 +91,7 @@ export default { simple: 0, salted: 1, iterated: 3, + argon2: 4, gnu: 101 }, diff --git a/src/message.js b/src/message.js index ce922dcc..5a88e7b0 100644 --- a/src/message.js +++ b/src/message.js @@ -18,6 +18,7 @@ import * as stream from '@openpgp/web-stream-tools'; import { armor, unarmor } from './encoding/armor'; import KeyID from './type/keyid'; +import { Argon2OutOfMemoryError } from './type/s2k'; import defaultConfig from './config'; import crypto from './crypto'; import enums from './enums'; @@ -183,6 +184,9 @@ export class Message { decryptedSessionKeyPackets.push(skeskPacket); } catch (err) { util.printDebugError(err); + if (err instanceof Argon2OutOfMemoryError) { + exception = err; + } } })); })); diff --git a/src/packet/secret_key.js b/src/packet/secret_key.js index a0df643a..cab07335 100644 --- a/src/packet/secret_key.js +++ b/src/packet/secret_key.js @@ -16,7 +16,7 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA import PublicKeyPacket from './public_key'; -import S2K from '../type/s2k'; +import { newS2KFromConfig, newS2KFromType } from '../type/s2k'; import crypto from '../crypto'; import enums from '../enums'; import util from '../util'; @@ -115,7 +115,8 @@ class SecretKeyPacket extends PublicKeyPacket { // - [Optional] If string-to-key usage octet was 255, 254, or 253, a // string-to-key specifier. The length of the string-to-key // specifier is implied by its type, as described above. - this.s2k = new S2K(); + const s2kType = bytes[i++]; + this.s2k = newS2KFromType(s2kType); i += this.s2k.read(bytes.subarray(i, bytes.length)); if (this.s2k.type === 'gnu-dummy') { @@ -279,7 +280,7 @@ class SecretKeyPacket extends PublicKeyPacket { delete this.unparseableKeyMaterial; this.isEncrypted = null; this.keyMaterial = null; - this.s2k = new S2K(config); + this.s2k = newS2KFromType(enums.s2k.gnu, config); this.s2k.algorithm = 0; this.s2k.c = 0; this.s2k.type = 'gnu-dummy'; @@ -310,8 +311,8 @@ class SecretKeyPacket extends PublicKeyPacket { throw new Error('A non-empty passphrase is required for key encryption.'); } - this.s2k = new S2K(config); - this.s2k.salt = crypto.random.getRandomBytes(8); + this.s2k = newS2KFromConfig(config); + this.s2k.generateSalt(); const cleartext = crypto.serializeParams(this.algorithm, this.privateParams); this.symmetric = enums.symmetric.aes256; const key = await produceEncryptionKey(this.s2k, passphrase, this.symmetric); diff --git a/src/packet/sym_encrypted_session_key.js b/src/packet/sym_encrypted_session_key.js index a383c711..6e940779 100644 --- a/src/packet/sym_encrypted_session_key.js +++ b/src/packet/sym_encrypted_session_key.js @@ -15,7 +15,7 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -import S2K from '../type/s2k'; +import { newS2KFromConfig, newS2KFromType } from '../type/s2k'; import defaultConfig from '../config'; import crypto from '../crypto'; import enums from '../enums'; @@ -89,7 +89,8 @@ class SymEncryptedSessionKeyPacket { } // A string-to-key (S2K) specifier, length as defined above. - this.s2k = new S2K(); + const s2kType = bytes[offset++]; + this.s2k = newS2KFromType(s2kType); offset += this.s2k.read(bytes.subarray(offset, bytes.length)); if (this.version === 5) { @@ -178,8 +179,8 @@ class SymEncryptedSessionKeyPacket { this.sessionKeyEncryptionAlgorithm = algo; - this.s2k = new S2K(config); - this.s2k.salt = crypto.random.getRandomBytes(8); + this.s2k = newS2KFromConfig(config); + this.s2k.generateSalt(); const { blockSize, keySize } = crypto.getCipher(algo); const encryptionKey = await this.s2k.produceKey(passphrase, keySize); diff --git a/src/type/s2k/argon2.js b/src/type/s2k/argon2.js new file mode 100644 index 00000000..f79e3ef6 --- /dev/null +++ b/src/type/s2k/argon2.js @@ -0,0 +1,137 @@ +import defaultConfig from '../../config'; +import enums from '../../enums'; +import util from '../../util'; +import crypto from '../../crypto'; + +const ARGON2_TYPE = 0x02; // id +const ARGON2_VERSION = 0x13; +const ARGON2_SALT_SIZE = 16; + +export class Argon2OutOfMemoryError extends Error { + constructor(...params) { + super(...params); + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, Argon2OutOfMemoryError); + } + + this.name = 'Argon2OutOfMemoryError'; + } +} + +// cache argon wasm module +let loadArgonWasmModule; +let argon2Promise; +// reload wasm module above this treshold, to deallocated used memory +const ARGON2_WASM_MEMORY_THRESHOLD_RELOAD = 2 << 19; + +class Argon2S2K { + /** + * @param {Object} [config] - Full configuration, defaults to openpgp.config + */ + constructor(config = defaultConfig) { + const { passes, parallelism, memoryExponent } = config.s2kArgon2Params; + + this.type = 'argon2'; + /** @type {Uint8Array} 16 bytes of salt */ + this.salt = null; + /** @type {Integer} number of passes */ + this.t = passes; + /** @type {Integer} degree of parallelism (lanes) */ + this.p = parallelism; + /** @type {Integer} exponent indicating memory size */ + this.encodedM = memoryExponent; + } + + generateSalt() { + this.salt = crypto.random.getRandomBytes(ARGON2_SALT_SIZE); + } + + /** + * Parsing function for argon2 string-to-key specifier. + * @param {Uint8Array} bytes - Payload of argon2 string-to-key specifier + * @returns {Integer} Actual length of the object. + */ + read(bytes) { + let i = 0; + + this.salt = bytes.subarray(i, i + 16); + i += 16; + + this.t = bytes[i++]; + this.p = bytes[i++]; + this.encodedM = bytes[i++]; // memory size exponent, one-octect + + return i; + } + + /** + * Serializes s2k information + * @returns {Uint8Array} Binary representation of s2k. + */ + write() { + const arr = [ + new Uint8Array([enums.write(enums.s2k, this.type)]), + this.salt, + new Uint8Array([this.t, this.p, this.encodedM]) + ]; + + return util.concatUint8Array(arr); + } + + /** + * Produces a key using the specified passphrase and the defined + * hashAlgorithm + * @param {String} passphrase - Passphrase containing user input + * @returns {Promise} Produced key with a length corresponding to `keySize` + * @throws {Argon2OutOfMemoryError|Errors} + * @async + */ + async produceKey(passphrase, keySize) { + const decodedM = 2 << (this.encodedM - 1); + + try { + // on first load, the argon2 lib is imported and the WASM module is initialized. + // the two steps need to be atomic to avoid race conditions causing multiple wasm modules + // being loaded when `argon2Promise` is not initialized. + loadArgonWasmModule = loadArgonWasmModule || (await import('argon2id')).default; + argon2Promise = argon2Promise || loadArgonWasmModule(); + + // important to keep local ref to argon2 in case the module is reloaded by another instance + const argon2 = await argon2Promise; + + const passwordBytes = util.encodeUTF8(passphrase); + const hash = argon2({ + version: ARGON2_VERSION, + type: ARGON2_TYPE, + password: passwordBytes, + salt: this.salt, + tagLength: keySize, + memorySize: decodedM, + parallelism: this.p, + passes: this.t + }); + + // a lot of memory was used, reload to deallocate + if (decodedM > ARGON2_WASM_MEMORY_THRESHOLD_RELOAD) { + // it will be awaited if needed at the next `produceKey` invocation + argon2Promise = loadArgonWasmModule(); + argon2Promise.catch(() => {}); + } + return hash; + } catch (e) { + if (e.message && ( + e.message.includes('Unable to grow instance memory') || // Chrome + e.message.includes('failed to grow memory') || // Firefox + e.message.includes('WebAssembly.Memory.grow') || // Safari + e.message.includes('Out of memory') // Safari iOS + )) { + throw new Argon2OutOfMemoryError('Could not allocate required memory for Argon2'); + } else { + throw e; + } + } + } +} + +export default Argon2S2K; diff --git a/src/type/s2k.js b/src/type/s2k/generic.js similarity index 92% rename from src/type/s2k.js rename to src/type/s2k/generic.js index 250c7e25..ab9b2855 100644 --- a/src/type/s2k.js +++ b/src/type/s2k/generic.js @@ -28,17 +28,17 @@ * @private */ -import defaultConfig from '../config'; -import crypto from '../crypto'; -import enums from '../enums'; -import { UnsupportedError } from '../packet/packet'; -import util from '../util'; +import defaultConfig from '../../config'; +import crypto from '../../crypto'; +import enums from '../../enums'; +import { UnsupportedError } from '../../packet/packet'; +import util from '../../util'; -class S2K { +class GenericS2K { /** * @param {Object} [config] - Full configuration, defaults to openpgp.config */ - constructor(config = defaultConfig) { + constructor(s2kType, config = defaultConfig) { /** * Hash function identifier, or 0 for gnu-dummy keys * @type {module:enums.hash | 0} @@ -48,7 +48,7 @@ class S2K { * enums.s2k identifier or 'gnu-dummy' * @type {String} */ - this.type = 'iterated'; + this.type = enums.read(enums.s2k, s2kType); /** @type {Integer} */ this.c = config.s2kIterationCountByte; /** Eight bytes of salt in a binary string. @@ -57,6 +57,14 @@ class S2K { this.salt = null; } + generateSalt() { + switch (this.type) { + case 'salted': + case 'iterated': + this.salt = crypto.random.getRandomBytes(8); + } + } + getCount() { // Exponent bias, defined in RFC4880 const expbias = 6; @@ -71,11 +79,6 @@ class S2K { */ read(bytes) { let i = 0; - try { - this.type = enums.read(enums.s2k, bytes[i++]); - } catch (err) { - throw new UnsupportedError('Unknown S2K type.'); - } this.algorithm = bytes[i++]; switch (this.type) { @@ -196,4 +199,4 @@ class S2K { } } -export default S2K; +export default GenericS2K; diff --git a/src/type/s2k/index.js b/src/type/s2k/index.js new file mode 100644 index 00000000..8a725c18 --- /dev/null +++ b/src/type/s2k/index.js @@ -0,0 +1,46 @@ +import defaultConfig from '../../config'; +import Argon2S2K, { Argon2OutOfMemoryError } from './argon2'; +import GenericS2K from './generic'; +import enums from '../../enums'; +import { UnsupportedError } from '../../packet/packet'; + +const allowedS2KTypesForEncryption = new Set([enums.s2k.argon2, enums.s2k.iterated]); + +/** + * Instantiate a new S2K instance of the given type + * @param {module:enums.s2k} type + * @oaram {Object} [config] + * @returns {Object} New s2k object + * @throws {Error} for unknown or unsupported types + */ +export function newS2KFromType(type, config = defaultConfig) { + switch (type) { + case enums.s2k.argon2: + return new Argon2S2K(config); + case enums.s2k.iterated: + case enums.s2k.gnu: + case enums.s2k.salted: + case enums.s2k.simple: + return new GenericS2K(type, config); + default: + throw new UnsupportedError('Unsupported S2K type'); + } +} + +/** + * Instantiate a new S2K instance based on the config settings + * @oaram {Object} config + * @returns {Object} New s2k object + * @throws {Error} for unknown or unsupported types + */ +export function newS2KFromConfig(config) { + const { s2kType } = config; + + if (!allowedS2KTypesForEncryption.has(s2kType)) { + throw new Error('The provided `config.s2kType` value is not allowed'); + } + + return newS2KFromType(s2kType, config); +} + +export { Argon2OutOfMemoryError }; diff --git a/test/general/openpgp.js b/test/general/openpgp.js index 1ae43b01..f03f13b5 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -15,6 +15,7 @@ const { isAEADSupported } = require('../../src/key'); const input = require('./testInputs'); const detectNode = () => typeof globalThis.process === 'object' && typeof globalThis.process.versions === 'object'; +const detectBrowser = () => typeof navigator === 'object'; const pub_key = [ '-----BEGIN PGP PUBLIC KEY BLOCK-----', @@ -1243,6 +1244,25 @@ VFBLG8uc9IiaKann/DYBAJcZNZHRSfpDoV2pUA5EAEi2MdjxkRysFQnYPRAu expect(unlocked.isDecrypted()).to.be.true; }); + it('should support encrypting with argon2 s2k', async function() { + const key = await openpgp.readKey({ armoredKey: gnuDummyKeySigningSubkey }); + const locked = await openpgp.encryptKey({ + privateKey: key, + passphrase: passphrase, + config: { s2kType: openpgp.enums.s2k.argon2 } + }); + expect(key.isDecrypted()).to.be.true; + expect(locked.isDecrypted()).to.be.false; + expect(locked.keyPacket.isDummy()).to.be.true; + const unlocked = await openpgp.decryptKey({ + privateKey: locked, + passphrase: passphrase + }); + expect(key.isDecrypted()).to.be.true; + expect(unlocked.isDecrypted()).to.be.true; + expect(unlocked.keyPacket.isDummy()).to.be.true; + }); + it('should encrypt gnu-dummy key', async function() { const key = await openpgp.readKey({ armoredKey: gnuDummyKeySigningSubkey }); const locked = await openpgp.encryptKey({ @@ -2150,6 +2170,50 @@ VFBLG8uc9IiaKann/DYBAJcZNZHRSfpDoV2pUA5EAEi2MdjxkRysFQnYPRAu data: util.hexToUint8Array('3e99c1bb485e70a1fcef09a7ad8d38d171015243bbdd853e1a2b0e334d122ff3') })).to.be.rejectedWith(/No encryption keys or passwords provided/); }); + + it('supports decrypting with argon2 s2k (memory-heavy params)', async function() { + const passwords = 'password'; + // Test vector from https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#appendix-A.8.1 + const armoredMessage = `-----BEGIN PGP MESSAGE----- +Comment: Encrypted using AES with 128-bit key +Comment: Session key: 01FE16BBACFD1E7B78EF3B865187374F + +wycEBwScUvg8J/leUNU1RA7N/zE2AQQVnlL8rSLPP5VlQsunlO+ECxHSPgGYGKY+ +YJz4u6F+DDlDBOr5NRQXt/KJIf4m4mOlKyC/uqLbpnLJZMnTq3o79GxBTdIdOzhH +XfA3pqV4mTzF +-----END PGP MESSAGE-----`; + const expectedSessionKey = util.hexToUint8Array('01FE16BBACFD1E7B78EF3B865187374F'); + + try { + const [decryptedSessionKey] = await openpgp.decryptSessionKeys({ + message: await openpgp.readMessage({ armoredMessage }), + passwords + }); + expect(decryptedSessionKey.data).to.deep.equal(expectedSessionKey); + expect(decryptedSessionKey.algorithm).to.equal('aes128'); + } catch (err) { + if (detectBrowser()) { // Expected to fail in the CI, especially in Browserstack + expect(err.message).to.match(/Could not allocate required memory/); + } + } + + }); + + // keep this after the 'memory-heavy' test to confirm that the Wasm module was successfully reloaded + it('supports encrypting with argon2 s2k', async function() { + const config = { s2kType: openpgp.enums.s2k.argon2 }; + const passwords = 'password'; + const sessionKey = { + algorithm: 'aes128', + data: util.hexToUint8Array('01FE16BBACFD1E7B78EF3B865187374F') + }; + const encrypted = await openpgp.encryptSessionKey({ ...sessionKey, passwords, config, format: 'object' }); + expect(encrypted.packets).to.have.length(1); + const skesk = encrypted.packets[0]; + expect(skesk.s2k.type).to.equal('argon2'); + const [decryptedSessionKey] = await openpgp.decryptSessionKeys({ message: encrypted, passwords }); + expect(decryptedSessionKey).to.deep.equal(sessionKey); + }); }); describe('encrypt, decrypt, sign, verify - integration tests', function() { diff --git a/test/general/packet.js b/test/general/packet.js index 212e874f..8fd963ac 100644 --- a/test/general/packet.js +++ b/test/general/packet.js @@ -1042,7 +1042,7 @@ kePFjAnu9cpynKXu3usf8+FuBw2zLsg1Id1n7ttxoAte416KjBN9lFBt8mcu await expect( openpgp.PacketList.fromBinary(binaryMessage, allAllowedPackets, { ...openpgp.config, ignoreUnsupportedPackets: false }) - ).to.be.rejectedWith(/Unknown S2K type/); + ).to.be.rejectedWith(/Unsupported S2K type/); }); it('Throws on disallowed packet even with tolerant mode enabled', async function() { From 3520a357f58f85823b3d92faed84a6236c379e16 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Tue, 4 Apr 2023 14:32:39 +0200 Subject: [PATCH 007/201] CI: drop Node 14 --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index c816f93e..4c55e991 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -30,7 +30,7 @@ jobs: node: strategy: matrix: - node-version: [14.x, 16.x, 18.x, 20.x] + node-version: [16.x, 18.x, '20.x'] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ name: Node ${{ matrix.node-version }} From d49d92e5cb45b262053cc3d4e6f570ba58eebacd Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Tue, 9 May 2023 18:45:46 +0200 Subject: [PATCH 008/201] Update to Mocha v10 in tests, declare lib as `module` and add `exports` to package.json Mocha v10 requires the lib to be esm compliant. ESM mandates the use of file extensions in imports, so to minimize the changes (for now), we rely on the flag `experimental-specifier-resolution=node` and on `ts-node` (needed only for Node 20). Breaking changes: downstream bundlers might be affected by the package.json changes depending on how they load the library. NB: legacy package.json entrypoints are still available. --- .jsdocrc.js => .jsdocrc.cjs | 0 .mocharc.json | 6 + lightweight/package.json | 2 +- package-lock.json | 2267 ++++++++++++--------- package.json | 55 +- rollup.config.js | 35 +- src/crypto/cmac.js | 1 - src/crypto/mode/eax.js | 1 - src/crypto/mode/index.js | 1 - src/crypto/public_key/elliptic/ecdsa.js | 2 +- src/crypto/public_key/rsa.js | 2 +- src/key/subkey.js | 1 - src/util.js | 11 +- test/benchmarks/memory_usage.js | 16 +- test/benchmarks/time.js | 4 +- test/crypto/aes_kw.js | 8 +- test/crypto/cipher/aes.js | 6 +- test/crypto/cipher/blowfish.js | 8 +- test/crypto/cipher/cast5.js | 8 +- test/crypto/cipher/des.js | 8 +- test/crypto/cipher/index.js | 18 +- test/crypto/cipher/twofish.js | 8 +- test/crypto/crypto.js | 15 +- test/crypto/eax.js | 15 +- test/crypto/ecdh.js | 23 +- test/crypto/elliptic.js | 21 +- test/crypto/elliptic_data.js | 2 +- test/crypto/gcm.js | 15 +- test/crypto/hash/index.js | 12 +- test/crypto/hash/md5.js | 8 +- test/crypto/hash/ripemd.js | 16 +- test/crypto/hash/sha.js | 8 +- test/crypto/hkdf.js | 13 +- test/crypto/index.js | 42 +- test/crypto/ocb.js | 13 +- test/crypto/pkcs5.js | 6 +- test/crypto/rsa.js | 17 +- test/crypto/validate.js | 11 +- test/general/armor.js | 7 +- test/general/biginteger.js | 13 +- test/general/brainpool.js | 13 +- test/general/config.js | 6 +- test/general/decompression.js | 9 +- test/general/ecc_nist.js | 13 +- test/general/ecc_secp256k1.js | 11 +- test/general/index.js | 49 +- test/general/key.js | 15 +- test/general/oid.js | 8 +- test/general/openpgp.js | 33 +- test/general/packet.js | 19 +- test/general/signature.js | 23 +- test/general/streaming.js | 27 +- test/general/testInputs.js | 4 +- test/general/util.js | 7 +- test/general/x25519.js | 22 +- test/{karma.conf.js => karma.conf.cjs} | 0 test/security/index.js | 15 +- test/security/message_signature_bypass.js | 11 +- test/security/preferred_algo_mismatch.js | 9 +- test/security/subkey_trust.js | 10 +- test/security/unsigned_subpackets.js | 10 +- test/typescript/definitions.ts | 2 +- test/unittests.js | 19 +- test/worker/application_worker.js | 5 +- test/worker/index.js | 6 +- tsconfig.json | 12 +- 66 files changed, 1710 insertions(+), 1373 deletions(-) rename .jsdocrc.js => .jsdocrc.cjs (100%) create mode 100644 .mocharc.json rename test/{karma.conf.js => karma.conf.cjs} (100%) diff --git a/.jsdocrc.js b/.jsdocrc.cjs similarity index 100% rename from .jsdocrc.js rename to .jsdocrc.cjs diff --git a/.mocharc.json b/.mocharc.json new file mode 100644 index 00000000..7b963c2d --- /dev/null +++ b/.mocharc.json @@ -0,0 +1,6 @@ +{ + "node-option": [ + "experimental-specifier-resolution=node", + "loader=ts-node/esm" + ] +} diff --git a/lightweight/package.json b/lightweight/package.json index 134e03c9..c141a35d 100644 --- a/lightweight/package.json +++ b/lightweight/package.json @@ -1,5 +1,5 @@ { "name": "openpgp-lightweight", - "main": "../dist/lightweight/openpgp.min.mjs", + "browser": "../dist/lightweight/openpgp.min.mjs", "types": "../openpgp.d.ts" } diff --git a/package-lock.json b/package-lock.json index 0e86bc5c..676a4bb7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,20 +14,22 @@ "devDependencies": { "@openpgp/asmcrypto.js": "^2.3.2", "@openpgp/elliptic": "^6.5.1", - "@openpgp/jsdoc": "^3.6.4", + "@openpgp/jsdoc": "^3.6.11", "@openpgp/pako": "^1.0.12", "@openpgp/seek-bzip": "^1.0.5-git", "@openpgp/tweetnacl": "^1.0.3", - "@openpgp/web-stream-tools": "^0.0.13", - "@rollup/plugin-commonjs": "^11.1.0", - "@rollup/plugin-node-resolve": "^7.1.3", - "@rollup/plugin-replace": "^2.3.2", + "@openpgp/web-stream-tools": "^0.0.14", + "@rollup/plugin-alias": "^5.0.0", + "@rollup/plugin-commonjs": "^24.0.1", + "@rollup/plugin-node-resolve": "^15.0.1", + "@rollup/plugin-replace": "^5.0.2", + "@rollup/plugin-terser": "^0.4.0", "@rollup/plugin-wasm": "^6.1.2", "@types/chai": "^4.2.14", "argon2id": "^1.0.1", "benchmark": "^2.1.4", "bn.js": "^4.11.8", - "chai": "^4.3.6", + "chai": "^4.3.7", "chai-as-promised": "^7.1.1", "email-addresses": "3.1.0", "eslint": "^8.34.0", @@ -35,7 +37,6 @@ "eslint-config-airbnb-base": "^15.0.0", "eslint-plugin-chai-friendly": "^0.7.2", "eslint-plugin-import": "^2.27.5", - "esm": "^3.2.25", "hash.js": "^1.1.3", "http-server": "^14.1.1", "karma": "^6.4.0", @@ -45,12 +46,12 @@ "karma-mocha": "^2.0.1", "karma-mocha-reporter": "^2.2.5", "karma-webkit-launcher": "^2.1.0", - "mocha": "^8.4.0", + "mocha": "^10.2.0", "nyc": "^14.1.1", "playwright": "^1.30.0", - "rollup": "^2.38.5", - "rollup-plugin-terser": "^7.0.2", + "rollup": "^2.79.1", "sinon": "^4.3.0", + "ts-node": "^10.9.1", "typescript": "^4.1.2", "web-streams-polyfill": "^3.2.0" }, @@ -59,70 +60,108 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", - "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", + "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", "dev": true, "dependencies": { - "@babel/highlight": "^7.8.3" + "@babel/highlight": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/generator": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", - "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.5.tgz", + "integrity": "sha512-SrKK/sRv8GesIW1bDagf9cCG38IOMYZusoe1dfg0D8aiUe3Amvoj1QtjTPAWcfrZFvIwlleLb0gxzQidL9w14w==", "dev": true, "dependencies": { - "@babel/types": "^7.9.6", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" + "@babel/types": "^7.21.5", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.21.5.tgz", + "integrity": "sha512-IYl4gZ3ETsWocUWgsFZLM5i1BYx9SoemminVEXadgLBa9TdeorzgLKm8wWLA6J1N/kT3Kch8XIk1laNzYoHKvQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", - "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", + "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", "dev": true, "dependencies": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.9.5" + "@babel/template": "^7.20.7", + "@babel/types": "^7.21.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@babel/helper-get-function-arity": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", - "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "node_modules/@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", "dev": true, "dependencies": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", - "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", "dev": true, "dependencies": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.21.5.tgz", + "integrity": "sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==", + "dev": true, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", - "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", - "dev": true + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, "node_modules/@babel/highlight": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", - "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "dev": true, "dependencies": { + "@babel/helper-validator-identifier": "^7.18.6", "chalk": "^2.0.0", - "esutils": "^2.0.2", "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/highlight/node_modules/ansi-styles": { @@ -151,12 +190,6 @@ "node": ">=4" } }, - "node_modules/@babel/highlight/node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, "node_modules/@babel/highlight/node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -170,9 +203,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", - "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", + "version": "7.21.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.8.tgz", + "integrity": "sha512-6zavDGdzG3gUqAdWvlLFfk+36RilI+Pwyuuh7HItyeScCWP3k6i8vKclAQ0bM/0y/Kz/xiwvxhMv9MgTJP5gmA==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -209,31 +242,38 @@ } }, "node_modules/@babel/template": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", - "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.6", - "@babel/types": "^7.8.6" + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", - "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.5.tgz", + "integrity": "sha512-AhQoI3YjWi6u/y/ntv7k48mcrCXmus0t79J9qPNlk/lAsFlCiJ047RmbfMOawySTHtywXhbXgpx/8nXMYd+oFw==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.6", - "@babel/helper-function-name": "^7.9.5", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.9.6", - "@babel/types": "^7.9.6", + "@babel/code-frame": "^7.21.4", + "@babel/generator": "^7.21.5", + "@babel/helper-environment-visitor": "^7.21.5", + "@babel/helper-function-name": "^7.21.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.21.5", + "@babel/types": "^7.21.5", "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/traverse/node_modules/debug": { @@ -253,14 +293,17 @@ "dev": true }, "node_modules/@babel/types": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", - "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.5.tgz", + "integrity": "sha512-m4AfNvVF2mVC/F7fDEdH2El3HzUg9It/XsCxZiOTTA3m3qYfcSVSbTfM6Q9xG+hYDniZssYhlXKKUMD5m8tF4Q==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.9.5", - "lodash": "^4.17.13", + "@babel/helper-string-parser": "^7.21.5", + "@babel/helper-validator-identifier": "^7.19.1", "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@colors/colors": { @@ -272,6 +315,28 @@ "node": ">=0.1.90" } }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "node_modules/@eslint/eslintrc": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", @@ -546,31 +611,32 @@ } }, "node_modules/@openpgp/jsdoc": { - "version": "3.6.4", - "resolved": "https://registry.npmjs.org/@openpgp/jsdoc/-/jsdoc-3.6.4.tgz", - "integrity": "sha512-PR4NtdOVev7wbUYe4/T0CeLDAr0qxDthBqUrqngKIHn6h+m9fgRz20vH5OBalIVYaDeHcUcxdwGbEFRT30/WSg==", + "version": "3.6.11", + "resolved": "https://registry.npmjs.org/@openpgp/jsdoc/-/jsdoc-3.6.11.tgz", + "integrity": "sha512-mwvKQrW9raTU4CM3Oa93deRPh3TknFL0PUaGJWXwk3Inqf5nT8x4Z867ctqKYPekqw9FdDGyTaGb4rkbyPl9fA==", "dev": true, "dependencies": { "@babel/parser": "^7.9.4", + "@types/markdown-it": "^12.2.3", "bluebird": "^3.7.2", - "catharsis": "^0.8.11", + "catharsis": "^0.9.0", "escape-string-regexp": "^2.0.0", - "js2xmlparser": "^4.0.1", + "js2xmlparser": "^4.0.2", "klaw": "^3.0.0", - "markdown-it": "^10.0.0", - "markdown-it-anchor": "^5.2.7", - "marked": "^0.8.2", + "markdown-it": "^12.3.2", + "markdown-it-anchor": "^8.4.1", + "marked": "^4.0.10", "mkdirp": "^1.0.4", "requizzle": "^0.2.3", "strip-json-comments": "^3.1.0", "taffydb": "2.6.2", - "underscore": "~1.10.2" + "underscore": "~1.13.2" }, "bin": { "jsdoc": "jsdoc.js" }, "engines": { - "node": ">=8.15.0" + "node": ">=12.0.0" } }, "node_modules/@openpgp/jsdoc/node_modules/escape-string-regexp": { @@ -620,9 +686,9 @@ "dev": true }, "node_modules/@openpgp/web-stream-tools": { - "version": "0.0.13", - "resolved": "https://registry.npmjs.org/@openpgp/web-stream-tools/-/web-stream-tools-0.0.13.tgz", - "integrity": "sha512-VQ0O0lUcD9ilLcMLQMJMgPhp8fDgMd4copd+UhSBGjud0vbI1ONQ3ffAhixEMml/AApLJtqCpd7PJcccPliFSA==", + "version": "0.0.14", + "resolved": "https://registry.npmjs.org/@openpgp/web-stream-tools/-/web-stream-tools-0.0.14.tgz", + "integrity": "sha512-6btCNVf6YSsmlyIS7yw+IbzXeXCEcJxeSpxvSxkDuZj9B/ekt4fXkZj4oOaIxG4SKTftIK1svnlVroJ1cCMT4g==", "dev": true, "peerDependencies": { "typescript": ">=4.2" @@ -633,72 +699,199 @@ } } }, - "node_modules/@rollup/plugin-commonjs": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-11.1.0.tgz", - "integrity": "sha512-Ycr12N3ZPN96Fw2STurD21jMqzKwL9QuFhms3SD7KKRK7oaXUsBU9Zt0jL/rOPHiPYisI21/rXGO3jr9BnLHUA==", + "node_modules/@rollup/plugin-alias": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.0.0.tgz", + "integrity": "sha512-l9hY5chSCjuFRPsnRm16twWBiSApl2uYFLsepQYwtBuAxNMQ/1dJqADld40P0Jkqm65GRTLy/AC6hnpVebtLsA==", "dev": true, "dependencies": { - "@rollup/pluginutils": "^3.0.8", - "commondir": "^1.0.1", - "estree-walker": "^1.0.1", - "glob": "^7.1.2", - "is-reference": "^1.1.2", - "magic-string": "^0.25.2", - "resolve": "^1.11.0" + "slash": "^4.0.0" }, "engines": { - "node": ">= 8.0.0" + "node": ">=14.0.0" }, "peerDependencies": { - "rollup": "^1.20.0||^2.0.0" + "rollup": "^1.20.0||^2.0.0||^3.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-commonjs": { + "version": "24.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-24.1.0.tgz", + "integrity": "sha512-eSL45hjhCWI0jCCXcNtLVqM5N1JlBGvlFfY0m6oOYnLCJ6N0qEXoZql4sY2MOUArzhH4SA/qBpTxvvZp2Sc+DQ==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "commondir": "^1.0.1", + "estree-walker": "^2.0.2", + "glob": "^8.0.3", + "is-reference": "1.2.1", + "magic-string": "^0.27.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.68.0||^3.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-commonjs/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@rollup/plugin-commonjs/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@rollup/plugin-commonjs/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" } }, "node_modules/@rollup/plugin-node-resolve": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.3.tgz", - "integrity": "sha512-RxtSL3XmdTAE2byxekYLnx+98kEUOrPHF/KRVjLH+DEIHy6kjIw7YINQzn+NXiH/NTrQLAwYs0GWB+csWygA9Q==", + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.0.2.tgz", + "integrity": "sha512-Y35fRGUjC3FaurG722uhUuG8YHOJRJQbI6/CkbRkdPotSpDj9NtIN85z1zrcyDcCQIW4qp5mgG72U+gJ0TAFEg==", "dev": true, "dependencies": { - "@rollup/pluginutils": "^3.0.8", - "@types/resolve": "0.0.8", - "builtin-modules": "^3.1.0", + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-builtin-module": "^3.2.1", "is-module": "^1.0.0", - "resolve": "^1.14.2" + "resolve": "^1.22.1" }, "engines": { - "node": ">= 8.0.0" + "node": ">=14.0.0" }, "peerDependencies": { - "rollup": "^1.20.0||^2.0.0" + "rollup": "^2.78.0||^3.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } } }, "node_modules/@rollup/plugin-node-resolve/node_modules/builtin-modules": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz", - "integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", "dev": true, "engines": { "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@rollup/plugin-node-resolve/node_modules/is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, + "dependencies": { + "builtin-modules": "^3.3.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@rollup/plugin-replace": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.3.2.tgz", - "integrity": "sha512-KEEL7V2tMNOsbAoNMKg91l1sNXBDoiP31GFlqXVOuV5691VQKzKBh91+OKKOG4uQWYqcFskcjFyh1d5YnZd0Zw==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-5.0.2.tgz", + "integrity": "sha512-M9YXNekv/C/iHHK+cvORzfRYfPbq0RDD8r0G+bMiTXjNGKulPnCT9O3Ss46WfhI6ZOCgApOP7xAdmCQJ+U2LAA==", "dev": true, "dependencies": { - "@rollup/pluginutils": "^3.0.8", - "magic-string": "^0.25.5" + "@rollup/pluginutils": "^5.0.1", + "magic-string": "^0.27.0" + }, + "engines": { + "node": ">=14.0.0" }, "peerDependencies": { - "rollup": "^1.20.0 || ^2.0.0" + "rollup": "^1.20.0||^2.0.0||^3.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-terser": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.1.tgz", + "integrity": "sha512-aKS32sw5a7hy+fEXVy+5T95aDIwjpGHCTv833HXVtyKMDoVS7pBr5K3L9hEQoNqbJFjfANPrNpIXlTQ7is00eA==", + "dev": true, + "dependencies": { + "serialize-javascript": "^6.0.0", + "smob": "^0.0.6", + "terser": "^5.15.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.x || ^3.x" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-terser/node_modules/serialize-javascript": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", + "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" } }, "node_modules/@rollup/plugin-wasm": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-wasm/-/plugin-wasm-6.1.2.tgz", - "integrity": "sha512-YdrQ7zfnZ54Y+6raCev3tR1PrhQGxYKSTajGylhyP0oBacouuNo6KcNCk+pYKw9M98jxRWLFFca/udi76IDXzg==", + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-wasm/-/plugin-wasm-6.1.3.tgz", + "integrity": "sha512-7ItTTeyauE6lwdDtQWceEHZ9+txbi4RRy0mYPFn9BW7rD7YdgBDu7HTHsLtHrRzJc313RM/1m6GKgV3np/aEaw==", "dev": true, "engines": { "node": ">=14.0.0" @@ -713,40 +906,36 @@ } }, "node_modules/@rollup/pluginutils": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.0.9.tgz", - "integrity": "sha512-TLZavlfPAZYI7v33wQh4mTP6zojne14yok3DNSLcjoG/Hirxfkonn6icP5rrNWRn8nZsirJBFFpijVOJzkUHDg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", + "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", "dev": true, "dependencies": { - "@types/estree": "0.0.39", - "estree-walker": "^1.0.1", - "micromatch": "^4.0.2" + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" }, "engines": { - "node": ">= 8.0.0" + "node": ">=14.0.0" }, "peerDependencies": { - "rollup": "^1.20.0||^2.0.0" + "rollup": "^1.20.0||^2.0.0||^3.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } } }, "node_modules/@sinonjs/commons": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.7.1.tgz", - "integrity": "sha512-Debi3Baff1Qu1Unc3mjJ96MgpbwTn43S1+9yJ0llWygPwDNu2aaWBD6yc9y/Z8XDRNhx7U+u2UDg2OGQXkclUQ==", + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", "dev": true, "dependencies": { "type-detect": "4.0.8" } }, - "node_modules/@sinonjs/commons/node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/@sinonjs/formatio": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz", @@ -768,9 +957,9 @@ } }, "node_modules/@sinonjs/text-encoding": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", - "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", + "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", "dev": true }, "node_modules/@socket.io/component-emitter": { @@ -779,10 +968,34 @@ "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==", "dev": true }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "dev": true + }, "node_modules/@types/chai": { - "version": "4.2.14", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.14.tgz", - "integrity": "sha512-G+ITQPXkwTrslfG5L/BksmbLUA0M1iybEsmCWPqzSxsRRhJZimBKJkoMi8fr/CPygPTj4zO5pJH7I2/cm9M7SQ==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.5.tgz", + "integrity": "sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==", "dev": true }, "node_modules/@types/cookie": { @@ -801,9 +1014,9 @@ } }, "node_modules/@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", "dev": true }, "node_modules/@types/json5": { @@ -812,6 +1025,28 @@ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, + "node_modules/@types/linkify-it": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz", + "integrity": "sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==", + "dev": true + }, + "node_modules/@types/markdown-it": { + "version": "12.2.3", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz", + "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==", + "dev": true, + "dependencies": { + "@types/linkify-it": "*", + "@types/mdurl": "*" + } + }, + "node_modules/@types/mdurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz", + "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==", + "dev": true + }, "node_modules/@types/node": { "version": "13.13.2", "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.2.tgz", @@ -819,18 +1054,9 @@ "dev": true }, "node_modules/@types/resolve": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", - "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", "dev": true }, "node_modules/accepts": { @@ -867,6 +1093,15 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/agent-base": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", @@ -941,9 +1176,9 @@ } }, "node_modules/anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "dependencies": { "normalize-path": "^3.0.0", @@ -971,6 +1206,12 @@ "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", "dev": true }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, "node_modules/argon2id": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/argon2id/-/argon2id-1.0.1.tgz", @@ -1003,7 +1244,7 @@ "node_modules/array-from": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", - "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", + "integrity": "sha512-GQTc6Uupx1FCavi5mPzBvVT7nEOeWMmUA9P95wpfpW1XwMSKs+KaymD5C2Up7KAUKg/mYwbsUYzdZWcoajlNZg==", "dev": true }, "node_modules/array-includes": { @@ -1397,26 +1638,26 @@ } }, "node_modules/catharsis": { - "version": "0.8.11", - "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.8.11.tgz", - "integrity": "sha512-a+xUyMV7hD1BrDQA/3iPV7oc+6W26BgVJO05PGEoatMyIuPScQKsde6i3YorWX1qs+AZjnJ18NqdKoCtKiNh1g==", + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", + "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", "dev": true, "dependencies": { - "lodash": "^4.17.14" + "lodash": "^4.17.15" }, "engines": { - "node": ">= 8" + "node": ">= 10" } }, "node_modules/chai": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", - "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", + "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", "dev": true, "dependencies": { "assertion-error": "^1.1.0", "check-error": "^1.0.2", - "deep-eql": "^3.0.1", + "deep-eql": "^4.1.2", "get-func-name": "^2.0.0", "loupe": "^2.3.1", "pathval": "^1.1.1", @@ -1457,31 +1698,37 @@ "node_modules/check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", "dev": true, "engines": { "node": "*" } }, "node_modules/chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], "dependencies": { - "anymatch": "~3.1.1", + "anymatch": "~3.1.2", "braces": "~3.0.2", - "glob-parent": "~5.1.0", + "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" + "readdirp": "~3.6.0" }, "engines": { "node": ">= 8.10.0" }, "optionalDependencies": { - "fsevents": "~2.3.1" + "fsevents": "~2.3.2" } }, "node_modules/ci-info": { @@ -1677,6 +1924,12 @@ "node": ">=6" } }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -1747,15 +2000,15 @@ } }, "node_modules/deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", "dev": true, "dependencies": { "type-detect": "^4.0.0" }, "engines": { - "node": ">=0.12" + "node": ">=6" } }, "node_modules/deep-is": { @@ -1764,6 +2017,15 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/default-require-extensions": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", @@ -1933,10 +2195,13 @@ "dev": true }, "node_modules/entities": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", - "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", - "dev": true + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } }, "node_modules/error-ex": { "version": "1.3.1", @@ -2590,15 +2855,6 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node_modules/esm": { - "version": "3.2.25", - "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", - "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/espree": { "version": "9.4.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", @@ -2672,9 +2928,9 @@ } }, "node_modules/estree-walker": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", - "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "dev": true }, "node_modules/esutils": { @@ -3075,7 +3331,7 @@ "node_modules/get-func-name": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", "dev": true, "engines": { "node": "*" @@ -3185,15 +3441,6 @@ "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", "dev": true }, - "node_modules/growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true, - "engines": { - "node": ">=4.x" - } - }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -3710,12 +3957,12 @@ } }, "node_modules/is-reference": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.1.4.tgz", - "integrity": "sha512-uJA/CDPO3Tao3GTrxYn6AwkM4nUPJiGGYu5+cB8qbC7WGFlrKZbiRo7SFKxUAEpFUfiHofWCXBUNhvYJMh+6zw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", "dev": true, "dependencies": { - "@types/estree": "0.0.39" + "@types/estree": "*" } }, "node_modules/is-regex": { @@ -3791,6 +4038,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-weakref": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", @@ -3815,6 +4074,12 @@ "node": ">=8" } }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "dev": true + }, "node_modules/isbinaryfile": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.8.tgz", @@ -3972,20 +4237,6 @@ "node": ">=6" } }, - "node_modules/jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "dev": true, - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, "node_modules/js-sdsl": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", @@ -3997,11 +4248,10 @@ } }, "node_modules/js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true, - "peer": true + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true }, "node_modules/js-yaml": { "version": "3.13.1", @@ -4017,12 +4267,12 @@ } }, "node_modules/js2xmlparser": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.1.tgz", - "integrity": "sha512-KrPTolcw6RocpYjdC7pL7v62e55q7qOMHvLX1UCLc5AAS8qeJ6nukarEJAF2KL2PZxlbGueEbINqZR2bDe/gUw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", + "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==", "dev": true, "dependencies": { - "xmlcreate": "^2.0.3" + "xmlcreate": "^2.0.4" } }, "node_modules/jsesc": { @@ -4093,6 +4343,12 @@ "node": ">=4.0" } }, + "node_modules/just-extend": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", + "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", + "dev": true + }, "node_modules/karma": { "version": "6.4.1", "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.1.tgz", @@ -4445,9 +4701,9 @@ } }, "node_modules/linkify-it": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", - "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", + "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", "dev": true, "dependencies": { "uc.micro": "^1.0.1" @@ -4483,7 +4739,7 @@ "node_modules/lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", "dev": true }, "node_modules/lodash.merge": { @@ -4582,9 +4838,9 @@ "dev": true }, "node_modules/lolex": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.3.2.tgz", - "integrity": "sha512-A5pN2tkFj7H0dGIAM6MFvHKMJcPnjZsOMvR7ujCjfgW5TbV6H9vb1PgxLtHvjqNZTHsUolz+6/WEO0N1xNx2ng==", + "version": "2.7.5", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz", + "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==", "dev": true }, "node_modules/loose-envify": { @@ -4601,21 +4857,24 @@ } }, "node_modules/loupe": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", - "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", + "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", "dev": true, "dependencies": { "get-func-name": "^2.0.0" } }, "node_modules/magic-string": { - "version": "0.25.7", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", - "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", + "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", "dev": true, "dependencies": { - "sourcemap-codec": "^1.4.4" + "@jridgewell/sourcemap-codec": "^1.4.13" + }, + "engines": { + "node": ">=12" } }, "node_modules/make-dir": { @@ -4649,6 +4908,12 @@ "semver": "bin/semver" } }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, "node_modules/map-stream": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", @@ -4656,14 +4921,14 @@ "dev": true }, "node_modules/markdown-it": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", - "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==", + "version": "12.3.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", + "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", "dev": true, "dependencies": { - "argparse": "^1.0.7", - "entities": "~2.0.0", - "linkify-it": "^2.0.0", + "argparse": "^2.0.1", + "entities": "~2.1.0", + "linkify-it": "^3.0.1", "mdurl": "^1.0.1", "uc.micro": "^1.0.5" }, @@ -4672,30 +4937,37 @@ } }, "node_modules/markdown-it-anchor": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.3.0.tgz", - "integrity": "sha512-/V1MnLL/rgJ3jkMWo84UR+K+jF1cxNG1a+KwqeXqTIJ+jtA8aWSHuigx8lTzauiIjBDbwF3NcWQMotd0Dm39jA==", + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz", + "integrity": "sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==", "dev": true, "peerDependencies": { + "@types/markdown-it": "*", "markdown-it": "*" } }, + "node_modules/markdown-it/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, "node_modules/marked": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/marked/-/marked-0.8.2.tgz", - "integrity": "sha512-EGwzEeCcLniFX51DhTpmTom+dSA/MG/OBUDjnWtHbEnjAH180VzUeAw+oE4+Zv+CoYBWyRlYOTR0N8SO9R1PVw==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", + "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", "dev": true, "bin": { - "marked": "bin/marked" + "marked": "bin/marked.js" }, "engines": { - "node": ">= 8.16.2" + "node": ">= 12" } }, "node_modules/mdurl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", "dev": true }, "node_modules/media-typer": { @@ -4725,25 +4997,6 @@ "node": ">=0.10.0" } }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "dev": true, - "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/mime": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", @@ -4822,43 +5075,39 @@ } }, "node_modules/mocha": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz", - "integrity": "sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", + "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", "dev": true, "dependencies": { - "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", - "chokidar": "3.5.1", - "debug": "4.3.1", + "chokidar": "3.5.3", + "debug": "4.3.4", "diff": "5.0.0", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", - "glob": "7.1.6", - "growl": "1.10.5", + "glob": "7.2.0", "he": "1.2.0", - "js-yaml": "4.0.0", - "log-symbols": "4.0.0", - "minimatch": "3.0.4", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "5.0.1", "ms": "2.1.3", - "nanoid": "3.1.20", - "serialize-javascript": "5.0.1", + "nanoid": "3.3.3", + "serialize-javascript": "6.0.0", "strip-json-comments": "3.1.1", "supports-color": "8.1.1", - "which": "2.0.2", - "wide-align": "1.1.3", - "workerpool": "6.1.0", + "workerpool": "6.2.1", "yargs": "16.2.0", "yargs-parser": "20.2.4", "yargs-unparser": "2.0.0" }, "bin": { "_mocha": "bin/_mocha", - "mocha": "bin/mocha" + "mocha": "bin/mocha.js" }, "engines": { - "node": ">= 10.12.0" + "node": ">= 14.0.0" }, "funding": { "type": "opencollective", @@ -4883,9 +5132,9 @@ } }, "node_modules/mocha/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -4933,9 +5182,9 @@ } }, "node_modules/mocha/node_modules/glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", @@ -4983,9 +5232,9 @@ } }, "node_modules/mocha/node_modules/js-yaml": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", - "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "dependencies": { "argparse": "^2.0.1" @@ -4995,15 +5244,40 @@ } }, "node_modules/mocha/node_modules/log-symbols": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", - "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, "dependencies": { - "chalk": "^4.0.0" + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/minimatch/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" } }, "node_modules/mocha/node_modules/ms": { @@ -5013,9 +5287,9 @@ "dev": true }, "node_modules/mocha/node_modules/serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", "dev": true, "dependencies": { "randombytes": "^2.1.0" @@ -5050,21 +5324,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/mocha/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/mocha/node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -5125,9 +5384,9 @@ "dev": true }, "node_modules/nanoid": { - "version": "3.1.20", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", - "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", "dev": true, "bin": { "nanoid": "bin/nanoid.cjs" @@ -5180,12 +5439,6 @@ "@sinonjs/samsam": "^3.1.0" } }, - "node_modules/nise/node_modules/just-extend": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.1.0.tgz", - "integrity": "sha512-ApcjaOdVTJ7y4r08xI5wIqpvwS48Q0PBG4DJROcEkH1f8MdAiNFyFxz3xoL0LWAVwjrwPYZdVHHxhRHcx/uGLA==", - "dev": true - }, "node_modules/nise/node_modules/lolex": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", @@ -5607,20 +5860,14 @@ "dev": true }, "node_modules/path-to-regexp": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", - "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", "dev": true, "dependencies": { "isarray": "0.0.1" } }, - "node_modules/path-to-regexp/node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, "node_modules/pathval": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", @@ -5640,9 +5887,9 @@ } }, "node_modules/picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "engines": { "node": ">=8.6" @@ -5872,9 +6119,9 @@ "peer": true }, "node_modules/readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "dependencies": { "picomatch": "^2.2.1" @@ -6019,9 +6266,9 @@ } }, "node_modules/rollup": { - "version": "2.38.5", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.38.5.tgz", - "integrity": "sha512-VoWt8DysFGDVRGWuHTqZzT02J0ASgjVq/hPs9QcBOGMd7B+jfTr/iqMVEyOi901rE3xq+Deq66GzIT1yt7sGwQ==", + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", "dev": true, "bin": { "rollup": "dist/bin/rollup" @@ -6030,101 +6277,7 @@ "node": ">=10.0.0" }, "optionalDependencies": { - "fsevents": "~2.3.1" - } - }, - "node_modules/rollup-plugin-terser": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", - "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.10.4", - "jest-worker": "^26.2.1", - "serialize-javascript": "^4.0.0", - "terser": "^5.0.0" - }, - "peerDependencies": { - "rollup": "^2.0.0" - } - }, - "node_modules/rollup-plugin-terser/node_modules/@babel/code-frame": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", - "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/rollup-plugin-terser/node_modules/@babel/helper-validator-identifier": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", - "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/rollup-plugin-terser/node_modules/@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.14.5", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/rollup-plugin-terser/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/rollup-plugin-terser/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/rollup-plugin-terser/node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/rollup-plugin-terser/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" + "fsevents": "~2.3.2" } }, "node_modules/run-parallel": { @@ -6198,15 +6351,6 @@ "semver": "bin/semver" } }, - "node_modules/serialize-javascript": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", - "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", @@ -6261,10 +6405,11 @@ "dev": true }, "node_modules/sinon": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-4.3.0.tgz", - "integrity": "sha512-pmf05hFgEZUS52AGJcsVjOjqAyJW2yo14cOwVYvzCyw7+inv06YXkLyW75WG6X6p951lzkoKh51L2sNbR9CDvw==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-4.5.0.tgz", + "integrity": "sha512-trdx+mB0VBBgoYucy6a9L7/jfQOmvGeaKZT4OOJ+lPAtI8623xyGr8wLiE4eojzBS8G9yXbhx42GHUOVLr4X2w==", "dev": true, + "hasInstallScript": true, "dependencies": { "@sinonjs/formatio": "^2.0.0", "diff": "^3.1.0", @@ -6276,9 +6421,9 @@ } }, "node_modules/sinon/node_modules/supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "dependencies": { "has-flag": "^3.0.0" @@ -6287,6 +6432,24 @@ "node": ">=4" } }, + "node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/smob": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/smob/-/smob-0.0.6.tgz", + "integrity": "sha512-V21+XeNni+tTyiST1MHsa84AQhT1aFZipzPpOFAVB8DkHzwJyjjAmt9bgwnuZiZWnIbMo2duE29wybxv/7HWUw==", + "dev": true + }, "node_modules/socket.io": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.6.0.tgz", @@ -6372,15 +6535,6 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/source-map-support": { "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", @@ -6400,12 +6554,6 @@ "node": ">=0.10.0" } }, - "node_modules/sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", - "dev": true - }, "node_modules/spawn-wrap": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.3.tgz", @@ -6932,6 +7080,58 @@ "node": ">=0.6" } }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/tsconfig-paths": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", @@ -6957,9 +7157,9 @@ } }, "node_modules/type-detect": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.5.tgz", - "integrity": "sha512-N9IvkQslUGYGC24RkJk1ba99foK6TkwC2FHAEBlQFBP0RxQZS8ZpJuAZcwiY/w9ZJHFQb1aOXBI60OdxhTrwEQ==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true, "engines": { "node": ">=4" @@ -7044,9 +7244,9 @@ } }, "node_modules/underscore": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.10.2.tgz", - "integrity": "sha512-N4P+Q/BuyuEKFJ43B9gYuOj4TQUHXX+j2FqguVOpjkssLUUrnJofCcBccJSCoeturDoZU6GorDTHSvUDlSQbTg==", + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", "dev": true }, "node_modules/union": { @@ -7113,6 +7313,12 @@ "uuid": "bin/uuid" } }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, "node_modules/validate-npm-package-license": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", @@ -7208,49 +7414,6 @@ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, - "node_modules/wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "dependencies": { - "string-width": "^1.0.2 || 2" - } - }, - "node_modules/wide-align/node_modules/ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -7261,9 +7424,9 @@ } }, "node_modules/workerpool": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", - "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", "dev": true }, "node_modules/wrap-ansi": { @@ -7341,9 +7504,9 @@ } }, "node_modules/xmlcreate": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.3.tgz", - "integrity": "sha512-HgS+X6zAztGa9zIK3Y3LXuJes33Lz9x+YyTxgrkIdabu2vqcGOWwdfCpf1hWLRrd553wd4QCDf6BBO6FfdsRiQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", + "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", "dev": true }, "node_modules/y18n": { @@ -7495,6 +7658,15 @@ "node": ">=4" } }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -7510,69 +7682,80 @@ }, "dependencies": { "@babel/code-frame": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", - "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", + "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", "dev": true, "requires": { - "@babel/highlight": "^7.8.3" + "@babel/highlight": "^7.18.6" } }, "@babel/generator": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", - "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.5.tgz", + "integrity": "sha512-SrKK/sRv8GesIW1bDagf9cCG38IOMYZusoe1dfg0D8aiUe3Amvoj1QtjTPAWcfrZFvIwlleLb0gxzQidL9w14w==", "dev": true, "requires": { - "@babel/types": "^7.9.6", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" + "@babel/types": "^7.21.5", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" } }, + "@babel/helper-environment-visitor": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.21.5.tgz", + "integrity": "sha512-IYl4gZ3ETsWocUWgsFZLM5i1BYx9SoemminVEXadgLBa9TdeorzgLKm8wWLA6J1N/kT3Kch8XIk1laNzYoHKvQ==", + "dev": true + }, "@babel/helper-function-name": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", - "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", + "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.9.5" + "@babel/template": "^7.20.7", + "@babel/types": "^7.21.0" } }, - "@babel/helper-get-function-arity": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", - "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.18.6" } }, "@babel/helper-split-export-declaration": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", - "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.18.6" } }, + "@babel/helper-string-parser": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.21.5.tgz", + "integrity": "sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==", + "dev": true + }, "@babel/helper-validator-identifier": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", - "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", "dev": true }, "@babel/highlight": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", - "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "dev": true, "requires": { + "@babel/helper-validator-identifier": "^7.18.6", "chalk": "^2.0.0", - "esutils": "^2.0.2", "js-tokens": "^4.0.0" }, "dependencies": { @@ -7596,12 +7779,6 @@ "supports-color": "^5.3.0" } }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -7614,9 +7791,9 @@ } }, "@babel/parser": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", - "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", + "version": "7.21.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.8.tgz", + "integrity": "sha512-6zavDGdzG3gUqAdWvlLFfk+36RilI+Pwyuuh7HItyeScCWP3k6i8vKclAQ0bM/0y/Kz/xiwvxhMv9MgTJP5gmA==", "dev": true }, "@babel/runtime": { @@ -7641,31 +7818,32 @@ } }, "@babel/template": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", - "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", "dev": true, "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.6", - "@babel/types": "^7.8.6" + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" } }, "@babel/traverse": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", - "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.5.tgz", + "integrity": "sha512-AhQoI3YjWi6u/y/ntv7k48mcrCXmus0t79J9qPNlk/lAsFlCiJ047RmbfMOawySTHtywXhbXgpx/8nXMYd+oFw==", "dev": true, "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.6", - "@babel/helper-function-name": "^7.9.5", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.9.6", - "@babel/types": "^7.9.6", + "@babel/code-frame": "^7.21.4", + "@babel/generator": "^7.21.5", + "@babel/helper-environment-visitor": "^7.21.5", + "@babel/helper-function-name": "^7.21.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.21.5", + "@babel/types": "^7.21.5", "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" + "globals": "^11.1.0" }, "dependencies": { "debug": { @@ -7686,13 +7864,13 @@ } }, "@babel/types": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", - "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.5.tgz", + "integrity": "sha512-m4AfNvVF2mVC/F7fDEdH2El3HzUg9It/XsCxZiOTTA3m3qYfcSVSbTfM6Q9xG+hYDniZssYhlXKKUMD5m8tF4Q==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.9.5", - "lodash": "^4.17.13", + "@babel/helper-string-parser": "^7.21.5", + "@babel/helper-validator-identifier": "^7.19.1", "to-fast-properties": "^2.0.0" } }, @@ -7702,6 +7880,27 @@ "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", "dev": true }, + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "dependencies": { + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + } + } + }, "@eslint/eslintrc": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", @@ -7915,25 +8114,26 @@ } }, "@openpgp/jsdoc": { - "version": "3.6.4", - "resolved": "https://registry.npmjs.org/@openpgp/jsdoc/-/jsdoc-3.6.4.tgz", - "integrity": "sha512-PR4NtdOVev7wbUYe4/T0CeLDAr0qxDthBqUrqngKIHn6h+m9fgRz20vH5OBalIVYaDeHcUcxdwGbEFRT30/WSg==", + "version": "3.6.11", + "resolved": "https://registry.npmjs.org/@openpgp/jsdoc/-/jsdoc-3.6.11.tgz", + "integrity": "sha512-mwvKQrW9raTU4CM3Oa93deRPh3TknFL0PUaGJWXwk3Inqf5nT8x4Z867ctqKYPekqw9FdDGyTaGb4rkbyPl9fA==", "dev": true, "requires": { "@babel/parser": "^7.9.4", + "@types/markdown-it": "^12.2.3", "bluebird": "^3.7.2", - "catharsis": "^0.8.11", + "catharsis": "^0.9.0", "escape-string-regexp": "^2.0.0", - "js2xmlparser": "^4.0.1", + "js2xmlparser": "^4.0.2", "klaw": "^3.0.0", - "markdown-it": "^10.0.0", - "markdown-it-anchor": "^5.2.7", - "marked": "^0.8.2", + "markdown-it": "^12.3.2", + "markdown-it-anchor": "^8.4.1", + "marked": "^4.0.10", "mkdirp": "^1.0.4", "requizzle": "^0.2.3", "strip-json-comments": "^3.1.0", "taffydb": "2.6.2", - "underscore": "~1.10.2" + "underscore": "~1.13.2" }, "dependencies": { "escape-string-regexp": { @@ -7972,91 +8172,156 @@ "dev": true }, "@openpgp/web-stream-tools": { - "version": "0.0.13", - "resolved": "https://registry.npmjs.org/@openpgp/web-stream-tools/-/web-stream-tools-0.0.13.tgz", - "integrity": "sha512-VQ0O0lUcD9ilLcMLQMJMgPhp8fDgMd4copd+UhSBGjud0vbI1ONQ3ffAhixEMml/AApLJtqCpd7PJcccPliFSA==", + "version": "0.0.14", + "resolved": "https://registry.npmjs.org/@openpgp/web-stream-tools/-/web-stream-tools-0.0.14.tgz", + "integrity": "sha512-6btCNVf6YSsmlyIS7yw+IbzXeXCEcJxeSpxvSxkDuZj9B/ekt4fXkZj4oOaIxG4SKTftIK1svnlVroJ1cCMT4g==", "dev": true, "requires": {} }, - "@rollup/plugin-commonjs": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-11.1.0.tgz", - "integrity": "sha512-Ycr12N3ZPN96Fw2STurD21jMqzKwL9QuFhms3SD7KKRK7oaXUsBU9Zt0jL/rOPHiPYisI21/rXGO3jr9BnLHUA==", + "@rollup/plugin-alias": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.0.0.tgz", + "integrity": "sha512-l9hY5chSCjuFRPsnRm16twWBiSApl2uYFLsepQYwtBuAxNMQ/1dJqADld40P0Jkqm65GRTLy/AC6hnpVebtLsA==", "dev": true, "requires": { - "@rollup/pluginutils": "^3.0.8", + "slash": "^4.0.0" + } + }, + "@rollup/plugin-commonjs": { + "version": "24.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-24.1.0.tgz", + "integrity": "sha512-eSL45hjhCWI0jCCXcNtLVqM5N1JlBGvlFfY0m6oOYnLCJ6N0qEXoZql4sY2MOUArzhH4SA/qBpTxvvZp2Sc+DQ==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^5.0.1", "commondir": "^1.0.1", - "estree-walker": "^1.0.1", - "glob": "^7.1.2", - "is-reference": "^1.1.2", - "magic-string": "^0.25.2", - "resolve": "^1.11.0" + "estree-walker": "^2.0.2", + "glob": "^8.0.3", + "is-reference": "1.2.1", + "magic-string": "^0.27.0" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + } + }, + "minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } } }, "@rollup/plugin-node-resolve": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.3.tgz", - "integrity": "sha512-RxtSL3XmdTAE2byxekYLnx+98kEUOrPHF/KRVjLH+DEIHy6kjIw7YINQzn+NXiH/NTrQLAwYs0GWB+csWygA9Q==", + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.0.2.tgz", + "integrity": "sha512-Y35fRGUjC3FaurG722uhUuG8YHOJRJQbI6/CkbRkdPotSpDj9NtIN85z1zrcyDcCQIW4qp5mgG72U+gJ0TAFEg==", "dev": true, "requires": { - "@rollup/pluginutils": "^3.0.8", - "@types/resolve": "0.0.8", - "builtin-modules": "^3.1.0", + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-builtin-module": "^3.2.1", "is-module": "^1.0.0", - "resolve": "^1.14.2" + "resolve": "^1.22.1" }, "dependencies": { "builtin-modules": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz", - "integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", "dev": true + }, + "is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, + "requires": { + "builtin-modules": "^3.3.0" + } } } }, "@rollup/plugin-replace": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.3.2.tgz", - "integrity": "sha512-KEEL7V2tMNOsbAoNMKg91l1sNXBDoiP31GFlqXVOuV5691VQKzKBh91+OKKOG4uQWYqcFskcjFyh1d5YnZd0Zw==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-5.0.2.tgz", + "integrity": "sha512-M9YXNekv/C/iHHK+cvORzfRYfPbq0RDD8r0G+bMiTXjNGKulPnCT9O3Ss46WfhI6ZOCgApOP7xAdmCQJ+U2LAA==", "dev": true, "requires": { - "@rollup/pluginutils": "^3.0.8", - "magic-string": "^0.25.5" + "@rollup/pluginutils": "^5.0.1", + "magic-string": "^0.27.0" + } + }, + "@rollup/plugin-terser": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.1.tgz", + "integrity": "sha512-aKS32sw5a7hy+fEXVy+5T95aDIwjpGHCTv833HXVtyKMDoVS7pBr5K3L9hEQoNqbJFjfANPrNpIXlTQ7is00eA==", + "dev": true, + "requires": { + "serialize-javascript": "^6.0.0", + "smob": "^0.0.6", + "terser": "^5.15.1" + }, + "dependencies": { + "serialize-javascript": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", + "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + } } }, "@rollup/plugin-wasm": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-wasm/-/plugin-wasm-6.1.2.tgz", - "integrity": "sha512-YdrQ7zfnZ54Y+6raCev3tR1PrhQGxYKSTajGylhyP0oBacouuNo6KcNCk+pYKw9M98jxRWLFFca/udi76IDXzg==", + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-wasm/-/plugin-wasm-6.1.3.tgz", + "integrity": "sha512-7ItTTeyauE6lwdDtQWceEHZ9+txbi4RRy0mYPFn9BW7rD7YdgBDu7HTHsLtHrRzJc313RM/1m6GKgV3np/aEaw==", "dev": true, "requires": {} }, "@rollup/pluginutils": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.0.9.tgz", - "integrity": "sha512-TLZavlfPAZYI7v33wQh4mTP6zojne14yok3DNSLcjoG/Hirxfkonn6icP5rrNWRn8nZsirJBFFpijVOJzkUHDg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", + "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", "dev": true, "requires": { - "@types/estree": "0.0.39", - "estree-walker": "^1.0.1", - "micromatch": "^4.0.2" + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" } }, "@sinonjs/commons": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.7.1.tgz", - "integrity": "sha512-Debi3Baff1Qu1Unc3mjJ96MgpbwTn43S1+9yJ0llWygPwDNu2aaWBD6yc9y/Z8XDRNhx7U+u2UDg2OGQXkclUQ==", + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", "dev": true, "requires": { "type-detect": "4.0.8" - }, - "dependencies": { - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - } } }, "@sinonjs/formatio": { @@ -8080,9 +8345,9 @@ } }, "@sinonjs/text-encoding": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", - "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", + "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", "dev": true }, "@socket.io/component-emitter": { @@ -8091,10 +8356,34 @@ "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==", "dev": true }, + "@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "dev": true + }, "@types/chai": { - "version": "4.2.14", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.14.tgz", - "integrity": "sha512-G+ITQPXkwTrslfG5L/BksmbLUA0M1iybEsmCWPqzSxsRRhJZimBKJkoMi8fr/CPygPTj4zO5pJH7I2/cm9M7SQ==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.5.tgz", + "integrity": "sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==", "dev": true }, "@types/cookie": { @@ -8113,9 +8402,9 @@ } }, "@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", "dev": true }, "@types/json5": { @@ -8124,6 +8413,28 @@ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, + "@types/linkify-it": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz", + "integrity": "sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==", + "dev": true + }, + "@types/markdown-it": { + "version": "12.2.3", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz", + "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==", + "dev": true, + "requires": { + "@types/linkify-it": "*", + "@types/mdurl": "*" + } + }, + "@types/mdurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz", + "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==", + "dev": true + }, "@types/node": { "version": "13.13.2", "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.2.tgz", @@ -8131,18 +8442,9 @@ "dev": true }, "@types/resolve": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", - "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", "dev": true }, "accepts": { @@ -8168,6 +8470,12 @@ "dev": true, "requires": {} }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true + }, "agent-base": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", @@ -8222,9 +8530,9 @@ } }, "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "requires": { "normalize-path": "^3.0.0", @@ -8246,6 +8554,12 @@ "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", "dev": true }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, "argon2id": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/argon2id/-/argon2id-1.0.1.tgz", @@ -8275,7 +8589,7 @@ "array-from": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", - "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", + "integrity": "sha512-GQTc6Uupx1FCavi5mPzBvVT7nEOeWMmUA9P95wpfpW1XwMSKs+KaymD5C2Up7KAUKg/mYwbsUYzdZWcoajlNZg==", "dev": true }, "array-includes": { @@ -8595,23 +8909,23 @@ "dev": true }, "catharsis": { - "version": "0.8.11", - "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.8.11.tgz", - "integrity": "sha512-a+xUyMV7hD1BrDQA/3iPV7oc+6W26BgVJO05PGEoatMyIuPScQKsde6i3YorWX1qs+AZjnJ18NqdKoCtKiNh1g==", + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", + "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", "dev": true, "requires": { - "lodash": "^4.17.14" + "lodash": "^4.17.15" } }, "chai": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", - "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", + "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", "dev": true, "requires": { "assertion-error": "^1.1.0", "check-error": "^1.0.2", - "deep-eql": "^3.0.1", + "deep-eql": "^4.1.2", "get-func-name": "^2.0.0", "loupe": "^2.3.1", "pathval": "^1.1.1", @@ -8640,23 +8954,23 @@ "check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", "dev": true }, "chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, "requires": { - "anymatch": "~3.1.1", + "anymatch": "~3.1.2", "braces": "~3.0.2", - "fsevents": "~2.3.1", - "glob-parent": "~5.1.0", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" + "readdirp": "~3.6.0" } }, "ci-info": { @@ -8812,6 +9126,12 @@ } } }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -8869,9 +9189,9 @@ "dev": true }, "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", "dev": true, "requires": { "type-detect": "^4.0.0" @@ -8883,6 +9203,12 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true + }, "default-require-extensions": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", @@ -9019,9 +9345,9 @@ "dev": true }, "entities": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", - "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", "dev": true }, "error-ex": { @@ -9535,12 +9861,6 @@ } } }, - "esm": { - "version": "3.2.25", - "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", - "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", - "dev": true - }, "espree": { "version": "9.4.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", @@ -9591,9 +9911,9 @@ "dev": true }, "estree-walker": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", - "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "dev": true }, "esutils": { @@ -9912,7 +10232,7 @@ "get-func-name": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", "dev": true }, "get-intrinsic": { @@ -9994,12 +10314,6 @@ "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", "dev": true }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -10381,12 +10695,12 @@ "dev": true }, "is-reference": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.1.4.tgz", - "integrity": "sha512-uJA/CDPO3Tao3GTrxYn6AwkM4nUPJiGGYu5+cB8qbC7WGFlrKZbiRo7SFKxUAEpFUfiHofWCXBUNhvYJMh+6zw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", "dev": true, "requires": { - "@types/estree": "0.0.39" + "@types/estree": "*" } }, "is-regex": { @@ -10438,6 +10752,12 @@ "has-symbols": "^1.0.2" } }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, "is-weakref": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", @@ -10456,6 +10776,12 @@ "is-docker": "^2.0.0" } }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "dev": true + }, "isbinaryfile": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.8.tgz", @@ -10582,17 +10908,6 @@ "html-escaper": "^2.0.0" } }, - "jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "dev": true, - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - } - }, "js-sdsl": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", @@ -10600,11 +10915,10 @@ "dev": true }, "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true, - "peer": true + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true }, "js-yaml": { "version": "3.13.1", @@ -10617,12 +10931,12 @@ } }, "js2xmlparser": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.1.tgz", - "integrity": "sha512-KrPTolcw6RocpYjdC7pL7v62e55q7qOMHvLX1UCLc5AAS8qeJ6nukarEJAF2KL2PZxlbGueEbINqZR2bDe/gUw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", + "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==", "dev": true, "requires": { - "xmlcreate": "^2.0.3" + "xmlcreate": "^2.0.4" } }, "jsesc": { @@ -10679,6 +10993,12 @@ "object.assign": "^4.1.3" } }, + "just-extend": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", + "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", + "dev": true + }, "karma": { "version": "6.4.1", "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.1.tgz", @@ -10968,9 +11288,9 @@ } }, "linkify-it": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", - "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", + "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", "dev": true, "requires": { "uc.micro": "^1.0.1" @@ -11000,7 +11320,7 @@ "lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", "dev": true }, "lodash.merge": { @@ -11080,9 +11400,9 @@ } }, "lolex": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.3.2.tgz", - "integrity": "sha512-A5pN2tkFj7H0dGIAM6MFvHKMJcPnjZsOMvR7ujCjfgW5TbV6H9vb1PgxLtHvjqNZTHsUolz+6/WEO0N1xNx2ng==", + "version": "2.7.5", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz", + "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==", "dev": true }, "loose-envify": { @@ -11096,21 +11416,21 @@ } }, "loupe": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", - "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", + "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", "dev": true, "requires": { "get-func-name": "^2.0.0" } }, "magic-string": { - "version": "0.25.7", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", - "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", + "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", "dev": true, "requires": { - "sourcemap-codec": "^1.4.4" + "@jridgewell/sourcemap-codec": "^1.4.13" } }, "make-dir": { @@ -11137,6 +11457,12 @@ } } }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, "map-stream": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", @@ -11144,35 +11470,43 @@ "dev": true }, "markdown-it": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", - "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==", + "version": "12.3.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", + "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", "dev": true, "requires": { - "argparse": "^1.0.7", - "entities": "~2.0.0", - "linkify-it": "^2.0.0", + "argparse": "^2.0.1", + "entities": "~2.1.0", + "linkify-it": "^3.0.1", "mdurl": "^1.0.1", "uc.micro": "^1.0.5" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + } } }, "markdown-it-anchor": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.3.0.tgz", - "integrity": "sha512-/V1MnLL/rgJ3jkMWo84UR+K+jF1cxNG1a+KwqeXqTIJ+jtA8aWSHuigx8lTzauiIjBDbwF3NcWQMotd0Dm39jA==", + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz", + "integrity": "sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==", "dev": true, "requires": {} }, "marked": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/marked/-/marked-0.8.2.tgz", - "integrity": "sha512-EGwzEeCcLniFX51DhTpmTom+dSA/MG/OBUDjnWtHbEnjAH180VzUeAw+oE4+Zv+CoYBWyRlYOTR0N8SO9R1PVw==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", + "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", "dev": true }, "mdurl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", "dev": true }, "media-typer": { @@ -11198,22 +11532,6 @@ } } }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" - } - }, "mime": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", @@ -11271,33 +11589,29 @@ } }, "mocha": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz", - "integrity": "sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", + "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", "dev": true, "requires": { - "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", - "chokidar": "3.5.1", - "debug": "4.3.1", + "chokidar": "3.5.3", + "debug": "4.3.4", "diff": "5.0.0", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", - "glob": "7.1.6", - "growl": "1.10.5", + "glob": "7.2.0", "he": "1.2.0", - "js-yaml": "4.0.0", - "log-symbols": "4.0.0", - "minimatch": "3.0.4", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "5.0.1", "ms": "2.1.3", - "nanoid": "3.1.20", - "serialize-javascript": "5.0.1", + "nanoid": "3.3.3", + "serialize-javascript": "6.0.0", "strip-json-comments": "3.1.1", "supports-color": "8.1.1", - "which": "2.0.2", - "wide-align": "1.1.3", - "workerpool": "6.1.0", + "workerpool": "6.2.1", "yargs": "16.2.0", "yargs-parser": "20.2.4", "yargs-unparser": "2.0.0" @@ -11321,9 +11635,9 @@ } }, "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -11356,9 +11670,9 @@ "dev": true }, "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -11393,21 +11707,42 @@ "dev": true }, "js-yaml": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", - "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "requires": { "argparse": "^2.0.1" } }, "log-symbols": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", - "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, "requires": { - "chalk": "^4.0.0" + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, + "minimatch": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + } } }, "ms": { @@ -11417,9 +11752,9 @@ "dev": true }, "serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", "dev": true, "requires": { "randombytes": "^2.1.0" @@ -11445,15 +11780,6 @@ "has-flag": "^4.0.0" } }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, "wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -11501,9 +11827,9 @@ "dev": true }, "nanoid": { - "version": "3.1.20", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", - "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", "dev": true }, "natural-compare": { @@ -11547,12 +11873,6 @@ "@sinonjs/samsam": "^3.1.0" } }, - "just-extend": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.1.0.tgz", - "integrity": "sha512-ApcjaOdVTJ7y4r08xI5wIqpvwS48Q0PBG4DJROcEkH1f8MdAiNFyFxz3xoL0LWAVwjrwPYZdVHHxhRHcx/uGLA==", - "dev": true - }, "lolex": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", @@ -11872,20 +12192,12 @@ "dev": true }, "path-to-regexp": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", - "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", "dev": true, "requires": { "isarray": "0.0.1" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - } } }, "pathval": { @@ -11904,9 +12216,9 @@ } }, "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, "platform": { @@ -12070,9 +12382,9 @@ "peer": true }, "readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "requires": { "picomatch": "^2.2.1" @@ -12177,87 +12489,12 @@ } }, "rollup": { - "version": "2.38.5", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.38.5.tgz", - "integrity": "sha512-VoWt8DysFGDVRGWuHTqZzT02J0ASgjVq/hPs9QcBOGMd7B+jfTr/iqMVEyOi901rE3xq+Deq66GzIT1yt7sGwQ==", + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", "dev": true, "requires": { - "fsevents": "~2.3.1" - } - }, - "rollup-plugin-terser": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", - "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "jest-worker": "^26.2.1", - "serialize-javascript": "^4.0.0", - "terser": "^5.0.0" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", - "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.14.5" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", - "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", - "dev": true - }, - "@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.14.5", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "fsevents": "~2.3.2" } }, "run-parallel": { @@ -12310,15 +12547,6 @@ "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", "dev": true }, - "serialize-javascript": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", - "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", @@ -12364,9 +12592,9 @@ "dev": true }, "sinon": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-4.3.0.tgz", - "integrity": "sha512-pmf05hFgEZUS52AGJcsVjOjqAyJW2yo14cOwVYvzCyw7+inv06YXkLyW75WG6X6p951lzkoKh51L2sNbR9CDvw==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-4.5.0.tgz", + "integrity": "sha512-trdx+mB0VBBgoYucy6a9L7/jfQOmvGeaKZT4OOJ+lPAtI8623xyGr8wLiE4eojzBS8G9yXbhx42GHUOVLr4X2w==", "dev": true, "requires": { "@sinonjs/formatio": "^2.0.0", @@ -12379,9 +12607,9 @@ }, "dependencies": { "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -12389,6 +12617,18 @@ } } }, + "slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true + }, + "smob": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/smob/-/smob-0.0.6.tgz", + "integrity": "sha512-V21+XeNni+tTyiST1MHsa84AQhT1aFZipzPpOFAVB8DkHzwJyjjAmt9bgwnuZiZWnIbMo2duE29wybxv/7HWUw==", + "dev": true + }, "socket.io": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.6.0.tgz", @@ -12456,12 +12696,6 @@ } } }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, "source-map-support": { "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", @@ -12480,12 +12714,6 @@ } } }, - "sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", - "dev": true - }, "spawn-wrap": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.3.tgz", @@ -12901,6 +13129,35 @@ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true }, + "ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "requires": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "dependencies": { + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + } + } + }, "tsconfig-paths": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", @@ -12923,9 +13180,9 @@ } }, "type-detect": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.5.tgz", - "integrity": "sha512-N9IvkQslUGYGC24RkJk1ba99foK6TkwC2FHAEBlQFBP0RxQZS8ZpJuAZcwiY/w9ZJHFQb1aOXBI60OdxhTrwEQ==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, "type-fest": { @@ -12975,9 +13232,9 @@ } }, "underscore": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.10.2.tgz", - "integrity": "sha512-N4P+Q/BuyuEKFJ43B9gYuOj4TQUHXX+j2FqguVOpjkssLUUrnJofCcBccJSCoeturDoZU6GorDTHSvUDlSQbTg==", + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", "dev": true }, "union": { @@ -13028,6 +13285,12 @@ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "dev": true }, + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, "validate-npm-package-license": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", @@ -13104,42 +13367,6 @@ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -13147,9 +13374,9 @@ "dev": true }, "workerpool": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", - "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", "dev": true }, "wrap-ansi": { @@ -13203,9 +13430,9 @@ "requires": {} }, "xmlcreate": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.3.tgz", - "integrity": "sha512-HgS+X6zAztGa9zIK3Y3LXuJes33Lz9x+YyTxgrkIdabu2vqcGOWwdfCpf1hWLRrd553wd4QCDf6BBO6FfdsRiQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", + "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", "dev": true }, "y18n": { @@ -13325,6 +13552,12 @@ } } }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true + }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index b48b07fc..a24d4c41 100644 --- a/package.json +++ b/package.json @@ -13,13 +13,26 @@ "gpg", "openpgp" ], - "main": "dist/node/openpgp.min.js", + "main": "dist/node/openpgp.min.cjs", "module": "dist/node/openpgp.min.mjs", "browser": { - "./dist/node/openpgp.min.js": "./dist/openpgp.min.js", + "./dist/node/openpgp.min.cjs": "./dist/openpgp.min.js", "./dist/node/openpgp.min.mjs": "./dist/openpgp.min.mjs" }, + "exports": { + ".": { + "types": "./openpgp.d.ts", + "import": "./dist/node/openpgp.mjs", + "require": "./dist/node/openpgp.min.cjs", + "browser": "./dist/openpgp.min.mjs" + }, + "./lightweight": { + "types": "../openpgp.d.ts", + "browser": "./dist/lightweight/openpgp.min.mjs" + } + }, "types": "openpgp.d.ts", + "type": "module", "directories": { "lib": "src" }, @@ -28,27 +41,22 @@ "lightweight/", "openpgp.d.ts" ], - "esm": { - "cjs": { - "dedefault": true - } - }, "scripts": { "build": "rollup --config", "build-test": "npm run build --build-only=test", "prepare": "npm run build", - "test": "mocha --require esm --timeout 120000 test/unittests.js", - "test-type-definitions": "tsc test/typescript/definitions.ts && node test/typescript/definitions.js", + "test": "mocha --timeout 120000 test/unittests.js", + "test-type-definitions": "ts-node --esm test/typescript/definitions.ts", "benchmark-time": "node test/benchmarks/time.js", - "benchmark-memory-usage": "node --require esm test/benchmarks/memory_usage.js", + "benchmark-memory-usage": "node test/benchmarks/memory_usage.js", "start": "http-server", "prebrowsertest": "npm run build-test", "browsertest": "npm start -- -o test/unittests.html", - "test-browser": "karma start test/karma.conf.js", - "test-browserstack": "karma start test/karma.conf.js --browsers bs_safari_latest,bs_ios_14,bs_safari_13_1", + "test-browser": "karma start test/karma.conf.cjs", + "test-browserstack": "karma start test/karma.conf.cjs --browsers bs_safari_latest,bs_ios_14,bs_safari_13_1", "coverage": "nyc npm test", "lint": "eslint .", - "docs": "jsdoc --configure .jsdocrc.js --destination docs --recurse README.md src && printf '%s' 'docs.openpgpjs.org' > docs/CNAME", + "docs": "jsdoc --configure .jsdocrc.cjs --destination docs --recurse README.md src && printf '%s' 'docs.openpgpjs.org' > docs/CNAME", "preversion": "rm -rf dist docs node_modules && npm ci && npm test", "version": "npm run docs && git add -A docs", "postversion": "git push && git push --tags && npm publish" @@ -56,20 +64,22 @@ "devDependencies": { "@openpgp/asmcrypto.js": "^2.3.2", "@openpgp/elliptic": "^6.5.1", - "@openpgp/jsdoc": "^3.6.4", + "@openpgp/jsdoc": "^3.6.11", "@openpgp/pako": "^1.0.12", "@openpgp/seek-bzip": "^1.0.5-git", "@openpgp/tweetnacl": "^1.0.3", - "@openpgp/web-stream-tools": "^0.0.13", - "@rollup/plugin-commonjs": "^11.1.0", - "@rollup/plugin-node-resolve": "^7.1.3", - "@rollup/plugin-replace": "^2.3.2", + "@openpgp/web-stream-tools": "^0.0.14", + "@rollup/plugin-alias": "^5.0.0", + "@rollup/plugin-commonjs": "^24.0.1", + "@rollup/plugin-node-resolve": "^15.0.1", + "@rollup/plugin-replace": "^5.0.2", + "@rollup/plugin-terser": "^0.4.0", "@rollup/plugin-wasm": "^6.1.2", "@types/chai": "^4.2.14", "argon2id": "^1.0.1", "benchmark": "^2.1.4", "bn.js": "^4.11.8", - "chai": "^4.3.6", + "chai": "^4.3.7", "chai-as-promised": "^7.1.1", "email-addresses": "3.1.0", "eslint": "^8.34.0", @@ -77,7 +87,6 @@ "eslint-config-airbnb-base": "^15.0.0", "eslint-plugin-chai-friendly": "^0.7.2", "eslint-plugin-import": "^2.27.5", - "esm": "^3.2.25", "hash.js": "^1.1.3", "http-server": "^14.1.1", "karma": "^6.4.0", @@ -87,12 +96,12 @@ "karma-mocha": "^2.0.1", "karma-mocha-reporter": "^2.2.5", "karma-webkit-launcher": "^2.1.0", - "mocha": "^8.4.0", + "mocha": "^10.2.0", "nyc": "^14.1.1", "playwright": "^1.30.0", - "rollup": "^2.38.5", - "rollup-plugin-terser": "^7.0.2", + "rollup": "^2.79.1", "sinon": "^4.3.0", + "ts-node": "^10.9.1", "typescript": "^4.1.2", "web-streams-polyfill": "^3.2.0" }, diff --git a/rollup.config.js b/rollup.config.js index 97656497..1d723d6f 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -2,16 +2,18 @@ import { builtinModules } from 'module'; +import alias from '@rollup/plugin-alias'; import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; import replace from '@rollup/plugin-replace'; -import { terser } from 'rollup-plugin-terser'; +import terser from '@rollup/plugin-terser'; import { wasm } from '@rollup/plugin-wasm'; - import pkg from './package.json'; const nodeDependencies = Object.keys(pkg.dependencies); +const nodeBuiltinModules = builtinModules.concat(['module']); + const wasmOptions = { node: { targetEnv: 'node' }, browser: { targetEnv: 'browser', maxFileSize: undefined } // always inlline (our wasm files are small) @@ -47,6 +49,7 @@ const terserOptions = { export default Object.assign([ { input: 'src/index.js', + external: nodeBuiltinModules.concat(nodeDependencies), output: [ { file: 'dist/openpgp.js', format: 'iife', name: pkg.name, banner, intro }, { file: 'dist/openpgp.min.js', format: 'iife', name: pkg.name, banner, intro, plugins: [terser(terserOptions)], sourcemap: true }, @@ -59,11 +62,11 @@ export default Object.assign([ browser: true }), commonjs({ - ignore: builtinModules.concat(nodeDependencies) + ignore: nodeBuiltinModules.concat(nodeDependencies) }), replace({ 'OpenPGP.js VERSION': `OpenPGP.js ${pkg.version}`, - 'require(': 'void(', + "import { createRequire } from 'module';": 'const createRequire = () => () => {}', delimiters: ['', ''] }), wasm(wasmOptions.browser) @@ -72,10 +75,10 @@ export default Object.assign([ { input: 'src/index.js', inlineDynamicImports: true, - external: builtinModules.concat(nodeDependencies), + external: nodeBuiltinModules.concat(nodeDependencies), output: [ - { file: 'dist/node/openpgp.js', format: 'cjs', name: pkg.name, banner, intro }, - { file: 'dist/node/openpgp.min.js', format: 'cjs', name: pkg.name, banner, intro, plugins: [terser(terserOptions)], sourcemap: true }, + { file: 'dist/node/openpgp.cjs', format: 'cjs', name: pkg.name, banner, intro }, + { file: 'dist/node/openpgp.min.cjs', format: 'cjs', name: pkg.name, banner, intro, plugins: [terser(terserOptions)], sourcemap: true }, { file: 'dist/node/openpgp.mjs', format: 'es', banner, intro }, { file: 'dist/node/openpgp.min.mjs', format: 'es', banner, intro, plugins: [terser(terserOptions)], sourcemap: true } ], @@ -90,6 +93,7 @@ export default Object.assign([ }, { input: 'src/index.js', + external: nodeBuiltinModules.concat(nodeDependencies), output: [ { dir: 'dist/lightweight', entryFileNames: 'openpgp.mjs', chunkFileNames: chunkInfo => getChunkFileName(chunkInfo, 'mjs'), format: 'es', banner, intro }, { dir: 'dist/lightweight', entryFileNames: 'openpgp.min.mjs', chunkFileNames: chunkInfo => getChunkFileName(chunkInfo, 'min.mjs'), format: 'es', banner, intro, plugins: [terser(terserOptions)], sourcemap: true } @@ -100,11 +104,11 @@ export default Object.assign([ browser: true }), commonjs({ - ignore: builtinModules.concat(nodeDependencies) + ignore: nodeBuiltinModules.concat(nodeDependencies) }), replace({ 'OpenPGP.js VERSION': `OpenPGP.js ${pkg.version}`, - 'require(': 'void(', + "import { createRequire } from 'module';": 'const createRequire = () => () => {}', delimiters: ['', ''] }), wasm(wasmOptions.browser) @@ -116,17 +120,22 @@ export default Object.assign([ { file: 'test/lib/unittests-bundle.js', format: 'es', intro, sourcemap: true } ], inlineDynamicImports: true, - external: ['../..', '../../..'], + external: nodeBuiltinModules.concat(nodeDependencies), plugins: [ + alias({ + entries: { + openpgp: `./dist/${process.env.npm_config_lightweight ? 'lightweight/' : ''}openpgp.mjs` + } + }), resolve({ browser: true }), commonjs({ - ignore: builtinModules.concat(nodeDependencies) + ignore: nodeBuiltinModules.concat(nodeDependencies), + requireReturnsDefault: 'preferred' }), replace({ - "import openpgpjs from '../../..';": `import * as openpgpjs from '/dist/${process.env.npm_config_lightweight ? 'lightweight/' : ''}openpgp.mjs'; window.openpgp = openpgpjs;`, - 'require(': 'void(', + "import { createRequire } from 'module';": 'const createRequire = () => () => {}', delimiters: ['', ''] }), wasm(wasmOptions.browser) diff --git a/src/crypto/cmac.js b/src/crypto/cmac.js index c183a70a..e838bd6f 100644 --- a/src/crypto/cmac.js +++ b/src/crypto/cmac.js @@ -2,7 +2,6 @@ * @fileoverview This module implements AES-CMAC on top of * native AES-CBC using either the WebCrypto API or Node.js' crypto API. * @module crypto/cmac - * @private */ import { AES_CBC } from '@openpgp/asmcrypto.js/dist_es8/aes/cbc'; diff --git a/src/crypto/mode/eax.js b/src/crypto/mode/eax.js index 2dfff46e..4917ba1c 100644 --- a/src/crypto/mode/eax.js +++ b/src/crypto/mode/eax.js @@ -19,7 +19,6 @@ * @fileoverview This module implements AES-EAX en/decryption on top of * native AES-CTR using either the WebCrypto API or Node.js' crypto API. * @module crypto/mode/eax - * @private */ import { AES_CTR } from '@openpgp/asmcrypto.js/dist_es8/aes/ctr'; diff --git a/src/crypto/mode/index.js b/src/crypto/mode/index.js index c1ae364f..beeeca55 100644 --- a/src/crypto/mode/index.js +++ b/src/crypto/mode/index.js @@ -1,7 +1,6 @@ /** * @fileoverview Cipher modes * @module crypto/mode - * @private */ import * as cfb from './cfb'; diff --git a/src/crypto/public_key/elliptic/ecdsa.js b/src/crypto/public_key/elliptic/ecdsa.js index 285c40f3..a11e49c2 100644 --- a/src/crypto/public_key/elliptic/ecdsa.js +++ b/src/crypto/public_key/elliptic/ecdsa.js @@ -280,7 +280,7 @@ async function nodeVerify(curve, hashAlgo, { r, s }, message, publicKey) { /* eslint-disable no-invalid-this */ -const asn1 = nodeCrypto ? require('asn1.js') : undefined; +const asn1 = nodeCrypto ? util.nodeRequire('asn1.js') : undefined; const ECDSASignature = nodeCrypto ? asn1.define('ECDSASignature', function() { diff --git a/src/crypto/public_key/rsa.js b/src/crypto/public_key/rsa.js index bdbf36c3..2b24a152 100644 --- a/src/crypto/public_key/rsa.js +++ b/src/crypto/public_key/rsa.js @@ -30,7 +30,7 @@ import enums from '../../enums'; const webCrypto = util.getWebCrypto(); const nodeCrypto = util.getNodeCrypto(); -const asn1 = nodeCrypto ? require('asn1.js') : undefined; +const asn1 = nodeCrypto ? util.nodeRequire('asn1.js') : undefined; /* eslint-disable no-invalid-this */ const RSAPrivateKey = nodeCrypto ? asn1.define('RSAPrivateKey', function () { diff --git a/src/key/subkey.js b/src/key/subkey.js index 57e34a0b..130155a7 100644 --- a/src/key/subkey.js +++ b/src/key/subkey.js @@ -1,6 +1,5 @@ /** * @module key/Subkey - * @private */ import enums from '../enums'; diff --git a/src/util.js b/src/util.js index c720d596..255d020f 100644 --- a/src/util.js +++ b/src/util.js @@ -24,6 +24,7 @@ */ import * as stream from '@openpgp/web-stream-tools'; +import { createRequire } from 'module'; // Must be stripped in browser built import { getBigInteger } from './biginteger'; import enums from './enums'; @@ -39,6 +40,8 @@ const util = { return typeof data === 'string' || data instanceof String; }, + nodeRequire: createRequire(import.meta.url), + isArray: function(data) { return data instanceof Array; }, @@ -396,11 +399,11 @@ const util = { * @returns {Object} The crypto module or 'undefined'. */ getNodeCrypto: function() { - return require('crypto'); + return this.nodeRequire('crypto'); }, getNodeZlib: function() { - return require('zlib'); + return this.nodeRequire('zlib'); }, /** @@ -409,7 +412,7 @@ const util = { * @returns {Function} The Buffer constructor or 'undefined'. */ getNodeBuffer: function() { - return (require('buffer') || {}).Buffer; + return (this.nodeRequire('buffer') || {}).Buffer; }, getHardwareConcurrency: function() { @@ -417,7 +420,7 @@ const util = { return navigator.hardwareConcurrency || 1; } - const os = require('os'); // Assume we're on Node.js. + const os = this.nodeRequire('os'); // Assume we're on Node.js. return os.cpus().length; }, diff --git a/test/benchmarks/memory_usage.js b/test/benchmarks/memory_usage.js index 58166105..e50873e4 100644 --- a/test/benchmarks/memory_usage.js +++ b/test/benchmarks/memory_usage.js @@ -1,9 +1,10 @@ /* eslint-disable no-console */ -const assert = require('assert'); -const path = require('path'); -const { writeFileSync, unlinkSync } = require('fs'); -const { fork } = require('child_process'); -const openpgp = require('../..'); +import assert from 'assert'; +import path from 'path'; +import { writeFileSync, unlinkSync } from 'fs'; +import { fork } from 'child_process'; +import { fileURLToPath } from 'url'; +import * as openpgp from 'openpgp'; /** * Benchmark max memory usage recorded during execution of the given function. @@ -12,11 +13,12 @@ const openpgp = require('../..'); * @returns {NodeJS.MemoryUsage} memory usage snapshot with max RSS (sizes in bytes) */ const benchmark = async function(fn) { - const tmpFileName = path.join(__dirname, 'tmp.js'); + const __dirname = path.dirname(fileURLToPath(import.meta.url)); + const tmpFileName = path.join(__dirname, 'tmp.cjs'); // the code to execute must be written to a file writeFileSync(tmpFileName, ` const assert = require('assert'); -const openpgp = require('../..'); +const openpgp = require('openpgp'); let maxMemoryComsumption; let activeSampling = false; diff --git a/test/benchmarks/time.js b/test/benchmarks/time.js index e2a32241..e86340f7 100644 --- a/test/benchmarks/time.js +++ b/test/benchmarks/time.js @@ -1,5 +1,5 @@ -const Benchmark = require('benchmark'); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..'); +import Benchmark from 'benchmark'; +import * as openpgp from 'openpgp'; const wrapAsync = func => ({ fn: async deferred => { diff --git a/test/crypto/aes_kw.js b/test/crypto/aes_kw.js index 130cfc5e..1a3b04c4 100644 --- a/test/crypto/aes_kw.js +++ b/test/crypto/aes_kw.js @@ -1,9 +1,9 @@ -const { expect } = require('chai'); +import { expect } from 'chai'; -const aesKW = require('../../src/crypto/aes_kw'); -const util = require('../../src/util'); +import * as aesKW from '../../src/crypto/aes_kw.js'; +import util from '../../src/util.js'; -module.exports = () => describe('AES Key Wrap and Unwrap', function () { +export default () => describe('AES Key Wrap and Unwrap', function () { const test_vectors = [ [ '128 bits of Key Data with a 128-bit KEK', diff --git a/test/crypto/cipher/aes.js b/test/crypto/cipher/aes.js index 798e8662..6ec39863 100644 --- a/test/crypto/cipher/aes.js +++ b/test/crypto/cipher/aes.js @@ -1,8 +1,8 @@ -const { expect } = require('chai'); +import { expect } from 'chai'; -const { aes128: AES128 } = require('../../../src/crypto/cipher'); +import { aes128 as AES128 } from '../../../src/crypto/cipher'; -module.exports = () => describe('AES Rijndael cipher test with test vectors from ecb_tbl.txt', function() { +export default () => describe('AES Rijndael cipher test with test vectors from ecb_tbl.txt', function() { function test_aes(input, key, output) { const aes = new AES128(new Uint8Array(key)); diff --git a/test/crypto/cipher/blowfish.js b/test/crypto/cipher/blowfish.js index fc31fe89..f1e7477f 100644 --- a/test/crypto/cipher/blowfish.js +++ b/test/crypto/cipher/blowfish.js @@ -1,9 +1,9 @@ -const { expect } = require('chai'); +import { expect } from 'chai'; -const BF = require('../../../src/crypto/cipher/blowfish'); -const util = require('../../../src/util'); +import BF from '../../../src/crypto/cipher/blowfish'; +import util from '../../../src/util.js'; -module.exports = () => it('Blowfish cipher test with test vectors from https://www.schneier.com/code/vectors.txt', function(done) { +export default () => it('Blowfish cipher test with test vectors from https://www.schneier.com/code/vectors.txt', function(done) { function test_bf(input, key, output) { const blowfish = new BF(util.uint8ArrayToString(key)); const result = blowfish.encrypt(input); diff --git a/test/crypto/cipher/cast5.js b/test/crypto/cipher/cast5.js index c68ab094..cde718c3 100644 --- a/test/crypto/cipher/cast5.js +++ b/test/crypto/cipher/cast5.js @@ -1,9 +1,9 @@ -const { expect } = require('chai'); +import { expect } from 'chai'; -const CAST5 = require('../../../src/crypto/cipher/cast5'); -const util = require('../../../src/util'); +import CAST5 from '../../../src/crypto/cipher/cast5.js'; +import util from '../../../src/util.js'; -module.exports = () => it('CAST-128 cipher test with test vectors from RFC2144', function (done) { +export default () => it('CAST-128 cipher test with test vectors from RFC2144', function (done) { function test_cast(input, key, output) { const cast5 = new CAST5(key); const result = cast5.encrypt(input); diff --git a/test/crypto/cipher/des.js b/test/crypto/cipher/des.js index 72dbd594..e3a00285 100644 --- a/test/crypto/cipher/des.js +++ b/test/crypto/cipher/des.js @@ -1,9 +1,9 @@ -const { expect } = require('chai'); +import { expect } from 'chai'; -const { DES, TripleDES } = require('../../../src/crypto/cipher/des'); -const util = require('../../../src/util'); +import { DES, TripleDES } from '../../../src/crypto/cipher/des.js'; +import util from '../../../src/util.js'; -module.exports = () => describe('TripleDES (EDE) cipher test with test vectors from NIST SP 800-20', function() { +export default () => describe('TripleDES (EDE) cipher test with test vectors from NIST SP 800-20', function() { // see https://csrc.nist.gov/publications/nistpubs/800-20/800-20.pdf const key = new Uint8Array([1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]); const testvectors = [[[0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x95,0xF8,0xA5,0xE5,0xDD,0x31,0xD9,0x00]], diff --git a/test/crypto/cipher/index.js b/test/crypto/cipher/index.js index 35770ed8..7f852f20 100644 --- a/test/crypto/cipher/index.js +++ b/test/crypto/cipher/index.js @@ -1,7 +1,13 @@ -module.exports = () => describe('Cipher', function () { - require('./aes')(); - require('./blowfish')(); - require('./cast5')(); - require('./des')(); - require('./twofish')(); +import testAES from './aes'; +import testBlowfish from './blowfish'; +import testCAST5 from './cast5'; +import testDES from './des'; +import testTwofish from './twofish'; + +export default () => describe('Cipher', function () { + testAES(); + testBlowfish(); + testCAST5(); + testDES(); + testTwofish(); }); diff --git a/test/crypto/cipher/twofish.js b/test/crypto/cipher/twofish.js index 6a0e1445..f66d105a 100644 --- a/test/crypto/cipher/twofish.js +++ b/test/crypto/cipher/twofish.js @@ -1,9 +1,9 @@ -const { expect } = require('chai'); +import { expect } from 'chai'; -const TF = require('../../../src/crypto/cipher/twofish'); -const util = require('../../../src/util'); +import TF from '../../../src/crypto/cipher/twofish.js'; +import util from '../../../src/util.js'; -module.exports = () => it('Twofish with test vectors from https://www.schneier.com/code/ecb_ival.txt', function(done) { +export default () => it('Twofish with test vectors from https://www.schneier.com/code/ecb_ival.txt', function(done) { function tfencrypt(block, key) { const tf = new TF(util.stringToUint8Array(key)); diff --git a/test/crypto/crypto.js b/test/crypto/crypto.js index 8c5417bc..5f2f7b31 100644 --- a/test/crypto/crypto.js +++ b/test/crypto/crypto.js @@ -1,12 +1,13 @@ -const { use: chaiUse, expect } = require('chai'); -chaiUse(require('chai-as-promised')); +import { use as chaiUse, expect } from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..'); -const sandbox = require('sinon/lib/sinon/sandbox'); -const crypto = require('../../src/crypto'); -const util = require('../../src/util'); +const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import sandbox from 'sinon/lib/sinon/sandbox'; +import crypto from '../../src/crypto'; +import util from '../../src/util.js'; -module.exports = () => describe('API functional testing', function() { +export default () => describe('API functional testing', function() { const RSAPublicKeyMaterial = util.concatUint8Array([ new Uint8Array([0x08,0x00,0xac,0x15,0xb3,0xd6,0xd2,0x0f,0xf0,0x7a,0xdd,0x21,0xb7, 0xbf,0x61,0xfa,0xca,0x93,0x86,0xc8,0x55,0x5a,0x4b,0xa6,0xa4,0x1a, diff --git a/test/crypto/eax.js b/test/crypto/eax.js index 2c7e7625..5c8e535d 100644 --- a/test/crypto/eax.js +++ b/test/crypto/eax.js @@ -1,13 +1,14 @@ // Modified by ProtonTech AG // Adapted from https://github.com/artjomb/cryptojs-extension/blob/8c61d159/test/eax.js -const sandbox = require('sinon/lib/sinon/sandbox'); -const { use: chaiUse, expect } = require('chai'); -chaiUse(require('chai-as-promised')); +import sandbox from 'sinon/lib/sinon/sandbox'; +import { use as chaiUse, expect } from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..'); -const EAX = require('../../src/crypto/mode/eax'); -const util = require('../../src/util'); +const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import EAX from '../../src/crypto/mode/eax.js'; +import util from '../../src/util.js'; function testAESEAX() { it('Passes all test vectors', async function() { @@ -124,7 +125,7 @@ function testAESEAX() { } /* eslint-disable no-invalid-this */ -module.exports = () => describe('Symmetric AES-EAX', function() { +export default () => describe('Symmetric AES-EAX', function() { let sinonSandbox; let getWebCryptoStub; let getNodeCryptoStub; diff --git a/test/crypto/ecdh.js b/test/crypto/ecdh.js index d9e3d824..fc0edb19 100644 --- a/test/crypto/ecdh.js +++ b/test/crypto/ecdh.js @@ -1,18 +1,19 @@ -const sandbox = require('sinon/lib/sinon/sandbox'); -const { use: chaiUse, expect } = require('chai'); -chaiUse(require('chai-as-promised')); +import sandbox from 'sinon/lib/sinon/sandbox'; +import { use as chaiUse, expect } from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..'); -const OID = require('../../src/type/oid'); -const KDFParams = require('../../src/type/kdf_params'); -const elliptic_curves = require('../../src/crypto/public_key/elliptic'); -const util = require('../../src/util'); -const elliptic_data = require('./elliptic_data'); -const random = require('../../src/crypto/random'); +const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import OID from '../../src/type/oid.js'; +import KDFParams from '../../src/type/kdf_params.js'; +import * as elliptic_curves from '../../src/crypto/public_key/elliptic'; +import util from '../../src/util.js'; +import elliptic_data from './elliptic_data.js'; +import * as random from '../../src/crypto/random.js'; const key_data = elliptic_data.key_data; /* eslint-disable no-invalid-this */ -module.exports = () => describe('ECDH key exchange @lightweight', function () { +export default () => describe('ECDH key exchange @lightweight', function () { const decrypt_message = function (oid, hash, cipher, priv, pub, ephemeral, data, fingerprint) { if (util.isString(data)) { data = util.stringToUint8Array(data); diff --git a/test/crypto/elliptic.js b/test/crypto/elliptic.js index f1a52a86..6072ae44 100644 --- a/test/crypto/elliptic.js +++ b/test/crypto/elliptic.js @@ -1,18 +1,19 @@ -const sandbox = require('sinon/lib/sinon/sandbox'); -const { use: chaiUse, expect } = require('chai'); -chaiUse(require('chai-as-promised')); +import sandbox from 'sinon/lib/sinon/sandbox'; +import { use as chaiUse, expect } from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..'); -const elliptic_curves = require('../../src/crypto/public_key/elliptic'); -const hashMod = require('../../src/crypto/hash'); -const config = require('../../src/config'); -const util = require('../../src/util'); +const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import * as elliptic_curves from '../../src/crypto/public_key/elliptic'; +import hashMod from '../../src/crypto/hash'; +import config from '../../src/config'; +import util from '../../src/util.js'; -const elliptic_data = require('./elliptic_data'); +import elliptic_data from './elliptic_data'; const key_data = elliptic_data.key_data; /* eslint-disable no-invalid-this */ -module.exports = () => describe('Elliptic Curve Cryptography @lightweight', function () { +export default () => describe('Elliptic Curve Cryptography @lightweight', function () { const signature_data = { priv: new Uint8Array([ 0x14, 0x2B, 0xE2, 0xB7, 0x4D, 0xBD, 0x1B, 0x22, diff --git a/test/crypto/elliptic_data.js b/test/crypto/elliptic_data.js index c6cd83c1..61eba7d9 100644 --- a/test/crypto/elliptic_data.js +++ b/test/crypto/elliptic_data.js @@ -99,4 +99,4 @@ const elliptic_data = { } }; -module.exports = elliptic_data; +export default elliptic_data; diff --git a/test/crypto/gcm.js b/test/crypto/gcm.js index d3b0f01b..4e06806e 100644 --- a/test/crypto/gcm.js +++ b/test/crypto/gcm.js @@ -1,13 +1,14 @@ -const sandbox = require('sinon/lib/sinon/sandbox'); -const { use: chaiUse, expect } = require('chai'); -chaiUse(require('chai-as-promised')); +import sandbox from 'sinon/lib/sinon/sandbox'; +import { use as chaiUse, expect } from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..'); -const crypto = require('../../src/crypto'); -const util = require('../../src/util'); +const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import crypto from '../../src/crypto'; +import util from '../../src/util.js'; -module.exports = () => describe('Symmetric AES-GCM (experimental)', function() { +export default () => describe('Symmetric AES-GCM (experimental)', function() { let sinonSandbox; let getWebCryptoStub; let getNodeCryptoStub; diff --git a/test/crypto/hash/index.js b/test/crypto/hash/index.js index c0b01f8c..53366177 100644 --- a/test/crypto/hash/index.js +++ b/test/crypto/hash/index.js @@ -1,5 +1,9 @@ -module.exports = () => describe('Hash', function () { - require('./md5')(); - require('./ripemd')(); - require('./sha')(); +import testMD5 from './md5'; +import testRipeMD from './ripemd'; +import testSHA from './sha'; + +export default () => describe('Hash', function () { + testMD5(); + testRipeMD(); + testSHA(); }); diff --git a/test/crypto/hash/md5.js b/test/crypto/hash/md5.js index 078f6c1b..0825e421 100644 --- a/test/crypto/hash/md5.js +++ b/test/crypto/hash/md5.js @@ -1,9 +1,9 @@ -const { expect } = require('chai'); +import { expect } from 'chai'; -const md5 = require('../../../src/crypto/hash/md5'); -const util = require('../../../src/util'); +import md5 from '../../../src/crypto/hash/md5.js'; +import util from '../../../src/util.js'; -module.exports = () => it('MD5 with test vectors from RFC 1321', async function() { +export default () => it('MD5 with test vectors from RFC 1321', async function() { expect(util.uint8ArrayToHex(await md5(util.stringToUint8Array('')), 'MD5("") = d41d8cd98f00b204e9800998ecf8427e')).to.equal('d41d8cd98f00b204e9800998ecf8427e'); expect(util.uint8ArrayToHex(await md5(util.stringToUint8Array('abc')), 'MD5("a") = 0cc175b9c0f1b6a831c399e269772661')).to.equal('900150983cd24fb0d6963f7d28e17f72'); expect(util.uint8ArrayToHex(await md5(util.stringToUint8Array('message digest')), 'MD5("message digest") = f96b697d7cb7938d525a2f31aaf161d0')).to.equal('f96b697d7cb7938d525a2f31aaf161d0'); diff --git a/test/crypto/hash/ripemd.js b/test/crypto/hash/ripemd.js index e9d93d62..a1116c31 100644 --- a/test/crypto/hash/ripemd.js +++ b/test/crypto/hash/ripemd.js @@ -1,11 +1,11 @@ -const { expect } = require('chai'); +import { expect } from 'chai'; -const { ripemd: rmdString } = require('../../../src/crypto/hash'); -const util = require('../../../src/util'); +import hash from '../../../src/crypto/hash'; +import util from '../../../src/util.js'; -module.exports = () => it('RIPE-MD 160 bits with test vectors from https://homes.esat.kuleuven.be/~bosselae/ripemd160.html', async function() { - expect(util.uint8ArrayToHex(await rmdString(util.stringToUint8Array('')), 'RMDstring("") = 9c1185a5c5e9fc54612808977ee8f548b2258d31')).to.equal('9c1185a5c5e9fc54612808977ee8f548b2258d31'); - expect(util.uint8ArrayToHex(await rmdString(util.stringToUint8Array('a')), 'RMDstring("a") = 0bdc9d2d256b3ee9daae347be6f4dc835a467ffe')).to.equal('0bdc9d2d256b3ee9daae347be6f4dc835a467ffe'); - expect(util.uint8ArrayToHex(await rmdString(util.stringToUint8Array('abc')), 'RMDstring("abc") = 8eb208f7e05d987a9b044a8e98c6b087f15a0bfc')).to.equal('8eb208f7e05d987a9b044a8e98c6b087f15a0bfc'); - expect(util.uint8ArrayToHex(await rmdString(util.stringToUint8Array('message digest')), 'RMDstring("message digest") = 5d0689ef49d2fae572b881b123a85ffa21595f36')).to.equal('5d0689ef49d2fae572b881b123a85ffa21595f36'); +export default () => it('RIPE-MD 160 bits with test vectors from https://homes.esat.kuleuven.be/~bosselae/ripemd160.html', async function() { + expect(util.uint8ArrayToHex(await hash.ripemd(util.stringToUint8Array('')), 'RMDstring("") = 9c1185a5c5e9fc54612808977ee8f548b2258d31')).to.equal('9c1185a5c5e9fc54612808977ee8f548b2258d31'); + expect(util.uint8ArrayToHex(await hash.ripemd(util.stringToUint8Array('a')), 'RMDstring("a") = 0bdc9d2d256b3ee9daae347be6f4dc835a467ffe')).to.equal('0bdc9d2d256b3ee9daae347be6f4dc835a467ffe'); + expect(util.uint8ArrayToHex(await hash.ripemd(util.stringToUint8Array('abc')), 'RMDstring("abc") = 8eb208f7e05d987a9b044a8e98c6b087f15a0bfc')).to.equal('8eb208f7e05d987a9b044a8e98c6b087f15a0bfc'); + expect(util.uint8ArrayToHex(await hash.ripemd(util.stringToUint8Array('message digest')), 'RMDstring("message digest") = 5d0689ef49d2fae572b881b123a85ffa21595f36')).to.equal('5d0689ef49d2fae572b881b123a85ffa21595f36'); }); diff --git a/test/crypto/hash/sha.js b/test/crypto/hash/sha.js index fc81b29f..dc5284f0 100644 --- a/test/crypto/hash/sha.js +++ b/test/crypto/hash/sha.js @@ -1,9 +1,9 @@ -const { expect } = require('chai'); +import { expect } from 'chai'; -const hash = require('../../../src/crypto/hash'); -const util = require('../../../src/util'); +import hash from '../../../src/crypto/hash'; +import util from '../../../src/util.js'; -module.exports = () => it('SHA* with test vectors from NIST FIPS 180-2', async function() { +export default () => it('SHA* with test vectors from NIST FIPS 180-2', async function() { expect(util.uint8ArrayToHex(await hash.sha1(util.stringToUint8Array('abc')), 'hash.sha1("abc") = a9993e364706816aba3e25717850c26c9cd0d89d')).to.equal('a9993e364706816aba3e25717850c26c9cd0d89d'); expect(util.uint8ArrayToHex(await hash.sha1(util.stringToUint8Array('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq')), 'hash.sha1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 84983e441c3bd26ebaae4aa1f95129e5e54670f1')).to.equal('84983e441c3bd26ebaae4aa1f95129e5e54670f1'); expect(util.uint8ArrayToHex(await hash.sha224(util.stringToUint8Array('abc')), 'hash.sha224("abc") = 23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7')).to.equal('23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7'); diff --git a/test/crypto/hkdf.js b/test/crypto/hkdf.js index b2b88023..de048e1a 100644 --- a/test/crypto/hkdf.js +++ b/test/crypto/hkdf.js @@ -1,13 +1,10 @@ -const { expect } = require('chai'); +import { expect } from 'chai'; -const computeHKDF = require('../../src/crypto/hkdf'); -const enums = require('../../src/enums'); -const util = require('../../src/util'); +import computeHKDF from '../../src/crypto/hkdf'; +import enums from '../../src/enums'; +import util from '../../src/util'; -// WebCrypto implements HKDF natively, no need to test it -const maybeDescribe = util.getNodeCrypto() ? describe : describe; - -module.exports = () => maybeDescribe('HKDF test vectors', function() { +export default () => describe('HKDF test vectors', function() { // Vectors from https://www.rfc-editor.org/rfc/rfc5869#appendix-A it('Test Case 1', async function() { const inputKey = util.hexToUint8Array('0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b'); diff --git a/test/crypto/index.js b/test/crypto/index.js index 932dd1d8..205b9866 100644 --- a/test/crypto/index.js +++ b/test/crypto/index.js @@ -1,15 +1,29 @@ -module.exports = () => describe('Crypto', function () { - require('./cipher')(); - require('./hash')(); - require('./crypto')(); - require('./elliptic')(); - require('./ecdh')(); - require('./pkcs5')(); - require('./aes_kw')(); - require('./hkdf')(); - require('./gcm')(); - require('./eax')(); - require('./ocb')(); - require('./rsa')(); - require('./validate')(); +import testCipher from './cipher'; +import testHash from './hash'; +import testCrypto from './crypto'; +import testElliptic from './elliptic'; +import testECDH from './ecdh'; +import testPKCS5 from './pkcs5'; +import testAESKW from './aes_kw'; +import testHKDF from './hkdf'; +import testGCM from './gcm'; +import testEAX from './eax'; +import testOCB from './ocb'; +import testRSA from './rsa'; +import testValidate from './validate'; + +export default () => describe('Crypto', function () { + testCipher(); + testHash(); + testCrypto(); + testElliptic(); + testECDH(); + testPKCS5(); + testAESKW(); + testHKDF(); + testGCM(); + testEAX(); + testOCB(); + testRSA(); + testValidate(); }); diff --git a/test/crypto/ocb.js b/test/crypto/ocb.js index c97beb27..67bea175 100644 --- a/test/crypto/ocb.js +++ b/test/crypto/ocb.js @@ -1,14 +1,15 @@ // Modified by ProtonTech AG // Adapted from https://github.com/artjomb/cryptojs-extension/blob/8c61d159/test/eax.js -const { use: chaiUse, expect } = require('chai'); -chaiUse(require('chai-as-promised')); +import { use as chaiUse, expect } from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..'); -const OCB = require('../../src/crypto/mode/ocb'); -const util = require('../../src/util'); +const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import OCB from '../../src/crypto/mode/ocb.js'; +import util from '../../src/util.js'; -module.exports = () => describe('Symmetric AES-OCB', function() { +export default () => describe('Symmetric AES-OCB', function() { it('Passes all test vectors', async function() { const K = '000102030405060708090A0B0C0D0E0F'; const keyBytes = util.hexToUint8Array(K); diff --git a/test/crypto/pkcs5.js b/test/crypto/pkcs5.js index c051206e..30d666a6 100644 --- a/test/crypto/pkcs5.js +++ b/test/crypto/pkcs5.js @@ -1,8 +1,8 @@ -const { expect } = require('chai'); +import { expect } from 'chai'; -const pkcs5 = require('../../src/crypto/pkcs5'); +import * as pkcs5 from '../../src/crypto/pkcs5.js'; -module.exports = () => describe('PKCS5 padding', function() { +export default () => describe('PKCS5 padding', function() { it('Add and remove padding', function () { const m = new Uint8Array([0,1,2,3,4,5,6,7,8]); const padded = pkcs5.encode(m); diff --git a/test/crypto/rsa.js b/test/crypto/rsa.js index 37f7e1e5..4aa24d61 100644 --- a/test/crypto/rsa.js +++ b/test/crypto/rsa.js @@ -1,14 +1,15 @@ -const sandbox = require('sinon/lib/sinon/sandbox'); -const { use: chaiUse, expect } = require('chai'); -chaiUse(require('chai-as-promised')); +import sandbox from 'sinon/lib/sinon/sandbox'; +import { use as chaiUse, expect } from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..'); -const crypto = require('../../src/crypto'); -const random = require('../../src/crypto/random'); -const util = require('../../src/util'); +const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import crypto from '../../src/crypto'; +import * as random from '../../src/crypto/random.js'; +import util from '../../src/util.js'; /* eslint-disable no-invalid-this */ -module.exports = () => describe('basic RSA cryptography', function () { +export default () => describe('basic RSA cryptography', function () { let sinonSandbox; let getWebCryptoStub; let getNodeCryptoStub; diff --git a/test/crypto/validate.js b/test/crypto/validate.js index 5e311532..610728b5 100644 --- a/test/crypto/validate.js +++ b/test/crypto/validate.js @@ -1,8 +1,9 @@ -const BN = require('bn.js'); -const { use: chaiUse, expect } = require('chai'); -chaiUse(require('chai-as-promised')); +import BN from 'bn.js'; +import { use as chaiUse, expect } from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..'); +const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); const armoredDSAKey = `-----BEGIN PGP PRIVATE KEY BLOCK----- @@ -86,7 +87,7 @@ async function generatePrivateKeyObject(options) { } /* eslint-disable no-invalid-this */ -module.exports = () => { +export default () => { describe('EdDSA parameter validation (legacy format)', function() { let eddsaKey; before(async () => { diff --git a/test/general/armor.js b/test/general/armor.js index 3ec400a3..53119f2b 100644 --- a/test/general/armor.js +++ b/test/general/armor.js @@ -1,9 +1,8 @@ -const { expect } = require('chai'); +import { expect } from 'chai'; -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..'); +const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); - -module.exports = () => describe('ASCII armor', function() { +export default () => describe('ASCII armor', function() { function getArmor(headers, signatureHeaders) { return ['-----BEGIN PGP SIGNED MESSAGE-----'] diff --git a/test/general/biginteger.js b/test/general/biginteger.js index 10dd8446..142b5026 100644 --- a/test/general/biginteger.js +++ b/test/general/biginteger.js @@ -1,9 +1,10 @@ -const { use: chaiUse, expect } = require('chai'); -chaiUse(require('chai-as-promised')); +import { use as chaiUse, expect } from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chaiUse(chaiAsPromised); -const BN = require('bn.js'); -const random = require('../../src/crypto/random'); -const util = require('../../src/util'); +import BN from 'bn.js'; +import * as random from '../../src/crypto/random.js'; +import util from '../../src/util.js'; let BigInteger; @@ -18,7 +19,7 @@ async function getRandomBN(min, max) { return r.mod(modulus).add(min); } -module.exports = () => describe('BigInteger interface', function() { +export default () => describe('BigInteger interface', function() { before(async () => { BigInteger = await util.getBigInteger(); }); diff --git a/test/general/brainpool.js b/test/general/brainpool.js index fbcc9b94..ce662ca6 100644 --- a/test/general/brainpool.js +++ b/test/general/brainpool.js @@ -1,14 +1,15 @@ /* globals tryTests */ -const { use: chaiUse, expect } = require('chai'); -chaiUse(require('chai-as-promised')); +import { use as chaiUse, expect } from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..'); -const util = require('../../src/util'); +const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import util from '../../src/util.js'; -const input = require('./testInputs'); +import * as input from './testInputs.js'; -module.exports = () => (openpgp.config.ci ? describe.skip : describe)('Brainpool Cryptography @lightweight', function () { +export default () => (openpgp.config.ci ? describe.skip : describe)('Brainpool Cryptography @lightweight', function () { let rejectCurvesVal; before(function() { //only x25519 crypto is fully functional in lightbuild diff --git a/test/general/config.js b/test/general/config.js index 10ba476b..b86b1eb7 100644 --- a/test/general/config.js +++ b/test/general/config.js @@ -1,8 +1,8 @@ -const { expect } = require('chai'); +import { expect } from 'chai'; -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..'); +const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); -module.exports = () => describe('Custom configuration', function() { +export default () => describe('Custom configuration', function() { it('openpgp.readMessage', async function() { const armoredMessage = await openpgp.encrypt({ message: await openpgp.createMessage({ text:'hello world' }), passwords: 'password' }); const message = await openpgp.readMessage({ armoredMessage }); diff --git a/test/general/decompression.js b/test/general/decompression.js index d6ebbc6a..844bd259 100644 --- a/test/general/decompression.js +++ b/test/general/decompression.js @@ -1,7 +1,8 @@ -const { use: chaiUse, expect } = require('chai'); -chaiUse(require('chai-as-promised')); +import { use as chaiUse, expect } from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..'); +const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); const password = 'I am a password'; @@ -38,7 +39,7 @@ Xg== } }; -module.exports = () => describe('Decrypt and decompress message tests', function () { +export default () => describe('Decrypt and decompress message tests', function () { function runTest(key, test) { it(`Decrypts message compressed with ${key}`, async function () { diff --git a/test/general/ecc_nist.js b/test/general/ecc_nist.js index 06287a68..93234716 100644 --- a/test/general/ecc_nist.js +++ b/test/general/ecc_nist.js @@ -1,13 +1,14 @@ -const { use: chaiUse, expect } = require('chai'); -chaiUse(require('chai-as-promised')); +import { use as chaiUse, expect } from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..'); +const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); -const util = require('../../src/util'); +import util from '../../src/util.js'; -const input = require('./testInputs'); +import * as input from './testInputs.js'; -module.exports = () => describe('Elliptic Curve Cryptography for NIST P-256,P-384,P-521 curves @lightweight', function () { +export default () => describe('Elliptic Curve Cryptography for NIST P-256,P-384,P-521 curves @lightweight', function () { function omnibus() { it('Omnibus NIST P-256 Test', async function () { const testData = input.createSomeMessage(); diff --git a/test/general/ecc_secp256k1.js b/test/general/ecc_secp256k1.js index a8d63741..f539a3ad 100644 --- a/test/general/ecc_secp256k1.js +++ b/test/general/ecc_secp256k1.js @@ -1,10 +1,11 @@ -const { use: chaiUse, expect } = require('chai'); -chaiUse(require('chai-as-promised')); +import { use as chaiUse, expect } from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..'); -const util = require('../../src/util'); +const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import util from '../../src/util.js'; -module.exports = () => describe('Elliptic Curve Cryptography for secp256k1 curve @lightweight', function () { +export default () => describe('Elliptic Curve Cryptography for secp256k1 curve @lightweight', function () { if (!openpgp.config.useIndutnyElliptic && !util.getNodeCrypto()) { before(function() { this.skip(); // eslint-disable-line no-invalid-this diff --git a/test/general/index.js b/test/general/index.js index 01a81a86..2ddf0794 100644 --- a/test/general/index.js +++ b/test/general/index.js @@ -1,18 +1,33 @@ -module.exports = () => describe('General', function () { - require('./util')(); - require('./biginteger')(); - require('./armor')(); - require('./packet')(); - require('./signature')(); - require('./key')(); - require('./openpgp')(); - require('./config')(); - require('./oid')(); - require('./ecc_nist')(); - require('./ecc_secp256k1')(); - require('./x25519')(); - require('./brainpool')(); - require('./decompression')(); - require('./streaming')(); -}); +import testX25519 from './x25519.js'; +import testUtil from './util.js'; +import testBigInteger from './biginteger.js'; +import testArmor from './armor.js'; +import testPacket from './packet.js'; +import testSignature from './signature.js'; +import testKey from './key.js'; +import testOpenPGP from './openpgp.js'; +import testConfig from './config.js'; +import testOID from './oid.js'; +import testNistECC from './ecc_nist.js'; +import testSecp256k1 from './ecc_secp256k1.js'; +import testBrainpool from './brainpool.js'; +import testDecompression from './decompression.js'; +import testStreaming from './streaming.js'; +export default () => describe('General', function () { + testX25519(); + testUtil(); + testBigInteger(); + testArmor(); + testPacket(); + testSignature(); + testKey(); + testOpenPGP(); + testConfig(); + testOID(); + testNistECC(); + testSecp256k1(); + testBrainpool(); + testDecompression(); + testStreaming(); +}); diff --git a/test/general/key.js b/test/general/key.js index 7bf66805..3024b933 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -1,12 +1,13 @@ /* eslint-disable max-lines */ /* globals tryTests */ -const { use: chaiUse, expect } = require('chai'); -chaiUse(require('chai-as-promised')); +import { use as chaiUse, expect } from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..'); -const util = require('../../src/util'); -const { isAEADSupported, getPreferredAlgo } = require('../../src/key'); -const KeyID = require('../../src/type/keyid'); +const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import util from '../../src/util.js'; +import { isAEADSupported, getPreferredAlgo } from '../../src/key'; +import KeyID from '../../src/type/keyid.js'; const priv_key_arm2 = @@ -2892,7 +2893,7 @@ function versionSpecificTests() { }); } -module.exports = () => describe('Key', function() { +export default () => describe('Key', function() { let v5KeysVal; let aeadProtectVal; diff --git a/test/general/oid.js b/test/general/oid.js index 8e500c41..b351cfc5 100644 --- a/test/general/oid.js +++ b/test/general/oid.js @@ -1,9 +1,9 @@ -const { expect } = require('chai'); +import { expect } from 'chai'; -const OID = require('../../src/type/oid'); -const util = require('../../src/util'); +import OID from '../../src/type/oid.js'; +import util from '../../src/util.js'; -module.exports = () => describe('Oid tests', function() { +export default () => describe('Oid tests', function() { const p256_oid = new Uint8Array([0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07]); const p384_oid = new Uint8Array([0x2B, 0x81, 0x04, 0x00, 0x22]); const p521_oid = new Uint8Array([0x2B, 0x81, 0x04, 0x00, 0x23]); diff --git a/test/general/openpgp.js b/test/general/openpgp.js index f03f13b5..5f41ba5f 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -1,18 +1,19 @@ /* eslint-disable max-lines */ /* globals tryTests, loadStreamsPolyfill */ -const spy = require('sinon/lib/sinon/spy'); -const stream = require('@openpgp/web-stream-tools'); -const { use: chaiUse, expect } = require('chai'); -chaiUse(require('chai-as-promised')); +import spy from 'sinon/lib/sinon/spy'; +import * as stream from '@openpgp/web-stream-tools'; +import { use as chaiUse, expect } from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..'); -const crypto = require('../../src/crypto'); -const random = require('../../src/crypto/random'); -const util = require('../../src/util'); -const keyIDType = require('../../src/type/keyid'); -const { isAEADSupported } = require('../../src/key'); +const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import crypto from '../../src/crypto'; +import * as random from '../../src/crypto/random.js'; +import util from '../../src/util.js'; +import keyIDType from '../../src/type/keyid.js'; +import { isAEADSupported } from '../../src/key'; -const input = require('./testInputs'); +import * as input from './testInputs.js'; const detectNode = () => typeof globalThis.process === 'object' && typeof globalThis.process.versions === 'object'; const detectBrowser = () => typeof navigator === 'object'; @@ -895,7 +896,7 @@ function withCompression(tests) { }); } -module.exports = () => describe('OpenPGP.js public api tests', function() { +export default () => describe('OpenPGP.js public api tests', function() { describe('readKey(s) and readPrivateKey(s) - unit tests', function() { it('readKey and readPrivateKey should create equal private keys', async function() { const key = await openpgp.readKey({ armoredKey: priv_key }); @@ -3064,7 +3065,7 @@ XfA3pqV4mTzF throw new Error('Was not able to successfully modify checksum'); } const badBodyEncrypted = data.replace(/\n=([a-zA-Z0-9/+]{4})/, 'aaa\n=$1'); - loadStreamsPolyfill(); + await loadStreamsPolyfill(); try { for (const allowStreaming of [true, false]) { openpgp.config.allowUnauthenticatedStream = allowStreaming; @@ -3329,9 +3330,9 @@ XfA3pqV4mTzF const plaintext = []; let i = 0; const useNativeStream = (() => { try { new global.ReadableStream(); return true; } catch (e) { return false; } })(); // eslint-disable-line no-new - loadStreamsPolyfill(); - const ReadableStream = useNativeStream ? global.ReadableStream : stream.ReadableStream; - const data = new ReadableStream({ + await loadStreamsPolyfill(); + const GenericReadableStream = useNativeStream ? global.ReadableStream : ReadableStream; + const data = new GenericReadableStream({ pull(controller) { if (i++ < 4) { const randomBytes = random.getRandomBytes(10); diff --git a/test/general/packet.js b/test/general/packet.js index 8fd963ac..ba229dbb 100644 --- a/test/general/packet.js +++ b/test/general/packet.js @@ -1,14 +1,15 @@ /* eslint-disable max-lines */ -const stream = require('@openpgp/web-stream-tools'); -const stub = require('sinon/lib/sinon/stub'); -const { use: chaiUse, expect } = require('chai'); -chaiUse(require('chai-as-promised')); +import * as stream from '@openpgp/web-stream-tools'; +import stub from 'sinon/lib/sinon/stub'; +import { use as chaiUse, expect } from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..'); -const crypto = require('../../src/crypto'); -const util = require('../../src/util'); +const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import crypto from '../../src/crypto'; +import util from '../../src/util.js'; -const input = require('./testInputs'); +import * as input from './testInputs.js'; function stringify(array) { if (stream.isStream(array)) { @@ -26,7 +27,7 @@ function stringify(array) { return result.join(''); } -module.exports = () => describe('Packet', function() { +export default () => describe('Packet', function() { const allAllowedPackets = util.constructAllowedPackets([...Object.values(openpgp).filter(packetClass => !!packetClass.tag)]); const armored_key = diff --git a/test/general/signature.js b/test/general/signature.js index 75468fb8..a4d8e31e 100644 --- a/test/general/signature.js +++ b/test/general/signature.js @@ -1,14 +1,15 @@ /* eslint-disable max-lines */ /* globals tryTests, loadStreamsPolyfill */ -const stream = require('@openpgp/web-stream-tools'); -const { use: chaiUse, expect } = require('chai'); -chaiUse(require('chai-as-promised')); +import * as stream from '@openpgp/web-stream-tools'; +import { use as chaiUse, expect } from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..'); +const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); -const util = require('../../src/util'); +import util from '../../src/util.js'; -module.exports = () => describe('Signature', function() { +export default () => describe('Signature', function() { const priv_key_arm1 = ['-----BEGIN PGP PRIVATE KEY BLOCK-----', 'Version: GnuPG v1.4.11 (GNU/Linux)', @@ -900,7 +901,7 @@ AkLaG/AkATpuH+DMkYDmKbDLGgD+N4yuxXBJmBfC2IBe4J1S2Gg= date: key.keyPacket.created, format: 'object' }); - loadStreamsPolyfill(); + await loadStreamsPolyfill(); const { signatures: [sigInfo] } = await openpgp.verify({ verificationKeys: expiredKey, message: await openpgp.readMessage({ armoredMessage: stream.toStream(armoredMessage) }), @@ -931,7 +932,7 @@ aMsUdQBgnPAcSGVsbG8gV29ybGQgOik= date: key.keyPacket.created, format: 'object' }); - loadStreamsPolyfill(); + await loadStreamsPolyfill(); const { signatures: [sigInfo] } = await openpgp.verify({ verificationKeys: expiredKey, message: await openpgp.readMessage({ armoredMessage: stream.toStream(armoredMessage) }), @@ -961,7 +962,7 @@ eSvSZutLuKKbidSYMLhWROPlwKc2GU2ws6PrLZAyCAel/lU= date: key.keyPacket.created, format: 'object' }); - loadStreamsPolyfill(); + await loadStreamsPolyfill(); const { signatures: [sigInfo] } = await openpgp.verify({ verificationKeys: expiredKey, message: await openpgp.readMessage({ armoredMessage: stream.toStream(armoredMessage) }), @@ -1454,7 +1455,7 @@ yYDnCgA= -----END PGP MESSAGE-----`.split(''); const plaintext = 'space: \nspace and tab: \t\nno trailing space\n \ntab:\t\ntab and space:\t '; - loadStreamsPolyfill(); + await loadStreamsPolyfill(); const message = await openpgp.readMessage({ armoredMessage: new ReadableStream({ async pull(controller) { @@ -1520,7 +1521,7 @@ hkJiXopCSWKSlQInL1devkJJUWJmTmZeugJYlpdLAagQJM0JpsCqIQZwKgAA -----END PGP MESSAGE-----`.split(''); const plaintext = 'space: \nspace and tab: \t\nno trailing space\n \ntab:\t\ntab and space:\t '; - loadStreamsPolyfill(); + await loadStreamsPolyfill(); const message = await openpgp.readMessage({ armoredMessage: new ReadableStream({ async pull(controller) { diff --git a/test/general/streaming.js b/test/general/streaming.js index 41b73dc9..b26db049 100644 --- a/test/general/streaming.js +++ b/test/general/streaming.js @@ -1,15 +1,16 @@ /* eslint-disable max-lines */ /* globals loadStreamsPolyfill */ -const stream = require('@openpgp/web-stream-tools'); -const stub = require('sinon/lib/sinon/stub'); -const { use: chaiUse, expect } = require('chai'); -chaiUse(require('chai-as-promised')); +import * as stream from '@openpgp/web-stream-tools'; +import stub from 'sinon/lib/sinon/stub'; +import { use as chaiUse, expect } from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..'); -const random = require('../../src/crypto/random'); -const util = require('../../src/util'); +const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import * as random from '../../src/crypto/random.js'; +import util from '../../src/util.js'; -const input = require('./testInputs'); +import * as input from './testInputs.js'; const useNativeStream = (() => { try { new global.ReadableStream(); return true; } catch (e) { return false; } })(); // eslint-disable-line no-new const NodeReadableStream = useNativeStream ? undefined : require('stream').Readable; @@ -890,7 +891,7 @@ function tests() { it("Don't pull entire input stream when we're not pulling decrypted stream (AEAD)", async function() { let coresStub; if (detectNode()) { - coresStub = stub(require('os'), 'cpus'); + coresStub = stub(util.nodeRequire('os'), 'cpus'); coresStub.returns(new Array(2)); // Object.defineProperty(require('os'), 'cpus', { value: () => [,], configurable: true }); } else { @@ -947,7 +948,7 @@ function tests() { }); } -module.exports = () => describe('Streaming', function() { +export default () => describe('Streaming', function() { let currentTest = 0; before(async function() { @@ -957,7 +958,7 @@ module.exports = () => describe('Streaming', function() { passphrase: 'hello world' }); - loadStreamsPolyfill(); + await loadStreamsPolyfill(); }); beforeEach(function() { @@ -1013,7 +1014,9 @@ module.exports = () => describe('Streaming', function() { tests(); if (detectNode()) { - const fs = require('fs'); + const fs = util.nodeRequire('fs'); + const { fileURLToPath } = util.nodeRequire('url'); + const __filename = fileURLToPath(import.meta.url); it('Node: Encrypt and decrypt text message roundtrip', async function() { dataArrived(); // Do not wait until data arrived. diff --git a/test/general/testInputs.js b/test/general/testInputs.js index 5879321b..44d59d32 100644 --- a/test/general/testInputs.js +++ b/test/general/testInputs.js @@ -12,6 +12,6 @@ function createSomeMessage() { return '  \t' + String.fromCodePoint(...arr).replace(/[\r\u2028\u2029]/g, '\n') + '  \t\n한국어/조선말'; } -module.exports = { - createSomeMessage: createSomeMessage +export { + createSomeMessage }; diff --git a/test/general/util.js b/test/general/util.js index d4833af2..25dab192 100644 --- a/test/general/util.js +++ b/test/general/util.js @@ -1,8 +1,7 @@ -const { expect } = require('chai'); -const util = require('../../src/util'); +import { expect } from 'chai'; +import util from '../../src/util'; - -module.exports = () => describe('Util unit tests', function() { +export default () => describe('Util unit tests', function() { describe('isString', function() { it('should return true for type "string"', function() { diff --git a/test/general/x25519.js b/test/general/x25519.js index 0a465b83..0cf9e2e3 100644 --- a/test/general/x25519.js +++ b/test/general/x25519.js @@ -1,17 +1,19 @@ -const { use: chaiUse, expect } = require('chai'); -chaiUse(require('chai-as-promised')); +import { use as chaiUse, expect } from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chaiUse(chaiAsPromised); -const nacl = require('@openpgp/tweetnacl'); +const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..'); -const elliptic = require('../../src/crypto/public_key/elliptic'); -const signature = require('../../src/crypto/signature'); -const OID = require('../../src/type/oid'); -const util = require('../../src/util'); +import nacl from '@openpgp/tweetnacl'; -const input = require('./testInputs'); +import * as elliptic from '../../src/crypto/public_key/elliptic'; +import * as signature from '../../src/crypto/signature'; +import OID from '../../src/type/oid'; +import util from '../../src/util'; -module.exports = () => (openpgp.config.ci ? describe.skip : describe)('X25519 Cryptography (legacy format)', function () { +import * as input from './testInputs'; + +export default () => (openpgp.config.ci ? describe.skip : describe)('X25519 Cryptography (legacy format)', function () { const data = { light: { id: '1ecdf026c0245830', diff --git a/test/karma.conf.js b/test/karma.conf.cjs similarity index 100% rename from test/karma.conf.js rename to test/karma.conf.cjs diff --git a/test/security/index.js b/test/security/index.js index a83ecc21..6c227fc3 100644 --- a/test/security/index.js +++ b/test/security/index.js @@ -1,6 +1,11 @@ -module.exports = () => describe('Security', function () { - require('./message_signature_bypass')(); - require('./unsigned_subpackets')(); - require('./subkey_trust')(); - require('./preferred_algo_mismatch')(); +import testMessageSignatureBypess from './message_signature_bypass'; +import testUnsignedSubpackets from './unsigned_subpackets'; +import testSubkeyTrust from './subkey_trust'; +import testPreferredAlgoMismatch from './preferred_algo_mismatch'; + +export default () => describe('Security', function () { + testMessageSignatureBypess(); + testUnsignedSubpackets(); + testSubkeyTrust(); + testPreferredAlgoMismatch(); }); diff --git a/test/security/message_signature_bypass.js b/test/security/message_signature_bypass.js index 0a6276a9..28f7879f 100644 --- a/test/security/message_signature_bypass.js +++ b/test/security/message_signature_bypass.js @@ -1,8 +1,9 @@ -const { use: chaiUse, expect } = require('chai'); -chaiUse(require('chai-as-promised')); +import { use as chaiUse, expect } from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..'); -const util = require('../../src/util'); +const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import util from '../../src/util.js'; const { readKey, readCleartextMessage, SignaturePacket } = openpgp; @@ -101,4 +102,4 @@ async function fakeSignature() { expect(signatures).to.have.length(0); } -module.exports = () => it('Does not accept non-binary/text signatures', fakeSignature); +export default () => it('Does not accept non-binary/text signatures', fakeSignature); diff --git a/test/security/preferred_algo_mismatch.js b/test/security/preferred_algo_mismatch.js index e53c710e..4277eb48 100644 --- a/test/security/preferred_algo_mismatch.js +++ b/test/security/preferred_algo_mismatch.js @@ -1,7 +1,8 @@ -const { use: chaiUse, expect } = require('chai'); -chaiUse(require('chai-as-promised')); +import { use as chaiUse, expect } from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..'); +const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); const armoredMessage = `-----BEGIN PGP MESSAGE----- Version: OpenPGP.js VERSION @@ -38,7 +39,7 @@ EnxUPL95HuMKoVkf4w== =oopr -----END PGP PRIVATE KEY BLOCK-----`; -module.exports = () => it('Does not accept message encrypted with algo not mentioned in preferred algorithms', async function() { +export default () => it('Does not accept message encrypted with algo not mentioned in preferred algorithms', async function() { const message = await openpgp.readMessage({ armoredMessage }); const privKey = await openpgp.readKey({ armoredKey: privateKeyArmor }); await expect(openpgp.decrypt({ message, decryptionKeys: [privKey] })).to.be.rejectedWith('A non-preferred symmetric algorithm was used.'); diff --git a/test/security/subkey_trust.js b/test/security/subkey_trust.js index 3aec7588..54dcca56 100644 --- a/test/security/subkey_trust.js +++ b/test/security/subkey_trust.js @@ -1,7 +1,9 @@ -const { use: chaiUse, expect } = require('chai'); -chaiUse(require('chai-as-promised')); +import { use as chaiUse, expect } from 'chai'; +import chaiAsPromised from 'chai-as-promised'; -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..'); +chaiUse(chaiAsPromised); + +const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); const { readKey, PublicKey, readCleartextMessage, createCleartextMessage, enums, PacketList, SignaturePacket } = openpgp; @@ -33,7 +35,7 @@ async function generateTestData() { }; } -module.exports = () => it('Does not trust subkeys without Primary Key Binding Signature', async function() { +export default () => it('Does not trust subkeys without Primary Key Binding Signature', async function() { // attacker only has his own private key, // the victim's public key and a signed message const { victimPubKey, attackerPrivKey, signed } = await generateTestData(); diff --git a/test/security/unsigned_subpackets.js b/test/security/unsigned_subpackets.js index cc559bc4..68ca86ca 100644 --- a/test/security/unsigned_subpackets.js +++ b/test/security/unsigned_subpackets.js @@ -1,7 +1,9 @@ -const { use: chaiUse, expect } = require('chai'); -chaiUse(require('chai-as-promised')); +import { use as chaiUse, expect } from 'chai'; +import chaiAsPromised from 'chai-as-promised'; -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..'); +chaiUse(chaiAsPromised); + +const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); const { readKey, PrivateKey, createMessage, enums, PacketList, SignaturePacket } = openpgp; @@ -89,4 +91,4 @@ async function makeKeyValid() { expect(await encryptFails(modifiedkey)).to.be.true; } -module.exports = () => it('Does not accept unsigned subpackets', makeKeyValid); +export default () => it('Does not accept unsigned subpackets', makeKeyValid); diff --git a/test/typescript/definitions.ts b/test/typescript/definitions.ts index 5d61f9c6..c3513ef4 100644 --- a/test/typescript/definitions.ts +++ b/test/typescript/definitions.ts @@ -16,7 +16,7 @@ import { generateSessionKey, encryptSessionKey, decryptSessionKeys, LiteralDataPacket, PacketList, CompressedDataPacket, PublicKeyPacket, PublicSubkeyPacket, SecretKeyPacket, SecretSubkeyPacket, CleartextMessage, WebStream, NodeStream, -} from '../..'; +} from 'openpgp'; (async () => { diff --git a/test/unittests.js b/test/unittests.js index 4bf00069..a9460817 100644 --- a/test/unittests.js +++ b/test/unittests.js @@ -1,4 +1,6 @@ -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('..'); +import * as openpgp from 'openpgp'; +if (typeof window !== 'undefined' && !window.openpgp) { window.openpgp = openpgp } + (typeof window !== 'undefined' ? window : global).globalThis = (typeof window !== 'undefined' ? window : global); @@ -27,9 +29,14 @@ globalThis.tryTests = function(name, tests, options) { }; globalThis.loadStreamsPolyfill = function() { - require('web-streams-polyfill/es2018'); // eslint-disable-line import/no-unassigned-import + return import('web-streams-polyfill'); }; +import runWorkerTests from './worker'; +import runCryptoTests from './crypto'; +import runGeneralTests from './general'; +import runSecurityTests from './security'; + describe('Unit Tests', function () { openpgp.config.s2kIterationCountByte = 0; @@ -59,8 +66,8 @@ describe('Unit Tests', function () { }); } - require('./worker')(); - require('./crypto')(); - require('./general')(); - require('./security')(); + runWorkerTests(); + runCryptoTests(); + runGeneralTests(); + runSecurityTests(); }); diff --git a/test/worker/application_worker.js b/test/worker/application_worker.js index cbd1fa94..1ffdc558 100644 --- a/test/worker/application_worker.js +++ b/test/worker/application_worker.js @@ -1,9 +1,8 @@ /* globals tryTests */ -const { expect } = require('chai'); +import { expect } from 'chai'; -/* eslint-disable no-invalid-this */ -module.exports = () => tryTests('Application Worker', tests, { +export default () => tryTests('Application Worker', tests, { if: typeof window !== 'undefined' && window.Worker && window.MessageChannel }); diff --git a/test/worker/index.js b/test/worker/index.js index 8d1b8b72..2654cac6 100644 --- a/test/worker/index.js +++ b/test/worker/index.js @@ -1,4 +1,6 @@ -module.exports = () => describe('Web Worker', function () { - require('./application_worker')(); +import testApplicationWorker from './application_worker.js'; + +export default () => describe('Web Worker', function () { + testApplicationWorker(); }); diff --git a/tsconfig.json b/tsconfig.json index 60f1e065..a41b561b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,8 +1,12 @@ { - "exclude": [ - "./build/" - ], "compilerOptions": { - "strict": true + "strict": true, + "target": "es2021", + "module": "esnext", + "moduleResolution": "node", + "allowJs": true, + "paths": { + "openpgp": [ "." ] + }, } } From ae4ed1fbf3794ddc48f24438f9306807c29f4efe Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Fri, 2 Jun 2023 14:12:14 +0200 Subject: [PATCH 009/201] Tests: explicitly share openpgp instance used in tests Also, init config before any code is run in tests --- .eslintrc.js | 1 + test/crypto/crypto.js | 4 ++-- test/crypto/eax.js | 4 ++-- test/crypto/ecdh.js | 4 ++-- test/crypto/elliptic.js | 4 ++-- test/crypto/gcm.js | 4 ++-- test/crypto/ocb.js | 4 ++-- test/crypto/rsa.js | 4 ++-- test/crypto/validate.js | 4 ++-- test/general/armor.js | 2 +- test/general/biginteger.js | 2 +- test/general/brainpool.js | 4 ++-- test/general/config.js | 2 +- test/general/decompression.js | 4 ++-- test/general/ecc_nist.js | 4 ++-- test/general/ecc_secp256k1.js | 4 ++-- test/general/key.js | 4 ++-- test/general/openpgp.js | 4 ++-- test/general/packet.js | 4 ++-- test/general/signature.js | 4 ++-- test/general/streaming.js | 4 ++-- test/general/x25519.js | 5 ++--- test/initOpenpgp.js | 14 ++++++++++++++ test/security/message_signature_bypass.js | 4 ++-- test/security/preferred_algo_mismatch.js | 4 ++-- test/security/subkey_trust.js | 5 ++--- test/security/unsigned_subpackets.js | 5 ++--- test/unittests.js | 7 +------ 28 files changed, 63 insertions(+), 56 deletions(-) create mode 100644 test/initOpenpgp.js diff --git a/.eslintrc.js b/.eslintrc.js index 6a58bb27..93758d15 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -96,6 +96,7 @@ module.exports = { // eslint-plugin-import rules: 'import/named': 'error', 'import/extensions': 'error', + 'import/first': 'off', 'import/no-extraneous-dependencies': ['error', { 'devDependencies': true, 'optionalDependencies': false, 'peerDependencies': false }], 'import/no-unassigned-import': 'error', 'import/prefer-default-export': 'off', diff --git a/test/crypto/crypto.js b/test/crypto/crypto.js index 5f2f7b31..05d89880 100644 --- a/test/crypto/crypto.js +++ b/test/crypto/crypto.js @@ -1,9 +1,9 @@ import { use as chaiUse, expect } from 'chai'; -import chaiAsPromised from 'chai-as-promised'; +import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); import sandbox from 'sinon/lib/sinon/sandbox'; +import openpgp from '../initOpenpgp.js'; import crypto from '../../src/crypto'; import util from '../../src/util.js'; diff --git a/test/crypto/eax.js b/test/crypto/eax.js index 5c8e535d..54023f46 100644 --- a/test/crypto/eax.js +++ b/test/crypto/eax.js @@ -3,10 +3,10 @@ // Adapted from https://github.com/artjomb/cryptojs-extension/blob/8c61d159/test/eax.js import sandbox from 'sinon/lib/sinon/sandbox'; import { use as chaiUse, expect } from 'chai'; -import chaiAsPromised from 'chai-as-promised'; +import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import openpgp from '../initOpenpgp.js'; import EAX from '../../src/crypto/mode/eax.js'; import util from '../../src/util.js'; diff --git a/test/crypto/ecdh.js b/test/crypto/ecdh.js index fc0edb19..35ae5c3a 100644 --- a/test/crypto/ecdh.js +++ b/test/crypto/ecdh.js @@ -1,9 +1,9 @@ import sandbox from 'sinon/lib/sinon/sandbox'; import { use as chaiUse, expect } from 'chai'; -import chaiAsPromised from 'chai-as-promised'; +import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import openpgp from '../initOpenpgp.js'; import OID from '../../src/type/oid.js'; import KDFParams from '../../src/type/kdf_params.js'; import * as elliptic_curves from '../../src/crypto/public_key/elliptic'; diff --git a/test/crypto/elliptic.js b/test/crypto/elliptic.js index 6072ae44..c92102b1 100644 --- a/test/crypto/elliptic.js +++ b/test/crypto/elliptic.js @@ -1,9 +1,9 @@ import sandbox from 'sinon/lib/sinon/sandbox'; import { use as chaiUse, expect } from 'chai'; -import chaiAsPromised from 'chai-as-promised'; +import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import openpgp from '../initOpenpgp.js'; import * as elliptic_curves from '../../src/crypto/public_key/elliptic'; import hashMod from '../../src/crypto/hash'; import config from '../../src/config'; diff --git a/test/crypto/gcm.js b/test/crypto/gcm.js index 4e06806e..441d6f9c 100644 --- a/test/crypto/gcm.js +++ b/test/crypto/gcm.js @@ -1,9 +1,9 @@ import sandbox from 'sinon/lib/sinon/sandbox'; import { use as chaiUse, expect } from 'chai'; -import chaiAsPromised from 'chai-as-promised'; +import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import openpgp from '../initOpenpgp.js'; import crypto from '../../src/crypto'; import util from '../../src/util.js'; diff --git a/test/crypto/ocb.js b/test/crypto/ocb.js index 67bea175..ef80a96b 100644 --- a/test/crypto/ocb.js +++ b/test/crypto/ocb.js @@ -2,10 +2,10 @@ // Adapted from https://github.com/artjomb/cryptojs-extension/blob/8c61d159/test/eax.js import { use as chaiUse, expect } from 'chai'; -import chaiAsPromised from 'chai-as-promised'; +import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import openpgp from '../initOpenpgp.js'; import OCB from '../../src/crypto/mode/ocb.js'; import util from '../../src/util.js'; diff --git a/test/crypto/rsa.js b/test/crypto/rsa.js index 4aa24d61..1be4a127 100644 --- a/test/crypto/rsa.js +++ b/test/crypto/rsa.js @@ -1,9 +1,9 @@ import sandbox from 'sinon/lib/sinon/sandbox'; import { use as chaiUse, expect } from 'chai'; -import chaiAsPromised from 'chai-as-promised'; +import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import openpgp from '../initOpenpgp.js'; import crypto from '../../src/crypto'; import * as random from '../../src/crypto/random.js'; import util from '../../src/util.js'; diff --git a/test/crypto/validate.js b/test/crypto/validate.js index 610728b5..54d79ca3 100644 --- a/test/crypto/validate.js +++ b/test/crypto/validate.js @@ -1,9 +1,9 @@ import BN from 'bn.js'; import { use as chaiUse, expect } from 'chai'; -import chaiAsPromised from 'chai-as-promised'; +import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import openpgp from '../initOpenpgp.js'; const armoredDSAKey = `-----BEGIN PGP PRIVATE KEY BLOCK----- diff --git a/test/general/armor.js b/test/general/armor.js index 53119f2b..10624ee2 100644 --- a/test/general/armor.js +++ b/test/general/armor.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import openpgp from '../initOpenpgp.js'; export default () => describe('ASCII armor', function() { diff --git a/test/general/biginteger.js b/test/general/biginteger.js index 142b5026..90fd0d38 100644 --- a/test/general/biginteger.js +++ b/test/general/biginteger.js @@ -1,5 +1,5 @@ import { use as chaiUse, expect } from 'chai'; -import chaiAsPromised from 'chai-as-promised'; +import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import chaiUse(chaiAsPromised); import BN from 'bn.js'; diff --git a/test/general/brainpool.js b/test/general/brainpool.js index ce662ca6..e22dae58 100644 --- a/test/general/brainpool.js +++ b/test/general/brainpool.js @@ -1,9 +1,9 @@ /* globals tryTests */ import { use as chaiUse, expect } from 'chai'; -import chaiAsPromised from 'chai-as-promised'; +import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import openpgp from '../initOpenpgp.js'; import util from '../../src/util.js'; import * as input from './testInputs.js'; diff --git a/test/general/config.js b/test/general/config.js index b86b1eb7..038e72f5 100644 --- a/test/general/config.js +++ b/test/general/config.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import openpgp from '../initOpenpgp.js'; export default () => describe('Custom configuration', function() { it('openpgp.readMessage', async function() { diff --git a/test/general/decompression.js b/test/general/decompression.js index 844bd259..7680a73d 100644 --- a/test/general/decompression.js +++ b/test/general/decompression.js @@ -1,8 +1,8 @@ import { use as chaiUse, expect } from 'chai'; -import chaiAsPromised from 'chai-as-promised'; +import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import openpgp from '../initOpenpgp.js'; const password = 'I am a password'; diff --git a/test/general/ecc_nist.js b/test/general/ecc_nist.js index 93234716..1838e031 100644 --- a/test/general/ecc_nist.js +++ b/test/general/ecc_nist.js @@ -1,8 +1,8 @@ import { use as chaiUse, expect } from 'chai'; -import chaiAsPromised from 'chai-as-promised'; +import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import openpgp from '../initOpenpgp.js'; import util from '../../src/util.js'; diff --git a/test/general/ecc_secp256k1.js b/test/general/ecc_secp256k1.js index f539a3ad..da457640 100644 --- a/test/general/ecc_secp256k1.js +++ b/test/general/ecc_secp256k1.js @@ -1,8 +1,8 @@ import { use as chaiUse, expect } from 'chai'; -import chaiAsPromised from 'chai-as-promised'; +import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import openpgp from '../initOpenpgp.js'; import util from '../../src/util.js'; export default () => describe('Elliptic Curve Cryptography for secp256k1 curve @lightweight', function () { diff --git a/test/general/key.js b/test/general/key.js index 3024b933..661f1904 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -1,10 +1,10 @@ /* eslint-disable max-lines */ /* globals tryTests */ import { use as chaiUse, expect } from 'chai'; -import chaiAsPromised from 'chai-as-promised'; +import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import openpgp from '../initOpenpgp.js'; import util from '../../src/util.js'; import { isAEADSupported, getPreferredAlgo } from '../../src/key'; import KeyID from '../../src/type/keyid.js'; diff --git a/test/general/openpgp.js b/test/general/openpgp.js index 5f41ba5f..1d435d60 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -3,10 +3,10 @@ import spy from 'sinon/lib/sinon/spy'; import * as stream from '@openpgp/web-stream-tools'; import { use as chaiUse, expect } from 'chai'; -import chaiAsPromised from 'chai-as-promised'; +import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import openpgp from '../initOpenpgp.js'; import crypto from '../../src/crypto'; import * as random from '../../src/crypto/random.js'; import util from '../../src/util.js'; diff --git a/test/general/packet.js b/test/general/packet.js index ba229dbb..5590e6cd 100644 --- a/test/general/packet.js +++ b/test/general/packet.js @@ -2,10 +2,10 @@ import * as stream from '@openpgp/web-stream-tools'; import stub from 'sinon/lib/sinon/stub'; import { use as chaiUse, expect } from 'chai'; -import chaiAsPromised from 'chai-as-promised'; +import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import openpgp from '../initOpenpgp.js'; import crypto from '../../src/crypto'; import util from '../../src/util.js'; diff --git a/test/general/signature.js b/test/general/signature.js index a4d8e31e..1c123f75 100644 --- a/test/general/signature.js +++ b/test/general/signature.js @@ -2,10 +2,10 @@ /* globals tryTests, loadStreamsPolyfill */ import * as stream from '@openpgp/web-stream-tools'; import { use as chaiUse, expect } from 'chai'; -import chaiAsPromised from 'chai-as-promised'; +import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import openpgp from '../initOpenpgp.js'; import util from '../../src/util.js'; diff --git a/test/general/streaming.js b/test/general/streaming.js index b26db049..1a1ad5fb 100644 --- a/test/general/streaming.js +++ b/test/general/streaming.js @@ -3,10 +3,10 @@ import * as stream from '@openpgp/web-stream-tools'; import stub from 'sinon/lib/sinon/stub'; import { use as chaiUse, expect } from 'chai'; -import chaiAsPromised from 'chai-as-promised'; +import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import openpgp from '../initOpenpgp.js'; import * as random from '../../src/crypto/random.js'; import util from '../../src/util.js'; diff --git a/test/general/x25519.js b/test/general/x25519.js index 0cf9e2e3..52bd19c2 100644 --- a/test/general/x25519.js +++ b/test/general/x25519.js @@ -1,10 +1,9 @@ import { use as chaiUse, expect } from 'chai'; -import chaiAsPromised from 'chai-as-promised'; +import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); - import nacl from '@openpgp/tweetnacl'; +import openpgp from '../initOpenpgp.js'; import * as elliptic from '../../src/crypto/public_key/elliptic'; import * as signature from '../../src/crypto/signature'; diff --git a/test/initOpenpgp.js b/test/initOpenpgp.js new file mode 100644 index 00000000..4fd4a360 --- /dev/null +++ b/test/initOpenpgp.js @@ -0,0 +1,14 @@ +/** + * This module centralises the openpgp import and ensures that the module is initialised + * at the top of the test bundle, and that the config is initialised before the tests code runs (incl. that outside of `describe`). + */ + +import * as openpgp from 'openpgp'; + +if (typeof window !== 'undefined') { + window.openpgp = openpgp; +} + +openpgp.config.s2kIterationCountByte = 0; + +export default openpgp; diff --git a/test/security/message_signature_bypass.js b/test/security/message_signature_bypass.js index 28f7879f..614d5c05 100644 --- a/test/security/message_signature_bypass.js +++ b/test/security/message_signature_bypass.js @@ -1,8 +1,8 @@ import { use as chaiUse, expect } from 'chai'; -import chaiAsPromised from 'chai-as-promised'; +import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import openpgp from '../initOpenpgp.js'; import util from '../../src/util.js'; const { readKey, readCleartextMessage, SignaturePacket } = openpgp; diff --git a/test/security/preferred_algo_mismatch.js b/test/security/preferred_algo_mismatch.js index 4277eb48..c000d9d7 100644 --- a/test/security/preferred_algo_mismatch.js +++ b/test/security/preferred_algo_mismatch.js @@ -1,8 +1,8 @@ import { use as chaiUse, expect } from 'chai'; -import chaiAsPromised from 'chai-as-promised'; +import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import openpgp from '../initOpenpgp.js'; const armoredMessage = `-----BEGIN PGP MESSAGE----- Version: OpenPGP.js VERSION diff --git a/test/security/subkey_trust.js b/test/security/subkey_trust.js index 54dcca56..e8aee45b 100644 --- a/test/security/subkey_trust.js +++ b/test/security/subkey_trust.js @@ -1,9 +1,8 @@ import { use as chaiUse, expect } from 'chai'; -import chaiAsPromised from 'chai-as-promised'; - +import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import openpgp from '../initOpenpgp.js'; const { readKey, PublicKey, readCleartextMessage, createCleartextMessage, enums, PacketList, SignaturePacket } = openpgp; diff --git a/test/security/unsigned_subpackets.js b/test/security/unsigned_subpackets.js index 68ca86ca..82721103 100644 --- a/test/security/unsigned_subpackets.js +++ b/test/security/unsigned_subpackets.js @@ -1,9 +1,8 @@ import { use as chaiUse, expect } from 'chai'; -import chaiAsPromised from 'chai-as-promised'; - +import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import chaiUse(chaiAsPromised); -const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : await import('openpgp'); +import openpgp from '../initOpenpgp.js'; const { readKey, PrivateKey, createMessage, enums, PacketList, SignaturePacket } = openpgp; diff --git a/test/unittests.js b/test/unittests.js index a9460817..54f63c3c 100644 --- a/test/unittests.js +++ b/test/unittests.js @@ -1,6 +1,4 @@ -import * as openpgp from 'openpgp'; -if (typeof window !== 'undefined' && !window.openpgp) { window.openpgp = openpgp } - +import openpgp from './initOpenpgp.js'; (typeof window !== 'undefined' ? window : global).globalThis = (typeof window !== 'undefined' ? window : global); @@ -38,9 +36,6 @@ import runGeneralTests from './general'; import runSecurityTests from './security'; describe('Unit Tests', function () { - - openpgp.config.s2kIterationCountByte = 0; - if (typeof window !== 'undefined') { // Safari 14.1.*, 15.* and 16.* seem to have issues handling rejections when their native TransformStream implementation is involved, // so for now we ignore unhandled rejections for those browser versions. From b094274d98104e368a9236b8536fdd2503b58b08 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Wed, 17 May 2023 13:42:25 +0200 Subject: [PATCH 010/201] Remove @private JSDoc directives interfering with TS --- src/crypto/aes_kw.js | 1 - src/crypto/cipher/index.js | 1 - src/crypto/crypto.js | 1 - src/crypto/hash/index.js | 1 - src/crypto/hkdf.js | 1 - src/crypto/index.js | 1 - src/crypto/mode/cfb.js | 1 - src/crypto/mode/gcm.js | 1 - src/crypto/mode/ocb.js | 1 - src/crypto/pkcs1.js | 1 - src/crypto/public_key/dsa.js | 1 - src/crypto/public_key/elgamal.js | 1 - src/crypto/public_key/elliptic/ecdh.js | 1 - src/crypto/public_key/elliptic/ecdh_x.js | 1 - src/crypto/public_key/elliptic/ecdsa.js | 1 - src/crypto/public_key/elliptic/eddsa.js | 1 - src/crypto/public_key/elliptic/eddsa_legacy.js | 1 - src/crypto/public_key/elliptic/index.js | 1 - src/crypto/public_key/elliptic/indutnyKey.js | 1 - src/crypto/public_key/elliptic/oid_curves.js | 1 - src/crypto/public_key/index.js | 1 - src/crypto/public_key/prime.js | 1 - src/crypto/public_key/rsa.js | 1 - src/crypto/random.js | 1 - src/crypto/signature.js | 1 - src/encoding/base64.js | 1 - src/key/helper.js | 1 - src/key/user.js | 1 - src/packet/packet.js | 1 - src/type/ecdh_symkey.js | 1 - src/type/keyid.js | 1 - src/type/oid.js | 1 - src/type/s2k/generic.js | 1 - src/util.js | 1 - 34 files changed, 34 deletions(-) diff --git a/src/crypto/aes_kw.js b/src/crypto/aes_kw.js index d9bbbb3e..e747ecc3 100644 --- a/src/crypto/aes_kw.js +++ b/src/crypto/aes_kw.js @@ -19,7 +19,6 @@ * @fileoverview Implementation of RFC 3394 AES Key Wrap & Key Unwrap funcions * @see module:crypto/public_key/elliptic/ecdh * @module crypto/aes_kw - * @private */ import * as cipher from './cipher'; diff --git a/src/crypto/cipher/index.js b/src/crypto/cipher/index.js index 4f96ef38..d40c8e08 100644 --- a/src/crypto/cipher/index.js +++ b/src/crypto/cipher/index.js @@ -1,7 +1,6 @@ /** * @fileoverview Symmetric cryptography functions * @module crypto/cipher - * @private */ import aes from './aes'; diff --git a/src/crypto/crypto.js b/src/crypto/crypto.js index 0cb86be1..aa6e6f34 100644 --- a/src/crypto/crypto.js +++ b/src/crypto/crypto.js @@ -21,7 +21,6 @@ * @fileoverview Provides functions for asymmetric encryption and decryption as * well as key generation and parameter handling for all public-key cryptosystems. * @module crypto/crypto - * @private */ import publicKey from './public_key'; diff --git a/src/crypto/hash/index.js b/src/crypto/hash/index.js index 0765881e..d5752841 100644 --- a/src/crypto/hash/index.js +++ b/src/crypto/hash/index.js @@ -3,7 +3,6 @@ * @see {@link https://github.com/asmcrypto/asmcrypto.js|asmCrypto} * @see {@link https://github.com/indutny/hash.js|hash.js} * @module crypto/hash - * @private */ import { Sha1 } from '@openpgp/asmcrypto.js/dist_es8/hash/sha1/sha1'; diff --git a/src/crypto/hkdf.js b/src/crypto/hkdf.js index a14d751c..cf531aed 100644 --- a/src/crypto/hkdf.js +++ b/src/crypto/hkdf.js @@ -1,7 +1,6 @@ /** * @fileoverview This module implements HKDF using either the WebCrypto API or Node.js' crypto API. * @module crypto/hkdf - * @private */ import enums from '../enums'; diff --git a/src/crypto/index.js b/src/crypto/index.js index ab6b166a..460140c1 100644 --- a/src/crypto/index.js +++ b/src/crypto/index.js @@ -7,7 +7,6 @@ * @see module:crypto/random * @see module:crypto/hash * @module crypto - * @private */ import * as cipher from './cipher'; diff --git a/src/crypto/mode/cfb.js b/src/crypto/mode/cfb.js index e16f88b6..a1bdb526 100644 --- a/src/crypto/mode/cfb.js +++ b/src/crypto/mode/cfb.js @@ -19,7 +19,6 @@ /** * @module crypto/mode/cfb - * @private */ import { AES_CFB } from '@openpgp/asmcrypto.js/dist_es8/aes/cfb'; diff --git a/src/crypto/mode/gcm.js b/src/crypto/mode/gcm.js index 25c7a059..c5b5e332 100644 --- a/src/crypto/mode/gcm.js +++ b/src/crypto/mode/gcm.js @@ -19,7 +19,6 @@ * @fileoverview This module wraps native AES-GCM en/decryption for both * the WebCrypto api as well as node.js' crypto api. * @module crypto/mode/gcm - * @private */ import { AES_GCM } from '@openpgp/asmcrypto.js/dist_es8/aes/gcm'; diff --git a/src/crypto/mode/ocb.js b/src/crypto/mode/ocb.js index 868b0ebc..3cd1926c 100644 --- a/src/crypto/mode/ocb.js +++ b/src/crypto/mode/ocb.js @@ -18,7 +18,6 @@ /** * @fileoverview This module implements AES-OCB en/decryption. * @module crypto/mode/ocb - * @private */ import * as ciphers from '../cipher'; diff --git a/src/crypto/pkcs1.js b/src/crypto/pkcs1.js index db981322..229081e8 100644 --- a/src/crypto/pkcs1.js +++ b/src/crypto/pkcs1.js @@ -21,7 +21,6 @@ * @see module:crypto/public_key/elliptic/ecdh * @see PublicKeyEncryptedSessionKeyPacket * @module crypto/pkcs1 - * @private */ import { getRandomBytes } from './random'; diff --git a/src/crypto/public_key/dsa.js b/src/crypto/public_key/dsa.js index 7fa69649..286adb64 100644 --- a/src/crypto/public_key/dsa.js +++ b/src/crypto/public_key/dsa.js @@ -18,7 +18,6 @@ /** * @fileoverview A Digital signature algorithm implementation * @module crypto/public_key/dsa - * @private */ import { getRandomBigInteger } from '../random'; import util from '../../util'; diff --git a/src/crypto/public_key/elgamal.js b/src/crypto/public_key/elgamal.js index bcd41efe..2f69e6f0 100644 --- a/src/crypto/public_key/elgamal.js +++ b/src/crypto/public_key/elgamal.js @@ -18,7 +18,6 @@ /** * @fileoverview ElGamal implementation * @module crypto/public_key/elgamal - * @private */ import util from '../../util'; diff --git a/src/crypto/public_key/elliptic/ecdh.js b/src/crypto/public_key/elliptic/ecdh.js index 11238f71..e37fb633 100644 --- a/src/crypto/public_key/elliptic/ecdh.js +++ b/src/crypto/public_key/elliptic/ecdh.js @@ -18,7 +18,6 @@ /** * @fileoverview Key encryption and decryption for RFC 6637 ECDH * @module crypto/public_key/elliptic/ecdh - * @private */ import nacl from '@openpgp/tweetnacl/nacl-fast-light'; diff --git a/src/crypto/public_key/elliptic/ecdh_x.js b/src/crypto/public_key/elliptic/ecdh_x.js index 3b66c0c0..1e0b3861 100644 --- a/src/crypto/public_key/elliptic/ecdh_x.js +++ b/src/crypto/public_key/elliptic/ecdh_x.js @@ -1,7 +1,6 @@ /** * @fileoverview Key encryption and decryption for RFC 6637 ECDH * @module crypto/public_key/elliptic/ecdh - * @private */ import nacl from '@openpgp/tweetnacl/nacl-fast-light'; diff --git a/src/crypto/public_key/elliptic/ecdsa.js b/src/crypto/public_key/elliptic/ecdsa.js index a11e49c2..19412aa1 100644 --- a/src/crypto/public_key/elliptic/ecdsa.js +++ b/src/crypto/public_key/elliptic/ecdsa.js @@ -18,7 +18,6 @@ /** * @fileoverview Implementation of ECDSA following RFC6637 for Openpgpjs * @module crypto/public_key/elliptic/ecdsa - * @private */ import enums from '../../../enums'; diff --git a/src/crypto/public_key/elliptic/eddsa.js b/src/crypto/public_key/elliptic/eddsa.js index e38cbb96..413f967f 100644 --- a/src/crypto/public_key/elliptic/eddsa.js +++ b/src/crypto/public_key/elliptic/eddsa.js @@ -18,7 +18,6 @@ /** * @fileoverview Implementation of EdDSA following RFC4880bis-03 for OpenPGP * @module crypto/public_key/elliptic/eddsa - * @private */ import sha512 from 'hash.js/lib/hash/sha/512'; diff --git a/src/crypto/public_key/elliptic/eddsa_legacy.js b/src/crypto/public_key/elliptic/eddsa_legacy.js index 63929ea7..726d7ce0 100644 --- a/src/crypto/public_key/elliptic/eddsa_legacy.js +++ b/src/crypto/public_key/elliptic/eddsa_legacy.js @@ -19,7 +19,6 @@ * @fileoverview Implementation of legacy EdDSA following RFC4880bis-03 for OpenPGP. * This key type has been deprecated by the crypto-refresh RFC. * @module crypto/public_key/elliptic/eddsa_legacy - * @private */ import sha512 from 'hash.js/lib/hash/sha/512'; diff --git a/src/crypto/public_key/elliptic/index.js b/src/crypto/public_key/elliptic/index.js index 562918b9..61a75a23 100644 --- a/src/crypto/public_key/elliptic/index.js +++ b/src/crypto/public_key/elliptic/index.js @@ -22,7 +22,6 @@ * @see module:crypto/public_key/elliptic/ecdsa * @see module:crypto/public_key/elliptic/eddsa * @module crypto/public_key/elliptic - * @private */ import { CurveWithOID, generate, getPreferredHashAlgo } from './oid_curves'; diff --git a/src/crypto/public_key/elliptic/indutnyKey.js b/src/crypto/public_key/elliptic/indutnyKey.js index aa7565c5..ddfc6aa7 100644 --- a/src/crypto/public_key/elliptic/indutnyKey.js +++ b/src/crypto/public_key/elliptic/indutnyKey.js @@ -18,7 +18,6 @@ /** * @fileoverview Wrapper for a KeyPair of an curve from indutny/elliptic library * @module crypto/public_key/elliptic/indutnyKey - * @private */ import config from '../../../config'; diff --git a/src/crypto/public_key/elliptic/oid_curves.js b/src/crypto/public_key/elliptic/oid_curves.js index e8d563ef..dab26436 100644 --- a/src/crypto/public_key/elliptic/oid_curves.js +++ b/src/crypto/public_key/elliptic/oid_curves.js @@ -18,7 +18,6 @@ /** * @fileoverview Wrapper of an instance of an Elliptic Curve * @module crypto/public_key/elliptic/curve - * @private */ import nacl from '@openpgp/tweetnacl/nacl-fast-light'; diff --git a/src/crypto/public_key/index.js b/src/crypto/public_key/index.js index 94714eb4..ac34ab76 100644 --- a/src/crypto/public_key/index.js +++ b/src/crypto/public_key/index.js @@ -1,7 +1,6 @@ /** * @fileoverview Asymmetric cryptography functions * @module crypto/public_key - * @private */ import nacl from '@openpgp/tweetnacl/nacl-fast-light'; diff --git a/src/crypto/public_key/prime.js b/src/crypto/public_key/prime.js index 3755d08e..a7b7cba0 100644 --- a/src/crypto/public_key/prime.js +++ b/src/crypto/public_key/prime.js @@ -18,7 +18,6 @@ /** * @fileoverview Algorithms for probabilistic random prime generation * @module crypto/public_key/prime - * @private */ import util from '../../util'; diff --git a/src/crypto/public_key/rsa.js b/src/crypto/public_key/rsa.js index 2b24a152..0a17ff06 100644 --- a/src/crypto/public_key/rsa.js +++ b/src/crypto/public_key/rsa.js @@ -18,7 +18,6 @@ /** * @fileoverview RSA implementation * @module crypto/public_key/rsa - * @private */ import { randomProbablePrime } from './prime'; diff --git a/src/crypto/random.js b/src/crypto/random.js index 022bb4aa..ffef7d65 100644 --- a/src/crypto/random.js +++ b/src/crypto/random.js @@ -20,7 +20,6 @@ /** * @fileoverview Provides tools for retrieving secure randomness from browsers or Node.js * @module crypto/random - * @private */ import util from '../util'; diff --git a/src/crypto/signature.js b/src/crypto/signature.js index b4d2aed3..00c7086c 100644 --- a/src/crypto/signature.js +++ b/src/crypto/signature.js @@ -1,7 +1,6 @@ /** * @fileoverview Provides functions for asymmetric signing and signature verification * @module crypto/signature - * @private */ import publicKey from './public_key'; diff --git a/src/encoding/base64.js b/src/encoding/base64.js index dfea632d..ee95d56b 100644 --- a/src/encoding/base64.js +++ b/src/encoding/base64.js @@ -13,7 +13,6 @@ /** * @module encoding/base64 - * @private */ import * as stream from '@openpgp/web-stream-tools'; diff --git a/src/key/helper.js b/src/key/helper.js index 05a83331..a8bc7cf9 100644 --- a/src/key/helper.js +++ b/src/key/helper.js @@ -1,7 +1,6 @@ /** * @fileoverview Provides helpers methods for key module * @module key/helper - * @private */ import { diff --git a/src/key/user.js b/src/key/user.js index c1e22eb0..49159c5a 100644 --- a/src/key/user.js +++ b/src/key/user.js @@ -1,6 +1,5 @@ /** * @module key/User - * @private */ import enums from '../enums'; diff --git a/src/packet/packet.js b/src/packet/packet.js index b42e4edf..c40082f5 100644 --- a/src/packet/packet.js +++ b/src/packet/packet.js @@ -18,7 +18,6 @@ /** * @fileoverview Functions for reading and writing packets * @module packet/packet - * @private */ import * as stream from '@openpgp/web-stream-tools'; diff --git a/src/type/ecdh_symkey.js b/src/type/ecdh_symkey.js index 71d05983..e23fdd84 100644 --- a/src/type/ecdh_symkey.js +++ b/src/type/ecdh_symkey.js @@ -19,7 +19,6 @@ * Encoded symmetric key for ECDH (incl. legacy x25519) * * @module type/ecdh_symkey - * @private */ import util from '../util'; diff --git a/src/type/keyid.js b/src/type/keyid.js index 2abf6ae0..76da3e00 100644 --- a/src/type/keyid.js +++ b/src/type/keyid.js @@ -17,7 +17,6 @@ /** * @module type/keyid - * @private */ import util from '../util'; diff --git a/src/type/oid.js b/src/type/oid.js index 20278c8a..370f583a 100644 --- a/src/type/oid.js +++ b/src/type/oid.js @@ -30,7 +30,6 @@ * is constructed by omitting the first two octets. Only the truncated * sequence of octets is the valid representation of a curve OID. * @module type/oid - * @private */ import util from '../util'; diff --git a/src/type/s2k/generic.js b/src/type/s2k/generic.js index ab9b2855..76b81f5b 100644 --- a/src/type/s2k/generic.js +++ b/src/type/s2k/generic.js @@ -25,7 +25,6 @@ * private keyring, and to convert passphrases to encryption keys for * symmetrically encrypted messages. * @module type/s2k - * @private */ import defaultConfig from '../../config'; diff --git a/src/util.js b/src/util.js index 255d020f..47a02f95 100644 --- a/src/util.js +++ b/src/util.js @@ -20,7 +20,6 @@ /** * This object contains utility functions * @module util - * @private */ import * as stream from '@openpgp/web-stream-tools'; From 1aefed960278cc59b87d962c6b86f93ac692a370 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Wed, 17 May 2023 19:20:22 +0200 Subject: [PATCH 011/201] Fix streaming tests for browser, drop NodeReadableStream tests in Node.js Unclear why the Node tests fails, but we're planning to drop support --- test/general/openpgp.js | 22 +++++------- test/general/streaming.js | 76 +++++---------------------------------- 2 files changed, 16 insertions(+), 82 deletions(-) diff --git a/test/general/openpgp.js b/test/general/openpgp.js index 1d435d60..1039e78d 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -3329,10 +3329,8 @@ XfA3pqV4mTzF it('Streaming encrypt and decrypt small message roundtrip', async function() { const plaintext = []; let i = 0; - const useNativeStream = (() => { try { new global.ReadableStream(); return true; } catch (e) { return false; } })(); // eslint-disable-line no-new await loadStreamsPolyfill(); - const GenericReadableStream = useNativeStream ? global.ReadableStream : ReadableStream; - const data = new GenericReadableStream({ + const data = new globalThis.ReadableStream({ pull(controller) { if (i++ < 4) { const randomBytes = random.getRandomBytes(10); @@ -3347,7 +3345,7 @@ XfA3pqV4mTzF message: await openpgp.createMessage({ binary: data }), passwords: ['test'] })); - expect(stream.isStream(encrypted)).to.equal(useNativeStream ? 'web' : 'web-like'); + expect(stream.isStream(encrypted)).to.equal('web'); const message = await openpgp.readMessage({ armoredMessage: encrypted }); const decrypted = await openpgp.decrypt({ @@ -3355,7 +3353,7 @@ XfA3pqV4mTzF message, format: 'binary' }); - expect(stream.isStream(decrypted.data)).to.equal(useNativeStream ? 'web' : 'web-like'); + expect(stream.isStream(decrypted.data)).to.equal('web'); expect(await stream.readToEnd(decrypted.data)).to.deep.equal(util.concatUint8Array(plaintext)); }); }); @@ -3658,17 +3656,13 @@ XfA3pqV4mTzF it('should streaming sign and verify binary data without one-pass signature', async function () { const data = new Uint8Array([3, 14, 15, 92, 65, 35, 59]); - const dataStream = global.ReadableStream ? new global.ReadableStream({ + const dataStream = new globalThis.ReadableStream({ start(controller) { controller.enqueue(data); controller.close(); } - }) : new (require('stream').Readable)({ - read() { - this.push(data); - this.push(null); - } }); + const signOpt = { message: await openpgp.createMessage({ binary: dataStream }), signingKeys: privateKey, @@ -3679,7 +3673,7 @@ XfA3pqV4mTzF format: 'binary' }; return openpgp.sign(signOpt).then(async function (signed) { - expect(stream.isStream(signed)).to.equal(global.ReadableStream ? 'web' : 'node'); + expect(stream.isStream(signed)).to.equal('web'); const message = await openpgp.readMessage({ binaryMessage: signed }); message.packets.push(...await stream.readToEnd(message.packets.stream, _ => _)); const packets = new openpgp.PacketList(); @@ -3687,12 +3681,12 @@ XfA3pqV4mTzF packets.push(message.packets.findPacket(openpgp.enums.packet.literalData)); verifyOpt.message = await openpgp.readMessage({ binaryMessage: stream[ - global.ReadableStream ? 'toStream' : 'webToNode' + globalThis.ReadableStream ? 'toStream' : 'webToNode' ](packets.write()) }); return openpgp.verify(verifyOpt); }).then(async function (verified) { - expect(stream.isStream(verified.data)).to.equal(global.ReadableStream ? 'web' : 'node'); + expect(stream.isStream(verified.data)).to.equal('web'); expect([].slice.call(await stream.readToEnd(verified.data))).to.deep.equal([].slice.call(data)); expect(await verified.signatures[0].verified).to.be.true; expect(await privateKey.getSigningKey(verified.signatures[0].keyID)) diff --git a/test/general/streaming.js b/test/general/streaming.js index 1a1ad5fb..e4dd91b7 100644 --- a/test/general/streaming.js +++ b/test/general/streaming.js @@ -12,9 +12,6 @@ import util from '../../src/util.js'; import * as input from './testInputs.js'; -const useNativeStream = (() => { try { new global.ReadableStream(); return true; } catch (e) { return false; } })(); // eslint-disable-line no-new -const NodeReadableStream = useNativeStream ? undefined : require('stream').Readable; - const detectNode = () => typeof globalThis.process === 'object' && typeof globalThis.process.versions === 'object'; const pub_key = [ @@ -180,18 +177,12 @@ let dataArrived; function tests() { it('Encrypt small message', async function() { dataArrived(); // Do not wait until data arrived. - const data = global.ReadableStream ? new global.ReadableStream({ + const data = new globalThis.ReadableStream({ start(controller) { controller.enqueue(util.stringToUint8Array('hello ')); controller.enqueue(util.stringToUint8Array('world')); controller.close(); } - }) : new NodeReadableStream({ - read() { - this.push(util.stringToUint8Array('hello ')); - this.push(util.stringToUint8Array('world')); - this.push(null); - } }); const encrypted = await openpgp.encrypt({ message: await openpgp.createMessage({ binary: data }), @@ -657,18 +648,12 @@ function tests() { it('Detached sign small message', async function() { dataArrived(); // Do not wait until data arrived. - const data = global.ReadableStream ? new global.ReadableStream({ + const data = new globalThis.ReadableStream({ start(controller) { controller.enqueue(util.stringToUint8Array('hello ')); controller.enqueue(util.stringToUint8Array('world')); controller.close(); } - }) : new NodeReadableStream({ - read() { - this.push(util.stringToUint8Array('hello ')); - this.push(util.stringToUint8Array('world')); - this.push(null); - } }); const signed = await openpgp.sign({ message: await openpgp.createMessage({ binary: data }), @@ -692,18 +677,12 @@ function tests() { it('Detached sign small message using brainpool curve keys', async function() { dataArrived(); // Do not wait until data arrived. - const data = global.ReadableStream ? new global.ReadableStream({ + const data = new globalThis.ReadableStream({ start(controller) { controller.enqueue(util.stringToUint8Array('hello ')); controller.enqueue(util.stringToUint8Array('world')); controller.close(); } - }) : new NodeReadableStream({ - read() { - this.push(util.stringToUint8Array('hello ')); - this.push(util.stringToUint8Array('world')); - this.push(null); - } }); const pub = await openpgp.readKey({ armoredKey: brainpoolPub }); const priv = await openpgp.decryptKey({ @@ -734,18 +713,12 @@ function tests() { it('Detached sign small message using curve25519 keys (legacy format)', async function() { dataArrived(); // Do not wait until data arrived. - const data = global.ReadableStream ? new global.ReadableStream({ + const data = new globalThis.ReadableStream({ async start(controller) { controller.enqueue(util.stringToUint8Array('hello ')); controller.enqueue(util.stringToUint8Array('world')); controller.close(); } - }) : new NodeReadableStream({ - read() { - this.push(util.stringToUint8Array('hello ')); - this.push(util.stringToUint8Array('world')); - this.push(null); - } }); const pub = await openpgp.readKey({ armoredKey: xPub }); const priv = await openpgp.decryptKey({ @@ -843,7 +816,7 @@ function tests() { const plaintext = []; let i = 0; - const data = global.ReadableStream ? new global.ReadableStream({ + const data = new globalThis.ReadableStream({ async pull(controller) { await new Promise(resolve => { setTimeout(resolve, 10); }); if (i++ < 10) { @@ -854,20 +827,6 @@ function tests() { controller.close(); } } - }) : new NodeReadableStream({ - encoding: 'utf8', - async read() { - while (true) { - await new Promise(resolve => { setTimeout(resolve, 10); }); - if (i++ < 10) { - const randomData = input.createSomeMessage(); - plaintext.push(randomData); - if (!this.push(randomData)) break; - } else { - return this.push(null); - } - } - } }); const encrypted = await openpgp.encrypt({ message: await openpgp.createMessage({ text: data }), @@ -970,7 +929,7 @@ export default () => describe('Streaming', function() { plaintext = []; i = 0; canceled = false; - data = global.ReadableStream ? new global.ReadableStream({ + data = new globalThis.ReadableStream({ async pull(controller) { await new Promise(setTimeout); if (test === currentTest && i < (expectedType === 'web' ? 100 : 500)) { @@ -988,27 +947,8 @@ export default () => describe('Streaming', function() { } }, new ByteLengthQueuingStrategy({ highWaterMark: 1024 - })) : new NodeReadableStream({ - highWaterMark: 1024, - async read() { - while (true) { - await new Promise(setTimeout); - if (test === currentTest && i < (expectedType === 'web' ? 100 : 500)) { - i++; - if (i === 4) await dataArrivedPromise; - const randomBytes = random.getRandomBytes(1024); - plaintext.push(randomBytes); - if (!this.push(randomBytes)) break; - } else { - return this.push(null); - } - } - }, - destroy() { - canceled = true; - } - }); - expectedType = global.ReadableStream ? 'web' : 'node'; + })); + expectedType = 'web'; }); tests(); From 0b2767fe4c485783e065f88defcbd55aacb76321 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Wed, 31 May 2023 15:47:36 +0200 Subject: [PATCH 012/201] Replace pako with fflate as compression lib fflate already supports ESM and is actively maintained --- package-lock.json | 26 +++++++-------- package.json | 2 +- src/packet/compressed_data.js | 63 ++++++++++++++++++++++++----------- 3 files changed, 58 insertions(+), 33 deletions(-) diff --git a/package-lock.json b/package-lock.json index 676a4bb7..31e521ee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,6 @@ "@openpgp/asmcrypto.js": "^2.3.2", "@openpgp/elliptic": "^6.5.1", "@openpgp/jsdoc": "^3.6.11", - "@openpgp/pako": "^1.0.12", "@openpgp/seek-bzip": "^1.0.5-git", "@openpgp/tweetnacl": "^1.0.3", "@openpgp/web-stream-tools": "^0.0.14", @@ -37,6 +36,7 @@ "eslint-config-airbnb-base": "^15.0.0", "eslint-plugin-chai-friendly": "^0.7.2", "eslint-plugin-import": "^2.27.5", + "fflate": "^0.7.4", "hash.js": "^1.1.3", "http-server": "^14.1.1", "karma": "^6.4.0", @@ -660,12 +660,6 @@ "node": ">=10" } }, - "node_modules/@openpgp/pako": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/@openpgp/pako/-/pako-1.0.12.tgz", - "integrity": "sha512-r3+UotSXn4j2snQIuIYjsvA9xzx/5hEPi4vAqHhjhtQ+Q/XyLxYwfJpeIAdJvud6dKp57h48lDQpMkGda4MBQw==", - "dev": true - }, "node_modules/@openpgp/seek-bzip": { "version": "1.0.5-git", "resolved": "https://registry.npmjs.org/@openpgp/seek-bzip/-/seek-bzip-1.0.5-git.tgz", @@ -2996,6 +2990,12 @@ "reusify": "^1.0.4" } }, + "node_modules/fflate": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.4.tgz", + "integrity": "sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==", + "dev": true + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -8150,12 +8150,6 @@ } } }, - "@openpgp/pako": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/@openpgp/pako/-/pako-1.0.12.tgz", - "integrity": "sha512-r3+UotSXn4j2snQIuIYjsvA9xzx/5hEPi4vAqHhjhtQ+Q/XyLxYwfJpeIAdJvud6dKp57h48lDQpMkGda4MBQw==", - "dev": true - }, "@openpgp/seek-bzip": { "version": "1.0.5-git", "resolved": "https://registry.npmjs.org/@openpgp/seek-bzip/-/seek-bzip-1.0.5-git.tgz", @@ -9976,6 +9970,12 @@ "reusify": "^1.0.4" } }, + "fflate": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.4.tgz", + "integrity": "sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==", + "dev": true + }, "file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", diff --git a/package.json b/package.json index a24d4c41..96ff8a05 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,6 @@ "@openpgp/asmcrypto.js": "^2.3.2", "@openpgp/elliptic": "^6.5.1", "@openpgp/jsdoc": "^3.6.11", - "@openpgp/pako": "^1.0.12", "@openpgp/seek-bzip": "^1.0.5-git", "@openpgp/tweetnacl": "^1.0.3", "@openpgp/web-stream-tools": "^0.0.14", @@ -87,6 +86,7 @@ "eslint-config-airbnb-base": "^15.0.0", "eslint-plugin-chai-friendly": "^0.7.2", "eslint-plugin-import": "^2.27.5", + "fflate": "^0.7.4", "hash.js": "^1.1.3", "http-server": "^14.1.1", "karma": "^6.4.0", diff --git a/src/packet/compressed_data.js b/src/packet/compressed_data.js index e924a46c..778027e7 100644 --- a/src/packet/compressed_data.js +++ b/src/packet/compressed_data.js @@ -15,9 +15,7 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -import { Deflate } from '@openpgp/pako/lib/deflate'; -import { Inflate } from '@openpgp/pako/lib/inflate'; -import { Z_SYNC_FLUSH, Z_FINISH } from '@openpgp/pako/lib/zlib/constants'; +import { Inflate, Deflate, Zlib, Unzlib } from 'fflate'; import { decode as BunzipDecode } from '@openpgp/seek-bzip'; import * as stream from '@openpgp/web-stream-tools'; import enums from '../enums'; @@ -168,18 +166,45 @@ function node_zlib(func, create, options = {}) { }; } -function pako_zlib(constructor, options = {}) { - return function(data) { - const obj = new constructor(options); - return stream.transform(data, value => { - if (value.length) { - obj.push(value, Z_SYNC_FLUSH); - return obj.result; - } - }, () => { - if (constructor === Deflate) { - obj.push([], Z_FINISH); - return obj.result; +function fflate_zlib(ZlibStreamedConstructor, options) { + return data => { + if (!util.isStream(data) || stream.isArrayStream(data)) { + return stream.fromAsync(() => stream.readToEnd(data).then(inputData => { + return new Promise((resolve, reject) => { + const zlibStream = new ZlibStreamedConstructor(options); + zlibStream.ondata = processedData => { + resolve(processedData); + }; + try { + zlibStream.push(inputData, true); // only one chunk to push + } catch (err) { + reject(err); + } + }); + })); + } + + const inputReader = data.getReader(); + const zlibStream = new ZlibStreamedConstructor(options); + + return new ReadableStream({ + async start(controller) { + zlibStream.ondata = async (value, isLast) => { + controller.enqueue(value); + if (isLast) { + controller.close(); + } + }; + + while (true) { + const { done, value } = await inputReader.read(); + if (done) { + zlibStream.push(new Uint8Array(), true); + return; + } else if (value.length) { + zlibStream.push(value); + } + } } }); }; @@ -195,8 +220,8 @@ const compress_fns = nodeZlib ? { zip: /*#__PURE__*/ (compressed, level) => node_zlib(nodeZlib.deflateRaw, nodeZlib.createDeflateRaw, { level })(compressed), zlib: /*#__PURE__*/ (compressed, level) => node_zlib(nodeZlib.deflate, nodeZlib.createDeflate, { level })(compressed) } : { - zip: /*#__PURE__*/ (compressed, level) => pako_zlib(Deflate, { raw: true, level })(compressed), - zlib: /*#__PURE__*/ (compressed, level) => pako_zlib(Deflate, { level })(compressed) + zip: /*#__PURE__*/ (compressed, level) => fflate_zlib(Deflate, { level })(compressed), + zlib: /*#__PURE__*/ (compressed, level) => fflate_zlib(Zlib, { level })(compressed) }; const decompress_fns = nodeZlib ? { @@ -206,8 +231,8 @@ const decompress_fns = nodeZlib ? { bzip2: /*#__PURE__*/ bzip2(BunzipDecode) } : { uncompressed: uncompressed, - zip: /*#__PURE__*/ pako_zlib(Inflate, { raw: true }), - zlib: /*#__PURE__*/ pako_zlib(Inflate), + zip: /*#__PURE__*/ fflate_zlib(Inflate), + zlib: /*#__PURE__*/ fflate_zlib(Unzlib), bzip2: /*#__PURE__*/ bzip2(BunzipDecode) }; From 21a6d83ec81524c87d16382d21b4f75a0ba33493 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Tue, 30 May 2023 18:14:01 +0200 Subject: [PATCH 013/201] Update asmcrypto.js, use for AES only (move to noble-hashes for sha1, sha256) --- .eslintrc.js => .eslintrc.cjs | 0 package-lock.json | 59 ++++++++++++++++++++++++++++++----- package.json | 3 +- src/crypto/cipher/aes.js | 2 +- src/crypto/cmac.js | 2 +- src/crypto/hash/index.js | 18 +++++------ src/crypto/mode/cfb.js | 2 +- src/crypto/mode/eax.js | 2 +- src/crypto/mode/gcm.js | 2 +- 9 files changed, 68 insertions(+), 22 deletions(-) rename .eslintrc.js => .eslintrc.cjs (100%) diff --git a/.eslintrc.js b/.eslintrc.cjs similarity index 100% rename from .eslintrc.js rename to .eslintrc.cjs diff --git a/package-lock.json b/package-lock.json index 31e521ee..db59ef68 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,9 +12,10 @@ "asn1.js": "^5.0.0" }, "devDependencies": { - "@openpgp/asmcrypto.js": "^2.3.2", + "@openpgp/asmcrypto.js": "^3.0.0", "@openpgp/elliptic": "^6.5.1", "@openpgp/jsdoc": "^3.6.11", + "@openpgp/noble-hashes": "^1.3.2-1", "@openpgp/seek-bzip": "^1.0.5-git", "@openpgp/tweetnacl": "^1.0.3", "@openpgp/web-stream-tools": "^0.0.14", @@ -590,9 +591,9 @@ } }, "node_modules/@openpgp/asmcrypto.js": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@openpgp/asmcrypto.js/-/asmcrypto.js-2.3.2.tgz", - "integrity": "sha512-CEb3I/Tqg+i5NgEnhYj3fi6XsT5JTuvYdwbMq+STGxlZ8uYSWmYFmVyz9vQgtNwCll/FbB6eR1opa4hoeHGceQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@openpgp/asmcrypto.js/-/asmcrypto.js-3.0.0.tgz", + "integrity": "sha512-X/DPYy7uHe+dlY2Botb99uXwb2kXR6HTv0hQOnnI0TVEqOIMQyzCDWAzlX00AacsYryDAphuOndg6mk6wtJCNg==", "dev": true }, "node_modules/@openpgp/elliptic": { @@ -660,6 +661,22 @@ "node": ">=10" } }, + "node_modules/@openpgp/noble-hashes": { + "version": "1.3.2-1", + "resolved": "https://registry.npmjs.org/@openpgp/noble-hashes/-/noble-hashes-1.3.2-1.tgz", + "integrity": "sha512-4pmVh5O+bq1vO4xIAQXh0m7AxasEidFmHA1zm3Fk46IsLObz8pI43EyuLdwqs/6cmL6vAUCde/Xh2MYrVZd5bw==", + "dev": true, + "dependencies": { + "@types/bn.js": "^4.11.6", + "bn.js": "^4.11.8" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@openpgp/seek-bzip": { "version": "1.0.5-git", "resolved": "https://registry.npmjs.org/@openpgp/seek-bzip/-/seek-bzip-1.0.5-git.tgz", @@ -986,6 +1003,15 @@ "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", "dev": true }, + "node_modules/@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/chai": { "version": "4.3.5", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.5.tgz", @@ -8093,9 +8119,9 @@ } }, "@openpgp/asmcrypto.js": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@openpgp/asmcrypto.js/-/asmcrypto.js-2.3.2.tgz", - "integrity": "sha512-CEb3I/Tqg+i5NgEnhYj3fi6XsT5JTuvYdwbMq+STGxlZ8uYSWmYFmVyz9vQgtNwCll/FbB6eR1opa4hoeHGceQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@openpgp/asmcrypto.js/-/asmcrypto.js-3.0.0.tgz", + "integrity": "sha512-X/DPYy7uHe+dlY2Botb99uXwb2kXR6HTv0hQOnnI0TVEqOIMQyzCDWAzlX00AacsYryDAphuOndg6mk6wtJCNg==", "dev": true }, "@openpgp/elliptic": { @@ -8150,6 +8176,16 @@ } } }, + "@openpgp/noble-hashes": { + "version": "1.3.2-1", + "resolved": "https://registry.npmjs.org/@openpgp/noble-hashes/-/noble-hashes-1.3.2-1.tgz", + "integrity": "sha512-4pmVh5O+bq1vO4xIAQXh0m7AxasEidFmHA1zm3Fk46IsLObz8pI43EyuLdwqs/6cmL6vAUCde/Xh2MYrVZd5bw==", + "dev": true, + "requires": { + "@types/bn.js": "^4.11.6", + "bn.js": "^4.11.8" + } + }, "@openpgp/seek-bzip": { "version": "1.0.5-git", "resolved": "https://registry.npmjs.org/@openpgp/seek-bzip/-/seek-bzip-1.0.5-git.tgz", @@ -8374,6 +8410,15 @@ "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", "dev": true }, + "@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/chai": { "version": "4.3.5", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.5.tgz", diff --git a/package.json b/package.json index 96ff8a05..b2dbd347 100644 --- a/package.json +++ b/package.json @@ -62,9 +62,10 @@ "postversion": "git push && git push --tags && npm publish" }, "devDependencies": { - "@openpgp/asmcrypto.js": "^2.3.2", + "@openpgp/asmcrypto.js": "^3.0.0", "@openpgp/elliptic": "^6.5.1", "@openpgp/jsdoc": "^3.6.11", + "@openpgp/noble-hashes": "^1.3.2-1", "@openpgp/seek-bzip": "^1.0.5-git", "@openpgp/tweetnacl": "^1.0.3", "@openpgp/web-stream-tools": "^0.0.14", diff --git a/src/crypto/cipher/aes.js b/src/crypto/cipher/aes.js index 8a985079..0ef89041 100644 --- a/src/crypto/cipher/aes.js +++ b/src/crypto/cipher/aes.js @@ -1,4 +1,4 @@ -import { AES_ECB } from '@openpgp/asmcrypto.js/dist_es8/aes/ecb'; +import { AES_ECB } from '@openpgp/asmcrypto.js/aes/ecb.js'; /** * Javascript AES implementation. diff --git a/src/crypto/cmac.js b/src/crypto/cmac.js index e838bd6f..8c20afc7 100644 --- a/src/crypto/cmac.js +++ b/src/crypto/cmac.js @@ -4,7 +4,7 @@ * @module crypto/cmac */ -import { AES_CBC } from '@openpgp/asmcrypto.js/dist_es8/aes/cbc'; +import { AES_CBC } from '@openpgp/asmcrypto.js/aes/cbc.js'; import util from '../util'; const webCrypto = util.getWebCrypto(); diff --git a/src/crypto/hash/index.js b/src/crypto/hash/index.js index d5752841..a3dc6972 100644 --- a/src/crypto/hash/index.js +++ b/src/crypto/hash/index.js @@ -5,8 +5,8 @@ * @module crypto/hash */ -import { Sha1 } from '@openpgp/asmcrypto.js/dist_es8/hash/sha1/sha1'; -import { Sha256 } from '@openpgp/asmcrypto.js/dist_es8/hash/sha256/sha256'; +import { sha1 } from '@openpgp/noble-hashes/sha1'; +import { sha256 } from '@openpgp/noble-hashes/sha256'; import sha224 from 'hash.js/lib/hash/sha/224'; import sha384 from 'hash.js/lib/hash/sha/384'; import sha512 from 'hash.js/lib/hash/sha/512'; @@ -48,29 +48,29 @@ function hashjsHash(hash, webCryptoHash) { }; } -function asmcryptoHash(hash, webCryptoHash) { +function nobleHash(hash, webCryptoHash) { return async function(data, config = defaultConfig) { if (stream.isArrayStream(data)) { data = await stream.readToEnd(data); } if (util.isStream(data)) { - const hashInstance = new hash(); + const hashInstance = hash.create(); return stream.transform(data, value => { - hashInstance.process(value); - }, () => hashInstance.finish().result); + hashInstance.update(value); + }, () => hashInstance.digest()); } else if (webCrypto && webCryptoHash && data.length >= config.minBytesForWebCrypto) { return new Uint8Array(await webCrypto.digest(webCryptoHash, data)); } else { - return hash.bytes(data); + return hash(data); } }; } const hashFunctions = { md5: nodeHash('md5') || md5, - sha1: nodeHash('sha1') || asmcryptoHash(Sha1, 'SHA-1'), + sha1: nodeHash('sha1') || nobleHash(sha1, 'SHA-1'), sha224: nodeHash('sha224') || hashjsHash(sha224), - sha256: nodeHash('sha256') || asmcryptoHash(Sha256, 'SHA-256'), + sha256: nodeHash('sha256') || nobleHash(sha256, 'SHA-256'), sha384: nodeHash('sha384') || hashjsHash(sha384, 'SHA-384'), sha512: nodeHash('sha512') || hashjsHash(sha512, 'SHA-512'), // asmcrypto sha512 is huge. ripemd: nodeHash('ripemd160') || hashjsHash(ripemd160) diff --git a/src/crypto/mode/cfb.js b/src/crypto/mode/cfb.js index a1bdb526..bca03563 100644 --- a/src/crypto/mode/cfb.js +++ b/src/crypto/mode/cfb.js @@ -21,7 +21,7 @@ * @module crypto/mode/cfb */ -import { AES_CFB } from '@openpgp/asmcrypto.js/dist_es8/aes/cfb'; +import { AES_CFB } from '@openpgp/asmcrypto.js/aes/cfb.js'; import * as stream from '@openpgp/web-stream-tools'; import getCipher from '../cipher/getCipher'; import util from '../../util'; diff --git a/src/crypto/mode/eax.js b/src/crypto/mode/eax.js index 4917ba1c..433d4485 100644 --- a/src/crypto/mode/eax.js +++ b/src/crypto/mode/eax.js @@ -21,7 +21,7 @@ * @module crypto/mode/eax */ -import { AES_CTR } from '@openpgp/asmcrypto.js/dist_es8/aes/ctr'; +import { AES_CTR } from '@openpgp/asmcrypto.js/aes/ctr.js'; import CMAC from '../cmac'; import util from '../../util'; import enums from '../../enums'; diff --git a/src/crypto/mode/gcm.js b/src/crypto/mode/gcm.js index c5b5e332..0088b58b 100644 --- a/src/crypto/mode/gcm.js +++ b/src/crypto/mode/gcm.js @@ -21,7 +21,7 @@ * @module crypto/mode/gcm */ -import { AES_GCM } from '@openpgp/asmcrypto.js/dist_es8/aes/gcm'; +import { AES_GCM } from '@openpgp/asmcrypto.js/aes/gcm.js'; import util from '../../util'; import enums from '../../enums'; From 2377b2958d297f553ae062aed50dc1c5d4a08b5f Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Tue, 30 May 2023 22:19:00 +0200 Subject: [PATCH 014/201] Use WebCrypto for streamed CFB encryption; for CFB/GCM/EAX, fallback to asmcrypto only if key size is not supported CFB decryption is too slow using WebCrypto (CBC mode), since every block needs to be decrypted separately --- src/crypto/cmac.js | 25 ++++++-- src/crypto/mode/cfb.js | 141 ++++++++++++++++++++++++++++++++++------- src/crypto/mode/eax.js | 28 +++++--- src/crypto/mode/gcm.js | 45 ++++++++----- 4 files changed, 182 insertions(+), 57 deletions(-) diff --git a/src/crypto/cmac.js b/src/crypto/cmac.js index 8c20afc7..19d996a8 100644 --- a/src/crypto/cmac.js +++ b/src/crypto/cmac.js @@ -72,13 +72,6 @@ export default async function CMAC(key) { } async function CBC(key) { - if (util.getWebCrypto() && key.length !== 24) { // WebCrypto (no 192 bit support) see: https://www.chromium.org/blink/webcrypto#TOC-AES-support - key = await webCrypto.importKey('raw', key, { name: 'AES-CBC', length: key.length * 8 }, false, ['encrypt']); - return async function(pt) { - const ct = await webCrypto.encrypt({ name: 'AES-CBC', iv: zeroBlock, length: blockLength * 8 }, key, pt); - return new Uint8Array(ct).subarray(0, ct.byteLength - blockLength); - }; - } if (util.getNodeCrypto()) { // Node crypto library return async function(pt) { const en = new nodeCrypto.createCipheriv('aes-' + (key.length * 8) + '-cbc', key, zeroBlock); @@ -86,6 +79,24 @@ async function CBC(key) { return new Uint8Array(ct); }; } + + if (util.getWebCrypto()) { + try { + key = await webCrypto.importKey('raw', key, { name: 'AES-CBC', length: key.length * 8 }, false, ['encrypt']); + return async function(pt) { + const ct = await webCrypto.encrypt({ name: 'AES-CBC', iv: zeroBlock, length: blockLength * 8 }, key, pt); + return new Uint8Array(ct).subarray(0, ct.byteLength - blockLength); + }; + } catch (err) { + // no 192 bit support in Chromium, which throws `OperationError`, see: https://www.chromium.org/blink/webcrypto#TOC-AES-support + if (err.name !== 'NotSupportedError' && + !(key.length === 24 && err.name === 'OperationError')) { + throw err; + } + util.printDebugError('Browser did not support operation: ' + err.message); + } + } + // asm.js fallback return async function(pt) { return AES_CBC.encrypt(pt, key, false, zeroBlock); diff --git a/src/crypto/mode/cfb.js b/src/crypto/mode/cfb.js index bca03563..6fce90c1 100644 --- a/src/crypto/mode/cfb.js +++ b/src/crypto/mode/cfb.js @@ -96,7 +96,7 @@ export async function encrypt(algo, key, plaintext, iv, config) { */ export async function decrypt(algo, key, ciphertext, iv) { const algoName = enums.read(enums.symmetric, algo); - if (util.getNodeCrypto() && nodeAlgos[algoName]) { // Node crypto library. + if (nodeCrypto && nodeAlgos[algoName]) { // Node crypto library. return nodeDecrypt(algo, key, ciphertext, iv); } if (util.isAES(algo)) { @@ -129,18 +129,122 @@ export async function decrypt(algo, key, ciphertext, iv) { return stream.transform(ciphertext, process, process); } -function aesEncrypt(algo, key, pt, iv, config) { - if ( - util.getWebCrypto() && - key.length !== 24 && // Chrome doesn't support 192 bit keys, see https://www.chromium.org/blink/webcrypto#TOC-AES-support - !util.isStream(pt) && - pt.length >= 3000 * config.minBytesForWebCrypto // Default to a 3MB minimum. Chrome is pretty slow for small messages, see: https://bugs.chromium.org/p/chromium/issues/detail?id=701188#c2 - ) { // Web Crypto - return webEncrypt(algo, key, pt, iv); +class WebCryptoEncryptor { + constructor(algo, key, iv) { + const { blockSize } = getCipher(algo); + this.key = key; + this.prevBlock = iv; + this.nextBlock = new Uint8Array(blockSize); + this.i = 0; // pointer inside next block + this.blockSize = blockSize; + this.zeroBlock = new Uint8Array(this.blockSize); + } + + static async isSupported(algo) { + const { keySize } = getCipher(algo); + return webCrypto.importKey('raw', new Uint8Array(keySize), 'aes-cbc', false, ['encrypt']) + .then(() => true, () => false); + } + + async _runCBC(plaintext, nonZeroIV) { + const mode = 'AES-CBC'; + this.keyRef = this.keyRef || await webCrypto.importKey('raw', this.key, mode, false, ['encrypt']); + const ciphertext = await webCrypto.encrypt( + { name: mode, iv: nonZeroIV || this.zeroBlock }, + this.keyRef, + plaintext + ); + return new Uint8Array(ciphertext).subarray(0, plaintext.length); + } + + async encryptChunk(value) { + const missing = this.nextBlock.length - this.i; + const added = value.subarray(0, missing); + this.nextBlock.set(added, this.i); + if ((this.i + value.length) >= (2 * this.blockSize)) { + const leftover = (value.length - missing) % this.blockSize; + const plaintext = util.concatUint8Array([ + this.nextBlock, + value.subarray(missing, value.length - leftover) + ]); + const toEncrypt = util.concatUint8Array([ + this.prevBlock, + plaintext.subarray(0, plaintext.length - this.blockSize) // stop one block "early", since we only need to xor the plaintext and pass it over as prevBlock + ]); + + const encryptedBlocks = await this._runCBC(toEncrypt); + xorMut(encryptedBlocks, plaintext); + this.prevBlock = encryptedBlocks.subarray(-this.blockSize).slice(); + + // take care of leftover data + if (leftover > 0) this.nextBlock.set(value.subarray(-leftover).slice()); + this.i = leftover; + + return encryptedBlocks; + } + + this.i += added.length; + let encryptedBlock = new Uint8Array(); + if (this.i === this.nextBlock.length) { // block ready to be encrypted + const curBlock = this.nextBlock; + encryptedBlock = await this._runCBC(this.prevBlock); + xorMut(encryptedBlock, curBlock); + this.prevBlock = encryptedBlock.slice(); + this.i = 0; + + const remaining = value.subarray(added.length); + this.nextBlock.set(remaining, this.i); + this.i += remaining.length; + } + + return encryptedBlock; + } + + async finish() { + let result; + if (this.i === 0) { // nothing more to encrypt + result = new Uint8Array(); + } else { + this.nextBlock = this.nextBlock.subarray(0, this.i); + const curBlock = this.nextBlock; + const encryptedBlock = await this._runCBC(this.prevBlock); + xorMut(encryptedBlock, curBlock); + result = encryptedBlock.subarray(0, curBlock.length); + } + + this.clearSensitiveData(); + return result; + } + + clearSensitiveData() { + this.nextBlock.fill(0); + this.prevBlock.fill(0); + this.keyRef = null; + this.key = null; + } + + async encrypt(plaintext) { + // plaintext is internally padded to block length before encryption + const encryptedWithPadding = await this._runCBC( + util.concatUint8Array([new Uint8Array(this.blockSize), plaintext]), + this.iv + ); + // drop encrypted padding + const ct = encryptedWithPadding.subarray(0, plaintext.length); + xorMut(ct, plaintext); + this.clearSensitiveData(); + return ct; + } +} + +async function aesEncrypt(algo, key, pt, iv) { + if (webCrypto && await WebCryptoEncryptor.isSupported(algo)) { // Chromium does not implement AES with 192-bit keys + const cfb = new WebCryptoEncryptor(algo, key, iv); + return util.isStream(pt) ? stream.transform(pt, value => cfb.encryptChunk(value), () => cfb.finish()) : cfb.encrypt(pt); + } else { + const cfb = new AES_CFB(key, iv); + return stream.transform(pt, value => cfb.aes.AES_Encrypt_process(value), () => cfb.aes.AES_Encrypt_finish()); } - // asm.js fallback - const cfb = new AES_CFB(key, iv); - return stream.transform(pt, value => cfb.aes.AES_Encrypt_process(value), () => cfb.aes.AES_Encrypt_finish()); } function aesDecrypt(algo, key, ct, iv) { @@ -152,21 +256,12 @@ function aesDecrypt(algo, key, ct, iv) { } function xorMut(a, b) { - for (let i = 0; i < a.length; i++) { + const aLength = Math.min(a.length, b.length); + for (let i = 0; i < aLength; i++) { a[i] = a[i] ^ b[i]; } } -async function webEncrypt(algo, key, pt, iv) { - const ALGO = 'AES-CBC'; - const _key = await webCrypto.importKey('raw', key, { name: ALGO }, false, ['encrypt']); - const { blockSize } = getCipher(algo); - const cbc_pt = util.concatUint8Array([new Uint8Array(blockSize), pt]); - const ct = new Uint8Array(await webCrypto.encrypt({ name: ALGO, iv }, _key, cbc_pt)).subarray(0, pt.length); - xorMut(ct, pt); - return ct; -} - function nodeEncrypt(algo, key, pt, iv) { const algoName = enums.read(enums.symmetric, algo); const cipherObj = new nodeCrypto.createCipheriv(nodeAlgos[algoName], key, iv); diff --git a/src/crypto/mode/eax.js b/src/crypto/mode/eax.js index 433d4485..ab64ec6b 100644 --- a/src/crypto/mode/eax.js +++ b/src/crypto/mode/eax.js @@ -47,16 +47,6 @@ async function OMAC(key) { } async function CTR(key) { - if ( - util.getWebCrypto() && - key.length !== 24 // WebCrypto (no 192 bit support) see: https://www.chromium.org/blink/webcrypto#TOC-AES-support - ) { - key = await webCrypto.importKey('raw', key, { name: 'AES-CTR', length: key.length * 8 }, false, ['encrypt']); - return async function(pt, iv) { - const ct = await webCrypto.encrypt({ name: 'AES-CTR', counter: iv, length: blockLength * 8 }, key, pt); - return new Uint8Array(ct); - }; - } if (util.getNodeCrypto()) { // Node crypto library return async function(pt, iv) { const en = new nodeCrypto.createCipheriv('aes-' + (key.length * 8) + '-ctr', key, iv); @@ -64,6 +54,24 @@ async function CTR(key) { return new Uint8Array(ct); }; } + + if (util.getWebCrypto()) { + try { + const keyRef = await webCrypto.importKey('raw', key, { name: 'AES-CTR', length: key.length * 8 }, false, ['encrypt']); + return async function(pt, iv) { + const ct = await webCrypto.encrypt({ name: 'AES-CTR', counter: iv, length: blockLength * 8 }, keyRef, pt); + return new Uint8Array(ct); + }; + } catch (err) { + // no 192 bit support in Chromium, which throws `OperationError`, see: https://www.chromium.org/blink/webcrypto#TOC-AES-support + if (err.name !== 'NotSupportedError' && + !(key.length === 24 && err.name === 'OperationError')) { + throw err; + } + util.printDebugError('Browser did not support operation: ' + err.message); + } + } + // asm.js fallback return async function(pt, iv) { return AES_CTR.encrypt(pt, key, iv); diff --git a/src/crypto/mode/gcm.js b/src/crypto/mode/gcm.js index 0088b58b..a3cbd941 100644 --- a/src/crypto/mode/gcm.js +++ b/src/crypto/mode/gcm.js @@ -65,26 +65,37 @@ async function GCM(cipher, key) { }; } - if (util.getWebCrypto() && key.length !== 24) { // WebCrypto (no 192 bit support) see: https://www.chromium.org/blink/webcrypto#TOC-AES-support - const _key = await webCrypto.importKey('raw', key, { name: ALGO }, false, ['encrypt', 'decrypt']); + if (util.getWebCrypto()) { + try { + const _key = await webCrypto.importKey('raw', key, { name: ALGO }, false, ['encrypt', 'decrypt']); + // Safari 13 and Safari iOS 14 does not support GCM-en/decrypting empty messages + const webcryptoEmptyMessagesUnsupported = navigator.userAgent.match(/Version\/13\.\d(\.\d)* Safari/) || + navigator.userAgent.match(/Version\/(13|14)\.\d(\.\d)* Mobile\/\S* Safari/); + return { + encrypt: async function(pt, iv, adata = new Uint8Array()) { + if (webcryptoEmptyMessagesUnsupported && !pt.length) { + return AES_GCM.encrypt(pt, key, iv, adata); + } + const ct = await webCrypto.encrypt({ name: ALGO, iv, additionalData: adata, tagLength: tagLength * 8 }, _key, pt); + return new Uint8Array(ct); + }, - return { - encrypt: async function(pt, iv, adata = new Uint8Array()) { - if (!pt.length) { // iOS does not support GCM-en/decrypting empty messages - return AES_GCM.encrypt(pt, key, iv, adata); + decrypt: async function(ct, iv, adata = new Uint8Array()) { + if (webcryptoEmptyMessagesUnsupported && ct.length === tagLength) { + return AES_GCM.decrypt(ct, key, iv, adata); + } + const pt = await webCrypto.decrypt({ name: ALGO, iv, additionalData: adata, tagLength: tagLength * 8 }, _key, ct); + return new Uint8Array(pt); } - const ct = await webCrypto.encrypt({ name: ALGO, iv, additionalData: adata, tagLength: tagLength * 8 }, _key, pt); - return new Uint8Array(ct); - }, - - decrypt: async function(ct, iv, adata = new Uint8Array()) { - if (ct.length === tagLength) { // iOS does not support GCM-en/decrypting empty messages - return AES_GCM.decrypt(ct, key, iv, adata); - } - const pt = await webCrypto.decrypt({ name: ALGO, iv, additionalData: adata, tagLength: tagLength * 8 }, _key, ct); - return new Uint8Array(pt); + }; + } catch (err) { + // no 192 bit support in Chromium, which throws `OperationError`, see: https://www.chromium.org/blink/webcrypto#TOC-AES-support + if (err.name !== 'NotSupportedError' && + !(key.length === 24 && err.name === 'OperationError')) { + throw err; } - }; + util.printDebugError('Browser did not support operation: ' + err.message); + } } return { From 6d477ea509a7022fb44e2a8f7381f47b9485f39b Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Wed, 31 May 2023 10:38:18 +0200 Subject: [PATCH 015/201] Add time benchmark test for streamed sign (testing hashing performance) --- test/benchmarks/time.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/test/benchmarks/time.js b/test/benchmarks/time.js index e86340f7..24ba752a 100644 --- a/test/benchmarks/time.js +++ b/test/benchmarks/time.js @@ -1,4 +1,5 @@ import Benchmark from 'benchmark'; +import { readToEnd } from '@openpgp/web-stream-tools'; import * as openpgp from 'openpgp'; const wrapAsync = func => ({ @@ -25,6 +26,22 @@ const onError = err => { (async () => { const suite = new Benchmark.Suite(); const { armoredKey, privateKey, publicKey, armoredEncryptedMessage, armoredSignedMessage } = await getTestData(); + function* largeDataGenerator({ chunk, numberOfChunks }) { + for (let chunkNumber = 0; chunkNumber < numberOfChunks; chunkNumber++) { + yield chunk; + } + } + + const streamFromGenerator = it => new ReadableStream({ + pull: controller => { + const { value, done } = it.next(); + if (done) { + controller.close(); + } else { + controller.enqueue(value); + } + } + }); suite.add('openpgp.readKey', wrapAsync(async () => { await openpgp.readKey({ armoredKey }); @@ -48,6 +65,14 @@ const onError = err => { await openpgp.sign({ message, signingKeys: privateKey }); })); + suite.add('openpgp.sign (stream)', wrapAsync(async () => { + const inputStream = streamFromGenerator(largeDataGenerator({ chunk: new Uint8Array(10000), numberOfChunks: 10 })); + const message = await openpgp.createMessage({ binary: inputStream }); + const signed = await openpgp.sign({ message, signingKeys: privateKey }); + + await readToEnd(signed); + })); + suite.add('openpgp.decrypt', wrapAsync(async () => { const message = await openpgp.readMessage({ armoredMessage: armoredEncryptedMessage }); await openpgp.decrypt({ message, decryptionKeys: privateKey }); From b3574d6b3e641fb44a7e65b2e8c539d4910793e5 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Wed, 31 May 2023 16:31:52 +0200 Subject: [PATCH 016/201] CI: test all Node.js version even if some fail --- .github/workflows/tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 4c55e991..53feed35 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -29,6 +29,7 @@ jobs: node: strategy: + fail-fast: false # if tests for one version fail, continue with the rest matrix: node-version: [16.x, 18.x, '20.x'] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ From b3ef95e60ebb53058141a3c06dbdea200192afb0 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Thu, 1 Jun 2023 16:28:45 +0200 Subject: [PATCH 017/201] Tests: update sinon --- package-lock.json | 251 +++++++++++++++----------------------- package.json | 2 +- test/crypto/crypto.js | 14 --- test/crypto/eax.js | 6 +- test/crypto/ecdh.js | 4 +- test/crypto/elliptic.js | 4 +- test/crypto/gcm.js | 4 +- test/crypto/rsa.js | 4 +- test/general/openpgp.js | 6 +- test/general/packet.js | 10 +- test/general/streaming.js | 4 +- 11 files changed, 118 insertions(+), 191 deletions(-) diff --git a/package-lock.json b/package-lock.json index db59ef68..b3eb3310 100644 --- a/package-lock.json +++ b/package-lock.json @@ -51,7 +51,7 @@ "nyc": "^14.1.1", "playwright": "^1.30.0", "rollup": "^2.79.1", - "sinon": "^4.3.0", + "sinon": "^15.1.0", "ts-node": "^10.9.1", "typescript": "^4.1.2", "web-streams-polyfill": "^3.2.0" @@ -939,32 +939,41 @@ } }, "node_modules/@sinonjs/commons": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", - "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", "dev": true, "dependencies": { "type-detect": "4.0.8" } }, - "node_modules/@sinonjs/formatio": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz", - "integrity": "sha512-ls6CAMA6/5gG+O/IdsBcblvnd8qcO/l1TYoNeAzp3wcISOxlPXQEus0mLcdwazEkWjaBdaJ3TaxmNgCLWwvWzg==", + "node_modules/@sinonjs/fake-timers": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.2.0.tgz", + "integrity": "sha512-OPwQlEdg40HAj5KNF8WW6q2KG4Z+cBCZb3m4ninfTZKaBmbIJodviQsDBoYMPHkOyJJMHnOJo5j2+LKDOhOACg==", "dev": true, "dependencies": { - "samsam": "1.3.0" + "@sinonjs/commons": "^3.0.0" } }, "node_modules/@sinonjs/samsam": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.3.tgz", - "integrity": "sha512-bKCMKZvWIjYD0BLGnNrxVuw4dkWCYsLqFOUWw8VgKF/+5Y+mE7LfHWPIYoDXowH+3a9LsWDMo0uAP8YDosPvHQ==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", + "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", "dev": true, "dependencies": { - "@sinonjs/commons": "^1.3.0", - "array-from": "^2.1.1", - "lodash": "^4.17.15" + "@sinonjs/commons": "^2.0.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + } + }, + "node_modules/@sinonjs/samsam/node_modules/@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" } }, "node_modules/@sinonjs/text-encoding": { @@ -1261,12 +1270,6 @@ "node": ">=6.0" } }, - "node_modules/array-from": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", - "integrity": "sha512-GQTc6Uupx1FCavi5mPzBvVT7nEOeWMmUA9P95wpfpW1XwMSKs+KaymD5C2Up7KAUKg/mYwbsUYzdZWcoajlNZg==", - "dev": true - }, "node_modules/array-includes": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", @@ -2090,9 +2093,9 @@ "dev": true }, "node_modules/diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", + "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", "dev": true, "engines": { "node": ">=0.3.1" @@ -4863,12 +4866,6 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node_modules/lolex": { - "version": "2.7.5", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz", - "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==", - "dev": true - }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -5443,35 +5440,25 @@ "dev": true }, "node_modules/nise": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/nise/-/nise-1.5.3.tgz", - "integrity": "sha512-Ymbac/94xeIrMf59REBPOv0thr+CJVFMhrlAkW/gjCIE58BGQdCj0x7KRCb3yz+Ga2Rz3E9XXSvUyyxqqhjQAQ==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.4.tgz", + "integrity": "sha512-8+Ib8rRJ4L0o3kfmyVCL7gzrohyDe0cMFTBa2d364yIrEGMEoetznKJx899YxjybU6bL9SQkYPSBBs1gyYs8Xg==", "dev": true, "dependencies": { - "@sinonjs/formatio": "^3.2.1", + "@sinonjs/commons": "^2.0.0", + "@sinonjs/fake-timers": "^10.0.2", "@sinonjs/text-encoding": "^0.7.1", "just-extend": "^4.0.2", - "lolex": "^5.0.1", "path-to-regexp": "^1.7.0" } }, - "node_modules/nise/node_modules/@sinonjs/formatio": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.2.tgz", - "integrity": "sha512-B8SEsgd8gArBLMD6zpRw3juQ2FVSsmdd7qlevyDqzS9WTCtvF55/gAL+h6gue8ZvPYcdiPdvueM/qm//9XzyTQ==", + "node_modules/nise/node_modules/@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", "dev": true, "dependencies": { - "@sinonjs/commons": "^1", - "@sinonjs/samsam": "^3.1.0" - } - }, - "node_modules/nise/node_modules/lolex": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", - "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^1.7.0" + "type-detect": "4.0.8" } }, "node_modules/normalize-package-data": { @@ -6355,13 +6342,6 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, - "node_modules/samsam": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", - "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==", - "deprecated": "This package has been deprecated in favour of @sinonjs/samsam", - "dev": true - }, "node_modules/secure-compare": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", @@ -6431,31 +6411,21 @@ "dev": true }, "node_modules/sinon": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-4.5.0.tgz", - "integrity": "sha512-trdx+mB0VBBgoYucy6a9L7/jfQOmvGeaKZT4OOJ+lPAtI8623xyGr8wLiE4eojzBS8G9yXbhx42GHUOVLr4X2w==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@sinonjs/formatio": "^2.0.0", - "diff": "^3.1.0", - "lodash.get": "^4.4.2", - "lolex": "^2.2.0", - "nise": "^1.2.0", - "supports-color": "^5.1.0", - "type-detect": "^4.0.5" - } - }, - "node_modules/sinon/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.1.0.tgz", + "integrity": "sha512-cS5FgpDdE9/zx7no8bxROHymSlPLZzq0ChbbLk1DrxBfc+eTeBK3y8nIL+nu/0QeYydhhbLIr7ecHJpywjQaoQ==", "dev": true, "dependencies": { - "has-flag": "^3.0.0" + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^10.2.0", + "@sinonjs/samsam": "^8.0.0", + "diff": "^5.1.0", + "nise": "^5.1.4", + "supports-color": "^7.2.0" }, - "engines": { - "node": ">=4" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/sinon" } }, "node_modules/slash": { @@ -8346,32 +8316,43 @@ } }, "@sinonjs/commons": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", - "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", "dev": true, "requires": { "type-detect": "4.0.8" } }, - "@sinonjs/formatio": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz", - "integrity": "sha512-ls6CAMA6/5gG+O/IdsBcblvnd8qcO/l1TYoNeAzp3wcISOxlPXQEus0mLcdwazEkWjaBdaJ3TaxmNgCLWwvWzg==", + "@sinonjs/fake-timers": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.2.0.tgz", + "integrity": "sha512-OPwQlEdg40HAj5KNF8WW6q2KG4Z+cBCZb3m4ninfTZKaBmbIJodviQsDBoYMPHkOyJJMHnOJo5j2+LKDOhOACg==", "dev": true, "requires": { - "samsam": "1.3.0" + "@sinonjs/commons": "^3.0.0" } }, "@sinonjs/samsam": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.3.tgz", - "integrity": "sha512-bKCMKZvWIjYD0BLGnNrxVuw4dkWCYsLqFOUWw8VgKF/+5Y+mE7LfHWPIYoDXowH+3a9LsWDMo0uAP8YDosPvHQ==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", + "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", "dev": true, "requires": { - "@sinonjs/commons": "^1.3.0", - "array-from": "^2.1.1", - "lodash": "^4.17.15" + "@sinonjs/commons": "^2.0.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + }, + "dependencies": { + "@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + } } }, "@sinonjs/text-encoding": { @@ -8625,12 +8606,6 @@ "@babel/runtime-corejs3": "^7.10.2" } }, - "array-from": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", - "integrity": "sha512-GQTc6Uupx1FCavi5mPzBvVT7nEOeWMmUA9P95wpfpW1XwMSKs+KaymD5C2Up7KAUKg/mYwbsUYzdZWcoajlNZg==", - "dev": true - }, "array-includes": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", @@ -9280,9 +9255,9 @@ "dev": true }, "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", + "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", "dev": true }, "doctrine": { @@ -11444,12 +11419,6 @@ } } }, - "lolex": { - "version": "2.7.5", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz", - "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==", - "dev": true - }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -11896,35 +11865,25 @@ "dev": true }, "nise": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/nise/-/nise-1.5.3.tgz", - "integrity": "sha512-Ymbac/94xeIrMf59REBPOv0thr+CJVFMhrlAkW/gjCIE58BGQdCj0x7KRCb3yz+Ga2Rz3E9XXSvUyyxqqhjQAQ==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.4.tgz", + "integrity": "sha512-8+Ib8rRJ4L0o3kfmyVCL7gzrohyDe0cMFTBa2d364yIrEGMEoetznKJx899YxjybU6bL9SQkYPSBBs1gyYs8Xg==", "dev": true, "requires": { - "@sinonjs/formatio": "^3.2.1", + "@sinonjs/commons": "^2.0.0", + "@sinonjs/fake-timers": "^10.0.2", "@sinonjs/text-encoding": "^0.7.1", "just-extend": "^4.0.2", - "lolex": "^5.0.1", "path-to-regexp": "^1.7.0" }, "dependencies": { - "@sinonjs/formatio": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.2.tgz", - "integrity": "sha512-B8SEsgd8gArBLMD6zpRw3juQ2FVSsmdd7qlevyDqzS9WTCtvF55/gAL+h6gue8ZvPYcdiPdvueM/qm//9XzyTQ==", + "@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", "dev": true, "requires": { - "@sinonjs/commons": "^1", - "@sinonjs/samsam": "^3.1.0" - } - }, - "lolex": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", - "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" + "type-detect": "4.0.8" } } } @@ -12574,12 +12533,6 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, - "samsam": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", - "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==", - "dev": true - }, "secure-compare": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", @@ -12637,29 +12590,17 @@ "dev": true }, "sinon": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-4.5.0.tgz", - "integrity": "sha512-trdx+mB0VBBgoYucy6a9L7/jfQOmvGeaKZT4OOJ+lPAtI8623xyGr8wLiE4eojzBS8G9yXbhx42GHUOVLr4X2w==", + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.1.0.tgz", + "integrity": "sha512-cS5FgpDdE9/zx7no8bxROHymSlPLZzq0ChbbLk1DrxBfc+eTeBK3y8nIL+nu/0QeYydhhbLIr7ecHJpywjQaoQ==", "dev": true, "requires": { - "@sinonjs/formatio": "^2.0.0", - "diff": "^3.1.0", - "lodash.get": "^4.4.2", - "lolex": "^2.2.0", - "nise": "^1.2.0", - "supports-color": "^5.1.0", - "type-detect": "^4.0.5" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^10.2.0", + "@sinonjs/samsam": "^8.0.0", + "diff": "^5.1.0", + "nise": "^5.1.4", + "supports-color": "^7.2.0" } }, "slash": { diff --git a/package.json b/package.json index b2dbd347..5486f194 100644 --- a/package.json +++ b/package.json @@ -101,7 +101,7 @@ "nyc": "^14.1.1", "playwright": "^1.30.0", "rollup": "^2.79.1", - "sinon": "^4.3.0", + "sinon": "^15.1.0", "ts-node": "^10.9.1", "typescript": "^4.1.2", "web-streams-polyfill": "^3.2.0" diff --git a/test/crypto/crypto.js b/test/crypto/crypto.js index 05d89880..e5bbeaf9 100644 --- a/test/crypto/crypto.js +++ b/test/crypto/crypto.js @@ -2,7 +2,6 @@ import { use as chaiUse, expect } from 'chai'; import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import chaiUse(chaiAsPromised); -import sandbox from 'sinon/lib/sinon/sandbox'; import openpgp from '../initOpenpgp.js'; import crypto from '../../src/crypto'; import util from '../../src/util.js'; @@ -253,19 +252,6 @@ export default () => describe('API functional testing', function() { await testCFB('1234567'); await testCFB('foobarfoobar1234567890'); await testCFB('12345678901234567890123456789012345678901234567890'); - // test using webCrypto - const sinonSandbox = sandbox.create(); - const webCrypto = util.getWebCrypto(); - if (webCrypto && !util.getNodeCrypto()) { - const webCryptoSpy = sinonSandbox.spy(webCrypto, 'encrypt'); - try { - await testCFB('12345678901234567890123456789012345678901234567890', { ...openpgp.config, minBytesForWebCrypto: 0 }); - } finally { - expect(webCryptoSpy.called).to.be.true; - sinonSandbox.restore(); - } - } - }); it('Asymmetric using RSA with eme_pkcs1 padding', function () { diff --git a/test/crypto/eax.js b/test/crypto/eax.js index 54023f46..d5191b37 100644 --- a/test/crypto/eax.js +++ b/test/crypto/eax.js @@ -1,7 +1,7 @@ // Modified by ProtonTech AG // Adapted from https://github.com/artjomb/cryptojs-extension/blob/8c61d159/test/eax.js -import sandbox from 'sinon/lib/sinon/sandbox'; +import sinon from 'sinon'; import { use as chaiUse, expect } from 'chai'; import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import chaiUse(chaiAsPromised); @@ -148,7 +148,7 @@ export default () => describe('Symmetric AES-EAX', function() { }); beforeEach(function () { - sinonSandbox = sandbox.create(); + sinonSandbox = sinon.createSandbox(); enableNative(); }); @@ -161,7 +161,7 @@ export default () => describe('Symmetric AES-EAX', function() { describe('Symmetric AES-EAX (asm.js fallback)', function() { beforeEach(function () { - sinonSandbox = sandbox.create(); + sinonSandbox = sinon.createSandbox(); disableNative(); }); diff --git a/test/crypto/ecdh.js b/test/crypto/ecdh.js index 35ae5c3a..501f0481 100644 --- a/test/crypto/ecdh.js +++ b/test/crypto/ecdh.js @@ -1,4 +1,4 @@ -import sandbox from 'sinon/lib/sinon/sandbox'; +import sinon from 'sinon'; import { use as chaiUse, expect } from 'chai'; import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import chaiUse(chaiAsPromised); @@ -208,7 +208,7 @@ export default () => describe('ECDH key exchange @lightweight', function () { let getNodeCryptoStub; beforeEach(function () { - sinonSandbox = sandbox.create(); + sinonSandbox = sinon.createSandbox(); }); afterEach(function () { diff --git a/test/crypto/elliptic.js b/test/crypto/elliptic.js index c92102b1..f34660e0 100644 --- a/test/crypto/elliptic.js +++ b/test/crypto/elliptic.js @@ -1,4 +1,4 @@ -import sandbox from 'sinon/lib/sinon/sandbox'; +import sinon from 'sinon'; import { use as chaiUse, expect } from 'chai'; import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import chaiUse(chaiAsPromised); @@ -104,7 +104,7 @@ export default () => describe('Elliptic Curve Cryptography @lightweight', functi let getNodeCryptoStub; beforeEach(function () { - sinonSandbox = sandbox.create(); + sinonSandbox = sinon.createSandbox(); }); afterEach(function () { diff --git a/test/crypto/gcm.js b/test/crypto/gcm.js index 441d6f9c..f564c400 100644 --- a/test/crypto/gcm.js +++ b/test/crypto/gcm.js @@ -1,4 +1,4 @@ -import sandbox from 'sinon/lib/sinon/sandbox'; +import sinon from 'sinon'; import { use as chaiUse, expect } from 'chai'; import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import chaiUse(chaiAsPromised); @@ -14,7 +14,7 @@ export default () => describe('Symmetric AES-GCM (experimental)', function() { let getNodeCryptoStub; beforeEach(function () { - sinonSandbox = sandbox.create(); + sinonSandbox = sinon.createSandbox(); enableNative(); }); diff --git a/test/crypto/rsa.js b/test/crypto/rsa.js index 1be4a127..21739fe5 100644 --- a/test/crypto/rsa.js +++ b/test/crypto/rsa.js @@ -1,4 +1,4 @@ -import sandbox from 'sinon/lib/sinon/sandbox'; +import sinon from 'sinon'; import { use as chaiUse, expect } from 'chai'; import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import chaiUse(chaiAsPromised); @@ -15,7 +15,7 @@ export default () => describe('basic RSA cryptography', function () { let getNodeCryptoStub; beforeEach(function () { - sinonSandbox = sandbox.create(); + sinonSandbox = sinon.createSandbox(); enableNative(); }); diff --git a/test/general/openpgp.js b/test/general/openpgp.js index 1039e78d..06326518 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -1,6 +1,6 @@ /* eslint-disable max-lines */ /* globals tryTests, loadStreamsPolyfill */ -import spy from 'sinon/lib/sinon/spy'; +import sinon from 'sinon'; import * as stream from '@openpgp/web-stream-tools'; import { use as chaiUse, expect } from 'chai'; import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import @@ -865,8 +865,8 @@ function withCompression(tests) { let decompressSpy; beforeEach(function () { - compressSpy = spy(openpgp.CompressedDataPacket.prototype, 'compress'); - decompressSpy = spy(openpgp.CompressedDataPacket.prototype, 'decompress'); + compressSpy = sinon.spy(openpgp.CompressedDataPacket.prototype, 'compress'); + decompressSpy = sinon.spy(openpgp.CompressedDataPacket.prototype, 'decompress'); }); afterEach(function () { diff --git a/test/general/packet.js b/test/general/packet.js index 5590e6cd..ced7121c 100644 --- a/test/general/packet.js +++ b/test/general/packet.js @@ -1,6 +1,6 @@ /* eslint-disable max-lines */ import * as stream from '@openpgp/web-stream-tools'; -import stub from 'sinon/lib/sinon/stub'; +import sinon from 'sinon'; import { use as chaiUse, expect } from 'chai'; import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import chaiUse(chaiAsPromised); @@ -183,7 +183,7 @@ export default () => describe('Packet', function() { function cryptStub(webCrypto, method) { const crypt = webCrypto[method]; - const cryptStub = stub(webCrypto, method); + const cryptStub = sinon.stub(webCrypto, method); let cryptCallsActive = 0; cryptStub.onCall(0).callsFake(async function() { cryptCallsActive++; @@ -265,7 +265,7 @@ export default () => describe('Packet', function() { const msg2 = new openpgp.PacketList(); - const randomBytesStub = stub(nodeCrypto, 'randomBytes'); + const randomBytesStub = sinon.stub(nodeCrypto, 'randomBytes'); randomBytesStub.returns(iv); try { @@ -534,7 +534,7 @@ export default () => describe('Packet', function() { const sessionIV = util.hexToUint8Array('bc 66 9e 34 e5 00 dc ae dc 5b 32 aa 2d ab 02 35'.replace(/\s+/g, '')); const dataIV = util.hexToUint8Array('b7 32 37 9f 73 c4 92 8d e2 5f ac fe 65 17 ec 10'.replace(/\s+/g, '')); - const randomBytesStub = stub(nodeCrypto, 'randomBytes'); + const randomBytesStub = sinon.stub(nodeCrypto, 'randomBytes'); randomBytesStub.onCall(0).returns(salt); randomBytesStub.onCall(1).returns(sessionKey); randomBytesStub.onCall(2).returns(sessionIV); @@ -611,7 +611,7 @@ export default () => describe('Packet', function() { const sessionIV = util.hexToUint8Array('99 e3 26 e5 40 0a 90 93 6c ef b4 e8 eb a0 8c'.replace(/\s+/g, '')); const dataIV = util.hexToUint8Array('5e d2 bc 1e 47 0a be 8f 1d 64 4c 7a 6c 8a 56'.replace(/\s+/g, '')); - const randomBytesStub = stub(nodeCrypto, 'randomBytes'); + const randomBytesStub = sinon.stub(nodeCrypto, 'randomBytes'); randomBytesStub.onCall(0).returns(salt); randomBytesStub.onCall(1).returns(sessionKey); randomBytesStub.onCall(2).returns(sessionIV); diff --git a/test/general/streaming.js b/test/general/streaming.js index e4dd91b7..e60a9f16 100644 --- a/test/general/streaming.js +++ b/test/general/streaming.js @@ -1,7 +1,7 @@ /* eslint-disable max-lines */ /* globals loadStreamsPolyfill */ import * as stream from '@openpgp/web-stream-tools'; -import stub from 'sinon/lib/sinon/stub'; +import sinon from 'sinon'; import { use as chaiUse, expect } from 'chai'; import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import chaiUse(chaiAsPromised); @@ -850,7 +850,7 @@ function tests() { it("Don't pull entire input stream when we're not pulling decrypted stream (AEAD)", async function() { let coresStub; if (detectNode()) { - coresStub = stub(util.nodeRequire('os'), 'cpus'); + coresStub = sinon.stub(util.nodeRequire('os'), 'cpus'); coresStub.returns(new Array(2)); // Object.defineProperty(require('os'), 'cpus', { value: () => [,], configurable: true }); } else { From 7c9549ce883e55f18d235a7637b2e96906c38790 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Tue, 20 Jun 2023 13:13:48 +0200 Subject: [PATCH 018/201] Drop `config.minBytesForWebCrypto` WebCrypto performance is now on-par or better than non-native libs even for small messages --- openpgp.d.ts | 1 - src/config/config.js | 6 ------ src/crypto/hash/index.js | 9 ++++----- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/openpgp.d.ts b/openpgp.d.ts index c161efac..e674c017 100644 --- a/openpgp.d.ts +++ b/openpgp.d.ts @@ -335,7 +335,6 @@ interface Config { s2kType: enums.s2k.iterated | enums.s2k.argon2; s2kIterationCountByte: number; s2kArgon2Params: { passes: number, parallelism: number; memoryExponent: number; }; - minBytesForWebCrypto: number; maxUserIDLength: number; knownNotations: string[]; useIndutnyElliptic: boolean; diff --git a/src/config/config.js b/src/config/config.js index 6f2baadb..1e6bd3ef 100644 --- a/src/config/config.js +++ b/src/config/config.js @@ -190,12 +190,6 @@ export default { * @property {Set} constantTimePKCS1DecryptionSupportedSymmetricAlgorithms {@link module:enums.symmetric} */ constantTimePKCS1DecryptionSupportedSymmetricAlgorithms: new Set([enums.symmetric.aes128, enums.symmetric.aes192, enums.symmetric.aes256]), - - /** - * @memberof module:config - * @property {Integer} minBytesForWebCrypto The minimum amount of bytes for which to use native WebCrypto APIs when available - */ - minBytesForWebCrypto: 1000, /** * @memberof module:config * @property {Boolean} ignoreUnsupportedPackets Ignore unsupported/unrecognizable packets on parsing instead of throwing an error diff --git a/src/crypto/hash/index.js b/src/crypto/hash/index.js index a3dc6972..50b66ad2 100644 --- a/src/crypto/hash/index.js +++ b/src/crypto/hash/index.js @@ -14,7 +14,6 @@ import { ripemd160 } from 'hash.js/lib/hash/ripemd'; import * as stream from '@openpgp/web-stream-tools'; import md5 from './md5'; import util from '../../util'; -import defaultConfig from '../../config'; import enums from '../../enums'; const webCrypto = util.getWebCrypto(); @@ -34,11 +33,11 @@ function nodeHash(type) { } function hashjsHash(hash, webCryptoHash) { - return async function(data, config = defaultConfig) { + return async function(data) { if (stream.isArrayStream(data)) { data = await stream.readToEnd(data); } - if (!util.isStream(data) && webCrypto && webCryptoHash && data.length >= config.minBytesForWebCrypto) { + if (!util.isStream(data) && webCrypto && webCryptoHash) { return new Uint8Array(await webCrypto.digest(webCryptoHash, data)); } const hashInstance = hash(); @@ -49,7 +48,7 @@ function hashjsHash(hash, webCryptoHash) { } function nobleHash(hash, webCryptoHash) { - return async function(data, config = defaultConfig) { + return async function(data) { if (stream.isArrayStream(data)) { data = await stream.readToEnd(data); } @@ -58,7 +57,7 @@ function nobleHash(hash, webCryptoHash) { return stream.transform(data, value => { hashInstance.update(value); }, () => hashInstance.digest()); - } else if (webCrypto && webCryptoHash && data.length >= config.minBytesForWebCrypto) { + } else if (webCrypto && webCryptoHash) { return new Uint8Array(await webCrypto.digest(webCryptoHash, data)); } else { return hash(data); From e07a0c432ab2094c43b521e64c2b28055220483c Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Tue, 20 Jun 2023 13:44:23 +0200 Subject: [PATCH 019/201] Replace hash.js with noble-hashes --- package-lock.json | 1 - package.json | 1 - src/crypto/hash/index.js | 37 ++++--------------- src/crypto/public_key/elliptic/eddsa.js | 4 +- .../public_key/elliptic/eddsa_legacy.js | 4 +- 5 files changed, 11 insertions(+), 36 deletions(-) diff --git a/package-lock.json b/package-lock.json index b3eb3310..3047d644 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,7 +38,6 @@ "eslint-plugin-chai-friendly": "^0.7.2", "eslint-plugin-import": "^2.27.5", "fflate": "^0.7.4", - "hash.js": "^1.1.3", "http-server": "^14.1.1", "karma": "^6.4.0", "karma-browserstack-launcher": "^1.6.0", diff --git a/package.json b/package.json index 5486f194..afae2ddd 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,6 @@ "eslint-plugin-chai-friendly": "^0.7.2", "eslint-plugin-import": "^2.27.5", "fflate": "^0.7.4", - "hash.js": "^1.1.3", "http-server": "^14.1.1", "karma": "^6.4.0", "karma-browserstack-launcher": "^1.6.0", diff --git a/src/crypto/hash/index.js b/src/crypto/hash/index.js index 50b66ad2..bdf6d60b 100644 --- a/src/crypto/hash/index.js +++ b/src/crypto/hash/index.js @@ -6,11 +6,9 @@ */ import { sha1 } from '@openpgp/noble-hashes/sha1'; -import { sha256 } from '@openpgp/noble-hashes/sha256'; -import sha224 from 'hash.js/lib/hash/sha/224'; -import sha384 from 'hash.js/lib/hash/sha/384'; -import sha512 from 'hash.js/lib/hash/sha/512'; -import { ripemd160 } from 'hash.js/lib/hash/ripemd'; +import { sha224, sha256 } from '@openpgp/noble-hashes/sha256'; +import { sha384, sha512 } from '@openpgp/noble-hashes/sha512'; +import { ripemd160 } from '@openpgp/noble-hashes/ripemd160'; import * as stream from '@openpgp/web-stream-tools'; import md5 from './md5'; import util from '../../util'; @@ -32,21 +30,6 @@ function nodeHash(type) { }; } -function hashjsHash(hash, webCryptoHash) { - return async function(data) { - if (stream.isArrayStream(data)) { - data = await stream.readToEnd(data); - } - if (!util.isStream(data) && webCrypto && webCryptoHash) { - return new Uint8Array(await webCrypto.digest(webCryptoHash, data)); - } - const hashInstance = hash(); - return stream.transform(data, value => { - hashInstance.update(value); - }, () => new Uint8Array(hashInstance.digest())); - }; -} - function nobleHash(hash, webCryptoHash) { return async function(data) { if (stream.isArrayStream(data)) { @@ -68,28 +51,22 @@ function nobleHash(hash, webCryptoHash) { const hashFunctions = { md5: nodeHash('md5') || md5, sha1: nodeHash('sha1') || nobleHash(sha1, 'SHA-1'), - sha224: nodeHash('sha224') || hashjsHash(sha224), + sha224: nodeHash('sha224') || nobleHash(sha224), sha256: nodeHash('sha256') || nobleHash(sha256, 'SHA-256'), - sha384: nodeHash('sha384') || hashjsHash(sha384, 'SHA-384'), - sha512: nodeHash('sha512') || hashjsHash(sha512, 'SHA-512'), // asmcrypto sha512 is huge. - ripemd: nodeHash('ripemd160') || hashjsHash(ripemd160) + sha384: nodeHash('sha384') || nobleHash(sha384, 'SHA-384'), + sha512: nodeHash('sha512') || nobleHash(sha512, 'SHA-512'), + ripemd: nodeHash('ripemd160') || nobleHash(ripemd160) }; export default { /** @see module:md5 */ md5: hashFunctions.md5, - /** @see asmCrypto */ sha1: hashFunctions.sha1, - /** @see hash.js */ sha224: hashFunctions.sha224, - /** @see asmCrypto */ sha256: hashFunctions.sha256, - /** @see hash.js */ sha384: hashFunctions.sha384, - /** @see asmCrypto */ sha512: hashFunctions.sha512, - /** @see hash.js */ ripemd: hashFunctions.ripemd, /** diff --git a/src/crypto/public_key/elliptic/eddsa.js b/src/crypto/public_key/elliptic/eddsa.js index 413f967f..002f3f29 100644 --- a/src/crypto/public_key/elliptic/eddsa.js +++ b/src/crypto/public_key/elliptic/eddsa.js @@ -20,14 +20,14 @@ * @module crypto/public_key/elliptic/eddsa */ -import sha512 from 'hash.js/lib/hash/sha/512'; +import { sha512 } from '@openpgp/noble-hashes/sha512'; import nacl from '@openpgp/tweetnacl/nacl-fast-light'; import util from '../../../util'; import enums from '../../../enums'; import hash from '../../hash'; import { getRandomBytes } from '../../random'; -nacl.hash = bytes => new Uint8Array(sha512().update(bytes).digest()); +nacl.hash = bytes => sha512(bytes); /** * Generate (non-legacy) EdDSA key diff --git a/src/crypto/public_key/elliptic/eddsa_legacy.js b/src/crypto/public_key/elliptic/eddsa_legacy.js index 726d7ce0..3de09ba4 100644 --- a/src/crypto/public_key/elliptic/eddsa_legacy.js +++ b/src/crypto/public_key/elliptic/eddsa_legacy.js @@ -21,13 +21,13 @@ * @module crypto/public_key/elliptic/eddsa_legacy */ -import sha512 from 'hash.js/lib/hash/sha/512'; +import { sha512 } from '@openpgp/noble-hashes/sha512'; import nacl from '@openpgp/tweetnacl/nacl-fast-light'; import util from '../../../util'; import enums from '../../../enums'; import hash from '../../hash'; -nacl.hash = bytes => new Uint8Array(sha512().update(bytes).digest()); +nacl.hash = bytes => sha512(bytes); /** * Sign a message using the provided legacy EdDSA key From 6ef4392fb11af9dca75b6dca2a5ee0acda4f8425 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Tue, 20 Jun 2023 14:23:08 +0200 Subject: [PATCH 020/201] Lint: update config to support ESM imports --- .eslintrc.cjs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 93758d15..7d077cba 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -95,10 +95,14 @@ module.exports = { // eslint-plugin-import rules: 'import/named': 'error', - 'import/extensions': 'error', + 'import/extensions': 'off', // temporary: we use them in tests (ESM compliant), but not in the lib (to limit diff) 'import/first': 'off', 'import/no-extraneous-dependencies': ['error', { 'devDependencies': true, 'optionalDependencies': false, 'peerDependencies': false }], 'import/no-unassigned-import': 'error', + 'import/no-unresolved': ['error', { + // esm exports not supported: https://github.com/import-js/eslint-plugin-import/issues/1810 + ignore: ['openpgp', '@openpgp/noble-hashes', '@openpgp/web-stream-tools', '@openpgp/asmcrypto.js'] + }], 'import/prefer-default-export': 'off', // Custom silencers: From 97b73489d1e0a598262b6885145a5efa2ef47859 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Wed, 21 Jun 2023 11:55:44 +0200 Subject: [PATCH 021/201] Replace internal BigInteger code with that from noble-hashes The noble-hashes fork uses the same fallback implementation, except BN.js is always imported (due to lib contraints), so a dynamic import is now superfluous --- src/biginteger/bn.interface.js | 334 -------------- src/biginteger/index.js | 14 - src/biginteger/native.interface.js | 453 ------------------- src/crypto/public_key/dsa.js | 50 +- src/crypto/public_key/elgamal.js | 44 +- src/crypto/public_key/elliptic/oid_curves.js | 8 +- src/crypto/public_key/prime.js | 23 +- src/crypto/public_key/rsa.js | 68 ++- src/crypto/random.js | 5 +- src/util.js | 10 - test/general/biginteger.js | 161 ------- test/general/index.js | 2 - 12 files changed, 88 insertions(+), 1084 deletions(-) delete mode 100644 src/biginteger/bn.interface.js delete mode 100644 src/biginteger/index.js delete mode 100644 src/biginteger/native.interface.js delete mode 100644 test/general/biginteger.js diff --git a/src/biginteger/bn.interface.js b/src/biginteger/bn.interface.js deleted file mode 100644 index b8d5b79e..00000000 --- a/src/biginteger/bn.interface.js +++ /dev/null @@ -1,334 +0,0 @@ -import BN from 'bn.js'; - -/** - * @fileoverview - * BigInteger implementation of basic operations - * Wrapper of bn.js library (wwww.github.com/indutny/bn.js) - * @module biginteger/bn - * @private - */ - -/** - * @private - */ -export default class BigInteger { - /** - * Get a BigInteger (input must be big endian for strings and arrays) - * @param {Number|String|Uint8Array} n - Value to convert - * @throws {Error} on undefined input - */ - constructor(n) { - if (n === undefined) { - throw new Error('Invalid BigInteger input'); - } - - this.value = new BN(n); - } - - clone() { - const clone = new BigInteger(null); - this.value.copy(clone.value); - return clone; - } - - /** - * BigInteger increment in place - */ - iinc() { - this.value.iadd(new BN(1)); - return this; - } - - /** - * BigInteger increment - * @returns {BigInteger} this + 1. - */ - inc() { - return this.clone().iinc(); - } - - /** - * BigInteger decrement in place - */ - idec() { - this.value.isub(new BN(1)); - return this; - } - - /** - * BigInteger decrement - * @returns {BigInteger} this - 1. - */ - dec() { - return this.clone().idec(); - } - - - /** - * BigInteger addition in place - * @param {BigInteger} x - Value to add - */ - iadd(x) { - this.value.iadd(x.value); - return this; - } - - /** - * BigInteger addition - * @param {BigInteger} x - Value to add - * @returns {BigInteger} this + x. - */ - add(x) { - return this.clone().iadd(x); - } - - /** - * BigInteger subtraction in place - * @param {BigInteger} x - Value to subtract - */ - isub(x) { - this.value.isub(x.value); - return this; - } - - /** - * BigInteger subtraction - * @param {BigInteger} x - Value to subtract - * @returns {BigInteger} this - x. - */ - sub(x) { - return this.clone().isub(x); - } - - /** - * BigInteger multiplication in place - * @param {BigInteger} x - Value to multiply - */ - imul(x) { - this.value.imul(x.value); - return this; - } - - /** - * BigInteger multiplication - * @param {BigInteger} x - Value to multiply - * @returns {BigInteger} this * x. - */ - mul(x) { - return this.clone().imul(x); - } - - /** - * Compute value modulo m, in place - * @param {BigInteger} m - Modulo - */ - imod(m) { - this.value = this.value.umod(m.value); - return this; - } - - /** - * Compute value modulo m - * @param {BigInteger} m - Modulo - * @returns {BigInteger} this mod m. - */ - mod(m) { - return this.clone().imod(m); - } - - /** - * Compute modular exponentiation - * Much faster than this.exp(e).mod(n) - * @param {BigInteger} e - Exponent - * @param {BigInteger} n - Modulo - * @returns {BigInteger} this ** e mod n. - */ - modExp(e, n) { - // We use either Montgomery or normal reduction context - // Montgomery requires coprime n and R (montogmery multiplier) - // bn.js picks R as power of 2, so n must be odd - const nred = n.isEven() ? BN.red(n.value) : BN.mont(n.value); - const x = this.clone(); - x.value = x.value.toRed(nred).redPow(e.value).fromRed(); - return x; - } - - /** - * Compute the inverse of this value modulo n - * Note: this and and n must be relatively prime - * @param {BigInteger} n - Modulo - * @returns {BigInteger} x such that this*x = 1 mod n - * @throws {Error} if the inverse does not exist - */ - modInv(n) { - // invm returns a wrong result if the inverse does not exist - if (!this.gcd(n).isOne()) { - throw new Error('Inverse does not exist'); - } - return new BigInteger(this.value.invm(n.value)); - } - - /** - * Compute greatest common divisor between this and n - * @param {BigInteger} n - Operand - * @returns {BigInteger} gcd - */ - gcd(n) { - return new BigInteger(this.value.gcd(n.value)); - } - - /** - * Shift this to the left by x, in place - * @param {BigInteger} x - Shift value - */ - ileftShift(x) { - this.value.ishln(x.value.toNumber()); - return this; - } - - /** - * Shift this to the left by x - * @param {BigInteger} x - Shift value - * @returns {BigInteger} this << x. - */ - leftShift(x) { - return this.clone().ileftShift(x); - } - - /** - * Shift this to the right by x, in place - * @param {BigInteger} x - Shift value - */ - irightShift(x) { - this.value.ishrn(x.value.toNumber()); - return this; - } - - /** - * Shift this to the right by x - * @param {BigInteger} x - Shift value - * @returns {BigInteger} this >> x. - */ - rightShift(x) { - return this.clone().irightShift(x); - } - - /** - * Whether this value is equal to x - * @param {BigInteger} x - * @returns {Boolean} - */ - equal(x) { - return this.value.eq(x.value); - } - - /** - * Whether this value is less than x - * @param {BigInteger} x - * @returns {Boolean} - */ - lt(x) { - return this.value.lt(x.value); - } - - /** - * Whether this value is less than or equal to x - * @param {BigInteger} x - * @returns {Boolean} - */ - lte(x) { - return this.value.lte(x.value); - } - - /** - * Whether this value is greater than x - * @param {BigInteger} x - * @returns {Boolean} - */ - gt(x) { - return this.value.gt(x.value); - } - - /** - * Whether this value is greater than or equal to x - * @param {BigInteger} x - * @returns {Boolean} - */ - gte(x) { - return this.value.gte(x.value); - } - - isZero() { - return this.value.isZero(); - } - - isOne() { - return this.value.eq(new BN(1)); - } - - isNegative() { - return this.value.isNeg(); - } - - isEven() { - return this.value.isEven(); - } - - abs() { - const res = this.clone(); - res.value = res.value.abs(); - return res; - } - - /** - * Get this value as a string - * @returns {String} this value. - */ - toString() { - return this.value.toString(); - } - - /** - * Get this value as an exact Number (max 53 bits) - * Fails if this value is too large - * @returns {Number} - */ - toNumber() { - return this.value.toNumber(); - } - - /** - * Get value of i-th bit - * @param {Number} i - Bit index - * @returns {Number} Bit value. - */ - getBit(i) { - return this.value.testn(i) ? 1 : 0; - } - - /** - * Compute bit length - * @returns {Number} Bit length. - */ - bitLength() { - return this.value.bitLength(); - } - - /** - * Compute byte length - * @returns {Number} Byte length. - */ - byteLength() { - return this.value.byteLength(); - } - - /** - * Get Uint8Array representation of this number - * @param {String} endian - Endianess of output array (defaults to 'be') - * @param {Number} length - Of output array - * @returns {Uint8Array} - */ - toUint8Array(endian = 'be', length) { - return this.value.toArrayLike(Uint8Array, endian, length); - } -} diff --git a/src/biginteger/index.js b/src/biginteger/index.js deleted file mode 100644 index cf687b44..00000000 --- a/src/biginteger/index.js +++ /dev/null @@ -1,14 +0,0 @@ -import BigInteger from './native.interface'; - -const detectBigInt = () => typeof BigInt !== 'undefined'; - -async function getBigInteger() { - if (detectBigInt()) { - return BigInteger; - } else { - const { default: BigInteger } = await import('./bn.interface'); - return BigInteger; - } -} - -export { getBigInteger }; diff --git a/src/biginteger/native.interface.js b/src/biginteger/native.interface.js deleted file mode 100644 index a524006c..00000000 --- a/src/biginteger/native.interface.js +++ /dev/null @@ -1,453 +0,0 @@ -/* eslint-disable new-cap */ - -/** - * @fileoverview - * BigInteger implementation of basic operations - * that wraps the native BigInt library. - * Operations are not constant time, - * but we try and limit timing leakage where we can - * @module biginteger/native - * @private - */ - -/** - * @private - */ -export default class BigInteger { - /** - * Get a BigInteger (input must be big endian for strings and arrays) - * @param {Number|String|Uint8Array} n - Value to convert - * @throws {Error} on null or undefined input - */ - constructor(n) { - if (n === undefined) { - throw new Error('Invalid BigInteger input'); - } - - if (n instanceof Uint8Array) { - const bytes = n; - const hex = new Array(bytes.length); - for (let i = 0; i < bytes.length; i++) { - const hexByte = bytes[i].toString(16); - hex[i] = (bytes[i] <= 0xF) ? ('0' + hexByte) : hexByte; - } - this.value = BigInt('0x0' + hex.join('')); - } else { - this.value = BigInt(n); - } - } - - clone() { - return new BigInteger(this.value); - } - - /** - * BigInteger increment in place - */ - iinc() { - this.value++; - return this; - } - - /** - * BigInteger increment - * @returns {BigInteger} this + 1. - */ - inc() { - return this.clone().iinc(); - } - - /** - * BigInteger decrement in place - */ - idec() { - this.value--; - return this; - } - - /** - * BigInteger decrement - * @returns {BigInteger} this - 1. - */ - dec() { - return this.clone().idec(); - } - - /** - * BigInteger addition in place - * @param {BigInteger} x - Value to add - */ - iadd(x) { - this.value += x.value; - return this; - } - - /** - * BigInteger addition - * @param {BigInteger} x - Value to add - * @returns {BigInteger} this + x. - */ - add(x) { - return this.clone().iadd(x); - } - - /** - * BigInteger subtraction in place - * @param {BigInteger} x - Value to subtract - */ - isub(x) { - this.value -= x.value; - return this; - } - - /** - * BigInteger subtraction - * @param {BigInteger} x - Value to subtract - * @returns {BigInteger} this - x. - */ - sub(x) { - return this.clone().isub(x); - } - - /** - * BigInteger multiplication in place - * @param {BigInteger} x - Value to multiply - */ - imul(x) { - this.value *= x.value; - return this; - } - - /** - * BigInteger multiplication - * @param {BigInteger} x - Value to multiply - * @returns {BigInteger} this * x. - */ - mul(x) { - return this.clone().imul(x); - } - - /** - * Compute value modulo m, in place - * @param {BigInteger} m - Modulo - */ - imod(m) { - this.value %= m.value; - if (this.isNegative()) { - this.iadd(m); - } - return this; - } - - /** - * Compute value modulo m - * @param {BigInteger} m - Modulo - * @returns {BigInteger} this mod m. - */ - mod(m) { - return this.clone().imod(m); - } - - /** - * Compute modular exponentiation using square and multiply - * @param {BigInteger} e - Exponent - * @param {BigInteger} n - Modulo - * @returns {BigInteger} this ** e mod n. - */ - modExp(e, n) { - if (n.isZero()) throw Error('Modulo cannot be zero'); - if (n.isOne()) return new BigInteger(0); - if (e.isNegative()) throw Error('Unsopported negative exponent'); - - let exp = e.value; - let x = this.value; - - x %= n.value; - let r = BigInt(1); - while (exp > BigInt(0)) { - const lsb = exp & BigInt(1); - exp >>= BigInt(1); // e / 2 - // Always compute multiplication step, to reduce timing leakage - const rx = (r * x) % n.value; - // Update r only if lsb is 1 (odd exponent) - r = lsb ? rx : r; - x = (x * x) % n.value; // Square - } - return new BigInteger(r); - } - - - /** - * Compute the inverse of this value modulo n - * Note: this and and n must be relatively prime - * @param {BigInteger} n - Modulo - * @returns {BigInteger} x such that this*x = 1 mod n - * @throws {Error} if the inverse does not exist - */ - modInv(n) { - const { gcd, x } = this._egcd(n); - if (!gcd.isOne()) { - throw new Error('Inverse does not exist'); - } - return x.add(n).mod(n); - } - - /** - * Extended Eucleadian algorithm (http://anh.cs.luc.edu/331/notes/xgcd.pdf) - * Given a = this and b, compute (x, y) such that ax + by = gdc(a, b) - * @param {BigInteger} b - Second operand - * @returns {{ gcd, x, y: BigInteger }} - */ - _egcd(b) { - let x = BigInt(0); - let y = BigInt(1); - let xPrev = BigInt(1); - let yPrev = BigInt(0); - - let a = this.value; - b = b.value; - - while (b !== BigInt(0)) { - const q = a / b; - let tmp = x; - x = xPrev - q * x; - xPrev = tmp; - - tmp = y; - y = yPrev - q * y; - yPrev = tmp; - - tmp = b; - b = a % b; - a = tmp; - } - - return { - x: new BigInteger(xPrev), - y: new BigInteger(yPrev), - gcd: new BigInteger(a) - }; - } - - /** - * Compute greatest common divisor between this and n - * @param {BigInteger} b - Operand - * @returns {BigInteger} gcd - */ - gcd(b) { - let a = this.value; - b = b.value; - while (b !== BigInt(0)) { - const tmp = b; - b = a % b; - a = tmp; - } - return new BigInteger(a); - } - - /** - * Shift this to the left by x, in place - * @param {BigInteger} x - Shift value - */ - ileftShift(x) { - this.value <<= x.value; - return this; - } - - /** - * Shift this to the left by x - * @param {BigInteger} x - Shift value - * @returns {BigInteger} this << x. - */ - leftShift(x) { - return this.clone().ileftShift(x); - } - - /** - * Shift this to the right by x, in place - * @param {BigInteger} x - Shift value - */ - irightShift(x) { - this.value >>= x.value; - return this; - } - - /** - * Shift this to the right by x - * @param {BigInteger} x - Shift value - * @returns {BigInteger} this >> x. - */ - rightShift(x) { - return this.clone().irightShift(x); - } - - /** - * Whether this value is equal to x - * @param {BigInteger} x - * @returns {Boolean} - */ - equal(x) { - return this.value === x.value; - } - - /** - * Whether this value is less than x - * @param {BigInteger} x - * @returns {Boolean} - */ - lt(x) { - return this.value < x.value; - } - - /** - * Whether this value is less than or equal to x - * @param {BigInteger} x - * @returns {Boolean} - */ - lte(x) { - return this.value <= x.value; - } - - /** - * Whether this value is greater than x - * @param {BigInteger} x - * @returns {Boolean} - */ - gt(x) { - return this.value > x.value; - } - - /** - * Whether this value is greater than or equal to x - * @param {BigInteger} x - * @returns {Boolean} - */ - gte(x) { - return this.value >= x.value; - } - - isZero() { - return this.value === BigInt(0); - } - - isOne() { - return this.value === BigInt(1); - } - - isNegative() { - return this.value < BigInt(0); - } - - isEven() { - return !(this.value & BigInt(1)); - } - - abs() { - const res = this.clone(); - if (this.isNegative()) { - res.value = -res.value; - } - return res; - } - - /** - * Get this value as a string - * @returns {String} this value. - */ - toString() { - return this.value.toString(); - } - - /** - * Get this value as an exact Number (max 53 bits) - * Fails if this value is too large - * @returns {Number} - */ - toNumber() { - const number = Number(this.value); - if (number > Number.MAX_SAFE_INTEGER) { - // We throw and error to conform with the bn.js implementation - throw new Error('Number can only safely store up to 53 bits'); - } - return number; - } - - /** - * Get value of i-th bit - * @param {Number} i - Bit index - * @returns {Number} Bit value. - */ - getBit(i) { - const bit = (this.value >> BigInt(i)) & BigInt(1); - return (bit === BigInt(0)) ? 0 : 1; - } - - /** - * Compute bit length - * @returns {Number} Bit length. - */ - bitLength() { - const zero = new BigInteger(0); - const one = new BigInteger(1); - const negOne = new BigInteger(-1); - - // -1n >> -1n is -1n - // 1n >> 1n is 0n - const target = this.isNegative() ? negOne : zero; - let bitlen = 1; - const tmp = this.clone(); - while (!tmp.irightShift(one).equal(target)) { - bitlen++; - } - return bitlen; - } - - /** - * Compute byte length - * @returns {Number} Byte length. - */ - byteLength() { - const zero = new BigInteger(0); - const negOne = new BigInteger(-1); - - const target = this.isNegative() ? negOne : zero; - const eight = new BigInteger(8); - let len = 1; - const tmp = this.clone(); - while (!tmp.irightShift(eight).equal(target)) { - len++; - } - return len; - } - - /** - * Get Uint8Array representation of this number - * @param {String} endian - Endianess of output array (defaults to 'be') - * @param {Number} length - Of output array - * @returns {Uint8Array} - */ - toUint8Array(endian = 'be', length) { - // we get and parse the hex string (https://coolaj86.com/articles/convert-js-bigints-to-typedarrays/) - // this is faster than shift+mod iterations - let hex = this.value.toString(16); - if (hex.length % 2 === 1) { - hex = '0' + hex; - } - - const rawLength = hex.length / 2; - const bytes = new Uint8Array(length || rawLength); - // parse hex - const offset = length ? (length - rawLength) : 0; - let i = 0; - while (i < rawLength) { - bytes[i + offset] = parseInt(hex.slice(2 * i, 2 * i + 2), 16); - i++; - } - - if (endian !== 'be') { - bytes.reverse(); - } - - return bytes; - } -} diff --git a/src/crypto/public_key/dsa.js b/src/crypto/public_key/dsa.js index 286adb64..b48a4d97 100644 --- a/src/crypto/public_key/dsa.js +++ b/src/crypto/public_key/dsa.js @@ -19,6 +19,7 @@ * @fileoverview A Digital signature algorithm implementation * @module crypto/public_key/dsa */ +import { BigInteger } from '@openpgp/noble-hashes/biginteger'; import { getRandomBigInteger } from '../random'; import util from '../../util'; import { isProbablePrime } from './prime'; @@ -41,12 +42,11 @@ import { isProbablePrime } from './prime'; * @async */ export async function sign(hashAlgo, hashed, g, p, q, x) { - const BigInteger = await util.getBigInteger(); - const one = new BigInteger(1); - p = new BigInteger(p); - q = new BigInteger(q); - g = new BigInteger(g); - x = new BigInteger(x); + const one = BigInteger.new(1); + p = BigInteger.new(p); + q = BigInteger.new(q); + g = BigInteger.new(g); + x = BigInteger.new(x); let k; let r; @@ -59,7 +59,7 @@ export async function sign(hashAlgo, hashed, g, p, q, x) { // of leftmost bits equal to the number of bits of q. This (possibly // truncated) hash function result is treated as a number and used // directly in the DSA signature algorithm. - const h = new BigInteger(hashed.subarray(0, q.byteLength())).mod(q); + const h = BigInteger.new(hashed.subarray(0, q.byteLength())).mod(q); // FIPS-186-4, section 4.6: // The values of r and s shall be checked to determine if r = 0 or s = 0. // If either r = 0 or s = 0, a new value of k shall be generated, and the @@ -100,22 +100,21 @@ export async function sign(hashAlgo, hashed, g, p, q, x) { * @async */ export async function verify(hashAlgo, r, s, hashed, g, p, q, y) { - const BigInteger = await util.getBigInteger(); - const zero = new BigInteger(0); - r = new BigInteger(r); - s = new BigInteger(s); + const zero = BigInteger.new(0); + r = BigInteger.new(r); + s = BigInteger.new(s); - p = new BigInteger(p); - q = new BigInteger(q); - g = new BigInteger(g); - y = new BigInteger(y); + p = BigInteger.new(p); + q = BigInteger.new(q); + g = BigInteger.new(g); + y = BigInteger.new(y); if (r.lte(zero) || r.gte(q) || s.lte(zero) || s.gte(q)) { util.printDebug('invalid DSA Signature'); return false; } - const h = new BigInteger(hashed.subarray(0, q.byteLength())).imod(q); + const h = BigInteger.new(hashed.subarray(0, q.byteLength())).imod(q); const w = s.modInv(q); // s**-1 mod q if (w.isZero()) { util.printDebug('invalid DSA Signature'); @@ -143,12 +142,11 @@ export async function verify(hashAlgo, r, s, hashed, g, p, q, y) { * @async */ export async function validateParams(p, q, g, y, x) { - const BigInteger = await util.getBigInteger(); - p = new BigInteger(p); - q = new BigInteger(q); - g = new BigInteger(g); - y = new BigInteger(y); - const one = new BigInteger(1); + p = BigInteger.new(p); + q = BigInteger.new(q); + g = BigInteger.new(g); + y = BigInteger.new(y); + const one = BigInteger.new(1); // Check that 1 < g < p if (g.lte(one) || g.gte(p)) { return false; @@ -172,8 +170,8 @@ export async function validateParams(p, q, g, y, x) { /** * Check q is large and probably prime (we mainly want to avoid small factors) */ - const qSize = new BigInteger(q.bitLength()); - const n150 = new BigInteger(150); + const qSize = BigInteger.new(q.bitLength()); + const n150 = BigInteger.new(150); if (qSize.lt(n150) || !(await isProbablePrime(q, null, 32))) { return false; } @@ -184,8 +182,8 @@ export async function validateParams(p, q, g, y, x) { * * Blinded exponentiation computes g**{rq + x} to compare to y */ - x = new BigInteger(x); - const two = new BigInteger(2); + x = BigInteger.new(x); + const two = BigInteger.new(2); const r = await getRandomBigInteger(two.leftShift(qSize.dec()), two.leftShift(qSize)); // draw r of same size as q const rqx = q.mul(r).add(x); if (!y.equal(g.modExp(rqx, p))) { diff --git a/src/crypto/public_key/elgamal.js b/src/crypto/public_key/elgamal.js index 2f69e6f0..e9d66865 100644 --- a/src/crypto/public_key/elgamal.js +++ b/src/crypto/public_key/elgamal.js @@ -19,8 +19,7 @@ * @fileoverview ElGamal implementation * @module crypto/public_key/elgamal */ - -import util from '../../util'; +import { BigInteger } from '@openpgp/noble-hashes/biginteger'; import { getRandomBigInteger } from '../random'; import { emeEncode, emeDecode } from '../pkcs1'; @@ -35,17 +34,16 @@ import { emeEncode, emeDecode } from '../pkcs1'; * @async */ export async function encrypt(data, p, g, y) { - const BigInteger = await util.getBigInteger(); - p = new BigInteger(p); - g = new BigInteger(g); - y = new BigInteger(y); + p = BigInteger.new(p); + g = BigInteger.new(g); + y = BigInteger.new(y); const padded = emeEncode(data, p.byteLength()); - const m = new BigInteger(padded); + const m = BigInteger.new(padded); // OpenPGP uses a "special" version of ElGamal where g is generator of the full group Z/pZ* // hence g has order p-1, and to avoid that k = 0 mod p-1, we need to pick k in [1, p-2] - const k = await getRandomBigInteger(new BigInteger(1), p.dec()); + const k = await getRandomBigInteger(BigInteger.new(1), p.dec()); return { c1: g.modExp(k, p).toUint8Array(), c2: y.modExp(k, p).imul(m).imod(p).toUint8Array() @@ -65,11 +63,10 @@ export async function encrypt(data, p, g, y) { * @async */ export async function decrypt(c1, c2, p, x, randomPayload) { - const BigInteger = await util.getBigInteger(); - c1 = new BigInteger(c1); - c2 = new BigInteger(c2); - p = new BigInteger(p); - x = new BigInteger(x); + c1 = BigInteger.new(c1); + c2 = BigInteger.new(c2); + p = BigInteger.new(p); + x = BigInteger.new(x); const padded = c1.modExp(x, p).modInv(p).imul(c2).imod(p); return emeDecode(padded.toUint8Array('be', p.byteLength()), randomPayload); @@ -85,20 +82,19 @@ export async function decrypt(c1, c2, p, x, randomPayload) { * @async */ export async function validateParams(p, g, y, x) { - const BigInteger = await util.getBigInteger(); - p = new BigInteger(p); - g = new BigInteger(g); - y = new BigInteger(y); + p = BigInteger.new(p); + g = BigInteger.new(g); + y = BigInteger.new(y); - const one = new BigInteger(1); + const one = BigInteger.new(1); // Check that 1 < g < p if (g.lte(one) || g.gte(p)) { return false; } // Expect p-1 to be large - const pSize = new BigInteger(p.bitLength()); - const n1023 = new BigInteger(1023); + const pSize = BigInteger.new(p.bitLength()); + const n1023 = BigInteger.new(1023); if (pSize.lt(n1023)) { return false; } @@ -118,8 +114,8 @@ export async function validateParams(p, g, y, x) { * We just check g**i != 1 for all i up to a threshold */ let res = g; - const i = new BigInteger(1); - const threshold = new BigInteger(2).leftShift(new BigInteger(17)); // we want order > threshold + const i = BigInteger.new(1); + const threshold = BigInteger.new(2).leftShift(BigInteger.new(17)); // we want order > threshold while (i.lt(threshold)) { res = res.mul(g).imod(p); if (res.isOne()) { @@ -134,8 +130,8 @@ export async function validateParams(p, g, y, x) { * * Blinded exponentiation computes g**{r(p-1) + x} to compare to y */ - x = new BigInteger(x); - const two = new BigInteger(2); + x = BigInteger.new(x); + const two = BigInteger.new(2); const r = await getRandomBigInteger(two.leftShift(pSize.dec()), two.leftShift(pSize)); // draw r of same size as p-1 const rqx = p.dec().imul(r).iadd(x); if (!y.equal(g.modExp(rqx, p))) { diff --git a/src/crypto/public_key/elliptic/oid_curves.js b/src/crypto/public_key/elliptic/oid_curves.js index dab26436..129ab22c 100644 --- a/src/crypto/public_key/elliptic/oid_curves.js +++ b/src/crypto/public_key/elliptic/oid_curves.js @@ -19,7 +19,7 @@ * @fileoverview Wrapper of an instance of an Elliptic Curve * @module crypto/public_key/elliptic/curve */ - +import { BigInteger } from '@openpgp/noble-hashes/biginteger'; import nacl from '@openpgp/tweetnacl/nacl-fast-light'; import { getRandomBytes } from '../../random'; import enums from '../../../enums'; @@ -205,12 +205,10 @@ class CurveWithOID { } async function generate(curve) { - const BigInteger = await util.getBigInteger(); - curve = new CurveWithOID(curve); const keyPair = await curve.genKeyPair(); - const Q = new BigInteger(keyPair.publicKey).toUint8Array(); - const secret = new BigInteger(keyPair.privateKey).toUint8Array('be', curve.payloadSize); + const Q = BigInteger.new(keyPair.publicKey).toUint8Array(); + const secret = BigInteger.new(keyPair.privateKey).toUint8Array('be', curve.payloadSize); return { oid: curve.oid, Q, diff --git a/src/crypto/public_key/prime.js b/src/crypto/public_key/prime.js index a7b7cba0..8e0bd13d 100644 --- a/src/crypto/public_key/prime.js +++ b/src/crypto/public_key/prime.js @@ -19,8 +19,7 @@ * @fileoverview Algorithms for probabilistic random prime generation * @module crypto/public_key/prime */ - -import util from '../../util'; +import { BigInteger } from '@openpgp/noble-hashes/biginteger'; import { getRandomBigInteger } from '../random'; /** @@ -32,10 +31,9 @@ import { getRandomBigInteger } from '../random'; * @async */ export async function randomProbablePrime(bits, e, k) { - const BigInteger = await util.getBigInteger(); - const one = new BigInteger(1); - const min = one.leftShift(new BigInteger(bits - 1)); - const thirty = new BigInteger(30); + const one = BigInteger.new(1); + const min = one.leftShift(BigInteger.new(bits - 1)); + const thirty = BigInteger.new(30); /* * We can avoid any multiples of 3 and 5 by looking at n mod 30 * n mod 30 = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 @@ -48,7 +46,7 @@ export async function randomProbablePrime(bits, e, k) { let i = n.mod(thirty).toNumber(); do { - n.iadd(new BigInteger(adds[i])); + n.iadd(BigInteger.new(adds[i])); i = (i + adds[i]) % adds.length; // If reached the maximum, go back to the minimum. if (n.bitLength() > bits) { @@ -93,15 +91,13 @@ export async function isProbablePrime(n, e, k) { * @returns {boolean} */ export async function fermat(n, b) { - const BigInteger = await util.getBigInteger(); - b = b || new BigInteger(2); + b = b || BigInteger.new(2); return b.modExp(n.dec(), n).isOne(); } export async function divisionTest(n) { - const BigInteger = await util.getBigInteger(); return smallPrimes.every(m => { - return n.mod(new BigInteger(m)) !== 0; + return n.mod(BigInteger.new(m)) !== 0; }); } @@ -228,7 +224,6 @@ const smallPrimes = [ * @async */ export async function millerRabin(n, k, rand) { - const BigInteger = await util.getBigInteger(); const len = n.bitLength(); if (!k) { @@ -240,10 +235,10 @@ export async function millerRabin(n, k, rand) { // Find d and s, (n - 1) = (2 ^ s) * d; let s = 0; while (!n1.getBit(s)) { s++; } - const d = n.rightShift(new BigInteger(s)); + const d = n.rightShift(BigInteger.new(s)); for (; k > 0; k--) { - const a = rand ? rand() : await getRandomBigInteger(new BigInteger(2), n1); + const a = rand ? rand() : await getRandomBigInteger(BigInteger.new(2), n1); let x = a.modExp(d, n); if (x.isOne() || x.equal(n1)) { diff --git a/src/crypto/public_key/rsa.js b/src/crypto/public_key/rsa.js index 0a17ff06..180a3326 100644 --- a/src/crypto/public_key/rsa.js +++ b/src/crypto/public_key/rsa.js @@ -19,7 +19,7 @@ * @fileoverview RSA implementation * @module crypto/public_key/rsa */ - +import { BigInteger } from '@openpgp/noble-hashes/biginteger'; import { randomProbablePrime } from './prime'; import { getRandomBigInteger } from '../random'; import util from '../../util'; @@ -159,9 +159,7 @@ export async function decrypt(data, n, e, d, p, q, u, randomPayload) { * @async */ export async function generate(bits, e) { - const BigInteger = await util.getBigInteger(); - - e = new BigInteger(e); + e = BigInteger.new(e); // Native RSA keygen using Web Crypto if (util.getWebCrypto()) { @@ -264,25 +262,24 @@ export async function generate(bits, e) { * @async */ export async function validateParams(n, e, d, p, q, u) { - const BigInteger = await util.getBigInteger(); - n = new BigInteger(n); - p = new BigInteger(p); - q = new BigInteger(q); + n = BigInteger.new(n); + p = BigInteger.new(p); + q = BigInteger.new(q); // expect pq = n if (!p.mul(q).equal(n)) { return false; } - const two = new BigInteger(2); + const two = BigInteger.new(2); // expect p*u = 1 mod q - u = new BigInteger(u); + u = BigInteger.new(u); if (!p.mul(u).mod(q).isOne()) { return false; } - e = new BigInteger(e); - d = new BigInteger(d); + e = BigInteger.new(e); + d = BigInteger.new(d); /** * In RSA pkcs#1 the exponents (d, e) are inverses modulo lcm(p-1, q-1) * We check that [de = 1 mod (p-1)] and [de = 1 mod (q-1)] @@ -290,7 +287,7 @@ export async function validateParams(n, e, d, p, q, u) { * * We blind the multiplication with r, and check that rde = r mod lcm(p-1, q-1) */ - const nSizeOver3 = new BigInteger(Math.floor(n.bitLength() / 3)); + const nSizeOver3 = BigInteger.new(Math.floor(n.bitLength() / 3)); const r = await getRandomBigInteger(two, two.leftShift(nSizeOver3)); // r in [ 2, 2^{|n|/3} ) < p and q const rde = r.mul(d).mul(e); @@ -303,10 +300,9 @@ export async function validateParams(n, e, d, p, q, u) { } async function bnSign(hashAlgo, n, d, hashed) { - const BigInteger = await util.getBigInteger(); - n = new BigInteger(n); - const m = new BigInteger(await emsaEncode(hashAlgo, hashed, n.byteLength())); - d = new BigInteger(d); + n = BigInteger.new(n); + const m = BigInteger.new(await emsaEncode(hashAlgo, hashed, n.byteLength())); + d = BigInteger.new(d); if (m.gte(n)) { throw new Error('Message size cannot exceed modulus size'); } @@ -364,10 +360,9 @@ async function nodeSign(hashAlgo, data, n, e, d, p, q, u) { } async function bnVerify(hashAlgo, s, n, e, hashed) { - const BigInteger = await util.getBigInteger(); - n = new BigInteger(n); - s = new BigInteger(s); - e = new BigInteger(e); + n = BigInteger.new(n); + s = BigInteger.new(s); + e = BigInteger.new(e); if (s.gte(n)) { throw new Error('Signature size cannot exceed modulus size'); } @@ -432,10 +427,9 @@ async function nodeEncrypt(data, n, e) { } async function bnEncrypt(data, n, e) { - const BigInteger = await util.getBigInteger(); - n = new BigInteger(n); - data = new BigInteger(emeEncode(data, n.byteLength())); - e = new BigInteger(e); + n = BigInteger.new(n); + data = BigInteger.new(emeEncode(data, n.byteLength())); + e = BigInteger.new(e); if (data.gte(n)) { throw new Error('Message size cannot exceed modulus size'); } @@ -484,21 +478,20 @@ async function nodeDecrypt(data, n, e, d, p, q, u, randomPayload) { } async function bnDecrypt(data, n, e, d, p, q, u, randomPayload) { - const BigInteger = await util.getBigInteger(); - data = new BigInteger(data); - n = new BigInteger(n); - e = new BigInteger(e); - d = new BigInteger(d); - p = new BigInteger(p); - q = new BigInteger(q); - u = new BigInteger(u); + data = BigInteger.new(data); + n = BigInteger.new(n); + e = BigInteger.new(e); + d = BigInteger.new(d); + p = BigInteger.new(p); + q = BigInteger.new(q); + u = BigInteger.new(u); if (data.gte(n)) { throw new Error('Data too large.'); } const dq = d.mod(q.dec()); // d mod (q-1) const dp = d.mod(p.dec()); // d mod (p-1) - const unblinder = (await getRandomBigInteger(new BigInteger(2), n)).mod(n); + const unblinder = (await getRandomBigInteger(BigInteger.new(2), n)).mod(n); const blinder = unblinder.modInv(n).modExp(e, n); data = data.mul(blinder).mod(n); @@ -526,10 +519,9 @@ async function bnDecrypt(data, n, e, d, p, q, u, randomPayload) { * @param {Uint8Array} u */ async function privateToJWK(n, e, d, p, q, u) { - const BigInteger = await util.getBigInteger(); - const pNum = new BigInteger(p); - const qNum = new BigInteger(q); - const dNum = new BigInteger(d); + const pNum = BigInteger.new(p); + const qNum = BigInteger.new(q); + const dNum = BigInteger.new(d); let dq = dNum.mod(qNum.dec()); // d mod (q-1) let dp = dNum.mod(pNum.dec()); // d mod (p-1) diff --git a/src/crypto/random.js b/src/crypto/random.js index ffef7d65..8c7ad418 100644 --- a/src/crypto/random.js +++ b/src/crypto/random.js @@ -21,6 +21,7 @@ * @fileoverview Provides tools for retrieving secure randomness from browsers or Node.js * @module crypto/random */ +import { BigInteger } from '@openpgp/noble-hashes/biginteger'; import util from '../util'; const nodeCrypto = util.getNodeCrypto(); @@ -51,8 +52,6 @@ export function getRandomBytes(length) { * @async */ export async function getRandomBigInteger(min, max) { - const BigInteger = await util.getBigInteger(); - if (max.lt(min)) { throw new Error('Illegal parameter value: max <= min'); } @@ -63,6 +62,6 @@ export async function getRandomBigInteger(min, max) { // Using a while loop is necessary to avoid bias introduced by the mod operation. // However, we request 64 extra random bits so that the bias is negligible. // Section B.1.1 here: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf - const r = new BigInteger(await getRandomBytes(bytes + 8)); + const r = BigInteger.new(await getRandomBytes(bytes + 8)); return r.mod(modulus).add(min); } diff --git a/src/util.js b/src/util.js index 47a02f95..25ba5cd0 100644 --- a/src/util.js +++ b/src/util.js @@ -24,7 +24,6 @@ import * as stream from '@openpgp/web-stream-tools'; import { createRequire } from 'module'; // Must be stripped in browser built -import { getBigInteger } from './biginteger'; import enums from './enums'; const debugMode = (() => { @@ -384,15 +383,6 @@ const util = { return typeof globalThis !== 'undefined' && globalThis.crypto && globalThis.crypto.subtle; }, - /** - * Get BigInteger class - * It wraps the native BigInt type if it's available - * Otherwise it relies on bn.js - * @returns {BigInteger} - * @async - */ - getBigInteger, - /** * Get native Node.js crypto api. * @returns {Object} The crypto module or 'undefined'. diff --git a/test/general/biginteger.js b/test/general/biginteger.js deleted file mode 100644 index 90fd0d38..00000000 --- a/test/general/biginteger.js +++ /dev/null @@ -1,161 +0,0 @@ -import { use as chaiUse, expect } from 'chai'; -import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import -chaiUse(chaiAsPromised); - -import BN from 'bn.js'; -import * as random from '../../src/crypto/random.js'; -import util from '../../src/util.js'; - -let BigInteger; - -async function getRandomBN(min, max) { - if (max.cmp(min) <= 0) { - throw new Error('Illegal parameter value: max <= min'); - } - - const modulus = max.sub(min); - const bytes = modulus.byteLength(); - const r = new BN(random.getRandomBytes(bytes + 8)); - return r.mod(modulus).add(min); -} - -export default () => describe('BigInteger interface', function() { - before(async () => { - BigInteger = await util.getBigInteger(); - }); - - it('constructor throws on undefined input', function() { - expect(() => new BigInteger()).to.throw('Invalid BigInteger input'); - }); - - - it('constructor supports strings', function() { - const input = '417653931840771530406225971293556769925351769207235721650257629558293828796031115397206059067934284452829611906818956352854418342467914729341523414945427019410284762464062112274326172407819051167058569790660930309496043254270888417520676082271432948852231332576271876251597199882908964994070268531832274431027'; - const got = new BigInteger(input); - const expected = new BN(input); - expect(got.toString()).to.equal(expected.toString()); - }); - - it('constructor supports Uint8Arrays', function() { - const expected = new BN('417653931840771530406225971293556769925351769207235721650257629558293828796031115397206059067934284452829611906818956352854418342467914729341523414945427019410284762464062112274326172407819051167058569790660930309496043254270888417520676082271432948852231332576271876251597199882908964994070268531832274431027'); - const input = expected.toArrayLike(Uint8Array); - const got = new BigInteger(input); - expect(got.toString()).to.equal(expected.toString()); - }); - - it('conditional operators are correct', function() { - const a = new BigInteger(12); - const b = new BigInteger(34); - - expect(a.equal(a)).to.be.true; - expect(a.equal(b)).to.be.false; - expect(a.gt(a) === a.lt(a)).to.be.true; - expect(a.gt(b) === a.lt(b)).to.be.false; - expect(a.gte(a) === a.lte(a)).to.be.true; - - const zero = new BigInteger(0); - const one = new BigInteger(1); - expect(zero.isZero()).to.be.true; - expect(one.isZero()).to.be.false; - - expect(one.isOne()).to.be.true; - expect(zero.isOne()).to.be.false; - - expect(zero.isEven()).to.be.true; - expect(one.isEven()).to.be.false; - - expect(zero.isNegative()).to.be.false; - expect(zero.dec().isNegative()).to.be.true; - }); - - it('bitLength is correct', function() { - const n = new BigInteger(127); - let expected = 7; - expect(n.bitLength() === expected).to.be.true; - expect(n.inc().bitLength() === (++expected)).to.be.true; - }); - - it('byteLength is correct', function() { - const n = new BigInteger(65535); - let expected = 2; - expect(n.byteLength() === expected).to.be.true; - expect(n.inc().byteLength() === (++expected)).to.be.true; - }); - - it('toUint8Array is correct', function() { - const nString = '417653931840771530406225971293556769925351769207235721650257629558293828796031115397206059067934284452829611906818956352854418342467914729341523414945427019410284762464062112274326172407819051167058569790660930309496043254270888417520676082271432948852231332576271876251597199882908964994070268531832274431027'; - const n = new BigInteger(nString); - const paddedSize = Number(n.byteLength()) + 1; - // big endian, unpadded - let expected = new BN(nString).toArrayLike(Uint8Array); - expect(n.toUint8Array()).to.deep.equal(expected); - // big endian, padded - expected = new BN(nString).toArrayLike(Uint8Array, 'be', paddedSize); - expect(n.toUint8Array('be', paddedSize)).to.deep.equal(expected); - // little endian, unpadded - expected = new BN(nString).toArrayLike(Uint8Array, 'le'); - expect(n.toUint8Array('le')).to.deep.equal(expected); - //little endian, padded - expected = new BN(nString).toArrayLike(Uint8Array, 'le', paddedSize); - expect(n.toUint8Array('le', paddedSize)).to.deep.equal(expected); - }); - - it('binary operators are consistent', function() { - const a = new BigInteger(12); - const b = new BigInteger(34); - const ops = ['add', 'sub', 'mul', 'mod', 'leftShift', 'rightShift']; - ops.forEach(op => { - const iop = `i${op}`; - expect(a[op](b).equal(a[iop](b))).to.be.true; - }); - }); - - it('unary operators are consistent', function() { - const a = new BigInteger(12); - const one = new BigInteger(1); - expect(a.sub(one).equal(a.dec())).to.be.true; - expect(a.add(one).equal(a.inc())).to.be.true; - }); - - it('modExp is correct (large values)', function() { - const stringX = '417653931840771530406225971293556769925351769207235721650257629558293828796031115397206059067934284452829611906818956352854418342467914729341523414945427019410284762464062112274326172407819051167058569790660930309496043254270888417520676082271432948852231332576271876251597199882908964994070268531832274431027'; - const stringE = '21139356010872569239159922781526379521587348169074209285187910481667533072168468011617194695181255483288792585413365359733692097084373249198758148704369207793873998901870577262254971784191473102265830193058813215898765238784670469696574407580179153118937858890572095234316482449291777882525949871374961971753'; - const stringN = '129189808515414783602892982235788912674846062846614219472827821758734760420002631653235573915244294540972376140705505703576175711417114803419704967903726436285518767606681184247119430411311152556442947708732584954518890222684529678365388350886907287414896703685680210648760841628375425909680236584021041565183'; - const x = new BigInteger(stringX); - const e = new BigInteger(stringE); - const n = new BigInteger(stringN); - - const got = x.modExp(e, n); - const expected = new BN(stringX).toRed(BN.red(new BN(stringN))).redPow(new BN(stringE)); - // different formats, it's easier to compare strings - expect(got.toString() === expected.toString()).to.be.true; - }); - - it('gcd is correct', async function() { - const aBN = await getRandomBN(new BN(2), new BN(200)); - const bBN = await getRandomBN(new BN(2), new BN(200)); - if (aBN.isEven()) aBN.iaddn(1); - const a = new BigInteger(aBN.toString()); - const b = new BigInteger(bBN.toString()); - const expected = aBN.gcd(bBN); - expect(a.gcd(b).toString()).to.equal(expected.toString()); - }); - - it('modular inversion is correct', async function() { - const moduloBN = new BN(229); // this is a prime - const baseBN = await getRandomBN(new BN(2), moduloBN); - const a = new BigInteger(baseBN.toString()); - const n = new BigInteger(moduloBN.toString()); - const expected = baseBN.invm(moduloBN); - expect(a.modInv(n).toString()).to.equal(expected.toString()); - expect(() => a.mul(n).modInv(n)).to.throw('Inverse does not exist'); - }); - - it('getBit is correct', async function() { - const i = 5; - const nBN = await getRandomBN(new BN(2), new BN(200)); - const n = new BigInteger(nBN.toString()); - const expected = nBN.testn(5) ? 1 : 0; - expect(n.getBit(i) === expected).to.be.true; - }); -}); diff --git a/test/general/index.js b/test/general/index.js index 2ddf0794..478a0c5a 100644 --- a/test/general/index.js +++ b/test/general/index.js @@ -1,6 +1,5 @@ import testX25519 from './x25519.js'; import testUtil from './util.js'; -import testBigInteger from './biginteger.js'; import testArmor from './armor.js'; import testPacket from './packet.js'; import testSignature from './signature.js'; @@ -17,7 +16,6 @@ import testStreaming from './streaming.js'; export default () => describe('General', function () { testX25519(); testUtil(); - testBigInteger(); testArmor(); testPacket(); testSignature(); From 538b5b63043f20408aacb2c668bb1fe695ccf740 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Thu, 27 Jul 2023 12:31:02 +0200 Subject: [PATCH 022/201] Set Node 16 as minimum supported version in package.json --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3047d644..f1439c74 100644 --- a/package-lock.json +++ b/package-lock.json @@ -56,7 +56,7 @@ "web-streams-polyfill": "^3.2.0" }, "engines": { - "node": ">= 8.0.0" + "node": ">= 16.0.0" } }, "node_modules/@babel/code-frame": { diff --git a/package.json b/package.json index afae2ddd..d73390ec 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "license": "LGPL-3.0+", "homepage": "https://openpgpjs.org/", "engines": { - "node": ">= 8.0.0" + "node": ">= 16.0.0" }, "keywords": [ "crypto", From 4521de2beac27af94ac5e9c45b5c971dea712c40 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Thu, 27 Jul 2023 12:28:27 +0200 Subject: [PATCH 023/201] HKDF: remove fallback for Node 14 v6 drops support for Node 14, which does not include SubtleCrypto --- src/crypto/hkdf.js | 48 ++++------------------------------------------ 1 file changed, 4 insertions(+), 44 deletions(-) diff --git a/src/crypto/hkdf.js b/src/crypto/hkdf.js index cf531aed..c08720b1 100644 --- a/src/crypto/hkdf.js +++ b/src/crypto/hkdf.js @@ -8,53 +8,13 @@ import util from '../util'; const webCrypto = util.getWebCrypto(); const nodeCrypto = util.getNodeCrypto(); -const nodeSubtleCrypto = nodeCrypto && nodeCrypto.webcrypto && nodeCrypto.webcrypto.subtle; export default async function HKDF(hashAlgo, inputKey, salt, info, outLen) { const hash = enums.read(enums.webHash, hashAlgo); if (!hash) throw new Error('Hash algo not supported with HKDF'); - if (webCrypto || nodeSubtleCrypto) { - const crypto = webCrypto || nodeSubtleCrypto; - const importedKey = await crypto.importKey('raw', inputKey, 'HKDF', false, ['deriveBits']); - const bits = await crypto.deriveBits({ name: 'HKDF', hash, salt, info }, importedKey, outLen * 8); - return new Uint8Array(bits); - } - - if (nodeCrypto) { - const hashAlgoName = enums.read(enums.hash, hashAlgo); - // Node-only HKDF implementation based on https://www.rfc-editor.org/rfc/rfc5869 - - const computeHMAC = (hmacKey, hmacMessage) => nodeCrypto.createHmac(hashAlgoName, hmacKey).update(hmacMessage).digest(); - // Step 1: Extract - // PRK = HMAC-Hash(salt, IKM) - const pseudoRandomKey = computeHMAC(salt, inputKey); - - const hashLen = pseudoRandomKey.length; - - // Step 2: Expand - // HKDF-Expand(PRK, info, L) -> OKM - const n = Math.ceil(outLen / hashLen); - const outputKeyingMaterial = new Uint8Array(n * hashLen); - - // HMAC input buffer updated at each iteration - const roundInput = new Uint8Array(hashLen + info.length + 1); - // T_i and last byte are updated at each iteration, but `info` remains constant - roundInput.set(info, hashLen); - - for (let i = 0; i < n; i++) { - // T(0) = empty string (zero length) - // T(i) = HMAC-Hash(PRK, T(i-1) | info | i) - roundInput[roundInput.length - 1] = i + 1; - // t = T(i+1) - const t = computeHMAC(pseudoRandomKey, i > 0 ? roundInput : roundInput.subarray(hashLen)); - roundInput.set(t, 0); - - outputKeyingMaterial.set(t, i * hashLen); - } - - return outputKeyingMaterial.subarray(0, outLen); - } - - throw new Error('No HKDF implementation available'); + const crypto = webCrypto || nodeCrypto.webcrypto.subtle; + const importedKey = await crypto.importKey('raw', inputKey, 'HKDF', false, ['deriveBits']); + const bits = await crypto.deriveBits({ name: 'HKDF', hash, salt, info }, importedKey, outLen * 8); + return new Uint8Array(bits); } From 31c2a2575d05eb65dc3f4eb0bcd0bf14f1eaae08 Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Wed, 15 Mar 2023 18:39:19 +0100 Subject: [PATCH 024/201] Add support for v6 key packets Compared to v5 keys, v6 keys contain additional length fields to aid in parsing the key, but omit the secret key material length field. Additionally, unencrypted v6 secret key packets don't include the count of the optional fields, as per the updated crypto refresh. Since they are always absent, the count is not needed. Finally, unencrypted v6 secret keys do not include the two-byte checksum. --- src/packet/public_key.js | 19 +++++++++---------- src/packet/secret_key.js | 39 +++++++++++++++++++++++++++++++++------ 2 files changed, 42 insertions(+), 16 deletions(-) diff --git a/src/packet/public_key.js b/src/packet/public_key.js index 15e90857..d9d038f2 100644 --- a/src/packet/public_key.js +++ b/src/packet/public_key.js @@ -106,10 +106,10 @@ class PublicKeyPacket { */ async read(bytes) { let pos = 0; - // A one-octet version number (3, 4 or 5). + // A one-octet version number (4, 5 or 6). this.version = bytes[pos++]; - if (this.version === 4 || this.version === 5) { + if (this.version === 4 || this.version === 5 || this.version === 6) { // - A four-octet number denoting the time that the key was created. this.created = util.readDate(bytes.subarray(pos, pos + 4)); pos += 4; @@ -117,7 +117,7 @@ class PublicKeyPacket { // - A one-octet number denoting the public-key algorithm of this key. this.algorithm = bytes[pos++]; - if (this.version === 5) { + if (this.version >= 5) { // - A four-octet scalar octet count for the following key material. pos += 4; } @@ -147,7 +147,7 @@ class PublicKeyPacket { arr.push(new Uint8Array([this.algorithm])); const params = crypto.serializeParams(this.algorithm, this.publicParams); - if (this.version === 5) { + if (this.version >= 5) { // A four-octet scalar octet count for the following key material arr.push(util.writeNumber(params.length, 4)); } @@ -163,10 +163,9 @@ class PublicKeyPacket { writeForHash(version) { const bytes = this.writePublicKey(); - if (version === 5) { - return util.concatUint8Array([new Uint8Array([0x9A]), util.writeNumber(bytes.length, 4), bytes]); - } - return util.concatUint8Array([new Uint8Array([0x99]), util.writeNumber(bytes.length, 2), bytes]); + const versionOctet = 0x95 + version; + const lengthOctets = version >= 5 ? 4 : 2; + return util.concatUint8Array([new Uint8Array([versionOctet]), util.writeNumber(bytes.length, lengthOctets), bytes]); } /** @@ -201,7 +200,7 @@ class PublicKeyPacket { await this.computeFingerprint(); this.keyID = new KeyID(); - if (this.version === 5) { + if (this.version >= 5) { this.keyID.read(this.fingerprint.subarray(0, 8)); } else if (this.version === 4) { this.keyID.read(this.fingerprint.subarray(12, 20)); @@ -216,7 +215,7 @@ class PublicKeyPacket { async computeFingerprint() { const toHash = this.writeForHash(this.version); - if (this.version === 5) { + if (this.version >= 5) { this.fingerprint = await crypto.hash.sha256(toHash); } else if (this.version === 4) { this.fingerprint = await crypto.hash.sha1(toHash); diff --git a/src/packet/secret_key.js b/src/packet/secret_key.js index cab07335..d3e8616f 100644 --- a/src/packet/secret_key.js +++ b/src/packet/secret_key.js @@ -100,6 +100,14 @@ class SecretKeyPacket extends PublicKeyPacket { i++; } + // - Only for a version 6 packet where the secret key material is + // encrypted (that is, where the previous octet is not zero), a one- + // octet scalar octet count of the cumulative length of all the + // following optional string-to-key parameter fields. + if (this.version === 6 && this.s2kUsage) { + i++; + } + try { // - [Optional] If string-to-key usage octet was 255, 254, or 253, a // one-octet symmetric encryption algorithm. @@ -112,6 +120,12 @@ class SecretKeyPacket extends PublicKeyPacket { this.aead = bytes[i++]; } + // - [Optional] Only for a version 6 packet, and if string-to-key usage + // octet was 255, 254, or 253, an one-octet count of the following field. + if (this.version === 6) { + i++; + } + // - [Optional] If string-to-key usage octet was 255, 254, or 253, a // string-to-key specifier. The length of the string-to-key // specifier is implied by its type, as described above. @@ -157,9 +171,14 @@ class SecretKeyPacket extends PublicKeyPacket { this.isEncrypted = !!this.s2kUsage; if (!this.isEncrypted) { - const cleartext = this.keyMaterial.subarray(0, -2); - if (!util.equalsUint8Array(util.writeChecksum(cleartext), this.keyMaterial.subarray(-2))) { - throw new Error('Key checksum mismatch'); + let cleartext; + if (this.version === 6) { + cleartext = this.keyMaterial; + } else { + cleartext = this.keyMaterial.subarray(0, -2); + if (!util.equalsUint8Array(util.writeChecksum(cleartext), this.keyMaterial.subarray(-2))) { + throw new Error('Key checksum mismatch'); + } } try { const { privateParams } = crypto.parsePrivateKeyParams(this.algorithm, cleartext, this.publicParams); @@ -200,10 +219,18 @@ class SecretKeyPacket extends PublicKeyPacket { optionalFieldsArr.push(this.aead); } + const s2k = this.s2k.write(); + + // - [Optional] Only for a version 6 packet, and if string-to-key usage + // octet was 255, 254, or 253, an one-octet count of the following field. + if (this.version === 6) { + optionalFieldsArr.push(s2k.length); + } + // - [Optional] If string-to-key usage octet was 255, 254, or 253, a // string-to-key specifier. The length of the string-to-key // specifier is implied by its type, as described above. - optionalFieldsArr.push(...this.s2k.write()); + optionalFieldsArr.push(...s2k); } // - [Optional] If secret data is encrypted (string-to-key usage octet @@ -213,7 +240,7 @@ class SecretKeyPacket extends PublicKeyPacket { optionalFieldsArr.push(...this.iv); } - if (this.version === 5) { + if (this.version === 5 || (this.version === 6 && this.s2kUsage)) { arr.push(new Uint8Array([optionalFieldsArr.length])); } arr.push(new Uint8Array(optionalFieldsArr)); @@ -228,7 +255,7 @@ class SecretKeyPacket extends PublicKeyPacket { } arr.push(this.keyMaterial); - if (!this.s2kUsage) { + if (!this.s2kUsage && this.version !== 6) { arr.push(util.writeChecksum(this.keyMaterial)); } } From 8816bd754159f4cfcc2f217a822715d4e76fde26 Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Wed, 15 Mar 2023 19:37:55 +0100 Subject: [PATCH 025/201] Replace config.v5Keys with config.v6Keys flag Also, don't generate v5 keys flag, which has been removed from the draft specification. --- openpgp.d.ts | 2 +- src/config/config.js | 6 ++--- src/key/factory.js | 3 --- src/packet/public_key.js | 2 +- test/general/config.js | 10 +++---- test/general/key.js | 20 +++++++------- test/general/openpgp.js | 10 +++---- test/general/packet.js | 48 +++++++++++++++++++++++++--------- test/typescript/definitions.ts | 2 +- 9 files changed, 61 insertions(+), 42 deletions(-) diff --git a/openpgp.d.ts b/openpgp.d.ts index e674c017..049c0d53 100644 --- a/openpgp.d.ts +++ b/openpgp.d.ts @@ -329,7 +329,7 @@ interface Config { allowInsecureVerificationWithReformattedKeys: boolean; constantTimePKCS1Decryption: boolean; constantTimePKCS1DecryptionSupportedSymmetricAlgorithms: Set; - v5Keys: boolean; + v6Keys: boolean; preferredAEADAlgorithm: enums.aead; aeadChunkSizeByte: number; s2kType: enums.s2k.iterated | enums.s2k.argon2; diff --git a/src/config/config.js b/src/config/config.js index 1e6bd3ef..e7f68435 100644 --- a/src/config/config.js +++ b/src/config/config.js @@ -68,13 +68,13 @@ export default { */ aeadChunkSizeByte: 12, /** - * Use V5 keys. + * Use v6 keys. * Note: not all OpenPGP implementations are compatible with this option. * **FUTURE OPENPGP.JS VERSIONS MAY BREAK COMPATIBILITY WHEN USING THIS OPTION** * @memberof module:config - * @property {Boolean} v5Keys + * @property {Boolean} v6Keys */ - v5Keys: false, + v6Keys: false, /** * S2K (String to Key) type, used for key derivation in the context of secret key encryption * and password-encrypted data. Weaker s2k options are not allowed. diff --git a/src/key/factory.js b/src/key/factory.js index 44d7462f..7a150aaf 100644 --- a/src/key/factory.js +++ b/src/key/factory.js @@ -232,9 +232,6 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, conf if (config.aeadProtect) { signatureProperties.features[0] |= enums.features.aead; } - if (config.v5Keys) { - signatureProperties.features[0] |= enums.features.v5Keys; - } if (options.keyExpirationTime > 0) { signatureProperties.keyExpirationTime = options.keyExpirationTime; signatureProperties.keyNeverExpires = false; diff --git a/src/packet/public_key.js b/src/packet/public_key.js index d9d038f2..af81f3a9 100644 --- a/src/packet/public_key.js +++ b/src/packet/public_key.js @@ -47,7 +47,7 @@ class PublicKeyPacket { * Packet version * @type {Integer} */ - this.version = config.v5Keys ? 5 : 4; + this.version = config.v6Keys ? 6 : 4; /** * Key creation date. * @type {Date} diff --git a/test/general/config.js b/test/general/config.js index 038e72f5..73363792 100644 --- a/test/general/config.js +++ b/test/general/config.js @@ -116,10 +116,10 @@ n9/quqtmyOtYOA6gXNCw0Fal3iANKBmsPmYI }); it('openpgp.generateKey', async function() { - const v5KeysVal = openpgp.config.v5Keys; + const v6KeysVal = openpgp.config.v6Keys; const preferredHashAlgorithmVal = openpgp.config.preferredHashAlgorithm; const showCommentVal = openpgp.config.showComment; - openpgp.config.v5Keys = false; + openpgp.config.v6Keys = false; openpgp.config.preferredHashAlgorithm = openpgp.enums.hash.sha256; openpgp.config.showComment = false; @@ -134,7 +134,7 @@ n9/quqtmyOtYOA6gXNCw0Fal3iANKBmsPmYI expect(key.users[0].selfCertifications[0].preferredHashAlgorithms[0]).to.equal(openpgp.config.preferredHashAlgorithm); const config = { - v5Keys: true, + v6Keys: true, showComment: true, preferredHashAlgorithm: openpgp.enums.hash.sha512 }; @@ -144,11 +144,11 @@ n9/quqtmyOtYOA6gXNCw0Fal3iANKBmsPmYI }; const { privateKey: privateKeyArmored2 } = await openpgp.generateKey(opt2); const key2 = await openpgp.readKey({ armoredKey: privateKeyArmored2 }); - expect(key2.keyPacket.version).to.equal(5); + expect(key2.keyPacket.version).to.equal(6); expect(privateKeyArmored2.indexOf(openpgp.config.commentString) > 0).to.be.true; expect(key2.users[0].selfCertifications[0].preferredHashAlgorithms[0]).to.equal(config.preferredHashAlgorithm); } finally { - openpgp.config.v5Keys = v5KeysVal; + openpgp.config.v6Keys = v6KeysVal; openpgp.config.preferredHashAlgorithm = preferredHashAlgorithmVal; openpgp.config.showComment = showCommentVal; } diff --git a/test/general/key.js b/test/general/key.js index 661f1904..04a99541 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -2258,7 +2258,7 @@ function versionSpecificTests() { expect(key.users[0].selfCertifications[0].preferredCompressionAlgorithms).to.eql([compr.uncompressed, compr.zlib, compr.zip]); let expectedFeatures; - if (openpgp.config.v5Keys) { + if (openpgp.config.v6Keys) { expectedFeatures = [7]; // v5 + aead + mdc } else if (openpgp.config.aeadProtect) { expectedFeatures = [3]; // aead + mdc @@ -2303,7 +2303,7 @@ function versionSpecificTests() { expect(key.users[0].selfCertifications[0].preferredCompressionAlgorithms).to.eql([compr.zip, compr.zlib, compr.uncompressed]); let expectedFeatures; - if (openpgp.config.v5Keys) { + if (openpgp.config.v6Keys) { expectedFeatures = [7]; // v5 + aead + mdc } else if (openpgp.config.aeadProtect) { expectedFeatures = [3]; // aead + mdc @@ -2894,30 +2894,30 @@ function versionSpecificTests() { } export default () => describe('Key', function() { - let v5KeysVal; + let v6KeysVal; let aeadProtectVal; tryTests('V4', versionSpecificTests, { if: !openpgp.config.ci, beforeEach: function() { - v5KeysVal = openpgp.config.v5Keys; - openpgp.config.v5Keys = false; + v6KeysVal = openpgp.config.v6Keys; + openpgp.config.v6Keys = false; }, afterEach: function() { - openpgp.config.v5Keys = v5KeysVal; + openpgp.config.v6Keys = v6KeysVal; } }); - tryTests('V5', versionSpecificTests, { + tryTests('V6', versionSpecificTests, { if: !openpgp.config.ci, beforeEach: function() { - v5KeysVal = openpgp.config.v5Keys; + v6KeysVal = openpgp.config.v6Keys; aeadProtectVal = openpgp.config.aeadProtect; - openpgp.config.v5Keys = true; + openpgp.config.v6Keys = true; openpgp.config.aeadProtect = true; }, afterEach: function() { - openpgp.config.v5Keys = v5KeysVal; + openpgp.config.v6Keys = v6KeysVal; openpgp.config.aeadProtect = aeadProtectVal; } }); diff --git a/test/general/openpgp.js b/test/general/openpgp.js index 06326518..20a8e1ac 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -2231,7 +2231,7 @@ XfA3pqV4mTzF let aeadProtectVal; let preferredAEADAlgorithmVal; let aeadChunkSizeByteVal; - let v5KeysVal; + let v6KeysVal; let minRSABitsVal; beforeEach(async function() { @@ -2248,7 +2248,7 @@ XfA3pqV4mTzF aeadProtectVal = openpgp.config.aeadProtect; preferredAEADAlgorithmVal = openpgp.config.preferredAEADAlgorithm; aeadChunkSizeByteVal = openpgp.config.aeadChunkSizeByte; - v5KeysVal = openpgp.config.v5Keys; + v6KeysVal = openpgp.config.v6Keys; minRSABitsVal = openpgp.config.minRSABits; openpgp.config.minRSABits = 512; @@ -2258,7 +2258,7 @@ XfA3pqV4mTzF openpgp.config.aeadProtect = aeadProtectVal; openpgp.config.preferredAEADAlgorithm = preferredAEADAlgorithmVal; openpgp.config.aeadChunkSizeByte = aeadChunkSizeByteVal; - openpgp.config.v5Keys = v5KeysVal; + openpgp.config.v6Keys = v6KeysVal; openpgp.config.minRSABits = minRSABitsVal; }); @@ -2293,12 +2293,12 @@ XfA3pqV4mTzF } }); - tryTests('GCM mode (V5 keys)', tests, { + tryTests('GCM mode (V6 keys)', tests, { if: true, beforeEach: function() { openpgp.config.aeadProtect = true; openpgp.config.preferredAEADAlgorithm = openpgp.enums.aead.experimentalGCM; - openpgp.config.v5Keys = true; + openpgp.config.v6Keys = true; // Monkey-patch AEAD feature flag publicKey.users[0].selfCertifications[0].features = [7]; diff --git a/test/general/packet.js b/test/general/packet.js index ced7121c..dca36ead 100644 --- a/test/general/packet.js +++ b/test/general/packet.js @@ -854,8 +854,36 @@ V+HOQJQxXJkVRYa3QrFUehiMzTeqqMdgC6ZqJy7+ }); it('Writing of unencrypted v5 secret key packet', async function() { - const originalV5KeysSetting = openpgp.config.v5Keys; - openpgp.config.v5Keys = true; + const packet = new openpgp.SecretKeyPacket(); + packet.version = 5; + packet.privateParams = { key: new Uint8Array([1, 2, 3]) }; + packet.publicParams = { pubKey: new Uint8Array([4, 5, 6]) }; + packet.algorithm = openpgp.enums.publicKey.rsaSign; + packet.isEncrypted = false; + packet.s2kUsage = 0; + + const written = packet.write(); + expect(written.length).to.equal(28); + + /* The serialized length of private data */ + expect(written[17]).to.equal(0); + expect(written[18]).to.equal(0); + expect(written[19]).to.equal(0); + expect(written[20]).to.equal(5); + + /** + * The private data + * + * The 2 bytes missing here are the length prefix of the MPI + */ + expect(written[23]).to.equal(1); + expect(written[24]).to.equal(2); + expect(written[25]).to.equal(3); + }); + + it('Writing of unencrypted v6 secret key packet', async function() { + const originalv6KeysSetting = openpgp.config.v6Keys; + openpgp.config.v6Keys = true; try { const packet = new openpgp.SecretKeyPacket(); @@ -867,24 +895,18 @@ V+HOQJQxXJkVRYa3QrFUehiMzTeqqMdgC6ZqJy7+ packet.s2kUsage = 0; const written = packet.write(); - expect(written.length).to.equal(28); - - /* The serialized length of private data */ - expect(written[17]).to.equal(0); - expect(written[18]).to.equal(0); - expect(written[19]).to.equal(0); - expect(written[20]).to.equal(5); + expect(written.length).to.equal(21); /** * The private data * * The 2 bytes missing here are the length prefix of the MPI */ - expect(written[23]).to.equal(1); - expect(written[24]).to.equal(2); - expect(written[25]).to.equal(3); + expect(written[18]).to.equal(1); + expect(written[19]).to.equal(2); + expect(written[20]).to.equal(3); } finally { - openpgp.config.v5Keys = originalV5KeysSetting; + openpgp.config.v6Keys = originalv6KeysSetting; } }); diff --git a/test/typescript/definitions.ts b/test/typescript/definitions.ts index c3513ef4..94983043 100644 --- a/test/typescript/definitions.ts +++ b/test/typescript/definitions.ts @@ -21,7 +21,7 @@ import { (async () => { // Generate keys - const keyOptions = { userIDs: [{ email: 'user@corp.co' }], config: { v5Keys: true } }; + const keyOptions = { userIDs: [{ email: 'user@corp.co' }], config: { v6Keys: true } }; const { privateKey: privateKeyArmored, publicKey: publicKeyArmored } = await generateKey(keyOptions); const { privateKey: privateKeyBinary } = await generateKey({ ...keyOptions, format: 'binary' }); const { privateKey, publicKey, revocationCertificate } = await generateKey({ ...keyOptions, format: 'object' }); From a5f1ab8a1c9ba5994eac5ea9eddec8ca2876e51c Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Wed, 15 Mar 2023 19:28:52 +0100 Subject: [PATCH 026/201] Add support for v6 signatures Compared to v5 signatures, v6 signatures include a salt, and the subpacket lengths are increased from 2 to 4 bytes. --- src/packet/signature.js | 71 +++++++++++++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 16 deletions(-) diff --git a/src/packet/signature.js b/src/packet/signature.js index 8bd0347a..25188a1d 100644 --- a/src/packet/signature.js +++ b/src/packet/signature.js @@ -60,6 +60,7 @@ class SignaturePacket { this.signatureData = null; this.unhashedSubpackets = []; this.signedHashValue = null; + this.salt = null; this.created = null; this.signatureExpirationTime = null; @@ -110,7 +111,7 @@ class SignaturePacket { let i = 0; this.version = bytes[i++]; - if (this.version !== 4 && this.version !== 5) { + if (this.version !== 4 && this.version !== 5 && this.version !== 6) { throw new UnsupportedError(`Version ${this.version} of the signature packet is unsupported.`); } @@ -139,6 +140,20 @@ class SignaturePacket { this.signedHashValue = bytes.subarray(i, i + 2); i += 2; + // Only for v6 signatures, a variable-length field containing: + if (this.version === 6) { + // A one-octet salt size. The value MUST match the value defined + // for the hash algorithm as specified in Table 23 (Hash algorithm registry). + const saltLength = bytes[i++]; + if (saltLength !== saltLengthForHash(this.hashAlgorithm)) { + throw new Error('Unexpected salt size for the hash algorithm'); + } + + // The salt; a random value value of the specified size. + this.salt = bytes.subarray(i, i + saltLength); + i += saltLength; + } + this.params = crypto.signature.parseSignatureParams(this.publicKeyAlgorithm, bytes.subarray(i, bytes.length)); } @@ -159,6 +174,10 @@ class SignaturePacket { arr.push(this.signatureData); arr.push(this.writeUnhashedSubPackets()); arr.push(this.signedHashValue); + if (this.version === 6) { + arr.push(new Uint8Array([this.salt.length])); + arr.push(this.salt); + } arr.push(this.writeParams()); return util.concat(arr); } @@ -173,18 +192,15 @@ class SignaturePacket { * @async */ async sign(key, data, date = new Date(), detached = false) { - if (key.version === 5) { - this.version = 5; - } else { - this.version = 4; - } - const arr = [new Uint8Array([this.version, this.signatureType, this.publicKeyAlgorithm, this.hashAlgorithm])]; + this.version = key.version; this.created = util.normalizeDate(date); this.issuerKeyVersion = key.version; this.issuerFingerprint = key.getFingerprintBytes(); this.issuerKeyID = key.getKeyID(); + const arr = [new Uint8Array([this.version, this.signatureType, this.publicKeyAlgorithm, this.hashAlgorithm])]; + // Add hashed subpackets arr.push(this.writeHashedSubPackets()); @@ -195,6 +211,10 @@ class SignaturePacket { this.signatureData = util.concat(arr); + if (this.version === 6) { + const saltLength = saltLengthForHash(this.hashAlgorithm); + this.salt = await crypto.random.getRandomBytes(saltLength); + } const toHash = this.toHash(this.signatureType, data, detached); const hash = await this.hash(this.signatureType, data, toHash, detached); @@ -255,7 +275,7 @@ class SignaturePacket { bytes = util.concat([bytes, this.revocationKeyFingerprint]); arr.push(writeSubPacket(sub.revocationKey, false, bytes)); } - if (!this.issuerKeyID.isNull() && this.issuerKeyVersion !== 5) { + if (!this.issuerKeyID.isNull() && this.issuerKeyVersion < 5) { // If the version of [the] key is greater than 4, this subpacket // MUST NOT be included in the signature. arr.push(writeSubPacket(sub.issuer, true, this.issuerKeyID.write())); @@ -320,7 +340,7 @@ class SignaturePacket { if (this.issuerFingerprint !== null) { bytes = [new Uint8Array([this.issuerKeyVersion]), this.issuerFingerprint]; bytes = util.concat(bytes); - arr.push(writeSubPacket(sub.issuerFingerprint, this.version === 5, bytes)); + arr.push(writeSubPacket(sub.issuerFingerprint, this.version >= 5, bytes)); } if (this.preferredAEADAlgorithms !== null) { bytes = util.stringToUint8Array(util.uint8ArrayToString(this.preferredAEADAlgorithms)); @@ -328,7 +348,7 @@ class SignaturePacket { } const result = util.concat(arr); - const length = util.writeNumber(result.length, 2); + const length = util.writeNumber(result.length, this.version === 6 ? 4 : 2); return util.concat([length, result]); } @@ -345,7 +365,7 @@ class SignaturePacket { }); const result = util.concat(arr); - const length = util.writeNumber(result.length, 2); + const length = util.writeNumber(result.length, this.version === 6 ? 4 : 2); return util.concat([length, result]); } @@ -509,7 +529,7 @@ class SignaturePacket { // Issuer Fingerprint this.issuerKeyVersion = bytes[mypos++]; this.issuerFingerprint = bytes.subarray(mypos, bytes.length); - if (this.issuerKeyVersion === 5) { + if (this.issuerKeyVersion >= 5) { this.issuerKeyID.read(this.issuerFingerprint); } else { this.issuerKeyID.read(this.issuerFingerprint.subarray(-8)); @@ -531,10 +551,12 @@ class SignaturePacket { } readSubPackets(bytes, trusted = true, config) { - // Two-octet scalar octet count for following subpacket data. - const subpacketLength = util.readNumber(bytes.subarray(0, 2)); + const subpacketLengthBytes = this.version === 6 ? 4 : 2; - let i = 2; + // Two-octet scalar octet count for following subpacket data. + const subpacketLength = util.readNumber(bytes.subarray(0, subpacketLengthBytes)); + + let i = subpacketLengthBytes; // subpacket data set (zero or more subpackets) while (i < 2 + subpacketLength) { @@ -645,7 +667,7 @@ class SignaturePacket { toHash(signatureType, data, detached = false) { const bytes = this.toSign(signatureType, data); - return util.concat([bytes, this.signatureData, this.calculateTrailer(data, detached)]); + return util.concat([this.salt || new Uint8Array(), bytes, this.signatureData, this.calculateTrailer(data, detached)]); } async hash(signatureType, data, toHash, detached = false) { @@ -769,3 +791,20 @@ function writeSubPacket(type, critical, data) { arr.push(data); return util.concat(arr); } + +/** + * Select the required salt length for the given hash algorithm, as per Table 23 (Hash algorithm registry) of the crypto refresh. + * @see {@link https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh#section-9.5|Crypto Refresh Section 9.5} + * @param {enums.hash} hashAlgorithm - Hash algorithm. + * @returns {Integer} Salt length. + * @private + */ +function saltLengthForHash(hashAlgorithm) { + switch (hashAlgorithm) { + case enums.hash.sha256: return 16; + case enums.hash.sha384: return 24; + case enums.hash.sha512: return 32; + case enums.hash.sha224: return 16; + default: throw new Error('Unsupported hash function for V6 signatures'); + } +} From 71ac6aff2f0813b97c1f26784e95839ca1e9e341 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Thu, 31 Aug 2023 15:24:44 +0200 Subject: [PATCH 027/201] Only parse Issuer Key ID subpacket in v4 signatures This packet must not be included in newer signature versions, but if it is present it can cause internal inconsistencies, so we avoid parsing it. --- src/packet/signature.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/packet/signature.js b/src/packet/signature.js index 25188a1d..07f2a823 100644 --- a/src/packet/signature.js +++ b/src/packet/signature.js @@ -444,7 +444,19 @@ class SignaturePacket { case enums.signatureSubpacket.issuer: // Issuer - this.issuerKeyID.read(bytes.subarray(mypos, bytes.length)); + if (this.version === 4) { + this.issuerKeyID.read(bytes.subarray(mypos, bytes.length)); + } else if (hashed) { + // If the version of the key is greater than 4, this subpacket MUST NOT be included in the signature, + // since the Issuer Fingerprint subpacket is to be used instead. + // The `issuerKeyID` value will be set when reading the issuerFingerprint packet. + // For this reason, if the issuer Key ID packet is present but unhashed, we simply ignore it, + // to avoid situations where `.getSigningKeyIDs()` returns a keyID potentially different from the (signed) + // issuerFingerprint. + // If the packet is hashed, then we reject the signature, to avoid verifying data different from + // what was parsed. + throw new Error('Unexpected Issuer Key ID subpacket'); + } break; case enums.signatureSubpacket.notationData: { From 091be036f40c65f32c347b9448c7bbdfd382a70a Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Thu, 31 Aug 2023 16:00:11 +0200 Subject: [PATCH 028/201] Rename `enums.signatureSubpacket.issuer` to `.issuerKeyID` To reflect the subpacket rename in the crypto-refresh. --- src/enums.js | 2 +- src/packet/signature.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/enums.js b/src/enums.js index 33982062..fd6fb725 100644 --- a/src/enums.js +++ b/src/enums.js @@ -378,7 +378,7 @@ export default { placeholderBackwardsCompatibility: 10, preferredSymmetricAlgorithms: 11, revocationKey: 12, - issuer: 16, + issuerKeyID: 16, notationData: 20, preferredHashAlgorithms: 21, preferredCompressionAlgorithms: 22, diff --git a/src/packet/signature.js b/src/packet/signature.js index 07f2a823..f129dbef 100644 --- a/src/packet/signature.js +++ b/src/packet/signature.js @@ -30,7 +30,7 @@ const verified = Symbol('verified'); // Tampering with those invalidates the signature, so we still trust them and parse them. // All other unhashed subpackets are ignored. const allowedUnhashedSubpackets = new Set([ - enums.signatureSubpacket.issuer, + enums.signatureSubpacket.issuerKeyID, enums.signatureSubpacket.issuerFingerprint, enums.signatureSubpacket.embeddedSignature ]); @@ -278,7 +278,7 @@ class SignaturePacket { if (!this.issuerKeyID.isNull() && this.issuerKeyVersion < 5) { // If the version of [the] key is greater than 4, this subpacket // MUST NOT be included in the signature. - arr.push(writeSubPacket(sub.issuer, true, this.issuerKeyID.write())); + arr.push(writeSubPacket(sub.issuerKeyID, true, this.issuerKeyID.write())); } this.rawNotations.forEach(({ name, value, humanReadable, critical }) => { bytes = [new Uint8Array([humanReadable ? 0x80 : 0, 0, 0, 0])]; @@ -442,7 +442,7 @@ class SignaturePacket { this.revocationKeyFingerprint = bytes.subarray(mypos, mypos + 20); break; - case enums.signatureSubpacket.issuer: + case enums.signatureSubpacket.issuerKeyID: // Issuer if (this.version === 4) { this.issuerKeyID.read(bytes.subarray(mypos, bytes.length)); From 3ea21f6c6ade6047bfc628a257f9f3e36db0d48a Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Wed, 2 Mar 2022 17:16:58 +0100 Subject: [PATCH 029/201] For v6 keys, create direct-key signature for key properties Store key flags, features and preferences in a direct-key signature instead of user ID signatures, for V6 keys. --- src/key/factory.js | 43 +++++++++++++++++++++++++++++------------- test/general/config.js | 2 +- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/src/key/factory.js b/src/key/factory.js index 7a150aaf..8d609415 100644 --- a/src/key/factory.js +++ b/src/key/factory.js @@ -188,18 +188,12 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, conf const packetlist = new PacketList(); packetlist.push(secretKeyPacket); - await Promise.all(options.userIDs.map(async function(userID, index) { - function createPreferredAlgos(algos, preferredAlgo) { - return [preferredAlgo, ...algos.filter(algo => algo !== preferredAlgo)]; - } - - const userIDPacket = UserIDPacket.fromObject(userID); - const dataToSign = {}; - dataToSign.userID = userIDPacket; - dataToSign.key = secretKeyPacket; + function createPreferredAlgos(algos, preferredAlgo) { + return [preferredAlgo, ...algos.filter(algo => algo !== preferredAlgo)]; + } + function getKeySignatureProperties() { const signatureProperties = {}; - signatureProperties.signatureType = enums.signature.certGeneric; signatureProperties.keyFlags = [enums.keyFlags.certifyKeys | enums.keyFlags.signData]; signatureProperties.preferredSymmetricAlgorithms = createPreferredAlgos([ // prefer aes256, aes128, then aes192 (no WebCrypto support: https://www.chromium.org/blink/webcrypto#TOC-AES-support) @@ -223,9 +217,6 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, conf enums.compression.zip, enums.compression.uncompressed ], config.preferredCompressionAlgorithm); - if (index === 0) { - signatureProperties.isPrimaryUserID = true; - } // integrity protection always enabled signatureProperties.features = [0]; signatureProperties.features[0] |= enums.features.modificationDetection; @@ -236,6 +227,32 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, conf signatureProperties.keyExpirationTime = options.keyExpirationTime; signatureProperties.keyNeverExpires = false; } + return signatureProperties; + } + + if (secretKeyPacket.version === 6) { // add direct key signature with key prefs + const dataToSign = { + key: secretKeyPacket + }; + + const signatureProperties = getKeySignatureProperties(); + signatureProperties.signatureType = enums.signature.key; + + const signaturePacket = await helper.createSignaturePacket(dataToSign, null, secretKeyPacket, signatureProperties, options.date, undefined, undefined, undefined, config); + packetlist.push(signaturePacket); + } + + await Promise.all(options.userIDs.map(async function(userID, index) { + const userIDPacket = UserIDPacket.fromObject(userID); + const dataToSign = { + userID: userIDPacket, + key: secretKeyPacket + }; + const signatureProperties = secretKeyPacket.version !== 6 ? getKeySignatureProperties() : {}; + signatureProperties.signatureType = enums.signature.certGeneric; + if (index === 0) { + signatureProperties.isPrimaryUserID = true; + } const signaturePacket = await helper.createSignaturePacket(dataToSign, null, secretKeyPacket, signatureProperties, options.date, undefined, undefined, undefined, config); diff --git a/test/general/config.js b/test/general/config.js index 73363792..e522097a 100644 --- a/test/general/config.js +++ b/test/general/config.js @@ -146,7 +146,7 @@ n9/quqtmyOtYOA6gXNCw0Fal3iANKBmsPmYI const key2 = await openpgp.readKey({ armoredKey: privateKeyArmored2 }); expect(key2.keyPacket.version).to.equal(6); expect(privateKeyArmored2.indexOf(openpgp.config.commentString) > 0).to.be.true; - expect(key2.users[0].selfCertifications[0].preferredHashAlgorithms[0]).to.equal(config.preferredHashAlgorithm); + expect(key2.directSignatures[0].preferredHashAlgorithms[0]).to.equal(config.preferredHashAlgorithm); } finally { openpgp.config.v6Keys = v6KeysVal; openpgp.config.preferredHashAlgorithm = preferredHashAlgorithmVal; From bafdab20cfbad5b744415fdf4db072511c4d4840 Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Wed, 2 Mar 2022 17:17:49 +0100 Subject: [PATCH 030/201] Don't require User IDs for v6 keys --- src/openpgp.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/openpgp.js b/src/openpgp.js index 28554e7b..cef01e9b 100644 --- a/src/openpgp.js +++ b/src/openpgp.js @@ -58,8 +58,8 @@ export async function generateKey({ userIDs = [], passphrase, type = 'ecc', rsaB userIDs = toArray(userIDs); const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`); - if (userIDs.length === 0) { - throw new Error('UserIDs are required for key generation'); + if (userIDs.length === 0 && !config.v6Keys) { + throw new Error('UserIDs are required for V4 keys'); } if (type === 'rsa' && rsaBits < config.minRSABits) { throw new Error(`rsaBits should be at least ${config.minRSABits}, got: ${rsaBits}`); @@ -102,8 +102,8 @@ export async function reformatKey({ privateKey, userIDs = [], passphrase, keyExp userIDs = toArray(userIDs); const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`); - if (userIDs.length === 0) { - throw new Error('UserIDs are required for key reformat'); + if (userIDs.length === 0 && privateKey.keyPacket.version !== 6) { + throw new Error('UserIDs are required for V4 keys'); } const options = { privateKey, userIDs, passphrase, keyExpirationTime, date }; From 5078b8a66dd62048e526d134cbd5bab4dde57795 Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Wed, 2 Mar 2022 17:18:44 +0100 Subject: [PATCH 031/201] Generate SEIPD v2 flag instead of AEAD flag The AEAD Encrypted Data packet has been removed from the draft in favor of version 2 of the Sym. Encrypted Integrity Protected Data packet. It also has a new feature flag to match. --- src/enums.js | 3 ++- src/key/factory.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/enums.js b/src/enums.js index fd6fb725..b120ebb7 100644 --- a/src/enums.js +++ b/src/enums.js @@ -462,7 +462,8 @@ export default { aead: 2, /** 0x04 - Version 5 Public-Key Packet format and corresponding new * fingerprint format */ - v5Keys: 4 + v5Keys: 4, + seipdv2: 8 }, /** diff --git a/src/key/factory.js b/src/key/factory.js index 8d609415..516a3cee 100644 --- a/src/key/factory.js +++ b/src/key/factory.js @@ -221,7 +221,7 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, conf signatureProperties.features = [0]; signatureProperties.features[0] |= enums.features.modificationDetection; if (config.aeadProtect) { - signatureProperties.features[0] |= enums.features.aead; + signatureProperties.features[0] |= enums.features.seipdv2; } if (options.keyExpirationTime > 0) { signatureProperties.keyExpirationTime = options.keyExpirationTime; From b6dc112eb358c70b0afc95b02e190663a3b54f87 Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Wed, 2 Mar 2022 18:17:16 +0100 Subject: [PATCH 032/201] Add (non-experimental) GCM Also, set it as the preferred AEAD algorithm. --- src/config/config.js | 2 +- src/enums.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/config/config.js b/src/config/config.js index e7f68435..4b273c91 100644 --- a/src/config/config.js +++ b/src/config/config.js @@ -58,7 +58,7 @@ export default { * @memberof module:config * @property {Integer} preferredAEADAlgorithm Default AEAD mode {@link module:enums.aead} */ - preferredAEADAlgorithm: enums.aead.eax, + preferredAEADAlgorithm: enums.aead.gcm, /** * Chunk Size Byte for Authenticated Encryption with Additional Data (AEAD) mode * Only has an effect when aeadProtect is set to true. diff --git a/src/enums.js b/src/enums.js index b120ebb7..342373e0 100644 --- a/src/enums.js +++ b/src/enums.js @@ -197,6 +197,7 @@ export default { aead: { eax: 1, ocb: 2, + gcm: 3, experimentalGCM: 100 // Private algorithm }, From 5008f07808d7d67592cdb7cd2359ec9ea639f277 Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Wed, 2 Mar 2022 18:50:40 +0100 Subject: [PATCH 033/201] Add preferred ciphersuites subpacket This subpacket replaces both symmetric algorithm preferences and AEAD algorithm preferences when AEAD is supported, by providing sets of preferred symmetric and AEAD algorithm pairs. We still keep the symmetric algorithm preferences in case AEAD is not supported. --- src/enums.js | 3 ++- src/key/factory.js | 11 +++++++++-- src/packet/signature.js | 12 ++++++++++++ 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/enums.js b/src/enums.js index 342373e0..aa49c972 100644 --- a/src/enums.js +++ b/src/enums.js @@ -394,7 +394,8 @@ export default { signatureTarget: 31, embeddedSignature: 32, issuerFingerprint: 33, - preferredAEADAlgorithms: 34 + preferredAEADAlgorithms: 34, + preferredCipherSuites: 39 }, /** Key flags diff --git a/src/key/factory.js b/src/key/factory.js index 516a3cee..95bcc748 100644 --- a/src/key/factory.js +++ b/src/key/factory.js @@ -195,17 +195,24 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, conf function getKeySignatureProperties() { const signatureProperties = {}; signatureProperties.keyFlags = [enums.keyFlags.certifyKeys | enums.keyFlags.signData]; - signatureProperties.preferredSymmetricAlgorithms = createPreferredAlgos([ + const symmetricAlgorithms = createPreferredAlgos([ // prefer aes256, aes128, then aes192 (no WebCrypto support: https://www.chromium.org/blink/webcrypto#TOC-AES-support) enums.symmetric.aes256, enums.symmetric.aes128, enums.symmetric.aes192 ], config.preferredSymmetricAlgorithm); + signatureProperties.preferredSymmetricAlgorithms = symmetricAlgorithms; if (config.aeadProtect) { - signatureProperties.preferredAEADAlgorithms = createPreferredAlgos([ + const aeadAlgorithms = createPreferredAlgos([ + enums.aead.gcm, enums.aead.eax, enums.aead.ocb ], config.preferredAEADAlgorithm); + signatureProperties.preferredCipherSuites = aeadAlgorithms.flatMap(aeadAlgorithm => { + return symmetricAlgorithms.map(symmetricAlgorithm => { + return [symmetricAlgorithm, aeadAlgorithm]; + }); + }); } signatureProperties.preferredHashAlgorithms = createPreferredAlgos([ // prefer fast asm.js implementations (SHA-256) diff --git a/src/packet/signature.js b/src/packet/signature.js index f129dbef..eb7f8062 100644 --- a/src/packet/signature.js +++ b/src/packet/signature.js @@ -97,6 +97,7 @@ class SignaturePacket { this.issuerKeyVersion = null; this.issuerFingerprint = null; this.preferredAEADAlgorithms = null; + this.preferredCipherSuites = null; this.revoked = null; this[verified] = null; @@ -346,6 +347,10 @@ class SignaturePacket { bytes = util.stringToUint8Array(util.uint8ArrayToString(this.preferredAEADAlgorithms)); arr.push(writeSubPacket(sub.preferredAEADAlgorithms, false, bytes)); } + if (this.preferredCipherSuites !== null) { + bytes = new Uint8Array([].concat(...this.preferredCipherSuites)); + arr.push(writeSubPacket(sub.preferredCipherSuites, false, bytes)); + } const result = util.concat(arr); const length = util.writeNumber(result.length, this.version === 6 ? 4 : 2); @@ -551,6 +556,13 @@ class SignaturePacket { // Preferred AEAD Algorithms this.preferredAEADAlgorithms = [...bytes.subarray(mypos, bytes.length)]; break; + case enums.signatureSubpacket.preferredCipherSuites: + // Preferred AEAD Cipher Suites + this.preferredCipherSuites = []; + for (let i = mypos; i < bytes.length; i += 2) { + this.preferredCipherSuites.push([bytes[i], bytes[i + 1]]); + } + break; default: { const err = new Error(`Unknown signature subpacket type ${type}`); if (critical) { From b077504b3cf6d9ff0d23e83f3d2b839ca1ccdc73 Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Tue, 6 Dec 2022 13:22:09 +0100 Subject: [PATCH 034/201] Remove AES-192 from preferred symmetric algorithms Chrome's Web Crypto implementation doesn't support it, and it seems unnecessary to list it when AES-256 is available. --- src/key/factory.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/key/factory.js b/src/key/factory.js index 95bcc748..b25c9873 100644 --- a/src/key/factory.js +++ b/src/key/factory.js @@ -196,10 +196,9 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, conf const signatureProperties = {}; signatureProperties.keyFlags = [enums.keyFlags.certifyKeys | enums.keyFlags.signData]; const symmetricAlgorithms = createPreferredAlgos([ - // prefer aes256, aes128, then aes192 (no WebCrypto support: https://www.chromium.org/blink/webcrypto#TOC-AES-support) + // prefer aes256, aes128, no aes192 (no Web Crypto support in Chrome: https://www.chromium.org/blink/webcrypto#TOC-AES-support) enums.symmetric.aes256, - enums.symmetric.aes128, - enums.symmetric.aes192 + enums.symmetric.aes128 ], config.preferredSymmetricAlgorithm); signatureProperties.preferredSymmetricAlgorithms = symmetricAlgorithms; if (config.aeadProtect) { From 762775bc03ef8d6fcd1e6fa8f6cc830e586132f5 Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Wed, 30 Nov 2022 17:48:06 +0100 Subject: [PATCH 035/201] Don't generate armor checksum lines --- src/encoding/armor.js | 8 -------- test/general/armor.js | 3 +-- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/encoding/armor.js b/src/encoding/armor.js index 47442c34..6011b94c 100644 --- a/src/encoding/armor.js +++ b/src/encoding/armor.js @@ -369,21 +369,18 @@ export function armor(messageType, body, partIndex, partTotal, customComment, co hash = body.hash; body = body.data; } - const bodyClone = stream.passiveClone(body); const result = []; switch (messageType) { case enums.armor.multipartSection: result.push('-----BEGIN PGP MESSAGE, PART ' + partIndex + '/' + partTotal + '-----\n'); result.push(addheader(customComment, config)); result.push(base64.encode(body)); - result.push('=', getCheckSum(bodyClone)); result.push('-----END PGP MESSAGE, PART ' + partIndex + '/' + partTotal + '-----\n'); break; case enums.armor.multipartLast: result.push('-----BEGIN PGP MESSAGE, PART ' + partIndex + '-----\n'); result.push(addheader(customComment, config)); result.push(base64.encode(body)); - result.push('=', getCheckSum(bodyClone)); result.push('-----END PGP MESSAGE, PART ' + partIndex + '-----\n'); break; case enums.armor.signed: @@ -393,35 +390,30 @@ export function armor(messageType, body, partIndex, partTotal, customComment, co result.push('\n-----BEGIN PGP SIGNATURE-----\n'); result.push(addheader(customComment, config)); result.push(base64.encode(body)); - result.push('=', getCheckSum(bodyClone)); result.push('-----END PGP SIGNATURE-----\n'); break; case enums.armor.message: result.push('-----BEGIN PGP MESSAGE-----\n'); result.push(addheader(customComment, config)); result.push(base64.encode(body)); - result.push('=', getCheckSum(bodyClone)); result.push('-----END PGP MESSAGE-----\n'); break; case enums.armor.publicKey: result.push('-----BEGIN PGP PUBLIC KEY BLOCK-----\n'); result.push(addheader(customComment, config)); result.push(base64.encode(body)); - result.push('=', getCheckSum(bodyClone)); result.push('-----END PGP PUBLIC KEY BLOCK-----\n'); break; case enums.armor.privateKey: result.push('-----BEGIN PGP PRIVATE KEY BLOCK-----\n'); result.push(addheader(customComment, config)); result.push(base64.encode(body)); - result.push('=', getCheckSum(bodyClone)); result.push('-----END PGP PRIVATE KEY BLOCK-----\n'); break; case enums.armor.signature: result.push('-----BEGIN PGP SIGNATURE-----\n'); result.push(addheader(customComment, config)); result.push(base64.encode(body)); - result.push('=', getCheckSum(bodyClone)); result.push('-----END PGP SIGNATURE-----\n'); break; } diff --git a/test/general/armor.js b/test/general/armor.js index 10624ee2..7f7c788b 100644 --- a/test/general/armor.js +++ b/test/general/armor.js @@ -379,7 +379,6 @@ VWx8AtKEInT8YvN19cS2Jpr81jCN819IqgDr+YQezYMwZMzWISmA3w5Z3UCU lO771jlg4fHlWOZ2nJqselFlNc3X/VoZ8swmMkI6KVDV+rKaeyTWe61Up0Jj NJCB6+LWtabSoVIjNVgKwyKqyTLaESNwC2ogZwkdE8qPGiDFEHo4Gg9zuRof -=trqv -----END PGP PUBLIC KEY BLOCK----- `; @@ -390,7 +389,7 @@ NJCB6+LWtabSoVIjNVgKwyKqyTLaESNwC2ogZwkdE8qPGiDFEHo4Gg9zuRof .replace(/^(Version|Comment): .*$\n/mg, '') ).to.equal( pubKey - .replace('\n=', '=') + .replace('\n-', '-') .replace(/\n\r/g, '\n') ); }); From 2419e6b4c5a1111ba06958d2562674fce1eb8c41 Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Tue, 6 Dec 2022 12:43:02 +0100 Subject: [PATCH 036/201] Remove compression algorithms from preferences --- src/key/factory.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/key/factory.js b/src/key/factory.js index b25c9873..6c1d7ee1 100644 --- a/src/key/factory.js +++ b/src/key/factory.js @@ -219,8 +219,6 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, conf enums.hash.sha512 ], config.preferredHashAlgorithm); signatureProperties.preferredCompressionAlgorithms = createPreferredAlgos([ - enums.compression.zlib, - enums.compression.zip, enums.compression.uncompressed ], config.preferredCompressionAlgorithm); // integrity protection always enabled From f21e327e69b893a3da63b3bb1212b43e01fb1400 Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Tue, 6 Dec 2022 14:33:42 +0100 Subject: [PATCH 037/201] Tests: update expected algorithm preferences --- test/general/key.js | 72 +++++++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 29 deletions(-) diff --git a/test/general/key.js b/test/general/key.js index 04a99541..2f266ef9 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -2240,32 +2240,36 @@ VFBLG8uc9IiaKann/DYBAJcZNZHRSfpDoV2pUA5EAEi2MdjxkRysFQnYPRAu function versionSpecificTests() { it('Preferences of generated key', function() { const testPref = function(key) { + const selfSignature = openpgp.config.v6Keys ? key.directSignatures[0] : key.users[0].selfCertifications[0]; // key flags const keyFlags = openpgp.enums.keyFlags; - expect(key.users[0].selfCertifications[0].keyFlags[0] & keyFlags.certifyKeys).to.equal(keyFlags.certifyKeys); - expect(key.users[0].selfCertifications[0].keyFlags[0] & keyFlags.signData).to.equal(keyFlags.signData); + expect(selfSignature.keyFlags[0] & keyFlags.certifyKeys).to.equal(keyFlags.certifyKeys); + expect(selfSignature.keyFlags[0] & keyFlags.signData).to.equal(keyFlags.signData); expect(key.subkeys[0].bindingSignatures[0].keyFlags[0] & keyFlags.encryptCommunication).to.equal(keyFlags.encryptCommunication); expect(key.subkeys[0].bindingSignatures[0].keyFlags[0] & keyFlags.encryptStorage).to.equal(keyFlags.encryptStorage); const sym = openpgp.enums.symmetric; - expect(key.users[0].selfCertifications[0].preferredSymmetricAlgorithms).to.eql([sym.aes256, sym.aes128, sym.aes192]); + expect(selfSignature.preferredSymmetricAlgorithms).to.eql([sym.aes256, sym.aes128]); if (openpgp.config.aeadProtect) { const aead = openpgp.enums.aead; - expect(key.users[0].selfCertifications[0].preferredAEADAlgorithms).to.eql([aead.eax, aead.ocb]); + expect(selfSignature.preferredCipherSuites).to.eql([ + [sym.aes256, aead.gcm], + [sym.aes128, aead.gcm], + [sym.aes256, aead.eax], + [sym.aes128, aead.eax], + [sym.aes256, aead.ocb], + [sym.aes128, aead.ocb] + ]); } const hash = openpgp.enums.hash; - expect(key.users[0].selfCertifications[0].preferredHashAlgorithms).to.eql([hash.sha256, hash.sha512]); + expect(selfSignature.preferredHashAlgorithms).to.eql([hash.sha256, hash.sha512]); const compr = openpgp.enums.compression; - expect(key.users[0].selfCertifications[0].preferredCompressionAlgorithms).to.eql([compr.uncompressed, compr.zlib, compr.zip]); + expect(selfSignature.preferredCompressionAlgorithms).to.eql([compr.uncompressed]); - let expectedFeatures; - if (openpgp.config.v6Keys) { - expectedFeatures = [7]; // v5 + aead + mdc - } else if (openpgp.config.aeadProtect) { - expectedFeatures = [3]; // aead + mdc - } else { - expectedFeatures = [1]; // mdc + let expectedFeatures = 0x01; // SEIPDv1 + if (openpgp.config.aeadProtect) { + expectedFeatures |= 0x08; // SEIPDv2 } - expect(key.users[0].selfCertifications[0].features).to.eql(expectedFeatures); + expect(selfSignature.features).to.eql([expectedFeatures]); }; const opt = { userIDs: { name: 'test', email: 'a@b.com' }, passphrase: 'hello', format: 'object' }; return openpgp.generateKey(opt).then(async function({ privateKey, publicKey }) { @@ -2281,36 +2285,46 @@ function versionSpecificTests() { const preferredAEADAlgorithmVal = openpgp.config.preferredAEADAlgorithm; openpgp.config.preferredSymmetricAlgorithm = openpgp.enums.symmetric.aes192; openpgp.config.preferredHashAlgorithm = openpgp.enums.hash.sha224; - openpgp.config.preferredCompressionAlgorithm = openpgp.enums.compression.zip; + openpgp.config.preferredCompressionAlgorithm = openpgp.enums.compression.zlib; openpgp.config.preferredAEADAlgorithm = openpgp.enums.aead.experimentalGCM; const testPref = function(key) { + const selfSignature = openpgp.config.v6Keys ? key.directSignatures[0] : key.users[0].selfCertifications[0]; // key flags const keyFlags = openpgp.enums.keyFlags; - expect(key.users[0].selfCertifications[0].keyFlags[0] & keyFlags.certifyKeys).to.equal(keyFlags.certifyKeys); - expect(key.users[0].selfCertifications[0].keyFlags[0] & keyFlags.signData).to.equal(keyFlags.signData); + expect(selfSignature.keyFlags[0] & keyFlags.certifyKeys).to.equal(keyFlags.certifyKeys); + expect(selfSignature.keyFlags[0] & keyFlags.signData).to.equal(keyFlags.signData); expect(key.subkeys[0].bindingSignatures[0].keyFlags[0] & keyFlags.encryptCommunication).to.equal(keyFlags.encryptCommunication); expect(key.subkeys[0].bindingSignatures[0].keyFlags[0] & keyFlags.encryptStorage).to.equal(keyFlags.encryptStorage); const sym = openpgp.enums.symmetric; - expect(key.users[0].selfCertifications[0].preferredSymmetricAlgorithms).to.eql([sym.aes192, sym.aes256, sym.aes128]); + expect(selfSignature.preferredSymmetricAlgorithms).to.eql([sym.aes192, sym.aes256, sym.aes128]); if (openpgp.config.aeadProtect) { const aead = openpgp.enums.aead; - expect(key.users[0].selfCertifications[0].preferredAEADAlgorithms).to.eql([aead.experimentalGCM, aead.eax, aead.ocb]); + expect(selfSignature.preferredCipherSuites).to.eql([ + [sym.aes192, aead.experimentalGCM], + [sym.aes256, aead.experimentalGCM], + [sym.aes128, aead.experimentalGCM], + [sym.aes192, aead.gcm], + [sym.aes256, aead.gcm], + [sym.aes128, aead.gcm], + [sym.aes192, aead.eax], + [sym.aes256, aead.eax], + [sym.aes128, aead.eax], + [sym.aes192, aead.ocb], + [sym.aes256, aead.ocb], + [sym.aes128, aead.ocb] + ]); } const hash = openpgp.enums.hash; - expect(key.users[0].selfCertifications[0].preferredHashAlgorithms).to.eql([hash.sha224, hash.sha256, hash.sha512]); + expect(selfSignature.preferredHashAlgorithms).to.eql([hash.sha224, hash.sha256, hash.sha512]); const compr = openpgp.enums.compression; - expect(key.users[0].selfCertifications[0].preferredCompressionAlgorithms).to.eql([compr.zip, compr.zlib, compr.uncompressed]); + expect(selfSignature.preferredCompressionAlgorithms).to.eql([compr.zlib, compr.uncompressed]); - let expectedFeatures; - if (openpgp.config.v6Keys) { - expectedFeatures = [7]; // v5 + aead + mdc - } else if (openpgp.config.aeadProtect) { - expectedFeatures = [3]; // aead + mdc - } else { - expectedFeatures = [1]; // mdc + let expectedFeatures = 0x01; // SEIPDv1 + if (openpgp.config.aeadProtect) { + expectedFeatures |= 0x08; // SEIPDv2 } - expect(key.users[0].selfCertifications[0].features).to.eql(expectedFeatures); + expect(selfSignature.features).to.eql([expectedFeatures]); }; const opt = { userIDs: { name: 'test', email: 'a@b.com' }, passphrase: 'hello', format: 'object' }; try { From 5391bcc1bcf13d187173e42814eb33a28558604b Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Tue, 6 Dec 2022 19:32:27 +0100 Subject: [PATCH 038/201] Update fallback (mandatory) AEAD algorithm to OCB This has been changed in the crypto refresh. --- src/key/helper.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/key/helper.js b/src/key/helper.js index a8bc7cf9..f80b31dd 100644 --- a/src/key/helper.js +++ b/src/key/helper.js @@ -144,9 +144,9 @@ export async function getPreferredHashAlgo(key, keyPacket, date = new Date(), us * @async */ export async function getPreferredAlgo(type, keys = [], date = new Date(), userIDs = [], config = defaultConfig) { - const defaultAlgo = { // these are all must-implement in rfc4880bis + const defaultAlgo = { // these are all must-implement in the crypto refresh 'symmetric': enums.symmetric.aes128, - 'aead': enums.aead.eax, + 'aead': enums.aead.ocb, 'compression': enums.compression.uncompressed }[type]; const preferredSenderAlgo = { From 6f1eb061197554c7cecce5c0b5a112706e0e3c78 Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Tue, 6 Dec 2022 14:33:10 +0100 Subject: [PATCH 039/201] For v6 keys, check direct-key signature for key properties Key flags, expiration time, algorithm preferences, et cetera, are now read from the direct-key signature instead of the primary User ID binding signature for v6 keys. This also requires a direct-key signature to be present for v6 keys. --- src/key/helper.js | 16 ++++++------ src/key/key.js | 55 ++++++++++++++++++++++++++++++------------ src/key/private_key.js | 4 +-- src/message.js | 6 ++--- 4 files changed, 53 insertions(+), 28 deletions(-) diff --git a/src/key/helper.js b/src/key/helper.js index f80b31dd..55fb5ff2 100644 --- a/src/key/helper.js +++ b/src/key/helper.js @@ -116,9 +116,9 @@ export async function getPreferredHashAlgo(key, keyPacket, date = new Date(), us let hashAlgo = config.preferredHashAlgorithm; let prefAlgo = hashAlgo; if (key) { - const primaryUser = await key.getPrimaryUser(date, userID, config); - if (primaryUser.selfCertification.preferredHashAlgorithms) { - [prefAlgo] = primaryUser.selfCertification.preferredHashAlgorithms; + const selfCertification = await key.getPrimarySelfSignature(date, userID, config); + if (selfCertification.preferredHashAlgorithms) { + [prefAlgo] = selfCertification.preferredHashAlgorithms; hashAlgo = crypto.hash.getHashByteLength(hashAlgo) <= crypto.hash.getHashByteLength(prefAlgo) ? prefAlgo : hashAlgo; } @@ -164,8 +164,8 @@ export async function getPreferredAlgo(type, keys = [], date = new Date(), userI // otherwise we use the default algo // if no keys are available, preferredSenderAlgo is returned const senderAlgoSupport = await Promise.all(keys.map(async function(key, i) { - const primaryUser = await key.getPrimaryUser(date, userIDs[i], config); - const recipientPrefs = primaryUser.selfCertification[prefPropertyName]; + const selfCertification = await key.getPrimarySelfSignature(date, userIDs[i], config); + const recipientPrefs = selfCertification[prefPropertyName]; return !!recipientPrefs && recipientPrefs.indexOf(preferredSenderAlgo) >= 0; })); return senderAlgoSupport.every(Boolean) ? preferredSenderAlgo : defaultAlgo; @@ -306,9 +306,9 @@ export async function isAEADSupported(keys, date = new Date(), userIDs = [], con let supported = true; // TODO replace when Promise.some or Promise.any are implemented await Promise.all(keys.map(async function(key, i) { - const primaryUser = await key.getPrimaryUser(date, userIDs[i], config); - if (!primaryUser.selfCertification.features || - !(primaryUser.selfCertification.features[0] & enums.features.aead)) { + const selfCertification = await key.getPrimarySelfSignature(date, userIDs[i], config); + if (!selfCertification.features || + !(selfCertification.features[0] & enums.features.aead)) { supported = false; } })); diff --git a/src/key/key.js b/src/key/key.js index 72286b1c..3b1ed8c2 100644 --- a/src/key/key.js +++ b/src/key/key.js @@ -288,9 +288,9 @@ class Key { } try { - const primaryUser = await this.getPrimaryUser(date, userID, config); + const selfCertification = await this.getPrimarySelfSignature(date, userID, config); if ((!keyID || primaryKey.getKeyID().equals(keyID)) && - helper.isValidSigningKeyPacket(primaryKey, primaryUser.selfCertification, config)) { + helper.isValidSigningKeyPacket(primaryKey, selfCertification, config)) { helper.checkKeyRequirements(primaryKey, config); return this; } @@ -334,9 +334,9 @@ class Key { try { // if no valid subkey for encryption, evaluate primary key - const primaryUser = await this.getPrimaryUser(date, userID, config); + const selfCertification = await this.getPrimarySelfSignature(date, userID, config); if ((!keyID || primaryKey.getKeyID().equals(keyID)) && - helper.isValidEncryptionKeyPacket(primaryKey, primaryUser.selfCertification)) { + helper.isValidEncryptionKeyPacket(primaryKey, selfCertification)) { helper.checkKeyRequirements(primaryKey, config); return this; } @@ -380,18 +380,20 @@ class Key { throw new Error('Primary key is revoked'); } // check for valid, unrevoked, unexpired self signature - const { selfCertification } = await this.getPrimaryUser(date, userID, config); + const selfCertification = await this.getPrimarySelfSignature(date, userID, config); // check for expiration time in binding signatures if (helper.isDataExpired(primaryKey, selfCertification, date)) { throw new Error('Primary key is expired'); } - // check for expiration time in direct signatures - const directSignature = await helper.getLatestValidSignature( - this.directSignatures, primaryKey, enums.signature.key, { key: primaryKey }, date, config - ).catch(() => {}); // invalid signatures are discarded, to avoid breaking the key + if (primaryKey.version !== 6) { + // check for expiration time in direct signatures (for V6 keys, the above already did so) + const directSignature = await helper.getLatestValidSignature( + this.directSignatures, primaryKey, enums.signature.key, { key: primaryKey }, date, config + ).catch(() => {}); // invalid signatures are discarded, to avoid breaking the key - if (directSignature && helper.isDataExpired(primaryKey, directSignature, date)) { - throw new Error('Primary key is expired'); + if (directSignature && helper.isDataExpired(primaryKey, directSignature, date)) { + throw new Error('Primary key is expired'); + } } } @@ -406,12 +408,13 @@ class Key { async getExpirationTime(userID, config = defaultConfig) { let primaryKeyExpiry; try { - const { selfCertification } = await this.getPrimaryUser(null, userID, config); + const selfCertification = await this.getPrimarySelfSignature(null, userID, config); const selfSigKeyExpiry = helper.getKeyExpirationTime(this.keyPacket, selfCertification); const selfSigExpiry = selfCertification.getExpirationTime(); - const directSignature = await helper.getLatestValidSignature( - this.directSignatures, this.keyPacket, enums.signature.key, { key: this.keyPacket }, null, config - ).catch(() => {}); + const directSignature = this.keyPacket.version !== 6 && // For V6 keys, the above already returns the direct-key signature. + await helper.getLatestValidSignature( + this.directSignatures, this.keyPacket, enums.signature.key, { key: this.keyPacket }, null, config + ).catch(() => {}); if (directSignature) { const directSigKeyExpiry = helper.getKeyExpirationTime(this.keyPacket, directSignature); // We do not support the edge case where the direct signature expires, since it would invalidate the corresponding key expiration, @@ -428,6 +431,28 @@ class Key { } + /** + * For V4 keys, returns the self-signature of the primary user. + * For V5 keys, returns the latest valid direct-key self-signature. + * This self-signature is to be used to check the key expiration, + * algorithm preferences, and so on. + * @param {Date} [date] - Use the given date for verification instead of the current time + * @param {Object} [userID] - User ID to get instead of the primary user for V4 keys, if it exists + * @param {Object} [config] - Full configuration, defaults to openpgp.config + * @returns {Promise} The primary self-signature + * @async + */ + async getPrimarySelfSignature(date = new Date(), userID = {}, config = defaultConfig) { + const primaryKey = this.keyPacket; + if (primaryKey.version === 6) { + return helper.getLatestValidSignature( + this.directSignatures, primaryKey, enums.signature.key, { key: primaryKey }, date, config + ); + } + const { selfCertification } = await this.getPrimaryUser(date, userID, config); + return selfCertification; + } + /** * Returns primary user and most significant (latest valid) self signature * - if multiple primary users exist, returns the one with the latest self signature diff --git a/src/key/private_key.js b/src/key/private_key.js index 384a94ec..055de008 100644 --- a/src/key/private_key.js +++ b/src/key/private_key.js @@ -93,9 +93,9 @@ class PrivateKey extends PublicKey { } // evaluate primary key - const primaryUser = await this.getPrimaryUser(date, userID, config); + const selfCertification = await this.getPrimarySelfSignature(date, userID, config); if ((!keyID || primaryKey.getKeyID().equals(keyID, true)) && - helper.isValidDecryptionKeyPacket(primaryUser.selfCertification, config)) { + helper.isValidDecryptionKeyPacket(selfCertification, config)) { keys.push(this); } diff --git a/src/message.js b/src/message.js index 5a88e7b0..611dfbc8 100644 --- a/src/message.js +++ b/src/message.js @@ -204,9 +204,9 @@ export class Message { enums.symmetric.cast5 // Golang OpenPGP fallback ]; try { - const primaryUser = await decryptionKey.getPrimaryUser(date, undefined, config); // TODO: Pass userID from somewhere. - if (primaryUser.selfCertification.preferredSymmetricAlgorithms) { - algos = algos.concat(primaryUser.selfCertification.preferredSymmetricAlgorithms); + const selfCertification = await decryptionKey.getPrimarySelfSignature(date, undefined, config); // TODO: Pass userID from somewhere. + if (selfCertification.preferredSymmetricAlgorithms) { + algos = algos.concat(selfCertification.preferredSymmetricAlgorithms); } } catch (e) {} From 939622e82797dee9f71efd955778f0fdc08d0b5b Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Tue, 13 Dec 2022 15:04:07 +0100 Subject: [PATCH 040/201] Remove armor checksum check The crypto refresh says that we MUST NOT reject messages where the CRC24 checksum is incorrect. So, we remove the check for it. Also, remove the checksumRequired config. --- openpgp.d.ts | 1 - src/config/config.js | 5 --- src/encoding/armor.js | 91 --------------------------------------- test/general/armor.js | 54 ++--------------------- test/general/openpgp.js | 85 ++++++++++++++++-------------------- test/general/streaming.js | 49 +++------------------ 6 files changed, 47 insertions(+), 238 deletions(-) diff --git a/openpgp.d.ts b/openpgp.d.ts index 049c0d53..19a681a1 100644 --- a/openpgp.d.ts +++ b/openpgp.d.ts @@ -317,7 +317,6 @@ interface Config { aeadProtect: boolean; allowUnauthenticatedMessages: boolean; allowUnauthenticatedStream: boolean; - checksumRequired: boolean; minRSABits: number; passwordCollisionCheck: boolean; revocationsExpire: boolean; diff --git a/src/config/config.js b/src/config/config.js index 4b273c91..2b8c35f1 100644 --- a/src/config/config.js +++ b/src/config/config.js @@ -130,11 +130,6 @@ export default { * @property {Boolean} allowUnauthenticatedStream */ allowUnauthenticatedStream: false, - /** - * @memberof module:config - * @property {Boolean} checksumRequired Do not throw error when armor is missing a checksum - */ - checksumRequired: false, /** * Minimum RSA key size allowed for key generation and message signing, verification and encryption. * The default is 2047 since due to a bug, previous versions of OpenPGP.js could generate 2047-bit keys instead of 2048-bit ones. diff --git a/src/encoding/armor.js b/src/encoding/armor.js index 6011b94c..daff2d4d 100644 --- a/src/encoding/armor.js +++ b/src/encoding/armor.js @@ -108,79 +108,6 @@ function addheader(customComment, config) { } -/** - * Calculates a checksum over the given data and returns it base64 encoded - * @param {String | ReadableStream} data - Data to create a CRC-24 checksum for - * @returns {String | ReadableStream} Base64 encoded checksum. - * @private - */ -function getCheckSum(data) { - const crc = createcrc24(data); - return base64.encode(crc); -} - -// https://create.stephan-brumme.com/crc32/#slicing-by-8-overview - -const crc_table = [ - new Array(0xFF), - new Array(0xFF), - new Array(0xFF), - new Array(0xFF) -]; - -for (let i = 0; i <= 0xFF; i++) { - let crc = i << 16; - for (let j = 0; j < 8; j++) { - crc = (crc << 1) ^ ((crc & 0x800000) !== 0 ? 0x864CFB : 0); - } - crc_table[0][i] = - ((crc & 0xFF0000) >> 16) | - (crc & 0x00FF00) | - ((crc & 0x0000FF) << 16); -} -for (let i = 0; i <= 0xFF; i++) { - crc_table[1][i] = (crc_table[0][i] >> 8) ^ crc_table[0][crc_table[0][i] & 0xFF]; -} -for (let i = 0; i <= 0xFF; i++) { - crc_table[2][i] = (crc_table[1][i] >> 8) ^ crc_table[0][crc_table[1][i] & 0xFF]; -} -for (let i = 0; i <= 0xFF; i++) { - crc_table[3][i] = (crc_table[2][i] >> 8) ^ crc_table[0][crc_table[2][i] & 0xFF]; -} - -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView#Endianness -const isLittleEndian = (function() { - const buffer = new ArrayBuffer(2); - new DataView(buffer).setInt16(0, 0xFF, true /* littleEndian */); - // Int16Array uses the platform's endianness. - return new Int16Array(buffer)[0] === 0xFF; -}()); - -/** - * Internal function to calculate a CRC-24 checksum over a given string (data) - * @param {String | ReadableStream} input - Data to create a CRC-24 checksum for - * @returns {Uint8Array | ReadableStream} The CRC-24 checksum. - * @private - */ -function createcrc24(input) { - let crc = 0xCE04B7; - return stream.transform(input, value => { - const len32 = isLittleEndian ? Math.floor(value.length / 4) : 0; - const arr32 = new Uint32Array(value.buffer, value.byteOffset, len32); - for (let i = 0; i < len32; i++) { - crc ^= arr32[i]; - crc = - crc_table[0][(crc >> 24) & 0xFF] ^ - crc_table[1][(crc >> 16) & 0xFF] ^ - crc_table[2][(crc >> 8) & 0xFF] ^ - crc_table[3][(crc >> 0) & 0xFF]; - } - for (let i = len32 * 4; i < value.length; i++) { - crc = (crc >> 8) ^ crc_table[0][(crc & 0xFF) ^ value[i]]; - } - }, () => new Uint8Array([crc, crc >> 8, crc >> 16])); -} - /** * Verify armored headers. crypto-refresh-06, section 6.2: * "An OpenPGP implementation may consider improperly formatted Armor @@ -321,24 +248,6 @@ export function unarmor(input, config = defaultConfig) { await writer.abort(e); } })); - data = stream.transformPair(data, async (readable, writable) => { - const checksumVerified = stream.readToEnd(getCheckSum(stream.passiveClone(readable))); - checksumVerified.catch(() => {}); - await stream.pipe(readable, writable, { - preventClose: true - }); - const writer = stream.getWriter(writable); - try { - const checksumVerifiedString = (await checksumVerified).replace('\n', ''); - if (checksum !== checksumVerifiedString && (checksum || config.checksumRequired)) { - throw new Error('Ascii armor integrity check failed'); - } - await writer.ready; - await writer.close(); - } catch (e) { - await writer.abort(e); - } - }); } catch (e) { reject(e); } diff --git a/test/general/armor.js b/test/general/armor.js index 7f7c788b..2c620d35 100644 --- a/test/general/armor.js +++ b/test/general/armor.js @@ -171,15 +171,7 @@ export default () => describe('ASCII armor', function() { '-----END PGP PRIVATE KEY BLOCK-----' ].join('\n'); - // try with default config - await expect(openpgp.readKey({ armoredKey: privKey })).to.be.rejectedWith(/Ascii armor integrity check failed/); - - // try opposite config - openpgp.config.checksumRequired = !openpgp.config.checksumRequired; - await expect(openpgp.readKey({ armoredKey: privKey })).to.be.rejectedWith(/Ascii armor integrity check failed/); - - // back to default - openpgp.config.checksumRequired = !openpgp.config.checksumRequired; + await openpgp.readKey({ armoredKey: privKey }); }); it('Armor checksum validation - valid', async function () { @@ -203,15 +195,7 @@ export default () => describe('ASCII armor', function() { '=wJNM', '-----END PGP PRIVATE KEY BLOCK-----'].join('\n'); - // try with default config await openpgp.readKey({ armoredKey: privKey }); - - // try opposite config - openpgp.config.checksumRequired = !openpgp.config.checksumRequired; - await openpgp.readKey({ armoredKey: privKey }); - - // back to default - openpgp.config.checksumRequired = !openpgp.config.checksumRequired; }); it('Armor checksum validation - missing', async function () { @@ -234,23 +218,7 @@ export default () => describe('ASCII armor', function() { '71vlXMJNXvoCeuejiRw=', '-----END PGP PRIVATE KEY BLOCK-----'].join('\n'); - // try with default config - if (openpgp.config.checksumRequired) { - await expect(openpgp.readKey({ armoredKey: privKeyNoCheckSum })).to.be.rejectedWith(/Ascii armor integrity check failed/); - } else { - await openpgp.readKey({ armoredKey: privKeyNoCheckSum }); - } - - // try opposite config - openpgp.config.checksumRequired = !openpgp.config.checksumRequired; - if (openpgp.config.checksumRequired) { - await expect(openpgp.readKey({ armoredKey: privKeyNoCheckSum })).to.be.rejectedWith(/Ascii armor integrity check failed/); - } else { - await openpgp.readKey({ armoredKey: privKeyNoCheckSum }); - } - - // back to default - openpgp.config.checksumRequired = !openpgp.config.checksumRequired; + await openpgp.readKey({ armoredKey: privKeyNoCheckSum }); }); it('Armor checksum validation - missing - trailing newline', async function () { @@ -274,23 +242,7 @@ export default () => describe('ASCII armor', function() { '-----END PGP PRIVATE KEY BLOCK-----', ''].join('\n'); - // try with default config - if (openpgp.config.checksumRequired) { - await expect(openpgp.readKey({ armoredKey: privKeyNoCheckSumWithTrailingNewline })).to.be.rejectedWith(/Ascii armor integrity check failed/); - } else { - await openpgp.readKey({ armoredKey: privKeyNoCheckSumWithTrailingNewline }); - } - - // try opposite config - openpgp.config.checksumRequired = !openpgp.config.checksumRequired; - if (openpgp.config.checksumRequired) { - await expect(openpgp.readKey({ armoredKey: privKeyNoCheckSumWithTrailingNewline })).to.be.rejectedWith(/Ascii armor integrity check failed/); - } else { - await openpgp.readKey({ armoredKey: privKeyNoCheckSumWithTrailingNewline }); - } - - // back to default - openpgp.config.checksumRequired = !openpgp.config.checksumRequired; + await openpgp.readKey({ armoredKey: privKeyNoCheckSumWithTrailingNewline }); }); it('Accept header with trailing whitespace', async function () { diff --git a/test/general/openpgp.js b/test/general/openpgp.js index 20a8e1ac..15c5f9d8 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -3057,60 +3057,51 @@ XfA3pqV4mTzF expect(await isAEADSupported([key])).to.equal(openpgp.config.aeadProtect); const data = await openpgp.encrypt({ message: await openpgp.createMessage({ binary: new Uint8Array(500) }), encryptionKeys: [key.toPublic()] }); - let badSumEncrypted = data.replace(/\n=[a-zA-Z0-9/+]{4}/, '\n=aaaa'); - if (badSumEncrypted === data) { // checksum was already =aaaa - badSumEncrypted = data.replace(/\n=[a-zA-Z0-9/+]{4}/, '\n=bbbb'); - } - if (badSumEncrypted === data) { - throw new Error('Was not able to successfully modify checksum'); - } - const badBodyEncrypted = data.replace(/\n=([a-zA-Z0-9/+]{4})/, 'aaa\n=$1'); + const encrypted = data.substr(0, 500) + (data[500] === 'a' ? 'b' : 'a') + data.substr(501); await loadStreamsPolyfill(); try { for (const allowStreaming of [true, false]) { openpgp.config.allowUnauthenticatedStream = allowStreaming; - await Promise.all([badSumEncrypted, badBodyEncrypted].map(async (encrypted, i) => { - await Promise.all([ - encrypted, - new ReadableStream({ - start(controller) { - controller.enqueue(encrypted); + for (const [i, encryptedData] of [ + encrypted, + new ReadableStream({ + start(controller) { + controller.enqueue(encrypted); + controller.close(); + } + }), + new ReadableStream({ + start() { + this.remaining = encrypted.split('\n'); + }, + async pull(controller) { + if (this.remaining.length) { + await new Promise(res => setTimeout(res)); + controller.enqueue(this.remaining.shift() + '\n'); + } else { controller.close(); } - }), - new ReadableStream({ - start() { - this.remaining = encrypted.split('\n'); - }, - async pull(controller) { - if (this.remaining.length) { - await new Promise(res => { setTimeout(res); }); - controller.enqueue(this.remaining.shift() + '\n'); - } else { - controller.close(); - } - } - }) - ].map(async (encrypted, j) => { - let stepReached = 0; - try { - const message = await openpgp.readMessage({ armoredMessage: encrypted }); - stepReached = 1; - const { data: decrypted } = await openpgp.decrypt({ message: message, decryptionKeys: [key] }); - stepReached = 2; - await stream.readToEnd(decrypted); - } catch (e) { - expect(e.message).to.match(/Ascii armor integrity check failed/); - expect(stepReached).to.equal( - j === 0 ? 0 : - (openpgp.config.aeadChunkSizeByte === 0 && (j === 2 || detectNode() || util.getHardwareConcurrency() < 8)) || (!openpgp.config.aeadProtect && openpgp.config.allowUnauthenticatedStream) ? 2 : - 1 - ); - return; } - throw new Error(`Expected "Ascii armor integrity check failed" error in subtest ${i}.${j}`); - })); - })); + }) + ].entries()) { + let stepReached = 0; + try { + const message = await openpgp.readMessage({ armoredMessage: encryptedData }); + stepReached = 1; + const { data: decrypted } = await openpgp.decrypt({ message: message, decryptionKeys: [key] }); + stepReached = 2; + await stream.readToEnd(decrypted); + } catch (e) { + expect(e.message).to.match(/Modification detected|Authentication tag mismatch|Unsupported state or unable to authenticate data/); + expect(stepReached).to.equal( + i === 0 ? 1 : + (openpgp.config.aeadChunkSizeByte === 0 && (i === 2 || detectNode() || util.getHardwareConcurrency() < 8)) || (!openpgp.config.aeadProtect && openpgp.config.allowUnauthenticatedStream) ? 2 : + 1 + ); + continue; + } + throw new Error(`Expected "Modification detected" error in subtest ${i}`); + } } } finally { openpgp.config.allowUnauthenticatedStream = allowUnauthenticatedStream; diff --git a/test/general/streaming.js b/test/general/streaming.js index e60a9f16..3489656a 100644 --- a/test/general/streaming.js +++ b/test/general/streaming.js @@ -403,7 +403,7 @@ function tests() { } }); - it('Detect MDC modifications (allowUnauthenticatedStream=true)', async function() { + it('Detect modification (allowUnauthenticatedStream=true)', async function() { const aeadProtectValue = openpgp.config.aeadProtect; openpgp.config.aeadProtect = false; const allowUnauthenticatedStreamValue = openpgp.config.allowUnauthenticatedStream; @@ -418,7 +418,6 @@ function tests() { const message = await openpgp.readMessage({ armoredMessage: stream[expectedType === 'node' ? 'webToNode' : 'toStream'](stream.transform(encrypted, value => { value += ''; - if (value === '=' || value.length === 5) return; // Remove checksum const newlineIndex = value.indexOf('\n', 500); if (value.length > 1000) return value.slice(0, newlineIndex - 1) + (value[newlineIndex - 1] === 'a' ? 'b' : 'a') + value.slice(newlineIndex); return value; @@ -441,44 +440,7 @@ function tests() { } }); - it('Detect armor checksum error (allowUnauthenticatedStream=true)', async function() { - const allowUnauthenticatedStreamValue = openpgp.config.allowUnauthenticatedStream; - openpgp.config.allowUnauthenticatedStream = true; - try { - const encrypted = await openpgp.encrypt({ - message: await openpgp.createMessage({ binary: data }), - encryptionKeys: pubKey, - signingKeys: privKey, - config: { minRSABits: 1024 } - }); - expect(stream.isStream(encrypted)).to.equal(expectedType); - - const message = await openpgp.readMessage({ - armoredMessage: stream[expectedType === 'node' ? 'webToNode' : 'toStream'](stream.transform(encrypted, value => { - value += ''; - const newlineIndex = value.indexOf('\n', 500); - if (value.length > 1000) return value.slice(0, newlineIndex - 1) + (value[newlineIndex - 1] === 'a' ? 'b' : 'a') + value.slice(newlineIndex); - return value; - }), { encoding: 'utf8' }) - }); - const decrypted = await openpgp.decrypt({ - verificationKeys: pubKey, - decryptionKeys: privKey, - message, - format: 'binary' - }); - expect(stream.isStream(decrypted.data)).to.equal(expectedType); - const reader = stream.getReader(decrypted.data); - expect(await reader.peekBytes(1024)).not.to.deep.equal(plaintext[0]); - dataArrived(); - await expect(reader.readToEnd()).to.be.rejectedWith('Ascii armor integrity check failed'); - expect(decrypted.signatures).to.exist.and.have.length(1); - } finally { - openpgp.config.allowUnauthenticatedStream = allowUnauthenticatedStreamValue; - } - }); - - it('Detect armor checksum error when not passing public keys (allowUnauthenticatedStream=true)', async function() { + it('Detect modification when not passing public keys (allowUnauthenticatedStream=true)', async function() { const allowUnauthenticatedStreamValue = openpgp.config.allowUnauthenticatedStream; openpgp.config.allowUnauthenticatedStream = true; try { @@ -507,7 +469,7 @@ function tests() { const reader = stream.getReader(decrypted.data); expect(await reader.peekBytes(1024)).not.to.deep.equal(plaintext[0]); dataArrived(); - await expect(reader.readToEnd()).to.be.rejectedWith('Ascii armor integrity check failed'); + await expect(reader.readToEnd()).to.be.rejectedWith('Modification detected.'); expect(decrypted.signatures).to.exist.and.have.length(1); await expect(decrypted.signatures[0].verified).to.be.eventually.rejectedWith(/Could not find signing key/); } finally { @@ -515,7 +477,7 @@ function tests() { } }); - it('Sign/verify: Detect armor checksum error', async function() { + it('Sign/verify: Detect modification', async function() { const signed = await openpgp.sign({ message: await openpgp.createMessage({ binary: data }), signingKeys: privKey, @@ -541,8 +503,9 @@ function tests() { const reader = stream.getReader(verified.data); expect(await reader.peekBytes(1024)).not.to.deep.equal(plaintext[0]); dataArrived(); - await expect(reader.readToEnd()).to.be.rejectedWith('Ascii armor integrity check failed'); expect(verified.signatures).to.exist.and.have.length(1); + await reader.readToEnd(); + await expect(verified.signatures[0].verified).to.be.rejectedWith('Signed digest did not match'); }); it('stream.transformPair()', async function() { From 9d85938ed716bf11acba8ad94ecbc9e339b6f0ec Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Tue, 13 Dec 2022 17:30:29 +0100 Subject: [PATCH 041/201] Implement SEIPD v2 --- src/crypto/hkdf.js | 2 +- src/key/helper.js | 2 +- src/message.js | 7 +- src/packet/aead_encrypted_data.js | 84 +------ .../sym_encrypted_integrity_protected_data.js | 222 +++++++++++++++--- test/benchmarks/memory_usage.js | 21 +- test/general/config.js | 4 +- test/general/openpgp.js | 38 +-- test/general/packet.js | 8 +- 9 files changed, 238 insertions(+), 150 deletions(-) diff --git a/src/crypto/hkdf.js b/src/crypto/hkdf.js index c08720b1..91ff9a2e 100644 --- a/src/crypto/hkdf.js +++ b/src/crypto/hkdf.js @@ -9,7 +9,7 @@ import util from '../util'; const webCrypto = util.getWebCrypto(); const nodeCrypto = util.getNodeCrypto(); -export default async function HKDF(hashAlgo, inputKey, salt, info, outLen) { +export default async function computeHKDF(hashAlgo, inputKey, salt, info, outLen) { const hash = enums.read(enums.webHash, hashAlgo); if (!hash) throw new Error('Hash algo not supported with HKDF'); diff --git a/src/key/helper.js b/src/key/helper.js index 55fb5ff2..766f41c9 100644 --- a/src/key/helper.js +++ b/src/key/helper.js @@ -308,7 +308,7 @@ export async function isAEADSupported(keys, date = new Date(), userIDs = [], con await Promise.all(keys.map(async function(key, i) { const selfCertification = await key.getPrimarySelfSignature(date, userIDs[i], config); if (!selfCertification.features || - !(selfCertification.features[0] & enums.features.aead)) { + !(selfCertification.features[0] & enums.features.seipdv2)) { supported = false; } })); diff --git a/src/message.js b/src/message.js index 611dfbc8..a17f523c 100644 --- a/src/message.js +++ b/src/message.js @@ -392,13 +392,12 @@ export class Message { const msg = await Message.encryptSessionKey(sessionKeyData, algorithmName, aeadAlgorithmName, encryptionKeys, passwords, wildcard, encryptionKeyIDs, date, userIDs, config); - let symEncryptedPacket; + const symEncryptedPacket = new SymEncryptedIntegrityProtectedDataPacket(); if (aeadAlgorithmName) { - symEncryptedPacket = new AEADEncryptedDataPacket(); + symEncryptedPacket.version = 2; symEncryptedPacket.aeadAlgorithm = enums.write(enums.aead, aeadAlgorithmName); - } else { - symEncryptedPacket = new SymEncryptedIntegrityProtectedDataPacket(); } + symEncryptedPacket.packets = this.packets; const algorithm = enums.write(enums.symmetric, algorithmName); diff --git a/src/packet/aead_encrypted_data.js b/src/packet/aead_encrypted_data.js index 5f42a8fb..60bdc3a7 100644 --- a/src/packet/aead_encrypted_data.js +++ b/src/packet/aead_encrypted_data.js @@ -21,6 +21,7 @@ import enums from '../enums'; import util from '../util'; import defaultConfig from '../config'; import { UnsupportedError } from './packet'; +import { runAEAD } from './sym_encrypted_integrity_protected_data'; import LiteralDataPacket from './literal_data'; import CompressedDataPacket from './compressed_data'; @@ -101,7 +102,7 @@ class AEADEncryptedDataPacket { */ async decrypt(sessionKeyAlgorithm, key, config = defaultConfig) { this.packets = await PacketList.fromBinary( - await this.crypt('decrypt', key, stream.clone(this.encrypted)), + await runAEAD(this, 'decrypt', key, stream.clone(this.encrypted)), allowedPackets, config ); @@ -122,86 +123,7 @@ class AEADEncryptedDataPacket { this.iv = crypto.random.getRandomBytes(ivLength); // generate new random IV this.chunkSizeByte = config.aeadChunkSizeByte; const data = this.packets.write(); - this.encrypted = await this.crypt('encrypt', key, data); - } - - /** - * En/decrypt the payload. - * @param {encrypt|decrypt} fn - Whether to encrypt or decrypt - * @param {Uint8Array} key - The session key used to en/decrypt the payload - * @param {Uint8Array | ReadableStream} data - The data to en/decrypt - * @returns {Promise>} - * @async - */ - async crypt(fn, key, data) { - const mode = crypto.getAEADMode(this.aeadAlgorithm); - const modeInstance = await mode(this.cipherAlgorithm, key); - const tagLengthIfDecrypting = fn === 'decrypt' ? mode.tagLength : 0; - const tagLengthIfEncrypting = fn === 'encrypt' ? mode.tagLength : 0; - const chunkSize = 2 ** (this.chunkSizeByte + 6) + tagLengthIfDecrypting; // ((uint64_t)1 << (c + 6)) - const adataBuffer = new ArrayBuffer(21); - const adataArray = new Uint8Array(adataBuffer, 0, 13); - const adataTagArray = new Uint8Array(adataBuffer); - const adataView = new DataView(adataBuffer); - const chunkIndexArray = new Uint8Array(adataBuffer, 5, 8); - adataArray.set([0xC0 | AEADEncryptedDataPacket.tag, this.version, this.cipherAlgorithm, this.aeadAlgorithm, this.chunkSizeByte], 0); - let chunkIndex = 0; - let latestPromise = Promise.resolve(); - let cryptedBytes = 0; - let queuedBytes = 0; - const iv = this.iv; - return stream.transformPair(data, async (readable, writable) => { - if (util.isStream(readable) !== 'array') { - const buffer = new TransformStream({}, { - highWaterMark: util.getHardwareConcurrency() * 2 ** (this.chunkSizeByte + 6), - size: array => array.length - }); - stream.pipe(buffer.readable, writable); - writable = buffer.writable; - } - const reader = stream.getReader(readable); - const writer = stream.getWriter(writable); - try { - while (true) { - let chunk = await reader.readBytes(chunkSize + tagLengthIfDecrypting) || new Uint8Array(); - const finalChunk = chunk.subarray(chunk.length - tagLengthIfDecrypting); - chunk = chunk.subarray(0, chunk.length - tagLengthIfDecrypting); - let cryptedPromise; - let done; - if (!chunkIndex || chunk.length) { - reader.unshift(finalChunk); - cryptedPromise = modeInstance[fn](chunk, mode.getNonce(iv, chunkIndexArray), adataArray); - queuedBytes += chunk.length - tagLengthIfDecrypting + tagLengthIfEncrypting; - } else { - // After the last chunk, we either encrypt a final, empty - // data chunk to get the final authentication tag or - // validate that final authentication tag. - adataView.setInt32(13 + 4, cryptedBytes); // Should be setInt64(13, ...) - cryptedPromise = modeInstance[fn](finalChunk, mode.getNonce(iv, chunkIndexArray), adataTagArray); - queuedBytes += tagLengthIfEncrypting; - done = true; - } - cryptedBytes += chunk.length - tagLengthIfDecrypting; - // eslint-disable-next-line no-loop-func - latestPromise = latestPromise.then(() => cryptedPromise).then(async crypted => { - await writer.ready; - await writer.write(crypted); - queuedBytes -= crypted.length; - }).catch(err => writer.abort(err)); - if (done || queuedBytes > writer.desiredSize) { - await latestPromise; // Respect backpressure - } - if (!done) { - adataView.setInt32(5 + 4, ++chunkIndex); // Should be setInt64(5, ...) - } else { - await writer.close(); - break; - } - } - } catch (e) { - await writer.abort(e); - } - }); + this.encrypted = await runAEAD(this, 'encrypt', key, data); } } diff --git a/src/packet/sym_encrypted_integrity_protected_data.js b/src/packet/sym_encrypted_integrity_protected_data.js index d1099a9f..3f462c90 100644 --- a/src/packet/sym_encrypted_integrity_protected_data.js +++ b/src/packet/sym_encrypted_integrity_protected_data.js @@ -17,6 +17,7 @@ import * as stream from '@openpgp/web-stream-tools'; import crypto from '../crypto'; +import computeHKDF from '../crypto/hkdf'; import enums from '../enums'; import util from '../util'; import defaultConfig from '../config'; @@ -36,8 +37,6 @@ const allowedPackets = /*#__PURE__*/ util.constructAllowedPackets([ SignaturePacket ]); -const VERSION = 1; // A one-octet version number of the data packet. - /** * Implementation of the Sym. Encrypted Integrity Protected Data Packet (Tag 18) * @@ -54,28 +53,55 @@ class SymEncryptedIntegrityProtectedDataPacket { } constructor() { - this.version = VERSION; + this.version = 1; + + // The following 4 fields are for V2 only. + /** @type {enums.symmetric} */ + this.cipherAlgorithm = null; + /** @type {enums.aead} */ + this.aeadAlgorithm = null; + this.chunkSizeByte = null; + this.salt = null; + this.encrypted = null; this.packets = null; } async read(bytes) { await stream.parse(bytes, async reader => { - const version = await reader.readByte(); - // - A one-octet version number. The only currently defined value is 1. - if (version !== VERSION) { + this.version = await reader.readByte(); + // - A one-octet version number with value 1 or 2. + if (this.version !== 1 && this.version !== 2) { throw new UnsupportedError(`Version ${version} of the SEIP packet is unsupported.`); } + if (this.version === 2) { + // - A one-octet cipher algorithm. + this.cipherAlgorithm = await reader.readByte(); + // - A one-octet AEAD algorithm. + this.aeadAlgorithm = await reader.readByte(); + // - A one-octet chunk size. + this.chunkSizeByte = await reader.readByte(); + // - Thirty-two octets of salt. The salt is used to derive the message key and must be unique. + this.salt = await reader.readBytes(32); + } + + // For V1: // - Encrypted data, the output of the selected symmetric-key cipher // operating in Cipher Feedback mode with shift amount equal to the // block size of the cipher (CFB-n where n is the block size). + // For V2: + // - Encrypted data, the output of the selected symmetric-key cipher operating in the given AEAD mode. + // - A final, summary authentication tag for the AEAD mode. this.encrypted = reader.remainder(); }); } write() { - return util.concat([new Uint8Array([VERSION]), this.encrypted]); + if (this.version === 2) { + return util.concat([new Uint8Array([this.version, this.cipherAlgorithm, this.aeadAlgorithm, this.chunkSizeByte]), this.salt, this.encrypted]); + } + return util.concat([new Uint8Array([this.version]), this.encrypted]); } /** @@ -88,18 +114,27 @@ class SymEncryptedIntegrityProtectedDataPacket { * @async */ async encrypt(sessionKeyAlgorithm, key, config = defaultConfig) { - const { blockSize } = crypto.getCipher(sessionKeyAlgorithm); - let bytes = this.packets.write(); if (stream.isArrayStream(bytes)) bytes = await stream.readToEnd(bytes); - const prefix = await crypto.getPrefixRandom(sessionKeyAlgorithm); - const mdc = new Uint8Array([0xD3, 0x14]); // modification detection code packet - const tohash = util.concat([prefix, bytes, mdc]); - const hash = await crypto.hash.sha1(stream.passiveClone(tohash)); - const plaintext = util.concat([tohash, hash]); + if (this.version === 2) { + this.cipherAlgorithm = sessionKeyAlgorithm; - this.encrypted = await crypto.mode.cfb.encrypt(sessionKeyAlgorithm, key, plaintext, new Uint8Array(blockSize), config); + this.salt = crypto.random.getRandomBytes(32); + this.chunkSizeByte = config.aeadChunkSizeByte; + this.encrypted = await runAEAD(this, 'encrypt', key, bytes); + } else { + const { blockSize } = crypto.getCipher(sessionKeyAlgorithm); + + const prefix = await crypto.getPrefixRandom(sessionKeyAlgorithm); + const mdc = new Uint8Array([0xD3, 0x14]); // modification detection code packet + + const tohash = util.concat([prefix, bytes, mdc]); + const hash = await crypto.hash.sha1(stream.passiveClone(tohash)); + const plaintext = util.concat([tohash, hash]); + + this.encrypted = await crypto.mode.cfb.encrypt(sessionKeyAlgorithm, key, plaintext, new Uint8Array(blockSize), config); + } return true; } @@ -113,33 +148,152 @@ class SymEncryptedIntegrityProtectedDataPacket { * @async */ async decrypt(sessionKeyAlgorithm, key, config = defaultConfig) { - const { blockSize } = crypto.getCipher(sessionKeyAlgorithm); let encrypted = stream.clone(this.encrypted); if (stream.isArrayStream(encrypted)) encrypted = await stream.readToEnd(encrypted); - const decrypted = await crypto.mode.cfb.decrypt(sessionKeyAlgorithm, key, encrypted, new Uint8Array(blockSize)); - // there must be a modification detection code packet as the - // last packet and everything gets hashed except the hash itself - const realHash = stream.slice(stream.passiveClone(decrypted), -20); - const tohash = stream.slice(decrypted, 0, -20); - const verifyHash = Promise.all([ - stream.readToEnd(await crypto.hash.sha1(stream.passiveClone(tohash))), - stream.readToEnd(realHash) - ]).then(([hash, mdc]) => { - if (!util.equalsUint8Array(hash, mdc)) { - throw new Error('Modification detected.'); + let packetbytes; + if (this.version === 2) { + packetbytes = await runAEAD(this, 'decrypt', key, encrypted); + } else { + const { blockSize } = crypto.getCipher(sessionKeyAlgorithm); + const decrypted = await crypto.mode.cfb.decrypt(sessionKeyAlgorithm, key, encrypted, new Uint8Array(blockSize)); + + // there must be a modification detection code packet as the + // last packet and everything gets hashed except the hash itself + const realHash = stream.slice(stream.passiveClone(decrypted), -20); + const tohash = stream.slice(decrypted, 0, -20); + const verifyHash = Promise.all([ + stream.readToEnd(await crypto.hash.sha1(stream.passiveClone(tohash))), + stream.readToEnd(realHash) + ]).then(([hash, mdc]) => { + if (!util.equalsUint8Array(hash, mdc)) { + throw new Error('Modification detected.'); + } + return new Uint8Array(); + }); + const bytes = stream.slice(tohash, blockSize + 2); // Remove random prefix + packetbytes = stream.slice(bytes, 0, -2); // Remove MDC packet + packetbytes = stream.concat([packetbytes, stream.fromAsync(() => verifyHash)]); + if (!util.isStream(encrypted) || !config.allowUnauthenticatedStream) { + packetbytes = await stream.readToEnd(packetbytes); } - return new Uint8Array(); - }); - const bytes = stream.slice(tohash, blockSize + 2); // Remove random prefix - let packetbytes = stream.slice(bytes, 0, -2); // Remove MDC packet - packetbytes = stream.concat([packetbytes, stream.fromAsync(() => verifyHash)]); - if (!util.isStream(encrypted) || !config.allowUnauthenticatedStream) { - packetbytes = await stream.readToEnd(packetbytes); } + this.packets = await PacketList.fromBinary(packetbytes, allowedPackets, config); return true; } } export default SymEncryptedIntegrityProtectedDataPacket; + +/** + * En/decrypt the payload. + * @param {encrypt|decrypt} fn - Whether to encrypt or decrypt + * @param {Uint8Array} key - The session key used to en/decrypt the payload + * @param {Uint8Array | ReadableStream} data - The data to en/decrypt + * @returns {Promise>} + * @async + */ +export async function runAEAD(packet, fn, key, data) { + const isSEIPDv2 = packet instanceof SymEncryptedIntegrityProtectedDataPacket && packet.version === 2; + const isAEADP = !isSEIPDv2 && packet.constructor.tag === enums.packet.aeadEncryptedData; // no `instanceof` to avoid importing the corresponding class (circular import) + if (!isSEIPDv2 && !isAEADP) throw new Error('Unexpected packet type'); + + const mode = crypto.getAEADMode(packet.aeadAlgorithm); + const tagLengthIfDecrypting = fn === 'decrypt' ? mode.tagLength : 0; + const tagLengthIfEncrypting = fn === 'encrypt' ? mode.tagLength : 0; + const chunkSize = 2 ** (packet.chunkSizeByte + 6) + tagLengthIfDecrypting; // ((uint64_t)1 << (c + 6)) + const chunkIndexSizeIfAEADEP = isAEADP ? 8 : 0; + const adataBuffer = new ArrayBuffer(13 + chunkIndexSizeIfAEADEP); + const adataArray = new Uint8Array(adataBuffer, 0, 5 + chunkIndexSizeIfAEADEP); + const adataTagArray = new Uint8Array(adataBuffer); + const adataView = new DataView(adataBuffer); + const chunkIndexArray = new Uint8Array(adataBuffer, 5, 8); + adataArray.set([0xC0 | packet.constructor.tag, packet.version, packet.cipherAlgorithm, packet.aeadAlgorithm, packet.chunkSizeByte], 0); + let chunkIndex = 0; + let latestPromise = Promise.resolve(); + let cryptedBytes = 0; + let queuedBytes = 0; + let iv; + let ivView; + if (isSEIPDv2) { + const { keySize } = crypto.getCipher(packet.cipherAlgorithm); + const { ivLength } = mode; + const info = new Uint8Array(adataBuffer, 0, 5); + const derived = await computeHKDF(enums.hash.sha256, key, packet.salt, info, keySize + ivLength); + key = derived.subarray(0, keySize); + iv = derived.subarray(keySize); // The last 8 bytes of HKDF output are unneeded, but this avoids one copy. + iv.fill(0, iv.length - 8); + ivView = new DataView(iv.buffer, iv.byteOffset, iv.byteLength); + } else { // AEADEncryptedDataPacket + iv = packet.iv; + // ivView is unused in this case + } + const modeInstance = await mode(packet.cipherAlgorithm, key); + return stream.transformPair(data, async (readable, writable) => { + if (util.isStream(readable) !== 'array') { + const buffer = new TransformStream({}, { + highWaterMark: util.getHardwareConcurrency() * 2 ** (packet.chunkSizeByte + 6), + size: array => array.length + }); + stream.pipe(buffer.readable, writable); + writable = buffer.writable; + } + const reader = stream.getReader(readable); + const writer = stream.getWriter(writable); + try { + while (true) { + let chunk = await reader.readBytes(chunkSize + tagLengthIfDecrypting) || new Uint8Array(); + const finalChunk = chunk.subarray(chunk.length - tagLengthIfDecrypting); + chunk = chunk.subarray(0, chunk.length - tagLengthIfDecrypting); + let cryptedPromise; + let done; + let nonce; + if (isSEIPDv2) { // SEIPD V2 + nonce = iv; + } else { // AEADEncryptedDataPacket + nonce = iv.slice(); + for (let i = 0; i < 8; i++) { + nonce[iv.length - 8 + i] ^= chunkIndexArray[i]; + } + } + if (!chunkIndex || chunk.length) { + reader.unshift(finalChunk); + cryptedPromise = modeInstance[fn](chunk, nonce, adataArray); + queuedBytes += chunk.length - tagLengthIfDecrypting + tagLengthIfEncrypting; + } else { + // After the last chunk, we either encrypt a final, empty + // data chunk to get the final authentication tag or + // validate that final authentication tag. + adataView.setInt32(5 + chunkIndexSizeIfAEADEP + 4, cryptedBytes); // Should be setInt64(5 + chunkIndexSizeIfAEADEP, ...) + cryptedPromise = modeInstance[fn](finalChunk, nonce, adataTagArray); + queuedBytes += tagLengthIfEncrypting; + done = true; + } + cryptedBytes += chunk.length - tagLengthIfDecrypting; + // eslint-disable-next-line no-loop-func + latestPromise = latestPromise.then(() => cryptedPromise).then(async crypted => { + await writer.ready; + await writer.write(crypted); + queuedBytes -= crypted.length; + }).catch(err => writer.abort(err)); + if (done || queuedBytes > writer.desiredSize) { + await latestPromise; // Respect backpressure + } + if (!done) { + if (isSEIPDv2) { // SEIPD V2 + ivView.setInt32(iv.length - 4, ++chunkIndex); // Should be setInt64(iv.length - 8, ...) + } else { // AEADEncryptedDataPacket + adataView.setInt32(5 + 4, ++chunkIndex); // Should be setInt64(5, ...) + } + } else { + await writer.close(); + break; + } + } + } catch (e) { + await writer.ready.catch(() => {}); + await writer.abort(e); + } + }); +} diff --git a/test/benchmarks/memory_usage.js b/test/benchmarks/memory_usage.js index e50873e4..323ae475 100644 --- a/test/benchmarks/memory_usage.js +++ b/test/benchmarks/memory_usage.js @@ -119,6 +119,7 @@ class MemoryBenchamrkSuite { const armoredEncryptedMessage = await openpgp.encrypt({ message: plaintextMessage, passwords, config }); const encryptedMessage = await openpgp.readMessage({ armoredMessage: armoredEncryptedMessage }); assert.ok(encryptedMessage.packets[1] instanceof openpgp.SymEncryptedIntegrityProtectedDataPacket); + assert.ok(encryptedMessage.packets[1].version === 1); await openpgp.decrypt({ message: encryptedMessage, passwords, config }); }); @@ -131,6 +132,7 @@ class MemoryBenchamrkSuite { const armoredEncryptedMessage = await openpgp.encrypt({ message: plaintextMessage, passwords, config }); const encryptedMessage = await openpgp.readMessage({ armoredMessage: armoredEncryptedMessage }); assert.ok(encryptedMessage.packets[1] instanceof openpgp.SymEncryptedIntegrityProtectedDataPacket); + assert.ok(encryptedMessage.packets[1].version === 1); await openpgp.decrypt({ message: encryptedMessage, passwords, config }); }); @@ -142,7 +144,8 @@ class MemoryBenchamrkSuite { const armoredEncryptedMessage = await openpgp.encrypt({ message: plaintextMessage, passwords, config }); const encryptedMessage = await openpgp.readMessage({ armoredMessage: armoredEncryptedMessage }); - assert.ok(encryptedMessage.packets[1] instanceof openpgp.AEADEncryptedDataPacket); + assert.ok(encryptedMessage.packets[1] instanceof openpgp.SymEncryptedIntegrityProtectedDataPacket); + assert.ok(encryptedMessage.packets[1].version === 2); await openpgp.decrypt({ message: encryptedMessage, passwords, config }); }); @@ -154,7 +157,8 @@ class MemoryBenchamrkSuite { const armoredEncryptedMessage = await openpgp.encrypt({ message: plaintextMessage, passwords, config }); const encryptedMessage = await openpgp.readMessage({ armoredMessage: armoredEncryptedMessage }); - assert.ok(encryptedMessage.packets[1] instanceof openpgp.AEADEncryptedDataPacket); + assert.ok(encryptedMessage.packets[1] instanceof openpgp.SymEncryptedIntegrityProtectedDataPacket); + assert.ok(encryptedMessage.packets[1].version === 2); await openpgp.decrypt({ message: encryptedMessage, passwords, config }); }); @@ -176,6 +180,7 @@ class MemoryBenchamrkSuite { const armoredEncryptedMessage = await openpgp.encrypt({ message: plaintextMessage, passwords, config }); const encryptedMessage = await openpgp.readMessage({ armoredMessage: armoredEncryptedMessage }); assert.ok(encryptedMessage.packets[1] instanceof openpgp.SymEncryptedIntegrityProtectedDataPacket); + assert.ok(encryptedMessage.packets[1].version === 1); const { data: decryptedData } = await openpgp.decrypt({ message: encryptedMessage, passwords, config }); // read out output stream to trigger decryption await new Promise(resolve => { @@ -201,6 +206,7 @@ class MemoryBenchamrkSuite { const armoredEncryptedMessage = await openpgp.encrypt({ message: plaintextMessage, passwords, config }); const encryptedMessage = await openpgp.readMessage({ armoredMessage: armoredEncryptedMessage }); assert.ok(encryptedMessage.packets[1] instanceof openpgp.SymEncryptedIntegrityProtectedDataPacket); + assert.ok(encryptedMessage.packets[1].version === 1); const { data: decryptedData } = await openpgp.decrypt({ message: encryptedMessage, passwords, config }); // read out output stream to trigger decryption await new Promise(resolve => { @@ -225,7 +231,8 @@ class MemoryBenchamrkSuite { const armoredEncryptedMessage = await openpgp.encrypt({ message: plaintextMessage, passwords, config }); const encryptedMessage = await openpgp.readMessage({ armoredMessage: armoredEncryptedMessage }); - assert.ok(encryptedMessage.packets[1] instanceof openpgp.AEADEncryptedDataPacket); + assert.ok(encryptedMessage.packets[1] instanceof openpgp.SymEncryptedIntegrityProtectedDataPacket); + assert.ok(encryptedMessage.packets[1].version === 2); const { data: decryptedData } = await openpgp.decrypt({ message: encryptedMessage, passwords, config }); // read out output stream to trigger decryption await new Promise(resolve => { @@ -250,7 +257,8 @@ class MemoryBenchamrkSuite { const armoredEncryptedMessage = await openpgp.encrypt({ message: plaintextMessage, passwords, config }); const encryptedMessage = await openpgp.readMessage({ armoredMessage: armoredEncryptedMessage }); - assert.ok(encryptedMessage.packets[1] instanceof openpgp.AEADEncryptedDataPacket); + assert.ok(encryptedMessage.packets[1] instanceof openpgp.SymEncryptedIntegrityProtectedDataPacket); + assert.ok(encryptedMessage.packets[1].version === 2); const { data: decryptedData } = await openpgp.decrypt({ message: encryptedMessage, passwords, config }); // read out output stream to trigger decryption await new Promise(resolve => { @@ -276,6 +284,7 @@ class MemoryBenchamrkSuite { const armoredEncryptedMessage = await openpgp.encrypt({ message: plaintextMessage, passwords, config }); const encryptedMessage = await openpgp.readMessage({ armoredMessage: armoredEncryptedMessage }); assert.ok(encryptedMessage.packets[1] instanceof openpgp.SymEncryptedIntegrityProtectedDataPacket); + assert.ok(encryptedMessage.packets[1].version === 1); const { data: decryptedData } = await openpgp.decrypt({ message: encryptedMessage, passwords, config }); // read out output stream to trigger decryption await new Promise(resolve => { @@ -301,6 +310,7 @@ class MemoryBenchamrkSuite { const armoredEncryptedMessage = await openpgp.encrypt({ message: plaintextMessage, passwords, config }); const encryptedMessage = await openpgp.readMessage({ armoredMessage: armoredEncryptedMessage }); assert.ok(encryptedMessage.packets[1] instanceof openpgp.SymEncryptedIntegrityProtectedDataPacket); + assert.ok(encryptedMessage.packets[1].version === 1); const { data: decryptedData } = await openpgp.decrypt({ message: encryptedMessage, passwords, @@ -329,7 +339,8 @@ class MemoryBenchamrkSuite { const armoredEncryptedMessage = await openpgp.encrypt({ message: plaintextMessage, passwords, config }); const encryptedMessage = await openpgp.readMessage({ armoredMessage: armoredEncryptedMessage }); - assert.ok(encryptedMessage.packets[1] instanceof openpgp.AEADEncryptedDataPacket); + assert.ok(encryptedMessage.packets[1] instanceof openpgp.SymEncryptedIntegrityProtectedDataPacket); + assert.ok(encryptedMessage.packets[1].version === 2); const { data: decryptedData } = await openpgp.decrypt({ message: encryptedMessage, passwords, config }); // read out output stream to trigger decryption await new Promise(resolve => { diff --git a/test/general/config.js b/test/general/config.js index e522097a..0d5393d1 100644 --- a/test/general/config.js +++ b/test/general/config.js @@ -272,6 +272,7 @@ n9/quqtmyOtYOA6gXNCw0Fal3iANKBmsPmYI const { packets: [skesk, encData] } = encrypted; expect(skesk.version).to.equal(4); // cfb expect(encData.constructor.tag).to.equal(openpgp.enums.packet.symEncryptedIntegrityProtectedData); + expect(encData.version).to.equal(1); const { packets: [literal] } = await encrypted.decrypt(null, passwords, null, encrypted.fromStream, openpgp.config); expect(literal.constructor.tag).to.equal(openpgp.enums.packet.literalData); @@ -284,7 +285,8 @@ n9/quqtmyOtYOA6gXNCw0Fal3iANKBmsPmYI const encrypted2 = await openpgp.readMessage({ armoredMessage: armored2 }); const { packets: [skesk2, encData2] } = encrypted2; expect(skesk2.version).to.equal(5); - expect(encData2.constructor.tag).to.equal(openpgp.enums.packet.aeadEncryptedData); + expect(encData2.constructor.tag).to.equal(openpgp.enums.packet.symEncryptedIntegrityProtectedData); + expect(encData2.version).to.equal(2); const { packets: [compressed] } = await encrypted2.decrypt(null, passwords, null, encrypted2.fromStream, openpgp.config); expect(compressed.constructor.tag).to.equal(openpgp.enums.packet.compressedData); expect(compressed.algorithm).to.equal(openpgp.enums.compression.zip); diff --git a/test/general/openpgp.js b/test/general/openpgp.js index 15c5f9d8..c0f19df8 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -2300,10 +2300,10 @@ XfA3pqV4mTzF openpgp.config.preferredAEADAlgorithm = openpgp.enums.aead.experimentalGCM; openpgp.config.v6Keys = true; - // Monkey-patch AEAD feature flag - publicKey.users[0].selfCertifications[0].features = [7]; - publicKey_2000_2008.users[0].selfCertifications[0].features = [7]; - publicKey_2038_2045.users[0].selfCertifications[0].features = [7]; + // Monkey-patch SEIPD V2 feature flag + publicKey.users[0].selfCertifications[0].features = [9]; + publicKey_2000_2008.users[0].selfCertifications[0].features = [9]; + publicKey_2038_2045.users[0].selfCertifications[0].features = [9]; } }); @@ -2313,10 +2313,10 @@ XfA3pqV4mTzF openpgp.config.aeadProtect = true; openpgp.config.aeadChunkSizeByte = 0; - // Monkey-patch AEAD feature flag - publicKey.users[0].selfCertifications[0].features = [7]; - publicKey_2000_2008.users[0].selfCertifications[0].features = [7]; - publicKey_2038_2045.users[0].selfCertifications[0].features = [7]; + // Monkey-patch SEIPD V2 feature flag + publicKey.users[0].selfCertifications[0].features = [9]; + publicKey_2000_2008.users[0].selfCertifications[0].features = [9]; + publicKey_2038_2045.users[0].selfCertifications[0].features = [9]; } }); @@ -2326,10 +2326,10 @@ XfA3pqV4mTzF openpgp.config.aeadProtect = true; openpgp.config.preferredAEADAlgorithm = openpgp.enums.aead.ocb; - // Monkey-patch AEAD feature flag - publicKey.users[0].selfCertifications[0].features = [7]; - publicKey_2000_2008.users[0].selfCertifications[0].features = [7]; - publicKey_2038_2045.users[0].selfCertifications[0].features = [7]; + // Monkey-patch SEIPD V2 feature flag + publicKey.users[0].selfCertifications[0].features = [9]; + publicKey_2000_2008.users[0].selfCertifications[0].features = [9]; + publicKey_2038_2045.users[0].selfCertifications[0].features = [9]; } }); @@ -2626,7 +2626,7 @@ XfA3pqV4mTzF return openpgp.encrypt(encOpt).then(async function (encrypted) { expect(encrypted).to.match(/^-----BEGIN PGP MESSAGE/); decOpt.message = await openpgp.readMessage({ armoredMessage: encrypted }); - expect(!!decOpt.message.packets.findPacket(openpgp.enums.packet.aeadEncryptedData)).to.equal(false); + expect(decOpt.message.packets.findPacket(openpgp.enums.packet.symEncryptedIntegrityProtectedData).version === 2).to.equal(false); return openpgp.decrypt(decOpt); }).then(function (decrypted) { expect(decrypted.data).to.equal(plaintext); @@ -2649,7 +2649,7 @@ XfA3pqV4mTzF return openpgp.encrypt(encOpt).then(async function (encrypted) { expect(encrypted).to.match(/^-----BEGIN PGP MESSAGE/); decOpt.message = await openpgp.readMessage({ armoredMessage: encrypted }); - expect(!!decOpt.message.packets.findPacket(openpgp.enums.packet.aeadEncryptedData)).to.equal(false); + expect(decOpt.message.packets.findPacket(openpgp.enums.packet.symEncryptedIntegrityProtectedData).version === 2).to.equal(false); return openpgp.decrypt(decOpt); }).then(function (decrypted) { expect(decrypted.data).to.equal(plaintext); @@ -2668,7 +2668,7 @@ XfA3pqV4mTzF }; return openpgp.encrypt(encOpt).then(async function (encrypted) { decOpt.message = await openpgp.readMessage({ armoredMessage: encrypted }); - expect(!!decOpt.message.packets.findPacket(openpgp.enums.packet.aeadEncryptedData)).to.equal(openpgp.config.aeadProtect); + expect(decOpt.message.packets.findPacket(openpgp.enums.packet.symEncryptedIntegrityProtectedData).version === 2).to.equal(openpgp.config.aeadProtect); return openpgp.decrypt(decOpt); }).then(async function (decrypted) { expect(decrypted.data).to.equal(plaintext); @@ -2692,7 +2692,7 @@ XfA3pqV4mTzF }; return openpgp.encrypt(encOpt).then(async function (encrypted) { decOpt.message = await openpgp.readMessage({ armoredMessage: encrypted }); - expect(!!decOpt.message.packets.findPacket(openpgp.enums.packet.aeadEncryptedData)).to.equal(openpgp.config.aeadProtect); + expect(decOpt.message.packets.findPacket(openpgp.enums.packet.symEncryptedIntegrityProtectedData).version === 2).to.equal(openpgp.config.aeadProtect); return openpgp.decrypt(decOpt); }).then(async function (decrypted) { expect(decrypted.data).to.equal(plaintext); @@ -2715,7 +2715,7 @@ XfA3pqV4mTzF }; return openpgp.encrypt(encOpt).then(async function (encrypted) { decOpt.message = await openpgp.readMessage({ armoredMessage: encrypted }); - expect(!!decOpt.message.packets.findPacket(openpgp.enums.packet.aeadEncryptedData)).to.equal(false); + expect(decOpt.message.packets.findPacket(openpgp.enums.packet.symEncryptedIntegrityProtectedData).version === 2).to.equal(false); return openpgp.decrypt(decOpt); }).then(async function (decrypted) { expect(decrypted.data).to.equal(plaintext); @@ -2746,7 +2746,7 @@ XfA3pqV4mTzF }; return openpgp.encrypt(encOpt).then(async function (encrypted) { decOpt.message = await openpgp.readMessage({ armoredMessage: encrypted }); - expect(!!decOpt.message.packets.findPacket(openpgp.enums.packet.aeadEncryptedData)).to.equal(openpgp.config.aeadProtect); + expect(decOpt.message.packets.findPacket(openpgp.enums.packet.symEncryptedIntegrityProtectedData).version === 2).to.equal(openpgp.config.aeadProtect); return openpgp.decrypt(decOpt); }).then(async function (decrypted) { expect(decrypted.data).to.equal(plaintext); @@ -2775,7 +2775,7 @@ XfA3pqV4mTzF detached: true }); const message = await openpgp.readMessage({ armoredMessage: encrypted }); - expect(!!message.packets.findPacket(openpgp.enums.packet.aeadEncryptedData)).to.equal(openpgp.config.aeadProtect); + expect(message.packets.findPacket(openpgp.enums.packet.symEncryptedIntegrityProtectedData).version === 2).to.equal(openpgp.config.aeadProtect); const decrypted = await openpgp.decrypt({ message, signature: await openpgp.readSignature({ armoredSignature: signed }), diff --git a/test/general/packet.js b/test/general/packet.js index dca36ead..8d77cdfe 100644 --- a/test/general/packet.js +++ b/test/general/packet.js @@ -152,7 +152,7 @@ export default () => describe('Packet', function() { expect(await stringify(msg2[0].packets[0].data)).to.equal(stringify(literal.data)); }); - it('Sym. encrypted AEAD protected packet', function() { + it('Sym. encrypted AEAD protected packet (AEADP)', function() { const aeadProtectVal = openpgp.config.aeadProtect; openpgp.config.aeadProtect = false; @@ -201,7 +201,7 @@ export default () => describe('Packet', function() { return cryptStub; } - it('Sym. encrypted AEAD protected packet is encrypted in parallel (AEAD, GCM)', async function() { + it('Sym. encrypted AEAD protected packet is encrypted in parallel (AEADP, GCM)', async function() { const webCrypto = util.getWebCrypto(); if (!webCrypto || util.getNodeCrypto()) return; const encryptStub = cryptStub(webCrypto, 'encrypt'); @@ -236,7 +236,7 @@ export default () => describe('Packet', function() { } }); - it('Sym. encrypted AEAD protected packet test vector (AEAD)', async function() { + it('AEAD Encrypted Data packet test vector (AEADP)', async function() { // From https://gitlab.com/openpgp-wg/rfc4880bis/commit/00b20923e6233fb6ff1666ecd5acfefceb32907d const nodeCrypto = util.getNodeCrypto(); @@ -516,7 +516,7 @@ export default () => describe('Packet', function() { } }); - it('Sym. encrypted session key reading/writing test vector (EAX, AEAD)', async function() { + it('Sym. encrypted session key reading/writing test vector (AEAD, EAX)', async function() { // From https://gitlab.com/openpgp-wg/rfc4880bis/blob/00b20923/back.mkd#sample-aead-eax-encryption-and-decryption const nodeCrypto = util.getNodeCrypto(); From 6ae87b92082a978e6a08a69ba278f2250d33b120 Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Wed, 14 Dec 2022 13:30:53 +0100 Subject: [PATCH 042/201] Implement Padding Packet --- src/enums.js | 3 +- src/packet/all_packets.js | 1 + src/packet/packetlist.js | 3 +- src/packet/padding.js | 63 +++++++++++++++ test/general/packet.js | 162 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 230 insertions(+), 2 deletions(-) create mode 100644 src/packet/padding.js diff --git a/src/enums.js b/src/enums.js index aa49c972..8b98ad17 100644 --- a/src/enums.js +++ b/src/enums.js @@ -223,7 +223,8 @@ export default { userAttribute: 17, symEncryptedIntegrityProtectedData: 18, modificationDetectionCode: 19, - aeadEncryptedData: 20 // see IETF draft: https://tools.ietf.org/html/draft-ford-openpgp-format-00#section-2.1 + aeadEncryptedData: 20, // see IETF draft: https://tools.ietf.org/html/draft-ford-openpgp-format-00#section-2.1 + padding: 21 }, /** Data types in the literal packet diff --git a/src/packet/all_packets.js b/src/packet/all_packets.js index 6362c3af..1c3fd978 100644 --- a/src/packet/all_packets.js +++ b/src/packet/all_packets.js @@ -21,3 +21,4 @@ export { default as UserIDPacket } from './userid'; export { default as SecretSubkeyPacket } from './secret_subkey'; export { default as SignaturePacket } from './signature'; export { default as TrustPacket } from './trust'; +export { default as PaddingPacket } from './padding'; diff --git a/src/packet/packetlist.js b/src/packet/packetlist.js index b0fea7f4..6207ef99 100644 --- a/src/packet/packetlist.js +++ b/src/packet/packetlist.js @@ -74,10 +74,11 @@ class PacketList extends Array { await writer.ready; const done = await readPackets(readable, async parsed => { try { - if (parsed.tag === enums.packet.marker || parsed.tag === enums.packet.trust) { + if (parsed.tag === enums.packet.marker || parsed.tag === enums.packet.trust || parsed.tag === enums.packet.padding) { // According to the spec, these packet types should be ignored and not cause parsing errors, even if not esplicitly allowed: // - Marker packets MUST be ignored when received: https://github.com/openpgpjs/openpgpjs/issues/1145 // - Trust packets SHOULD be ignored outside of keyrings (unsupported): https://datatracker.ietf.org/doc/html/rfc4880#section-5.10 + // - [Padding Packets] MUST be ignored when received: https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh#name-padding-packet-tag-21 return; } const packet = newPacketFromTag(parsed.tag, allowedPackets); diff --git a/src/packet/padding.js b/src/packet/padding.js new file mode 100644 index 00000000..b60e1e4b --- /dev/null +++ b/src/packet/padding.js @@ -0,0 +1,63 @@ +// OpenPGP.js - An OpenPGP implementation in javascript +// Copyright (C) 2022 Proton AG +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3.0 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +import crypto from '../crypto'; +import enums from '../enums'; + +/** + * Implementation of the Padding Packet + * + * {@link https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh#name-padding-packet-tag-21}: + * Padding Packet + */ +class PaddingPacket { + static get tag() { + return enums.packet.padding; + } + + constructor() { + this.padding = null; + } + + /** + * Read a padding packet + * @param {Uint8Array | ReadableStream} bytes + */ + read(bytes) { + // Padding packets are ignored, so this function is never called. + } + + /** + * Write the padding packet + * @returns {Uint8Array} The padding packet. + */ + write() { + return this.padding; + } + + /** + * Create random padding. + * @param {Number} length - The length of padding to be generated. + * @throws {Error} if padding generation was not successful + * @async + */ + async createPadding(length) { + this.padding = await crypto.random.getRandomBytes(length); + } +} + +export default PaddingPacket; diff --git a/test/general/packet.js b/test/general/packet.js index 8d77cdfe..329e13c7 100644 --- a/test/general/packet.js +++ b/test/general/packet.js @@ -280,6 +280,168 @@ export default () => describe('Packet', function() { } }); + it('Sym. encrypted AEAD protected packet test vector (SEIPDv2 - EAX)', async function() { + // From https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh#appendix-A-5 + + const nodeCrypto = util.getNodeCrypto(); + if (!nodeCrypto) return; + + const packetBytes = util.hexToUint8Array(` + d2 69 02 07 01 06 + 9f f9 0e 3b 32 19 64 f3 a4 29 13 c8 dc c6 61 93 + 25 01 52 27 ef b7 ea ea a4 9f 04 c2 e6 74 17 5d + 4a 3d 22 6e d6 af cb 9c a9 ac 12 2c 14 70 e1 1c + 63 d4 c0 ab 24 1c 6a 93 8a d4 8b f9 9a 5a 99 b9 + 0b ba 83 25 de + 61 04 75 40 25 8a b7 95 9a 95 ad 05 1d da 96 eb + 15 43 1d fe f5 f5 e2 25 5c a7 82 61 54 6e 33 9a + `.replace(/\s+/g, '')); + + const padding = util.hexToUint8Array('ae 5b f0 cd 67 05 50 03 55 81 6c b0 c8 ff'.replace(/\s+/g, '')); + const salt = util.hexToUint8Array('9f f9 0e 3b 32 19 64 f3 a4 29 13 c8 dc c6 61 93 25 01 52 27 ef b7 ea ea a4 9f 04 c2 e6 74 17 5d'.replace(/\s+/g, '')); + const key = util.hexToUint8Array('38 81 ba fe 98 54 12 45 9b 86 c3 6f 98 cb 9a 5e'.replace(/\s+/g, '')); + const algo = openpgp.enums.symmetric.aes128; + + const randomBytesStub = sinon.stub(nodeCrypto, 'randomBytes'); + randomBytesStub.withArgs(14).returns(padding); + randomBytesStub.withArgs(32).returns(salt); + + const literal = new openpgp.LiteralDataPacket(0); + literal.setBytes(util.stringToUint8Array('Hello, world!'), openpgp.enums.literal.binary); + literal.filename = ''; + const pad = new openpgp.PaddingPacket(); + await pad.createPadding(14); + const enc = new openpgp.SymEncryptedIntegrityProtectedDataPacket(); + enc.version = 2; + enc.aeadAlgorithm = openpgp.enums.aead.eax; + enc.packets = new openpgp.PacketList(); + enc.packets.push(literal); + enc.packets.push(pad); + const msg = new openpgp.PacketList(); + msg.push(enc); + + const msg2 = new openpgp.PacketList(); + + try { + await enc.encrypt(algo, key, { ...openpgp.config, aeadChunkSizeByte: 6 }); + const data = msg.write(); + expect(await stream.readToEnd(stream.clone(data))).to.deep.equal(packetBytes); + await msg2.read(data, allAllowedPackets); + await msg2[0].decrypt(algo, key); + expect(await stream.readToEnd(msg2[0].packets[0].data)).to.deep.equal(literal.data); + } finally { + randomBytesStub.restore(); + } + }); + + it('Sym. encrypted AEAD protected packet test vector (SEIPDv2 - OCB)', async function() { + // From https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh#appendix-A-5 + + const nodeCrypto = util.getNodeCrypto(); + if (!nodeCrypto) return; + + const packetBytes = util.hexToUint8Array(` + d2 69 02 07 02 06 + 20 a6 61 f7 31 fc 9a 30 32 b5 62 33 26 02 7e 3a + 5d 8d b5 74 8e be ff 0b 0c 59 10 d0 9e cd d6 41 + ff 9f d3 85 62 75 80 35 bc 49 75 4c e1 bf 3f ff + a7 da d0 a3 b8 10 4f 51 33 cf 42 a4 10 0a 83 ee + f4 ca 1b 48 01 + a8 84 6b f4 2b cd a7 c8 ce 9d 65 e2 12 f3 01 cb + cd 98 fd ca de 69 4a 87 7a d4 24 73 23 f6 e8 57 + `.replace(/\s+/g, '')); + + const padding = util.hexToUint8Array('ae 6a a1 64 9b 56 aa 83 5b 26 13 90 2b d2'.replace(/\s+/g, '')); + const salt = util.hexToUint8Array('20 a6 61 f7 31 fc 9a 30 32 b5 62 33 26 02 7e 3a 5d 8d b5 74 8e be ff 0b 0c 59 10 d0 9e cd d6 41'.replace(/\s+/g, '')); + const key = util.hexToUint8Array('28 e7 9a b8 23 97 d3 c6 3d e2 4a c2 17 d7 b7 91'.replace(/\s+/g, '')); + const algo = openpgp.enums.symmetric.aes128; + + const randomBytesStub = sinon.stub(nodeCrypto, 'randomBytes'); + randomBytesStub.withArgs(14).returns(padding); + randomBytesStub.withArgs(32).returns(salt); + + const literal = new openpgp.LiteralDataPacket(0); + literal.setBytes(util.stringToUint8Array('Hello, world!'), openpgp.enums.literal.binary); + literal.filename = ''; + const pad = new openpgp.PaddingPacket(); + await pad.createPadding(14); + const enc = new openpgp.SymEncryptedIntegrityProtectedDataPacket(); + enc.version = 2; + enc.aeadAlgorithm = openpgp.enums.aead.ocb; + enc.packets = new openpgp.PacketList(); + enc.packets.push(literal); + enc.packets.push(pad); + const msg = new openpgp.PacketList(); + msg.push(enc); + + const msg2 = new openpgp.PacketList(); + + try { + await enc.encrypt(algo, key, { ...openpgp.config, aeadChunkSizeByte: 6 }); + const data = msg.write(); + expect(await stream.readToEnd(stream.clone(data))).to.deep.equal(packetBytes); + await msg2.read(data, allAllowedPackets); + await msg2[0].decrypt(algo, key); + expect(await stream.readToEnd(msg2[0].packets[0].data)).to.deep.equal(literal.data); + } finally { + randomBytesStub.restore(); + } + }); + + it('Sym. encrypted AEAD protected packet test vector (SEIPDv2 - GCM)', async function() { + // From https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh#appendix-A-5 + + const nodeCrypto = util.getNodeCrypto(); + if (!nodeCrypto) return; + + const packetBytes = util.hexToUint8Array(` + d2 69 02 07 03 06 + fc b9 44 90 bc b9 8b bd c9 d1 06 c6 09 02 66 94 + 0f 72 e8 9e dc 21 b5 59 6b 15 76 b1 01 ed 0f 9f + fc 6f c6 d6 5b bf d2 4d cd 07 90 96 6e 6d 1e 85 + a3 00 53 78 4c b1 d8 b6 a0 69 9e f1 21 55 a7 b2 + ad 62 58 53 1b + 57 65 1f d7 77 79 12 fa 95 e3 5d 9b 40 21 6f 69 + a4 c2 48 db 28 ff 43 31 f1 63 29 07 39 9e 6f f9 + `.replace(/\s+/g, '')); + + const padding = util.hexToUint8Array('1c e2 26 9a 9e dd ef 81 03 21 72 b7 ed 7c'.replace(/\s+/g, '')); + const salt = util.hexToUint8Array('fc b9 44 90 bc b9 8b bd c9 d1 06 c6 09 02 66 94 0f 72 e8 9e dc 21 b5 59 6b 15 76 b1 01 ed 0f 9f'.replace(/\s+/g, '')); + const key = util.hexToUint8Array('19 36 fc 85 68 98 02 74 bb 90 0d 83 19 36 0c 77'.replace(/\s+/g, '')); + const algo = openpgp.enums.symmetric.aes128; + + const randomBytesStub = sinon.stub(nodeCrypto, 'randomBytes'); + randomBytesStub.withArgs(14).returns(padding); + randomBytesStub.withArgs(32).returns(salt); + + const literal = new openpgp.LiteralDataPacket(0); + literal.setBytes(util.stringToUint8Array('Hello, world!'), openpgp.enums.literal.binary); + literal.filename = ''; + const pad = new openpgp.PaddingPacket(); + await pad.createPadding(14); + const enc = new openpgp.SymEncryptedIntegrityProtectedDataPacket(); + enc.version = 2; + enc.aeadAlgorithm = openpgp.enums.aead.gcm; + enc.packets = new openpgp.PacketList(); + enc.packets.push(literal); + enc.packets.push(pad); + const msg = new openpgp.PacketList(); + msg.push(enc); + + const msg2 = new openpgp.PacketList(); + + try { + await enc.encrypt(algo, key, { ...openpgp.config, aeadChunkSizeByte: 6 }); + const data = msg.write(); + expect(await stream.readToEnd(stream.clone(data))).to.deep.equal(packetBytes); + await msg2.read(data, allAllowedPackets); + await msg2[0].decrypt(algo, key); + expect(await stream.readToEnd(msg2[0].packets[0].data)).to.deep.equal(literal.data); + } finally { + randomBytesStub.restore(); + } + }); + it('Sym. encrypted session key with a compressed packet', async function() { const msg = '-----BEGIN PGP MESSAGE-----\n' + From e5fe84dc2e81010780ae45061e92d20f456c0fe6 Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Wed, 14 Dec 2022 18:08:01 +0100 Subject: [PATCH 043/201] Support SKESK v6 as per the latest crypto refresh The latest crypto refresh specifies an HKDF step to be used for deriving the key to encrypt the session key with. It also specifies two additional length fields. --- src/packet/sym_encrypted_session_key.js | 50 +++-- test/general/config.js | 2 +- test/general/packet.js | 282 ++++++++++++++++++++++++ 3 files changed, 317 insertions(+), 17 deletions(-) diff --git a/src/packet/sym_encrypted_session_key.js b/src/packet/sym_encrypted_session_key.js index 6e940779..2dcfea54 100644 --- a/src/packet/sym_encrypted_session_key.js +++ b/src/packet/sym_encrypted_session_key.js @@ -18,6 +18,7 @@ import { newS2KFromConfig, newS2KFromType } from '../type/s2k'; import defaultConfig from '../config'; import crypto from '../crypto'; +import computeHKDF from '../crypto/hkdf'; import enums from '../enums'; import util from '../util'; import { UnsupportedError } from './packet'; @@ -44,7 +45,7 @@ class SymEncryptedSessionKeyPacket { * @param {Object} [config] - Full configuration, defaults to openpgp.config */ constructor(config = defaultConfig) { - this.version = config.aeadProtect ? 5 : 4; + this.version = config.aeadProtect ? 6 : 4; this.sessionKey = null; /** * Algorithm to encrypt the session key with @@ -74,18 +75,28 @@ class SymEncryptedSessionKeyPacket { read(bytes) { let offset = 0; - // A one-octet version number. The only currently defined version is 4. + // A one-octet version number with value 4, 5 or 6. this.version = bytes[offset++]; - if (this.version !== 4 && this.version !== 5) { + if (this.version !== 4 && this.version !== 5 && this.version !== 6) { throw new UnsupportedError(`Version ${this.version} of the SKESK packet is unsupported.`); } + if (this.version === 6) { + // A one-octet scalar octet count of the following 5 fields. + offset++; + } + // A one-octet number describing the symmetric algorithm used. const algo = bytes[offset++]; - if (this.version === 5) { + if (this.version >= 5) { // A one-octet AEAD algorithm. this.aeadAlgorithm = bytes[offset++]; + + if (this.version === 6) { + // A one-octet scalar octet count of the following field. + offset++; + } } // A string-to-key (S2K) specifier, length as defined above. @@ -93,7 +104,7 @@ class SymEncryptedSessionKeyPacket { this.s2k = newS2KFromType(s2kType); offset += this.s2k.read(bytes.subarray(offset, bytes.length)); - if (this.version === 5) { + if (this.version >= 5) { const mode = crypto.getAEADMode(this.aeadAlgorithm); // A starting initialization vector of size specified by the AEAD @@ -103,7 +114,7 @@ class SymEncryptedSessionKeyPacket { // The encrypted session key itself, which is decrypted with the // string-to-key object. This is optional in version 4. - if (this.version === 5 || offset < bytes.length) { + if (this.version >= 5 || offset < bytes.length) { this.encrypted = bytes.subarray(offset, bytes.length); this.sessionKeyEncryptionAlgorithm = algo; } else { @@ -123,10 +134,15 @@ class SymEncryptedSessionKeyPacket { let bytes; - if (this.version === 5) { - bytes = util.concatUint8Array([new Uint8Array([this.version, algo, this.aeadAlgorithm]), this.s2k.write(), this.iv, this.encrypted]); + const s2k = this.s2k.write(); + if (this.version === 6) { + const s2kLen = s2k.length; + const fieldsLen = 3 + s2kLen + this.iv.length; + bytes = util.concatUint8Array([new Uint8Array([this.version, fieldsLen, algo, this.aeadAlgorithm, s2kLen]), s2k, this.iv, this.encrypted]); + } else if (this.version === 5) { + bytes = util.concatUint8Array([new Uint8Array([this.version, algo, this.aeadAlgorithm]), s2k, this.iv, this.encrypted]); } else { - bytes = util.concatUint8Array([new Uint8Array([this.version, algo]), this.s2k.write()]); + bytes = util.concatUint8Array([new Uint8Array([this.version, algo]), s2k]); if (this.encrypted !== null) { bytes = util.concatUint8Array([bytes, this.encrypted]); @@ -150,10 +166,11 @@ class SymEncryptedSessionKeyPacket { const { blockSize, keySize } = crypto.getCipher(algo); const key = await this.s2k.produceKey(passphrase, keySize); - if (this.version === 5) { + if (this.version >= 5) { const mode = crypto.getAEADMode(this.aeadAlgorithm); const adata = new Uint8Array([0xC0 | SymEncryptedSessionKeyPacket.tag, this.version, this.sessionKeyEncryptionAlgorithm, this.aeadAlgorithm]); - const modeInstance = await mode(algo, key); + const encryptionKey = this.version === 6 ? await computeHKDF(enums.hash.sha256, key, new Uint8Array(), adata, keySize) : key; + const modeInstance = await mode(algo, encryptionKey); this.sessionKey = await modeInstance.decrypt(this.encrypted, this.iv, adata); } else if (this.encrypted !== null) { const decrypted = await crypto.mode.cfb.decrypt(algo, key, this.encrypted, new Uint8Array(blockSize)); @@ -183,24 +200,25 @@ class SymEncryptedSessionKeyPacket { this.s2k.generateSalt(); const { blockSize, keySize } = crypto.getCipher(algo); - const encryptionKey = await this.s2k.produceKey(passphrase, keySize); + const key = await this.s2k.produceKey(passphrase, keySize); if (this.sessionKey === null) { this.sessionKey = crypto.generateSessionKey(this.sessionKeyAlgorithm); } - if (this.version === 5) { + if (this.version >= 5) { const mode = crypto.getAEADMode(this.aeadAlgorithm); this.iv = crypto.random.getRandomBytes(mode.ivLength); // generate new random IV - const associatedData = new Uint8Array([0xC0 | SymEncryptedSessionKeyPacket.tag, this.version, this.sessionKeyEncryptionAlgorithm, this.aeadAlgorithm]); + const adata = new Uint8Array([0xC0 | SymEncryptedSessionKeyPacket.tag, this.version, this.sessionKeyEncryptionAlgorithm, this.aeadAlgorithm]); + const encryptionKey = this.version === 6 ? await computeHKDF(enums.hash.sha256, key, new Uint8Array(), adata, keySize) : key; const modeInstance = await mode(algo, encryptionKey); - this.encrypted = await modeInstance.encrypt(this.sessionKey, this.iv, associatedData); + this.encrypted = await modeInstance.encrypt(this.sessionKey, this.iv, adata); } else { const toEncrypt = util.concatUint8Array([ new Uint8Array([this.sessionKeyAlgorithm]), this.sessionKey ]); - this.encrypted = await crypto.mode.cfb.encrypt(algo, encryptionKey, toEncrypt, new Uint8Array(blockSize), config); + this.encrypted = await crypto.mode.cfb.encrypt(algo, key, toEncrypt, new Uint8Array(blockSize), config); } } } diff --git a/test/general/config.js b/test/general/config.js index 0d5393d1..66032a91 100644 --- a/test/general/config.js +++ b/test/general/config.js @@ -284,7 +284,7 @@ n9/quqtmyOtYOA6gXNCw0Fal3iANKBmsPmYI const armored2 = await openpgp.encrypt({ message, passwords, config }); const encrypted2 = await openpgp.readMessage({ armoredMessage: armored2 }); const { packets: [skesk2, encData2] } = encrypted2; - expect(skesk2.version).to.equal(5); + expect(skesk2.version).to.equal(6); expect(encData2.constructor.tag).to.equal(openpgp.enums.packet.symEncryptedIntegrityProtectedData); expect(encData2.version).to.equal(2); const { packets: [compressed] } = await encrypted2.decrypt(null, passwords, null, encrypted2.fromStream, openpgp.config); diff --git a/test/general/packet.js b/test/general/packet.js index 329e13c7..11397a45 100644 --- a/test/general/packet.js +++ b/test/general/packet.js @@ -644,6 +644,45 @@ export default () => describe('Packet', function() { const aeadProtectVal = openpgp.config.aeadProtect; openpgp.config.aeadProtect = true; + try { + const passphrase = 'hello'; + const algo = openpgp.enums.symmetric.aes256; + const testText = input.createSomeMessage(); + + const literal = new openpgp.LiteralDataPacket(); + literal.setText(testText); + const skesk = new openpgp.SymEncryptedSessionKeyPacket(); + skesk.version = 5; + const aeadEnc = new openpgp.AEADEncryptedDataPacket(); + aeadEnc.packets = new openpgp.PacketList(); + aeadEnc.packets.push(literal); + const msg = new openpgp.PacketList(); + msg.push(skesk); + msg.push(aeadEnc); + + skesk.sessionKeyAlgorithm = algo; + await skesk.encrypt(passphrase, openpgp.config); + + const key = skesk.sessionKey; + await aeadEnc.encrypt(algo, key, undefined, openpgp.config); + + const msg2 = new openpgp.PacketList(); + await msg2.read(msg.write(), allAllowedPackets); + + await msg2[0].decrypt(passphrase); + const key2 = msg2[0].sessionKey; + await msg2[1].decrypt(msg2[0].sessionKeyAlgorithm, key2); + + expect(await stringify(msg2[1].packets[0].data)).to.equal(stringify(literal.data)); + } finally { + openpgp.config.aeadProtect = aeadProtectVal; + } + }); + + it('Sym. encrypted session key reading/writing (SEIPDv2)', async function() { + const aeadProtectVal = openpgp.config.aeadProtect; + openpgp.config.aeadProtect = true; + try { const passphrase = 'hello'; const algo = openpgp.enums.symmetric.aes256; @@ -723,10 +762,12 @@ export default () => describe('Packet', function() { literal.setBytes(util.stringToUint8Array('Hello, world!\n'), openpgp.enums.literal.binary); literal.filename = ''; const skesk = new openpgp.SymEncryptedSessionKeyPacket(); + skesk.version = 5; skesk.sessionKeyAlgorithm = algo; const encData = new openpgp.AEADEncryptedDataPacket(); encData.packets = new openpgp.PacketList(); encData.packets.push(literal); + encData.aeadAlgorithm = skesk.aeadAlgorithm = openpgp.enums.aead.eax; const msg = new openpgp.PacketList(); msg.push(skesk); msg.push(encData); @@ -800,6 +841,7 @@ export default () => describe('Packet', function() { literal.setBytes(util.stringToUint8Array('Hello, world!\n'), openpgp.enums.literal.binary); literal.filename = ''; const skesk = new openpgp.SymEncryptedSessionKeyPacket(); + skesk.version = 5; skesk.sessionKeyAlgorithm = algo; const enc = new openpgp.AEADEncryptedDataPacket(); enc.packets = new openpgp.PacketList(); @@ -833,6 +875,246 @@ export default () => describe('Packet', function() { } }); + it('Sym. encrypted session key reading/writing test vector (SEIPDv2, EAX)', async function() { + // From https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh#appendix-A.5 + + const nodeCrypto = util.getNodeCrypto(); + if (!nodeCrypto) return; + + const aeadProtectVal = openpgp.config.aeadProtect; + const aeadChunkSizeByteVal = openpgp.config.aeadChunkSizeByte; + const s2kIterationCountByteVal = openpgp.config.s2kIterationCountByte; + openpgp.config.aeadProtect = true; + openpgp.config.aeadChunkSizeByte = 6; + openpgp.config.s2kIterationCountByte = 255; + + const padding = util.hexToUint8Array('ae 5b f0 cd 67 05 50 03 55 81 6c b0 c8 ff'.replace(/\s+/g, '')); + const salt = util.hexToUint8Array('a5 ae 57 9d 1f c5 d8 2b'.replace(/\s+/g, '')); + const sessionKey = util.hexToUint8Array('38 81 ba fe 98 54 12 45 9b 86 c3 6f 98 cb 9a 5e'.replace(/\s+/g, '')); + const sessionIV = util.hexToUint8Array('69 22 4f 91 99 93 b3 50 6f a3 b5 9a 6a 73 cf f8'.replace(/\s+/g, '')); + const dataSalt = util.hexToUint8Array('9f f9 0e 3b 32 19 64 f3 a4 29 13 c8 dc c6 61 93 25 01 52 27 ef b7 ea ea a4 9f 04 c2 e6 74 17 5d'.replace(/\s+/g, '')); + + const randomBytesStub = sinon.stub(nodeCrypto, 'randomBytes'); + randomBytesStub.onCall(0).returns(padding); + randomBytesStub.onCall(1).returns(salt); + randomBytesStub.onCall(2).returns(sessionKey); + randomBytesStub.onCall(3).returns(sessionIV); + randomBytesStub.onCall(4).returns(dataSalt); + + const { data: packetBytes } = await openpgp.unarmor(`-----BEGIN PGP MESSAGE----- + +w0AGHgcBCwMIpa5XnR/F2Cv/aSJPkZmTs1Bvo7WaanPP+MXvxfQcV/tU4cImgV14 +KPX5LEVOtl6+AKtZhsaObnxV0mkCBwEGn/kOOzIZZPOkKRPI3MZhkyUBUifvt+rq +pJ8EwuZ0F11KPSJu1q/LnKmsEiwUcOEcY9TAqyQcapOK1Iv5mlqZuQu6gyXeYQR1 +QCWKt5Wala0FHdqW6xVDHf719eIlXKeCYVRuM5o= +-----END PGP MESSAGE----- +`); + + try { + const passphrase = 'password'; + const algo = openpgp.enums.symmetric.aes128; + + const skesk = new openpgp.SymEncryptedSessionKeyPacket(); + skesk.sessionKeyAlgorithm = algo; + const literal = new openpgp.LiteralDataPacket(0); + literal.setBytes(util.stringToUint8Array('Hello, world!'), openpgp.enums.literal.binary); + literal.filename = ''; + const pad = new openpgp.PaddingPacket(); + await pad.createPadding(14); + const enc = new openpgp.SymEncryptedIntegrityProtectedDataPacket(); + enc.version = 2; + enc.aeadAlgorithm = skesk.aeadAlgorithm = openpgp.enums.aead.eax; + enc.packets = new openpgp.PacketList(); + enc.packets.push(literal); + enc.packets.push(pad); + const msg = new openpgp.PacketList(); + msg.push(skesk); + msg.push(enc); + + await skesk.encrypt(passphrase, openpgp.config); + + const key = skesk.sessionKey; + await enc.encrypt(algo, key, undefined, openpgp.config); + + const data = msg.write(); + expect(await stream.readToEnd(stream.clone(data))).to.deep.equal(packetBytes); + + const msg2 = new openpgp.PacketList(); + await msg2.read(data, allAllowedPackets); + + await msg2[0].decrypt(passphrase); + const key2 = msg2[0].sessionKey; + await msg2[1].decrypt(msg2[0].sessionKeyAlgorithm, key2); + + expect(await stringify(msg2[1].packets[0].data)).to.equal(stringify(literal.data)); + } finally { + openpgp.config.aeadProtect = aeadProtectVal; + openpgp.config.aeadChunkSizeByte = aeadChunkSizeByteVal; + openpgp.config.s2kIterationCountByte = s2kIterationCountByteVal; + randomBytesStub.restore(); + } + }); + + it('Sym. encrypted session key reading/writing test vector (SEIPDv2, OCB)', async function() { + // From https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh#appendix-A.6 + + const nodeCrypto = util.getNodeCrypto(); + if (!nodeCrypto) return; + + const aeadProtectVal = openpgp.config.aeadProtect; + const aeadChunkSizeByteVal = openpgp.config.aeadChunkSizeByte; + const s2kIterationCountByteVal = openpgp.config.s2kIterationCountByte; + openpgp.config.aeadProtect = true; + openpgp.config.aeadChunkSizeByte = 6; + openpgp.config.s2kIterationCountByte = 255; + + const padding = util.hexToUint8Array('ae 6a a1 64 9b 56 aa 83 5b 26 13 90 2b d2'.replace(/\s+/g, '')); + const salt = util.hexToUint8Array('56 a2 98 d2 f5 e3 64 53'.replace(/\s+/g, '')); + const sessionKey = util.hexToUint8Array('28 e7 9a b8 23 97 d3 c6 3d e2 4a c2 17 d7 b7 91'.replace(/\s+/g, '')); + const sessionIV = util.hexToUint8Array('cf cc 5c 11 66 4e db 9d b4 25 90 d7 dc 46 b0'.replace(/\s+/g, '')); + const dataSalt = util.hexToUint8Array('20 a6 61 f7 31 fc 9a 30 32 b5 62 33 26 02 7e 3a 5d 8d b5 74 8e be ff 0b 0c 59 10 d0 9e cd d6 41'.replace(/\s+/g, '')); + + const randomBytesStub = sinon.stub(nodeCrypto, 'randomBytes'); + randomBytesStub.onCall(0).returns(padding); + randomBytesStub.onCall(1).returns(salt); + randomBytesStub.onCall(2).returns(sessionKey); + randomBytesStub.onCall(3).returns(sessionIV); + randomBytesStub.onCall(4).returns(dataSalt); + + const { data: packetBytes } = await openpgp.unarmor(`-----BEGIN PGP MESSAGE----- + +wz8GHQcCCwMIVqKY0vXjZFP/z8xcEWZO2520JZDX3EawckG2EsOBLP/76gDyNHsl +ZBEj+IeuYNT9YU4IN9gZ02zSaQIHAgYgpmH3MfyaMDK1YjMmAn46XY21dI6+/wsM +WRDQns3WQf+f04VidYA1vEl1TOG/P/+n2tCjuBBPUTPPQqQQCoPu9MobSAGohGv0 +K82nyM6dZeIS8wHLzZj9yt5pSod61CRzI/boVw== +-----END PGP MESSAGE----- +`); + + try { + const passphrase = 'password'; + const algo = openpgp.enums.symmetric.aes128; + + const skesk = new openpgp.SymEncryptedSessionKeyPacket(); + skesk.sessionKeyAlgorithm = algo; + const literal = new openpgp.LiteralDataPacket(0); + literal.setBytes(util.stringToUint8Array('Hello, world!'), openpgp.enums.literal.binary); + literal.filename = ''; + const pad = new openpgp.PaddingPacket(); + await pad.createPadding(14); + const enc = new openpgp.SymEncryptedIntegrityProtectedDataPacket(); + enc.version = 2; + enc.aeadAlgorithm = skesk.aeadAlgorithm = openpgp.enums.aead.ocb; + enc.packets = new openpgp.PacketList(); + enc.packets.push(literal); + enc.packets.push(pad); + const msg = new openpgp.PacketList(); + msg.push(skesk); + msg.push(enc); + + await skesk.encrypt(passphrase, openpgp.config); + + const key = skesk.sessionKey; + await enc.encrypt(algo, key, undefined, openpgp.config); + + const data = msg.write(); + expect(await stream.readToEnd(stream.clone(data))).to.deep.equal(packetBytes); + + const msg2 = new openpgp.PacketList(); + await msg2.read(data, allAllowedPackets); + + await msg2[0].decrypt(passphrase); + const key2 = msg2[0].sessionKey; + await msg2[1].decrypt(msg2[0].sessionKeyAlgorithm, key2); + + expect(await stringify(msg2[1].packets[0].data)).to.equal(stringify(literal.data)); + } finally { + openpgp.config.aeadProtect = aeadProtectVal; + openpgp.config.aeadChunkSizeByte = aeadChunkSizeByteVal; + openpgp.config.s2kIterationCountByte = s2kIterationCountByteVal; + randomBytesStub.restore(); + } + }); + + it('Sym. encrypted session key reading/writing test vector (SEIPDv2, GCM)', async function() { + // From https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh#appendix-A.7 + + const nodeCrypto = util.getNodeCrypto(); + if (!nodeCrypto) return; + + const aeadProtectVal = openpgp.config.aeadProtect; + const aeadChunkSizeByteVal = openpgp.config.aeadChunkSizeByte; + const s2kIterationCountByteVal = openpgp.config.s2kIterationCountByte; + openpgp.config.aeadProtect = true; + openpgp.config.aeadChunkSizeByte = 6; + openpgp.config.s2kIterationCountByte = 255; + + const padding = util.hexToUint8Array('1c e2 26 9a 9e dd ef 81 03 21 72 b7 ed 7c'.replace(/\s+/g, '')); + const salt = util.hexToUint8Array('e9 d3 97 85 b2 07 00 08'.replace(/\s+/g, '')); + const sessionKey = util.hexToUint8Array('19 36 fc 85 68 98 02 74 bb 90 0d 83 19 36 0c 77'.replace(/\s+/g, '')); + const sessionIV = util.hexToUint8Array('b4 2e 7c 48 3e f4 88 44 57 cb 37 26'.replace(/\s+/g, '')); + const dataSalt = util.hexToUint8Array('fc b9 44 90 bc b9 8b bd c9 d1 06 c6 09 02 66 94 0f 72 e8 9e dc 21 b5 59 6b 15 76 b1 01 ed 0f 9f'.replace(/\s+/g, '')); + + const randomBytesStub = sinon.stub(nodeCrypto, 'randomBytes'); + randomBytesStub.onCall(0).returns(padding); + randomBytesStub.onCall(1).returns(salt); + randomBytesStub.onCall(2).returns(sessionKey); + randomBytesStub.onCall(3).returns(sessionIV); + randomBytesStub.onCall(4).returns(dataSalt); + + const { data: packetBytes } = await openpgp.unarmor(`-----BEGIN PGP MESSAGE----- + +wzwGGgcDCwMI6dOXhbIHAAj/tC58SD70iERXyzcmubPbn/d25fTZpAlS4kRymIUa +v/91Jt8t1VRBdXmneZ/SaQIHAwb8uUSQvLmLvcnRBsYJAmaUD3LontwhtVlrFXax +Ae0Pn/xvxtZbv9JNzQeQlm5tHoWjAFN4TLHYtqBpnvEhVaeyrWJYUxtXZR/Xd3kS ++pXjXZtAIW9ppMJI2yj/QzHxYykHOZ5v+Q== +-----END PGP MESSAGE----- +`); + + try { + const passphrase = 'password'; + const algo = openpgp.enums.symmetric.aes128; + + const skesk = new openpgp.SymEncryptedSessionKeyPacket(); + skesk.sessionKeyAlgorithm = algo; + const literal = new openpgp.LiteralDataPacket(0); + literal.setBytes(util.stringToUint8Array('Hello, world!'), openpgp.enums.literal.binary); + literal.filename = ''; + const pad = new openpgp.PaddingPacket(); + await pad.createPadding(14); + const enc = new openpgp.SymEncryptedIntegrityProtectedDataPacket(); + enc.version = 2; + enc.aeadAlgorithm = skesk.aeadAlgorithm = openpgp.enums.aead.gcm; + enc.packets = new openpgp.PacketList(); + enc.packets.push(literal); + enc.packets.push(pad); + const msg = new openpgp.PacketList(); + msg.push(skesk); + msg.push(enc); + + await skesk.encrypt(passphrase, openpgp.config); + + const key = skesk.sessionKey; + await enc.encrypt(algo, key, undefined, openpgp.config); + + const data = msg.write(); + expect(await stream.readToEnd(stream.clone(data))).to.deep.equal(packetBytes); + + const msg2 = new openpgp.PacketList(); + await msg2.read(data, allAllowedPackets); + + await msg2[0].decrypt(passphrase); + const key2 = msg2[0].sessionKey; + await msg2[1].decrypt(msg2[0].sessionKeyAlgorithm, key2); + + expect(await stringify(msg2[1].packets[0].data)).to.equal(stringify(literal.data)); + } finally { + openpgp.config.aeadProtect = aeadProtectVal; + openpgp.config.aeadChunkSizeByte = aeadChunkSizeByteVal; + openpgp.config.s2kIterationCountByte = s2kIterationCountByteVal; + randomBytesStub.restore(); + } + }); + it('Secret key encryption/decryption test', async function() { const armored_msg = '-----BEGIN PGP MESSAGE-----\n' + From f77ed0c0ed062349d64d52aca31c9e4b57d5fd8e Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Thu, 16 Mar 2023 18:17:26 +0100 Subject: [PATCH 044/201] Look up preferred ciphersuite in one go Instead of calling getPreferredAlgo('symmetric') and getPreferredAlgo('aead'), we define and call getPreferredCipherSuite() to determine the preferred symmetric and AEAD algorithm. Additionally, we remove isAEADSupported(), instead we return aeadAlgorithm: undefined from getPreferredCipherSuite() if AEAD is not supported (CFB is used instead). And finally, we define getPreferredCompressionAlgo() to replace getPreferredAlgo('compression'). --- src/key/helper.js | 78 +++++++++++++++++++--------------------- src/key/index.js | 8 ++--- src/message.js | 16 ++++----- src/openpgp.js | 4 +-- test/general/key.js | 79 +++++++++++++++++++++++------------------ test/general/openpgp.js | 5 +-- 6 files changed, 96 insertions(+), 94 deletions(-) diff --git a/src/key/helper.js b/src/key/helper.js index 766f41c9..15ed4370 100644 --- a/src/key/helper.js +++ b/src/key/helper.js @@ -134,43 +134,59 @@ export async function getPreferredHashAlgo(key, keyPacket, date = new Date(), us } /** - * Returns the preferred symmetric/aead/compression algorithm for a set of keys - * @param {'symmetric'|'aead'|'compression'} type - Type of preference to return + * Returns the preferred compression algorithm for a set of keys * @param {Array} [keys] - Set of keys * @param {Date} [date] - Use the given date for verification instead of the current time * @param {Array} [userIDs] - User IDs * @param {Object} [config] - Full configuration, defaults to openpgp.config - * @returns {Promise} Preferred algorithm + * @returns {Promise} Preferred compression algorithm * @async */ -export async function getPreferredAlgo(type, keys = [], date = new Date(), userIDs = [], config = defaultConfig) { - const defaultAlgo = { // these are all must-implement in the crypto refresh - 'symmetric': enums.symmetric.aes128, - 'aead': enums.aead.ocb, - 'compression': enums.compression.uncompressed - }[type]; - const preferredSenderAlgo = { - 'symmetric': config.preferredSymmetricAlgorithm, - 'aead': config.preferredAEADAlgorithm, - 'compression': config.preferredCompressionAlgorithm - }[type]; - const prefPropertyName = { - 'symmetric': 'preferredSymmetricAlgorithms', - 'aead': 'preferredAEADAlgorithms', - 'compression': 'preferredCompressionAlgorithms' - }[type]; +export async function getPreferredCompressionAlgo(keys = [], date = new Date(), userIDs = [], config = defaultConfig) { + const defaultAlgo = enums.compression.uncompressed; + const preferredSenderAlgo = config.preferredCompressionAlgorithm; // if preferredSenderAlgo appears in the prefs of all recipients, we pick it // otherwise we use the default algo // if no keys are available, preferredSenderAlgo is returned const senderAlgoSupport = await Promise.all(keys.map(async function(key, i) { const selfCertification = await key.getPrimarySelfSignature(date, userIDs[i], config); - const recipientPrefs = selfCertification[prefPropertyName]; + const recipientPrefs = selfCertification.preferredCompressionAlgorithms; return !!recipientPrefs && recipientPrefs.indexOf(preferredSenderAlgo) >= 0; })); return senderAlgoSupport.every(Boolean) ? preferredSenderAlgo : defaultAlgo; } +/** + * Returns the preferred symmetric and AEAD algorithm (if any) for a set of keys + * @param {Array} [keys] - Set of keys + * @param {Date} [date] - Use the given date for verification instead of the current time + * @param {Array} [userIDs] - User IDs + * @param {Object} [config] - Full configuration, defaults to openpgp.config + * @returns {Promise<{ symmetricAlgo: module:enums.symmetric, aeadAlgo: module:enums.aead | undefined }>} Object containing the preferred symmetric algorithm, and the preferred AEAD algorithm, or undefined if CFB is preferred + * @async + */ +export async function getPreferredCipherSuite(keys = [], date = new Date(), userIDs = [], config = defaultConfig) { + const selfSigs = await Promise.all(keys.map((key, i) => key.getPrimarySelfSignature(date, userIDs[i], config))); + if (config.aeadProtect && selfSigs.every(selfSig => selfSig.features[0] & enums.features.seipdv2)) { + const defaultCipherSuite = { symmetricAlgo: enums.symmetric.aes128, aeadAlgo: enums.aead.ocb }; + const desiredCipherSuite = { symmetricAlgo: config.preferredSymmetricAlgorithm, aeadAlgo: config.preferredAEADAlgorithm }; + return selfSigs.every(selfSig => selfSig.preferredCipherSuites && selfSig.preferredCipherSuites.some( + cipherSuite => cipherSuite[0] === desiredCipherSuite.symmetricAlgo && cipherSuite[1] === desiredCipherSuite.aeadAlgo + )) ? + desiredCipherSuite : + defaultCipherSuite; + } + const defaultSymAlgo = enums.symmetric.aes128; + const desiredSymAlgo = config.preferredSymmetricAlgorithm; + return { + symmetricAlgo: selfSigs.every(selfSig => selfSig.preferredSymmetricAlgorithms && selfSig.preferredSymmetricAlgorithms.includes(desiredSymAlgo)) ? + desiredSymAlgo : + defaultSymAlgo, + aeadAlgo: undefined + }; +} + /** * Create signature packet * @param {Object} dataToSign - Contains packets to be signed @@ -293,28 +309,6 @@ export function getKeyExpirationTime(keyPacket, signature) { return expirationTime ? new Date(expirationTime) : Infinity; } -/** - * Returns whether aead is supported by all keys in the set - * @param {Array} keys - Set of keys - * @param {Date} [date] - Use the given date for verification instead of the current time - * @param {Array} [userIDs] - User IDs - * @param {Object} config - full configuration - * @returns {Promise} - * @async - */ -export async function isAEADSupported(keys, date = new Date(), userIDs = [], config = defaultConfig) { - let supported = true; - // TODO replace when Promise.some or Promise.any are implemented - await Promise.all(keys.map(async function(key, i) { - const selfCertification = await key.getPrimarySelfSignature(date, userIDs[i], config); - if (!selfCertification.features || - !(selfCertification.features[0] & enums.features.seipdv2)) { - supported = false; - } - })); - return supported; -} - export function sanitizeKeyOptions(options, subkeyDefaults = {}) { options.type = options.type || subkeyDefaults.type; options.curve = options.curve || subkeyDefaults.curve; diff --git a/src/key/index.js b/src/key/index.js index 47c43019..6781baa9 100644 --- a/src/key/index.js +++ b/src/key/index.js @@ -8,9 +8,9 @@ import { } from './factory'; import { - getPreferredAlgo, - isAEADSupported, getPreferredHashAlgo, + getPreferredCompressionAlgo, + getPreferredCipherSuite, createSignaturePacket } from './helper'; @@ -25,9 +25,9 @@ export { readPrivateKeys, generate, reformat, - getPreferredAlgo, - isAEADSupported, getPreferredHashAlgo, + getPreferredCompressionAlgo, + getPreferredCipherSuite, createSignaturePacket, PrivateKey, PublicKey, diff --git a/src/message.js b/src/message.js index a17f523c..fac3eb96 100644 --- a/src/message.js +++ b/src/message.js @@ -24,7 +24,7 @@ import crypto from './crypto'; import enums from './enums'; import util from './util'; import { Signature } from './signature'; -import { getPreferredHashAlgo, getPreferredAlgo, isAEADSupported, createSignaturePacket } from './key'; +import { getPreferredHashAlgo, getPreferredCipherSuite, createSignaturePacket } from './key'; import { PacketList, LiteralDataPacket, @@ -343,23 +343,21 @@ export class Message { * @async */ static async generateSessionKey(encryptionKeys = [], date = new Date(), userIDs = [], config = defaultConfig) { - const algo = await getPreferredAlgo('symmetric', encryptionKeys, date, userIDs, config); - const algorithmName = enums.read(enums.symmetric, algo); - const aeadAlgorithmName = config.aeadProtect && await isAEADSupported(encryptionKeys, date, userIDs, config) ? - enums.read(enums.aead, await getPreferredAlgo('aead', encryptionKeys, date, userIDs, config)) : - undefined; + const { symmetricAlgo, aeadAlgo } = await getPreferredCipherSuite(encryptionKeys, date, userIDs, config); + const symmetricAlgoName = enums.read(enums.symmetric, symmetricAlgo); + const aeadAlgoName = aeadAlgo ? enums.read(enums.aead, aeadAlgo) : undefined; await Promise.all(encryptionKeys.map(key => key.getEncryptionKey() .catch(() => null) // ignore key strength requirements .then(maybeKey => { - if (maybeKey && (maybeKey.keyPacket.algorithm === enums.publicKey.x25519) && !util.isAES(algo)) { + if (maybeKey && (maybeKey.keyPacket.algorithm === enums.publicKey.x25519) && !util.isAES(symmetricAlgo)) { throw new Error('Could not generate a session key compatible with the given `encryptionKeys`: X22519 keys can only be used to encrypt AES session keys; change `config.preferredSymmetricAlgorithm` accordingly.'); } }) )); - const sessionKeyData = crypto.generateSessionKey(algo); - return { data: sessionKeyData, algorithm: algorithmName, aeadAlgorithm: aeadAlgorithmName }; + const sessionKeyData = crypto.generateSessionKey(symmetricAlgo); + return { data: sessionKeyData, algorithm: symmetricAlgoName, aeadAlgorithm: aeadAlgoName }; } /** diff --git a/src/openpgp.js b/src/openpgp.js index cef01e9b..223ebfdf 100644 --- a/src/openpgp.js +++ b/src/openpgp.js @@ -18,7 +18,7 @@ import * as stream from '@openpgp/web-stream-tools'; import { Message } from './message'; import { CleartextMessage } from './cleartext'; -import { generate, reformat, getPreferredAlgo } from './key'; +import { generate, reformat, getPreferredCompressionAlgo } from './key'; import defaultConfig from './config'; import util from './util'; import { checkKeyRequirements } from './key/helper'; @@ -284,7 +284,7 @@ export async function encrypt({ message, encryptionKeys, signingKeys, passwords, message = await message.sign(signingKeys, signature, signingKeyIDs, date, signingUserIDs, signatureNotations, config); } message = message.compress( - await getPreferredAlgo('compression', encryptionKeys, date, encryptionUserIDs, config), + await getPreferredCompressionAlgo(encryptionKeys, date, encryptionUserIDs, config), config ); message = await message.encrypt(encryptionKeys, passwords, sessionKey, wildcard, encryptionKeyIDs, date, encryptionUserIDs, config); diff --git a/test/general/key.js b/test/general/key.js index 2f266ef9..9ed68d97 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -6,7 +6,7 @@ chaiUse(chaiAsPromised); import openpgp from '../initOpenpgp.js'; import util from '../../src/util.js'; -import { isAEADSupported, getPreferredAlgo } from '../../src/key'; +import { getPreferredCipherSuite } from '../../src/key'; import KeyID from '../../src/type/keyid.js'; @@ -3643,76 +3643,85 @@ aU71tdtNBQ== expect(revKey.armor()).not.to.match(/Comment: This is a revocation certificate/); }); - it("getPreferredAlgo('symmetric') - one key", async function() { + it('getPreferredCipherSuite - one key', async function() { const [key1] = await openpgp.readKeys({ armoredKeys: twoKeys }); - const prefAlgo = await getPreferredAlgo('symmetric', [key1], undefined, undefined, { + const { symmetricAlgo, aeadAlgo } = await getPreferredCipherSuite([key1], undefined, undefined, { ...openpgp.config, preferredSymmetricAlgorithm: openpgp.enums.symmetric.aes256 }); - expect(prefAlgo).to.equal(openpgp.enums.symmetric.aes256); + expect(symmetricAlgo).to.equal(openpgp.enums.symmetric.aes256); + expect(aeadAlgo).to.equal(undefined); }); - it("getPreferredAlgo('symmetric') - two key", async function() { + it('getPreferredCipherSuite - two keys', async function() { const { aes128, aes192, cast5 } = openpgp.enums.symmetric; const [key1, key2] = await openpgp.readKeys({ armoredKeys: twoKeys }); const primaryUser = await key2.getPrimaryUser(); primaryUser.selfCertification.preferredSymmetricAlgorithms = [6, aes192, cast5]; - const prefAlgo = await getPreferredAlgo('symmetric', [key1, key2], undefined, undefined, { + const { symmetricAlgo, aeadAlgo } = await getPreferredCipherSuite([key1, key2], undefined, undefined, { ...openpgp.config, preferredSymmetricAlgorithm: openpgp.enums.symmetric.aes192 }); - expect(prefAlgo).to.equal(aes192); - const prefAlgo2 = await getPreferredAlgo('symmetric', [key1, key2], undefined, undefined, { + expect(symmetricAlgo).to.equal(aes192); + expect(aeadAlgo).to.equal(undefined); + const { symmetricAlgo: symmetricAlgo2, aeadAlgo: aeadAlgo2 } = await getPreferredCipherSuite([key1, key2], undefined, undefined, { ...openpgp.config, preferredSymmetricAlgorithm: openpgp.enums.symmetric.aes256 }); - expect(prefAlgo2).to.equal(aes128); + expect(symmetricAlgo2).to.equal(aes128); + expect(aeadAlgo2).to.equal(undefined); }); - it("getPreferredAlgo('symmetric') - two key - one without pref", async function() { + it('getPreferredCipherSuite - two keys - one without pref', async function() { const [key1, key2] = await openpgp.readKeys({ armoredKeys: twoKeys }); const primaryUser = await key2.getPrimaryUser(); primaryUser.selfCertification.preferredSymmetricAlgorithms = null; - const prefAlgo = await getPreferredAlgo('symmetric', [key1, key2]); - expect(prefAlgo).to.equal(openpgp.enums.symmetric.aes128); + const { symmetricAlgo, aeadAlgo } = await getPreferredCipherSuite([key1, key2]); + expect(symmetricAlgo).to.equal(openpgp.enums.symmetric.aes128); + expect(aeadAlgo).to.equal(undefined); }); - it("getPreferredAlgo('aead') - one key - OCB", async function() { + it('getPreferredCipherSuite with AEAD - one key - GCM', async function() { const [key1] = await openpgp.readKeys({ armoredKeys: twoKeys }); const primaryUser = await key1.getPrimaryUser(); - primaryUser.selfCertification.features = [7]; // Monkey-patch AEAD feature flag - primaryUser.selfCertification.preferredAEADAlgorithms = [2,1]; - const prefAlgo = await getPreferredAlgo('aead', [key1], undefined, undefined, { - ...openpgp.config, preferredAEADAlgorithm: openpgp.enums.aead.ocb + primaryUser.selfCertification.features = [9]; // Monkey-patch SEIPDv2 feature flag + primaryUser.selfCertification.preferredCipherSuites = [[9, 3], [9, 2]]; + const { symmetricAlgo, aeadAlgo } = await getPreferredCipherSuite([key1], undefined, undefined, { + ...openpgp.config, + aeadProtect: true, + preferredAEADAlgorithm: openpgp.enums.aead.gcm }); - expect(prefAlgo).to.equal(openpgp.enums.aead.ocb); - const supported = await isAEADSupported([key1]); - expect(supported).to.be.true; + expect(symmetricAlgo).to.equal(openpgp.enums.symmetric.aes256); + expect(aeadAlgo).to.equal(openpgp.enums.aead.gcm); }); - it("getPreferredAlgo('aead') - two key - one without pref", async function() { + it('getPreferredCipherSuite with AEAD - two keys - one without pref', async function() { const keys = await openpgp.readKeys({ armoredKeys: twoKeys }); const key1 = keys[0]; const key2 = keys[1]; const primaryUser = await key1.getPrimaryUser(); - primaryUser.selfCertification.features = [7]; // Monkey-patch AEAD feature flag - primaryUser.selfCertification.preferredAEADAlgorithms = [2,1]; + primaryUser.selfCertification.features = [9]; // Monkey-patch SEIPDv2 feature flag + primaryUser.selfCertification.preferredCipherSuites = [[9, 3], [9, 2]]; const primaryUser2 = await key2.getPrimaryUser(); - primaryUser2.selfCertification.features = [7]; // Monkey-patch AEAD feature flag - const prefAlgo = await getPreferredAlgo('aead', [key1, key2]); - expect(prefAlgo).to.equal(openpgp.enums.aead.eax); - const supported = await isAEADSupported([key1, key2]); - expect(supported).to.be.true; + primaryUser2.selfCertification.features = [9]; // Monkey-patch SEIPDv2 feature flag + const { symmetricAlgo, aeadAlgo } = await getPreferredCipherSuite([key1, key2], undefined, undefined, { + ...openpgp.config, + aeadProtect: true + }); + expect(symmetricAlgo).to.equal(openpgp.enums.symmetric.aes128); + expect(aeadAlgo).to.equal(openpgp.enums.aead.ocb); }); - it("getPreferredAlgo('aead') - two key - one with no support", async function() { + it('getPreferredCipherSuite with AEAD - two keys - one with no support', async function() { const keys = await openpgp.readKeys({ armoredKeys: twoKeys }); const key1 = keys[0]; const key2 = keys[1]; const primaryUser = await key1.getPrimaryUser(); - primaryUser.selfCertification.features = [7]; // Monkey-patch AEAD feature flag - primaryUser.selfCertification.preferredAEADAlgorithms = [2,1]; - const prefAlgo = await getPreferredAlgo('aead', [key1, key2]); - expect(prefAlgo).to.equal(openpgp.enums.aead.eax); - const supported = await isAEADSupported([key1, key2]); - expect(supported).to.be.false; + primaryUser.selfCertification.features = [9]; // Monkey-patch SEIPDv2 feature flag + primaryUser.selfCertification.preferredCipherSuites = [[9, 3], [9, 2]]; + const { symmetricAlgo, aeadAlgo } = await getPreferredCipherSuite([key1, key2], undefined, undefined, { + ...openpgp.config, + aeadProtect: true + }); + expect(symmetricAlgo).to.equal(openpgp.enums.symmetric.aes256); + expect(aeadAlgo).to.equal(undefined); }); it('User attribute packet read & write', async function() { diff --git a/test/general/openpgp.js b/test/general/openpgp.js index c0f19df8..16a2c949 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -11,7 +11,7 @@ import crypto from '../../src/crypto'; import * as random from '../../src/crypto/random.js'; import util from '../../src/util.js'; import keyIDType from '../../src/type/keyid.js'; -import { isAEADSupported } from '../../src/key'; +import { getPreferredCipherSuite } from '../../src/key'; import * as input from './testInputs.js'; @@ -3054,7 +3054,8 @@ XfA3pqV4mTzF it('should fail to decrypt modified message', async function() { const allowUnauthenticatedStream = openpgp.config.allowUnauthenticatedStream; const { privateKey: key } = await openpgp.generateKey({ userIDs: [{ email: 'test@email.com' }], format: 'object' }); - expect(await isAEADSupported([key])).to.equal(openpgp.config.aeadProtect); + const { aeadAlgo } = await getPreferredCipherSuite([key], undefined, undefined, openpgp.config); + expect(!!aeadAlgo).to.equal(openpgp.config.aeadProtect); const data = await openpgp.encrypt({ message: await openpgp.createMessage({ binary: new Uint8Array(500) }), encryptionKeys: [key.toPublic()] }); const encrypted = data.substr(0, 500) + (data[500] === 'a' ? 'b' : 'a') + data.substr(501); From 7e382e6e43d9867b3c3ccb3d04849743fde37b3a Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Fri, 17 Mar 2023 18:41:34 +0100 Subject: [PATCH 045/201] Add support for PKESK v6 Also, set version in PKESK constructor to null, requiring to explicitly set all fields. Co-authored-by: Lukas Burkhalter --- src/crypto/crypto.js | 2 +- src/message.js | 29 +++++-- src/openpgp.js | 2 +- .../public_key_encrypted_session_key.js | 84 +++++++++++++++---- test/general/openpgp.js | 34 ++++++++ test/general/packet.js | 2 + 6 files changed, 124 insertions(+), 29 deletions(-) diff --git a/src/crypto/crypto.js b/src/crypto/crypto.js index aa6e6f34..fa252a09 100644 --- a/src/crypto/crypto.js +++ b/src/crypto/crypto.js @@ -121,7 +121,7 @@ export async function publicKeyDecrypt(algo, publicKeyParams, privateKeyParams, const { A } = publicKeyParams; const { k } = privateKeyParams; const { ephemeralPublicKey, C } = sessionKeyParams; - if (!util.isAES(C.algorithm)) { + if (C.algorithm !== null && !util.isAES(C.algorithm)) { throw new Error('AES session key expected'); } return publicKey.elliptic.ecdhX.decrypt( diff --git a/src/message.js b/src/message.js index fac3eb96..ce103022 100644 --- a/src/message.js +++ b/src/message.js @@ -108,8 +108,6 @@ export class Message { * @async */ async decrypt(decryptionKeys, passwords, sessionKeys, date = new Date(), config = defaultConfig) { - const sessionKeyObjects = sessionKeys || await this.decryptSessionKeys(decryptionKeys, passwords, date, config); - const symEncryptedPacketlist = this.packets.filterByTag( enums.packet.symmetricallyEncryptedData, enums.packet.symEncryptedIntegrityProtectedData, @@ -121,14 +119,18 @@ export class Message { } const symEncryptedPacket = symEncryptedPacketlist[0]; + const expectedSymmetricAlgorithm = symEncryptedPacket.cipherAlgorithm; + + const sessionKeyObjects = sessionKeys || await this.decryptSessionKeys(decryptionKeys, passwords, expectedSymmetricAlgorithm, date, config); + let exception = null; const decryptedPromise = Promise.all(sessionKeyObjects.map(async ({ algorithm: algorithmName, data }) => { - if (!util.isUint8Array(data) || !util.isString(algorithmName)) { + if (!util.isUint8Array(data) || (!symEncryptedPacket.cipherAlgorithm && !util.isString(algorithmName))) { throw new Error('Invalid session key for decryption.'); } try { - const algo = enums.write(enums.symmetric, algorithmName); + const algo = symEncryptedPacket.cipherAlgorithm || enums.write(enums.symmetric, algorithmName); await symEncryptedPacket.decrypt(algo, data, config); } catch (e) { util.printDebugError(e); @@ -154,6 +156,7 @@ export class Message { * Decrypt encrypted session keys either with private keys or passwords. * @param {Array} [decryptionKeys] - Private keys with decrypted secret data * @param {Array} [passwords] - Passwords used to decrypt + * @param {enums.symmetric} [expectedSymmetricAlgorithm] - The symmetric algorithm the SEIPDv2 / AEAD packet is encrypted with (if applicable) * @param {Date} [date] - Use the given date for key verification, instead of current time * @param {Object} [config] - Full configuration, defaults to openpgp.config * @returns {Promise>} array of object with potential sessionKey, algorithm pairs * @async */ - async decryptSessionKeys(decryptionKeys, passwords, date = new Date(), config = defaultConfig) { + async decryptSessionKeys(decryptionKeys, passwords, expectedSymmetricAlgorithm, date = new Date(), config = defaultConfig) { let decryptedSessionKeyPackets = []; let exception; @@ -260,7 +263,8 @@ export class Message { } else { try { await pkeskPacket.decrypt(decryptionKeyPacket); - if (!algos.includes(enums.write(enums.symmetric, pkeskPacket.sessionKeyAlgorithm))) { + const symmetricAlgorithm = expectedSymmetricAlgorithm || pkeskPacket.sessionKeyAlgorithm; + if (symmetricAlgorithm && !algos.includes(enums.write(enums.symmetric, symmetricAlgorithm))) { throw new Error('A non-preferred symmetric algorithm was used.'); } decryptedSessionKeyPackets.push(pkeskPacket); @@ -294,7 +298,7 @@ export class Message { return decryptedSessionKeyPackets.map(packet => ({ data: packet.sessionKey, - algorithm: enums.read(enums.symmetric, packet.sessionKeyAlgorithm) + algorithm: packet.sessionKeyAlgorithm && enums.read(enums.symmetric, packet.sessionKeyAlgorithm) })); } throw exception || new Error('Session key decryption failed.'); @@ -350,7 +354,7 @@ export class Message { await Promise.all(encryptionKeys.map(key => key.getEncryptionKey() .catch(() => null) // ignore key strength requirements .then(maybeKey => { - if (maybeKey && (maybeKey.keyPacket.algorithm === enums.publicKey.x25519) && !util.isAES(symmetricAlgo)) { + if (maybeKey && (maybeKey.keyPacket.algorithm === enums.publicKey.x25519) && !aeadAlgoName && !util.isAES(symmetricAlgo)) { // if AEAD is defined, then PKESK v6 are used, and the algo info is encrypted throw new Error('Could not generate a session key compatible with the given `encryptionKeys`: X22519 keys can only be used to encrypt AES session keys; change `config.preferredSymmetricAlgorithm` accordingly.'); } }) @@ -430,7 +434,14 @@ export class Message { const results = await Promise.all(encryptionKeys.map(async function(primaryKey, i) { const encryptionKey = await primaryKey.getEncryptionKey(encryptionKeyIDs[i], date, userIDs, config); const pkESKeyPacket = new PublicKeyEncryptedSessionKeyPacket(); - pkESKeyPacket.publicKeyID = wildcard ? KeyID.wildcard() : encryptionKey.getKeyID(); + if (aeadAlgorithm) { + pkESKeyPacket.version = 6; + pkESKeyPacket.publicKeyVersion = wildcard ? 0 : encryptionKey.keyPacket.version; + pkESKeyPacket.publicKeyFingerprint = wildcard ? null : encryptionKey.keyPacket.getFingerprintBytes(); + } else { + pkESKeyPacket.version = 3; + pkESKeyPacket.publicKeyID = wildcard ? KeyID.wildcard() : encryptionKey.getKeyID(); + } pkESKeyPacket.publicKeyAlgorithm = encryptionKey.keyPacket.algorithm; pkESKeyPacket.sessionKey = sessionKey; pkESKeyPacket.sessionKeyAlgorithm = algorithm; diff --git a/src/openpgp.js b/src/openpgp.js index 223ebfdf..70dfd240 100644 --- a/src/openpgp.js +++ b/src/openpgp.js @@ -591,7 +591,7 @@ export async function decryptSessionKeys({ message, decryptionKeys, passwords, d const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`); try { - const sessionKeys = await message.decryptSessionKeys(decryptionKeys, passwords, date, config); + const sessionKeys = await message.decryptSessionKeys(decryptionKeys, passwords, undefined, date, config); return sessionKeys; } catch (err) { throw util.wrapError('Error decrypting session keys', err); diff --git a/src/packet/public_key_encrypted_session_key.js b/src/packet/public_key_encrypted_session_key.js index 231c62c7..02828b5e 100644 --- a/src/packet/public_key_encrypted_session_key.js +++ b/src/packet/public_key_encrypted_session_key.js @@ -21,8 +21,6 @@ import enums from '../enums'; import util from '../util'; import { UnsupportedError } from './packet'; -const VERSION = 3; - /** * Public-Key Encrypted Session Key Packets (Tag 1) * @@ -45,9 +43,16 @@ class PublicKeyEncryptedSessionKeyPacket { } constructor() { - this.version = 3; + this.version = null; + // For version 3: this.publicKeyID = new KeyID(); + + // For version 6: + this.publicKeyVersion = null; + this.publicKeyFingerprint = null; + + // For all versions: this.publicKeyAlgorithm = null; this.sessionKey = null; @@ -67,15 +72,39 @@ class PublicKeyEncryptedSessionKeyPacket { * @param {Uint8Array} bytes - Payload of a tag 1 packet */ read(bytes) { - let i = 0; - this.version = bytes[i++]; - if (this.version !== VERSION) { + let offset = 0; + this.version = bytes[offset++]; + if (this.version !== 3 && this.version !== 6) { throw new UnsupportedError(`Version ${this.version} of the PKESK packet is unsupported.`); } - i += this.publicKeyID.read(bytes.subarray(i)); - this.publicKeyAlgorithm = bytes[i++]; - this.encrypted = crypto.parseEncSessionKeyParams(this.publicKeyAlgorithm, bytes.subarray(i), this.version); - if (this.publicKeyAlgorithm === enums.publicKey.x25519) { + if (this.version === 6) { + // A one-octet size of the following two fields: + // - A one octet key version number. + // - The fingerprint of the public key or subkey to which the session key is encrypted. + // The size may also be zero. + const versionAndFingerprintLength = bytes[offset++]; + if (versionAndFingerprintLength) { + this.publicKeyVersion = bytes[offset++]; + const fingerprintLength = versionAndFingerprintLength - 1; + this.publicKeyFingerprint = bytes.subarray(offset, offset + fingerprintLength); offset += fingerprintLength; + if (this.publicKeyVersion >= 5) { + // For v5/6 the Key ID is the high-order 64 bits of the fingerprint. + this.publicKeyID.read(this.publicKeyFingerprint); + } else { + // For v4 The Key ID is the low-order 64 bits of the fingerprint. + this.publicKeyID.read(this.publicKeyFingerprint.subarray(-8)); + } + } else { + // The size may also be zero, and the key version and + // fingerprint omitted for an "anonymous recipient" + this.publicKeyID = KeyID.wildcard(); + } + } else { + offset += this.publicKeyID.read(bytes.subarray(offset, offset + 8)); + } + this.publicKeyAlgorithm = bytes[offset++]; + this.encrypted = crypto.parseEncSessionKeyParams(this.publicKeyAlgorithm, bytes.subarray(offset)); + if (this.version === 3 && this.publicKeyAlgorithm === enums.publicKey.x25519) { this.sessionKeyAlgorithm = enums.write(enums.symmetric, this.encrypted.C.algorithm); } } @@ -87,11 +116,27 @@ class PublicKeyEncryptedSessionKeyPacket { */ write() { const arr = [ - new Uint8Array([this.version]), - this.publicKeyID.write(), + new Uint8Array([this.version]) + ]; + + if (this.version === 6) { + if (this.publicKeyFingerprint !== null) { + arr.push(new Uint8Array([ + this.publicKeyFingerprint.length + 1, + this.publicKeyVersion] + )); + arr.push(this.publicKeyFingerprint); + } else { + arr.push(new Uint8Array([0])); + } + } else { + arr.push(this.publicKeyID.write()); + } + + arr.push( new Uint8Array([this.publicKeyAlgorithm]), crypto.serializeParams(this.publicKeyAlgorithm, this.encrypted) - ]; + ); return util.concatUint8Array(arr); } @@ -131,7 +176,7 @@ class PublicKeyEncryptedSessionKeyPacket { const { sessionKey, sessionKeyAlgorithm } = decodeSessionKey(this.version, this.publicKeyAlgorithm, decryptedData, randomSessionKey); // v3 Montgomery curves have cleartext cipher algo - if (this.publicKeyAlgorithm !== enums.publicKey.x25519) { + if (this.version === 3 && this.publicKeyAlgorithm !== enums.publicKey.x25519) { this.sessionKeyAlgorithm = sessionKeyAlgorithm; } this.sessionKey = sessionKey; @@ -149,7 +194,7 @@ function encodeSessionKey(version, keyAlgo, cipherAlgo, sessionKeyData) { case enums.publicKey.ecdh: { // add checksum return util.concatUint8Array([ - new Uint8Array([cipherAlgo]), + new Uint8Array(version === 6 ? [] : [cipherAlgo]), sessionKeyData, util.writeChecksum(sessionKeyData.subarray(sessionKeyData.length % 8)) ]); @@ -173,7 +218,9 @@ function decodeSessionKey(version, keyAlgo, decryptedData, randomSessionKey) { const checksum = decryptedData.subarray(decryptedData.length - 2); const computedChecksum = util.writeChecksum(result.subarray(result.length % 8)); const isValidChecksum = computedChecksum[0] === checksum[0] & computedChecksum[1] === checksum[1]; - const decryptedSessionKey = { sessionKeyAlgorithm: result[0], sessionKey: result.subarray(1) }; + const decryptedSessionKey = version === 6 ? + { sessionKeyAlgorithm: null, sessionKey: result } : + { sessionKeyAlgorithm: result[0], sessionKey: result.subarray(1) }; if (randomSessionKey) { // We must not leak info about the validity of the decrypted checksum or cipher algo. // The decrypted session key must be of the same algo and size as the random session key, otherwise we discard it and use the random data. @@ -182,14 +229,15 @@ function decodeSessionKey(version, keyAlgo, decryptedData, randomSessionKey) { decryptedSessionKey.sessionKey.length === randomSessionKey.sessionKey.length; return { sessionKey: util.selectUint8Array(isValidPayload, decryptedSessionKey.sessionKey, randomSessionKey.sessionKey), - sessionKeyAlgorithm: util.selectUint8( + sessionKeyAlgorithm: version === 6 ? null : util.selectUint8( isValidPayload, decryptedSessionKey.sessionKeyAlgorithm, randomSessionKey.sessionKeyAlgorithm ) }; } else { - const isValidPayload = isValidChecksum && enums.read(enums.symmetric, decryptedSessionKey.sessionKeyAlgorithm); + const isValidPayload = isValidChecksum && ( + version === 6 || enums.read(enums.symmetric, decryptedSessionKey.sessionKeyAlgorithm)); if (isValidPayload) { return decryptedSessionKey; } else { diff --git a/test/general/openpgp.js b/test/general/openpgp.js index 16a2c949..69260be9 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -1311,6 +1311,40 @@ VFBLG8uc9IiaKann/DYBAJcZNZHRSfpDoV2pUA5EAEi2MdjxkRysFQnYPRAu await expect(openpgp.decrypt(decOpt)).to.be.rejectedWith('Error decrypting message: Decryption key is not decrypted.'); }); + it('should decrypt test vector X25519-AEAD-OCB (PKESK v6, SEIPDv2)', async function() { + // test vector https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#appendix-A.8 + const armoredMessage = `-----BEGIN PGP MESSAGE----- + +wV0GIQYSyD8ecG9jCP4VGkF3Q6HwM3kOk+mXhIjR2zeNqZMIhRmHzxjV8bU/gXzO +WgBM85PMiVi93AZfJfhK9QmxfdNnZBjeo1VDeVZheQHgaVf7yopqR6W1FT6NOrfS +aQIHAgZhZBZTW+CwcW1g4FKlbExAf56zaw76/prQoN+bAzxpohup69LA7JW/Vp0l +yZnuSj3hcFj0DfqLTGgr4/u717J+sPWbtQBfgMfG9AOIwwrUBqsFE9zW+f1zdlYo +bhF30A+IitsxxA== +-----END PGP MESSAGE-----`; + + const privateKey = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xUsGY4d/4xsAAAAg+U2nu0jWCmHlZ3BqZYfQMxmZu52JGggkLq2EVD34laMAGXKB +exK+cH6NX1hs5hNhIB00TrJmosgv3mg1ditlsLfCsQYfGwoAAABCBYJjh3/jAwsJ +BwUVCg4IDAIWAAKbAwIeCSIhBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce6 +2azJBScJAgcCAAAAAK0oIBA+LX0ifsDm185Ecds2v8lwgyU2kCcUmKfvBXbAf6rh +RYWzuQOwEn7E/aLwIwRaLsdry0+VcallHhSu4RN6HWaEQsiPlR4zxP/TP7mhfVEe +7XWPxtnMUMtf15OyA51YBMdLBmOHf+MZAAAAIIaTJINn+eUBXbki+PSAld2nhJh/ +LVmFsS+60WyvXkQ1AE1gCk95TUR3XFeibg/u/tVY6a//1q0NWC1X+yui3O24wpsG +GBsKAAAALAWCY4d/4wKbDCIhBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce6 +2azJAAAAAAQBIKbpGG2dWTX8j+VjFM21J0hqWlEg+bdiojWnKfA5AQpWUWtnNwDE +M0g12vYxoWM8Y81W+bHBw805I8kWVkXU6vFOi+HWvv/ira7ofJu16NnoUkhclkUr +k0mXubZvyl4GBg== +-----END PGP PRIVATE KEY BLOCK-----` }); + + const { data: decryptedData } = await openpgp.decrypt({ + message: await openpgp.readMessage({ armoredMessage }), + decryptionKeys: privateKey + }); + + expect(decryptedData).to.equal('Hello, world!'); + }); + it('decrypt/verify should succeed with valid signature (expectSigned=true)', async function () { const publicKey = await openpgp.readKey({ armoredKey: pub_key }); const privateKey = await openpgp.decryptKey({ diff --git a/test/general/packet.js b/test/general/packet.js index 11397a45..0e1cdaab 100644 --- a/test/general/packet.js +++ b/test/general/packet.js @@ -474,6 +474,7 @@ export default () => describe('Packet', function() { return crypto.generateParams(rsa, keySize, 65537).then(function({ publicParams, privateParams }) { const enc = new openpgp.PublicKeyEncryptedSessionKeyPacket(); + enc.version = 3; const msg = new openpgp.PacketList(); const msg2 = new openpgp.PacketList(); @@ -523,6 +524,7 @@ export default () => describe('Packet', function() { key = key[0]; const enc = new openpgp.PublicKeyEncryptedSessionKeyPacket(); + enc.version = 3; const secret = new Uint8Array([1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2]); enc.sessionKey = secret; From 0e08abb3e210231cabd7946f7a1d16a438761584 Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Sat, 18 Mar 2023 00:30:30 +0100 Subject: [PATCH 046/201] When decrypting a v6 PKESK in constant-time, use the v2 SEIPD algorithm Rather than using the config to determine which algorithms to try to decrypt session keys for, try the algorithm we know the message was encrypted with. --- src/message.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/message.js b/src/message.js index ce103022..44d69a1c 100644 --- a/src/message.js +++ b/src/message.js @@ -243,7 +243,11 @@ export class Message { // NB: as a result, if the data is encrypted with a non-suported cipher, decryption will always fail. const serialisedPKESK = pkeskPacket.write(); // make copies to be able to decrypt the PKESK packet multiple times - await Promise.all(Array.from(config.constantTimePKCS1DecryptionSupportedSymmetricAlgorithms).map(async sessionKeyAlgorithm => { + await Promise.all(( + expectedSymmetricAlgorithm ? + [expectedSymmetricAlgorithm] : + Array.from(config.constantTimePKCS1DecryptionSupportedSymmetricAlgorithms) + ).map(async sessionKeyAlgorithm => { const pkeskPacketCopy = new PublicKeyEncryptedSessionKeyPacket(); pkeskPacketCopy.read(serialisedPKESK); const randomSessionKey = { From 33af3debc41b7e04bcffb5037fdf23c002de1889 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Wed, 5 Apr 2023 00:53:04 +0200 Subject: [PATCH 047/201] Throw intelligible error on GCM authentication failure, fix/refactor test for modification detection on decryption Also, address race condition in error handling as part of AEAD message decryption, which would cause non-uniform errors during testing. --- src/crypto/mode/gcm.js | 10 +- .../sym_encrypted_integrity_protected_data.js | 2 + test/general/openpgp.js | 140 +++++++++++------- 3 files changed, 96 insertions(+), 56 deletions(-) diff --git a/src/crypto/mode/gcm.js b/src/crypto/mode/gcm.js index a3cbd941..b482a5dc 100644 --- a/src/crypto/mode/gcm.js +++ b/src/crypto/mode/gcm.js @@ -84,8 +84,14 @@ async function GCM(cipher, key) { if (webcryptoEmptyMessagesUnsupported && ct.length === tagLength) { return AES_GCM.decrypt(ct, key, iv, adata); } - const pt = await webCrypto.decrypt({ name: ALGO, iv, additionalData: adata, tagLength: tagLength * 8 }, _key, ct); - return new Uint8Array(pt); + try { + const pt = await webCrypto.decrypt({ name: ALGO, iv, additionalData: adata, tagLength: tagLength * 8 }, _key, ct); + return new Uint8Array(pt); + } catch (e) { + if (e.name === 'OperationError') { + throw new Error('Authentication tag mismatch'); + } + } } }; } catch (err) { diff --git a/src/packet/sym_encrypted_integrity_protected_data.js b/src/packet/sym_encrypted_integrity_protected_data.js index 3f462c90..1718e214 100644 --- a/src/packet/sym_encrypted_integrity_protected_data.js +++ b/src/packet/sym_encrypted_integrity_protected_data.js @@ -260,6 +260,7 @@ export async function runAEAD(packet, fn, key, data) { if (!chunkIndex || chunk.length) { reader.unshift(finalChunk); cryptedPromise = modeInstance[fn](chunk, nonce, adataArray); + cryptedPromise.catch(() => {}); queuedBytes += chunk.length - tagLengthIfDecrypting + tagLengthIfEncrypting; } else { // After the last chunk, we either encrypt a final, empty @@ -267,6 +268,7 @@ export async function runAEAD(packet, fn, key, data) { // validate that final authentication tag. adataView.setInt32(5 + chunkIndexSizeIfAEADEP + 4, cryptedBytes); // Should be setInt64(5 + chunkIndexSizeIfAEADEP, ...) cryptedPromise = modeInstance[fn](finalChunk, nonce, adataTagArray); + cryptedPromise.catch(() => {}); queuedBytes += tagLengthIfEncrypting; done = true; } diff --git a/test/general/openpgp.js b/test/general/openpgp.js index 69260be9..98c6a3c6 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -15,7 +15,6 @@ import { getPreferredCipherSuite } from '../../src/key'; import * as input from './testInputs.js'; -const detectNode = () => typeof globalThis.process === 'object' && typeof globalThis.process.versions === 'object'; const detectBrowser = () => typeof navigator === 'object'; const pub_key = [ @@ -2331,7 +2330,7 @@ XfA3pqV4mTzF if: true, beforeEach: function() { openpgp.config.aeadProtect = true; - openpgp.config.preferredAEADAlgorithm = openpgp.enums.aead.experimentalGCM; + openpgp.config.preferredAEADAlgorithm = openpgp.enums.aead.gcm; openpgp.config.v6Keys = true; // Monkey-patch SEIPD V2 feature flag @@ -2346,6 +2345,7 @@ XfA3pqV4mTzF beforeEach: function() { openpgp.config.aeadProtect = true; openpgp.config.aeadChunkSizeByte = 0; + openpgp.config.preferredAEADAlgorithm = openpgp.enums.aead.eax; // Monkey-patch SEIPD V2 feature flag publicKey.users[0].selfCertifications[0].features = [9]; @@ -2355,7 +2355,7 @@ XfA3pqV4mTzF }); tryTests('OCB mode', tests, { - if: !openpgp.config.ci, + if: true, beforeEach: function() { openpgp.config.aeadProtect = true; openpgp.config.preferredAEADAlgorithm = openpgp.enums.aead.ocb; @@ -3086,60 +3086,92 @@ XfA3pqV4mTzF }); it('should fail to decrypt modified message', async function() { - const allowUnauthenticatedStream = openpgp.config.allowUnauthenticatedStream; - const { privateKey: key } = await openpgp.generateKey({ userIDs: [{ email: 'test@email.com' }], format: 'object' }); - const { aeadAlgo } = await getPreferredCipherSuite([key], undefined, undefined, openpgp.config); - expect(!!aeadAlgo).to.equal(openpgp.config.aeadProtect); - - const data = await openpgp.encrypt({ message: await openpgp.createMessage({ binary: new Uint8Array(500) }), encryptionKeys: [key.toPublic()] }); - const encrypted = data.substr(0, 500) + (data[500] === 'a' ? 'b' : 'a') + data.substr(501); await loadStreamsPolyfill(); - try { - for (const allowStreaming of [true, false]) { - openpgp.config.allowUnauthenticatedStream = allowStreaming; - for (const [i, encryptedData] of [ - encrypted, - new ReadableStream({ - start(controller) { - controller.enqueue(encrypted); - controller.close(); - } - }), - new ReadableStream({ - start() { - this.remaining = encrypted.split('\n'); - }, - async pull(controller) { - if (this.remaining.length) { - await new Promise(res => setTimeout(res)); - controller.enqueue(this.remaining.shift() + '\n'); - } else { - controller.close(); - } - } - }) - ].entries()) { - let stepReached = 0; - try { - const message = await openpgp.readMessage({ armoredMessage: encryptedData }); - stepReached = 1; - const { data: decrypted } = await openpgp.decrypt({ message: message, decryptionKeys: [key] }); - stepReached = 2; - await stream.readToEnd(decrypted); - } catch (e) { - expect(e.message).to.match(/Modification detected|Authentication tag mismatch|Unsupported state or unable to authenticate data/); - expect(stepReached).to.equal( - i === 0 ? 1 : - (openpgp.config.aeadChunkSizeByte === 0 && (i === 2 || detectNode() || util.getHardwareConcurrency() < 8)) || (!openpgp.config.aeadProtect && openpgp.config.allowUnauthenticatedStream) ? 2 : - 1 - ); - continue; - } - throw new Error(`Expected "Modification detected" error in subtest ${i}`); + // need to generate new key with AEAD support + const { privateKey } = await openpgp.generateKey({ userIDs: [{ email: 'test@email.com' }], type: 'rsa', format: 'object' }); + const { aeadAlgo } = await getPreferredCipherSuite([privateKey], undefined, undefined, openpgp.config); + // sanity check + expect(aeadAlgo).to.equal(openpgp.config.aeadProtect ? openpgp.config.preferredAEADAlgorithm : undefined); + + const encrypted = await openpgp.encrypt({ + message: await openpgp.createMessage({ binary: new Uint8Array(500) }), + encryptionKeys: privateKey + }); + // corrupt the SEIPD packet + const encryptedCorrupted = encrypted.substr(0, 1000) + (encrypted[1000] === 'a' ? 'b' : 'a') + encrypted.substr(1001); + + const generateSingleChunkStream = () => ( + new ReadableStream({ + start(controller) { + controller.enqueue(encryptedCorrupted); + controller.close(); } + }) + ); + const generateMultiChunkStream = () => ( + new ReadableStream({ + start() { + this.remaining = encryptedCorrupted.split('\n'); + }, + async pull(controller) { + if (this.remaining.length) { + // sleep to slow down enqeueing + await new Promise(resolve => { setTimeout(resolve); }); + controller.enqueue(this.remaining.shift() + '\n'); + } else { + controller.close(); + } + } + }) + ); + + if (openpgp.config.aeadProtect) { + const expectedError = /Authentication tag mismatch|Unsupported state or unable to authenticate data/; + // AEAD fails either on AEAD chunk decryption or when reading the decrypted stream: + // if the corruption is in the first AEAD chunk, then `openpgp.decrypt` will throw + // when reading the decrypted stream to parse the packet list. + await Promise.all([ + testStreamingDecryption(encryptedCorrupted, true, expectedError, true), + testStreamingDecryption(encryptedCorrupted, false, expectedError, true), + // `config.allowUnauthenticatedStream` does not apply to AEAD + testStreamingDecryption(generateSingleChunkStream(), true, expectedError, openpgp.config.aeadChunkSizeByte > 0), + testStreamingDecryption(generateSingleChunkStream(), false, expectedError, openpgp.config.aeadChunkSizeByte > 0), + // Increasing number of streaming chunks should not affect the result + testStreamingDecryption(generateMultiChunkStream(), true, expectedError, openpgp.config.aeadChunkSizeByte > 0), + testStreamingDecryption(generateMultiChunkStream(), false, expectedError, openpgp.config.aeadChunkSizeByte > 0) + ]); + } else { + const expectedError = /Modification detected/; + await Promise.all([ + testStreamingDecryption(encryptedCorrupted, true, expectedError, true), + testStreamingDecryption(encryptedCorrupted, false, expectedError, true), + testStreamingDecryption(generateSingleChunkStream(), true, expectedError, false), + testStreamingDecryption(generateSingleChunkStream(), false, expectedError, true), + // Increasing number of streaming chunks should not affect the result + testStreamingDecryption(generateMultiChunkStream(), true, expectedError, false), + testStreamingDecryption(generateMultiChunkStream(), false, expectedError, true) + ]); + } + + async function testStreamingDecryption(encryptedDataOrStream, allowUnauthenticatedStream, expectedErrorMessage, expectedFailureOnDecrypt = null) { + // parsing the message won't fail since armor checksum is ignored + const message = await openpgp.readMessage({ armoredMessage: encryptedDataOrStream }); + let didFailOnDecrypt = true; + + try { + const { data: decrypted } = await openpgp.decrypt({ + message, + decryptionKeys: [privateKey], + config: { allowUnauthenticatedStream } + }); + didFailOnDecrypt = false; + await stream.readToEnd(decrypted); + // expected to have thrown + throw new Error(`Expected decryption to fail with error ${expectedErrorMessage}`); + } catch (e) { + expect(e.message).to.match(expectedErrorMessage); + expect(didFailOnDecrypt).to.equal(expectedFailureOnDecrypt); } - } finally { - openpgp.config.allowUnauthenticatedStream = allowUnauthenticatedStream; } }); From 21343f2bb8b4be159d1b6da57e539af712336019 Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Thu, 6 Apr 2023 11:57:50 +0200 Subject: [PATCH 048/201] Appease linter --- src/encoding/armor.js | 23 ++++++++----------- src/message.js | 4 ++-- src/packet/padding.js | 2 +- .../sym_encrypted_integrity_protected_data.js | 2 +- 4 files changed, 13 insertions(+), 18 deletions(-) diff --git a/src/encoding/armor.js b/src/encoding/armor.js index daff2d4d..0e0aa5ae 100644 --- a/src/encoding/armor.js +++ b/src/encoding/armor.js @@ -128,24 +128,21 @@ function verifyHeaders(headers) { } /** - * Splits a message into two parts, the body and the checksum. This is an internal function - * @param {String} text - OpenPGP armored message part - * @returns {Object} An object with attribute "body" containing the body. - * and an attribute "checksum" containing the checksum. + * Remove the (optional) checksum from an armored message. + * @param {String} text - OpenPGP armored message + * @returns {String} The body of the armored message. * @private */ -function splitChecksum(text) { +function removeChecksum(text) { let body = text; - let checksum = ''; const lastEquals = text.lastIndexOf('='); if (lastEquals >= 0 && lastEquals !== text.length - 1) { // '=' as the last char means no checksum body = text.slice(0, lastEquals); - checksum = text.slice(lastEquals + 1).substr(0, 4); } - return { body: body, checksum: checksum }; + return body; } /** @@ -157,7 +154,7 @@ function splitChecksum(text) { * @async * @static */ -export function unarmor(input, config = defaultConfig) { +export function unarmor(input) { // eslint-disable-next-line no-async-promise-executor return new Promise(async (resolve, reject) => { try { @@ -170,8 +167,7 @@ export function unarmor(input, config = defaultConfig) { let headersDone; let text = []; let textDone; - let checksum; - let data = base64.decode(stream.transformPair(input, async (readable, writable) => { + const data = base64.decode(stream.transformPair(input, async (readable, writable) => { const reader = stream.getReader(readable); try { while (true) { @@ -236,9 +232,8 @@ export function unarmor(input, config = defaultConfig) { if (parts.length === 1) { throw new Error('Misformed armored text'); } - const split = splitChecksum(parts[0].slice(0, -1)); - checksum = split.checksum; - await writer.write(split.body); + const body = removeChecksum(parts[0].slice(0, -1)); + await writer.write(body); break; } } diff --git a/src/message.js b/src/message.js index 44d69a1c..2ce9f627 100644 --- a/src/message.js +++ b/src/message.js @@ -245,8 +245,8 @@ export class Message { const serialisedPKESK = pkeskPacket.write(); // make copies to be able to decrypt the PKESK packet multiple times await Promise.all(( expectedSymmetricAlgorithm ? - [expectedSymmetricAlgorithm] : - Array.from(config.constantTimePKCS1DecryptionSupportedSymmetricAlgorithms) + [expectedSymmetricAlgorithm] : + Array.from(config.constantTimePKCS1DecryptionSupportedSymmetricAlgorithms) ).map(async sessionKeyAlgorithm => { const pkeskPacketCopy = new PublicKeyEncryptedSessionKeyPacket(); pkeskPacketCopy.read(serialisedPKESK); diff --git a/src/packet/padding.js b/src/packet/padding.js index b60e1e4b..567ef2e5 100644 --- a/src/packet/padding.js +++ b/src/packet/padding.js @@ -37,7 +37,7 @@ class PaddingPacket { * Read a padding packet * @param {Uint8Array | ReadableStream} bytes */ - read(bytes) { + read(bytes) { // eslint-disable-line no-unused-vars // Padding packets are ignored, so this function is never called. } diff --git a/src/packet/sym_encrypted_integrity_protected_data.js b/src/packet/sym_encrypted_integrity_protected_data.js index 1718e214..8aedf18d 100644 --- a/src/packet/sym_encrypted_integrity_protected_data.js +++ b/src/packet/sym_encrypted_integrity_protected_data.js @@ -72,7 +72,7 @@ class SymEncryptedIntegrityProtectedDataPacket { this.version = await reader.readByte(); // - A one-octet version number with value 1 or 2. if (this.version !== 1 && this.version !== 2) { - throw new UnsupportedError(`Version ${version} of the SEIP packet is unsupported.`); + throw new UnsupportedError(`Version ${this.version} of the SEIP packet is unsupported.`); } if (this.version === 2) { From 95fd04db8e13a157c1115fbfc3b6fcde5100dba0 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Thu, 6 Apr 2023 18:00:14 +0200 Subject: [PATCH 049/201] Support AEAD encryption for v4 and v6 private keys --- src/packet/secret_key.js | 80 ++++++++++++++---- test/general/key.js | 171 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 233 insertions(+), 18 deletions(-) diff --git a/src/packet/secret_key.js b/src/packet/secret_key.js index d3e8616f..dc5b853d 100644 --- a/src/packet/secret_key.js +++ b/src/packet/secret_key.js @@ -21,7 +21,8 @@ import crypto from '../crypto'; import enums from '../enums'; import util from '../util'; import defaultConfig from '../config'; -import { UnsupportedError } from './packet'; +import { UnsupportedError, writeTag } from './packet'; +import computeHKDF from '../crypto/hkdf'; /** * A Secret-Key packet contains all the information that is found in a @@ -140,14 +141,27 @@ class SecretKeyPacket extends PublicKeyPacket { this.symmetric = this.s2kUsage; } - // - [Optional] If secret data is encrypted (string-to-key usage octet - // not zero), an Initial Vector (IV) of the same length as the - // cipher's block size. + if (this.s2kUsage) { - this.iv = bytes.subarray( - i, - i + crypto.getCipher(this.symmetric).blockSize - ); + // - crypto-refresh: If string-to-key usage octet was 255, 254 [..], an initialization vector (IV) + // of the same length as the cipher's block size. + // - RFC4880bis (v5 keys, regardless of AEAD): an Initial Vector (IV) of the same length as the + // cipher's block size. If string-to-key usage octet was 253 the IV is used as the nonce for the AEAD algorithm. + // If the AEAD algorithm requires a shorter nonce, the high-order bits of the IV are used and the remaining bits MUST be zero + if (this.s2kUsage !== 253 || this.version === 5) { + this.iv = bytes.subarray( + i, + i + crypto.getCipher(this.symmetric).blockSize + ); + } else { + // crypto-refresh: If string-to-key usage octet was 253 (that is, the secret data is AEAD-encrypted), + // an initialization vector (IV) of size specified by the AEAD algorithm (see Section 5.13.2), which + // is used as the nonce for the AEAD algorithm. + this.iv = bytes.subarray( + i, + i + crypto.getAEADMode(this.aead).ivLength + ); + } i += this.iv.length; } @@ -342,19 +356,28 @@ class SecretKeyPacket extends PublicKeyPacket { this.s2k.generateSalt(); const cleartext = crypto.serializeParams(this.algorithm, this.privateParams); this.symmetric = enums.symmetric.aes256; - const key = await produceEncryptionKey(this.s2k, passphrase, this.symmetric); const { blockSize } = crypto.getCipher(this.symmetric); - this.iv = crypto.random.getRandomBytes(blockSize); if (config.aeadProtect) { this.s2kUsage = 253; this.aead = enums.aead.eax; const mode = crypto.getAEADMode(this.aead); + + const serializedPacketTag = writeTag(this.constructor.tag); + const key = await produceEncryptionKey(this.version, this.s2k, passphrase, this.symmetric, this.aead, serializedPacketTag); + const modeInstance = await mode(this.symmetric, key); - this.keyMaterial = await modeInstance.encrypt(cleartext, this.iv.subarray(0, mode.ivLength), new Uint8Array()); + this.iv = (this.version === 5) ? crypto.random.getRandomBytes(blockSize) : crypto.random.getRandomBytes(mode.ivLength); + const associateData = this.version === 5 ? + new Uint8Array() : + util.concatUint8Array([serializedPacketTag, this.writePublicKey()]); + + this.keyMaterial = await modeInstance.encrypt(cleartext, this.iv.subarray(0, mode.ivLength), associateData); } else { this.s2kUsage = 254; + const key = await produceEncryptionKey(this.version, this.s2k, passphrase, this.symmetric); + this.iv = crypto.random.getRandomBytes(blockSize); this.keyMaterial = await crypto.mode.cfb.encrypt(this.symmetric, key, util.concatUint8Array([ cleartext, await crypto.hash.sha1(cleartext, config) @@ -385,8 +408,10 @@ class SecretKeyPacket extends PublicKeyPacket { } let key; + const serializedPacketTag = writeTag(this.constructor.tag); // relevant for AEAD only if (this.s2kUsage === 254 || this.s2kUsage === 253) { - key = await produceEncryptionKey(this.s2k, passphrase, this.symmetric); + key = await produceEncryptionKey( + this.version, this.s2k, passphrase, this.symmetric, this.aead, serializedPacketTag); } else if (this.s2kUsage === 255) { throw new Error('Encrypted private key is authenticated using an insecure two-byte hash'); } else { @@ -398,7 +423,10 @@ class SecretKeyPacket extends PublicKeyPacket { const mode = crypto.getAEADMode(this.aead); const modeInstance = await mode(this.symmetric, key); try { - cleartext = await modeInstance.decrypt(this.keyMaterial, this.iv.subarray(0, mode.ivLength), new Uint8Array()); + const associateData = this.version === 5 ? + new Uint8Array() : + util.concatUint8Array([serializedPacketTag, this.writePublicKey()]); + cleartext = await modeInstance.decrypt(this.keyMaterial, this.iv.subarray(0, mode.ivLength), associateData); } catch (err) { if (err.message === 'Authentication tag mismatch') { throw new Error('Incorrect key passphrase: ' + err.message); @@ -425,6 +453,8 @@ class SecretKeyPacket extends PublicKeyPacket { this.isEncrypted = false; this.keyMaterial = null; this.s2kUsage = 0; + this.aead = null; + this.symmetric = null; } /** @@ -478,9 +508,27 @@ class SecretKeyPacket extends PublicKeyPacket { } } -async function produceEncryptionKey(s2k, passphrase, algorithm) { - const { keySize } = crypto.getCipher(algorithm); - return s2k.produceKey(passphrase, keySize); +/** + * Derive encryption key + * @param {Number} keyVersion - key derivation differs for v5 keys + * @param {module:type/s2k} s2k + * @param {String} passphrase + * @param {module:enums.symmetric} cipherAlgo + * @param {module:enums.aead} [aeadMode] - for AEAD-encrypted keys only (excluding v5) + * @param {Uint8Array} serializedPacketTag - for AEAD-encrypted keys only (excluding v5) + * @returns encryption key + */ +async function produceEncryptionKey(keyVersion, s2k, passphrase, cipherAlgo, aeadMode, serializedPacketTag) { + const { keySize } = crypto.getCipher(cipherAlgo); + const derivedKey = await s2k.produceKey(passphrase, keySize); + if (!aeadMode || keyVersion === 5) { + return derivedKey; + } + const info = util.concatUint8Array([ + serializedPacketTag, + new Uint8Array([keyVersion, cipherAlgo, aeadMode]) + ]); + return computeHKDF(enums.hash.sha256, derivedKey, new Uint8Array(), info, keySize); } export default SecretKeyPacket; diff --git a/test/general/key.js b/test/general/key.js index 9ed68d97..68d956d5 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -4,6 +4,7 @@ import { use as chaiUse, expect } from 'chai'; import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import chaiUse(chaiAsPromised); +import sinon from 'sinon'; import openpgp from '../initOpenpgp.js'; import util from '../../src/util.js'; import { getPreferredCipherSuite } from '../../src/key'; @@ -2912,7 +2913,7 @@ export default () => describe('Key', function() { let aeadProtectVal; tryTests('V4', versionSpecificTests, { - if: !openpgp.config.ci, + if: true, beforeEach: function() { v6KeysVal = openpgp.config.v6Keys; openpgp.config.v6Keys = false; @@ -2923,7 +2924,7 @@ export default () => describe('Key', function() { }); tryTests('V6', versionSpecificTests, { - if: !openpgp.config.ci, + if: true, beforeEach: function() { v6KeysVal = openpgp.config.v6Keys; aeadProtectVal = openpgp.config.aeadProtect; @@ -2987,6 +2988,172 @@ export default () => describe('Key', function() { expect(key).to.exist; }); + it('Parsing, decrypting, encrypting and serializing V5 key (AEAD-encrypted)', async function() { + const armoredKey = `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xYwFZC7tvxYAAAAtCSsGAQQB2kcPAQEHQP/d1oBAqCKZYxb6k8foyX2Aa/VK +dHFymZPGvHRk1ncs/R0JAQMIrDnS3Bany9EAF6dwQSfPSdObc4ROYIMAnwAA +ADKV1OhGzwANnapimvODI6fK5F7/V0GxETY9WmnipnBzr4Fe9GZw4QD4Q4hd +IJMawjUBrs0MdjVAYWVhZC50ZXN0wpIFEBYKAEQFgmQu7b8ECwkHCAMVCAoE +FgACAQIZAQKbAwIeByKhBQ/Y89PNwfdXUdI/td5Q9rNrYP9mb7Dg6k/3nxTg +ugQ5AyIBAgAAf0kBAJv0OQvd4u8R0f3HAsmQeqMnwNA4or75BOn/ieApNZUt +AP9kQVmYEk4+MV57Us15l2kQEslLDr3qiH5+VCICdEprB8eRBWQu7b8SAAAA +MgorBgEEAZdVAQUBAQdA4IgEkfze3eNKRz6DgzGSJxw/CV/5Rp5u4Imn47h7 +pyADAQgH/R0JAQMIwayD3R4E0ugAyszSmOIpaLJ40YGBp5uU7wAAADKmSv4W +tio7GfZCVl8eJ7xX3J1b0iMvEm876tUeHANQlYYCWz+2ahmPVe79zzZA9OhN +FcJ6BRgWCAAsBYJkLu2/ApsMIqEFD9jz083B91dR0j+13lD2s2tg/2ZvsODq +T/efFOC6BDkAAHcjAPwIPNHnR9bKmkVop6cE05dCIpZ/W8zXDGnjKYrrC4Hb +4gEAmISD1GRkNOmCV8aHwN5svO6HuwXR4cR3o3l7HlYeag8= +=wpkQ +-----END PGP PRIVATE KEY BLOCK-----`; + const passphrase = 'password'; + const encryptedKey = await openpgp.readKey({ armoredKey }); + const decryptedKey = await openpgp.decryptKey({ + privateKey: encryptedKey, + passphrase + }); + const reecryptedKey = await openpgp.encryptKey({ + privateKey: decryptedKey, + passphrase, + config: { aeadProtect: true } + }); + expect(reecryptedKey.keyPacket.s2kUsage).to.equal(253); + const redecryptedKey = await openpgp.decryptKey({ + privateKey: reecryptedKey, + passphrase + }); + expect(redecryptedKey.write()).to.deep.equal(decryptedKey.write()); + }); + + it('Parsing, decrypting, encrypting and serializing V4 key (AEAD-encrypted)', async function() { + // key from gopenpgp + const armoredKey = `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xcMIBGQuuRABCADm+/vQI1Memff31qyXxdB4Z14hnF+Bu7RirXpYNjM07CcGTDdT +vj1AmZNR0o3G1vvbAUp2jWxquWq+8C//NJn13Axrg3R599j3+1TL+9vlwmgSJJdT +SjQkSUjlkJpZQJPfkk0tngLBQGwlEJJLOlnWLfCc1eTh5x/cjO5E/jOOHwSHNgBp +mhpKO/k6bAdgyB6jAYOJKI6TZE0JNc2+ZGSjr5EdwEs8sGDT2nMgn3oectuZO4y8 +tmFzNvAY9oQD0T4wmqwZ8evzlgRkCMRrdKCCdHfYdluQuRJb2WOWoV03PRaPfRQS +k2SiNSKYhQF2tnybd1BgnAiPcwa4dJtn1IWrABEBAAH9BwME1X5xBykUBjyv9kd4 +gx/UewMEEHfi7UejYVJhtGf63vgzp98C00CiDkYbCJXh2Io4Pro1lP7J75hm7zyf +1VuNQbd8dx2IEcig8OpF+tlH14U+YexVrbm1rX/vBg0BZrqO87HU+ILiZFpGV/tF +9GeLPBLLCyIqvb/PzP0hiqEHP84xBkIIOEY+PZJoXGpfA7TUNsGpVS9ySpGWxCny +nsjv9Lnv2NVtfaaA8YoQl7GJbI/Qh9wx/wtiqE8sVuH9ddFdFGSvjhrLSu58jPIv +9SBdMjI/WHVlqVXkAXpEPBlmpn4xgffW3HDAx19YuwHEVjrsLUISBi1PodfAieT/ +cdtqejiFLQv8zQkTOz/J59yUy+OUZ3SKBM3vRPf0lxSUAoNNYrvg0gNd6qpCNChN +z7LjNkUjgDp0DorPtTLT4FS/O/kB25K69CxkUeOyk3i+p3fqr/9wz0gFpRW5pkLa +Hi3T5gjT4O1kTyGeoetGKwbdzfLisc981ynqKhlLdBw0R0hMpalak3NOf3QUjZEu +10TFHhGUuCJVNbluQwVSD9e5znu5IBxawo8yHcV8OEIcc8wS1TuJer/cWj9zf/3Y +C/l5Gngwa99YE8nrZdhKlra0viiAvpPqJs61pOzGj5NoKoEPDWB26TpbrPGFyKu6 +EY8Uz1SNo+Zn42w1g4KTA2x4LPdyblYlea5RRqodqot9hgRMVy758QwMBmoLzwn3 +sSOZeasCF5pw4a1Trr+Qupy0N+TyoCvt7hlP3qt12+8Y7ObB5hAk9YHlWB/mXeGK +APA0n6o2eTKBrXcjAk600nn30BH93GQ88LxwPsF2IKcwqf8sBlm3IPzmQUbGTtfr +lcm7PTipnN9NyGZrimbS9Eujp6IEAQGsPT9VqWBf2xM18kLnkYWO3Q+iQxhoyeHU +R+SpZ3rzZ7dqJKzNF2R1bW15IDxkdW1teUB0ZXN0LnRlc3Q+wsCLBBMBCAA/BQJk +LrkQCZD/Lbr4zUX6OxYhBEJ8H0lz9aZ8pbX+hP8tuvjNRfo7AhsDAh4JAhkBAgsH +AhUIAhYABScHAwcCAAA3RAgA2+RQ/U9FYhTghvU/2r/SDiL1BRA+TOOwDKyxLKKm +J9j/f/GSon74YqZmWSZTWLgDxXGXO0+I9Mz029qEs/tQTcFrulJcxY6V5B6ci+Wv +J9+7A4UDz7wk30jb0FKT6NDhw/w2UbI5tf9aUY+iKxqcvDI3zBL3AMkILPKK+kXw +dq5DvbRIh3oUcD3+xhEnlkBWbB9oUcQC0QdC9bHdPNTPGNJLQozo+cSq/VMYn5Bj +RPJQSoSA6BJa4omdNi1GkVoYNmnBVi8W+DnqgwwOxOhlbTRHyhoKC8pbGC/ty/qd +HLWrGbFXOcl1cVio85zT74q98v+tL6CEKDHTire1tbKhy8fDCARkLrkQAQgAwbzO +crec+eXvoxyL/woFffGBKoMICXFGYiZvd0mI7iMYDRy2oVBIZuT5fAorSfc8PUYS +lljlV7LP9WW1/IA9oPRSTj0bywqZrxRVaIzBqoXNtpujnyPpFHDzubxkNr+WcbmQ +KufphQMolp2p0LQ7C6c6ssAKS6ue8mNJ1KRvdvRXMUqop+fGaEKoec+PgRUwIKDq +sLVAzGtGkJTC2J0w9673ZzxlbejHj/g/eEHFSwTm92E2q2UbSoJLV7dtpAR4y1i3 +GTZSNsPm3Wngn4C8AQtuZyqcFJiTvcrMJDptRsQ9pwkyDquEd0fsJel5pY1WQiXr +g4UZDLQ4QmIIwFdbnwARAQAB/QcDBOMwz+uO8Knhstz1WDIJvPoDBBA+WqgPij7y +RQz9nTftmWIPUVvrOC49h66Smv3eDVikCq2ibFj6znpvDZgp7LWly0OAfHLHf/qg +4x7ld0miXTSe4ZeCTo2qsh8gKqqW/CLgSgnixSjdyyqHBLvCS3dPbwrjjeI+qPuS +EcuDzRqDhwfs6eUCei2lDwOYlm69WkT73Ll2EoJUZOVkxrqHkfY5hakQZbMBy6gs +VqCzaLOaqHaBrg6c2KqWEZ6WB2KasT/p5fuW+aoYqNbQibmic1H1ETGjnUlVWhwf +4aySRvbaTw3DzJXduZsJEQSq2Dv04JM/InxZEvh+FLXluccv6Os6MqZnKEST/e7f +zL6G4zphIFecrOqvvl/ej1UlOXCqUfOn3Srsy8AjLOvPJJ13VBPFo6Lz+P+5RcUX +VauY/vepsjecrcY2BaANct6BNdL0rgRkoT2HZ2g8snvWl+UVTZnwsjnwEZYYazrK +C6woDti14bn0Mc71kaeNTog0FU/nqfP1exMiV87H+EU04XcyGn8b0oSSI3DcEDau +SV9qwksQcqF28fDbQz5h9UsEdWjjSYQmNpF4Iow6t18buspqSRbEZXap8Vt5tLAr +9t1CV9vIKNMU7JIodZngUxITMZYZyVHHbTidu3rzv9ojsAMvFElr590yIk8FPsDD +m3vnKlNHT7B8/irI8gyhLGlF+mwGEROM1PSeNNq6ufV74DWh0C4RpdzLfgzd8AqL +bxX1kOOzC6kVjwa8lCowMRS4d9Kah8jRoOgx9Az/GSJ2ODBXYGGcOwF1ERDU8P7i +IsAVjFZ2OeC5E36MHSiP60rRe4i/NGJOgY6pY3mwTdCFtUdnRv6ASc6k4TOQGMup +xgGFJ0ph68AtRheZ0IdN/VXMQfseyzufb5bq0Yc3yb9spogH7sY4IplxvEtMwsB2 +BBgBCAAqBQJkLrkQCZD/Lbr4zUX6OxYhBEJ8H0lz9aZ8pbX+hP8tuvjNRfo7AhsM +AABaJgf/dTX0lJCphR9DlppTFNhcwOdtmvJf9CPP8+vHpPjyL5fiB4wDPCU1C7x1 +ku/QS00EKIpPP1EbDUsY0jIN7IV24x0eQcAswIV1F63Bzfft1rWZsA5iiZms1bgh +AEA3Kv2Xh7DUaiykaXvbtyfCI6pX+MgMZsLqVhFEH/5lq+dlYc8UyM7IE3LNWYj3 +Uluz+3GjCdLZ8FVJVTrRZz8wR8HDlcPdC60gqnnx6QQ4rmzYoivK0Rf/4LLjujOc +VjyzpPJS+t/gabeMRho7vChSge603d227AKpJtQnfUKN3mjN1i/XQ3iIFlVAGlGA +oZIvKIVq9Vqf8XJVjMDbRMNTmh3a5A== +-----END PGP PRIVATE KEY BLOCK-----`; + const passphrase = 'password'; + const encryptedKey = await openpgp.readKey({ armoredKey }); + const decryptedKey = await openpgp.decryptKey({ + privateKey: encryptedKey, + passphrase + }); + const reecryptedKey = await openpgp.encryptKey({ + privateKey: decryptedKey, + passphrase, + config: { aeadProtect: true } + }); + expect(reecryptedKey.keyPacket.s2kUsage).to.equal(253); + const redecryptedKey = await openpgp.decryptKey({ + privateKey: reecryptedKey, + passphrase + }); + expect(redecryptedKey.write()).to.deep.equal(decryptedKey.write()); + }); + + it('Parsing, decrypting, encrypting and serializing V6 key (AEAD-encrypted)', async function() { + // official test vector from https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#appendix-A.5 + const armoredKey = `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xYIGY4d/4xsAAAAg+U2nu0jWCmHlZ3BqZYfQMxmZu52JGggkLq2EVD34laP9JgkC +FARdb9ccngltHraRe25uHuyuAQQVtKipJ0+r5jL4dacGWSAheCWPpITYiyfyIOPS +3gIDyg8f7strd1OB4+LZsUhcIjOMpVHgmiY/IutJkulneoBYwrEGHxsKAAAAQgWC +Y4d/4wMLCQcFFQoOCAwCFgACmwMCHgkiIQbLGGxPBgmml+TVLfpscisMHx4nwYpW +cI9lJewnutmsyQUnCQIHAgAAAACtKCAQPi19In7A5tfORHHbNr/JcIMlNpAnFJin +7wV2wH+q4UWFs7kDsBJ+xP2i8CMEWi7Ha8tPlXGpZR4UruETeh1mhELIj5UeM8T/ +0z+5oX1RHu11j8bZzFDLX9eTsgOdWATHggZjh3/jGQAAACCGkySDZ/nlAV25Ivj0 +gJXdp4SYfy1ZhbEvutFsr15ENf0mCQIUBA5hhGgp2oaavg6mFUXcFMwBBBUuE8qf +9Ock+xwusd+GAglBr5LVyr/lup3xxQvHXFSjjA2haXfoN6xUGRdDEHI6+uevKjVR +v5oAxgu7eJpaXNjCmwYYGwoAAAAsBYJjh3/jApsMIiEGyxhsTwYJppfk1S36bHIr +DB8eJ8GKVnCPZSXsJ7rZrMkAAAAABAEgpukYbZ1ZNfyP5WMUzbUnSGpaUSD5t2Ki +Nacp8DkBClZRa2c3AMQzSDXa9jGhYzxjzVb5scHDzTkjyRZWRdTq8U6L4da+/+Kt +ruh8m7Xo2ehSSFyWRSuTSZe5tm/KXgYG +-----END PGP PRIVATE KEY BLOCK-----`; + const passphrase = 'correct horse battery staple'; + const encryptedKey = await openpgp.readKey({ armoredKey }); + + // avoid argon2's expensive computation + const stubArgon2PrimaryKey = sinon.stub(encryptedKey.keyPacket.s2k, 'produceKey').returns( + util.hexToUint8Array('832bd2662a5c2b251ee3fc82aec349a766ca539015880133002e5a21960b3bcf')); + const stubArgon2Subkey = sinon.stub(encryptedKey.subkeys[0].keyPacket.s2k, 'produceKey').returns( + util.hexToUint8Array('f74a6ce873a089ef13a3da9ac059777bb22340d15eaa6c9dc0f8ef09035c67cd')); + + try { + const decryptedKey = await openpgp.decryptKey({ + privateKey: encryptedKey, + passphrase + }); + + const reecryptedKey = await openpgp.encryptKey({ + privateKey: decryptedKey, + passphrase, + config: { aeadProtect: true } + }); + expect(reecryptedKey.keyPacket.s2kUsage).to.equal(253); + const redecryptedKey = await openpgp.decryptKey({ + privateKey: reecryptedKey, + passphrase + }); + expect(redecryptedKey.write()).to.deep.equal(decryptedKey.write()); + } finally { + stubArgon2PrimaryKey.restore(); + stubArgon2Subkey.restore(); + } + }); + it('Parsing ECDH key with unknown kdf param version', async function() { // subkey with unknown kdfParam version 255. Parsing should not fail, the subkey should simply dropped const key = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- From 0b8501427bea7cf29aa8fc46784f8f9cf784a83a Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Tue, 25 Jul 2023 11:41:20 +0200 Subject: [PATCH 050/201] Implement packet criticality check The Packet Tag space is now partitioned into critical packets and non-critical packets. If an implementation encounters a critical packet where the packet type is unknown in a packet sequence, it MUST reject the whole packet sequence. On the other hand, an unknown non-critical packet MUST be ignored. See https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#section-4.3.1 . --- src/packet/packet.js | 13 +++++++++++++ src/packet/packetlist.js | 16 ++++++++++++++-- test/general/packet.js | 14 ++++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/packet/packet.js b/src/packet/packet.js index c40082f5..6eea1209 100644 --- a/src/packet/packet.js +++ b/src/packet/packet.js @@ -308,6 +308,19 @@ export class UnsupportedError extends Error { } } +// unknown packet types are handled differently depending on the packet criticality +export class UnknownPacketError extends UnsupportedError { + constructor(...params) { + super(...params); + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, UnsupportedError); + } + + this.name = 'UnknownPacketError'; + } +} + export class UnparseablePacket { constructor(tag, rawContent) { this.tag = tag; diff --git a/src/packet/packetlist.js b/src/packet/packetlist.js index 6207ef99..2c8e2a08 100644 --- a/src/packet/packetlist.js +++ b/src/packet/packetlist.js @@ -4,7 +4,8 @@ import { writeTag, writeHeader, writePartialLength, writeSimpleLength, UnparseablePacket, - UnsupportedError + UnsupportedError, + UnknownPacketError } from './packet'; import util from '../util'; import enums from '../enums'; @@ -25,7 +26,7 @@ export function newPacketFromTag(tag, allowedPackets) { try { packetType = enums.read(enums.packet, tag); } catch (e) { - throw new UnsupportedError(`Unknown packet type with tag: ${tag}`); + throw new UnknownPacketError(`Unknown packet type with tag: ${tag}`); } throw new Error(`Packet not allowed in this context: ${packetType}`); } @@ -87,6 +88,17 @@ class PacketList extends Array { await packet.read(parsed.packet, config); await writer.write(packet); } catch (e) { + // If an implementation encounters a critical packet where the packet type is unknown in a packet sequence, + // it MUST reject the whole packet sequence. On the other hand, an unknown non-critical packet MUST be ignored. + // Packet Tags from 0 to 39 are critical. Packet Tags from 40 to 63 are non-critical. + if (e instanceof UnknownPacketError) { + if (parsed.tag <= 39) { + await writer.abort(e); + } else { + return; + } + } + const throwUnsupportedError = !config.ignoreUnsupportedPackets && e instanceof UnsupportedError; const throwMalformedError = !config.ignoreMalformedPackets && !(e instanceof UnsupportedError); if (throwUnsupportedError || throwMalformedError || supportsStreaming(parsed.tag)) { diff --git a/test/general/packet.js b/test/general/packet.js index 0e1cdaab..696d2846 100644 --- a/test/general/packet.js +++ b/test/general/packet.js @@ -1514,6 +1514,20 @@ kePFjAnu9cpynKXu3usf8+FuBw2zLsg1Id1n7ttxoAte416KjBN9lFBt8mcu ).to.be.rejectedWith(/Unsupported S2K type/); }); + it('Throws on critical packet even with tolerant mode enabled', async function() { + const unknownPacketTag39 = util.hexToUint8Array('e70a750064bf943d6e756c6c'); // critical tag + + await expect(openpgp.PacketList.fromBinary(unknownPacketTag39, allAllowedPackets, { ...openpgp.config, ignoreUnsupportedPackets: false, ignoreMalformedPackets: false })).to.be.rejectedWith(/Unknown packet type/); + await expect(openpgp.PacketList.fromBinary(unknownPacketTag39, allAllowedPackets, { ...openpgp.config, ignoreUnsupportedPackets: true, ignoreMalformedPackets: true })).to.be.rejectedWith(/Unknown packet type/); + }); + + it('Ignores non-critical packet even with tolerant mode disabled', async function() { + const unknownPacketTag63 = util.hexToUint8Array('ff0a750064bf943d6e756c6c'); // non-critical tag + + await expect(openpgp.PacketList.fromBinary(unknownPacketTag63, allAllowedPackets, { ...openpgp.config, ignoreUnsupportedPackets: false, ignoreMalformedPackets: false })).to.eventually.have.length(0); + await expect(openpgp.PacketList.fromBinary(unknownPacketTag63, allAllowedPackets, { ...openpgp.config, ignoreUnsupportedPackets: true, ignoreMalformedPackets: true })).to.eventually.have.length(0); + }); + it('Throws on disallowed packet even with tolerant mode enabled', async function() { const packets = new openpgp.PacketList(); packets.push(new openpgp.LiteralDataPacket()); From af9662885560d0f8e6b02496f5c0f0dea2ca80e4 Mon Sep 17 00:00:00 2001 From: Lukas Burkhalter Date: Thu, 1 Jun 2023 15:18:43 +0200 Subject: [PATCH 051/201] Add support for v6 one-pass signature packets Introduces v6 one-pass signature packets required for v6 signatures. Includes the changes from !305 of the crypto refresh: https://gitlab.com/openpgp-wg/rfc4880bis/-/merge_requests/305 Also, introduce `OnePassSignaturePacket.fromSignaturePacket` to simplify OPS generation. --- src/message.js | 50 ++--------- src/packet/one_pass_signature.js | 88 ++++++++++++++---- src/packet/signature.js | 8 +- test/general/signature.js | 149 ++++++++++++++++++++++++++++++- 4 files changed, 233 insertions(+), 62 deletions(-) diff --git a/src/message.js b/src/message.js index 2ce9f627..bea828bf 100644 --- a/src/message.js +++ b/src/message.js @@ -24,7 +24,7 @@ import crypto from './crypto'; import enums from './enums'; import util from './util'; import { Signature } from './signature'; -import { getPreferredHashAlgo, getPreferredCipherSuite, createSignaturePacket } from './key'; +import { getPreferredCipherSuite, createSignaturePacket } from './key'; import { PacketList, LiteralDataPacket, @@ -514,49 +514,14 @@ export class Message { throw new Error('No literal data packet to sign.'); } - let i; - let existingSigPacketlist; - // If data packet was created from Uint8Array, use binary, otherwise use text - const signatureType = literalDataPacket.text === null ? - enums.signature.binary : enums.signature.text; - - if (signature) { - existingSigPacketlist = signature.packets.filterByTag(enums.packet.signature); - for (i = existingSigPacketlist.length - 1; i >= 0; i--) { - const signaturePacket = existingSigPacketlist[i]; - const onePassSig = new OnePassSignaturePacket(); - onePassSig.signatureType = signaturePacket.signatureType; - onePassSig.hashAlgorithm = signaturePacket.hashAlgorithm; - onePassSig.publicKeyAlgorithm = signaturePacket.publicKeyAlgorithm; - onePassSig.issuerKeyID = signaturePacket.issuerKeyID; - if (!signingKeys.length && i === 0) { - onePassSig.flags = 1; - } - packetlist.push(onePassSig); - } - } - - await Promise.all(Array.from(signingKeys).reverse().map(async function (primaryKey, i) { - if (!primaryKey.isPrivate()) { - throw new Error('Need private key for signing'); - } - const signingKeyID = signingKeyIDs[signingKeys.length - 1 - i]; - const signingKey = await primaryKey.getSigningKey(signingKeyID, date, userIDs, config); - const onePassSig = new OnePassSignaturePacket(); - onePassSig.signatureType = signatureType; - onePassSig.hashAlgorithm = await getPreferredHashAlgo(primaryKey, signingKey.keyPacket, date, userIDs, config); - onePassSig.publicKeyAlgorithm = signingKey.keyPacket.algorithm; - onePassSig.issuerKeyID = signingKey.getKeyID(); - if (i === signingKeys.length - 1) { - onePassSig.flags = 1; - } - return onePassSig; - })).then(onePassSignatureList => { - onePassSignatureList.forEach(onePassSig => packetlist.push(onePassSig)); - }); + const signaturePackets = await createSignaturePackets(literalDataPacket, signingKeys, signature, signingKeyIDs, date, userIDs, notations, false, config); // this returns the existing signature packets as well + const onePassSignaturePackets = signaturePackets.map( + (signaturePacket, i) => OnePassSignaturePacket.fromSignaturePacket(signaturePacket, i === 0)) + .reverse(); // innermost OPS refers to the first signature packet + packetlist.push(...onePassSignaturePackets); packetlist.push(literalDataPacket); - packetlist.push(...(await createSignaturePackets(literalDataPacket, signingKeys, signature, signingKeyIDs, date, userIDs, notations, false, config))); + packetlist.push(...signaturePackets); return new Message(packetlist); } @@ -733,6 +698,7 @@ export class Message { * @param {Date} [date] - Override the creationtime of the signature * @param {Array} [userIDs] - User IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }] * @param {Array} [notations] - Notation Data to add to the signatures, e.g. [{ name: 'test@example.org', value: new TextEncoder().encode('test'), humanReadable: true, critical: false }] + * @param {Array} [signatureSalts] - A list of signature salts matching the number of signingKeys that should be used for v6 signatures * @param {Boolean} [detached] - Whether to create detached signature packets * @param {Object} [config] - Full configuration, defaults to openpgp.config * @returns {Promise} List of signature packets. diff --git a/src/packet/one_pass_signature.js b/src/packet/one_pass_signature.js index 54e8697d..9018e79f 100644 --- a/src/packet/one_pass_signature.js +++ b/src/packet/one_pass_signature.js @@ -16,14 +16,12 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA import * as stream from '@openpgp/web-stream-tools'; -import SignaturePacket from './signature'; +import SignaturePacket, { saltLengthForHash } from './signature'; import KeyID from '../type/keyid'; import enums from '../enums'; import util from '../util'; import { UnsupportedError } from './packet'; -const VERSION = 3; - /** * Implementation of the One-Pass Signature Packets (Tag 4) * @@ -39,8 +37,22 @@ class OnePassSignaturePacket { return enums.packet.onePassSignature; } + static fromSignaturePacket(signaturePacket, isLast) { + const onePassSig = new OnePassSignaturePacket(); + onePassSig.version = signaturePacket.version === 6 ? 6 : 3; + onePassSig.signatureType = signaturePacket.signatureType; + onePassSig.hashAlgorithm = signaturePacket.hashAlgorithm; + onePassSig.publicKeyAlgorithm = signaturePacket.publicKeyAlgorithm; + onePassSig.issuerKeyID = signaturePacket.issuerKeyID; + onePassSig.salt = signaturePacket.salt; // v6 only + onePassSig.issuerFingerprint = signaturePacket.issuerFingerprint; // v6 only + + onePassSig.flags = isLast ? 1 : 0; + return onePassSig; + } + constructor() { - /** A one-octet version number. The current version is 3. */ + /** A one-octet version number. The current versions are 3 and 6. */ this.version = null; /** * A one-octet signature type. @@ -62,8 +74,12 @@ class OnePassSignaturePacket { * @type {enums.publicKey} */ this.publicKeyAlgorithm = null; - /** An eight-octet number holding the Key ID of the signing key. */ + /** Only for v6, a variable-length field containing the salt. */ + this.salt = null; + /** Only for v3 packets, an eight-octet number holding the Key ID of the signing key. */ this.issuerKeyID = null; + /** Only for v6 packets, 32 octets of the fingerprint of the signing key. */ + this.issuerFingerprint = null; /** * A one-octet number holding a flag showing whether the signature is nested. * A zero value indicates that the next packet is another One-Pass Signature packet @@ -79,9 +95,9 @@ class OnePassSignaturePacket { */ read(bytes) { let mypos = 0; - // A one-octet version number. The current version is 3. + // A one-octet version number. The current versions are 3 or 6. this.version = bytes[mypos++]; - if (this.version !== VERSION) { + if (this.version !== 3 && this.version !== 6) { throw new UnsupportedError(`Version ${this.version} of the one-pass signature packet is unsupported.`); } @@ -95,10 +111,32 @@ class OnePassSignaturePacket { // A one-octet number describing the public-key algorithm used. this.publicKeyAlgorithm = bytes[mypos++]; - // An eight-octet number holding the Key ID of the signing key. - this.issuerKeyID = new KeyID(); - this.issuerKeyID.read(bytes.subarray(mypos, mypos + 8)); - mypos += 8; + if (this.version === 6) { + // Only for v6 signatures, a variable-length field containing: + + // A one-octet salt size. The value MUST match the value defined + // for the hash algorithm as specified in Table 23 (Hash algorithm registry). + const saltLength = bytes[mypos++]; + if (saltLength !== saltLengthForHash(this.hashAlgorithm)) { + throw new Error('Unexpected salt size for the hash algorithm'); + } + + // The salt; a random value value of the specified size. + this.salt = bytes.subarray(mypos, mypos + saltLength); + mypos += saltLength; + + // Only for v6 packets, 32 octets of the fingerprint of the signing key. + this.issuerFingerprint = bytes.subarray(mypos, mypos + 32); + mypos += 32; + this.issuerKeyID = new KeyID(); + // For v6 the Key ID is the high-order 64 bits of the fingerprint. + this.issuerKeyID.read(this.issuerFingerprint); + } else { + // Only for v3 packets, an eight-octet number holding the Key ID of the signing key. + this.issuerKeyID = new KeyID(); + this.issuerKeyID.read(bytes.subarray(mypos, mypos + 8)); + mypos += 8; + } // A one-octet number holding a flag showing whether the signature // is nested. A zero value indicates that the next packet is @@ -113,11 +151,23 @@ class OnePassSignaturePacket { * @returns {Uint8Array} A Uint8Array representation of a one-pass signature packet. */ write() { - const start = new Uint8Array([VERSION, this.signatureType, this.hashAlgorithm, this.publicKeyAlgorithm]); - - const end = new Uint8Array([this.flags]); - - return util.concatUint8Array([start, this.issuerKeyID.write(), end]); + const arr = [new Uint8Array([ + this.version, + this.signatureType, + this.hashAlgorithm, + this.publicKeyAlgorithm + ])]; + if (this.version === 6) { + arr.push( + new Uint8Array([this.salt.length]), + this.salt, + this.issuerFingerprint + ); + } else { + arr.push(this.issuerKeyID.write()); + } + arr.push(new Uint8Array([this.flags])); + return util.concatUint8Array(arr); } calculateTrailer(...args) { @@ -133,7 +183,11 @@ class OnePassSignaturePacket { correspondingSig.signatureType !== this.signatureType || correspondingSig.hashAlgorithm !== this.hashAlgorithm || correspondingSig.publicKeyAlgorithm !== this.publicKeyAlgorithm || - !correspondingSig.issuerKeyID.equals(this.issuerKeyID) + !correspondingSig.issuerKeyID.equals(this.issuerKeyID) || + (this.version === 3 && correspondingSig.version === 6) || + (this.version === 6 && correspondingSig.version !== 6) || + (this.version === 6 && !util.equalsUint8Array(correspondingSig.issuerFingerprint, this.issuerFingerprint)) || + (this.version === 6 && !util.equalsUint8Array(correspondingSig.salt, this.salt)) ) { throw new Error('Corresponding signature packet does not match one-pass signature packet'); } diff --git a/src/packet/signature.js b/src/packet/signature.js index eb7f8062..6e0c0dc1 100644 --- a/src/packet/signature.js +++ b/src/packet/signature.js @@ -214,7 +214,11 @@ class SignaturePacket { if (this.version === 6) { const saltLength = saltLengthForHash(this.hashAlgorithm); - this.salt = await crypto.random.getRandomBytes(saltLength); + if (this.salt === null) { + this.salt = crypto.random.getRandomBytes(saltLength); + } else if (saltLength !== this.salt.length) { + throw new Error('Provided salt does not have the required length'); + } } const toHash = this.toHash(this.signatureType, data, detached); const hash = await this.hash(this.signatureType, data, toHash, detached); @@ -823,7 +827,7 @@ function writeSubPacket(type, critical, data) { * @returns {Integer} Salt length. * @private */ -function saltLengthForHash(hashAlgorithm) { +export function saltLengthForHash(hashAlgorithm) { switch (hashAlgorithm) { case enums.hash.sha256: return 16; case enums.hash.sha384: return 24; diff --git a/test/general/signature.js b/test/general/signature.js index 1c123f75..73e1425e 100644 --- a/test/general/signature.js +++ b/test/general/signature.js @@ -710,6 +710,68 @@ hUhMKMuiM3pRwdIyDOItkUWQmjEEw7/XmhgInkXsCw== expect(signature.getSigningKeyIDs().map(x => x.toHex())).to.include(publicKey.getKeyID().toHex()); }); + it('Generates valid one-pass signature packets (v6 keys)', async function () { + const v6PrivateKey = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xUsGY4d/4xsAAAAg+U2nu0jWCmHlZ3BqZYfQMxmZu52JGggkLq2EVD34laMAGXKB +exK+cH6NX1hs5hNhIB00TrJmosgv3mg1ditlsLfCsQYfGwoAAABCBYJjh3/jAwsJ +BwUVCg4IDAIWAAKbAwIeCSIhBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce6 +2azJBScJAgcCAAAAAK0oIBA+LX0ifsDm185Ecds2v8lwgyU2kCcUmKfvBXbAf6rh +RYWzuQOwEn7E/aLwIwRaLsdry0+VcallHhSu4RN6HWaEQsiPlR4zxP/TP7mhfVEe +7XWPxtnMUMtf15OyA51YBMdLBmOHf+MZAAAAIIaTJINn+eUBXbki+PSAld2nhJh/ +LVmFsS+60WyvXkQ1AE1gCk95TUR3XFeibg/u/tVY6a//1q0NWC1X+yui3O24wpsG +GBsKAAAALAWCY4d/4wKbDCIhBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce6 +2azJAAAAAAQBIKbpGG2dWTX8j+VjFM21J0hqWlEg+bdiojWnKfA5AQpWUWtnNwDE +M0g12vYxoWM8Y81W+bHBw805I8kWVkXU6vFOi+HWvv/ira7ofJu16NnoUkhclkUr +k0mXubZvyl4GBg== +-----END PGP PRIVATE KEY BLOCK-----` }); + const v4PrivateKey = await openpgp.readKey({ + armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xVgEZOjwQBYJKwYBBAHaRw8BAQdAIzsYHb7T7NhSFmkWKSk5ItaBYv2HET7u +IFXhGdvOpogAAQDMk8SQlysNkLe7VRwXedX63St1a2V6/dzDG926oPyW3hJ6 +zQ48dGVzdEB0ZXN0Lml0PsKMBBAWCgA+BYJk6PBABAsJBwgJkFMSwQwprjrH +AxUICgQWAAIBAhkBApsDAh4BFiEEwKKS1V/wldBNfwpjUxLBDCmuOscAAONc +AQDU1gi9moPtQzh6rrpKPWZ8nMSiZzLb3LYmpqz9Tn9YFAEAmEC2uHET/Oj6 +VVxvMwvGytr5y0nuc6ZV5D0I2qoMcAHHXQRk6PBAEgorBgEEAZdVAQUBAQdA +xeBFSxzKOtLEQ6mVO2mnxvDiiMKmq7NbOezoWkbeSjgDAQgHAAD/YMvH+eDP +h1RplHOiaAMwhpTRGSGOaC6+pu6AMWiRLWAQ88J4BBgWCAAqBYJk6PBACZBT +EsEMKa46xwKbDBYhBMCiktVf8JXQTX8KY1MSwQwprjrHAAD4igEAzoExR6VX +EY9xxFKtAVdtYOT61d0FZibs0TD0VjbqzdkBAK60jT9jKefpnZ9sGv7bhSRX +2hrIPyCF2f0R5Js3LCML +=xyQ6 +-----END PGP PRIVATE KEY BLOCK-----` + }); + const armoredSignedMessage = await openpgp.sign({ + message: await openpgp.createMessage({ text: 'test' }), + signingKeys: [v6PrivateKey, v4PrivateKey, v6PrivateKey] // get multiple signature packets + }); + const signedMessage = await openpgp.readMessage({ armoredMessage: armoredSignedMessage }); + // read signature packet stream + signedMessage.packets.push(...await stream.readToEnd(signedMessage.packets.stream, _ => _)); + const signature1 = signedMessage.packets[4]; + const signature2 = signedMessage.packets[5]; // v4 sig + const signature3 = signedMessage.packets[6]; + const opsSignature1 = signedMessage.packets[2]; + const opsSignature2 = signedMessage.packets[1]; + const opsSignature3 = signedMessage.packets[0]; + expect(opsSignature1).to.be.instanceOf(openpgp.OnePassSignaturePacket); + expect(signature1).to.be.instanceOf(openpgp.SignaturePacket); + expect(opsSignature2).to.be.instanceOf(openpgp.OnePassSignaturePacket); + expect(signature2).to.be.instanceOf(openpgp.SignaturePacket); + expect(opsSignature3).to.be.instanceOf(openpgp.OnePassSignaturePacket); + expect(signature3).to.be.instanceOf(openpgp.SignaturePacket); + expect(opsSignature1.version).to.equal(6); + expect(opsSignature2.version).to.equal(3); + expect(opsSignature3.version).to.equal(6); + expect(util.uint8ArrayToHex(opsSignature1.issuerFingerprint)).to.equal(v6PrivateKey.getFingerprint()); + expect(util.uint8ArrayToHex(opsSignature3.issuerFingerprint)).to.equal(v6PrivateKey.getFingerprint()); + expect(opsSignature1.salt).to.deep.equal(signature1.salt); + expect(opsSignature2.salt).to.be.null; + expect(opsSignature3.salt).to.deep.equal(signature3.salt); + expect(opsSignature1.salt).to.not.deep.equal(opsSignature3.salt); // sanity check + }); + it('Throws when reading a signature missing the creation time', async function () { const armoredSignature = `-----BEGIN PGP SIGNATURE----- @@ -1109,7 +1171,92 @@ Fk7EflUZzngwY4lBzYAfnNBjEjc30xD/ddo+rwE= }); }); - it('Verify signed message with two one pass signatures', async function() { + + it('Verify signed message with a v6 one pass signature', async function() { + // test vector from https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#appendix-A.7 + const message = await openpgp.readMessage({ armoredMessage: `-----BEGIN PGP MESSAGE----- + +xEYGAQobIHZJX1AhiJD39eLuPBgiUU9wUA9VHYblySHkBONKU/usyxhsTwYJppfk +1S36bHIrDB8eJ8GKVnCPZSXsJ7rZrMkBy0p1AAAAAABXaGF0IHdlIG5lZWQgZnJv +bSB0aGUgZ3JvY2VyeSBzdG9yZToKCi0gdG9mdQotIHZlZ2V0YWJsZXMKLSBub29k +bGVzCsKYBgEbCgAAACkFgmOYo2MiIQbLGGxPBgmml+TVLfpscisMHx4nwYpWcI9l +JewnutmsyQAAAABpNiB2SV9QIYiQ9/Xi7jwYIlFPcFAPVR2G5ckh5ATjSlP7rCfQ +b7gKqPxbyxbhljGygHQPnqau1eBzrQD5QVplPEDnemrnfmkrpx0GmhCfokxYz9jj +FtCgazStmsuOXF9SFQE= +-----END PGP MESSAGE-----` }); + const key = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PUBLIC KEY BLOCK----- + +xioGY4d/4xsAAAAg+U2nu0jWCmHlZ3BqZYfQMxmZu52JGggkLq2EVD34laPCsQYf +GwoAAABCBYJjh3/jAwsJBwUVCg4IDAIWAAKbAwIeCSIhBssYbE8GCaaX5NUt+mxy +KwwfHifBilZwj2Ul7Ce62azJBScJAgcCAAAAAK0oIBA+LX0ifsDm185Ecds2v8lw +gyU2kCcUmKfvBXbAf6rhRYWzuQOwEn7E/aLwIwRaLsdry0+VcallHhSu4RN6HWaE +QsiPlR4zxP/TP7mhfVEe7XWPxtnMUMtf15OyA51YBM4qBmOHf+MZAAAAIIaTJINn ++eUBXbki+PSAld2nhJh/LVmFsS+60WyvXkQ1wpsGGBsKAAAALAWCY4d/4wKbDCIh +BssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce62azJAAAAAAQBIKbpGG2dWTX8 +j+VjFM21J0hqWlEg+bdiojWnKfA5AQpWUWtnNwDEM0g12vYxoWM8Y81W+bHBw805 +I8kWVkXU6vFOi+HWvv/ira7ofJu16NnoUkhclkUrk0mXubZvyl4GBg== +-----END PGP PUBLIC KEY BLOCK-----` }); + + const signingKeyIDs = message.getSigningKeyIDs(); + expect(key.getKeys(signingKeyIDs[0])).to.not.be.empty; + + const { data, signatures } = await openpgp.verify({ message, verificationKeys: key }); + expect(signatures).to.have.length(1); + expect(await signatures[0].verified).to.be.true; + expect((await signatures[0].signature).packets.length).to.equal(1); + expect(data.includes('What we need from the grocery store')).to.be.true; + }); + + it('Verify signed message with two one pass signatures (v3 and v6)', async function() { + // test vector from gopenpgp + const message = await openpgp.readMessage({ armoredMessage: `-----BEGIN PGP MESSAGE----- + +xEYGAAobIBEtnAy3EeX8aDFd2bf/A1Xfi7C/D3mLIkGEwVmD0fecyxhsTwYJppfk +1S36bHIrDB8eJ8GKVnCPZSXsJ7rZrMkAxA0DAAoW8jFVDE9H444ByxRiAAAAAABI +ZWxsbyBXb3JsZCA6KcJ1BAAWCgAnBQJk52D2CRDyMVUMT0fjjhYhBOuFu1+jOnXh +XpROY/IxVQxPR+OOAABOSwEA2nLYxa9ELDxwuPskKCUVs8noyT4fVEScWlWZAKqP +ykIBAJEhqqNHFP4Gok1Ss9mvf6fE25tJkdJKD+7PIH0mCJgAwpgGABsKAAAAKQUC +ZOdg9iKhBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce62azJAAAAAA2MIBEt +nAy3EeX8aDFd2bf/A1Xfi7C/D3mLIkGEwVmD0fecr0oTPTcMNupiH7SCY4THe3ue +7PlRvF2WoeWKkNZT1uwcb+ilW5h9eBpp0I4Xj98C0hMA5+rHsTsME2EZM8HADA== +-----END PGP MESSAGE-----` }); + const v6Key = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PUBLIC KEY BLOCK----- + +xioGY4d/4xsAAAAg+U2nu0jWCmHlZ3BqZYfQMxmZu52JGggkLq2EVD34laPCsQYf +GwoAAABCBYJjh3/jAwsJBwUVCg4IDAIWAAKbAwIeCSIhBssYbE8GCaaX5NUt+mxy +KwwfHifBilZwj2Ul7Ce62azJBScJAgcCAAAAAK0oIBA+LX0ifsDm185Ecds2v8lw +gyU2kCcUmKfvBXbAf6rhRYWzuQOwEn7E/aLwIwRaLsdry0+VcallHhSu4RN6HWaE +QsiPlR4zxP/TP7mhfVEe7XWPxtnMUMtf15OyA51YBM4qBmOHf+MZAAAAIIaTJINn ++eUBXbki+PSAld2nhJh/LVmFsS+60WyvXkQ1wpsGGBsKAAAALAWCY4d/4wKbDCIh +BssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce62azJAAAAAAQBIKbpGG2dWTX8 +j+VjFM21J0hqWlEg+bdiojWnKfA5AQpWUWtnNwDEM0g12vYxoWM8Y81W+bHBw805 +I8kWVkXU6vFOi+HWvv/ira7ofJu16NnoUkhclkUrk0mXubZvyl4GBg== +-----END PGP PUBLIC KEY BLOCK-----` }); + const v4Key = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PUBLIC KEY BLOCK----- +Comment: Alice's OpenPGP certificate + +mDMEXEcE6RYJKwYBBAHaRw8BAQdArjWwk3FAqyiFbFBKT4TzXcVBqPTB3gmzlC/U +b7O1u120JkFsaWNlIExvdmVsYWNlIDxhbGljZUBvcGVucGdwLmV4YW1wbGU+iJAE +ExYIADgCGwMFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AWIQTrhbtfozp14V6UTmPy +MVUMT0fjjgUCXaWfOgAKCRDyMVUMT0fjjukrAPoDnHBSogOmsHOsd9qGsiZpgRnO +dypvbm+QtXZqth9rvwD9HcDC0tC+PHAsO7OTh1S1TC9RiJsvawAfCPaQZoed8gK4 +OARcRwTpEgorBgEEAZdVAQUBAQdAQv8GIa2rSTzgqbXCpDDYMiKRVitCsy203x3s +E9+eviIDAQgHiHgEGBYIACAWIQTrhbtfozp14V6UTmPyMVUMT0fjjgUCXEcE6QIb +DAAKCRDyMVUMT0fjjlnQAQDFHUs6TIcxrNTtEZFjUFm1M0PJ1Dng/cDW4xN80fsn +0QEA22Kr7VkCjeAEC08VSTeV+QFsmz55/lntWkwYWhmvOgE= +=iIGO +-----END PGP PUBLIC KEY BLOCK-----` }); + + const { data, signatures } = await openpgp.verify({ message, verificationKeys: [v4Key, v6Key] }); + expect(signatures).to.have.length(2); + expect(await signatures[0].verified).to.be.true; + expect((await signatures[0].signature).packets.length).to.equal(1); + expect(await signatures[1].verified).to.be.true; + expect((await signatures[1].signature).packets.length).to.equal(1); + expect(data).to.equal('Hello World :)'); + }); + + it('Verify signed message with two one pass signatures (both v3)', async function() { const msg_armor = ['-----BEGIN PGP MESSAGE-----', 'Version: GnuPG v2.0.19 (GNU/Linux)', From 1ddf4e151c04f869b6ce4572b83c12a86f8668e5 Mon Sep 17 00:00:00 2001 From: Lukas Burkhalter Date: Thu, 1 Jun 2023 16:24:38 +0200 Subject: [PATCH 052/201] Accept cleartext messages without hash header The latest version of the crypto refresh (i.e., !313, !314) specifies that the "Hash" header is deprecated, and that an implementation that is verifying a cleartext signed message MUST ignore this header. However, we go against this directive, and keep the checks in place to avoid arbitrary injection of text as part of the "Hash" header payload. We also mandate that if the hash header is present, the declared algorithm matches the signature algorithm. This is again to avoid a spoofing attack where e.g. a SHA1 signature is presented as using SHA512. Related CVEs: CVE-2019-11841, CVE-2023-41037. This commit does not change the writing part of cleartext messages. # Conflicts: # src/cleartext.js --- src/cleartext.js | 35 +++++++++++++++------------------ test/general/armor.js | 23 ---------------------- test/general/signature.js | 41 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 42 deletions(-) diff --git a/src/cleartext.js b/src/cleartext.js index a99155e3..77f60f7e 100644 --- a/src/cleartext.js +++ b/src/cleartext.js @@ -171,30 +171,27 @@ function verifyHeaders(headers, packetlist) { return true; }; - let oneHeader = null; - let hashAlgos = []; - headers.forEach(function(header) { - oneHeader = header.match(/^Hash: (.+)$/); // get header value - if (oneHeader) { - oneHeader = oneHeader[1].replace(/\s/g, ''); // remove whitespace - oneHeader = oneHeader.split(','); - oneHeader = oneHeader.map(function(hash) { - hash = hash.toLowerCase(); - try { - return enums.write(enums.hash, hash); - } catch (e) { - throw new Error('Unknown hash algorithm in armor header: ' + hash); - } - }); - hashAlgos = hashAlgos.concat(oneHeader); + const hashAlgos = []; + headers.forEach(header => { + const hashHeader = header.match(/^Hash: (.+)$/); // get header value + if (hashHeader) { + const parsedHashIDs = hashHeader[1] + .replace(/\s/g, '') // remove whitespace + .split(',') + .map(hashName => { + try { + return enums.write(enums.hash, hashName.toLowerCase()); + } catch (e) { + throw new Error('Unknown hash algorithm in armor header: ' + hashName.toLowerCase()); + } + }); + hashAlgos.push(...parsedHashIDs); } else { throw new Error('Only "Hash" header allowed in cleartext signed message'); } }); - if (!hashAlgos.length && !checkHashAlgos([enums.hash.md5])) { - throw new Error('If no "Hash" header in cleartext signed message, then only MD5 signatures allowed'); - } else if (hashAlgos.length && !checkHashAlgos(hashAlgos)) { + if (hashAlgos.length && !checkHashAlgos(hashAlgos)) { throw new Error('Hash algorithm mismatch in armor header and signature'); } } diff --git a/test/general/armor.js b/test/general/armor.js index 2c620d35..62773792 100644 --- a/test/general/armor.js +++ b/test/general/armor.js @@ -36,12 +36,6 @@ export default () => describe('ASCII armor', function() { await expect(msg).to.be.rejectedWith(Error, /Hash algorithm mismatch in armor header and signature/); }); - it('Exception if no header and non-MD5 signature', async function () { - let msg = getArmor(null); - msg = openpgp.readCleartextMessage({ cleartextMessage: msg }); - await expect(msg).to.be.rejectedWith(Error, /If no "Hash" header in cleartext signed message, then only MD5 signatures allowed/); - }); - it('Exception if unknown hash algorithm', async function () { let msg = getArmor(['Hash: LAV750']); msg = openpgp.readCleartextMessage({ cleartextMessage: msg }); @@ -66,18 +60,6 @@ export default () => describe('ASCII armor', function() { await expect(msg).to.be.rejectedWith(Error, /Only "Hash" header allowed in cleartext signed message/); }); - it('Multiple wrong hash values', async function () { - let msg = getArmor(['Hash: SHA512, SHA256']); - msg = openpgp.readCleartextMessage({ cleartextMessage: msg }); - await expect(msg).to.be.rejectedWith(Error, /Hash algorithm mismatch in armor header and signature/); - }); - - it('Multiple wrong hash values', async function () { - let msg = getArmor(['Hash: SHA512, SHA256']); - msg = openpgp.readCleartextMessage({ cleartextMessage: msg }); - await expect(msg).to.be.rejectedWith(Error, /Hash algorithm mismatch in armor header and signature/); - }); - it('Filter whitespace in blank line', async function () { let msg = [ '-----BEGIN PGP SIGNED MESSAGE-----', @@ -99,11 +81,6 @@ export default () => describe('ASCII armor', function() { expect(msg).to.be.an.instanceof(openpgp.CleartextMessage); }); - it('Exception if header is not Hash in cleartext signed message', async function () { - const msg = openpgp.readCleartextMessage({ cleartextMessage: getArmor(['Ha sh: SHA256']) }); - await expect(msg).to.be.rejectedWith(Error, /Only "Hash" header allowed in cleartext signed message/); - }); - it('Ignore improperly formatted armor header', async function () { await Promise.all(['Space : trailing', 'Space :switched', ': empty', 'none', 'Space:missing'].map(async function (invalidHeader) { expect(await openpgp.readCleartextMessage({ cleartextMessage: getArmor(['Hash: SHA1'], [invalidHeader]) })).to.be.an.instanceof(openpgp.CleartextMessage); diff --git a/test/general/signature.js b/test/general/signature.js index 73e1425e..c94acd8f 100644 --- a/test/general/signature.js +++ b/test/general/signature.js @@ -1365,6 +1365,47 @@ DAAKCRDyMVUMT0fjjlnQAQDFHUs6TIcxrNTtEZFjUFm1M0PJ1Dng/cDW4xN80fsn expect(notations[1].critical).to.be.false; }); + it('Verify v6 cleartext signed message with openpgp.verify', async function() { + // test vector from https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-08.html#name-sample-v6-certificate-trans + const cleartextMessage = `-----BEGIN PGP SIGNED MESSAGE----- + +What we need from the grocery store: + +- - tofu +- - vegetables +- - noodles + +-----BEGIN PGP SIGNATURE----- + +wpgGARsKAAAAKQWCY5ijYyIhBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce6 +2azJAAAAAGk2IHZJX1AhiJD39eLuPBgiUU9wUA9VHYblySHkBONKU/usJ9BvuAqo +/FvLFuGWMbKAdA+epq7V4HOtAPlBWmU8QOd6aud+aSunHQaaEJ+iTFjP2OMW0KBr +NK2ay45cX1IVAQ== +-----END PGP SIGNATURE-----`; + + const publicKey = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PUBLIC KEY BLOCK----- + +xioGY4d/4xsAAAAg+U2nu0jWCmHlZ3BqZYfQMxmZu52JGggkLq2EVD34laPCsQYf +GwoAAABCBYJjh3/jAwsJBwUVCg4IDAIWAAKbAwIeCSIhBssYbE8GCaaX5NUt+mxy +KwwfHifBilZwj2Ul7Ce62azJBScJAgcCAAAAAK0oIBA+LX0ifsDm185Ecds2v8lw +gyU2kCcUmKfvBXbAf6rhRYWzuQOwEn7E/aLwIwRaLsdry0+VcallHhSu4RN6HWaE +QsiPlR4zxP/TP7mhfVEe7XWPxtnMUMtf15OyA51YBM4qBmOHf+MZAAAAIIaTJINn ++eUBXbki+PSAld2nhJh/LVmFsS+60WyvXkQ1wpsGGBsKAAAALAWCY4d/4wKbDCIh +BssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce62azJAAAAAAQBIKbpGG2dWTX8 +j+VjFM21J0hqWlEg+bdiojWnKfA5AQpWUWtnNwDEM0g12vYxoWM8Y81W+bHBw805 +I8kWVkXU6vFOi+HWvv/ira7ofJu16NnoUkhclkUrk0mXubZvyl4GBg== +-----END PGP PUBLIC KEY BLOCK-----` }); + + const plaintext = 'What we need from the grocery store:\n\n- tofu\n- vegetables\n- noodles\n'; + const message = await openpgp.readCleartextMessage({ cleartextMessage }); + + const { signatures, data } = await openpgp.verify({ message, verificationKeys: publicKey }); + expect(data).to.equal(plaintext); + expect(signatures).to.have.length(1); + expect(await signatures[0].verified).to.be.true; + expect((await signatures[0].signature).packets.length).to.equal(1); + }); + it('Verify cleartext signed message with two signatures with openpgp.verify', async function() { const cleartextMessage = ['-----BEGIN PGP SIGNED MESSAGE-----', From 79b3687424a8289d4c173585a498df5dec97901f Mon Sep 17 00:00:00 2001 From: Lukas Burkhalter Date: Thu, 8 Jun 2023 10:05:01 +0200 Subject: [PATCH 053/201] Only emit Hash header below V6 for cleartext messages The latest version of the crypto refresh (i.e., !313, !314) specifies that the "Hash" header is depricated. This commit changes that the Hash header is only generated if a cleartext message contains a non-V6 signature. --- src/cleartext.js | 14 +++++++++----- src/encoding/armor.js | 6 +++--- test/general/signature.js | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/src/cleartext.js b/src/cleartext.js index 77f60f7e..34b1bc68 100644 --- a/src/cleartext.js +++ b/src/cleartext.js @@ -111,12 +111,16 @@ export class CleartextMessage { * @returns {String | ReadableStream} ASCII armor. */ armor(config = defaultConfig) { - let hashes = this.signature.packets.map(function(packet) { - return enums.read(enums.hash, packet.hashAlgorithm).toUpperCase(); - }); - hashes = hashes.filter(function(item, i, ar) { return ar.indexOf(item) === i; }); + // emit header if one of the signatures has a version not 6 + const emitHeader = this.signature.packets.some(packet => packet.version !== 6); + const hash = emitHeader ? + Array.from(new Set(this.signature.packets.map( + packet => enums.read(enums.hash, packet.hashAlgorithm).toUpperCase() + ))).join() : + null; + const body = { - hash: hashes.join(), + hash, text: this.text, data: this.signature.packets.write() }; diff --git a/src/encoding/armor.js b/src/encoding/armor.js index 0e0aa5ae..2177683f 100644 --- a/src/encoding/armor.js +++ b/src/encoding/armor.js @@ -190,12 +190,12 @@ export function unarmor(input) { } else { verifyHeaders(lastHeaders); headersDone = true; - if (textDone || type !== 2) { + if (textDone || type !== enums.armor.signed) { resolve({ text, data, headers, type }); break; } } - } else if (!textDone && type === 2) { + } else if (!textDone && type === enums.armor.signed) { if (!reSplit.test(line)) { // Reverse dash-escaping for msg text.push(line.replace(/^- /, '')); @@ -289,7 +289,7 @@ export function armor(messageType, body, partIndex, partTotal, customComment, co break; case enums.armor.signed: result.push('-----BEGIN PGP SIGNED MESSAGE-----\n'); - result.push('Hash: ' + hash + '\n\n'); + result.push(hash ? `Hash: ${hash}\n\n` : '\n'); result.push(text.replace(/^-/mg, '- -')); result.push('\n-----BEGIN PGP SIGNATURE-----\n'); result.push(addheader(customComment, config)); diff --git a/test/general/signature.js b/test/general/signature.js index c94acd8f..5a58dd1b 100644 --- a/test/general/signature.js +++ b/test/general/signature.js @@ -1594,6 +1594,38 @@ ${armoredSignature} expect(await signatures[0].verified).to.be.true; }); + it('Does not emit headers for v6 cleartext message', async function() { + const v6PrivateKey = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xUsGY4d/4xsAAAAg+U2nu0jWCmHlZ3BqZYfQMxmZu52JGggkLq2EVD34laMAGXKB +exK+cH6NX1hs5hNhIB00TrJmosgv3mg1ditlsLfCsQYfGwoAAABCBYJjh3/jAwsJ +BwUVCg4IDAIWAAKbAwIeCSIhBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce6 +2azJBScJAgcCAAAAAK0oIBA+LX0ifsDm185Ecds2v8lwgyU2kCcUmKfvBXbAf6rh +RYWzuQOwEn7E/aLwIwRaLsdry0+VcallHhSu4RN6HWaEQsiPlR4zxP/TP7mhfVEe +7XWPxtnMUMtf15OyA51YBMdLBmOHf+MZAAAAIIaTJINn+eUBXbki+PSAld2nhJh/ +LVmFsS+60WyvXkQ1AE1gCk95TUR3XFeibg/u/tVY6a//1q0NWC1X+yui3O24wpsG +GBsKAAAALAWCY4d/4wKbDCIhBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce6 +2azJAAAAAAQBIKbpGG2dWTX8j+VjFM21J0hqWlEg+bdiojWnKfA5AQpWUWtnNwDE +M0g12vYxoWM8Y81W+bHBw805I8kWVkXU6vFOi+HWvv/ira7ofJu16NnoUkhclkUr +k0mXubZvyl4GBg== +-----END PGP PRIVATE KEY BLOCK-----` }); + const v4PrivateKey = await openpgp.decryptKey({ + privateKey: await openpgp.readKey({ armoredKey: priv_key_arm2 }), + passphrase: 'hello world' + }); + + const message = await openpgp.createCleartextMessage({ text: 'check header message' }); + + const cleartextMessageV6 = await openpgp.sign({ message, signingKeys: v6PrivateKey }); + const cleartextMessageV4 = await openpgp.sign({ + message, + signingKeys: [v4PrivateKey, v6PrivateKey], + config: { minRSABits: 1024 } + }); + expect(cleartextMessageV6).to.not.contain('Hash:'); + expect(cleartextMessageV4).to.contain('Hash:'); + }); + function tests() { it('Verify signed message with trailing spaces from GPG', async function() { const armoredMessage = From 1423bdd56482bf761de40cc781020a4e141207d9 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Mon, 7 Aug 2023 21:45:50 +0200 Subject: [PATCH 054/201] Add PKESK.fromObject --- src/message.js | 26 ++++++------- .../public_key_encrypted_session_key.js | 26 ++++++++++++- test/general/openpgp.js | 37 ++++++++++--------- 3 files changed, 56 insertions(+), 33 deletions(-) diff --git a/src/message.js b/src/message.js index bea828bf..7afb2fd9 100644 --- a/src/message.js +++ b/src/message.js @@ -17,7 +17,6 @@ import * as stream from '@openpgp/web-stream-tools'; import { armor, unarmor } from './encoding/armor'; -import KeyID from './type/keyid'; import { Argon2OutOfMemoryError } from './type/s2k'; import defaultConfig from './config'; import crypto from './crypto'; @@ -431,24 +430,21 @@ export class Message { */ static async encryptSessionKey(sessionKey, algorithmName, aeadAlgorithmName, encryptionKeys, passwords, wildcard = false, encryptionKeyIDs = [], date = new Date(), userIDs = [], config = defaultConfig) { const packetlist = new PacketList(); - const algorithm = enums.write(enums.symmetric, algorithmName); + const symmetricAlgorithm = enums.write(enums.symmetric, algorithmName); const aeadAlgorithm = aeadAlgorithmName && enums.write(enums.aead, aeadAlgorithmName); if (encryptionKeys) { const results = await Promise.all(encryptionKeys.map(async function(primaryKey, i) { const encryptionKey = await primaryKey.getEncryptionKey(encryptionKeyIDs[i], date, userIDs, config); - const pkESKeyPacket = new PublicKeyEncryptedSessionKeyPacket(); - if (aeadAlgorithm) { - pkESKeyPacket.version = 6; - pkESKeyPacket.publicKeyVersion = wildcard ? 0 : encryptionKey.keyPacket.version; - pkESKeyPacket.publicKeyFingerprint = wildcard ? null : encryptionKey.keyPacket.getFingerprintBytes(); - } else { - pkESKeyPacket.version = 3; - pkESKeyPacket.publicKeyID = wildcard ? KeyID.wildcard() : encryptionKey.getKeyID(); - } - pkESKeyPacket.publicKeyAlgorithm = encryptionKey.keyPacket.algorithm; - pkESKeyPacket.sessionKey = sessionKey; - pkESKeyPacket.sessionKeyAlgorithm = algorithm; + + const pkESKeyPacket = PublicKeyEncryptedSessionKeyPacket.fromObject({ + version: aeadAlgorithm ? 6 : 3, + encryptionKeyPacket: encryptionKey.keyPacket, + anonymousRecipient: wildcard, + sessionKey, + sessionKeyAlgorithm: symmetricAlgorithm + }); + await pkESKeyPacket.encrypt(encryptionKey.keyPacket); delete pkESKeyPacket.sessionKey; // delete plaintext session key after encryption return pkESKeyPacket; @@ -487,7 +483,7 @@ export class Message { return symEncryptedSessionKeyPacket; }; - const results = await Promise.all(passwords.map(pwd => encryptPassword(sessionKey, algorithm, aeadAlgorithm, pwd))); + const results = await Promise.all(passwords.map(pwd => encryptPassword(sessionKey, symmetricAlgorithm, aeadAlgorithm, pwd))); packetlist.push(...results); } diff --git a/src/packet/public_key_encrypted_session_key.js b/src/packet/public_key_encrypted_session_key.js index 02828b5e..8121e32c 100644 --- a/src/packet/public_key_encrypted_session_key.js +++ b/src/packet/public_key_encrypted_session_key.js @@ -45,7 +45,7 @@ class PublicKeyEncryptedSessionKeyPacket { constructor() { this.version = null; - // For version 3: + // For version 3, but also used internally by v6 in e.g. `getEncryptionKeyIDs()` this.publicKeyID = new KeyID(); // For version 6: @@ -66,6 +66,30 @@ class PublicKeyEncryptedSessionKeyPacket { this.encrypted = {}; } + static fromObject({ + version, encryptionKeyPacket, anonymousRecipient, sessionKey, sessionKeyAlgorithm + }) { + const pkesk = new PublicKeyEncryptedSessionKeyPacket(); + + if (version !== 3 && version !== 6) { + throw new Error('Unsupported PKESK version'); + } + + pkesk.version = version; + + if (version === 6) { + pkesk.publicKeyVersion = anonymousRecipient ? null : encryptionKeyPacket.version; + pkesk.publicKeyFingerprint = anonymousRecipient ? null : encryptionKeyPacket.getFingerprintBytes(); + } + + pkesk.publicKeyID = anonymousRecipient ? KeyID.wildcard() : encryptionKeyPacket.getKeyID(); + pkesk.publicKeyAlgorithm = encryptionKeyPacket.algorithm; + pkesk.sessionKey = sessionKey; + pkesk.sessionKeyAlgorithm = sessionKeyAlgorithm; + + return pkesk; + } + /** * Parsing function for a publickey encrypted session key packet (tag 1). * diff --git a/test/general/openpgp.js b/test/general/openpgp.js index 98c6a3c6..b7365305 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -2581,27 +2581,30 @@ XfA3pqV4mTzF }); }); - it('should encrypt then decrypt with wildcard', async function () { - const encOpt = { + it('should encrypt then decrypt with wildcard (anonymous recipient)', async function () { + const { privateKey: privateKeyV4orV6 } = await openpgp.generateKey({ userIDs: { email: 'test@test.it' }, format: 'object' }); + const plaintext = 'hello world'; + + const encryptedMessage = await openpgp.encrypt({ message: await openpgp.createMessage({ text: plaintext }), - encryptionKeys: publicKey, - wildcard: true - }; - const decOpt = { - decryptionKeys: privateKey - }; - return openpgp.encrypt(encOpt).then(async function (encrypted) { - expect(encrypted).to.match(/^-----BEGIN PGP MESSAGE/); - decOpt.message = await openpgp.readMessage({ armoredMessage: encrypted }); - return openpgp.decrypt(decOpt); - }).then(function (decrypted) { - expect(decrypted.data).to.equal(plaintext); - expect(decrypted.signatures).to.exist; - expect(decrypted.signatures.length).to.equal(0); + encryptionKeys: privateKeyV4orV6, + wildcard: true, + format: 'object' }); + + expect(encryptedMessage.getEncryptionKeyIDs().every(keyID => keyID.isWildcard())).to.be.true; + const armoredMessage = encryptedMessage.armor(); + + const parsedEncryptedMessage = await openpgp.readMessage({ armoredMessage }); + expect(parsedEncryptedMessage.getEncryptionKeyIDs().every(keyID => keyID.isWildcard())).to.be.true; + + const decrypted = await openpgp.decrypt({ message: parsedEncryptedMessage, decryptionKeys: privateKeyV4orV6 }); + expect(decrypted.data).to.equal(plaintext); + expect(decrypted.signatures).to.exist; + expect(decrypted.signatures.length).to.equal(0); }); - it('should encrypt then decrypt with wildcard with multiple private keys', async function () { + it('should encrypt then decrypt with wildcard with multiple private keys (anonymous recipient)', async function () { const privKeyDE = await openpgp.decryptKey({ privateKey: await openpgp.readKey({ armoredKey: priv_key_de }), passphrase From 278a61adaba8b8245b308be4cf021da4969bb8bf Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Mon, 28 Aug 2023 15:31:00 +0200 Subject: [PATCH 055/201] Add SEIP.fromObject To avoid defaulting to v1 --- src/message.js | 10 ++++------ .../sym_encrypted_integrity_protected_data.js | 16 +++++++++++++++- test/general/packet.js | 2 ++ 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/message.js b/src/message.js index 7afb2fd9..8e5c725f 100644 --- a/src/message.js +++ b/src/message.js @@ -397,12 +397,10 @@ export class Message { const msg = await Message.encryptSessionKey(sessionKeyData, algorithmName, aeadAlgorithmName, encryptionKeys, passwords, wildcard, encryptionKeyIDs, date, userIDs, config); - const symEncryptedPacket = new SymEncryptedIntegrityProtectedDataPacket(); - if (aeadAlgorithmName) { - symEncryptedPacket.version = 2; - symEncryptedPacket.aeadAlgorithm = enums.write(enums.aead, aeadAlgorithmName); - } - + const symEncryptedPacket = SymEncryptedIntegrityProtectedDataPacket.fromObject({ + version: aeadAlgorithmName ? 2 : 1, + aeadAlgorithm: aeadAlgorithmName ? enums.write(enums.aead, aeadAlgorithmName) : null + }); symEncryptedPacket.packets = this.packets; const algorithm = enums.write(enums.symmetric, algorithmName); diff --git a/src/packet/sym_encrypted_integrity_protected_data.js b/src/packet/sym_encrypted_integrity_protected_data.js index 8aedf18d..f7c70646 100644 --- a/src/packet/sym_encrypted_integrity_protected_data.js +++ b/src/packet/sym_encrypted_integrity_protected_data.js @@ -52,8 +52,22 @@ class SymEncryptedIntegrityProtectedDataPacket { return enums.packet.symEncryptedIntegrityProtectedData; } + static fromObject({ version, aeadAlgorithm }) { + if (version !== 1 && version !== 2) { + throw new Error('Unsupported SEIPD version'); + } + + const seip = new SymEncryptedIntegrityProtectedDataPacket(); + seip.version = version; + if (version === 2) { + seip.aeadAlgorithm = aeadAlgorithm; + } + + return seip; + } + constructor() { - this.version = 1; + this.version = null; // The following 4 fields are for V2 only. /** @type {enums.symmetric} */ diff --git a/test/general/packet.js b/test/general/packet.js index 696d2846..f3a4e9b7 100644 --- a/test/general/packet.js +++ b/test/general/packet.js @@ -137,6 +137,7 @@ export default () => describe('Packet', function() { const literal = new openpgp.LiteralDataPacket(); const enc = new openpgp.SymEncryptedIntegrityProtectedDataPacket(); + enc.version = 1; enc.packets = new openpgp.PacketList(); enc.packets.push(literal); const msg = new openpgp.PacketList(); @@ -616,6 +617,7 @@ export default () => describe('Packet', function() { literal.setText(testText); const skesk = new openpgp.SymEncryptedSessionKeyPacket(); const seip = new openpgp.SymEncryptedIntegrityProtectedDataPacket(); + seip.version = 1; seip.packets = new openpgp.PacketList(); seip.packets.push(literal); const msg = new openpgp.PacketList(); From 8fe04c99c62a4807d9bb5bbf1b4b931d67a274e4 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Mon, 11 Sep 2023 13:57:02 +0200 Subject: [PATCH 056/201] Remove unused `enums.symmetric.plaintext` This special cipher value can be relevant for unencrypted private keys: https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#section-12.2.1 . However, it is no longer used internally, and on the contrary it could cause confusion on SKESK decryption, where "random" cipher algos are returned in case of wrong password. This change also fixes a flaky test on password-based decryption, caused by the PKESK v6 changes which add support for `null` cipher algos. The code did not distinguish between a `null` and a `0` (plaintext) algo identifier, and would break when the latter was returned on SKESK decryption. --- openpgp.d.ts | 10 +++++-- src/enums.js | 1 - test/general/openpgp.js | 65 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 4 deletions(-) diff --git a/openpgp.d.ts b/openpgp.d.ts index 19a681a1..d38bd10d 100644 --- a/openpgp.d.ts +++ b/openpgp.d.ts @@ -181,7 +181,7 @@ export function generateSessionKey(options: { encryptionKeys: MaybeArray; export function encryptSessionKey(options: EncryptSessionKeyOptions & { format: 'binary' }): Promise; export function encryptSessionKey(options: EncryptSessionKeyOptions & { format: 'object' }): Promise>; -export function decryptSessionKeys>(options: { message: Message, decryptionKeys?: MaybeArray, passwords?: MaybeArray, date?: Date, config?: PartialConfig }): Promise; +export function decryptSessionKeys>(options: { message: Message, decryptionKeys?: MaybeArray, passwords?: MaybeArray, date?: Date, config?: PartialConfig }): Promise; export function readMessage>(options: { armoredMessage: T, config?: PartialConfig }): Promise>; export function readMessage>(options: { binaryMessage: T, config?: PartialConfig }): Promise>; @@ -578,6 +578,11 @@ export interface SessionKey { aeadAlgorithm?: enums.aeadNames; } +export interface DecryptedSessionKey { + data: Uint8Array; + algorithm: enums.symmetricNames | null; // `null` if the session key is associated with a SEIPDv2 packet +} + export interface ReasonForRevocation { flag?: enums.reasonForRevocation, string?: string } interface EncryptOptions { @@ -843,9 +848,8 @@ export namespace enums { brainpoolP512r1 = 'brainpoolP512r1' } - export type symmetricNames = 'plaintext' | 'idea' | 'tripledes' | 'cast5' | 'blowfish' | 'aes128' | 'aes192' | 'aes256' | 'twofish'; + export type symmetricNames = 'idea' | 'tripledes' | 'cast5' | 'blowfish' | 'aes128' | 'aes192' | 'aes256' | 'twofish'; enum symmetric { - plaintext = 0, idea = 1, tripledes = 2, cast5 = 3, diff --git a/src/enums.js b/src/enums.js index 8b98ad17..210c380b 100644 --- a/src/enums.js +++ b/src/enums.js @@ -140,7 +140,6 @@ export default { * @readonly */ symmetric: { - plaintext: 0, /** Not implemented! */ idea: 1, tripledes: 2, diff --git a/test/general/openpgp.js b/test/general/openpgp.js index b7365305..41533bdf 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -2250,6 +2250,71 @@ XfA3pqV4mTzF }); }); + describe('decryptSessionKeys - unit tests', function() { + it('should decrypt message with two SKESKs where the wrong password returns a symmetric algo equal to 0', async function () { + // SKESK packets do not have an intrisic integrity check, and the session key must be used to check its validity. + // This message is such that when the password is used to try and decrypt the first (mismatching) SKESK, the result returns a '0' byte for + // the session key algo. This corresponds to the 'plaintext' algo identifier (https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#section-12.2.1), + // now removed from OpenPGP.js . + // This test guards against regressions caused by mishandling this value on SKESK decryption. + const message = await openpgp.readMessage({ armoredMessage:`-----BEGIN PGP MESSAGE----- + +wy4ECQMIf6HA/a6XkOAAlaU1z+uVfU5kmHmqNqahQH859nAMresQ6w1uIjsL +ZE5bwy4ECQMIKVfCf+GWBesA5KFPuIDa6kLLn/AvEgbCi5DOg2xdIf73SNSN +Tqy7nfex0sANAVtHHRkHVTRVTVa3MFjjiWeBEDtnfyVMntWJ21ihrIU9eb9p +qS7UljZZ0u++xSWclU2IGBXCIdO0wLuS6hYk3q5OFexWj8OIoYJX88nkA2iW +5xyGd9EFRWVsR4CREt8lwrIE2t/h8XpRlhJmY6Iefg8+2DeN8vDdhNs/B02o +0zAE0hF+3xvwZTLi4hDrhBZEgBedPaeX4jlmDc3qzh2wlgV/Mq/FUakYfSLl +bc1PCpfqkLZSuCfv4eoTrWohWi9lS/pRXY9hzzHtlnjo6w== +-----END PGP MESSAGE-----` }); + const sessionKeys = await openpgp.decryptSessionKeys({ message, passwords: 'I am another password' }); + expect(sessionKeys).to.have.length(1); // first SKESK dropped due to '0' being treated as invalid algo identifier + expect(sessionKeys[0].algorithm).to.equal('aes256'); + + // decrypt() used to fail on this type of input + const decrypted = await openpgp.decrypt({ message, passwords: 'I am another password', format: 'binary' }); + expect(decrypted.data).to.deep.equal( + util.hexToUint8Array('e280872009d699e0b5bae18ba1e28c86d280d184e1b888e1a8b3e28ab7e0afa8e0b98be283bde28db5e1b1afd48de1b5b2e280a7e199b0e1a487e185afd3a1e18ca5e0bfb4e28892e19e98e29bb8e29594e0baaae0b681e1929af09f9882f09f9897f09f9882f09f98abf09f988ff09f98b6f09f98bcf09f98bcf09f9981f09f9982e2808720090d0aed959ceab5adec96b42feca1b0ec84a0eba790') + ); + expect(decrypted.signatures.length).to.equal(0); + }); + + it('should decrypt PKESK v6 and return a null symmetric algorithm', async function() { + // test vector https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#appendix-A.8 + const armoredMessage = `-----BEGIN PGP MESSAGE----- + +wV0GIQYSyD8ecG9jCP4VGkF3Q6HwM3kOk+mXhIjR2zeNqZMIhRmHzxjV8bU/gXzO +WgBM85PMiVi93AZfJfhK9QmxfdNnZBjeo1VDeVZheQHgaVf7yopqR6W1FT6NOrfS +aQIHAgZhZBZTW+CwcW1g4FKlbExAf56zaw76/prQoN+bAzxpohup69LA7JW/Vp0l +yZnuSj3hcFj0DfqLTGgr4/u717J+sPWbtQBfgMfG9AOIwwrUBqsFE9zW+f1zdlYo +bhF30A+IitsxxA== +-----END PGP MESSAGE-----`; + + const privateKey = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xUsGY4d/4xsAAAAg+U2nu0jWCmHlZ3BqZYfQMxmZu52JGggkLq2EVD34laMAGXKB +exK+cH6NX1hs5hNhIB00TrJmosgv3mg1ditlsLfCsQYfGwoAAABCBYJjh3/jAwsJ +BwUVCg4IDAIWAAKbAwIeCSIhBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce6 +2azJBScJAgcCAAAAAK0oIBA+LX0ifsDm185Ecds2v8lwgyU2kCcUmKfvBXbAf6rh +RYWzuQOwEn7E/aLwIwRaLsdry0+VcallHhSu4RN6HWaEQsiPlR4zxP/TP7mhfVEe +7XWPxtnMUMtf15OyA51YBMdLBmOHf+MZAAAAIIaTJINn+eUBXbki+PSAld2nhJh/ +LVmFsS+60WyvXkQ1AE1gCk95TUR3XFeibg/u/tVY6a//1q0NWC1X+yui3O24wpsG +GBsKAAAALAWCY4d/4wKbDCIhBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce6 +2azJAAAAAAQBIKbpGG2dWTX8j+VjFM21J0hqWlEg+bdiojWnKfA5AQpWUWtnNwDE +M0g12vYxoWM8Y81W+bHBw805I8kWVkXU6vFOi+HWvv/ira7ofJu16NnoUkhclkUr +k0mXubZvyl4GBg== +-----END PGP PRIVATE KEY BLOCK-----` }); + + const sessionKeys = await openpgp.decryptSessionKeys({ + message: await openpgp.readMessage({ armoredMessage }), + decryptionKeys: privateKey + }); + + expect(sessionKeys).to.have.length(1); + expect(sessionKeys[0].algorithm).to.equal(null); // PKESK v6 does not include the algo info + }); + }); + describe('encrypt, decrypt, sign, verify - integration tests', function() { let privateKey_2000_2008; let publicKey_2000_2008; From 53e1ec023f4ebf45911c3a078e8dfe3f715d02bf Mon Sep 17 00:00:00 2001 From: Ryan Date: Mon, 25 Sep 2023 05:17:21 -0400 Subject: [PATCH 057/201] Add SHA-3 signature support (#1680) To support parsing, signing and verifying SHA3 signatures over messages and keys. --- src/crypto/hash/index.js | 15 ++++++++++++++- src/enums.js | 4 +++- src/packet/signature.js | 2 ++ test/crypto/hash/sha.js | 4 ++++ test/general/openpgp.js | 36 ++++++++++++++++++++++++++++++++++++ 5 files changed, 59 insertions(+), 2 deletions(-) diff --git a/src/crypto/hash/index.js b/src/crypto/hash/index.js index bdf6d60b..617b59a9 100644 --- a/src/crypto/hash/index.js +++ b/src/crypto/hash/index.js @@ -8,6 +8,7 @@ import { sha1 } from '@openpgp/noble-hashes/sha1'; import { sha224, sha256 } from '@openpgp/noble-hashes/sha256'; import { sha384, sha512 } from '@openpgp/noble-hashes/sha512'; +import { sha3_256, sha3_512 } from '@openpgp/noble-hashes/sha3'; import { ripemd160 } from '@openpgp/noble-hashes/ripemd160'; import * as stream from '@openpgp/web-stream-tools'; import md5 from './md5'; @@ -55,7 +56,9 @@ const hashFunctions = { sha256: nodeHash('sha256') || nobleHash(sha256, 'SHA-256'), sha384: nodeHash('sha384') || nobleHash(sha384, 'SHA-384'), sha512: nodeHash('sha512') || nobleHash(sha512, 'SHA-512'), - ripemd: nodeHash('ripemd160') || nobleHash(ripemd160) + ripemd: nodeHash('ripemd160') || nobleHash(ripemd160), + sha3_256: nodeHash('sha3-256') || nobleHash(sha3_256), + sha3_512: nodeHash('sha3-512') || nobleHash(sha3_512) }; export default { @@ -68,6 +71,8 @@ export default { sha384: hashFunctions.sha384, sha512: hashFunctions.sha512, ripemd: hashFunctions.ripemd, + sha3_256: hashFunctions.sha3_256, + sha3_512: hashFunctions.sha3_512, /** * Create a hash on the specified data using the specified algorithm @@ -91,6 +96,10 @@ export default { return this.sha512(data); case enums.hash.sha224: return this.sha224(data); + case enums.hash.sha3_256: + return this.sha3_256(data); + case enums.hash.sha3_512: + return this.sha3_512(data); default: throw new Error('Invalid hash function.'); } @@ -116,6 +125,10 @@ export default { return 64; case enums.hash.sha224: return 28; + case enums.hash.sha3_256: + return 32; + case enums.hash.sha3_512: + return 64; default: throw new Error('Invalid hash algorithm.'); } diff --git a/src/enums.js b/src/enums.js index 210c380b..5dbbffcc 100644 --- a/src/enums.js +++ b/src/enums.js @@ -175,7 +175,9 @@ export default { sha256: 8, sha384: 9, sha512: 10, - sha224: 11 + sha224: 11, + sha3_256: 12, + sha3_512: 14 }, /** A list of hash names as accepted by webCrypto functions. diff --git a/src/packet/signature.js b/src/packet/signature.js index 6e0c0dc1..6ab5a6a4 100644 --- a/src/packet/signature.js +++ b/src/packet/signature.js @@ -833,6 +833,8 @@ export function saltLengthForHash(hashAlgorithm) { case enums.hash.sha384: return 24; case enums.hash.sha512: return 32; case enums.hash.sha224: return 16; + case enums.hash.sha3_256: return 16; + case enums.hash.sha3_512: return 32; default: throw new Error('Unsupported hash function for V6 signatures'); } } diff --git a/test/crypto/hash/sha.js b/test/crypto/hash/sha.js index dc5284f0..5297aca5 100644 --- a/test/crypto/hash/sha.js +++ b/test/crypto/hash/sha.js @@ -14,4 +14,8 @@ export default () => it('SHA* with test vectors from NIST FIPS 180-2', async fun expect(util.uint8ArrayToHex(await hash.sha384(util.stringToUint8Array('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq')), 'hash.sha384("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b')).to.equal('3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b'); expect(util.uint8ArrayToHex(await hash.sha512(util.stringToUint8Array('abc')), 'hash.sha512("abc") = ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f')).to.equal('ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f'); expect(util.uint8ArrayToHex(await hash.sha512(util.stringToUint8Array('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq')), 'hash.sha512("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445')).to.equal('204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445'); + expect(util.uint8ArrayToHex(await hash.sha3_256(util.stringToUint8Array('abc')), 'hash.sha3_256("abc") = 3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532')).to.equal('3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532'); + expect(util.uint8ArrayToHex(await hash.sha3_256(util.stringToUint8Array('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq')), 'hash.sha3_256("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 41c0dba2a9d6240849100376a8235e2c82e1b9998a999e21db32dd97496d3376')).to.equal('41c0dba2a9d6240849100376a8235e2c82e1b9998a999e21db32dd97496d3376'); + expect(util.uint8ArrayToHex(await hash.sha3_512(util.stringToUint8Array('abc')), 'hash.sha3_512("abc") = b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0')).to.equal('b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0'); + expect(util.uint8ArrayToHex(await hash.sha3_512(util.stringToUint8Array('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq')), 'hash.sha3_512("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 04a371e84ecfb5b8b77cb48610fca8182dd457ce6f326a0fd3d7ec2f1e91636dee691fbe0c985302ba1b0d8dc78c086346b533b49c030d99a27daf1139d6e75e')).to.equal('04a371e84ecfb5b8b77cb48610fca8182dd457ce6f326a0fd3d7ec2f1e91636dee691fbe0c985302ba1b0d8dc78c086346b533b49c030d99a27daf1139d6e75e'); }); diff --git a/test/general/openpgp.js b/test/general/openpgp.js index 41533bdf..948e8862 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -297,6 +297,25 @@ DECl1Qu4QyeXin29uEXWiekMpNlZVsEuc8icCw6ABhIZ =/7PI -----END PGP PRIVATE KEY BLOCK-----`; +const priv_key_sha3 = `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xUsGZN8edBsAAAAgdUMlFMFCVKNo7sdUd6FVBos6NNjpUpSdrodk6BfPb/kA+3bu +A2+WY2LwyxlX5o07WR2VSn+wuegC3v28yO0tClHCtwYfGw4AAABIBYJk3x50BAsJ +CAcHFQ4MCgkICwIWAAIXgAKbAwIeCSIhBpbSe0QWuaCNSSLaePhXEP3BxQ2VHX3W +pW1U6svHvCUiBScJAgcCAAAAACMZIP8aHixoyC9wS3q/TNV/IfOQa81f+U5Ucz6H +4I+c5bWRYUzH/piBB4n5FoYlld+/SViCQIBCQ+fynLmaj5wlf22+mISTt/9je1Zf +YWlJ+WSJyi5gY5EH9DubfuIU3VaqCM0aQmVybmFkZXR0ZSA8YkBleGFtcGxlLm9y +Zz7CugYTGw4AAABLBYJk3x50BAsJCAcHFQ4MCgkICwIWAAIXgAIZAQKbAwIeCSIh +BpbSe0QWuaCNSSLaePhXEP3BxQ2VHX3WpW1U6svHvCUiBScJAgcCAAAAAMMGIJEi +9+yqkFKsNwX1H5II0riPudFpwBx2ypVjNk4aNb7Exl56Aac4tXEhz4fH41q0dAzF +ww2erZaiUqmohQ4AFSw1jN/WOiDfb1DkjT/HJ8vXMGpwWdgFPoqsWzTNhd5VCcdL +BmTfHnQZAAAAIAGMcsqVCXLclRhVamWciSxmnYF1FFs80W7dNUH07HUOAHh/S601 +If+/eZKDIj3jq7oOe2PzHSYEK+mpQD1hBpF2wpsGGBsOAAAALAWCZN8edAKbDCIh +BpbSe0QWuaCNSSLaePhXEP3BxQ2VHX3WpW1U6svHvCUiAAAAANj3IBknZTPsMpWA +we0Jl5gw/Dj4lWAGoJfWfk+6s3Q86Hag3Hu8VBsapzmul+vzy0KJa+ZRcZz2n8aj +0vTl4sOZ0EcCdFDfkh/tR//gKkT6BiSBG86WoFq3f6U/RC+z0Ym7Dw== +-----END PGP PRIVATE KEY BLOCK-----`; + const passphrase = 'hello world'; const plaintext = input.createSomeMessage(); const password1 = 'I am a password'; @@ -1821,6 +1840,23 @@ aOU= })).to.be.rejectedWith(/No signing keys provided/); }); + it('Signing with key which uses sha3 should generate a valid sha3 signature', async function() { + const privKey = await openpgp.readKey({ armoredKey: priv_key_sha3 }); + const pubKey = privKey.toPublic(); + const text = 'Hello, world.'; + const message = await openpgp.createCleartextMessage({ text }); + + const cleartextMessage = await openpgp.sign({ message, signingKeys: privKey, format: 'armored' }); + const parsedArmored = await openpgp.readCleartextMessage({ cleartextMessage }); + expect(parsedArmored.signature.packets.filterByTag(openpgp.enums.packet.signature)).to.have.length(1); + expect( + parsedArmored.signature.packets.filterByTag(openpgp.enums.packet.signature)[0].hashAlgorithm + ).to.equal(openpgp.enums.hash.sha3_512); + + const verified = await openpgp.verify({ message: parsedArmored, verificationKeys: pubKey, expectSigned: true }); + expect(verified.data).to.equal(text); + }); + it('should output cleartext message of expected format', async function() { const text = 'test'; const message = await openpgp.createCleartextMessage({ text }); From 97ebd14829ee1226280bfb7183db0be346ca9662 Mon Sep 17 00:00:00 2001 From: larabr Date: Mon, 25 Sep 2023 20:04:56 +0200 Subject: [PATCH 058/201] Fix parsing of v6 signatures with unknown hash algorithm (#1683) Fail on verification rather than parsing, also for unexpected salt size. --- src/crypto/hash/index.js | 2 +- src/packet/one_pass_signature.js | 6 ++-- src/packet/signature.js | 13 ++++--- test/general/signature.js | 62 ++++++++++++++++++++++++++++++-- 4 files changed, 70 insertions(+), 13 deletions(-) diff --git a/src/crypto/hash/index.js b/src/crypto/hash/index.js index 617b59a9..0943b82f 100644 --- a/src/crypto/hash/index.js +++ b/src/crypto/hash/index.js @@ -101,7 +101,7 @@ export default { case enums.hash.sha3_512: return this.sha3_512(data); default: - throw new Error('Invalid hash function.'); + throw new Error('Unsupported hash function'); } }, diff --git a/src/packet/one_pass_signature.js b/src/packet/one_pass_signature.js index 9018e79f..5676c8e6 100644 --- a/src/packet/one_pass_signature.js +++ b/src/packet/one_pass_signature.js @@ -16,7 +16,7 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA import * as stream from '@openpgp/web-stream-tools'; -import SignaturePacket, { saltLengthForHash } from './signature'; +import SignaturePacket from './signature'; import KeyID from '../type/keyid'; import enums from '../enums'; import util from '../util'; @@ -116,10 +116,8 @@ class OnePassSignaturePacket { // A one-octet salt size. The value MUST match the value defined // for the hash algorithm as specified in Table 23 (Hash algorithm registry). + // To allow parsing unknown hash algos, we only check the expected salt length when verifying. const saltLength = bytes[mypos++]; - if (saltLength !== saltLengthForHash(this.hashAlgorithm)) { - throw new Error('Unexpected salt size for the hash algorithm'); - } // The salt; a random value value of the specified size. this.salt = bytes.subarray(mypos, mypos + saltLength); diff --git a/src/packet/signature.js b/src/packet/signature.js index 6ab5a6a4..a66fbd49 100644 --- a/src/packet/signature.js +++ b/src/packet/signature.js @@ -145,10 +145,8 @@ class SignaturePacket { if (this.version === 6) { // A one-octet salt size. The value MUST match the value defined // for the hash algorithm as specified in Table 23 (Hash algorithm registry). + // To allow parsing unknown hash algos, we only check the expected salt length when verifying. const saltLength = bytes[i++]; - if (saltLength !== saltLengthForHash(this.hashAlgorithm)) { - throw new Error('Unexpected salt size for the hash algorithm'); - } // The salt; a random value value of the specified size. this.salt = bytes.subarray(i, i + saltLength); @@ -699,6 +697,11 @@ class SignaturePacket { } async hash(signatureType, data, toHash, detached = false) { + if (this.version === 6 && this.salt.length !== saltLengthForHash(this.hashAlgorithm)) { + // avoid hashing unexpected salt size + throw new Error('Signature salt does not have the expected length'); + } + if (!toHash) toHash = this.toHash(signatureType, data, detached); return crypto.hash.digest(this.hashAlgorithm, toHash); } @@ -827,7 +830,7 @@ function writeSubPacket(type, critical, data) { * @returns {Integer} Salt length. * @private */ -export function saltLengthForHash(hashAlgorithm) { +function saltLengthForHash(hashAlgorithm) { switch (hashAlgorithm) { case enums.hash.sha256: return 16; case enums.hash.sha384: return 24; @@ -835,6 +838,6 @@ export function saltLengthForHash(hashAlgorithm) { case enums.hash.sha224: return 16; case enums.hash.sha3_256: return 16; case enums.hash.sha3_512: return 32; - default: throw new Error('Unsupported hash function for V6 signatures'); + default: throw new Error('Unsupported hash function'); } } diff --git a/test/general/signature.js b/test/general/signature.js index 5a58dd1b..5580fedd 100644 --- a/test/general/signature.js +++ b/test/general/signature.js @@ -790,6 +790,31 @@ kCNcH9WI6idSzFjuYegECf+ZA1xOCjS9oLTGbSeT7jNfC8dH5+E92qlBLq4Ctt7k await expect(openpgp.readSignature({ armoredSignature })).to.be.rejectedWith(/Missing signature creation time/); }); + it('Supports parsing v6 signature with unknown hash algo', async function () { + // v6 signatures must check that the salt size is correct. + // but we want to support parsing signatures with unknown hash algos. + // this test checks that the parsing succeeds, while signing/verification fails. + + // key with direct signature of unknown hash algo 99 + const armoredKey = `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xUsGZN8edBsAAAAgdUMlFMFCVKNo7sdUd6FVBos6NNjpUpSdrodk6BfPb/kA ++3buA2+WY2LwyxlX5o07WR2VSn+wuegC3v28yO0tClHCtwYfG2MAAABIBYJk +3x50BAsJCAcHFQ4MCgkICwIWAAIXgAKbAwIeCSIhBpbSe0QWuaCNSSLaePhX +EP3BxQ2VHX3WpW1U6svHvCUiBScJAgcCAAAAACMZIP8aHixoyC9wS3q/TNV/ +IfOQa81f+U5Ucz6H4I+c5bWRYUzH/piBB4n5FoYlld+/SViCQIBCQ+fynLma +j5wlf22+mISTt/9je1ZfYWlJ+WSJyi5gY5EH9DubfuIU3VaqCM0aQmVybmFk +ZXR0ZSA8YkBleGFtcGxlLm9yZz7CugYTGw4AAABLBYJk3x50BAsJCAcHFQ4M +CgkICwIWAAIXgAIZAQKbAwIeCSIhBpbSe0QWuaCNSSLaePhXEP3BxQ2VHX3W +pW1U6svHvCUiBScJAgcCAAAAAMMGIJEi9+yqkFKsNwX1H5II0riPudFpwBx2 +ypVjNk4aNb7Exl56Aac4tXEhz4fH41q0dAzFww2erZaiUqmohQ4AFSw1jN/W +OiDfb1DkjT/HJ8vXMGpwWdgFPoqsWzTNhd5VCQ== +-----END PGP PRIVATE KEY BLOCK-----`; + + const key = await openpgp.readKey({ armoredKey }); + await expect(key.getSigningKey()).to.be.rejectedWith(/Unsupported hash function/); + }); + it('Ignores marker packets when verifying signatures', async function () { const signatureWithMarkerPacket = `-----BEGIN PGP SIGNATURE----- @@ -914,9 +939,7 @@ SlcdMBDgwngEGBYIAAkFAmFppjQCGwwAIQkQDmTSjoPv10MWIQRqj/4SGmAk ibGeE60OZNKOg+/XQx/EAQCM0UYrObp60YbOCxu07Dm6XjCVylbOcsaxCnE7 2eMU4AD+OkgajZgbqSIdAR1ud76FW+W+3xlDi/SMFdU7D49SbQI= =ASQu ------END PGP PRIVATE KEY BLOCK----- - -`; +-----END PGP PRIVATE KEY BLOCK-----`; const armoredMessage = `-----BEGIN PGP MESSAGE----- xA0DAQoWDmTSjoPv10MByw91AGFpplFwbGFpbnRleHTCdQQBFgoABgUCYWml @@ -1062,6 +1085,39 @@ eSvSZutLuKKbidSYMLhWROPlwKc2GU2ws6PrLZAyCAel/lU= expect(await sigInfo.verified).to.be.true; }); + it('Verification fails if v6 signature has unexpected salt length', async function() { + // signature with salt shorter than expected + const armoredMessage = `-----BEGIN PGP MESSAGE----- + +xEQGAQoWHgTCf3OkPcYPPB6GmoMeaOz1wYXbuSvHxW/PVbRIynPv5yU3YApt +KDJPb4mCbmxvCoKjGx6CMjDpDsVB+wDFAcsLdQBlEWcKaGVsbG/CmgYBFgoA +AAApBYJlEWcKIqEGc+/nJTdgCm0oMk9viYJubG8KgqMbHoIyMOkOxUH7AMUA +AAAA5GYeBMJ/c6Q9xg88Hoaagx5o7PXBhdu5K8fFb89VtEjKAQCW/XwAPo2V +ugvc1634oGA/74j7KonU2qdl0LvxVJuB2wEAtutHh3wry/SNkc+japCGO4u4 +XjIVmkzQNtymmOECUwI= +-----END PGP MESSAGE-----`; + const key = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xVoGZRFjtxYAAAAtCSsGAQQB2kcPAQEHQJRcfAi8wlCCWAeBcvpRO6iL5YK8 +1e8BVcOkAGVXKDguAAEAxIUb1xswIKPfVEyOZkqSFukVOegoArxIeEuDaoK0 +feXCrQYfFgoAAAA6BYJlEWO3AwsJBwMVCAoCFgACmwMCHgEioQZz7+clN2AK +bSgyT2+Jgm5sbwqCoxsegjIw6Q7FQfsAxQAAAACBKyDA5Ih9cWlc9o5NUzmo +jSCtKhy54bBzfRX0t9Jha4BfZwD9FvmhOEpJAnYRDmBrEiaO4okM3D6eNZz9 +rmGZkLT9oJMBAI6UbwsjgWw42W85Kb57tfYdF/779TrLHcNRZLNV0p8NzQDC +nwYQFgoAAAAsBYJlEWO3AhkBIqEGc+/nJTdgCm0oMk9viYJubG8KgqMbHoIy +MOkOxUH7AMUAAAAAV2kgOkNvj/g+Q6hFcHcpRFekCUxOons+JgXE+lxuKnbt +l10BAO7pYlHAee5dxkzQI3WPiiYFt/OYrnr7fT5QadRZhAutAP9n5bvQaoLX +vfHp79dKJnU1qDnSTEshB7ytt9I3Ze+DAQ== +-----END PGP PRIVATE KEY BLOCK-----` }); + + const { signatures } = await openpgp.verify({ + message: await openpgp.readMessage({ armoredMessage }), + verificationKeys: key + }); + expect(signatures).to.have.length(1); + await expect(signatures[0].verified).to.be.rejectedWith(/Signature salt does not have the expected length/); + }); + it('Reject cleartext message with arbitrary text added around hash headers (spoofed cleartext message)', async function() { await expect(openpgp.readCleartextMessage({ cleartextMessage: `-----BEGIN PGP SIGNED MESSAGE----- This is not signed but you might think it is Hash: SHA512 From 105b3cdde4af84088ec10a6a01363bb24537f7b2 Mon Sep 17 00:00:00 2001 From: larabr Date: Thu, 19 Oct 2023 14:22:31 +0200 Subject: [PATCH 059/201] Disregard `config.aeadProtect` when encrypting to public keys (#1678) Determine whether AEAD should be used for encryption solely based the encryption key preferences. Previously, the config flag was also used to control the behaviour, since AEAD messages were not standardised nor widely supported. To generate keys that declare AEAD in their preferences, use `generateKey` with `config.aeadProtect = true`. --- src/config/config.js | 9 ++-- src/key/helper.js | 6 ++- test/general/openpgp.js | 111 +++++++++++++++++++++++++++------------- 3 files changed, 87 insertions(+), 39 deletions(-) diff --git a/src/config/config.js b/src/config/config.js index 2b8c35f1..3f93e720 100644 --- a/src/config/config.js +++ b/src/config/config.js @@ -42,12 +42,15 @@ export default { * @property {Integer} deflateLevel Default zip/zlib compression level, between 1 and 9 */ deflateLevel: 6, - /** * Use Authenticated Encryption with Additional Data (AEAD) protection for symmetric encryption. + * This option is applicable to: + * - key generation (encryption key preferences), + * - password-based message encryption, and + * - private key encryption. + * In the case of message encryption using public keys, the encryption key preferences are respected instead. * Note: not all OpenPGP implementations are compatible with this option. - * **FUTURE OPENPGP.JS VERSIONS MAY BREAK COMPATIBILITY WHEN USING THIS OPTION** - * @see {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-07|RFC4880bis-07} + * @see {@link https://tools.ietf.org/html/draft-ietf-openpgp-crypto-refresh-10.html|draft-crypto-refresh-10} * @memberof module:config * @property {Boolean} aeadProtect */ diff --git a/src/key/helper.js b/src/key/helper.js index 15ed4370..852a0c40 100644 --- a/src/key/helper.js +++ b/src/key/helper.js @@ -168,7 +168,11 @@ export async function getPreferredCompressionAlgo(keys = [], date = new Date(), */ export async function getPreferredCipherSuite(keys = [], date = new Date(), userIDs = [], config = defaultConfig) { const selfSigs = await Promise.all(keys.map((key, i) => key.getPrimarySelfSignature(date, userIDs[i], config))); - if (config.aeadProtect && selfSigs.every(selfSig => selfSig.features[0] & enums.features.seipdv2)) { + const withAEAD = keys.length ? + selfSigs.every(selfSig => selfSig.features[0] & enums.features.seipdv2) : + config.aeadProtect; + + if (withAEAD) { const defaultCipherSuite = { symmetricAlgo: enums.symmetric.aes128, aeadAlgo: enums.aead.ocb }; const desiredCipherSuite = { symmetricAlgo: config.preferredSymmetricAlgorithm, aeadAlgo: config.preferredAEADAlgorithm }; return selfSigs.every(selfSig => selfSig.preferredCipherSuites && selfSig.preferredCipherSuites.some( diff --git a/test/general/openpgp.js b/test/general/openpgp.js index 948e8862..2ca7bdbd 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -2040,13 +2040,6 @@ aOU= }); describe('encrypt - unit tests', function() { - it('Does not encrypt to expired key (expiration time subpacket on a direct-key signature)', async function() { - const expiredKey = await openpgp.readKey({ armoredKey: expiredPublicKeyThroughDirectSignature }); - await expect( - openpgp.encrypt({ message: await openpgp.createMessage({ text: 'test' }), encryptionKeys: expiredKey }) - ).to.be.rejectedWith(/Primary key is expired/); - }); - it('should output message of expected format', async function() { const passwords = 'password'; const text = 'test'; @@ -2213,6 +2206,55 @@ VFBLG8uc9IiaKann/DYBAJcZNZHRSfpDoV2pUA5EAEi2MdjxkRysFQnYPRAu }); expect(decrypted.data).to.equal('test'); }); + + it('does not encrypt to expired key (expiration time subpacket on a direct-key signature)', async function() { + const expiredKey = await openpgp.readKey({ armoredKey: expiredPublicKeyThroughDirectSignature }); + await expect( + openpgp.encrypt({ message: await openpgp.createMessage({ text: 'test' }), encryptionKeys: expiredKey }) + ).to.be.rejectedWith(/Primary key is expired/); + }); + + it('uses AEAD when the encryption key prefs support it (SEIPv2', async function() { + const v4PrivateKeyWithOCBPref = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xUsGY4d/4xsAAAAg+U2nu0jWCmHlZ3BqZYfQMxmZu52JGggkLq2EVD34laMAGXKB +exK+cH6NX1hs5hNhIB00TrJmosgv3mg1ditlsLfCsQYfGwoAAABCBYJjh3/jAwsJ +BwUVCg4IDAIWAAKbAwIeCSIhBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce6 +2azJBScJAgcCAAAAAK0oIBA+LX0ifsDm185Ecds2v8lwgyU2kCcUmKfvBXbAf6rh +RYWzuQOwEn7E/aLwIwRaLsdry0+VcallHhSu4RN6HWaEQsiPlR4zxP/TP7mhfVEe +7XWPxtnMUMtf15OyA51YBMdLBmOHf+MZAAAAIIaTJINn+eUBXbki+PSAld2nhJh/ +LVmFsS+60WyvXkQ1AE1gCk95TUR3XFeibg/u/tVY6a//1q0NWC1X+yui3O24wpsG +GBsKAAAALAWCY4d/4wKbDCIhBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce6 +2azJAAAAAAQBIKbpGG2dWTX8j+VjFM21J0hqWlEg+bdiojWnKfA5AQpWUWtnNwDE +M0g12vYxoWM8Y81W+bHBw805I8kWVkXU6vFOi+HWvv/ira7ofJu16NnoUkhclkUr +k0mXubZvyl4GBg== +-----END PGP PRIVATE KEY BLOCK-----` }); + const v6PrivateKeyWithOCBPref = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xUsGY4d/4xsAAAAg+U2nu0jWCmHlZ3BqZYfQMxmZu52JGggkLq2EVD34laMAGXKB +exK+cH6NX1hs5hNhIB00TrJmosgv3mg1ditlsLfCsQYfGwoAAABCBYJjh3/jAwsJ +BwUVCg4IDAIWAAKbAwIeCSIhBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce6 +2azJBScJAgcCAAAAAK0oIBA+LX0ifsDm185Ecds2v8lwgyU2kCcUmKfvBXbAf6rh +RYWzuQOwEn7E/aLwIwRaLsdry0+VcallHhSu4RN6HWaEQsiPlR4zxP/TP7mhfVEe +7XWPxtnMUMtf15OyA51YBMdLBmOHf+MZAAAAIIaTJINn+eUBXbki+PSAld2nhJh/ +LVmFsS+60WyvXkQ1AE1gCk95TUR3XFeibg/u/tVY6a//1q0NWC1X+yui3O24wpsG +GBsKAAAALAWCY4d/4wKbDCIhBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce6 +2azJAAAAAAQBIKbpGG2dWTX8j+VjFM21J0hqWlEg+bdiojWnKfA5AQpWUWtnNwDE +M0g12vYxoWM8Y81W+bHBw805I8kWVkXU6vFOi+HWvv/ira7ofJu16NnoUkhclkUr +k0mXubZvyl4GBg== +-----END PGP PRIVATE KEY BLOCK-----` }); + + const encrypted = await openpgp.encrypt({ + message: await openpgp.createMessage({ text: 'test' }), + encryptionKeys: [v4PrivateKeyWithOCBPref, v6PrivateKeyWithOCBPref], + format: 'object' + }); + + const seipd = encrypted.packets[2]; + expect(seipd).to.be.instanceOf(openpgp.SymEncryptedIntegrityProtectedDataPacket); + expect(seipd.version).to.equal(2); + expect(seipd.aeadAlgorithm).to.equal(openpgp.enums.aead.ocb); + }); }); describe('encryptSessionKey - unit tests', function() { @@ -2241,34 +2283,6 @@ VFBLG8uc9IiaKann/DYBAJcZNZHRSfpDoV2pUA5EAEi2MdjxkRysFQnYPRAu })).to.be.rejectedWith(/No encryption keys or passwords provided/); }); - it('supports decrypting with argon2 s2k (memory-heavy params)', async function() { - const passwords = 'password'; - // Test vector from https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#appendix-A.8.1 - const armoredMessage = `-----BEGIN PGP MESSAGE----- -Comment: Encrypted using AES with 128-bit key -Comment: Session key: 01FE16BBACFD1E7B78EF3B865187374F - -wycEBwScUvg8J/leUNU1RA7N/zE2AQQVnlL8rSLPP5VlQsunlO+ECxHSPgGYGKY+ -YJz4u6F+DDlDBOr5NRQXt/KJIf4m4mOlKyC/uqLbpnLJZMnTq3o79GxBTdIdOzhH -XfA3pqV4mTzF ------END PGP MESSAGE-----`; - const expectedSessionKey = util.hexToUint8Array('01FE16BBACFD1E7B78EF3B865187374F'); - - try { - const [decryptedSessionKey] = await openpgp.decryptSessionKeys({ - message: await openpgp.readMessage({ armoredMessage }), - passwords - }); - expect(decryptedSessionKey.data).to.deep.equal(expectedSessionKey); - expect(decryptedSessionKey.algorithm).to.equal('aes128'); - } catch (err) { - if (detectBrowser()) { // Expected to fail in the CI, especially in Browserstack - expect(err.message).to.match(/Could not allocate required memory/); - } - } - - }); - // keep this after the 'memory-heavy' test to confirm that the Wasm module was successfully reloaded it('supports encrypting with argon2 s2k', async function() { const config = { s2kType: openpgp.enums.s2k.argon2 }; @@ -2349,6 +2363,33 @@ k0mXubZvyl4GBg== expect(sessionKeys).to.have.length(1); expect(sessionKeys[0].algorithm).to.equal(null); // PKESK v6 does not include the algo info }); + + it('supports decrypting with argon2 s2k (memory-heavy params)', async function() { + const passwords = 'password'; + // Test vector from https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#appendix-A.8.1 + const armoredMessage = `-----BEGIN PGP MESSAGE----- +Comment: Encrypted using AES with 128-bit key +Comment: Session key: 01FE16BBACFD1E7B78EF3B865187374F + +wycEBwScUvg8J/leUNU1RA7N/zE2AQQVnlL8rSLPP5VlQsunlO+ECxHSPgGYGKY+ +YJz4u6F+DDlDBOr5NRQXt/KJIf4m4mOlKyC/uqLbpnLJZMnTq3o79GxBTdIdOzhH +XfA3pqV4mTzF +-----END PGP MESSAGE-----`; + const expectedSessionKey = util.hexToUint8Array('01FE16BBACFD1E7B78EF3B865187374F'); + + try { + const [decryptedSessionKey] = await openpgp.decryptSessionKeys({ + message: await openpgp.readMessage({ armoredMessage }), + passwords + }); + expect(decryptedSessionKey.data).to.deep.equal(expectedSessionKey); + expect(decryptedSessionKey.algorithm).to.equal('aes128'); + } catch (err) { + if (detectBrowser()) { // Expected to fail in the CI, especially in Browserstack + expect(err.message).to.match(/Could not allocate required memory/); + } + } + }); }); describe('encrypt, decrypt, sign, verify - integration tests', function() { From 1ebf7034f57d717be361461654c9d5c4d0dcc293 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Tue, 28 Mar 2023 19:26:40 +0200 Subject: [PATCH 060/201] `crypto-refresh`: add support for Ed448 --- package-lock.json | 36 ++++++++++++--- package.json | 3 +- src/crypto/crypto.js | 49 ++++++++++++++++----- src/crypto/public_key/elliptic/ecdh_x.js | 13 ++++++ src/crypto/public_key/elliptic/eddsa.js | 46 +++++++++++++++---- src/crypto/signature.js | 15 +++++-- src/key/helper.js | 3 ++ test/crypto/crypto.js | 15 +++++++ test/general/key.js | 28 ++++++++++++ test/general/openpgp.js | 56 ++++++++++++++++++++++++ 10 files changed, 232 insertions(+), 32 deletions(-) diff --git a/package-lock.json b/package-lock.json index f1439c74..feafc4e0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,8 @@ "@openpgp/asmcrypto.js": "^3.0.0", "@openpgp/elliptic": "^6.5.1", "@openpgp/jsdoc": "^3.6.11", - "@openpgp/noble-hashes": "^1.3.2-1", + "@openpgp/noble-curves": "^1.2.1-0", + "@openpgp/noble-hashes": "^1.3.3-0", "@openpgp/seek-bzip": "^1.0.5-git", "@openpgp/tweetnacl": "^1.0.3", "@openpgp/web-stream-tools": "^0.0.14", @@ -660,10 +661,22 @@ "node": ">=10" } }, + "node_modules/@openpgp/noble-curves": { + "version": "1.2.1-0", + "resolved": "https://registry.npmjs.org/@openpgp/noble-curves/-/noble-curves-1.2.1-0.tgz", + "integrity": "sha512-RUJ3NIGJ04VbUHEOXYxXKKgD+u7D5fJYUox3Ewu1mPbgdjEUvS96nq6xZrCPCCyOTJlyh7jR1tcbOUzWJFiJbQ==", + "dev": true, + "dependencies": { + "@openpgp/noble-hashes": "1.3.3-0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@openpgp/noble-hashes": { - "version": "1.3.2-1", - "resolved": "https://registry.npmjs.org/@openpgp/noble-hashes/-/noble-hashes-1.3.2-1.tgz", - "integrity": "sha512-4pmVh5O+bq1vO4xIAQXh0m7AxasEidFmHA1zm3Fk46IsLObz8pI43EyuLdwqs/6cmL6vAUCde/Xh2MYrVZd5bw==", + "version": "1.3.3-0", + "resolved": "https://registry.npmjs.org/@openpgp/noble-hashes/-/noble-hashes-1.3.3-0.tgz", + "integrity": "sha512-2MOWNAzEm5fMu3u90HSLxddYU6Fr8P7/7knXrPHyS7DiJevOlDmPES/AZxcWQfhHrwdNLL0fRVdOHkftvIcXVQ==", "dev": true, "dependencies": { "@types/bn.js": "^4.11.6", @@ -8145,10 +8158,19 @@ } } }, + "@openpgp/noble-curves": { + "version": "1.2.1-0", + "resolved": "https://registry.npmjs.org/@openpgp/noble-curves/-/noble-curves-1.2.1-0.tgz", + "integrity": "sha512-RUJ3NIGJ04VbUHEOXYxXKKgD+u7D5fJYUox3Ewu1mPbgdjEUvS96nq6xZrCPCCyOTJlyh7jR1tcbOUzWJFiJbQ==", + "dev": true, + "requires": { + "@openpgp/noble-hashes": "1.3.3-0" + } + }, "@openpgp/noble-hashes": { - "version": "1.3.2-1", - "resolved": "https://registry.npmjs.org/@openpgp/noble-hashes/-/noble-hashes-1.3.2-1.tgz", - "integrity": "sha512-4pmVh5O+bq1vO4xIAQXh0m7AxasEidFmHA1zm3Fk46IsLObz8pI43EyuLdwqs/6cmL6vAUCde/Xh2MYrVZd5bw==", + "version": "1.3.3-0", + "resolved": "https://registry.npmjs.org/@openpgp/noble-hashes/-/noble-hashes-1.3.3-0.tgz", + "integrity": "sha512-2MOWNAzEm5fMu3u90HSLxddYU6Fr8P7/7knXrPHyS7DiJevOlDmPES/AZxcWQfhHrwdNLL0fRVdOHkftvIcXVQ==", "dev": true, "requires": { "@types/bn.js": "^4.11.6", diff --git a/package.json b/package.json index d73390ec..c8b4f351 100644 --- a/package.json +++ b/package.json @@ -63,9 +63,10 @@ }, "devDependencies": { "@openpgp/asmcrypto.js": "^3.0.0", + "@openpgp/noble-curves": "^1.2.1-0", "@openpgp/elliptic": "^6.5.1", "@openpgp/jsdoc": "^3.6.11", - "@openpgp/noble-hashes": "^1.3.2-1", + "@openpgp/noble-hashes": "^1.3.3-0", "@openpgp/seek-bzip": "^1.0.5-git", "@openpgp/tweetnacl": "^1.0.3", "@openpgp/web-stream-tools": "^0.0.14", diff --git a/src/crypto/crypto.js b/src/crypto/crypto.js index fa252a09..bdb3fd28 100644 --- a/src/crypto/crypto.js +++ b/src/crypto/crypto.js @@ -32,7 +32,6 @@ import KDFParams from '../type/kdf_params'; import enums from '../enums'; import util from '../util'; import OID from '../type/oid'; -import { CurveWithOID } from './public_key/elliptic/oid_curves'; import { UnsupportedError } from '../packet/packet'; import ECDHXSymmetricKey from '../type/ecdh_x_symkey'; @@ -182,8 +181,9 @@ export function parsePublicKeyParams(algo, bytes) { return { read: read, publicParams: { oid, Q, kdfParams } }; } case enums.publicKey.ed25519: + case enums.publicKey.ed448: case enums.publicKey.x25519: { - const A = bytes.subarray(read, read + 32); read += A.length; + const A = bytes.subarray(read, read + getCurvePayloadSize(algo)); read += A.length; return { read, publicParams: { A } }; } default: @@ -217,19 +217,21 @@ export function parsePrivateKeyParams(algo, bytes, publicParams) { } case enums.publicKey.ecdsa: case enums.publicKey.ecdh: { - const curve = new CurveWithOID(publicParams.oid); + const payloadSize = getCurvePayloadSize(algo, publicParams.oid); let d = util.readMPI(bytes.subarray(read)); read += d.length + 2; - d = util.leftPad(d, curve.payloadSize); + d = util.leftPad(d, payloadSize); return { read, privateParams: { d } }; } case enums.publicKey.eddsaLegacy: { - const curve = new CurveWithOID(publicParams.oid); + const payloadSize = getCurvePayloadSize(algo, publicParams.oid); let seed = util.readMPI(bytes.subarray(read)); read += seed.length + 2; - seed = util.leftPad(seed, curve.payloadSize); + seed = util.leftPad(seed, payloadSize); return { read, privateParams: { seed } }; } - case enums.publicKey.ed25519: { - const seed = bytes.subarray(read, read + 32); read += seed.length; + case enums.publicKey.ed25519: + case enums.publicKey.ed448: { + const payloadSize = getCurvePayloadSize(algo); + const seed = bytes.subarray(read, read + payloadSize); read += seed.length; return { read, privateParams: { seed } }; } case enums.publicKey.x25519: { @@ -296,7 +298,7 @@ export function parseEncSessionKeyParams(algo, bytes) { */ export function serializeParams(algo, params) { // Some algorithms do not rely on MPIs to store the binary params - const algosWithNativeRepresentation = new Set([enums.publicKey.ed25519, enums.publicKey.x25519]); + const algosWithNativeRepresentation = new Set([enums.publicKey.ed25519, enums.publicKey.x25519, enums.publicKey.ed448]); const orderedParams = Object.keys(params).map(name => { const param = params[name]; if (!util.isUint8Array(param)) return param.write(); @@ -343,6 +345,7 @@ export function generateParams(algo, bits, oid) { } })); case enums.publicKey.ed25519: + case enums.publicKey.ed448: return publicKey.elliptic.eddsa.generate(algo).then(({ A, seed }) => ({ privateParams: { seed }, publicParams: { A } @@ -402,7 +405,8 @@ export async function validateParams(algo, publicParams, privateParams) { const { seed } = privateParams; return publicKey.elliptic.eddsaLegacy.validateParams(oid, Q, seed); } - case enums.publicKey.ed25519: { + case enums.publicKey.ed25519: + case enums.publicKey.ed448: { const { A } = publicParams; const { seed } = privateParams; return publicKey.elliptic.eddsa.validateParams(algo, A, seed); @@ -469,7 +473,29 @@ function checkSupportedCurve(oid) { } /** - * Get preferred hash algo for a given elliptic algo + * Get encoded secret size for a given elliptic algo + * @param {module:enums.publicKey} algo - alrogithm identifier + * @param {module:type/oid} [oid] - curve OID if needed by algo + */ +export function getCurvePayloadSize(algo, oid) { + switch (algo) { + case enums.publicKey.ecdsa: + case enums.publicKey.ecdh: + case enums.publicKey.eddsaLegacy: + return new publicKey.elliptic.CurveWithOID(oid).payloadSize; + case enums.publicKey.ed25519: + case enums.publicKey.ed448: + return publicKey.elliptic.eddsa.getPayloadSize(algo); + case enums.publicKey.x25519: + case enums.publicKey.x448: + return publicKey.elliptic.ecdhX.getPayloadSize(algo); + default: + throw new Error('Unknown elliptic algo'); + } +} + +/** + * Get preferred signing hash algo for a given elliptic algo * @param {module:enums.publicKey} algo - alrogithm identifier * @param {module:type/oid} [oid] - curve OID if needed by algo */ @@ -479,6 +505,7 @@ export function getPreferredCurveHashAlgo(algo, oid) { case enums.publicKey.eddsaLegacy: return publicKey.elliptic.getPreferredHashAlgo(oid); case enums.publicKey.ed25519: + case enums.publicKey.ed448: return publicKey.elliptic.eddsa.getPreferredHashAlgo(algo); default: throw new Error('Unknown elliptic signing algo'); diff --git a/src/crypto/public_key/elliptic/ecdh_x.js b/src/crypto/public_key/elliptic/ecdh_x.js index 1e0b3861..d5d3f10e 100644 --- a/src/crypto/public_key/elliptic/ecdh_x.js +++ b/src/crypto/public_key/elliptic/ecdh_x.js @@ -120,3 +120,16 @@ export async function decrypt(algo, ephemeralPublicKey, wrappedKey, A, k) { throw new Error('Unsupported ECDH algorithm'); } } + +export function getPayloadSize(algo) { + switch (algo) { + case enums.publicKey.x25519: + return 32; + + case enums.publicKey.x448: + return 56; + + default: + throw new Error('Unsupported ECDH algorithm'); + } +} diff --git a/src/crypto/public_key/elliptic/eddsa.js b/src/crypto/public_key/elliptic/eddsa.js index 002f3f29..bcab724f 100644 --- a/src/crypto/public_key/elliptic/eddsa.js +++ b/src/crypto/public_key/elliptic/eddsa.js @@ -21,13 +21,14 @@ */ import { sha512 } from '@openpgp/noble-hashes/sha512'; -import nacl from '@openpgp/tweetnacl/nacl-fast-light'; +import ed25519 from '@openpgp/tweetnacl/nacl-fast-light'; +import { ed448 } from '@openpgp/noble-curves/ed448'; import util from '../../../util'; import enums from '../../../enums'; import hash from '../../hash'; import { getRandomBytes } from '../../random'; -nacl.hash = bytes => sha512(bytes); +ed25519.hash = bytes => sha512(bytes); /** * Generate (non-legacy) EdDSA key @@ -35,10 +36,15 @@ nacl.hash = bytes => sha512(bytes); * @returns {Promise<{ A: Uint8Array, seed: Uint8Array }>} */ export async function generate(algo) { + const seed = getRandomBytes(getPayloadSize(algo)); + switch (algo) { case enums.publicKey.ed25519: { - const seed = getRandomBytes(32); - const { publicKey: A } = nacl.sign.keyPair.fromSeed(seed); + const { publicKey: A } = ed25519.sign.keyPair.fromSeed(seed); + return { A, seed }; + } + case enums.publicKey.ed448: { + const A = ed448.getPublicKey(seed); return { A, seed }; } default: @@ -66,10 +72,13 @@ export async function sign(algo, hashAlgo, message, publicKey, privateKey, hashe switch (algo) { case enums.publicKey.ed25519: { const secretKey = util.concatUint8Array([privateKey, publicKey]); - const signature = nacl.sign.detached(hashed, secretKey); + const signature = ed25519.sign.detached(hashed, secretKey); + return { RS: signature }; + } + case enums.publicKey.ed448: { + const signature = ed448.sign(hashed, privateKey); return { RS: signature }; } - case enums.publicKey.ed448: default: throw new Error('Unsupported EdDSA algorithm'); } @@ -93,9 +102,10 @@ export async function verify(algo, hashAlgo, { RS }, m, publicKey, hashed) { } switch (algo) { case enums.publicKey.ed25519: { - return nacl.sign.detached.verify(hashed, RS, publicKey); + return ed25519.sign.detached.verify(hashed, RS, publicKey); } case enums.publicKey.ed448: + return ed448.verify(RS, hashed, publicKey); default: throw new Error('Unsupported EdDSA algorithm'); } @@ -116,20 +126,38 @@ export async function validateParams(algo, A, seed) { * Derive public point A' from private key * and expect A == A' */ - const { publicKey } = nacl.sign.keyPair.fromSeed(seed); + const { publicKey } = ed25519.sign.keyPair.fromSeed(seed); return util.equalsUint8Array(A, publicKey); } - case enums.publicKey.ed448: // unsupported + case enums.publicKey.ed448: { + const publicKey = ed448.getPublicKey(seed); + return util.equalsUint8Array(A, publicKey); + } default: return false; } } +export function getPayloadSize(algo) { + switch (algo) { + case enums.publicKey.ed25519: + return 32; + + case enums.publicKey.ed448: + return 57; + + default: + throw new Error('Unsupported EdDSA algorithm'); + } +} + export function getPreferredHashAlgo(algo) { switch (algo) { case enums.publicKey.ed25519: return enums.hash.sha256; + case enums.publicKey.ed448: + return enums.hash.sha512; default: throw new Error('Unknown EdDSA algo'); } diff --git a/src/crypto/signature.js b/src/crypto/signature.js index 00c7086c..5d3db48d 100644 --- a/src/crypto/signature.js +++ b/src/crypto/signature.js @@ -56,10 +56,15 @@ export function parseSignatureParams(algo, signature) { } // Algorithm-Specific Fields for Ed25519 signatures: // - 64 octets of the native signature - case enums.publicKey.ed25519: { - const RS = signature.subarray(read, read + 64); read += RS.length; + // Algorithm-Specific Fields for Ed448 signatures: + // - 114 octets of the native signature + case enums.publicKey.ed25519: + case enums.publicKey.ed448: { + const rsSize = 2 * publicKey.elliptic.eddsa.getPayloadSize(algo); + const RS = signature.subarray(read, read + rsSize); read += RS.length; return { RS }; } + default: throw new UnsupportedError('Unknown signature algorithm.'); } @@ -106,7 +111,8 @@ export async function verify(algo, hashAlgo, signature, publicParams, data, hash // signature already padded on parsing return publicKey.elliptic.eddsaLegacy.verify(oid, hashAlgo, signature, data, Q, hashed); } - case enums.publicKey.ed25519: { + case enums.publicKey.ed25519: + case enums.publicKey.ed448: { const { A } = publicParams; return publicKey.elliptic.eddsa.verify(algo, hashAlgo, signature, data, A, hashed); } @@ -160,7 +166,8 @@ export async function sign(algo, hashAlgo, publicKeyParams, privateKeyParams, da const { seed } = privateKeyParams; return publicKey.elliptic.eddsaLegacy.sign(oid, hashAlgo, data, Q, seed, hashed); } - case enums.publicKey.ed25519: { + case enums.publicKey.ed25519: + case enums.publicKey.ed448: { const { A } = publicKeyParams; const { seed } = privateKeyParams; return publicKey.elliptic.eddsa.sign(algo, hashAlgo, data, A, seed, hashed); diff --git a/src/key/helper.js b/src/key/helper.js index 852a0c40..d2795a89 100644 --- a/src/key/helper.js +++ b/src/key/helper.js @@ -127,8 +127,10 @@ export async function getPreferredHashAlgo(key, keyPacket, date = new Date(), us case enums.publicKey.ecdsa: case enums.publicKey.eddsaLegacy: case enums.publicKey.ed25519: + case enums.publicKey.ed448: prefAlgo = crypto.getPreferredCurveHashAlgo(keyPacket.algorithm, keyPacket.publicParams.oid); } + return crypto.hash.getHashByteLength(hashAlgo) <= crypto.hash.getHashByteLength(prefAlgo) ? prefAlgo : hashAlgo; } @@ -365,6 +367,7 @@ export function isValidEncryptionKeyPacket(keyPacket, signature) { keyAlgo !== enums.publicKey.ecdsa && keyAlgo !== enums.publicKey.eddsaLegacy && keyAlgo !== enums.publicKey.ed25519 && + keyAlgo !== enums.publicKey.ed448 && (!signature.keyFlags || (signature.keyFlags[0] & enums.keyFlags.encryptCommunication) !== 0 || (signature.keyFlags[0] & enums.keyFlags.encryptStorage) !== 0); diff --git a/test/crypto/crypto.js b/test/crypto/crypto.js index e5bbeaf9..1d017d84 100644 --- a/test/crypto/crypto.js +++ b/test/crypto/crypto.js @@ -229,6 +229,21 @@ export default () => describe('API functional testing', function() { return expect(success).to.be.true; }); + + it('Ed448', async function () { + // key data from https://www.rfc-editor.org/rfc/rfc8032#section-7.4 + const seed = util.hexToUint8Array('d65df341ad13e008567688baedda8e9dcdc17dc024974ea5b4227b6530e339bff21f99e68ca6968f3cca6dfe0fb9f4fab4fa135d5542ea3f01'); + const A = util.hexToUint8Array('df9705f58edbab802c7f8363cfe5560ab1c6132c20a9f1dd163483a26f8ac53a39d6808bf4a1dfbd261b099bb03b3fb50906cb28bd8a081f00'); + const toSign = await crypto.hash.digest(openpgp.enums.hash.sha512, data); + const signedData = await crypto.signature.sign( + openpgp.enums.publicKey.ed448, openpgp.enums.hash.sha512, { A }, { seed }, data, toSign + ); + const success = await crypto.signature.verify( + openpgp.enums.publicKey.ed448, openpgp.enums.hash.sha512, signedData, { A }, data, toSign + ); + + return expect(success).to.be.true; + }); }); describe('Encrypt and decrypt', function () { diff --git a/test/general/key.js b/test/general/key.js index 68d956d5..0a2fb66a 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -3220,6 +3220,34 @@ aU71tdtNBQ== expect(encryptionKey.getAlgorithmInfo()).to.deep.equal({ algorithm: 'x25519' }); }); + it('Parsing V4 key using curve448 format', async function() { + const privateKey = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xX0GZRqLYhwAAAA5U/IaIOge/FoLzCetXKx029bdJHCz2hMFBRMuzq4msjaT ++hLeV6puyC/PeSEfaanqTuo31vvsti2AAIttr4GDGXF4vfPzbzkWV9dT4VVs +IU7QqLv1hzwZ+k7pHroRyXnUiYxRYHuzlg7Vw4CrAtN/8T65OMLAHgYfHAoA +AAA9BQJlGotiIqEGAxidsHRHDsyFTw1Q7OoGEAEnRnxthKMwVBqhIL2o+HUC +GwMCHgkCCwcDFQoIAhYAAycHAgAAAAA2KiC+Y+fhQ/48CkT9WrXTX9SCn3vH +z43Wb++AkmpWL1HQmrJE3S4gGltezZK2E9ovagzxKxVrL14uC6hs6kJ0JIiW +QSeMeexCTy+Gdr6j0wb4FhFNnoIu3yu2ABmZpFX/5/191YeWUryKFDAoUZmK +gQTSOzJEvyO0ACR5L4vV3ADceOAdG8/sqhE89rTSevFXng4JAM0XVXNlckEg +PFVzZXJBQHRlc3QudGVzdD7CwA0GExwKAAAALAUCZRqLYiKhBgMYnbB0Rw7M +hU8NUOzqBhABJ0Z8bYSjMFQaoSC9qPh1AhkBAAAAAFw/IH72M1iyzMWhbgtw +v0SR/XxvOIW/ZrT4Ix9236lvoOE4taL/D46CbZOjm7VAeOSfSdxt1xSKnoAL +RsCNQ8tVPjPXclzqr6R8MbPIgBWxKcMS2eStYpBbG5qAmc+K5jdA2xcl9iW5 +bWleZ1LTah4lF6qCiD73IffADXtzw8iAMTX+0wM5N1tJUEGvgqe00ohRKiQA +-----END PGP PRIVATE KEY BLOCK-----` }); + // sanity checks + await expect(privateKey.validate()).to.be.fulfilled; + const signingKey = await privateKey.getSigningKey(); + expect(signingKey.keyPacket.algorithm).to.equal(openpgp.enums.publicKey.ed448); + expect(signingKey.getAlgorithmInfo()).to.deep.equal({ algorithm: 'ed448' }); + + // const encryptionKey = await privateKey.getEncryptionKey(); + // expect(encryptionKey.keyPacket.algorithm).to.equal(openpgp.enums.publicKey.x25519); + // expect(encryptionKey.getAlgorithmInfo()).to.deep.equal({ algorithm: 'x25519' }); + }); + it('Testing key ID and fingerprint for V4 keys', async function() { const pubKeysV4 = await openpgp.readKeys({ armoredKeys: twoKeys }); expect(pubKeysV4).to.exist; diff --git a/test/general/openpgp.js b/test/general/openpgp.js index 2ca7bdbd..e159f30b 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -4423,6 +4423,62 @@ J/qaHc+qmcEpIMmPNvLQ7n4F4kEXk8Zwz+OXovVWLQ+Njl5gzooF expect(signatures).to.have.length(1); expect(await signatures[0].verified).to.be.true; }); + + it('sign/verify with Ed448', async function () { + const privateKey = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xX0GZRqLYhwAAAA5U/IaIOge/FoLzCetXKx029bdJHCz2hMFBRMuzq4msjaT ++hLeV6puyC/PeSEfaanqTuo31vvsti2AAIttr4GDGXF4vfPzbzkWV9dT4VVs +IU7QqLv1hzwZ+k7pHroRyXnUiYxRYHuzlg7Vw4CrAtN/8T65OMLAHgYfHAoA +AAA9BQJlGotiIqEGAxidsHRHDsyFTw1Q7OoGEAEnRnxthKMwVBqhIL2o+HUC +GwMCHgkCCwcDFQoIAhYAAycHAgAAAAA2KiC+Y+fhQ/48CkT9WrXTX9SCn3vH +z43Wb++AkmpWL1HQmrJE3S4gGltezZK2E9ovagzxKxVrL14uC6hs6kJ0JIiW +QSeMeexCTy+Gdr6j0wb4FhFNnoIu3yu2ABmZpFX/5/191YeWUryKFDAoUZmK +gQTSOzJEvyO0ACR5L4vV3ADceOAdG8/sqhE89rTSevFXng4JAM0XVXNlckEg +PFVzZXJBQHRlc3QudGVzdD7CwA0GExwKAAAALAUCZRqLYiKhBgMYnbB0Rw7M +hU8NUOzqBhABJ0Z8bYSjMFQaoSC9qPh1AhkBAAAAAFw/IH72M1iyzMWhbgtw +v0SR/XxvOIW/ZrT4Ix9236lvoOE4taL/D46CbZOjm7VAeOSfSdxt1xSKnoAL +RsCNQ8tVPjPXclzqr6R8MbPIgBWxKcMS2eStYpBbG5qAmc+K5jdA2xcl9iW5 +bWleZ1LTah4lF6qCiD73IffADXtzw8iAMTX+0wM5N1tJUEGvgqe00ohRKiQA +-----END PGP PRIVATE KEY BLOCK-----` }); + const plaintext = 'plaintext'; + + const signed = await openpgp.sign({ + message: await openpgp.createMessage({ text: plaintext }), + signingKeys: privateKey + }); + + const { signatures, data } = await openpgp.verify({ + message: await openpgp.readMessage({ armoredMessage: signed }), + verificationKeys: privateKey + }); + expect(data).to.equal(plaintext); + expect(signatures).to.have.length(1); + expect(await signatures[0].verified).to.be.true; + }); + + it('should enforce using 512-bit signature digest', async function () { + // X448 key using sha256 for self signatures + const privateKeySHA256 = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xXsEZCWHXBwwtqciq6ZFU13s+dyhkWR5tOEmF1oX8OiP1B5ypfqyGVM8DkQh +5eTIMwB1oqJCROANoyA0q2dSigAAbDA5xr74DeClPPXC4ZXJ9uzuJWKvQvE8 +x3EflhgoQCGBM7JfvH5zwdrJvPt8RKDvm0QkZzhPvnFoHnzNBHRlc3TCugQQ +HAgAPgWCZCWHXAQLCQcICZDsN6h/ys3ppwMVCAoEFgACAQIZAQKbAwIeARYh +BOJyE9P2eIcU2N2Ne+w3qH/KzemnAAAh1hTFCcEU77bU3YelrJTCNIOQnvt7 +Hs6yZz2053CQTOC+wHkUQLaYYBEXSNyLZxoyv+NuGTiwbuYtAOlbE2erM7Cx +8B2Qz7M29UkFLMBUfb+yi+gTYYUWCXVQ7Um7MGjjgUG8+9p452i6f28mhRD8 +tTgNAMd5BGQlh1wavTIFgILtbzrqQCiwDGx0YcFNzu9+FZ8vK5Mmm7UEZj0a +y7FWQtZw8tTaU6mY+RrSa52RjzkGLtQAQO++tgYqc+BnCFdCZ3ZYPRvD3mof +ffoo3l4xmto+iyvJZbQ4wQPXttg7VjCpEfOsL9TW9Xs09aIbysKmBBgcCAAq +BYJkJYdcCZDsN6h/ys3ppwKbDBYhBOJyE9P2eIcU2N2Ne+w3qH/KzemnAAC0 +6/eZhh/Oj2gRdab2JeFGWACGIRDKxPXsWRCXR4YrSxcvCKK6rOvsyxQsgIsJ +JyPYkRPfmbKcseUDAEkSBLAfeizDGh7ea0GOdIMhwE/CW4f/H8ULbwi36y13 +x3oMNVaYsI9dZ588Gpi8XYy2jOtqIPQ1AA== +-----END PGP PRIVATE KEY BLOCK-----` }); + + await expect(privateKeySHA256.getSigningKey()).to.be.rejectedWith(/Hash algorithm too weak for EdDSA/); + }); }); describe('Errors', function() { From 56cd448a3219a4174ca29a51734a41f26620047e Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Thu, 30 Mar 2023 15:35:50 +0200 Subject: [PATCH 061/201] `crypto-refresh`: add support for X448 --- src/crypto/crypto.js | 38 ++++++--- src/crypto/public_key/elliptic/ecdh_x.js | 54 +++++++++++-- src/key/helper.js | 1 + src/message.js | 5 +- .../public_key_encrypted_session_key.js | 9 ++- test/crypto/ecdh.js | 10 +++ test/crypto/validate.js | 55 +++++++++++++ test/general/key.js | 43 ++++++---- test/general/openpgp.js | 80 ++++++++++++++++++- 9 files changed, 253 insertions(+), 42 deletions(-) diff --git a/src/crypto/crypto.js b/src/crypto/crypto.js index bdb3fd28..a9293e75 100644 --- a/src/crypto/crypto.js +++ b/src/crypto/crypto.js @@ -64,10 +64,11 @@ export async function publicKeyEncrypt(keyAlgo, symmetricAlgo, publicParams, dat oid, kdfParams, data, Q, fingerprint); return { V, C: new ECDHSymkey(C) }; } - case enums.publicKey.x25519: { + case enums.publicKey.x25519: + case enums.publicKey.x448: { if (!util.isAES(symmetricAlgo)) { // see https://gitlab.com/openpgp-wg/rfc4880bis/-/merge_requests/276 - throw new Error('X25519 keys can only encrypt AES session keys'); + throw new Error('X25519 and X448 keys can only encrypt AES session keys'); } const { A } = publicParams; const { ephemeralPublicKey, wrappedKey } = await publicKey.elliptic.ecdhX.encrypt( @@ -116,7 +117,8 @@ export async function publicKeyDecrypt(algo, publicKeyParams, privateKeyParams, return publicKey.elliptic.ecdh.decrypt( oid, kdfParams, V, C.data, Q, d, fingerprint); } - case enums.publicKey.x25519: { + case enums.publicKey.x25519: + case enums.publicKey.x448: { const { A } = publicKeyParams; const { k } = privateKeyParams; const { ephemeralPublicKey, C } = sessionKeyParams; @@ -182,7 +184,8 @@ export function parsePublicKeyParams(algo, bytes) { } case enums.publicKey.ed25519: case enums.publicKey.ed448: - case enums.publicKey.x25519: { + case enums.publicKey.x25519: + case enums.publicKey.x448: { const A = bytes.subarray(read, read + getCurvePayloadSize(algo)); read += A.length; return { read, publicParams: { A } }; } @@ -234,8 +237,10 @@ export function parsePrivateKeyParams(algo, bytes, publicParams) { const seed = bytes.subarray(read, read + payloadSize); read += seed.length; return { read, privateParams: { seed } }; } - case enums.publicKey.x25519: { - const k = bytes.subarray(read, read + 32); read += k.length; + case enums.publicKey.x25519: + case enums.publicKey.x448: { + const payloadSize = getCurvePayloadSize(algo); + const k = bytes.subarray(read, read + payloadSize); read += k.length; return { read, privateParams: { k } }; } default: @@ -275,13 +280,15 @@ export function parseEncSessionKeyParams(algo, bytes) { const C = new ECDHSymkey(); C.read(bytes.subarray(read)); return { V, C }; } - // Algorithm-Specific Fields for X25519 encrypted session keys: - // - 32 octets representing an ephemeral X25519 public key. + // Algorithm-Specific Fields for X25519 or X448 encrypted session keys: + // - 32 octets representing an ephemeral X25519 public key (or 57 octets for X448). // - A one-octet size of the following fields. // - The one-octet algorithm identifier, if it was passed (in the case of a v3 PKESK packet). // - The encrypted session key. - case enums.publicKey.x25519: { - const ephemeralPublicKey = bytes.subarray(read, read + 32); read += ephemeralPublicKey.length; + case enums.publicKey.x25519: + case enums.publicKey.x448: { + const pointSize = getCurvePayloadSize(algo); + const ephemeralPublicKey = bytes.subarray(read, read + pointSize); read += ephemeralPublicKey.length; const C = new ECDHXSymmetricKey(); C.read(bytes.subarray(read)); return { ephemeralPublicKey, C }; } @@ -298,7 +305,12 @@ export function parseEncSessionKeyParams(algo, bytes) { */ export function serializeParams(algo, params) { // Some algorithms do not rely on MPIs to store the binary params - const algosWithNativeRepresentation = new Set([enums.publicKey.ed25519, enums.publicKey.x25519, enums.publicKey.ed448]); + const algosWithNativeRepresentation = new Set([ + enums.publicKey.ed25519, + enums.publicKey.x25519, + enums.publicKey.ed448, + enums.publicKey.x448 + ]); const orderedParams = Object.keys(params).map(name => { const param = params[name]; if (!util.isUint8Array(param)) return param.write(); @@ -351,6 +363,7 @@ export function generateParams(algo, bits, oid) { publicParams: { A } })); case enums.publicKey.x25519: + case enums.publicKey.x448: return publicKey.elliptic.ecdhX.generate(algo).then(({ A, k }) => ({ privateParams: { k }, publicParams: { A } @@ -411,7 +424,8 @@ export async function validateParams(algo, publicParams, privateParams) { const { seed } = privateParams; return publicKey.elliptic.eddsa.validateParams(algo, A, seed); } - case enums.publicKey.x25519: { + case enums.publicKey.x25519: + case enums.publicKey.x448: { const { A } = publicParams; const { k } = privateParams; return publicKey.elliptic.ecdhX.validateParams(algo, A, k); diff --git a/src/crypto/public_key/elliptic/ecdh_x.js b/src/crypto/public_key/elliptic/ecdh_x.js index d5d3f10e..decdeaab 100644 --- a/src/crypto/public_key/elliptic/ecdh_x.js +++ b/src/crypto/public_key/elliptic/ecdh_x.js @@ -3,7 +3,8 @@ * @module crypto/public_key/elliptic/ecdh */ -import nacl from '@openpgp/tweetnacl/nacl-fast-light'; +import x25519 from '@openpgp/tweetnacl/nacl-fast-light'; +import { x448 } from '@openpgp/noble-curves/ed448'; import * as aesKW from '../../aes_kw'; import { getRandomBytes } from '../../random'; @@ -13,7 +14,8 @@ import getCipher from '../../cipher/getCipher'; import computeHKDF from '../../hkdf'; const HKDF_INFO = { - x25519: util.encodeUTF8('OpenPGP X25519') + x25519: util.encodeUTF8('OpenPGP X25519'), + x448: util.encodeUTF8('OpenPGP X448') }; /** @@ -26,7 +28,12 @@ export async function generate(algo) { case enums.publicKey.x25519: { // k stays in little-endian, unlike legacy ECDH over curve25519 const k = getRandomBytes(32); - const { publicKey: A } = nacl.box.keyPair.fromSecretKey(k); + const { publicKey: A } = x25519.box.keyPair.fromSecretKey(k); + return { A, k }; + } + case enums.publicKey.x448: { + const k = x448.utils.randomPrivateKey(); + const A = x448.getPublicKey(k); return { A, k }; } default: @@ -49,7 +56,15 @@ export async function validateParams(algo, A, k) { * Derive public point A' from private key * and expect A == A' */ - const { publicKey } = nacl.box.keyPair.fromSecretKey(k); + const { publicKey } = x25519.box.keyPair.fromSecretKey(k); + return util.equalsUint8Array(A, publicKey); + } + case enums.publicKey.x448: { + /** + * Derive public point A' from private key + * and expect A == A' + */ + const publicKey = x448.getPublicKey(k); return util.equalsUint8Array(A, publicKey); } @@ -74,8 +89,8 @@ export async function encrypt(algo, data, recipientA) { switch (algo) { case enums.publicKey.x25519: { const ephemeralSecretKey = getRandomBytes(32); - const sharedSecret = nacl.scalarMult(ephemeralSecretKey, recipientA); - const { publicKey: ephemeralPublicKey } = nacl.box.keyPair.fromSecretKey(ephemeralSecretKey); + const sharedSecret = x25519.scalarMult(ephemeralSecretKey, recipientA); + const { publicKey: ephemeralPublicKey } = x25519.box.keyPair.fromSecretKey(ephemeralSecretKey); const hkdfInput = util.concatUint8Array([ ephemeralPublicKey, recipientA, @@ -86,6 +101,20 @@ export async function encrypt(algo, data, recipientA) { const wrappedKey = aesKW.wrap(encryptionKey, data); return { ephemeralPublicKey, wrappedKey }; } + case enums.publicKey.x448: { + const ephemeralSecretKey = x448.utils.randomPrivateKey(); + const sharedSecret = x448.getSharedSecret(ephemeralSecretKey, recipientA); + const ephemeralPublicKey = x448.getPublicKey(ephemeralSecretKey); + const hkdfInput = util.concatUint8Array([ + ephemeralPublicKey, + recipientA, + sharedSecret + ]); + const { keySize } = getCipher(enums.symmetric.aes256); + const encryptionKey = await computeHKDF(enums.hash.sha512, hkdfInput, new Uint8Array(), HKDF_INFO.x448, keySize); + const wrappedKey = aesKW.wrap(encryptionKey, data); + return { ephemeralPublicKey, wrappedKey }; + } default: throw new Error('Unsupported ECDH algorithm'); @@ -106,7 +135,7 @@ export async function encrypt(algo, data, recipientA) { export async function decrypt(algo, ephemeralPublicKey, wrappedKey, A, k) { switch (algo) { case enums.publicKey.x25519: { - const sharedSecret = nacl.scalarMult(k, ephemeralPublicKey); + const sharedSecret = x25519.scalarMult(k, ephemeralPublicKey); const hkdfInput = util.concatUint8Array([ ephemeralPublicKey, A, @@ -116,6 +145,17 @@ export async function decrypt(algo, ephemeralPublicKey, wrappedKey, A, k) { const encryptionKey = await computeHKDF(enums.hash.sha256, hkdfInput, new Uint8Array(), HKDF_INFO.x25519, keySize); return aesKW.unwrap(encryptionKey, wrappedKey); } + case enums.publicKey.x448: { + const sharedSecret = x448.getSharedSecret(k, ephemeralPublicKey); + const hkdfInput = util.concatUint8Array([ + ephemeralPublicKey, + A, + sharedSecret + ]); + const { keySize } = getCipher(enums.symmetric.aes256); + const encryptionKey = await computeHKDF(enums.hash.sha512, hkdfInput, new Uint8Array(), HKDF_INFO.x448, keySize); + return aesKW.unwrap(encryptionKey, wrappedKey); + } default: throw new Error('Unsupported ECDH algorithm'); } diff --git a/src/key/helper.js b/src/key/helper.js index d2795a89..e887ed19 100644 --- a/src/key/helper.js +++ b/src/key/helper.js @@ -356,6 +356,7 @@ export function isValidSigningKeyPacket(keyPacket, signature) { keyAlgo !== enums.publicKey.elgamal && keyAlgo !== enums.publicKey.ecdh && keyAlgo !== enums.publicKey.x25519 && + keyAlgo !== enums.publicKey.x448 && (!signature.keyFlags || (signature.keyFlags[0] & enums.keyFlags.signData) !== 0); } diff --git a/src/message.js b/src/message.js index 8e5c725f..159c003e 100644 --- a/src/message.js +++ b/src/message.js @@ -357,8 +357,9 @@ export class Message { await Promise.all(encryptionKeys.map(key => key.getEncryptionKey() .catch(() => null) // ignore key strength requirements .then(maybeKey => { - if (maybeKey && (maybeKey.keyPacket.algorithm === enums.publicKey.x25519) && !aeadAlgoName && !util.isAES(symmetricAlgo)) { // if AEAD is defined, then PKESK v6 are used, and the algo info is encrypted - throw new Error('Could not generate a session key compatible with the given `encryptionKeys`: X22519 keys can only be used to encrypt AES session keys; change `config.preferredSymmetricAlgorithm` accordingly.'); + if (maybeKey && (maybeKey.keyPacket.algorithm === enums.publicKey.x25519 || maybeKey.keyPacket.algorithm === enums.publicKey.x448) && + !aeadAlgoName && !util.isAES(symmetricAlgo)) { // if AEAD is defined, then PKESK v6 are used, and the algo info is encrypted + throw new Error('Could not generate a session key compatible with the given `encryptionKeys`: X22519 and X448 keys can only be used to encrypt AES session keys; change `config.preferredSymmetricAlgorithm` accordingly.'); } }) )); diff --git a/src/packet/public_key_encrypted_session_key.js b/src/packet/public_key_encrypted_session_key.js index 8121e32c..2618ce32 100644 --- a/src/packet/public_key_encrypted_session_key.js +++ b/src/packet/public_key_encrypted_session_key.js @@ -128,7 +128,8 @@ class PublicKeyEncryptedSessionKeyPacket { } this.publicKeyAlgorithm = bytes[offset++]; this.encrypted = crypto.parseEncSessionKeyParams(this.publicKeyAlgorithm, bytes.subarray(offset)); - if (this.version === 3 && this.publicKeyAlgorithm === enums.publicKey.x25519) { + if (this.version === 3 && ( + this.publicKeyAlgorithm === enums.publicKey.x25519 || this.publicKeyAlgorithm === enums.publicKey.x448)) { this.sessionKeyAlgorithm = enums.write(enums.symmetric, this.encrypted.C.algorithm); } } @@ -200,7 +201,9 @@ class PublicKeyEncryptedSessionKeyPacket { const { sessionKey, sessionKeyAlgorithm } = decodeSessionKey(this.version, this.publicKeyAlgorithm, decryptedData, randomSessionKey); // v3 Montgomery curves have cleartext cipher algo - if (this.version === 3 && this.publicKeyAlgorithm !== enums.publicKey.x25519) { + if (this.version === 3 && ( + this.publicKeyAlgorithm !== enums.publicKey.x25519 && this.publicKeyAlgorithm !== enums.publicKey.x448) + ) { this.sessionKeyAlgorithm = sessionKeyAlgorithm; } this.sessionKey = sessionKey; @@ -224,6 +227,7 @@ function encodeSessionKey(version, keyAlgo, cipherAlgo, sessionKeyData) { ]); } case enums.publicKey.x25519: + case enums.publicKey.x448: return sessionKeyData; default: throw new Error('Unsupported public key algorithm'); @@ -270,6 +274,7 @@ function decodeSessionKey(version, keyAlgo, decryptedData, randomSessionKey) { } } case enums.publicKey.x25519: + case enums.publicKey.x448: return { sessionKey: decryptedData }; diff --git a/test/crypto/ecdh.js b/test/crypto/ecdh.js index 501f0481..4f211386 100644 --- a/test/crypto/ecdh.js +++ b/test/crypto/ecdh.js @@ -189,6 +189,16 @@ export default () => describe('ECDH key exchange @lightweight', function () { expect(await ecdhX.decrypt(openpgp.enums.publicKey.x25519, ephemeralPublicKey, wrappedKey, K_B, b)).to.deep.equal(data); }); + it('Successful exchange x448', async function () { + const { ecdhX } = elliptic_curves; + const data = random.getRandomBytes(); + // Bob's keys from https://www.rfc-editor.org/rfc/rfc7748#section-6.2 + const b = util.hexToUint8Array('1c306a7ac2a0e2e0990b294470cba339e6453772b075811d8fad0d1d6927c120bb5ee8972b0d3e21374c9c921b09d1b0366f10b65173992d'); + const K_B = util.hexToUint8Array('3eb7a829b0cd20f5bcfc0b599b6feccf6da4627107bdb0d4f345b43027d8b972fc3e34fb4232a13ca706dcb57aec3dae07bdc1c67bf33609'); + const { ephemeralPublicKey, wrappedKey } = await ecdhX.encrypt(openpgp.enums.publicKey.x448, data, K_B); + expect(await ecdhX.decrypt(openpgp.enums.publicKey.x448, ephemeralPublicKey, wrappedKey, K_B, b)).to.deep.equal(data); + }); + ['p256', 'p384', 'p521'].forEach(curveName => { it(`NIST ${curveName} - Successful exchange`, async function () { const curve = new elliptic_curves.CurveWithOID(curveName); diff --git a/test/crypto/validate.js b/test/crypto/validate.js index 54d79ca3..3388f26b 100644 --- a/test/crypto/validate.js +++ b/test/crypto/validate.js @@ -247,6 +247,61 @@ export default () => { }); }); + describe('Ed448/X448 parameter validation', function() { + let eddsaKey; + let ecdhXKey; + before(async () => { + eddsaKey = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xXsEZCWHXBwwtqciq6ZFU13s+dyhkWR5tOEmF1oX8OiP1B5ypfqyGVM8DkQh +5eTIMwB1oqJCROANoyA0q2dSigAAbDA5xr74DeClPPXC4ZXJ9uzuJWKvQvE8 +x3EflhgoQCGBM7JfvH5zwdrJvPt8RKDvm0QkZzhPvnFoHnzNBHRlc3TCugQQ +HAgAPgWCZCWHXAQLCQcICZDsN6h/ys3ppwMVCAoEFgACAQIZAQKbAwIeARYh +BOJyE9P2eIcU2N2Ne+w3qH/KzemnAAAh1hTFCcEU77bU3YelrJTCNIOQnvt7 +Hs6yZz2053CQTOC+wHkUQLaYYBEXSNyLZxoyv+NuGTiwbuYtAOlbE2erM7Cx +8B2Qz7M29UkFLMBUfb+yi+gTYYUWCXVQ7Um7MGjjgUG8+9p452i6f28mhRD8 +tTgNAMd5BGQlh1wavTIFgILtbzrqQCiwDGx0YcFNzu9+FZ8vK5Mmm7UEZj0a +y7FWQtZw8tTaU6mY+RrSa52RjzkGLtQAQO++tgYqc+BnCFdCZ3ZYPRvD3mof +ffoo3l4xmto+iyvJZbQ4wQPXttg7VjCpEfOsL9TW9Xs09aIbysKmBBgcCAAq +BYJkJYdcCZDsN6h/ys3ppwKbDBYhBOJyE9P2eIcU2N2Ne+w3qH/KzemnAAC0 +6/eZhh/Oj2gRdab2JeFGWACGIRDKxPXsWRCXR4YrSxcvCKK6rOvsyxQsgIsJ +JyPYkRPfmbKcseUDAEkSBLAfeizDGh7ea0GOdIMhwE/CW4f/H8ULbwi36y13 +x3oMNVaYsI9dZ588Gpi8XYy2jOtqIPQ1AA== +-----END PGP PRIVATE KEY BLOCK-----` }); + ecdhXKey = eddsaKey.subkeys[0]; + }); + + it('Ed448 params should be valid', async function() { + await expect(eddsaKey.keyPacket.validate()).to.not.be.rejected; + }); + + it('detect invalid Ed448 public point', async function() { + const eddsaKeyPacket = await cloneKeyPacket(eddsaKey); + const A = eddsaKeyPacket.publicParams.A; + A[0]++; + await expect(eddsaKeyPacket.validate()).to.be.rejectedWith('Key is invalid'); + + const infA = new Uint8Array(A.length); + eddsaKeyPacket.publicParams.A = infA; + await expect(eddsaKeyPacket.validate()).to.be.rejectedWith('Key is invalid'); + }); + + it('X448 params should be valid', async function() { + await expect(ecdhXKey.keyPacket.validate()).to.not.be.rejected; + }); + + it('detect invalid x448 public point', async function() { + const ecdhXKeyPacket = await cloneKeyPacket(ecdhXKey); + const A = ecdhXKeyPacket.publicParams.A; + A[0]++; + await expect(ecdhXKeyPacket.validate()).to.be.rejectedWith('Key is invalid'); + + const infA = new Uint8Array(A.length); + ecdhXKeyPacket.publicParams.A = infA; + await expect(ecdhXKeyPacket.validate()).to.be.rejectedWith('Key is invalid'); + }); + }); + describe('RSA parameter validation', function() { let rsaKey; before(async () => { diff --git a/test/general/key.js b/test/general/key.js index 0a2fb66a..0e5dc5ae 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -3223,29 +3223,38 @@ aU71tdtNBQ== it('Parsing V4 key using curve448 format', async function() { const privateKey = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- -xX0GZRqLYhwAAAA5U/IaIOge/FoLzCetXKx029bdJHCz2hMFBRMuzq4msjaT -+hLeV6puyC/PeSEfaanqTuo31vvsti2AAIttr4GDGXF4vfPzbzkWV9dT4VVs -IU7QqLv1hzwZ+k7pHroRyXnUiYxRYHuzlg7Vw4CrAtN/8T65OMLAHgYfHAoA -AAA9BQJlGotiIqEGAxidsHRHDsyFTw1Q7OoGEAEnRnxthKMwVBqhIL2o+HUC -GwMCHgkCCwcDFQoIAhYAAycHAgAAAAA2KiC+Y+fhQ/48CkT9WrXTX9SCn3vH -z43Wb++AkmpWL1HQmrJE3S4gGltezZK2E9ovagzxKxVrL14uC6hs6kJ0JIiW -QSeMeexCTy+Gdr6j0wb4FhFNnoIu3yu2ABmZpFX/5/191YeWUryKFDAoUZmK -gQTSOzJEvyO0ACR5L4vV3ADceOAdG8/sqhE89rTSevFXng4JAM0XVXNlckEg -PFVzZXJBQHRlc3QudGVzdD7CwA0GExwKAAAALAUCZRqLYiKhBgMYnbB0Rw7M -hU8NUOzqBhABJ0Z8bYSjMFQaoSC9qPh1AhkBAAAAAFw/IH72M1iyzMWhbgtw -v0SR/XxvOIW/ZrT4Ix9236lvoOE4taL/D46CbZOjm7VAeOSfSdxt1xSKnoAL -RsCNQ8tVPjPXclzqr6R8MbPIgBWxKcMS2eStYpBbG5qAmc+K5jdA2xcl9iW5 -bWleZ1LTah4lF6qCiD73IffADXtzw8iAMTX+0wM5N1tJUEGvgqe00ohRKiQA ------END PGP PRIVATE KEY BLOCK-----` }); +xX0GZRqLYhwAAAA52IEq/TpKiPp6RofQaq4uhCruTtiG+qiVFnwsQgeh0ui34kHD +Y1E04mBai0pCoDiFVokwsKt3F5sAAC8lDYfVP/p3atbXJDTJB2W9WmZxIS7pUGhS +bjlWpZB/OVTBsoIfP/2J+Hi4ESwBRfDUDgwK4aJVKsLAIAYfHAoAAAA/BQJlGoti +IqEGobsxt8WKsMuJWANyTXpWMdC1QN/7EyJClfcs+nBgqdUCGwMCHgkCCwcDFQoI +AhYABScHAwcCAAAAAPiGIG2qmhCULQ/+H4rKV0XEM1x0uVY3l878Pa6ijZLouZU/ +VRd5PnbGyLPL++q3LDViUUdZ1uusRc01f677Q6wpUU90k8MH/oULwI0+KPtqe1N4 +6nr1NTERsAmAaPjUdf4ZUXX/GWiTd/AlsS5JqGnAQxKRJkzCJacOTOElRMjzGUX7 +CGaAnhSC86YRZ68ocTPfZysAzRdVc2VyQiA8VXNlckJAdGVzdC50ZXN0PsLADQYT +HAoAAAAsBQJlGotiIqEGobsxt8WKsMuJWANyTXpWMdC1QN/7EyJClfcs+nBgqdUC +GQEAAAAASKwgVzMoPb2Hbr3lbNI1CRWECokYLokL7F8MbYiMnlg+v6QXLdStvT13 +ZjxdrWQAx3MbihSOUSXbdAys90yMOAdtognj+x418J/TaYFMtIGBHwoHv8gQVnx9 +9ICv8ezx1T5VvGBYNuKZ5Ww0WPEpYMf1VA+Y9JxpohdcRenNBdSug4tLWla2y8NH +aO28Fltpb4AuGQDHewZlGotiGgAAADjdabr1ohAOnbSUUkVhtUM/LVdnYgDLhmaj +YZ1N7TWY0fqEpMk2LLo2165HOmhddRPeTB1TWbuwBwB8lKc3czFUzYcAgvZ08T5S +UUHjfIhjeJeY4yd0OZDfzPw1vbegCc7t94bT+XGoIQbC/Bl7HCyAiMLADQYYHAoA +AAAsBQJlGotiIqEGobsxt8WKsMuJWANyTXpWMdC1QN/7EyJClfcs+nBgqdUCGwwA +AAAAHh0gf2kdqLoXdFX+aNVORr5VCVgcm2gBw8l68lDJ1ftA71bMllFi6Q5sLPUr +6UCpJYYk3o3hYUYzIHmCIZGVYe1pxRgIUNqxydXEfzylJmN5NbiJNkjJizrI7oAR +1mIcEEb/hmRMOUs1V2mcGuoeALBI/r/SyqDE2GRjH6d6g1RS7ZARPPHlZlY4CTqC +4a7L+8odDwA= +=chx0 +-----END PGP PRIVATE KEY BLOCK----- + ` }); // sanity checks await expect(privateKey.validate()).to.be.fulfilled; const signingKey = await privateKey.getSigningKey(); expect(signingKey.keyPacket.algorithm).to.equal(openpgp.enums.publicKey.ed448); expect(signingKey.getAlgorithmInfo()).to.deep.equal({ algorithm: 'ed448' }); - // const encryptionKey = await privateKey.getEncryptionKey(); - // expect(encryptionKey.keyPacket.algorithm).to.equal(openpgp.enums.publicKey.x25519); - // expect(encryptionKey.getAlgorithmInfo()).to.deep.equal({ algorithm: 'x25519' }); + const encryptionKey = await privateKey.getEncryptionKey(); + expect(encryptionKey.keyPacket.algorithm).to.equal(openpgp.enums.publicKey.x448); + expect(encryptionKey.getAlgorithmInfo()).to.deep.equal({ algorithm: 'x448' }); }); it('Testing key ID and fingerprint for V4 keys', async function() { diff --git a/test/general/openpgp.js b/test/general/openpgp.js index e159f30b..c84ccd54 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -2131,7 +2131,7 @@ mNwbfFbSNhZYWjFada77EKBn60j8QT/xCQzLR1clci7ieW2knw== expect(data).to.equal('Hello World!'); }); - it('supports encrypting new x25519 format', async function () { + it('supports encrypting/decrypting new x25519 format', async function () { // v4 key const privateKey = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- @@ -2160,6 +2160,40 @@ yxsNL0GomZ+hxiE0MOZwRr10DxfVaRabF1fcf9PHSHX2SwEFXUKMIHgbMQs= expect(data).to.equal(plaintext); }); + it('supports encrypting/decrypting with x448', async function () { + // v4 key + const privateKey = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xXsEZRqJ5BwHESfKnw5YJly5WobjigVm0kKY84NxrP6JKeIvIWiFqqSlozGpKZyR +50YbVTHmxpUCuJ7YNwX0UoAAoSO8IXmMM/XMd4ph00ju+fbSHdtQfyNhfFTi3UoM +V5DiFT+uOYDP+zwAwLWCR86csxmCWn6O10DNHcDNF1VzZXJBIDxVc2VyQUB0ZXN0 +LnRlc3Q+wroEExwKAD4FAmUaieQJEC8lwIrxSM+5FiEEGR2s5Bj5WVDN0Px6LyXA +ivFIz7kCGwMCHgkCGQECCwcDFQoIAhYAAycHAgAA21/PqAuGDL5+3qrf3YoVOP+5 +0BoJ+ZMhzcgax+cQTyndmOZYBfOqV/SJ8mf6CRhbB76JhGIvmRMtyYDQgDMVvcoA +yojVNs6e/Jco16bVJxM85wKDXJuq6AhtPQ8w/0WaCJtEf1uxqeQPEbOM+KtT/xY2 +KgDHeQRlGonkGuOtAhogSIU3z/+gFzF8U7JQe7QDRYr9VWfi2WXFFarzg/3DMRur +oIB7mqkaaSatrvVuud1ZmRCWAMM4f57dvSdCKsVqSe+tlS225OmdWmnGLqyErBb6 +44E2oENhDUom9OUGUPm8dXUjQbrmw6ec9hNLHWXCpgQYHAoAKgUCZRqJ5AkQLyXA +ivFIz7kWIQQZHazkGPlZUM3Q/HovJcCK8UjPuQIbDAAAZka10c8KlmwftJuboIV5 +DalGWrZhbywJpEZRfoikcebSYi5++w1SbpXZGu27sl+BznGyyyqAfxyJjoCZaqCs +ewbKh04DNAg4v4v0W0a8UvD3j/CuciEMXjK9nUErt91zEwxNZy43yrQY2aAayDs8 +94FqMAA= +=GBh1 +-----END PGP PRIVATE KEY BLOCK-----` }); + const plaintext = 'plaintext'; + + const signed = await openpgp.encrypt({ + message: await openpgp.createMessage({ text: plaintext }), + encryptionKeys: privateKey + }); + + const { data } = await openpgp.decrypt({ + message: await openpgp.readMessage({ armoredMessage: signed }), + decryptionKeys: privateKey + }); + expect(data).to.equal(plaintext); + }); + it('should support encrypting with encrypted key with unknown s2k (unparseableKeyMaterial)', async function() { const originalDecryptedKey = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- @@ -4370,7 +4404,7 @@ kl0L message: await openpgp.createMessage({ text: plaintext }), encryptionKeys: privateKeyCast5, sessionKey: { data: new Uint8Array(16).fill(1), algorithm: 'cast5' } - })).to.be.rejectedWith(/X25519 keys can only encrypt AES session keys/); + })).to.be.rejectedWith(/X25519 and X448 keys can only encrypt AES session keys/); await expect(openpgp.decryptSessionKeys({ message: await openpgp.readMessage({ armoredMessage: `-----BEGIN PGP MESSAGE----- @@ -4383,6 +4417,48 @@ A7sB7uYCTVCLIMfPFwVZH+c29gpCzPxSXQ== })).to.be.rejectedWith(/AES session key expected/); }); + it('should enforce using AES session keys with x448 keys', async function () { + // X448 key (v4) with cast5 as preferred cipher + const privateKeyCast5 = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xXsEZRrtaRyScvyNjK0o5ccICztnWhA1MSij7WdzPfuNy7ryUzB+kqzpziBR +IIKp5PN0NW3mOYRDnUyo7QHBl4AA30tR5ED8u5v/rNIzKz/mKsD6XeYy+d0Q +5utwuR8BUxx9mcIUGdS65z9H6PUMGnfCwqAGVCTzBrSCHgTNAMK3BBAcCgA7 +BYJlGu1pAwsDBwmQkFi4G9HqQDwDFQgKAhYAAhkBApsDAh4BFiEE7kZAI1Dd +SVlLtf4QkFi4G9HqQDwAAPA7E+p0vwVLtUCfT0aBFzapFn8xjoow6jrUNTo3 +8EtaN0fqP2vaeQwW/vv26wobD+hbL2RwyFtAEV6AeeDsPVhbx7WA7yKHPzvl +GOYEGw0h57DuhvSxGciuyt0Y5PR2Vrz/2/wHGcEHzsrhTNysUetluxEAx3kE +ZRrtaRrySCLAqKQSATJOXdoRoNKVasJHlKrG3qgMbt1U6uSdctHBitTiHHTf +GU/Jg0ADA3Eg0bCyDupWNACmHJGu7q0o7O7BTAm0AsMbHxoIkNN9JsijwAp5 +FLtdXK9cAOkNaXPMkEGQkt1hmoW50lUq0iWcGBpzwqYEGBwKACoFgmUa7WkJ +kJBYuBvR6kA8ApsMFiEE7kZAI1DdSVlLtf4QkFi4G9HqQDwAAD3uf3qdwHY8 +65W22GR17PbqF+9uvkPpXLBi32FVPFkxJqYvIN5/LAQ33xdEE0mzO4As4+Oi +x8fsFb2AEXLEwlSnL+Eo0O+iUQd3/94yMbMFRlNxrdaqZ3+7CehbnieI/vby +LIEnN38XBi0HE70uoU5prxUA +-----END PGP PRIVATE KEY BLOCK-----` }); + + await expect(openpgp.generateSessionKey({ + encryptionKeys: privateKeyCast5, + config: { preferredSymmetricAlgorithm: openpgp.enums.symmetric.cast5 } + })).to.be.rejectedWith(/Could not generate a session key compatible with the given `encryptionKeys`/); + + await expect(openpgp.encrypt({ + message: await openpgp.createMessage({ text: plaintext }), + encryptionKeys: privateKeyCast5, + sessionKey: { data: new Uint8Array(16).fill(1), algorithm: 'cast5' } + })).to.be.rejectedWith(/X25519 and X448 keys can only encrypt AES session keys/); + + await expect(openpgp.decryptSessionKeys({ + message: await openpgp.readMessage({ armoredMessage: `-----BEGIN PGP MESSAGE----- + +wVwD2k7TUuqJwZkaXvEGk7B3pklJ5uRcRdKwwDJ40yKT0m5ic1e/2F+Se3xQ +zDE+N2DZ0B37pu4NUzTGBRo0oLD9EwwZA9+oJpBBOOry3cGmBYWvQHbvBpNE +5X5l8A== +-----END PGP MESSAGE-----` }), + decryptionKeys: privateKeyCast5 + })).to.be.rejectedWith(/AES session key expected/); + }); + describe('Sign and verify with each curve', function() { const curves = ['secp256k1' , 'p256', 'p384', 'p521', 'curve25519', 'brainpoolP256r1', 'brainpoolP384r1', 'brainpoolP512r1']; curves.forEach(curve => { From 089a14f9e0e9451e2cde6103efa4d1eac4282b88 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Thu, 30 Mar 2023 13:27:16 +0200 Subject: [PATCH 062/201] Internal: refactor `uint8ArrayToHex` for performance and to avoid branching --- src/util.js | 16 ++++------------ test/crypto/cipher/des.js | 2 +- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/util.js b/src/util.js index 25ba5cd0..a1d5c3d2 100644 --- a/src/util.js +++ b/src/util.js @@ -154,18 +154,10 @@ const util = { * @returns {String} Hexadecimal representation of the array. */ uint8ArrayToHex: function (bytes) { - const r = []; - const e = bytes.length; - let c = 0; - let h; - while (c < e) { - h = bytes[c++].toString(16); - while (h.length < 2) { - h = '0' + h; - } - r.push('' + h); - } - return r.join(''); + const hexAlphabet = '0123456789abcdef'; + let s = ''; + bytes.forEach(v => { s += hexAlphabet[v >> 4] + hexAlphabet[v & 15]; }); + return s; }, /** diff --git a/test/crypto/cipher/des.js b/test/crypto/cipher/des.js index e3a00285..8cfc03b5 100644 --- a/test/crypto/cipher/des.js +++ b/test/crypto/cipher/des.js @@ -80,7 +80,7 @@ export default () => describe('TripleDES (EDE) cipher test with test vectors fro expect(encr, 'vector with block ' + util.uint8ArrayToHex(testvectors[i][0]) + ' and key ' + util.uint8ArrayToHex(key) + ' should be ' + util.uint8ArrayToHex(testvectors[i][1]) + - ' != ' + util.uint8ArrayToHex(encr)).to.be.equal(util.uint8ArrayToString(testvectors[i][1])); + ' != ' + encr).to.be.equal(util.uint8ArrayToString(testvectors[i][1])); } done(); }); From d291ce6d0f8813542781643c28bfba44bf0a46ec Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Wed, 23 Aug 2023 12:22:47 +0200 Subject: [PATCH 063/201] Update Curve448 tests using inputs from gopenpgp --- test/general/openpgp.js | 630 ++++++++++++++++++++++++++++------------ 1 file changed, 446 insertions(+), 184 deletions(-) diff --git a/test/general/openpgp.js b/test/general/openpgp.js index c84ccd54..e2ff3128 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -1329,40 +1329,6 @@ VFBLG8uc9IiaKann/DYBAJcZNZHRSfpDoV2pUA5EAEi2MdjxkRysFQnYPRAu await expect(openpgp.decrypt(decOpt)).to.be.rejectedWith('Error decrypting message: Decryption key is not decrypted.'); }); - it('should decrypt test vector X25519-AEAD-OCB (PKESK v6, SEIPDv2)', async function() { - // test vector https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#appendix-A.8 - const armoredMessage = `-----BEGIN PGP MESSAGE----- - -wV0GIQYSyD8ecG9jCP4VGkF3Q6HwM3kOk+mXhIjR2zeNqZMIhRmHzxjV8bU/gXzO -WgBM85PMiVi93AZfJfhK9QmxfdNnZBjeo1VDeVZheQHgaVf7yopqR6W1FT6NOrfS -aQIHAgZhZBZTW+CwcW1g4FKlbExAf56zaw76/prQoN+bAzxpohup69LA7JW/Vp0l -yZnuSj3hcFj0DfqLTGgr4/u717J+sPWbtQBfgMfG9AOIwwrUBqsFE9zW+f1zdlYo -bhF30A+IitsxxA== ------END PGP MESSAGE-----`; - - const privateKey = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- - -xUsGY4d/4xsAAAAg+U2nu0jWCmHlZ3BqZYfQMxmZu52JGggkLq2EVD34laMAGXKB -exK+cH6NX1hs5hNhIB00TrJmosgv3mg1ditlsLfCsQYfGwoAAABCBYJjh3/jAwsJ -BwUVCg4IDAIWAAKbAwIeCSIhBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce6 -2azJBScJAgcCAAAAAK0oIBA+LX0ifsDm185Ecds2v8lwgyU2kCcUmKfvBXbAf6rh -RYWzuQOwEn7E/aLwIwRaLsdry0+VcallHhSu4RN6HWaEQsiPlR4zxP/TP7mhfVEe -7XWPxtnMUMtf15OyA51YBMdLBmOHf+MZAAAAIIaTJINn+eUBXbki+PSAld2nhJh/ -LVmFsS+60WyvXkQ1AE1gCk95TUR3XFeibg/u/tVY6a//1q0NWC1X+yui3O24wpsG -GBsKAAAALAWCY4d/4wKbDCIhBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce6 -2azJAAAAAAQBIKbpGG2dWTX8j+VjFM21J0hqWlEg+bdiojWnKfA5AQpWUWtnNwDE -M0g12vYxoWM8Y81W+bHBw805I8kWVkXU6vFOi+HWvv/ira7ofJu16NnoUkhclkUr -k0mXubZvyl4GBg== ------END PGP PRIVATE KEY BLOCK-----` }); - - const { data: decryptedData } = await openpgp.decrypt({ - message: await openpgp.readMessage({ armoredMessage }), - decryptionKeys: privateKey - }); - - expect(decryptedData).to.equal('Hello, world!'); - }); - it('decrypt/verify should succeed with valid signature (expectSigned=true)', async function () { const publicKey = await openpgp.readKey({ armoredKey: pub_key }); const privateKey = await openpgp.decryptKey({ @@ -2101,99 +2067,6 @@ aOU= expect(await stream.readToEnd(streamedData)).to.equal(text); }); - it('supports decrypting new x25519 format', async function () { - // v4 key - const privateKey = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- - -xUkEZIbSkxsHknQrXGfb+kM2iOsOvin8yE05ff5hF8KE6k+saspAZQCy/kfFUYc2 -GkpOHc42BI+MsysKzk4ofjBAfqM+bb7goQ3hzRV1c2VyIDx1c2VyQHRlc3QudGVz -dD7ChwQTGwgAPQUCZIbSkwmQQezK2iB2tIkWIQRqZza9wQZcwxpjGYNB7MraIHa0 -iQIbAwIeAQIZAQILBwIVCAIWAAMnBwIAAFOeZ7jrKZsCzRfu1ffFa77074st0zRo -BTJXoXBQ1ZzLjsh+ZO6fB2odnYJtQYstv45H/3JyLVogcMnFeYmHeSP3AMdJBGSG -0pMZfpd7TiOQv7uKSK+k4HT9lKr5+dmvb7vox/8ids6unEkAF1v8fCKogIrtBWVT -nVbwnovjM3LLexpXFZSgTKRcNMgPRMJ0BBgbCAAqBQJkhtKTCZBB7MraIHa0iRYh -BGpnNr3BBlzDGmMZg0HsytogdrSJAhsMAADCYs2I9wBakIu9Hhxs4R3Jq9F8J7AH -yxsNL0GomZ+hxiE0MOZwRr10DxfVaRabF1fcf9PHSHX2SwEFXUKMIHgbMQs= -=bJqd ------END PGP PRIVATE KEY BLOCK-----` }); - - const messageToDecrypt = `-----BEGIN PGP MESSAGE----- - -wUQDYc6clYlCdtoZ3rAsvBDIwvoLmvM0zwViG8Ec0PgFfN5R6C4BqEZD53UZB1WM -J68hXSj1Sa235XAUYE1pZerTKhglvdI9Aeve8+L0w5RDMjmBBA50Yv/YT8liqhNi -mNwbfFbSNhZYWjFada77EKBn60j8QT/xCQzLR1clci7ieW2knw== -=NKye ------END PGP MESSAGE-----`; - const { data } = await openpgp.decrypt({ - message: await openpgp.readMessage({ armoredMessage: messageToDecrypt }), - decryptionKeys: privateKey - }); - expect(data).to.equal('Hello World!'); - }); - - it('supports encrypting/decrypting new x25519 format', async function () { - // v4 key - const privateKey = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- - -xUkEZIbSkxsHknQrXGfb+kM2iOsOvin8yE05ff5hF8KE6k+saspAZQCy/kfFUYc2 -GkpOHc42BI+MsysKzk4ofjBAfqM+bb7goQ3hzRV1c2VyIDx1c2VyQHRlc3QudGVz -dD7ChwQTGwgAPQUCZIbSkwmQQezK2iB2tIkWIQRqZza9wQZcwxpjGYNB7MraIHa0 -iQIbAwIeAQIZAQILBwIVCAIWAAMnBwIAAFOeZ7jrKZsCzRfu1ffFa77074st0zRo -BTJXoXBQ1ZzLjsh+ZO6fB2odnYJtQYstv45H/3JyLVogcMnFeYmHeSP3AMdJBGSG -0pMZfpd7TiOQv7uKSK+k4HT9lKr5+dmvb7vox/8ids6unEkAF1v8fCKogIrtBWVT -nVbwnovjM3LLexpXFZSgTKRcNMgPRMJ0BBgbCAAqBQJkhtKTCZBB7MraIHa0iRYh -BGpnNr3BBlzDGmMZg0HsytogdrSJAhsMAADCYs2I9wBakIu9Hhxs4R3Jq9F8J7AH -yxsNL0GomZ+hxiE0MOZwRr10DxfVaRabF1fcf9PHSHX2SwEFXUKMIHgbMQs= -=bJqd ------END PGP PRIVATE KEY BLOCK-----` }); - const plaintext = 'plaintext'; - - const signed = await openpgp.encrypt({ - message: await openpgp.createMessage({ text: plaintext }), - encryptionKeys: privateKey - }); - - const { data } = await openpgp.decrypt({ - message: await openpgp.readMessage({ armoredMessage: signed }), - decryptionKeys: privateKey - }); - expect(data).to.equal(plaintext); - }); - - it('supports encrypting/decrypting with x448', async function () { - // v4 key - const privateKey = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- - -xXsEZRqJ5BwHESfKnw5YJly5WobjigVm0kKY84NxrP6JKeIvIWiFqqSlozGpKZyR -50YbVTHmxpUCuJ7YNwX0UoAAoSO8IXmMM/XMd4ph00ju+fbSHdtQfyNhfFTi3UoM -V5DiFT+uOYDP+zwAwLWCR86csxmCWn6O10DNHcDNF1VzZXJBIDxVc2VyQUB0ZXN0 -LnRlc3Q+wroEExwKAD4FAmUaieQJEC8lwIrxSM+5FiEEGR2s5Bj5WVDN0Px6LyXA -ivFIz7kCGwMCHgkCGQECCwcDFQoIAhYAAycHAgAA21/PqAuGDL5+3qrf3YoVOP+5 -0BoJ+ZMhzcgax+cQTyndmOZYBfOqV/SJ8mf6CRhbB76JhGIvmRMtyYDQgDMVvcoA -yojVNs6e/Jco16bVJxM85wKDXJuq6AhtPQ8w/0WaCJtEf1uxqeQPEbOM+KtT/xY2 -KgDHeQRlGonkGuOtAhogSIU3z/+gFzF8U7JQe7QDRYr9VWfi2WXFFarzg/3DMRur -oIB7mqkaaSatrvVuud1ZmRCWAMM4f57dvSdCKsVqSe+tlS225OmdWmnGLqyErBb6 -44E2oENhDUom9OUGUPm8dXUjQbrmw6ec9hNLHWXCpgQYHAoAKgUCZRqJ5AkQLyXA -ivFIz7kWIQQZHazkGPlZUM3Q/HovJcCK8UjPuQIbDAAAZka10c8KlmwftJuboIV5 -DalGWrZhbywJpEZRfoikcebSYi5++w1SbpXZGu27sl+BznGyyyqAfxyJjoCZaqCs -ewbKh04DNAg4v4v0W0a8UvD3j/CuciEMXjK9nUErt91zEwxNZy43yrQY2aAayDs8 -94FqMAA= -=GBh1 ------END PGP PRIVATE KEY BLOCK-----` }); - const plaintext = 'plaintext'; - - const signed = await openpgp.encrypt({ - message: await openpgp.createMessage({ text: plaintext }), - encryptionKeys: privateKey - }); - - const { data } = await openpgp.decrypt({ - message: await openpgp.readMessage({ armoredMessage: signed }), - decryptionKeys: privateKey - }); - expect(data).to.equal(plaintext); - }); - it('should support encrypting with encrypted key with unknown s2k (unparseableKeyMaterial)', async function() { const originalDecryptedKey = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- @@ -4378,9 +4251,10 @@ bsZgJWVlAa5eil6J9ePX2xbo1vVAkLQdzE9+1jL+l7PRIZuVBQ== expect(data).to.equal('test'); }); - it('should enforce using AES session keys with x25519 keys (new format)', async function () { - // x25519 key (v4) with cast5 as preferred cipher - const privateKeyCast5 = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- + describe('X25519/Ed25519 (new format)', async function () { + it('should enforce using AES session keys with x25519 keys (v4 key)', async function () { + // x25519 key (v4) with cast5 as preferred cipher + const privateKeyCast5 = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- xUkEZK8BixuMghYwdEgHl+3ASI4VZkn048KG4DVuugT1bMe4QTtFtQCoKBOG JxrZh8E+7I5nK7McXP2U9gyC0+RFcD46AxSmRA46zQDCiAQQGwgAPgWCZK8B @@ -4395,31 +4269,126 @@ kl0L =SYJZ -----END PGP PRIVATE KEY BLOCK-----` }); - await expect(openpgp.generateSessionKey({ - encryptionKeys: privateKeyCast5, - config: { preferredSymmetricAlgorithm: openpgp.enums.symmetric.cast5 } - })).to.be.rejectedWith(/Could not generate a session key compatible with the given `encryptionKeys`/); + await expect(openpgp.generateSessionKey({ + encryptionKeys: privateKeyCast5, + config: { preferredSymmetricAlgorithm: openpgp.enums.symmetric.cast5 } + })).to.be.rejectedWith(/Could not generate a session key compatible with the given `encryptionKeys`/); - await expect(openpgp.encrypt({ - message: await openpgp.createMessage({ text: plaintext }), - encryptionKeys: privateKeyCast5, - sessionKey: { data: new Uint8Array(16).fill(1), algorithm: 'cast5' } - })).to.be.rejectedWith(/X25519 and X448 keys can only encrypt AES session keys/); - - await expect(openpgp.decryptSessionKeys({ - message: await openpgp.readMessage({ armoredMessage: `-----BEGIN PGP MESSAGE----- + await expect(openpgp.encrypt({ + message: await openpgp.createMessage({ text: plaintext }), + encryptionKeys: privateKeyCast5, + sessionKey: { data: new Uint8Array(16).fill(1), algorithm: 'cast5' } + })).to.be.rejectedWith(/X25519 and X448 keys can only encrypt AES session keys/); + await expect(openpgp.decryptSessionKeys({ + message: await openpgp.readMessage({ armoredMessage: `-----BEGIN PGP MESSAGE----- + wUQD66NYAXF0vfYZNWpc7s9eihtgj7EhHBeLOq2Ktw79artbhN5JMs+9aCIZ A7sB7uYCTVCLIMfPFwVZH+c29gpCzPxSXQ== =Dr02 -----END PGP MESSAGE-----` }), - decryptionKeys: privateKeyCast5 - })).to.be.rejectedWith(/AES session key expected/); + decryptionKeys: privateKeyCast5 + })).to.be.rejectedWith(/AES session key expected/); + }); + + it('supports decrypting new x25519 format (v4 key)', async function () { + // v4 key + const privateKey = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xUkEZIbSkxsHknQrXGfb+kM2iOsOvin8yE05ff5hF8KE6k+saspAZQCy/kfFUYc2 +GkpOHc42BI+MsysKzk4ofjBAfqM+bb7goQ3hzRV1c2VyIDx1c2VyQHRlc3QudGVz +dD7ChwQTGwgAPQUCZIbSkwmQQezK2iB2tIkWIQRqZza9wQZcwxpjGYNB7MraIHa0 +iQIbAwIeAQIZAQILBwIVCAIWAAMnBwIAAFOeZ7jrKZsCzRfu1ffFa77074st0zRo +BTJXoXBQ1ZzLjsh+ZO6fB2odnYJtQYstv45H/3JyLVogcMnFeYmHeSP3AMdJBGSG +0pMZfpd7TiOQv7uKSK+k4HT9lKr5+dmvb7vox/8ids6unEkAF1v8fCKogIrtBWVT +nVbwnovjM3LLexpXFZSgTKRcNMgPRMJ0BBgbCAAqBQJkhtKTCZBB7MraIHa0iRYh +BGpnNr3BBlzDGmMZg0HsytogdrSJAhsMAADCYs2I9wBakIu9Hhxs4R3Jq9F8J7AH +yxsNL0GomZ+hxiE0MOZwRr10DxfVaRabF1fcf9PHSHX2SwEFXUKMIHgbMQs= +=bJqd +-----END PGP PRIVATE KEY BLOCK-----` }); + + const messageToDecrypt = `-----BEGIN PGP MESSAGE----- + +wUQDYc6clYlCdtoZ3rAsvBDIwvoLmvM0zwViG8Ec0PgFfN5R6C4BqEZD53UZB1WM +J68hXSj1Sa235XAUYE1pZerTKhglvdI9Aeve8+L0w5RDMjmBBA50Yv/YT8liqhNi +mNwbfFbSNhZYWjFada77EKBn60j8QT/xCQzLR1clci7ieW2knw== +=NKye +-----END PGP MESSAGE-----`; + const { data } = await openpgp.decrypt({ + message: await openpgp.readMessage({ armoredMessage: messageToDecrypt }), + decryptionKeys: privateKey + }); + expect(data).to.equal('Hello World!'); + }); + + it('supports encrypting/decrypting new x25519 format (v4 key)', async function () { + // v4 key + const privateKey = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xUkEZIbSkxsHknQrXGfb+kM2iOsOvin8yE05ff5hF8KE6k+saspAZQCy/kfFUYc2 +GkpOHc42BI+MsysKzk4ofjBAfqM+bb7goQ3hzRV1c2VyIDx1c2VyQHRlc3QudGVz +dD7ChwQTGwgAPQUCZIbSkwmQQezK2iB2tIkWIQRqZza9wQZcwxpjGYNB7MraIHa0 +iQIbAwIeAQIZAQILBwIVCAIWAAMnBwIAAFOeZ7jrKZsCzRfu1ffFa77074st0zRo +BTJXoXBQ1ZzLjsh+ZO6fB2odnYJtQYstv45H/3JyLVogcMnFeYmHeSP3AMdJBGSG +0pMZfpd7TiOQv7uKSK+k4HT9lKr5+dmvb7vox/8ids6unEkAF1v8fCKogIrtBWVT +nVbwnovjM3LLexpXFZSgTKRcNMgPRMJ0BBgbCAAqBQJkhtKTCZBB7MraIHa0iRYh +BGpnNr3BBlzDGmMZg0HsytogdrSJAhsMAADCYs2I9wBakIu9Hhxs4R3Jq9F8J7AH +yxsNL0GomZ+hxiE0MOZwRr10DxfVaRabF1fcf9PHSHX2SwEFXUKMIHgbMQs= +=bJqd +-----END PGP PRIVATE KEY BLOCK-----` }); + const plaintext = 'plaintext'; + + const signed = await openpgp.encrypt({ + message: await openpgp.createMessage({ text: plaintext }), + encryptionKeys: privateKey + }); + + const { data } = await openpgp.decrypt({ + message: await openpgp.readMessage({ armoredMessage: signed }), + decryptionKeys: privateKey + }); + expect(data).to.equal(plaintext); + }); + + it('should decrypt test vector X25519-AEAD-OCB (PKESK v6, SEIPD v2)', async function() { + // test vector https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#appendix-A.8 + const armoredMessage = `-----BEGIN PGP MESSAGE----- + +wV0GIQYSyD8ecG9jCP4VGkF3Q6HwM3kOk+mXhIjR2zeNqZMIhRmHzxjV8bU/gXzO +WgBM85PMiVi93AZfJfhK9QmxfdNnZBjeo1VDeVZheQHgaVf7yopqR6W1FT6NOrfS +aQIHAgZhZBZTW+CwcW1g4FKlbExAf56zaw76/prQoN+bAzxpohup69LA7JW/Vp0l +yZnuSj3hcFj0DfqLTGgr4/u717J+sPWbtQBfgMfG9AOIwwrUBqsFE9zW+f1zdlYo +bhF30A+IitsxxA== +-----END PGP MESSAGE-----`; + + const privateKey = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xUsGY4d/4xsAAAAg+U2nu0jWCmHlZ3BqZYfQMxmZu52JGggkLq2EVD34laMAGXKB +exK+cH6NX1hs5hNhIB00TrJmosgv3mg1ditlsLfCsQYfGwoAAABCBYJjh3/jAwsJ +BwUVCg4IDAIWAAKbAwIeCSIhBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce6 +2azJBScJAgcCAAAAAK0oIBA+LX0ifsDm185Ecds2v8lwgyU2kCcUmKfvBXbAf6rh +RYWzuQOwEn7E/aLwIwRaLsdry0+VcallHhSu4RN6HWaEQsiPlR4zxP/TP7mhfVEe +7XWPxtnMUMtf15OyA51YBMdLBmOHf+MZAAAAIIaTJINn+eUBXbki+PSAld2nhJh/ +LVmFsS+60WyvXkQ1AE1gCk95TUR3XFeibg/u/tVY6a//1q0NWC1X+yui3O24wpsG +GBsKAAAALAWCY4d/4wKbDCIhBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce6 +2azJAAAAAAQBIKbpGG2dWTX8j+VjFM21J0hqWlEg+bdiojWnKfA5AQpWUWtnNwDE +M0g12vYxoWM8Y81W+bHBw805I8kWVkXU6vFOi+HWvv/ira7ofJu16NnoUkhclkUr +k0mXubZvyl4GBg== +-----END PGP PRIVATE KEY BLOCK-----` }); + + const { data: decryptedData } = await openpgp.decrypt({ + message: await openpgp.readMessage({ armoredMessage }), + decryptionKeys: privateKey + }); + + expect(decryptedData).to.equal('Hello, world!'); + }); }); - it('should enforce using AES session keys with x448 keys', async function () { - // X448 key (v4) with cast5 as preferred cipher - const privateKeyCast5 = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- + describe('X448/Ed448', async function () { + it('should enforce using AES session keys with x448 keys (v4 key)', async function () { + // X448 key (v4) with cast5 as preferred cipher + const privateKeyCast5 = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- xXsEZRrtaRyScvyNjK0o5ccICztnWhA1MSij7WdzPfuNy7ryUzB+kqzpziBR IIKp5PN0NW3mOYRDnUyo7QHBl4AA30tR5ED8u5v/rNIzKz/mKsD6XeYy+d0Q @@ -4437,26 +4406,342 @@ x8fsFb2AEXLEwlSnL+Eo0O+iUQd3/94yMbMFRlNxrdaqZ3+7CehbnieI/vby LIEnN38XBi0HE70uoU5prxUA -----END PGP PRIVATE KEY BLOCK-----` }); - await expect(openpgp.generateSessionKey({ - encryptionKeys: privateKeyCast5, - config: { preferredSymmetricAlgorithm: openpgp.enums.symmetric.cast5 } - })).to.be.rejectedWith(/Could not generate a session key compatible with the given `encryptionKeys`/); + await expect(openpgp.generateSessionKey({ + encryptionKeys: privateKeyCast5, + config: { preferredSymmetricAlgorithm: openpgp.enums.symmetric.cast5 } + })).to.be.rejectedWith(/Could not generate a session key compatible with the given `encryptionKeys`/); - await expect(openpgp.encrypt({ - message: await openpgp.createMessage({ text: plaintext }), - encryptionKeys: privateKeyCast5, - sessionKey: { data: new Uint8Array(16).fill(1), algorithm: 'cast5' } - })).to.be.rejectedWith(/X25519 and X448 keys can only encrypt AES session keys/); - - await expect(openpgp.decryptSessionKeys({ - message: await openpgp.readMessage({ armoredMessage: `-----BEGIN PGP MESSAGE----- + await expect(openpgp.encrypt({ + message: await openpgp.createMessage({ text: plaintext }), + encryptionKeys: privateKeyCast5, + sessionKey: { data: new Uint8Array(16).fill(1), algorithm: 'cast5' } + })).to.be.rejectedWith(/X25519 and X448 keys can only encrypt AES session keys/); + await expect(openpgp.decryptSessionKeys({ + message: await openpgp.readMessage({ armoredMessage: `-----BEGIN PGP MESSAGE----- + wVwD2k7TUuqJwZkaXvEGk7B3pklJ5uRcRdKwwDJ40yKT0m5ic1e/2F+Se3xQ zDE+N2DZ0B37pu4NUzTGBRo0oLD9EwwZA9+oJpBBOOry3cGmBYWvQHbvBpNE 5X5l8A== -----END PGP MESSAGE-----` }), - decryptionKeys: privateKeyCast5 - })).to.be.rejectedWith(/AES session key expected/); + decryptionKeys: privateKeyCast5 + })).to.be.rejectedWith(/AES session key expected/); + }); + + it('should enforce using 512-bit signature digest', async function () { + // X448 key using sha256 for self signatures + const privateKeySHA256 = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xXsEZCWHXBwwtqciq6ZFU13s+dyhkWR5tOEmF1oX8OiP1B5ypfqyGVM8DkQh +5eTIMwB1oqJCROANoyA0q2dSigAAbDA5xr74DeClPPXC4ZXJ9uzuJWKvQvE8 +x3EflhgoQCGBM7JfvH5zwdrJvPt8RKDvm0QkZzhPvnFoHnzNBHRlc3TCugQQ +HAgAPgWCZCWHXAQLCQcICZDsN6h/ys3ppwMVCAoEFgACAQIZAQKbAwIeARYh +BOJyE9P2eIcU2N2Ne+w3qH/KzemnAAAh1hTFCcEU77bU3YelrJTCNIOQnvt7 +Hs6yZz2053CQTOC+wHkUQLaYYBEXSNyLZxoyv+NuGTiwbuYtAOlbE2erM7Cx +8B2Qz7M29UkFLMBUfb+yi+gTYYUWCXVQ7Um7MGjjgUG8+9p452i6f28mhRD8 +tTgNAMd5BGQlh1wavTIFgILtbzrqQCiwDGx0YcFNzu9+FZ8vK5Mmm7UEZj0a +y7FWQtZw8tTaU6mY+RrSa52RjzkGLtQAQO++tgYqc+BnCFdCZ3ZYPRvD3mof +ffoo3l4xmto+iyvJZbQ4wQPXttg7VjCpEfOsL9TW9Xs09aIbysKmBBgcCAAq +BYJkJYdcCZDsN6h/ys3ppwKbDBYhBOJyE9P2eIcU2N2Ne+w3qH/KzemnAAC0 +6/eZhh/Oj2gRdab2JeFGWACGIRDKxPXsWRCXR4YrSxcvCKK6rOvsyxQsgIsJ +JyPYkRPfmbKcseUDAEkSBLAfeizDGh7ea0GOdIMhwE/CW4f/H8ULbwi36y13 +x3oMNVaYsI9dZ588Gpi8XYy2jOtqIPQ1AA== +-----END PGP PRIVATE KEY BLOCK-----` }); + + await expect(privateKeySHA256.getSigningKey()).to.be.rejectedWith(/Hash algorithm too weak for EdDSA/); + }); + + it('supports encrypting/decrypting with x448 (v4 key)', async function () { + // v4 key + const privateKey = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xXsEZRqJ5BwHESfKnw5YJly5WobjigVm0kKY84NxrP6JKeIvIWiFqqSlozGpKZyR +50YbVTHmxpUCuJ7YNwX0UoAAoSO8IXmMM/XMd4ph00ju+fbSHdtQfyNhfFTi3UoM +V5DiFT+uOYDP+zwAwLWCR86csxmCWn6O10DNHcDNF1VzZXJBIDxVc2VyQUB0ZXN0 +LnRlc3Q+wroEExwKAD4FAmUaieQJEC8lwIrxSM+5FiEEGR2s5Bj5WVDN0Px6LyXA +ivFIz7kCGwMCHgkCGQECCwcDFQoIAhYAAycHAgAA21/PqAuGDL5+3qrf3YoVOP+5 +0BoJ+ZMhzcgax+cQTyndmOZYBfOqV/SJ8mf6CRhbB76JhGIvmRMtyYDQgDMVvcoA +yojVNs6e/Jco16bVJxM85wKDXJuq6AhtPQ8w/0WaCJtEf1uxqeQPEbOM+KtT/xY2 +KgDHeQRlGonkGuOtAhogSIU3z/+gFzF8U7JQe7QDRYr9VWfi2WXFFarzg/3DMRur +oIB7mqkaaSatrvVuud1ZmRCWAMM4f57dvSdCKsVqSe+tlS225OmdWmnGLqyErBb6 +44E2oENhDUom9OUGUPm8dXUjQbrmw6ec9hNLHWXCpgQYHAoAKgUCZRqJ5AkQLyXA +ivFIz7kWIQQZHazkGPlZUM3Q/HovJcCK8UjPuQIbDAAAZka10c8KlmwftJuboIV5 +DalGWrZhbywJpEZRfoikcebSYi5++w1SbpXZGu27sl+BznGyyyqAfxyJjoCZaqCs +ewbKh04DNAg4v4v0W0a8UvD3j/CuciEMXjK9nUErt91zEwxNZy43yrQY2aAayDs8 +94FqMAA= +=GBh1 +-----END PGP PRIVATE KEY BLOCK-----` }); + const plaintext = 'plaintext'; + + const signed = await openpgp.encrypt({ + message: await openpgp.createMessage({ text: plaintext }), + encryptionKeys: privateKey + }); + + const { data } = await openpgp.decrypt({ + message: await openpgp.readMessage({ armoredMessage: signed }), + decryptionKeys: privateKey + }); + expect(data).to.equal(plaintext); + }); + + it('supports encrypting/decrypting with x448 (v6 key)', async function () { + const privateKey = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xX0GZRqLYhwAAAA52IEq/TpKiPp6RofQaq4uhCruTtiG+qiVFnwsQgeh0ui34kHD +Y1E04mBai0pCoDiFVokwsKt3F5sAAC8lDYfVP/p3atbXJDTJB2W9WmZxIS7pUGhS +bjlWpZB/OVTBsoIfP/2J+Hi4ESwBRfDUDgwK4aJVKsLAIAYfHAoAAAA/BQJlGoti +IqEGobsxt8WKsMuJWANyTXpWMdC1QN/7EyJClfcs+nBgqdUCGwMCHgkCCwcDFQoI +AhYABScHAwcCAAAAAPiGIG2qmhCULQ/+H4rKV0XEM1x0uVY3l878Pa6ijZLouZU/ +VRd5PnbGyLPL++q3LDViUUdZ1uusRc01f677Q6wpUU90k8MH/oULwI0+KPtqe1N4 +6nr1NTERsAmAaPjUdf4ZUXX/GWiTd/AlsS5JqGnAQxKRJkzCJacOTOElRMjzGUX7 +CGaAnhSC86YRZ68ocTPfZysAzRdVc2VyQiA8VXNlckJAdGVzdC50ZXN0PsLADQYT +HAoAAAAsBQJlGotiIqEGobsxt8WKsMuJWANyTXpWMdC1QN/7EyJClfcs+nBgqdUC +GQEAAAAASKwgVzMoPb2Hbr3lbNI1CRWECokYLokL7F8MbYiMnlg+v6QXLdStvT13 +ZjxdrWQAx3MbihSOUSXbdAys90yMOAdtognj+x418J/TaYFMtIGBHwoHv8gQVnx9 +9ICv8ezx1T5VvGBYNuKZ5Ww0WPEpYMf1VA+Y9JxpohdcRenNBdSug4tLWla2y8NH +aO28Fltpb4AuGQDHewZlGotiGgAAADjdabr1ohAOnbSUUkVhtUM/LVdnYgDLhmaj +YZ1N7TWY0fqEpMk2LLo2165HOmhddRPeTB1TWbuwBwB8lKc3czFUzYcAgvZ08T5S +UUHjfIhjeJeY4yd0OZDfzPw1vbegCc7t94bT+XGoIQbC/Bl7HCyAiMLADQYYHAoA +AAAsBQJlGotiIqEGobsxt8WKsMuJWANyTXpWMdC1QN/7EyJClfcs+nBgqdUCGwwA +AAAAHh0gf2kdqLoXdFX+aNVORr5VCVgcm2gBw8l68lDJ1ftA71bMllFi6Q5sLPUr +6UCpJYYk3o3hYUYzIHmCIZGVYe1pxRgIUNqxydXEfzylJmN5NbiJNkjJizrI7oAR +1mIcEEb/hmRMOUs1V2mcGuoeALBI/r/SyqDE2GRjH6d6g1RS7ZARPPHlZlY4CTqC +4a7L+8odDwA= +=chx0 +-----END PGP PRIVATE KEY BLOCK-----` }); + const plaintext = 'plaintext'; + + const signed = await openpgp.encrypt({ + message: await openpgp.createMessage({ text: plaintext }), + encryptionKeys: privateKey + }); + + const { data } = await openpgp.decrypt({ + message: await openpgp.readMessage({ armoredMessage: signed }), + decryptionKeys: privateKey + }); + expect(data).to.equal(plaintext); + }); + + it('decrypt/verify should succeed using X448/Ed448 (PKESK v4, SEIPD v2, GCM)', async function() { + // data generated by gopenpgp + const armoredMessage = `-----BEGIN PGP MESSAGE----- + +wWkGFQQ70agVm6o5r3tEzY5mrYaOV8yHChpUetZ33zrKGtw1F4PeFrE4bYkcTMQM +IcGoXcZj/0GJDCkOLLleSwrvuAuUwZV11bHBZ6eNTyj+XxhLdVflV/zqPmBhTHY9 +SMn0YYHwgiQFk6PSwGICBwMMRYkTpsy0dE4YKasf6b4Oh9cn6HYY5rjnrtvrwD+F +LrsELfudYwpwHBA5jnO11Hl5mUyXhhWSdPoLGdeiYP5R/vZjqoZr3P6FL4dCdVni +fGChUUSYmpO4HIFrRBt2gAxl+f0Q8GCOG8c7EQ7c5600kJOlHM7SuoLqsxd482V1 +H/1Rxd3cPwTDfOjH26KuDv60p0XjdCGyQXcDQMCPV+ZTs0TQl4wTFogZGaRMd9GC +5D5t/guKzR+H1ipXSFjFdWWTEehx8m0RKKKT3Bl81awKZb8ulR6YKI5x39nwOySN +azDRR3gn9xlKjcpa83k5sSZbUTxC8lzTeuMP0PkDrU2IpZUZOlzOhGYOGrtTFATK +PSoZU33h2h3hJqiX9aKrnw== +=Is5l +-----END PGP MESSAGE-----`; + + const privateKey = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xXsEZRqJ5BxV/xdxR4KvPofk3EzKaIZqM0Wlw904q+2S6Z84OmXN6Q1xCYurcwN1 +wLOlGJ/CO2QhByEdGlUldwAAIQSMnMITcmXQU3EWK5S81FS+u1IZFP55j51bA5mS +HZ/A7MOpyN40ybW8mhMIXXUYB7kC/bOTmwVHGt3NF1VzZXJCIDxVc2VyQkB0ZXN0 +LnRlc3Q+wrwEExwKAEAFAmUaieQJEP3WralmOT0PFiEEq4zuQzIBSh+Nk6G9/dat +qWY5PQ8CGwMCHgkCGQECCwcDFQoIAhYABScHAwcCAADAvnnhLp0DJYk7E0GfksCg +pUnnCjEePMVvRPVY3dwr9wLpdL/7T70fz541XVE8giYiZD7eiKvfc/nMgOhu1eqK +uXGUtDGBeabitJcrbquy2Tp/ENuW6rRHP7sAbu0mj6XxYEeCzKjGRT5Iq25AMevm +yeoIAMd5BGUaieQaqj/dF+uZGt9QLuji2eOlDC0/quq/sAtdJTbI1xj04aF0X7kJ +lVhEKeWZeAEpD4rVOCsrhMvr21gAu/BaFVKGUOuf0+ZE5jGcFcBvEP7OGyO296ry +zV7ONWS/FuoZ/NZmgWo9m9ftPtwqKDsgOWxiIj4cesKmBBgcCgAqBQJlGonkCRD9 +1q2pZjk9DxYhBKuM7kMyAUofjZOhvf3WralmOT0PAhsMAADWb+0aY+NblShwsym/ +2geh6XaqQUCJgdRfEl8xYLau/o8QQAzRp0ZBA+KeK3uwhRW3RizuqIw5iribAK3+ +30Si5nvv0TivalPK2C9yAqzh9rkNNUQa9b17IHYs/WwQrvP3F5EZ3V+StqdveAEo +FecSL/wTAA== +=FANS +-----END PGP PRIVATE KEY BLOCK-----` }); + + const senderKey = await openpgp.readKey({ + armoredKey: `-----BEGIN PGP PUBLIC KEY BLOCK----- + +xj8EZRqJ5BwHESfKnw5YJly5WobjigVm0kKY84NxrP6JKeIvIWiFqqSlozGpKZyR +50YbVTHmxpUCuJ7YNwX0UoDNF1VzZXJBIDxVc2VyQUB0ZXN0LnRlc3Q+wroEExwK +AD4FAmUaieQJEC8lwIrxSM+5FiEEGR2s5Bj5WVDN0Px6LyXAivFIz7kCGwMCHgkC +GQECCwcDFQoIAhYAAycHAgAA21/PqAuGDL5+3qrf3YoVOP+50BoJ+ZMhzcgax+cQ +TyndmOZYBfOqV/SJ8mf6CRhbB76JhGIvmRMtyYDQgDMVvcoAyojVNs6e/Jco16bV +JxM85wKDXJuq6AhtPQ8w/0WaCJtEf1uxqeQPEbOM+KtT/xY2KgDOPgRlGonkGuOt +AhogSIU3z/+gFzF8U7JQe7QDRYr9VWfi2WXFFarzg/3DMRuroIB7mqkaaSatrvVu +ud1ZmRCWwqYEGBwKACoFAmUaieQJEC8lwIrxSM+5FiEEGR2s5Bj5WVDN0Px6LyXA +ivFIz7kCGwwAAGZGtdHPCpZsH7Sbm6CFeQ2pRlq2YW8sCaRGUX6IpHHm0mIufvsN +Um6V2Rrtu7Jfgc5xsssqgH8ciY6AmWqgrHsGyodOAzQIOL+L9FtGvFLw94/wrnIh +DF4yvZ1BK7fdcxMMTWcuN8q0GNmgGsg7PPeBajAA +=VA/P +-----END PGP PUBLIC KEY BLOCK-----` }); + + const { data: decryptedData, signatures } = await openpgp.decrypt({ + message: await openpgp.readMessage({ armoredMessage }), + decryptionKeys: privateKey, + verificationKeys: senderKey + }); + + expect(decryptedData).to.equal('Hello there'); + expect(signatures).to.have.length(1); + expect(await signatures[0].verified).to.be.true; + }); + + + it('decrypt/verify should succeed using X448/Ed448 (PKESK v6, SEIPD v2, GCM)', async function() { + // data generated by gopenpgp + const armoredMessage = `-----BEGIN PGP MESSAGE----- + +wXUGIQZh4qTsn8glFgGNbIdCTl8gH2OtkI/PAGCQ0gi9s9k/rhrDhXo7kUKDJ39F +fNp3kmAaM24Ce3bcYXwLy0gF2i6rxfL20D+g3cxv0i3CuXQCgcbojTN/8KY8ExiV +Xdfo+OWIZ5XndtyMpJW28BiLHru+n9bSwM8CBwMMENh7cT8lILXteh885FrUUD1Q +JMtD7xJUn2y78cVGgFSIkLbvFPDerB37xuhtMRkykuWgbUoJH/kcgBPdeCoYzJmf +LV9FyATv0/AYq0yWpQ0VUfNLTFyeHIGxz7NHvrzJSrOy1Gm31PXqWvb4sBROjnOX +oAk12JdPudz3l1QZT/DX947f4h6hwkVv7RRT0oOS2pMaz/mekRuD6utUcpsjFQ/M +EDphnhOsB4RH0il8YPVc9DCnf3GhSs66h+Z699MXHBaUmdtiN1IgoEgLfb/900U2 +TfI6dvrvC56WIMA8EA1COvLGc9Ge4owW0UE8jIuqWLzA2nVg5belbzhNnOEh9b1c +OcDUh8CfBuXqHEi/ANMUOMmaIGfcHfQFVu5v/UMcLxcH/fSVF6DvtOxEoUxASWBS +mp6yC4A778BFuDFXb+/T8FjuJBaUj9rCSkYqt1TYVKG1XZPI4OdIvGtneo+vH/Cq +F6bxlLWU6oskZ5SE+xJblmmO01ObM9JRi9D8jZnXedTHExAnXHXIb8I= +=5RQw +-----END PGP MESSAGE-----`; + + const privateKey = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xX0GZRqLYhwAAAA52IEq/TpKiPp6RofQaq4uhCruTtiG+qiVFnwsQgeh0ui34kHD +Y1E04mBai0pCoDiFVokwsKt3F5sAAC8lDYfVP/p3atbXJDTJB2W9WmZxIS7pUGhS +bjlWpZB/OVTBsoIfP/2J+Hi4ESwBRfDUDgwK4aJVKsLAIAYfHAoAAAA/BQJlGoti +IqEGobsxt8WKsMuJWANyTXpWMdC1QN/7EyJClfcs+nBgqdUCGwMCHgkCCwcDFQoI +AhYABScHAwcCAAAAAPiGIG2qmhCULQ/+H4rKV0XEM1x0uVY3l878Pa6ijZLouZU/ +VRd5PnbGyLPL++q3LDViUUdZ1uusRc01f677Q6wpUU90k8MH/oULwI0+KPtqe1N4 +6nr1NTERsAmAaPjUdf4ZUXX/GWiTd/AlsS5JqGnAQxKRJkzCJacOTOElRMjzGUX7 +CGaAnhSC86YRZ68ocTPfZysAzRdVc2VyQiA8VXNlckJAdGVzdC50ZXN0PsLADQYT +HAoAAAAsBQJlGotiIqEGobsxt8WKsMuJWANyTXpWMdC1QN/7EyJClfcs+nBgqdUC +GQEAAAAASKwgVzMoPb2Hbr3lbNI1CRWECokYLokL7F8MbYiMnlg+v6QXLdStvT13 +ZjxdrWQAx3MbihSOUSXbdAys90yMOAdtognj+x418J/TaYFMtIGBHwoHv8gQVnx9 +9ICv8ezx1T5VvGBYNuKZ5Ww0WPEpYMf1VA+Y9JxpohdcRenNBdSug4tLWla2y8NH +aO28Fltpb4AuGQDHewZlGotiGgAAADjdabr1ohAOnbSUUkVhtUM/LVdnYgDLhmaj +YZ1N7TWY0fqEpMk2LLo2165HOmhddRPeTB1TWbuwBwB8lKc3czFUzYcAgvZ08T5S +UUHjfIhjeJeY4yd0OZDfzPw1vbegCc7t94bT+XGoIQbC/Bl7HCyAiMLADQYYHAoA +AAAsBQJlGotiIqEGobsxt8WKsMuJWANyTXpWMdC1QN/7EyJClfcs+nBgqdUCGwwA +AAAAHh0gf2kdqLoXdFX+aNVORr5VCVgcm2gBw8l68lDJ1ftA71bMllFi6Q5sLPUr +6UCpJYYk3o3hYUYzIHmCIZGVYe1pxRgIUNqxydXEfzylJmN5NbiJNkjJizrI7oAR +1mIcEEb/hmRMOUs1V2mcGuoeALBI/r/SyqDE2GRjH6d6g1RS7ZARPPHlZlY4CTqC +4a7L+8odDwA= +=chx0 +-----END PGP PRIVATE KEY BLOCK-----` }); + + const senderKey = await openpgp.readKey({ + armoredKey: `-----BEGIN PGP PUBLIC KEY BLOCK----- + +xkMGZRqLYhwAAAA5U/IaIOge/FoLzCetXKx029bdJHCz2hMFBRMuzq4msjaT+hLe +V6puyC/PeSEfaanqTuo31vvsti2AwsAeBh8cCgAAAD0FAmUai2IioQYDGJ2wdEcO +zIVPDVDs6gYQASdGfG2EozBUGqEgvaj4dQIbAwIeCQILBwMVCggCFgADJwcCAAAA +ADYqIL5j5+FD/jwKRP1atdNf1IKfe8fPjdZv74CSalYvUdCaskTdLiAaW17NkrYT +2i9qDPErFWsvXi4LqGzqQnQkiJZBJ4x57EJPL4Z2vqPTBvgWEU2egi7fK7YAGZmk +Vf/n/X3Vh5ZSvIoUMChRmYqBBNI7MkS/I7QAJHkvi9XcANx44B0bz+yqETz2tNJ6 +8VeeDgkAzRdVc2VyQSA8VXNlckFAdGVzdC50ZXN0PsLADQYTHAoAAAAsBQJlGoti +IqEGAxidsHRHDsyFTw1Q7OoGEAEnRnxthKMwVBqhIL2o+HUCGQEAAAAAXD8gfvYz +WLLMxaFuC3C/RJH9fG84hb9mtPgjH3bfqW+g4Ti1ov8PjoJtk6ObtUB45J9J3G3X +FIqegAtGwI1Dy1U+M9dyXOqvpHwxs8iAFbEpwxLZ5K1ikFsbmoCZz4rmN0DbFyX2 +JbltaV5nUtNqHiUXqoKIPvch98ANe3PDyIAxNf7TAzk3W0lQQa+Cp7TSiFEqJADO +QgZlGotiGgAAADjKb5lwMEt0ubSvwydaAF89wsn6H8NJO7kox5ioWW2Grn88CUZD +YaRBZj3ZH8HMdaih5kN4hJAeCMLADQYYHAoAAAAsBQJlGotiIqEGAxidsHRHDsyF +Tw1Q7OoGEAEnRnxthKMwVBqhIL2o+HUCGwwAAAAAFIQgGYYweuBej4XHAgZrcez8 +8VoTbIZDjMv6Qbj9g6jjW16Fyp10DKda10FFmbY+YjbNvQNYksF9bN/KFSS/PTYt +AVaOZDfW4fiN5s1QaYmA/xCT/zLHEYGryYCJLoLd7KLw28LS1KAWrC9h5cY6+fZE +05cavO/D/WqBLVPuA+5bftXnDvGcVS1p7buaMtQjKz4hAwA= +=GUIG +-----END PGP PUBLIC KEY BLOCK-----` }); + + const { data: decryptedData, signatures } = await openpgp.decrypt({ + message: await openpgp.readMessage({ armoredMessage }), + decryptionKeys: privateKey, + verificationKeys: senderKey + }); + + expect(decryptedData).to.equal('Hello there'); + expect(signatures).to.have.length(1); + expect(await signatures[0].verified).to.be.true; + }); + + it('decrypt/verify should succeed using X448/Ed448 (PKESK v6, SEIPD v2, OCB)', async function() { + // data generated by gopenpgp + const armoredMessage = `-----BEGIN PGP MESSAGE----- + +wXUGIQaYemlYu2ObOZ2IjFbL77NygqexwaCgtb0COZ0EnXfXlBri0wADNxbvwCnJ +GDlRX9VhIy46oPAvVJjm2d7ZC6wqxNfFuzQEB8KzwYBkExmZuAfO5KJ8la6+DRhc +OUH3A9cBGzq0eiKaKRqjHkiLHY5pFNPSwNoCBwIM98RL63I8iMyxcXpXQlBrYlBx +5uegrENlleNg6UJFr7rBT4eJH+Qeksb//V87eZymzqXZBsrTYmUjsFgYd5kL8NlU +wovy+qQnZmEaUKieDx3w+orR8b32ub5CNjHJa5lCdNWsIK825S5JUifZDd3hR6lC +EgtZRwxY/1CyQU94LR9j6w/YVF0W31+LxGGkL+uJEx0khJUzpxUM9QSEREOY7Frs +EegHNwDvxvxEwWpfkJOPIDME6Y7UcpsNp6xgiZ/XF06IRsliCRbeYaH1IWW+y0OS +CmPvvTFUzjwTxWogDccHz8YLHU0y6TKxf14YMvVLg2tf2P/BVVZSg0ejz6pfDKA5 +AP+Q/eXBAH272SpBjKo7YcVpTsz0KpWyhB6Jra4xaUFkt6pg39ydR3RJMvxbQVlR +aZqV/+1rwIiIauyHKiJFdCiXYPDU3xibVkFIFhuk5JwHm29XvOV1r8FFx7d78X5P +yJnXcXsl+GxwOojcLXSL0CEIU/iRqyAIyyhvUyyss3glehhgx0fENV2P/Ygi/naN +nJUJgg== +=m19C +-----END PGP MESSAGE-----`; + + const privateKey = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xX0GZRqLYhwAAAA5U/IaIOge/FoLzCetXKx029bdJHCz2hMFBRMuzq4msjaT+hLe +V6puyC/PeSEfaanqTuo31vvsti2AAIttr4GDGXF4vfPzbzkWV9dT4VVsIU7QqLv1 +hzwZ+k7pHroRyXnUiYxRYHuzlg7Vw4CrAtN/8T65OMLAHgYfHAoAAAA9BQJlGoti +IqEGAxidsHRHDsyFTw1Q7OoGEAEnRnxthKMwVBqhIL2o+HUCGwMCHgkCCwcDFQoI +AhYAAycHAgAAAAA2KiC+Y+fhQ/48CkT9WrXTX9SCn3vHz43Wb++AkmpWL1HQmrJE +3S4gGltezZK2E9ovagzxKxVrL14uC6hs6kJ0JIiWQSeMeexCTy+Gdr6j0wb4FhFN +noIu3yu2ABmZpFX/5/191YeWUryKFDAoUZmKgQTSOzJEvyO0ACR5L4vV3ADceOAd +G8/sqhE89rTSevFXng4JAM0XVXNlckEgPFVzZXJBQHRlc3QudGVzdD7CwA0GExwK +AAAALAUCZRqLYiKhBgMYnbB0Rw7MhU8NUOzqBhABJ0Z8bYSjMFQaoSC9qPh1AhkB +AAAAAFw/IH72M1iyzMWhbgtwv0SR/XxvOIW/ZrT4Ix9236lvoOE4taL/D46CbZOj +m7VAeOSfSdxt1xSKnoALRsCNQ8tVPjPXclzqr6R8MbPIgBWxKcMS2eStYpBbG5qA +mc+K5jdA2xcl9iW5bWleZ1LTah4lF6qCiD73IffADXtzw8iAMTX+0wM5N1tJUEGv +gqe00ohRKiQAx3sGZRqLYhoAAAA4ym+ZcDBLdLm0r8MnWgBfPcLJ+h/DSTu5KMeY +qFlthq5/PAlGQ2GkQWY92R/BzHWooeZDeISQHggAuraV/u+CE642fcbcq90OY+qg +n739wkHcBps/s/MgMI+Q2H13vEsFpYZ/kuBIIYP39xkdU48/1GbCwA0GGBwKAAAA +LAUCZRqLYiKhBgMYnbB0Rw7MhU8NUOzqBhABJ0Z8bYSjMFQaoSC9qPh1AhsMAAAA +ABSEIBmGMHrgXo+FxwIGa3Hs/PFaE2yGQ4zL+kG4/YOo41tehcqddAynWtdBRZm2 +PmI2zb0DWJLBfWzfyhUkvz02LQFWjmQ31uH4jebNUGmJgP8Qk/8yxxGBq8mAiS6C +3eyi8NvC0tSgFqwvYeXGOvn2RNOXGrzvw/1qgS1T7gPuW37V5w7xnFUtae27mjLU +Iys+IQMA +=iwhO +-----END PGP PRIVATE KEY BLOCK-----` }); + + const senderKey = await openpgp.readKey({ + armoredKey: `-----BEGIN PGP PUBLIC KEY BLOCK----- + +xkMGZRqLYhwAAAA52IEq/TpKiPp6RofQaq4uhCruTtiG+qiVFnwsQgeh0ui34kHD +Y1E04mBai0pCoDiFVokwsKt3F5sAwsAgBh8cCgAAAD8FAmUai2IioQahuzG3xYqw +y4lYA3JNelYx0LVA3/sTIkKV9yz6cGCp1QIbAwIeCQILBwMVCggCFgAFJwcDBwIA +AAAA+IYgbaqaEJQtD/4fispXRcQzXHS5VjeXzvw9rqKNkui5lT9VF3k+dsbIs8v7 +6rcsNWJRR1nW66xFzTV/rvtDrClRT3STwwf+hQvAjT4o+2p7U3jqevU1MRGwCYBo ++NR1/hlRdf8ZaJN38CWxLkmoacBDEpEmTMIlpw5M4SVEyPMZRfsIZoCeFILzphFn +ryhxM99nKwDNF1VzZXJCIDxVc2VyQkB0ZXN0LnRlc3Q+wsANBhMcCgAAACwFAmUa +i2IioQahuzG3xYqwy4lYA3JNelYx0LVA3/sTIkKV9yz6cGCp1QIZAQAAAABIrCBX +Myg9vYduveVs0jUJFYQKiRguiQvsXwxtiIyeWD6/pBct1K29PXdmPF2tZADHcxuK +FI5RJdt0DKz3TIw4B22iCeP7HjXwn9NpgUy0gYEfCge/yBBWfH30gK/x7PHVPlW8 +YFg24pnlbDRY8Slgx/VUD5j0nGmiF1xF6c0F1K6Di0taVrbLw0do7bwWW2lvgC4Z +AM5CBmUai2IaAAAAON1puvWiEA6dtJRSRWG1Qz8tV2diAMuGZqNhnU3tNZjR+oSk +yTYsujbXrkc6aF11E95MHVNZu7AHwsANBhgcCgAAACwFAmUai2IioQahuzG3xYqw +y4lYA3JNelYx0LVA3/sTIkKV9yz6cGCp1QIbDAAAAAAeHSB/aR2ouhd0Vf5o1U5G +vlUJWBybaAHDyXryUMnV+0DvVsyWUWLpDmws9SvpQKklhiTejeFhRjMgeYIhkZVh +7WnFGAhQ2rHJ1cR/PKUmY3k1uIk2SMmLOsjugBHWYhwQRv+GZEw5SzVXaZwa6h4A +sEj+v9LKoMTYZGMfp3qDVFLtkBE88eVmVjgJOoLhrsv7yh0PAA== +=2Usy +-----END PGP PUBLIC KEY BLOCK-----` }); + + const { data: decryptedData, signatures } = await openpgp.decrypt({ + message: await openpgp.readMessage({ armoredMessage }), + decryptionKeys: privateKey, + verificationKeys: senderKey + }); + + expect(decryptedData).to.equal('Hello nice to meet you'); + expect(signatures).to.have.length(1); + expect(await signatures[0].verified).to.be.true; + }); }); describe('Sign and verify with each curve', function() { @@ -4532,29 +4817,6 @@ bWleZ1LTah4lF6qCiD73IffADXtzw8iAMTX+0wM5N1tJUEGvgqe00ohRKiQA expect(signatures).to.have.length(1); expect(await signatures[0].verified).to.be.true; }); - - it('should enforce using 512-bit signature digest', async function () { - // X448 key using sha256 for self signatures - const privateKeySHA256 = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- - -xXsEZCWHXBwwtqciq6ZFU13s+dyhkWR5tOEmF1oX8OiP1B5ypfqyGVM8DkQh -5eTIMwB1oqJCROANoyA0q2dSigAAbDA5xr74DeClPPXC4ZXJ9uzuJWKvQvE8 -x3EflhgoQCGBM7JfvH5zwdrJvPt8RKDvm0QkZzhPvnFoHnzNBHRlc3TCugQQ -HAgAPgWCZCWHXAQLCQcICZDsN6h/ys3ppwMVCAoEFgACAQIZAQKbAwIeARYh -BOJyE9P2eIcU2N2Ne+w3qH/KzemnAAAh1hTFCcEU77bU3YelrJTCNIOQnvt7 -Hs6yZz2053CQTOC+wHkUQLaYYBEXSNyLZxoyv+NuGTiwbuYtAOlbE2erM7Cx -8B2Qz7M29UkFLMBUfb+yi+gTYYUWCXVQ7Um7MGjjgUG8+9p452i6f28mhRD8 -tTgNAMd5BGQlh1wavTIFgILtbzrqQCiwDGx0YcFNzu9+FZ8vK5Mmm7UEZj0a -y7FWQtZw8tTaU6mY+RrSa52RjzkGLtQAQO++tgYqc+BnCFdCZ3ZYPRvD3mof -ffoo3l4xmto+iyvJZbQ4wQPXttg7VjCpEfOsL9TW9Xs09aIbysKmBBgcCAAq -BYJkJYdcCZDsN6h/ys3ppwKbDBYhBOJyE9P2eIcU2N2Ne+w3qH/KzemnAAC0 -6/eZhh/Oj2gRdab2JeFGWACGIRDKxPXsWRCXR4YrSxcvCKK6rOvsyxQsgIsJ -JyPYkRPfmbKcseUDAEkSBLAfeizDGh7ea0GOdIMhwE/CW4f/H8ULbwi36y13 -x3oMNVaYsI9dZ588Gpi8XYy2jOtqIPQ1AA== ------END PGP PRIVATE KEY BLOCK-----` }); - - await expect(privateKeySHA256.getSigningKey()).to.be.rejectedWith(/Hash algorithm too weak for EdDSA/); - }); }); describe('Errors', function() { From 2afa19db01c2ca4b2cf75e60be1324a39cc52412 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Fri, 29 Sep 2023 22:21:43 +0200 Subject: [PATCH 064/201] Run npm audit --- package-lock.json | 300 ++++++++++------------------------------------ 1 file changed, 66 insertions(+), 234 deletions(-) diff --git a/package-lock.json b/package-lock.json index feafc4e0..a1264117 100644 --- a/package-lock.json +++ b/package-lock.json @@ -411,18 +411,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/@eslint/eslintrc/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -460,18 +448,6 @@ } } }, - "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/@humanwhocodes/config-array/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -2171,9 +2147,9 @@ } }, "node_modules/engine.io": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.4.1.tgz", - "integrity": "sha512-JFYQurD/nbsA5BSPmbaOSLa3tSVj8L6o4srSwXXY3NqE+gGUNmmPTbhn8tjzcCtSqhFgIeqef81ngny8JM25hw==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.4.2.tgz", + "integrity": "sha512-FKn/3oMiJjrOEOeUub2WCox6JhxBXq/Zn3fZOMCBxKnNYtsdKjxhl7yR3fZhM9PV+rdE75SU5SYMc+2PGzo+Tg==", "dev": true, "dependencies": { "@types/cookie": "^0.4.1", @@ -2453,9 +2429,9 @@ } }, "node_modules/eslint-config-airbnb-base/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -2569,18 +2545,6 @@ "ms": "^2.1.1" } }, - "node_modules/eslint-plugin-import/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/eslint-plugin-import/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -2588,9 +2552,9 @@ "dev": true }, "node_modules/eslint-plugin-import/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -2631,23 +2595,10 @@ "dev": true, "peer": true }, - "node_modules/eslint-plugin-jsx-a11y/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/eslint-plugin-jsx-a11y/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "peer": true, "bin": { @@ -2696,19 +2647,6 @@ "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" } }, - "node_modules/eslint-plugin-react/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/eslint-plugin-react/node_modules/resolve": { "version": "2.0.0-next.4", "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz", @@ -2728,9 +2666,9 @@ } }, "node_modules/eslint-plugin-react/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "peer": true, "bin": { @@ -2872,18 +2810,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/eslint/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -3370,9 +3296,9 @@ } }, "node_modules/get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true, "engines": { "node": "*" @@ -3440,18 +3366,6 @@ "node": ">= 6" } }, - "node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -4179,9 +4093,9 @@ } }, "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -4934,15 +4848,6 @@ "node": ">=6" } }, - "node_modules/make-dir/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", @@ -5077,9 +4982,9 @@ "dev": true }, "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "dependencies": { "brace-expansion": "^1.1.7" @@ -6361,9 +6266,9 @@ "dev": true }, "node_modules/semver": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", - "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, "bin": { "semver": "bin/semver" @@ -6485,9 +6390,9 @@ } }, "node_modules/socket.io-parser": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.2.tgz", - "integrity": "sha512-DJtziuKypFkMMHCm2uIshOYC7QaylbtzQwiMYDuCKy3OPkjLzu4B2vAhTlqipRHHzrI0NJeBAizTK7X+6m1jVw==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", "dev": true, "dependencies": { "@socket.io/component-emitter": "~3.1.0", @@ -7423,9 +7328,9 @@ "dev": true }, "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, "engines": { "node": ">=0.10.0" @@ -7959,15 +7864,6 @@ "argparse": "^2.0.1" } }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -7996,15 +7892,6 @@ "ms": "2.1.2" } }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -9333,9 +9220,9 @@ "dev": true }, "engine.io": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.4.1.tgz", - "integrity": "sha512-JFYQurD/nbsA5BSPmbaOSLa3tSVj8L6o4srSwXXY3NqE+gGUNmmPTbhn8tjzcCtSqhFgIeqef81ngny8JM25hw==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.4.2.tgz", + "integrity": "sha512-FKn/3oMiJjrOEOeUub2WCox6JhxBXq/Zn3fZOMCBxKnNYtsdKjxhl7yR3fZhM9PV+rdE75SU5SYMc+2PGzo+Tg==", "dev": true, "requires": { "@types/cookie": "^0.4.1", @@ -9595,15 +9482,6 @@ "argparse": "^2.0.1" } }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -9636,9 +9514,9 @@ }, "dependencies": { "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true } } @@ -9736,15 +9614,6 @@ "ms": "^2.1.1" } }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -9752,9 +9621,9 @@ "dev": true }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true } } @@ -9788,20 +9657,10 @@ "dev": true, "peer": true }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "peer": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "peer": true } @@ -9830,16 +9689,6 @@ "string.prototype.matchall": "^4.0.7" }, "dependencies": { - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "peer": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, "resolve": { "version": "2.0.0-next.4", "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz", @@ -9853,9 +9702,9 @@ } }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "peer": true } @@ -10271,9 +10120,9 @@ "dev": true }, "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true }, "get-intrinsic": { @@ -10309,17 +10158,6 @@ "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" - }, - "dependencies": { - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } } }, "glob-parent": { @@ -10866,9 +10704,9 @@ }, "dependencies": { "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true } } @@ -11483,12 +11321,6 @@ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true } } }, @@ -11600,9 +11432,9 @@ "dev": true }, "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -12561,9 +12393,9 @@ "dev": true }, "semver": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", - "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true }, "set-blocking": { @@ -12677,9 +12509,9 @@ } }, "socket.io-parser": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.2.tgz", - "integrity": "sha512-DJtziuKypFkMMHCm2uIshOYC7QaylbtzQwiMYDuCKy3OPkjLzu4B2vAhTlqipRHHzrI0NJeBAizTK7X+6m1jVw==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", "dev": true, "requires": { "@socket.io/component-emitter": "~3.1.0", @@ -13375,9 +13207,9 @@ "dev": true }, "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true }, "workerpool": { From 1509364a4987353b6c071fb11aecc4963d83e90f Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Tue, 3 Oct 2023 13:36:05 +0200 Subject: [PATCH 065/201] Throw on unexpected param sizes in secret keys, session keys and signatures Detect extra bytes in secret key material, as well as missing bytes in other parameters. --- src/config/config.js | 7 ++++++- src/crypto/crypto.js | 8 ++++---- src/crypto/signature.js | 16 ++++++++-------- src/packet/secret_key.js | 5 ++++- src/packet/signature.js | 7 ++++++- src/type/ecdh_x_symkey.js | 2 +- src/util.js | 21 ++++++++++++++++++++- test/general/key.js | 23 +++++++++++++++++++++++ 8 files changed, 72 insertions(+), 17 deletions(-) diff --git a/src/config/config.js b/src/config/config.js index 3f93e720..e448cbda 100644 --- a/src/config/config.js +++ b/src/config/config.js @@ -128,7 +128,12 @@ export default { * process large streams while limiting memory usage by releasing the decrypted chunks as soon as possible * and deferring checking their integrity until the decrypted stream has been read in full. * - * This setting is **insecure** if the partially decrypted message is processed further or displayed to the user. + * This setting is **insecure** if the encrypted data has been corrupted by a malicious entity: + * - if the partially decrypted message is processed further or displayed to the user, it opens up the possibility of attacks such as EFAIL + * (see https://efail.de/). + * - an attacker with access to traces or timing info of internal processing errors could learn some info about the data. + * + * NB: this setting does not apply to AEAD-encrypted data, where the AEAD data chunk is never released until integrity is confirmed. * @memberof module:config * @property {Boolean} allowUnauthenticatedStream */ diff --git a/src/crypto/crypto.js b/src/crypto/crypto.js index a9293e75..2576bd88 100644 --- a/src/crypto/crypto.js +++ b/src/crypto/crypto.js @@ -186,7 +186,7 @@ export function parsePublicKeyParams(algo, bytes) { case enums.publicKey.ed448: case enums.publicKey.x25519: case enums.publicKey.x448: { - const A = bytes.subarray(read, read + getCurvePayloadSize(algo)); read += A.length; + const A = util.readExactSubarray(bytes, read, read + getCurvePayloadSize(algo)); read += A.length; return { read, publicParams: { A } }; } default: @@ -234,13 +234,13 @@ export function parsePrivateKeyParams(algo, bytes, publicParams) { case enums.publicKey.ed25519: case enums.publicKey.ed448: { const payloadSize = getCurvePayloadSize(algo); - const seed = bytes.subarray(read, read + payloadSize); read += seed.length; + const seed = util.readExactSubarray(bytes, read, read + payloadSize); read += seed.length; return { read, privateParams: { seed } }; } case enums.publicKey.x25519: case enums.publicKey.x448: { const payloadSize = getCurvePayloadSize(algo); - const k = bytes.subarray(read, read + payloadSize); read += k.length; + const k = util.readExactSubarray(bytes, read, read + payloadSize); read += k.length; return { read, privateParams: { k } }; } default: @@ -288,7 +288,7 @@ export function parseEncSessionKeyParams(algo, bytes) { case enums.publicKey.x25519: case enums.publicKey.x448: { const pointSize = getCurvePayloadSize(algo); - const ephemeralPublicKey = bytes.subarray(read, read + pointSize); read += ephemeralPublicKey.length; + const ephemeralPublicKey = util.readExactSubarray(bytes, read, read + pointSize); read += ephemeralPublicKey.length; const C = new ECDHXSymmetricKey(); C.read(bytes.subarray(read)); return { ephemeralPublicKey, C }; } diff --git a/src/crypto/signature.js b/src/crypto/signature.js index 5d3db48d..5f0ceeab 100644 --- a/src/crypto/signature.js +++ b/src/crypto/signature.js @@ -27,10 +27,10 @@ export function parseSignatureParams(algo, signature) { case enums.publicKey.rsaEncryptSign: case enums.publicKey.rsaEncrypt: case enums.publicKey.rsaSign: { - const s = util.readMPI(signature.subarray(read)); + const s = util.readMPI(signature.subarray(read)); read += s.length + 2; // The signature needs to be the same length as the public key modulo n. // We pad s on signature verification, where we have access to n. - return { s }; + return { read, signatureParams: { s } }; } // Algorithm-Specific Fields for DSA or ECDSA signatures: // - MPI of DSA or ECDSA value r. @@ -39,8 +39,8 @@ export function parseSignatureParams(algo, signature) { case enums.publicKey.ecdsa: { const r = util.readMPI(signature.subarray(read)); read += r.length + 2; - const s = util.readMPI(signature.subarray(read)); - return { r, s }; + const s = util.readMPI(signature.subarray(read)); read += s.length + 2; + return { read, signatureParams: { r, s } }; } // Algorithm-Specific Fields for legacy EdDSA signatures: // - MPI of an EC point r. @@ -50,9 +50,9 @@ export function parseSignatureParams(algo, signature) { // https://www.ietf.org/archive/id/draft-ietf-openpgp-rfc4880bis-10.html#section-3.2-9 let r = util.readMPI(signature.subarray(read)); read += r.length + 2; r = util.leftPad(r, 32); - let s = util.readMPI(signature.subarray(read)); + let s = util.readMPI(signature.subarray(read)); read += s.length + 2; s = util.leftPad(s, 32); - return { r, s }; + return { read, signatureParams: { r, s } }; } // Algorithm-Specific Fields for Ed25519 signatures: // - 64 octets of the native signature @@ -61,8 +61,8 @@ export function parseSignatureParams(algo, signature) { case enums.publicKey.ed25519: case enums.publicKey.ed448: { const rsSize = 2 * publicKey.elliptic.eddsa.getPayloadSize(algo); - const RS = signature.subarray(read, read + rsSize); read += RS.length; - return { RS }; + const RS = util.readExactSubarray(signature, read, read + rsSize); read += RS.length; + return { read, signatureParams: { RS } }; } default: diff --git a/src/packet/secret_key.js b/src/packet/secret_key.js index dc5b853d..6dbb3b72 100644 --- a/src/packet/secret_key.js +++ b/src/packet/secret_key.js @@ -195,7 +195,10 @@ class SecretKeyPacket extends PublicKeyPacket { } } try { - const { privateParams } = crypto.parsePrivateKeyParams(this.algorithm, cleartext, this.publicParams); + const { read, privateParams } = crypto.parsePrivateKeyParams(this.algorithm, cleartext, this.publicParams); + if (read < cleartext.length) { + throw new Error('Error reading MPIs'); + } this.privateParams = privateParams; } catch (err) { if (err instanceof UnsupportedError) throw err; diff --git a/src/packet/signature.js b/src/packet/signature.js index a66fbd49..b650ca99 100644 --- a/src/packet/signature.js +++ b/src/packet/signature.js @@ -153,7 +153,12 @@ class SignaturePacket { i += saltLength; } - this.params = crypto.signature.parseSignatureParams(this.publicKeyAlgorithm, bytes.subarray(i, bytes.length)); + const signatureMaterial = bytes.subarray(i, bytes.length); + const { read, signatureParams } = crypto.signature.parseSignatureParams(this.publicKeyAlgorithm, signatureMaterial); + if (read < signatureMaterial.length) { + throw new Error('Error reading MPIs'); + } + this.params = signatureParams; } /** diff --git a/src/type/ecdh_x_symkey.js b/src/type/ecdh_x_symkey.js index ecef5715..2f3ee8c9 100644 --- a/src/type/ecdh_x_symkey.js +++ b/src/type/ecdh_x_symkey.js @@ -27,7 +27,7 @@ class ECDHXSymmetricKey { let followLength = bytes[read++]; this.algorithm = followLength % 2 ? bytes[read++] : null; // session key size is always even followLength -= followLength % 2; - this.wrappedKey = bytes.subarray(read, read + followLength); read += followLength; + this.wrappedKey = util.readExactSubarray(bytes, read, read + followLength); read += followLength; } /** diff --git a/src/util.js b/src/util.js index a1d5c3d2..f0ee7f63 100644 --- a/src/util.js +++ b/src/util.js @@ -89,7 +89,26 @@ const util = { readMPI: function (bytes) { const bits = (bytes[0] << 8) | bytes[1]; const bytelen = (bits + 7) >>> 3; - return bytes.subarray(2, 2 + bytelen); + // There is a decryption oracle risk here by enforcing the MPI length using `readExactSubarray` in the context of SEIPDv1 encrypted signatures, + // where unauthenticated streamed decryption is done (via `config.allowUnauthenticatedStream`), since the decrypted signature data being processed + // has not been authenticated (yet). + // However, such config setting is known to be insecure, and there are other packet parsing errors that can cause similar issues. + // Also, AEAD is also not affected. + return util.readExactSubarray(bytes, 2, 2 + bytelen); + }, + + /** + * Read exactly `end - start` bytes from input. + * This is a stricter version of `.subarray`. + * @param {Uint8Array} input - Input data to parse + * @returns {Uint8Array} subarray of size always equal to `end - start` + * @throws if the input array is too short. + */ + readExactSubarray: function (input, start, end) { + if (input.length < (end - start)) { + throw new Error('Input array too short'); + } + return input.subarray(start, end); }, /** diff --git a/test/general/key.js b/test/general/key.js index 0e5dc5ae..adc11528 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -3257,6 +3257,29 @@ AAAAHh0gf2kdqLoXdFX+aNVORr5VCVgcm2gBw8l68lDJ1ftA71bMllFi6Q5sLPUr expect(encryptionKey.getAlgorithmInfo()).to.deep.equal({ algorithm: 'x448' }); }); + it('Throw when parsing x448 key with unexpected secret param size', async function() { + // x448 subkey with secret seed of 57 bytes instead of 56 + const armoredKey = `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xXsEZRwKeRx0854v253kTyH54UIFSy3dLbMLTSIGh+UeC6IWXvxt2551rUee +wn9y5hJbJwm/f2eA3vkOUqhKbAAAy7hGpOu61AMTr6w9G9VLStDR9Int/vgi +cNSl1LTvF8f5lqBrpMFFPUHwi4igNMqb7I/c7J2Uc+4uInvNAMK3BBAcCgA7 +BYJlHAp5AwsJBwmQ+2DdQup2xx8DFQgKAhYAAhkBApsDAh4BFiEE5NkqBdRy +GYLB7cPm+2DdQup2xx8AAIuONFkN6wRtRJA9EJvwhj7DkzNRjFNw8OE/ENzj +3XcN/WtZYCnLZ+ih9HSar9+CZzI+4mHtvOunq7sAjuvPbGndbbdg46DSy0Ac +wIVxSeIMNpwpktMyUx/ugIZeu7VvcnW4SbQOEB5KPlja/qjapWwg4wIAx3oE +ZRwKeRogjMz3j2jL4X1Zhk+i/EK09BTU/2zuYuB+Pl9Y+RKDaxuOmZ4zzx+S +xa/RYWEVKkcIY9pBAxd4RgDZs0rJP9DRIe69vix1Wd/LxuSctG2SMfcjzyAl +5mmCsb+sgubDduEBotTv3qFnNTYMUUHEFojWC4EfjcKmBBgcCgAqBYJlHAp5 +CZD7YN1C6nbHHwKbDBYhBOTZKgXUchmCwe3D5vtg3ULqdscfAAD/uWh1fZy7 +hMeb7552mWqB0eGXpOJR9K/rLDj8woLkXJMyyhfYU5PTwmRpowsGwbm7TMku +gXxMryvfgBDKTN8tkgJ4BJUsDDwU7aJE1fzOZ5TP4iNHpPOY1qqpmaAtTh6Q +PzIEeL7UH3trraFmi+Gq8u4kAA== +-----END PGP PRIVATE KEY BLOCK-----`; + + await expect(openpgp.readKey({ armoredKey })).to.be.rejectedWith(/Error reading MPIs/); + }); + it('Testing key ID and fingerprint for V4 keys', async function() { const pubKeysV4 = await openpgp.readKeys({ armoredKeys: twoKeys }); expect(pubKeysV4).to.exist; From 24c644207d5d5fba6534010bcb38795568510134 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Thu, 7 Sep 2023 19:34:44 +0200 Subject: [PATCH 066/201] Support generating Curve448 and Curve25519 keys (new format) Neither type is set as default for now, since they are not widely supported. --- openpgp.d.ts | 6 +- src/crypto/public_key/elliptic/eddsa.js | 4 +- src/key/factory.js | 4 +- src/key/helper.js | 8 ++- src/key/private_key.js | 29 ++++++++- src/openpgp.js | 6 +- test/crypto/validate.js | 83 +++++++++++-------------- test/general/key.js | 58 +++++++++++++++++ test/general/openpgp.js | 31 ++------- 9 files changed, 143 insertions(+), 86 deletions(-) diff --git a/openpgp.d.ts b/openpgp.d.ts index d38bd10d..6a2e5418 100644 --- a/openpgp.d.ts +++ b/openpgp.d.ts @@ -816,7 +816,7 @@ export namespace enums { aeadEncryptedData = 20, } - export type publicKeyNames = 'rsaEncryptSign' | 'rsaEncrypt' | 'rsaSign' | 'elgamal' | 'dsa' | 'ecdh' | 'ecdsa' | 'eddsa' | 'aedh' | 'aedsa'; + export type publicKeyNames = 'rsaEncryptSign' | 'rsaEncrypt' | 'rsaSign' | 'elgamal' | 'dsa' | 'ecdh' | 'ecdsa' | 'eddsa' | 'ed25519Legacy' | 'aedh' | 'aedsa' | 'ed25519' | 'x25519' | 'ed448' | 'x448'; enum publicKey { rsaEncryptSign = 1, rsaEncrypt = 2, @@ -830,6 +830,10 @@ export namespace enums { eddsaLegacy = 22, aedh = 23, aedsa = 24, + x25519 = 25, + x448 = 26, + ed25519 = 27, + ed448 = 28 } enum curve { diff --git a/src/crypto/public_key/elliptic/eddsa.js b/src/crypto/public_key/elliptic/eddsa.js index bcab724f..8b08a671 100644 --- a/src/crypto/public_key/elliptic/eddsa.js +++ b/src/crypto/public_key/elliptic/eddsa.js @@ -36,14 +36,14 @@ ed25519.hash = bytes => sha512(bytes); * @returns {Promise<{ A: Uint8Array, seed: Uint8Array }>} */ export async function generate(algo) { - const seed = getRandomBytes(getPayloadSize(algo)); - switch (algo) { case enums.publicKey.ed25519: { + const seed = getRandomBytes(getPayloadSize(algo)); const { publicKey: A } = ed25519.sign.keyPair.fromSeed(seed); return { A, seed }; } case enums.publicKey.ed448: { + const seed = ed448.utils.randomPrivateKey(); const A = ed448.getPublicKey(seed); return { A, seed }; } diff --git a/src/key/factory.js b/src/key/factory.js index 6c1d7ee1..c485b35c 100644 --- a/src/key/factory.js +++ b/src/key/factory.js @@ -64,9 +64,9 @@ function createKey(packetlist) { /** - * Generates a new OpenPGP key. Supports RSA and ECC keys. + * Generates a new OpenPGP key. Supports RSA and ECC keys, as well as the newer Curve448 and Curve25519 keys. * By default, primary and subkeys will be of same type. - * @param {ecc|rsa} options.type The primary key algorithm type: ECC or RSA + * @param {ecc|rsa|curve448|curve25519} options.type The primary key algorithm type: ECC, RSA, Curve448 or Curve25519 (new format). * @param {String} options.curve Elliptic curve for ECC keys * @param {Integer} options.rsaBits Number of bits for RSA keys * @param {Array} options.userIDs User IDs as strings or objects: 'Jo Doe ' or { name:'Jo Doe', email:'info@jo.com' } diff --git a/src/key/helper.js b/src/key/helper.js index e887ed19..a23bbaae 100644 --- a/src/key/helper.js +++ b/src/key/helper.js @@ -326,7 +326,7 @@ export function sanitizeKeyOptions(options, subkeyDefaults = {}) { options.sign = options.sign || false; switch (options.type) { - case 'ecc': + case 'ecc': // NB: this case also handles legacy eddsa and x25519 keys, based on `options.curve` try { options.curve = enums.write(enums.curve, options.curve); } catch (e) { @@ -341,6 +341,12 @@ export function sanitizeKeyOptions(options, subkeyDefaults = {}) { options.algorithm = enums.publicKey.ecdh; } break; + case 'curve25519': + options.algorithm = options.sign ? enums.publicKey.ed25519 : enums.publicKey.x25519; + break; + case 'curve448': + options.algorithm = options.sign ? enums.publicKey.ed448 : enums.publicKey.x448; + break; case 'rsa': options.algorithm = enums.publicKey.rsaEncryptSign; break; diff --git a/src/key/private_key.js b/src/key/private_key.js index 055de008..7b86945b 100644 --- a/src/key/private_key.js +++ b/src/key/private_key.js @@ -198,8 +198,10 @@ class PrivateKey extends PublicKey { /** * Generates a new OpenPGP subkey, and returns a clone of the Key object with the new subkey added. - * Supports RSA and ECC keys. Defaults to the algorithm and bit size/curve of the primary key. DSA primary keys default to RSA subkeys. - * @param {ecc|rsa} options.type The subkey algorithm: ECC or RSA + * Supports RSA and ECC keys, as well as the newer Curve448 and Curve25519. + * Defaults to the algorithm and bit size/curve of the primary key. DSA primary keys default to RSA subkeys. + * @param {ecc|rsa|curve25519|curve448} options.type The subkey algorithm: ECC, RSA, Curve448 or Curve25519 (new format). + * Note: Curve448 and Curve25519 are not widely supported yet. * @param {String} options.curve (optional) Elliptic curve for ECC keys * @param {Integer} options.rsaBits (optional) Number of bits for RSA subkeys * @param {Number} options.keyExpirationTime (optional) Number of seconds from the key creation time after which the key expires @@ -225,7 +227,7 @@ class PrivateKey extends PublicKey { throw new Error('Key is not decrypted'); } const defaultOptions = secretKeyPacket.getAlgorithmInfo(); - defaultOptions.type = defaultOptions.curve ? 'ecc' : 'rsa'; // DSA keys default to RSA + defaultOptions.type = getDefaultSubkeyType(defaultOptions.algorithm); defaultOptions.rsaBits = defaultOptions.bits || 4096; defaultOptions.curve = defaultOptions.curve || 'curve25519'; options = helper.sanitizeKeyOptions(options, defaultOptions); @@ -238,4 +240,25 @@ class PrivateKey extends PublicKey { } } +function getDefaultSubkeyType(algoName) { + const algo = enums.write(enums.publicKey, algoName); + // NB: no encryption-only algos, since they cannot be in primary keys + switch (algo) { + case enums.publicKey.rsaEncrypt: + case enums.publicKey.rsaEncryptSign: + case enums.publicKey.rsaSign: + case enums.publicKey.dsa: + return 'rsa'; + case enums.publicKey.ecdsa: + case enums.publicKey.eddsaLegacy: + return 'ecc'; + case enums.publicKey.ed25519: + return 'curve25519'; + case enums.publicKey.ed448: + return 'curve448'; + default: + throw new Error('Unsupported algorithm'); + } +} + export default PrivateKey; diff --git a/src/openpgp.js b/src/openpgp.js index 70dfd240..7fad9aaa 100644 --- a/src/openpgp.js +++ b/src/openpgp.js @@ -32,11 +32,13 @@ import { checkKeyRequirements } from './key/helper'; /** - * Generates a new OpenPGP key pair. Supports RSA and ECC keys. By default, primary and subkeys will be of same type. + * Generates a new OpenPGP key pair. Supports RSA and ECC keys, as well as the newer Curve448 and Curve25519 keys. + * By default, primary and subkeys will be of same type. * The generated primary key will have signing capabilities. By default, one subkey with encryption capabilities is also generated. * @param {Object} options * @param {Object|Array} options.userIDs - User IDs as objects: `{ name: 'Jo Doe', email: 'info@jo.com' }` - * @param {'ecc'|'rsa'} [options.type='ecc'] - The primary key algorithm type: ECC (default) or RSA + * @param {'ecc'|'rsa'|'curve448'|'curve25519'} [options.type='ecc'] - The primary key algorithm type: ECC (default), RSA, Curve448 or Curve25519 (new format). + * Note: Curve448 and Curve25519 (new format) are not widely supported yet. * @param {String} [options.passphrase=(not protected)] - The passphrase used to encrypt the generated private key. If omitted or empty, the key won't be encrypted. * @param {Number} [options.rsaBits=4096] - Number of bits for RSA keys * @param {String} [options.curve='curve25519'] - Elliptic curve for ECC keys: diff --git a/test/crypto/validate.js b/test/crypto/validate.js index 3388f26b..9b9b883e 100644 --- a/test/crypto/validate.js +++ b/test/crypto/validate.js @@ -193,13 +193,13 @@ export default () => { }); }); - const curves = ['curve25519', 'p256', 'p384', 'p521', 'secp256k1', 'brainpoolP256r1', 'brainpoolP384r1', 'brainpoolP512r1']; + const curves = ['curve25519Legacy', 'p256', 'p384', 'p521', 'secp256k1', 'brainpoolP256r1', 'brainpoolP384r1', 'brainpoolP512r1']; curves.forEach(curve => { describe(`ECC ${curve} parameter validation`, () => { let ecdsaKey; let ecdhKey; before(async () => { - if (curve !== 'curve25519') { + if (curve !== 'curve25519Legacy') { ecdsaKey = await generatePrivateKeyObject({ curve }); ecdhKey = ecdsaKey.subkeys[0]; } else { @@ -247,58 +247,45 @@ export default () => { }); }); - describe('Ed448/X448 parameter validation', function() { - let eddsaKey; - let ecdhXKey; - before(async () => { - eddsaKey = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- + // new EdDSA/XECDH algos + ['25519', '448'].forEach(curveID => { + describe(`Ed${curveID}/X${curveID} parameter validation`, function() { + let eddsaKey; + let ecdhXKey; + before(async () => { + eddsaKey = await generatePrivateKeyObject({ type: `curve${curveID}` }); + ecdhXKey = eddsaKey.subkeys[0]; + }); -xXsEZCWHXBwwtqciq6ZFU13s+dyhkWR5tOEmF1oX8OiP1B5ypfqyGVM8DkQh -5eTIMwB1oqJCROANoyA0q2dSigAAbDA5xr74DeClPPXC4ZXJ9uzuJWKvQvE8 -x3EflhgoQCGBM7JfvH5zwdrJvPt8RKDvm0QkZzhPvnFoHnzNBHRlc3TCugQQ -HAgAPgWCZCWHXAQLCQcICZDsN6h/ys3ppwMVCAoEFgACAQIZAQKbAwIeARYh -BOJyE9P2eIcU2N2Ne+w3qH/KzemnAAAh1hTFCcEU77bU3YelrJTCNIOQnvt7 -Hs6yZz2053CQTOC+wHkUQLaYYBEXSNyLZxoyv+NuGTiwbuYtAOlbE2erM7Cx -8B2Qz7M29UkFLMBUfb+yi+gTYYUWCXVQ7Um7MGjjgUG8+9p452i6f28mhRD8 -tTgNAMd5BGQlh1wavTIFgILtbzrqQCiwDGx0YcFNzu9+FZ8vK5Mmm7UEZj0a -y7FWQtZw8tTaU6mY+RrSa52RjzkGLtQAQO++tgYqc+BnCFdCZ3ZYPRvD3mof -ffoo3l4xmto+iyvJZbQ4wQPXttg7VjCpEfOsL9TW9Xs09aIbysKmBBgcCAAq -BYJkJYdcCZDsN6h/ys3ppwKbDBYhBOJyE9P2eIcU2N2Ne+w3qH/KzemnAAC0 -6/eZhh/Oj2gRdab2JeFGWACGIRDKxPXsWRCXR4YrSxcvCKK6rOvsyxQsgIsJ -JyPYkRPfmbKcseUDAEkSBLAfeizDGh7ea0GOdIMhwE/CW4f/H8ULbwi36y13 -x3oMNVaYsI9dZ588Gpi8XYy2jOtqIPQ1AA== ------END PGP PRIVATE KEY BLOCK-----` }); - ecdhXKey = eddsaKey.subkeys[0]; - }); + it(`Ed${curveID} params should be valid`, async function() { + await expect(eddsaKey.keyPacket.validate()).to.not.be.rejected; + }); - it('Ed448 params should be valid', async function() { - await expect(eddsaKey.keyPacket.validate()).to.not.be.rejected; - }); + it(`detect invalid Ed${curveID} public point`, async function() { + const eddsaKeyPacket = await cloneKeyPacket(eddsaKey); + const A = eddsaKeyPacket.publicParams.A; + A[0]++; + await expect(eddsaKeyPacket.validate()).to.be.rejectedWith('Key is invalid'); - it('detect invalid Ed448 public point', async function() { - const eddsaKeyPacket = await cloneKeyPacket(eddsaKey); - const A = eddsaKeyPacket.publicParams.A; - A[0]++; - await expect(eddsaKeyPacket.validate()).to.be.rejectedWith('Key is invalid'); + const infA = new Uint8Array(A.length); + eddsaKeyPacket.publicParams.A = infA; + await expect(eddsaKeyPacket.validate()).to.be.rejectedWith('Key is invalid'); + }); - const infA = new Uint8Array(A.length); - eddsaKeyPacket.publicParams.A = infA; - await expect(eddsaKeyPacket.validate()).to.be.rejectedWith('Key is invalid'); - }); + it(`X${curveID} params should be valid`, async function() { + await expect(ecdhXKey.keyPacket.validate()).to.not.be.rejected; + }); - it('X448 params should be valid', async function() { - await expect(ecdhXKey.keyPacket.validate()).to.not.be.rejected; - }); + it(`detect invalid X${curveID} public point`, async function() { + const ecdhXKeyPacket = await cloneKeyPacket(ecdhXKey); + const A = ecdhXKeyPacket.publicParams.A; + A[0]++; + await expect(ecdhXKeyPacket.validate()).to.be.rejectedWith('Key is invalid'); - it('detect invalid x448 public point', async function() { - const ecdhXKeyPacket = await cloneKeyPacket(ecdhXKey); - const A = ecdhXKeyPacket.publicParams.A; - A[0]++; - await expect(ecdhXKeyPacket.validate()).to.be.rejectedWith('Key is invalid'); - - const infA = new Uint8Array(A.length); - ecdhXKeyPacket.publicParams.A = infA; - await expect(ecdhXKeyPacket.validate()).to.be.rejectedWith('Key is invalid'); + const infA = new Uint8Array(A.length); + ecdhXKeyPacket.publicParams.A = infA; + await expect(ecdhXKeyPacket.validate()).to.be.rejectedWith('Key is invalid'); + }); }); }); diff --git a/test/general/key.js b/test/general/key.js index adc11528..3fedd73f 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -2509,6 +2509,54 @@ function versionSpecificTests() { } }); + it('Generate Ed25519 key (new format) - default subkey', async function() { + const userID = { name: 'test', email: 'a@b.com' }; + const opt = { type: 'curve25519', userIDs: [userID], passphrase: '123', format: 'object' }; + const { privateKey: key } = await openpgp.generateKey(opt); + expect(key.users.length).to.equal(1); + expect(key.users[0].userID.userID).to.equal('test '); + expect(key.users[0].selfCertifications[0].isPrimaryUserID).to.be.true; + expect(key.getAlgorithmInfo().algorithm).to.equal('ed25519'); + expect(key.subkeys).to.have.length(1); + expect(key.subkeys[0].getAlgorithmInfo().algorithm).to.equal('x25519'); + }); + + it('Generate Ed25519 key (new format) - one signing subkey', async function() { + const userID = { name: 'test', email: 'a@b.com' }; + const opt = { type: 'curve25519', userIDs: [userID], passphrase: '123', format: 'object', subkeys:[{ sign: true }] }; + const { privateKey: key } = await openpgp.generateKey(opt); + expect(key.users.length).to.equal(1); + expect(key.users[0].userID.userID).to.equal('test '); + expect(key.users[0].selfCertifications[0].isPrimaryUserID).to.be.true; + expect(key.getAlgorithmInfo().algorithm).to.equal('ed25519'); + expect(key.subkeys).to.have.length(1); + expect(key.subkeys[0].getAlgorithmInfo().algorithm).to.equal('ed25519'); + }); + + it('Generate Ed448 key - default subkey', async function() { + const userID = { name: 'test', email: 'a@b.com' }; + const opt = { type: 'curve448', userIDs: [userID], passphrase: '123', format: 'object' }; + const { privateKey: key } = await openpgp.generateKey(opt); + expect(key.users.length).to.equal(1); + expect(key.users[0].userID.userID).to.equal('test '); + expect(key.users[0].selfCertifications[0].isPrimaryUserID).to.be.true; + expect(key.getAlgorithmInfo().algorithm).to.equal('ed448'); + expect(key.subkeys).to.have.length(1); + expect(key.subkeys[0].getAlgorithmInfo().algorithm).to.equal('x448'); + }); + + it('Generate Ed448 key - one signing subkey', async function() { + const userID = { name: 'test', email: 'a@b.com' }; + const opt = { type: 'curve448', userIDs: [userID], passphrase: '123', format: 'object', subkeys:[{ sign: true }] }; + const { privateKey: key } = await openpgp.generateKey(opt); + expect(key.users.length).to.equal(1); + expect(key.users[0].userID.userID).to.equal('test '); + expect(key.users[0].selfCertifications[0].isPrimaryUserID).to.be.true; + expect(key.getAlgorithmInfo().algorithm).to.equal('ed448'); + expect(key.subkeys).to.have.length(1); + expect(key.subkeys[0].getAlgorithmInfo().algorithm).to.equal('ed448'); + }); + it('Generate key - one signing subkey', function() { const userID = { name: 'test', email: 'a@b.com' }; const opt = { userIDs: [userID], passphrase: '123', format: 'object', subkeys:[{}, { sign: true }] }; @@ -4196,6 +4244,16 @@ VYGdb3eNlV8CfoEC expect(newKey.subkeys[0].getAlgorithmInfo().curve).to.equal('curve25519'); }); + it('Add a new default subkey to an Ed488 key', async function() { + const userID = { name: 'test', email: 'a@b.com' }; + const opt = { type: 'curve448', userIDs: [userID], format: 'object', subkeys: [] }; + const { privateKey: key } = await openpgp.generateKey(opt); + expect(key.subkeys).to.have.length(0); + const newKey = await key.addSubkey(); + expect(newKey.subkeys[0].getAlgorithmInfo().algorithm).to.equal('x448'); + expect(newKey.subkeys[0].getAlgorithmInfo().curve).to.be.undefined; + }); + it('Add a new default subkey to a dsa key', async function() { const key = await openpgp.readKey({ armoredKey: dsaPrivateKey }); const total = key.subkeys.length; diff --git a/test/general/openpgp.js b/test/general/openpgp.js index e2ff3128..e97a21f5 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -4758,17 +4758,8 @@ sEj+v9LKoMTYZGMfp3qDVFLtkBE88eVmVjgJOoLhrsv7yh0PAA== }); it('sign/verify with new Ed25519 format', async function () { - // v4 key, which we do not support generating - const privateKey = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- - -xUkEZBw5PBscroGar9fsilA0q9AX979pBhTNkGQ69vQGGW7kxRxNuABB+eAw -JrQ9A3o1gUJg28ORTQd72+kFo87184qR97a6rRGFzQR0ZXN0wogEEBsIAD4F -gmQcOTwECwkHCAmQT/m+Rl22Ps8DFQgKBBYAAgECGQECmwMCHgEWIQSUlOfm -G7MWJd2909ZP+b5GXbY+zwAAVs/4pWH4l7pWcTATBavVqSATMKi4A+usp89G -J/qaHc+qmcEpIMmPNvLQ7n4F4kEXk8Zwz+OXovVWLQ+Njl5gzooF -=wYg1 ------END PGP PRIVATE KEY BLOCK----- - ` }); + const userIDs = { name: 'Alice', email: 'info@alice.com' }; + const { privateKey } = await openpgp.generateKey({ type: 'curve25519', userIDs, format: 'object' }); const plaintext = 'plaintext'; const signed = await openpgp.sign({ @@ -4786,22 +4777,8 @@ J/qaHc+qmcEpIMmPNvLQ7n4F4kEXk8Zwz+OXovVWLQ+Njl5gzooF }); it('sign/verify with Ed448', async function () { - const privateKey = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- - -xX0GZRqLYhwAAAA5U/IaIOge/FoLzCetXKx029bdJHCz2hMFBRMuzq4msjaT -+hLeV6puyC/PeSEfaanqTuo31vvsti2AAIttr4GDGXF4vfPzbzkWV9dT4VVs -IU7QqLv1hzwZ+k7pHroRyXnUiYxRYHuzlg7Vw4CrAtN/8T65OMLAHgYfHAoA -AAA9BQJlGotiIqEGAxidsHRHDsyFTw1Q7OoGEAEnRnxthKMwVBqhIL2o+HUC -GwMCHgkCCwcDFQoIAhYAAycHAgAAAAA2KiC+Y+fhQ/48CkT9WrXTX9SCn3vH -z43Wb++AkmpWL1HQmrJE3S4gGltezZK2E9ovagzxKxVrL14uC6hs6kJ0JIiW -QSeMeexCTy+Gdr6j0wb4FhFNnoIu3yu2ABmZpFX/5/191YeWUryKFDAoUZmK -gQTSOzJEvyO0ACR5L4vV3ADceOAdG8/sqhE89rTSevFXng4JAM0XVXNlckEg -PFVzZXJBQHRlc3QudGVzdD7CwA0GExwKAAAALAUCZRqLYiKhBgMYnbB0Rw7M -hU8NUOzqBhABJ0Z8bYSjMFQaoSC9qPh1AhkBAAAAAFw/IH72M1iyzMWhbgtw -v0SR/XxvOIW/ZrT4Ix9236lvoOE4taL/D46CbZOjm7VAeOSfSdxt1xSKnoAL -RsCNQ8tVPjPXclzqr6R8MbPIgBWxKcMS2eStYpBbG5qAmc+K5jdA2xcl9iW5 -bWleZ1LTah4lF6qCiD73IffADXtzw8iAMTX+0wM5N1tJUEGvgqe00ohRKiQA ------END PGP PRIVATE KEY BLOCK-----` }); + const userIDs = { name: 'Alice', email: 'info@alice.com' }; + const { privateKey } = await openpgp.generateKey({ type: 'curve448', userIDs, format: 'object' }); const plaintext = 'plaintext'; const signed = await openpgp.sign({ From 0b7a5f69fafaca5f4aa3d95c2c4ea337f20ca1d5 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Thu, 7 Sep 2023 19:36:42 +0200 Subject: [PATCH 067/201] Drop `enums.publicKey.eddsa` in favour of `enums.publicKey.eddsaLegacy` The crypto-refresh has standardised a new key format for EdDSA, whose algorithm identifier are `enums.publicKey.ed25519` and `.ed448` --- openpgp.d.ts | 4 +--- src/enums.js | 6 +----- test/general/config.js | 8 ++++---- test/general/key.js | 12 ++++++------ test/general/x25519.js | 4 ++-- 5 files changed, 14 insertions(+), 20 deletions(-) diff --git a/openpgp.d.ts b/openpgp.d.ts index 6a2e5418..529fdb61 100644 --- a/openpgp.d.ts +++ b/openpgp.d.ts @@ -816,7 +816,7 @@ export namespace enums { aeadEncryptedData = 20, } - export type publicKeyNames = 'rsaEncryptSign' | 'rsaEncrypt' | 'rsaSign' | 'elgamal' | 'dsa' | 'ecdh' | 'ecdsa' | 'eddsa' | 'ed25519Legacy' | 'aedh' | 'aedsa' | 'ed25519' | 'x25519' | 'ed448' | 'x448'; + export type publicKeyNames = 'rsaEncryptSign' | 'rsaEncrypt' | 'rsaSign' | 'elgamal' | 'dsa' | 'ecdh' | 'ecdsa' | 'eddsaLegacy' | 'aedh' | 'aedsa' | 'ed25519' | 'x25519' | 'ed448' | 'x448'; enum publicKey { rsaEncryptSign = 1, rsaEncrypt = 2, @@ -825,8 +825,6 @@ export namespace enums { dsa = 17, ecdh = 18, ecdsa = 19, - /** @deprecated use `eddsaLegacy` instead */ - eddsa = 22, eddsaLegacy = 22, aedh = 23, aedsa = 24, diff --git a/src/enums.js b/src/enums.js index 5dbbffcc..61fe1b37 100644 --- a/src/enums.js +++ b/src/enums.js @@ -116,11 +116,7 @@ export default { ecdsa: 19, /** EdDSA (Sign only) - deprecated by crypto-refresh (replaced by `ed25519` identifier below) * [{@link https://tools.ietf.org/html/draft-koch-eddsa-for-openpgp-04|Draft RFC}] */ - eddsaLegacy: 22, // NB: this is declared before `eddsa` to translate 22 to 'eddsa' for backwards compatibility - /** @deprecated use `eddsaLegacy` instead */ - ed25519Legacy: 22, - /** @deprecated use `eddsaLegacy` instead */ - eddsa: 22, + eddsaLegacy: 22, /** Reserved for AEDH */ aedh: 23, /** Reserved for AEDSA */ diff --git a/test/general/config.js b/test/general/config.js index 66032a91..3da4c40a 100644 --- a/test/general/config.js +++ b/test/general/config.js @@ -369,10 +369,10 @@ n9/quqtmyOtYOA6gXNCw0Fal3iANKBmsPmYI await expect(openpgp.sign({ message, signingKeys: [key], config: { rejectPublicKeyAlgorithms: new Set([openpgp.enums.publicKey.eddsaLegacy]) } - })).to.be.eventually.rejectedWith(/eddsa keys are considered too weak/); + })).to.be.eventually.rejectedWith(/eddsaLegacy keys are considered too weak/); await expect(openpgp.sign({ message, signingKeys: [key], config: { rejectCurves: new Set([openpgp.enums.curve.ed25519Legacy]) } - })).to.be.eventually.rejectedWith(/Support for eddsa keys using curve ed25519 is disabled/); + })).to.be.eventually.rejectedWith(/Support for eddsaLegacy keys using curve ed25519 is disabled/); }); it('openpgp.verify', async function() { @@ -416,7 +416,7 @@ n9/quqtmyOtYOA6gXNCw0Fal3iANKBmsPmYI config: { rejectPublicKeyAlgorithms: new Set([openpgp.enums.publicKey.eddsaLegacy]) } }; const { signatures: [sig4] } = await openpgp.verify(opt4); - await expect(sig4.verified).to.be.rejectedWith(/eddsa keys are considered too weak/); + await expect(sig4.verified).to.be.rejectedWith(/eddsaLegacy keys are considered too weak/); const opt5 = { message: await openpgp.readMessage({ armoredMessage: signed }), @@ -424,7 +424,7 @@ n9/quqtmyOtYOA6gXNCw0Fal3iANKBmsPmYI config: { rejectCurves: new Set([openpgp.enums.curve.ed25519Legacy]) } }; const { signatures: [sig5] } = await openpgp.verify(opt5); - await expect(sig5.verified).to.be.eventually.rejectedWith(/Support for eddsa keys using curve ed25519 is disabled/); + await expect(sig5.verified).to.be.eventually.rejectedWith(/Support for eddsaLegacy keys using curve ed25519 is disabled/); }); describe('detects unknown config property', async function() { diff --git a/test/general/key.js b/test/general/key.js index 3fedd73f..4eb8eda1 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -2467,7 +2467,7 @@ function versionSpecificTests() { const opt = { userIDs: [userID], format: 'object' }; return openpgp.generateKey(opt).then(function({ privateKey: key }) { expect(key.isDecrypted()).to.be.true; - expect(key.getAlgorithmInfo().algorithm).to.equal('eddsa'); + expect(key.getAlgorithmInfo().algorithm).to.equal('eddsaLegacy'); expect(key.users.length).to.equal(1); expect(key.users[0].userID.userID).to.equal('test '); expect(key.users[0].selfCertifications[0].isPrimaryUserID).to.be.true; @@ -2567,7 +2567,7 @@ function versionSpecificTests() { expect(key.subkeys).to.have.length(2); expect(key.subkeys[0].getAlgorithmInfo().algorithm).to.equal('ecdh'); expect(await key.getEncryptionKey()).to.equal(key.subkeys[0]); - expect(key.subkeys[1].getAlgorithmInfo().algorithm).to.equal('eddsa'); + expect(key.subkeys[1].getAlgorithmInfo().algorithm).to.equal('eddsaLegacy'); expect(await key.getSigningKey()).to.equal(key.subkeys[1]); }); }); @@ -2585,7 +2585,7 @@ function versionSpecificTests() { expect(key.subkeys).to.have.length(2); expect(key.subkeys[0].getAlgorithmInfo().algorithm).to.equal('ecdh'); expect(await key.getEncryptionKey()).to.equal(key.subkeys[0]); - expect(key.subkeys[1].getAlgorithmInfo().algorithm).to.equal('eddsa'); + expect(key.subkeys[1].getAlgorithmInfo().algorithm).to.equal('eddsaLegacy'); expect(await key.getSigningKey()).to.equal(key.subkeys[1]); }); }); @@ -4344,7 +4344,7 @@ XvmoLueOOShu01X/kaylMqaT8w== const subkeyOid = subkey2.keyPacket.publicParams.oid; const pkOid = privateKey.keyPacket.publicParams.oid; expect(subkeyOid.getName()).to.be.equal(pkOid.getName()); - expect(subkey2.getAlgorithmInfo().algorithm).to.be.equal('eddsa'); + expect(subkey2.getAlgorithmInfo().algorithm).to.be.equal('eddsaLegacy'); await subkey2.verify(); }); @@ -4359,7 +4359,7 @@ XvmoLueOOShu01X/kaylMqaT8w== expect(newPrivateKey.subkeys.length).to.be.equal(total + 1); expect(newPrivateKey.getAlgorithmInfo().curve).to.be.equal('ed25519'); expect(subkey.getAlgorithmInfo().curve).to.be.equal('p256'); - expect(newPrivateKey.getAlgorithmInfo().algorithm).to.be.equal('eddsa'); + expect(newPrivateKey.getAlgorithmInfo().algorithm).to.be.equal('eddsaLegacy'); expect(subkey.getAlgorithmInfo().algorithm).to.be.equal('ecdsa'); await subkey.verify(); @@ -4427,7 +4427,7 @@ XvmoLueOOShu01X/kaylMqaT8w== const subkeyOid = subkey.keyPacket.publicParams.oid; const pkOid = newPrivateKey.keyPacket.publicParams.oid; expect(subkeyOid.getName()).to.be.equal(pkOid.getName()); - expect(subkey.getAlgorithmInfo().algorithm).to.be.equal('eddsa'); + expect(subkey.getAlgorithmInfo().algorithm).to.be.equal('eddsaLegacy'); await subkey.verify(); expect(await newPrivateKey.getSigningKey()).to.be.equal(subkey); const signed = await openpgp.sign({ message: await openpgp.createMessage({ text: 'the data to signed' }), signingKeys: newPrivateKey, format: 'binary' }); diff --git a/test/general/x25519.js b/test/general/x25519.js index 52bd19c2..f197c595 100644 --- a/test/general/x25519.js +++ b/test/general/x25519.js @@ -396,7 +396,7 @@ function omnibus() { const primaryKey = hi.keyPacket; const subkey = hi.subkeys[0]; expect(hi.getAlgorithmInfo().curve).to.equal('ed25519'); - expect(hi.getAlgorithmInfo().algorithm).to.equal('eddsa'); + expect(hi.getAlgorithmInfo().algorithm).to.equal('eddsaLegacy'); expect(subkey.getAlgorithmInfo().curve).to.equal('curve25519'); expect(subkey.getAlgorithmInfo().algorithm).to.equal('ecdh'); @@ -416,7 +416,7 @@ function omnibus() { return openpgp.generateKey(options).then(async function({ privateKey: bye }) { expect(bye.getAlgorithmInfo().curve).to.equal('ed25519'); - expect(bye.getAlgorithmInfo().algorithm).to.equal('eddsa'); + expect(bye.getAlgorithmInfo().algorithm).to.equal('eddsaLegacy'); expect(bye.subkeys[0].getAlgorithmInfo().curve).to.equal('curve25519'); expect(bye.subkeys[0].getAlgorithmInfo().algorithm).to.equal('ecdh'); From 360a44f57babdd08762abd22d89e6f6488d38f63 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Tue, 26 Sep 2023 19:23:30 +0200 Subject: [PATCH 068/201] `addSubkey`: match primary key version As required by the spec. --- src/key/private_key.js | 6 +++++- test/general/key.js | 41 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/key/private_key.js b/src/key/private_key.js index 7b86945b..b6533676 100644 --- a/src/key/private_key.js +++ b/src/key/private_key.js @@ -231,7 +231,11 @@ class PrivateKey extends PublicKey { defaultOptions.rsaBits = defaultOptions.bits || 4096; defaultOptions.curve = defaultOptions.curve || 'curve25519'; options = helper.sanitizeKeyOptions(options, defaultOptions); - const keyPacket = await helper.generateSecretSubkey(options); + // Every subkey for a v4 primary key MUST be a v4 subkey. + // Every subkey for a v6 primary key MUST be a v6 subkey. + // For v5 keys, since we dropped generation support, a v4 subkey is added. + // The config is always overwritten since we cannot tell if the defaultConfig was changed by the user. + const keyPacket = await helper.generateSecretSubkey(options, { ...config, v6Keys: this.keyPacket.version === 6 }); helper.checkKeyRequirements(keyPacket, config); const bindingSignature = await helper.createBindingSignature(keyPacket, secretKeyPacket, options, config); const packetList = this.toPacketList(); diff --git a/test/general/key.js b/test/general/key.js index 4eb8eda1..2238b510 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -4249,8 +4249,20 @@ VYGdb3eNlV8CfoEC const opt = { type: 'curve448', userIDs: [userID], format: 'object', subkeys: [] }; const { privateKey: key } = await openpgp.generateKey(opt); expect(key.subkeys).to.have.length(0); + const keyWithNewSubkey = await key.addSubkey(); + const parsedNewKey = await openpgp.readKey({ armoredKey: keyWithNewSubkey.armor() }); + expect(parsedNewKey.subkeys[0].getAlgorithmInfo().algorithm).to.equal('x448'); + expect(parsedNewKey.subkeys[0].getAlgorithmInfo().curve).to.be.undefined; + }); + + it('Add a new default subkey to a v6 key', async function() { + const userID = { name: 'test', email: 'a@b.com' }; + const opt = { type: 'curve25519', userIDs: [userID], format: 'object', subkeys: [], config: { v6Keys: true } }; + const { privateKey: key } = await openpgp.generateKey(opt); + expect(key.subkeys).to.have.length(0); const newKey = await key.addSubkey(); - expect(newKey.subkeys[0].getAlgorithmInfo().algorithm).to.equal('x448'); + expect(newKey.subkeys[0].keyPacket.version).to.equal(6); + expect(newKey.subkeys[0].getAlgorithmInfo().algorithm).to.equal('x25519'); expect(newKey.subkeys[0].getAlgorithmInfo().curve).to.be.undefined; }); @@ -4464,6 +4476,33 @@ XvmoLueOOShu01X/kaylMqaT8w== expect(decrypted.data).to.be.equal(vData); }); + ['curve25519', 'curve448'].forEach(keyType => ( + it(`encrypt/decrypt data with the new subkey correctly using ${keyType}`, async function() { + const userID = { name: 'test', email: 'a@b.com' }; + const vData = 'the data to encrypted!'; + const opt = { type: keyType, userIDs: [userID], format: 'object', subkeys:[] }; + const { privateKey } = await openpgp.generateKey(opt); + const total = privateKey.subkeys.length; + let newPrivateKey = await privateKey.addSubkey(); + const armoredKey = newPrivateKey.armor(); + newPrivateKey = await openpgp.readKey({ armoredKey: armoredKey }); + const subkey = newPrivateKey.subkeys[total]; + const publicKey = newPrivateKey.toPublic(); + await subkey.verify(); + expect(await newPrivateKey.getEncryptionKey()).to.be.equal(subkey); + const encrypted = await openpgp.encrypt({ message: await openpgp.createMessage({ text: vData }), encryptionKeys: publicKey, format: 'binary' }); + expect(encrypted).to.be.exist; + const message = await openpgp.readMessage({ binaryMessage: encrypted }); + const pkSessionKeys = message.packets.filterByTag(openpgp.enums.packet.publicKeyEncryptedSessionKey); + expect(pkSessionKeys).to.exist; + expect(pkSessionKeys.length).to.be.equal(1); + expect(pkSessionKeys[0].publicKeyID.toHex()).to.be.equals(subkey.keyPacket.getKeyID().toHex()); + const decrypted = await openpgp.decrypt({ message, decryptionKeys: newPrivateKey }); + expect(decrypted).to.exist; + expect(decrypted.data).to.be.equal(vData); + }) + )); + it('sign/verify data with the new subkey correctly using rsa', async function() { const privateKey = await openpgp.decryptKey({ privateKey: await openpgp.readKey({ armoredKey: priv_key_rsa }), From 7c2248151da0d31b1bbd8f06b50708cd8b947327 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Tue, 26 Sep 2023 15:36:14 +0200 Subject: [PATCH 069/201] Default to generating new curve25519 format for v6 keys As per the spec, v6 keys must not use the legacy curve25519 format. The new format is not used by default with v4 keys as it's not compatible with OpenPGP.js older than v5.10.0 . However, v6 keys already break compatibility, so if the user requests them via config flag, we can safely use the new curve format as well. --- src/openpgp.js | 11 +++++++++-- test/general/key.js | 29 ++++++++++++++++++++--------- test/general/openpgp.js | 34 +++++++++++++++++++++++++++++++++- 3 files changed, 62 insertions(+), 12 deletions(-) diff --git a/src/openpgp.js b/src/openpgp.js index 7fad9aaa..13c93d58 100644 --- a/src/openpgp.js +++ b/src/openpgp.js @@ -37,7 +37,7 @@ import { checkKeyRequirements } from './key/helper'; * The generated primary key will have signing capabilities. By default, one subkey with encryption capabilities is also generated. * @param {Object} options * @param {Object|Array} options.userIDs - User IDs as objects: `{ name: 'Jo Doe', email: 'info@jo.com' }` - * @param {'ecc'|'rsa'|'curve448'|'curve25519'} [options.type='ecc'] - The primary key algorithm type: ECC (default), RSA, Curve448 or Curve25519 (new format). + * @param {'ecc'|'rsa'|'curve448'|'curve25519'} [options.type='ecc'] - The primary key algorithm type: ECC (default for v4 keys), RSA, Curve448 or Curve25519 (new format, default for v6 keys). * Note: Curve448 and Curve25519 (new format) are not widely supported yet. * @param {String} [options.passphrase=(not protected)] - The passphrase used to encrypt the generated private key. If omitted or empty, the key won't be encrypted. * @param {Number} [options.rsaBits=4096] - Number of bits for RSA keys @@ -55,8 +55,15 @@ import { checkKeyRequirements } from './key/helper'; * @async * @static */ -export async function generateKey({ userIDs = [], passphrase, type = 'ecc', rsaBits = 4096, curve = 'curve25519', keyExpirationTime = 0, date = new Date(), subkeys = [{}], format = 'armored', config, ...rest }) { +export async function generateKey({ userIDs = [], passphrase, type, curve, rsaBits = 4096, keyExpirationTime = 0, date = new Date(), subkeys = [{}], format = 'armored', config, ...rest }) { config = { ...defaultConfig, ...config }; checkConfig(config); + if (!type && !curve) { + type = config.v6Keys ? 'curve25519' : 'ecc'; // default to new curve25519 for v6 keys (legacy curve25519 cannot be used with them) + curve = 'curve25519'; // unused with type != 'ecc' + } else { + type = type || 'ecc'; + curve = curve || 'curve25519'; + } userIDs = toArray(userIDs); const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`); diff --git a/test/general/key.js b/test/general/key.js index 2238b510..b30f0166 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -2463,29 +2463,35 @@ function versionSpecificTests() { }); it('Generate key - default values', function() { + const v6Key = openpgp.config.v6Keys; + const userID = { name: 'test', email: 'a@b.com' }; const opt = { userIDs: [userID], format: 'object' }; return openpgp.generateKey(opt).then(function({ privateKey: key }) { + expect(key.keyPacket.version).to.equal(v6Key ? 6 : 4); expect(key.isDecrypted()).to.be.true; - expect(key.getAlgorithmInfo().algorithm).to.equal('eddsaLegacy'); + expect(key.getAlgorithmInfo().algorithm).to.equal(v6Key ? 'ed25519' : 'eddsaLegacy'); expect(key.users.length).to.equal(1); expect(key.users[0].userID.userID).to.equal('test '); expect(key.users[0].selfCertifications[0].isPrimaryUserID).to.be.true; expect(key.subkeys).to.have.length(1); - expect(key.subkeys[0].getAlgorithmInfo().algorithm).to.equal('ecdh'); + expect(key.subkeys[0].getAlgorithmInfo().algorithm).to.equal(v6Key ? 'x25519' : 'ecdh'); }); }); it('Generate key - two subkeys with default values', function() { + const v6Key = openpgp.config.v6Keys; + const userID = { name: 'test', email: 'a@b.com' }; const opt = { userIDs: [userID], passphrase: '123', format: 'object', subkeys:[{},{}] }; return openpgp.generateKey(opt).then(function({ privateKey: key }) { + expect(key.keyPacket.version).to.equal(v6Key ? 6 : 4); expect(key.users.length).to.equal(1); expect(key.users[0].userID.userID).to.equal('test '); expect(key.users[0].selfCertifications[0].isPrimaryUserID).to.be.true; expect(key.subkeys).to.have.length(2); - expect(key.subkeys[0].getAlgorithmInfo().algorithm).to.equal('ecdh'); - expect(key.subkeys[1].getAlgorithmInfo().algorithm).to.equal('ecdh'); + expect(key.subkeys[0].getAlgorithmInfo().algorithm).to.equal(v6Key ? 'x25519' : 'ecdh'); + expect(key.subkeys[1].getAlgorithmInfo().algorithm).to.equal(v6Key ? 'x25519' : 'ecdh'); }); }); @@ -2558,34 +2564,39 @@ function versionSpecificTests() { }); it('Generate key - one signing subkey', function() { + const v6Key = openpgp.config.v6Keys; const userID = { name: 'test', email: 'a@b.com' }; const opt = { userIDs: [userID], passphrase: '123', format: 'object', subkeys:[{}, { sign: true }] }; + return openpgp.generateKey(opt).then(async function({ privateKey: key }) { + expect(key.keyPacket.version).to.equal(v6Key ? 6 : 4); expect(key.users.length).to.equal(1); expect(key.users[0].userID.userID).to.equal('test '); expect(key.users[0].selfCertifications[0].isPrimaryUserID).to.be.true; expect(key.subkeys).to.have.length(2); - expect(key.subkeys[0].getAlgorithmInfo().algorithm).to.equal('ecdh'); + expect(key.subkeys[0].getAlgorithmInfo().algorithm).to.equal(v6Key ? 'x25519' : 'ecdh'); expect(await key.getEncryptionKey()).to.equal(key.subkeys[0]); - expect(key.subkeys[1].getAlgorithmInfo().algorithm).to.equal('eddsaLegacy'); + expect(key.subkeys[1].getAlgorithmInfo().algorithm).to.equal(v6Key ? 'ed25519' : 'eddsaLegacy'); expect(await key.getSigningKey()).to.equal(key.subkeys[1]); }); }); it('Reformat key - one signing subkey', async function() { + const v6Key = openpgp.config.v6Keys; const userID = { name: 'test', email: 'a@b.com' }; const opt = { userIDs: [userID], format: 'object', subkeys:[{}, { sign: true }] }; const { privateKey } = await openpgp.generateKey(opt); return openpgp.reformatKey({ privateKey, userIDs: [userID] }).then(async function({ privateKey: armoredKey }) { const key = await openpgp.readKey({ armoredKey }); + expect(key.keyPacket.version).to.equal(v6Key ? 6 : 4); expect(key.users.length).to.equal(1); expect(key.users[0].userID.userID).to.equal('test '); expect(key.users[0].selfCertifications[0].isPrimaryUserID).to.be.true; expect(key.subkeys).to.have.length(2); - expect(key.subkeys[0].getAlgorithmInfo().algorithm).to.equal('ecdh'); + expect(key.subkeys[0].getAlgorithmInfo().algorithm).to.equal(v6Key ? 'x25519' : 'ecdh'); expect(await key.getEncryptionKey()).to.equal(key.subkeys[0]); - expect(key.subkeys[1].getAlgorithmInfo().algorithm).to.equal('eddsaLegacy'); + expect(key.subkeys[1].getAlgorithmInfo().algorithm).to.equal(v6Key ? 'ed25519' : 'eddsaLegacy'); expect(await key.getSigningKey()).to.equal(key.subkeys[1]); }); }); @@ -2596,7 +2607,7 @@ function versionSpecificTests() { openpgp.config.minRSABits = rsaBits; const userID = { name: 'test', email: 'a@b.com' }; - const opt = { type: 'rsa', rsaBits, userIDs: [userID], passphrase: '123', format: 'object', subkeys:[{ type: 'ecc', curve: 'curve25519' }] }; + const opt = { type: 'rsa', rsaBits, userIDs: [userID], passphrase: '123', format: 'object', subkeys:[{ type: 'ecc', curve: 'p256' }] }; try { const { privateKey: key } = await openpgp.generateKey(opt); expect(key.users.length).to.equal(1); diff --git a/test/general/openpgp.js b/test/general/openpgp.js index e97a21f5..d59c4cd1 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -1012,7 +1012,7 @@ export default () => describe('OpenPGP.js public api tests', function() { }); describe('generateKey - unit tests', function() { - it('should have default params set', function() { + it('should have default params set (v4 key)', function() { const now = util.normalizeDate(new Date()); const opt = { userIDs: { name: 'Test User', email: 'text@example.com' }, @@ -1023,6 +1023,7 @@ export default () => describe('OpenPGP.js public api tests', function() { return openpgp.generateKey(opt).then(async function({ privateKey, publicKey }) { for (const key of [publicKey, privateKey]) { expect(key).to.exist; + expect(key.keyPacket.version).to.equal(4); expect(key.users.length).to.equal(1); expect(key.users[0].userID.name).to.equal('Test User'); expect(key.users[0].userID.email).to.equal('text@example.com'); @@ -1039,6 +1040,37 @@ export default () => describe('OpenPGP.js public api tests', function() { }); }); + it('should have default params set (v6 key)', function() { + const now = util.normalizeDate(new Date()); + const opt = { + userIDs: { name: 'Test User', email: 'text@example.com' }, + passphrase: 'secret', + date: now, + format: 'object', + config: { v6Keys: true } + }; + return openpgp.generateKey(opt).then(async function({ privateKey, publicKey }) { + for (const key of [publicKey, privateKey]) { + expect(key).to.exist; + expect(key.keyPacket.version).to.equal(6); + expect(key.users.length).to.equal(1); + expect(key.users[0].userID.name).to.equal('Test User'); + expect(key.users[0].userID.email).to.equal('text@example.com'); + expect(key.getAlgorithmInfo().algorithm).to.equal('ed25519'); + expect(key.getAlgorithmInfo().rsaBits).to.equal(undefined); + expect(key.getAlgorithmInfo().curve).to.equal(undefined); + expect(+key.getCreationTime()).to.equal(+now); + expect(await key.getExpirationTime()).to.equal(Infinity); + expect(key.subkeys.length).to.equal(1); + expect(key.subkeys[0].getAlgorithmInfo().algorithm).to.equal('x25519'); + expect(key.subkeys[0].getAlgorithmInfo().rsaBits).to.equal(undefined); + expect(key.subkeys[0].getAlgorithmInfo().curve).to.equal(undefined); + expect(+key.subkeys[0].getCreationTime()).to.equal(+now); + expect(await key.subkeys[0].getExpirationTime()).to.equal(Infinity); + } + }); + }); + it('should output keypair with expected format', async function() { const opt = { userIDs: { name: 'Test User', email: 'text@example.com' } From c7efef60ac8b15895a6a45d990fdb659214bfde9 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Tue, 26 Sep 2023 15:30:44 +0200 Subject: [PATCH 070/201] Throw when parsing v6 keys using legacy curve25519 --- src/packet/public_key.js | 11 +++++++++++ test/general/signature.js | 30 ++++++++++++++---------------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/packet/public_key.js b/src/packet/public_key.js index af81f3a9..17732e07 100644 --- a/src/packet/public_key.js +++ b/src/packet/public_key.js @@ -124,6 +124,17 @@ class PublicKeyPacket { // - A series of values comprising the key material. const { read, publicParams } = crypto.parsePublicKeyParams(this.algorithm, bytes.subarray(pos)); + // The deprecated OIDs for Ed25519Legacy and Curve25519Legacy are used in legacy version 4 keys and signatures. + // Implementations MUST NOT accept or generate v6 key material using the deprecated OIDs. + if ( + this.version === 6 && + publicParams.oid && ( + publicParams.oid.getName() === enums.curve.curve25519Legacy || + publicParams.oid.getName() === enums.curve.ed25519Legacy + ) + ) { + throw new Error('Legacy curve25519 cannot be used with v6 keys'); + } this.publicParams = publicParams; pos += read; diff --git a/test/general/signature.js b/test/general/signature.js index 5580fedd..63ce14ba 100644 --- a/test/general/signature.js +++ b/test/general/signature.js @@ -1089,25 +1089,23 @@ eSvSZutLuKKbidSYMLhWROPlwKc2GU2ws6PrLZAyCAel/lU= // signature with salt shorter than expected const armoredMessage = `-----BEGIN PGP MESSAGE----- -xEQGAQoWHgTCf3OkPcYPPB6GmoMeaOz1wYXbuSvHxW/PVbRIynPv5yU3YApt -KDJPb4mCbmxvCoKjGx6CMjDpDsVB+wDFAcsLdQBlEWcKaGVsbG/CmgYBFgoA -AAApBYJlEWcKIqEGc+/nJTdgCm0oMk9viYJubG8KgqMbHoIyMOkOxUH7AMUA -AAAA5GYeBMJ/c6Q9xg88Hoaagx5o7PXBhdu5K8fFb89VtEjKAQCW/XwAPo2V -ugvc1634oGA/74j7KonU2qdl0LvxVJuB2wEAtutHh3wry/SNkc+japCGO4u4 -XjIVmkzQNtymmOECUwI= +xDQGAQgbDpdDiCIrq6YZAf5vD3wFIucHRyMNlExatdj6sQcW2FA/vV5eZGCv +mBUS4Mqqki4ByxR1AGUddyNUaGlzIGlzIHNpZ25lZMKGBgEbCAAAACkFgmUd +dyMioQYi5wdHIw2UTFq12PqxBxbYUD+9Xl5kYK+YFRLgyqqSLgAAAADZ9w6X +Q4giK6umGQH+bw98BS96KSXxW39Ue6hNxbSoc5xOqYnTsD+75FYdR1U9fco/ +HDpH7axPa2euIDpwT60NedSjcTx7C9Sots4mTvjMwQQ= -----END PGP MESSAGE-----`; const key = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- -xVoGZRFjtxYAAAAtCSsGAQQB2kcPAQEHQJRcfAi8wlCCWAeBcvpRO6iL5YK8 -1e8BVcOkAGVXKDguAAEAxIUb1xswIKPfVEyOZkqSFukVOegoArxIeEuDaoK0 -feXCrQYfFgoAAAA6BYJlEWO3AwsJBwMVCAoCFgACmwMCHgEioQZz7+clN2AK -bSgyT2+Jgm5sbwqCoxsegjIw6Q7FQfsAxQAAAACBKyDA5Ih9cWlc9o5NUzmo -jSCtKhy54bBzfRX0t9Jha4BfZwD9FvmhOEpJAnYRDmBrEiaO4okM3D6eNZz9 -rmGZkLT9oJMBAI6UbwsjgWw42W85Kb57tfYdF/779TrLHcNRZLNV0p8NzQDC -nwYQFgoAAAAsBYJlEWO3AhkBIqEGc+/nJTdgCm0oMk9viYJubG8KgqMbHoIy -MOkOxUH7AMUAAAAAV2kgOkNvj/g+Q6hFcHcpRFekCUxOons+JgXE+lxuKnbt -l10BAO7pYlHAee5dxkzQI3WPiiYFt/OYrnr7fT5QadRZhAutAP9n5bvQaoLX -vfHp79dKJnU1qDnSTEshB7ytt9I3Ze+DAQ== +xUsGZR13GRsAAAAgcCI5M7vPn+9uD1ii8nnT/schP5BjXXTyr+q7EmSlcaoA +/OkLygFTbUdwt6hMlfcNyUmS058WSIHxaVtG4uSfyjbCmQYfGwgAAAA6BYJl +HXcZAwsJBwMVCAoCFgACmwMCHgEioQYi5wdHIw2UTFq12PqxBxbYUD+9Xl5k +YK+YFRLgyqqSLgAAAABCZxAAxl8ycoAAY74DEPZDnfSYLP+dqdM8QZ3b/Mp4 +fnzOcVI4RvaxAjp3GZVXxisSS36A2fUx2lpj38y1tIvnnlShfpuylTp73foT +DVf/bROnAM0AwosGEBsIAAAALAWCZR13GQIZASKhBiLnB0cjDZRMWrXY+rEH +FthQP71eXmRgr5gVEuDKqpIuAAAAAFEEEFrhrlN40SgxwpL3UaSWs6F5pD83 +AOtaXLA/e9gFPNgiLnuid3AqUaFa6JlhWf4N/Md6SMQJ5cC7ATxTJ2a3xAMY +5UsE6+HN099QVLx95CMP -----END PGP PRIVATE KEY BLOCK-----` }); const { signatures } = await openpgp.verify({ From d6d8576700d1e29180ab1e934d60a6a6b8b9f18c Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Tue, 26 Sep 2023 15:31:24 +0200 Subject: [PATCH 071/201] Prevent generating v6 keys using legacy curve25519 --- src/packet/secret_key.js | 8 ++++++++ test/general/key.js | 20 ++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/packet/secret_key.js b/src/packet/secret_key.js index 6dbb3b72..acebd0a6 100644 --- a/src/packet/secret_key.js +++ b/src/packet/secret_key.js @@ -487,6 +487,14 @@ class SecretKeyPacket extends PublicKeyPacket { } async generate(bits, curve) { + // The deprecated OIDs for Ed25519Legacy and Curve25519Legacy are used in legacy version 4 keys and signatures. + // Implementations MUST NOT accept or generate v6 key material using the deprecated OIDs. + if (this.version === 6 && ( + (this.algorithm === enums.publicKey.ecdh && curve === enums.curve.curve25519Legacy) || + this.algorithm === enums.publicKey.eddsaLegacy + )) { + throw new Error(`Cannot generate v6 keys of type 'ecc' with curve ${curve}. Generate a key of type 'curve25519' instead`); + } const { privateParams, publicParams } = await crypto.generateParams(this.algorithm, bits, curve); this.privateParams = privateParams; this.publicParams = publicParams; diff --git a/test/general/key.js b/test/general/key.js index b30f0166..4ee96133 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -4314,6 +4314,26 @@ XvmoLueOOShu01X/kaylMqaT8w== expect(newKey.subkeys[0].getAlgorithmInfo().curve).to.equal('secp256k1'); }); + it('should throw when trying to add a curve25519Legacy key to a v6 key', async function() { + const v6Key = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xUsGY4d/4xsAAAAg+U2nu0jWCmHlZ3BqZYfQMxmZu52JGggkLq2EVD34laMA +GXKBexK+cH6NX1hs5hNhIB00TrJmosgv3mg1ditlsLfCsQYfGwoAAABCBYJj +h3/jAwsJBwUVCg4IDAIWAAKbAwIeCSIhBssYbE8GCaaX5NUt+mxyKwwfHifB +ilZwj2Ul7Ce62azJBScJAgcCAAAAAK0oIBA+LX0ifsDm185Ecds2v8lwgyU2 +kCcUmKfvBXbAf6rhRYWzuQOwEn7E/aLwIwRaLsdry0+VcallHhSu4RN6HWaE +QsiPlR4zxP/TP7mhfVEe7XWPxtnMUMtf15OyA51YBMdLBmOHf+MZAAAAIIaT +JINn+eUBXbki+PSAld2nhJh/LVmFsS+60WyvXkQ1AE1gCk95TUR3XFeibg/u +/tVY6a//1q0NWC1X+yui3O24wpsGGBsKAAAALAWCY4d/4wKbDCIhBssYbE8G +CaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce62azJAAAAAAQBIKbpGG2dWTX8j+Vj +FM21J0hqWlEg+bdiojWnKfA5AQpWUWtnNwDEM0g12vYxoWM8Y81W+bHBw805 +I8kWVkXU6vFOi+HWvv/ira7ofJu16NnoUkhclkUrk0mXubZvyl4GBg== +-----END PGP PRIVATE KEY BLOCK-----` }); + expect(v6Key.subkeys).to.have.length(1); + await expect(v6Key.addSubkey({ type: 'ecc' })).to.be.rejectedWith(/Cannot generate v6 keys of type 'ecc' with curve curve25519/); + expect(v6Key.subkeys).to.have.length(1); + }); + it('should throw when trying to encrypt a subkey separately from key', async function() { const privateKey = await openpgp.decryptKey({ privateKey: await openpgp.readKey({ armoredKey: priv_key_rsa }), From 01df8ca889368894056f8ef20a75c0c4624eb418 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Fri, 20 Oct 2023 17:16:04 +0200 Subject: [PATCH 072/201] Rename values of `enums.curve.{curve, ed}25519Legacy` from `'{curve. ed}25519'` to `'{curve. ed}25519Legacy'` To reflect the crypto-refresh naming, after the standardisation of the new EdDSA key types. --- openpgp.d.ts | 10 +++---- src/crypto/public_key/elliptic/ecdh.js | 4 +-- .../public_key/elliptic/eddsa_legacy.js | 2 +- src/crypto/public_key/elliptic/oid_curves.js | 20 ++++++------- src/enums.js | 30 +++++++++---------- src/key/helper.js | 3 +- src/key/private_key.js | 2 +- src/openpgp.js | 8 ++--- test/crypto/ecdh.js | 6 ++-- test/crypto/elliptic.js | 4 +-- test/crypto/validate.js | 6 ++-- test/general/config.js | 6 ++-- test/general/key.js | 18 +++++------ test/general/openpgp.js | 24 +++++++++++++-- test/general/x25519.js | 14 ++++----- 15 files changed, 88 insertions(+), 69 deletions(-) diff --git a/openpgp.d.ts b/openpgp.d.ts index 529fdb61..3082030f 100644 --- a/openpgp.d.ts +++ b/openpgp.d.ts @@ -687,7 +687,7 @@ interface KeyPair { publicKey: PublicKey; } -export type EllipticCurveName = 'ed25519' | 'curve25519' | 'p256' | 'p384' | 'p521' | 'secp256k1' | 'brainpoolP256r1' | 'brainpoolP384r1' | 'brainpoolP512r1'; +export type EllipticCurveName = 'ed25519Legacy' | 'curve25519Legacy' | 'p256' | 'p384' | 'p521' | 'secp256k1' | 'brainpoolP256r1' | 'brainpoolP384r1' | 'brainpoolP512r1'; interface GenerateKeyOptions { userIDs: MaybeArray; @@ -839,11 +839,11 @@ export namespace enums { p384 = 'p384', p521 = 'p521', /** @deprecated use `ed25519Legacy` instead */ - ed25519 = 'ed25519', - ed25519Legacy = 'ed25519', + ed25519 = 'ed25519Legacy', + ed25519Legacy = 'ed25519Legacy', /** @deprecated use `curve25519Legacy` instead */ - curve25519 = 'curve25519', - curve25519Legacy = 'curve25519', + curve25519 = 'curve25519Legacy', + curve25519Legacy = 'curve25519Legacy', secp256k1 = 'secp256k1', brainpoolP256r1 = 'brainpoolP256r1', brainpoolP384r1 = 'brainpoolP384r1', diff --git a/src/crypto/public_key/elliptic/ecdh.js b/src/crypto/public_key/elliptic/ecdh.js index e37fb633..37001916 100644 --- a/src/crypto/public_key/elliptic/ecdh.js +++ b/src/crypto/public_key/elliptic/ecdh.js @@ -92,7 +92,7 @@ async function kdf(hashAlgo, X, length, param, stripLeading = false, stripTraili */ async function genPublicEphemeralKey(curve, Q) { switch (curve.type) { - case 'curve25519': { + case 'curve25519Legacy': { const d = getRandomBytes(32); const { secretKey, sharedKey } = await genPrivateEphemeralKey(curve, Q, null, d); let { publicKey } = nacl.box.keyPair.fromSecretKey(secretKey); @@ -154,7 +154,7 @@ async function genPrivateEphemeralKey(curve, V, Q, d) { d = privateKey; } switch (curve.type) { - case 'curve25519': { + case 'curve25519Legacy': { const secretKey = d.slice().reverse(); const sharedKey = nacl.scalarMult(secretKey, V.subarray(1)); return { secretKey, sharedKey }; // Note: sharedKey is little-endian here, unlike below diff --git a/src/crypto/public_key/elliptic/eddsa_legacy.js b/src/crypto/public_key/elliptic/eddsa_legacy.js index 3de09ba4..d90e0f9c 100644 --- a/src/crypto/public_key/elliptic/eddsa_legacy.js +++ b/src/crypto/public_key/elliptic/eddsa_legacy.js @@ -86,7 +86,7 @@ export async function verify(oid, hashAlgo, { r, s }, m, publicKey, hashed) { */ export async function validateParams(oid, Q, k) { // Check whether the given curve is supported - if (oid.getName() !== 'ed25519') { + if (oid.getName() !== enums.curve.ed25519Legacy) { return false; } diff --git a/src/crypto/public_key/elliptic/oid_curves.js b/src/crypto/public_key/elliptic/oid_curves.js index 129ab22c..4d40e25b 100644 --- a/src/crypto/public_key/elliptic/oid_curves.js +++ b/src/crypto/public_key/elliptic/oid_curves.js @@ -89,14 +89,14 @@ const curves = { node: nodeCurves.secp256k1, payloadSize: 32 }, - ed25519: { + ed25519Legacy: { oid: [0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, 0x01, 0xDA, 0x47, 0x0F, 0x01], keyType: enums.publicKey.eddsaLegacy, hash: enums.hash.sha512, node: false, // nodeCurves.ed25519 TODO payloadSize: 32 }, - curve25519: { + curve25519Legacy: { oid: [0x06, 0x0A, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01], keyType: enums.publicKey.ecdh, hash: enums.hash.sha256, @@ -161,10 +161,10 @@ class CurveWithOID { this.type = 'web'; } else if (this.node && util.getNodeCrypto()) { this.type = 'node'; - } else if (this.name === 'curve25519') { - this.type = 'curve25519'; - } else if (this.name === 'ed25519') { - this.type = 'ed25519'; + } else if (this.name === enums.curve.curve25519Legacy) { + this.type = 'curve25519Legacy'; + } else if (this.name === enums.curve.ed25519Legacy) { + this.type = 'ed25519Legacy'; } } @@ -180,7 +180,7 @@ class CurveWithOID { } case 'node': return nodeGenKeyPair(this.name); - case 'curve25519': { + case 'curve25519Legacy': { const privateKey = getRandomBytes(32); privateKey[0] = (privateKey[0] & 127) | 64; privateKey[31] &= 248; @@ -189,7 +189,7 @@ class CurveWithOID { const publicKey = util.concatUint8Array([new Uint8Array([0x40]), keyPair.publicKey]); return { publicKey, privateKey }; } - case 'ed25519': { + case 'ed25519Legacy': { const privateKey = getRandomBytes(32); const keyPair = nacl.sign.keyPair.fromSeed(privateKey); const publicKey = util.concatUint8Array([new Uint8Array([0x40]), keyPair.publicKey]); @@ -243,7 +243,7 @@ async function validateStandardParams(algo, oid, Q, d) { p384: true, p521: true, secp256k1: true, - curve25519: algo === enums.publicKey.ecdh, + curve25519Legacy: algo === enums.publicKey.ecdh, brainpoolP256r1: true, brainpoolP384r1: true, brainpoolP512r1: true @@ -255,7 +255,7 @@ async function validateStandardParams(algo, oid, Q, d) { return false; } - if (curveName === 'curve25519') { + if (curveName === enums.curve.curve25519Legacy) { d = d.slice().reverse(); // Re-derive public point Q' const { publicKey } = nacl.box.keyPair.fromSecretKey(d); diff --git a/src/enums.js b/src/enums.js index 61fe1b37..8a417ec0 100644 --- a/src/enums.js +++ b/src/enums.js @@ -44,25 +44,25 @@ export default { '2B8104000A': 'secp256k1', /** Ed25519 - deprecated by crypto-refresh (replaced by standaone Ed25519 algo) */ - 'ed25519Legacy': 'ed25519', - 'ED25519': 'ed25519', + 'ed25519Legacy': 'ed25519Legacy', + 'ED25519': 'ed25519Legacy', /** @deprecated use `ed25519Legacy` instead */ - 'ed25519': 'ed25519', - 'Ed25519': 'ed25519', - '1.3.6.1.4.1.11591.15.1': 'ed25519', - '2b06010401da470f01': 'ed25519', - '2B06010401DA470F01': 'ed25519', + 'ed25519': 'ed25519Legacy', + 'Ed25519': 'ed25519Legacy', + '1.3.6.1.4.1.11591.15.1': 'ed25519Legacy', + '2b06010401da470f01': 'ed25519Legacy', + '2B06010401DA470F01': 'ed25519Legacy', /** Curve25519 - deprecated by crypto-refresh (replaced by standaone X25519 algo) */ - 'curve25519Legacy': 'curve25519', - 'X25519': 'curve25519', - 'cv25519': 'curve25519', + 'curve25519Legacy': 'curve25519Legacy', + 'X25519': 'curve25519Legacy', + 'cv25519': 'curve25519Legacy', /** @deprecated use `curve25519Legacy` instead */ - 'curve25519': 'curve25519', - 'Curve25519': 'curve25519', - '1.3.6.1.4.1.3029.1.5.1': 'curve25519', - '2b060104019755010501': 'curve25519', - '2B060104019755010501': 'curve25519', + 'curve25519': 'curve25519Legacy', + 'Curve25519': 'curve25519Legacy', + '1.3.6.1.4.1.3029.1.5.1': 'curve25519Legacy', + '2b060104019755010501': 'curve25519Legacy', + '2B060104019755010501': 'curve25519Legacy', /** BrainpoolP256r1 Curve */ 'brainpoolP256r1': 'brainpoolP256r1', diff --git a/src/key/helper.js b/src/key/helper.js index a23bbaae..babaf3e6 100644 --- a/src/key/helper.js +++ b/src/key/helper.js @@ -332,7 +332,8 @@ export function sanitizeKeyOptions(options, subkeyDefaults = {}) { } catch (e) { throw new Error('Unknown curve'); } - if (options.curve === enums.curve.ed25519Legacy || options.curve === enums.curve.curve25519Legacy) { + if (options.curve === enums.curve.ed25519Legacy || options.curve === enums.curve.curve25519Legacy || + options.curve === 'ed25519' || options.curve === 'curve25519') { // keep support for curve names without 'Legacy' addition, for now options.curve = options.sign ? enums.curve.ed25519Legacy : enums.curve.curve25519Legacy; } if (options.sign) { diff --git a/src/key/private_key.js b/src/key/private_key.js index b6533676..9fe89ca9 100644 --- a/src/key/private_key.js +++ b/src/key/private_key.js @@ -229,7 +229,7 @@ class PrivateKey extends PublicKey { const defaultOptions = secretKeyPacket.getAlgorithmInfo(); defaultOptions.type = getDefaultSubkeyType(defaultOptions.algorithm); defaultOptions.rsaBits = defaultOptions.bits || 4096; - defaultOptions.curve = defaultOptions.curve || 'curve25519'; + defaultOptions.curve = defaultOptions.curve || 'curve25519Legacy'; options = helper.sanitizeKeyOptions(options, defaultOptions); // Every subkey for a v4 primary key MUST be a v4 subkey. // Every subkey for a v6 primary key MUST be a v6 subkey. diff --git a/src/openpgp.js b/src/openpgp.js index 13c93d58..408eb3e2 100644 --- a/src/openpgp.js +++ b/src/openpgp.js @@ -41,8 +41,8 @@ import { checkKeyRequirements } from './key/helper'; * Note: Curve448 and Curve25519 (new format) are not widely supported yet. * @param {String} [options.passphrase=(not protected)] - The passphrase used to encrypt the generated private key. If omitted or empty, the key won't be encrypted. * @param {Number} [options.rsaBits=4096] - Number of bits for RSA keys - * @param {String} [options.curve='curve25519'] - Elliptic curve for ECC keys: - * curve25519 (default), p256, p384, p521, secp256k1, + * @param {String} [options.curve='curve25519Legacy'] - Elliptic curve for ECC keys: + * curve25519Legacy (default), p256, p384, p521, secp256k1, * brainpoolP256r1, brainpoolP384r1, or brainpoolP512r1 * @param {Date} [options.date=current date] - Override the creation date of the key and the key signatures * @param {Number} [options.keyExpirationTime=0 (never expires)] - Number of seconds from the key creation time after which the key expires @@ -59,10 +59,10 @@ export async function generateKey({ userIDs = [], passphrase, type, curve, rsaBi config = { ...defaultConfig, ...config }; checkConfig(config); if (!type && !curve) { type = config.v6Keys ? 'curve25519' : 'ecc'; // default to new curve25519 for v6 keys (legacy curve25519 cannot be used with them) - curve = 'curve25519'; // unused with type != 'ecc' + curve = 'curve25519Legacy'; // unused with type != 'ecc' } else { type = type || 'ecc'; - curve = curve || 'curve25519'; + curve = curve || 'curve25519Legacy'; } userIDs = toArray(userIDs); const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`); diff --git a/test/crypto/ecdh.js b/test/crypto/ecdh.js index 4f211386..85eba9fa 100644 --- a/test/crypto/ecdh.js +++ b/test/crypto/ecdh.js @@ -149,7 +149,7 @@ export default () => describe('ECDH key exchange @lightweight', function () { }); it('Different keys', async function () { - const curve = new elliptic_curves.CurveWithOID('curve25519'); + const curve = new elliptic_curves.CurveWithOID(openpgp.enums.curve.curve25519Legacy); const oid = new OID(curve.oid); const kdfParams = new KDFParams({ hash: curve.hash, cipher: curve.cipher }); const data = util.stringToUint8Array('test'); @@ -160,7 +160,7 @@ export default () => describe('ECDH key exchange @lightweight', function () { }); it('Invalid fingerprint', async function () { - const curve = new elliptic_curves.CurveWithOID('curve25519'); + const curve = new elliptic_curves.CurveWithOID(openpgp.enums.curve.curve25519Legacy); const oid = new OID(curve.oid); const kdfParams = new KDFParams({ hash: curve.hash, cipher: curve.cipher }); const data = util.stringToUint8Array('test'); @@ -171,7 +171,7 @@ export default () => describe('ECDH key exchange @lightweight', function () { }); it('Successful exchange x25519 (legacy)', async function () { - const curve = new elliptic_curves.CurveWithOID('curve25519'); + const curve = new elliptic_curves.CurveWithOID(openpgp.enums.curve.curve25519Legacy); const oid = new OID(curve.oid); const kdfParams = new KDFParams({ hash: curve.hash, cipher: curve.cipher }); const data = util.stringToUint8Array('test'); diff --git a/test/crypto/elliptic.js b/test/crypto/elliptic.js index f34660e0..048413fd 100644 --- a/test/crypto/elliptic.js +++ b/test/crypto/elliptic.js @@ -71,8 +71,8 @@ export default () => describe('Elliptic Curve Cryptography @lightweight', functi if (!config.useIndutnyElliptic && !util.getNodeCrypto()) { this.skip(); } - const names = config.useIndutnyElliptic ? ['p256', 'p384', 'p521', 'secp256k1', 'curve25519', 'brainpoolP256r1', 'brainpoolP384r1', 'brainpoolP512r1'] : - ['p256', 'p384', 'p521', 'curve25519']; + const names = config.useIndutnyElliptic ? ['p256', 'p384', 'p521', 'secp256k1', 'curve25519Legacy', 'brainpoolP256r1', 'brainpoolP384r1', 'brainpoolP512r1'] : + ['p256', 'p384', 'p521', 'curve25519Legacy']; return Promise.all(names.map(function (name) { const curve = new elliptic_curves.CurveWithOID(name); return curve.genKeyPair().then(keyPair => { diff --git a/test/crypto/validate.js b/test/crypto/validate.js index 9b9b883e..ee4fa29e 100644 --- a/test/crypto/validate.js +++ b/test/crypto/validate.js @@ -91,7 +91,7 @@ export default () => { describe('EdDSA parameter validation (legacy format)', function() { let eddsaKey; before(async () => { - eddsaKey = await generatePrivateKeyObject({ curve: 'ed25519' }); + eddsaKey = await generatePrivateKeyObject({ curve: 'ed25519Legacy' }); }); it('EdDSA params should be valid', async function() { @@ -115,7 +115,7 @@ export default () => { let ecdhKey; let ecdsaKey; before(async () => { - eddsaKey = await generatePrivateKeyObject({ curve: 'ed25519' }); + eddsaKey = await generatePrivateKeyObject({ curve: 'ed25519Legacy' }); ecdhKey = eddsaKey.subkeys[0]; ecdsaKey = await generatePrivateKeyObject({ curve: 'p256' }); }); @@ -203,7 +203,7 @@ export default () => { ecdsaKey = await generatePrivateKeyObject({ curve }); ecdhKey = ecdsaKey.subkeys[0]; } else { - const eddsaKey = await generatePrivateKeyObject({ curve: 'ed25519' }); + const eddsaKey = await generatePrivateKeyObject({ curve: 'ed25519Legacy' }); ecdhKey = eddsaKey.subkeys[0]; } }); diff --git a/test/general/config.js b/test/general/config.js index 3da4c40a..55120a30 100644 --- a/test/general/config.js +++ b/test/general/config.js @@ -299,7 +299,7 @@ n9/quqtmyOtYOA6gXNCw0Fal3iANKBmsPmYI await expect(openpgp.encrypt({ message, encryptionKeys: [key], config: { rejectCurves: new Set([openpgp.enums.curve.curve25519Legacy]) } - })).to.be.eventually.rejectedWith(/Support for ecdh keys using curve curve25519 is disabled/); + })).to.be.eventually.rejectedWith(/Support for ecdh keys using curve curve25519Legacy is disabled/); const echdEncrypted = await openpgp.encrypt({ message, encryptionKeys: [key], config: { rejectCurves: new Set([openpgp.enums.curve.ed25519Legacy]) } @@ -372,7 +372,7 @@ n9/quqtmyOtYOA6gXNCw0Fal3iANKBmsPmYI })).to.be.eventually.rejectedWith(/eddsaLegacy keys are considered too weak/); await expect(openpgp.sign({ message, signingKeys: [key], config: { rejectCurves: new Set([openpgp.enums.curve.ed25519Legacy]) } - })).to.be.eventually.rejectedWith(/Support for eddsaLegacy keys using curve ed25519 is disabled/); + })).to.be.eventually.rejectedWith(/Support for eddsaLegacy keys using curve ed25519Legacy is disabled/); }); it('openpgp.verify', async function() { @@ -424,7 +424,7 @@ n9/quqtmyOtYOA6gXNCw0Fal3iANKBmsPmYI config: { rejectCurves: new Set([openpgp.enums.curve.ed25519Legacy]) } }; const { signatures: [sig5] } = await openpgp.verify(opt5); - await expect(sig5.verified).to.be.eventually.rejectedWith(/Support for eddsaLegacy keys using curve ed25519 is disabled/); + await expect(sig5.verified).to.be.eventually.rejectedWith(/Support for eddsaLegacy keys using curve ed25519Legacy is disabled/); }); describe('detects unknown config property', async function() { diff --git a/test/general/key.js b/test/general/key.js index 4ee96133..f1ee51a1 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -3510,7 +3510,7 @@ PzIEeL7UH3trraFmi+Gq8u4kAA== }); it("validate() - don't throw if key parameters correspond", async function() { - const { privateKey: key } = await openpgp.generateKey({ userIDs: {}, curve: 'ed25519', format: 'object' }); + const { privateKey: key } = await openpgp.generateKey({ userIDs: {}, curve: 'ed25519Legacy', format: 'object' }); await expect(key.validate()).to.not.be.rejected; }); @@ -3536,7 +3536,7 @@ PzIEeL7UH3trraFmi+Gq8u4kAA== it('isDecrypted() - should reflect whether all (sub)keys are encrypted', async function() { const passphrase = '12345678'; - const { privateKey: key } = await openpgp.generateKey({ userIDs: {}, curve: 'ed25519', passphrase, format: 'object' }); + const { privateKey: key } = await openpgp.generateKey({ userIDs: {}, curve: 'ed25519Legacy', passphrase, format: 'object' }); expect(key.isDecrypted()).to.be.false; await key.subkeys[0].keyPacket.decrypt(passphrase); expect(key.isDecrypted()).to.be.true; @@ -4252,7 +4252,7 @@ VYGdb3eNlV8CfoEC expect(key.subkeys).to.have.length(0); const newKey = await key.addSubkey(); expect(newKey.subkeys[0].getAlgorithmInfo().algorithm).to.equal('ecdh'); - expect(newKey.subkeys[0].getAlgorithmInfo().curve).to.equal('curve25519'); + expect(newKey.subkeys[0].getAlgorithmInfo().curve).to.equal('curve25519Legacy'); }); it('Add a new default subkey to an Ed488 key', async function() { @@ -4330,7 +4330,7 @@ FM21J0hqWlEg+bdiojWnKfA5AQpWUWtnNwDEM0g12vYxoWM8Y81W+bHBw805 I8kWVkXU6vFOi+HWvv/ira7ofJu16NnoUkhclkUrk0mXubZvyl4GBg== -----END PGP PRIVATE KEY BLOCK-----` }); expect(v6Key.subkeys).to.have.length(1); - await expect(v6Key.addSubkey({ type: 'ecc' })).to.be.rejectedWith(/Cannot generate v6 keys of type 'ecc' with curve curve25519/); + await expect(v6Key.addSubkey({ type: 'ecc' })).to.be.rejectedWith(/Cannot generate v6 keys of type 'ecc' with curve curve25519Legacy/); expect(v6Key.subkeys).to.have.length(1); }); @@ -4369,10 +4369,10 @@ I8kWVkXU6vFOi+HWvv/ira7ofJu16NnoUkhclkUrk0mXubZvyl4GBg== it('create and add a new eddsa subkey to a eddsa key', async function() { const passphrase = '12345678'; const userID = { name: 'test', email: 'a@b.com' }; - const { privateKey } = await openpgp.generateKey({ curve: 'curve25519', userIDs: [userID], format: 'object', subkeys:[] }); + const { privateKey } = await openpgp.generateKey({ curve: 'curve25519Legacy', userIDs: [userID], format: 'object', subkeys:[] }); const total = privateKey.subkeys.length; - let newPrivateKey = await privateKey.addSubkey({ curve: 'curve25519', userIDs: [userID], sign: true }); + let newPrivateKey = await privateKey.addSubkey({ curve: 'curve25519Legacy', userIDs: [userID], sign: true }); const subkey1 = newPrivateKey.subkeys[total]; const encNewPrivateKey = await openpgp.encryptKey({ privateKey: newPrivateKey, passphrase }); newPrivateKey = await openpgp.decryptKey({ @@ -4393,14 +4393,14 @@ I8kWVkXU6vFOi+HWvv/ira7ofJu16NnoUkhclkUrk0mXubZvyl4GBg== it('create and add a new ecdsa subkey to a eddsa key', async function() { const userID = { name: 'test', email: 'a@b.com' }; - const { privateKey } = await openpgp.generateKey({ curve: 'ed25519', userIDs: [userID], format: 'object', subkeys:[] }); + const { privateKey } = await openpgp.generateKey({ curve: 'ed25519Legacy', userIDs: [userID], format: 'object', subkeys:[] }); const total = privateKey.subkeys.length; let newPrivateKey = await privateKey.addSubkey({ curve: 'p256', sign: true }); newPrivateKey = await openpgp.readKey({ armoredKey: newPrivateKey.armor() }); const subkey = newPrivateKey.subkeys[total]; expect(subkey).to.exist; expect(newPrivateKey.subkeys.length).to.be.equal(total + 1); - expect(newPrivateKey.getAlgorithmInfo().curve).to.be.equal('ed25519'); + expect(newPrivateKey.getAlgorithmInfo().curve).to.be.equal('ed25519Legacy'); expect(subkey.getAlgorithmInfo().curve).to.be.equal('p256'); expect(newPrivateKey.getAlgorithmInfo().algorithm).to.be.equal('eddsaLegacy'); expect(subkey.getAlgorithmInfo().algorithm).to.be.equal('ecdsa'); @@ -4428,7 +4428,7 @@ I8kWVkXU6vFOi+HWvv/ira7ofJu16NnoUkhclkUrk0mXubZvyl4GBg== it('create and add a new rsa subkey to a ecc key', async function() { const userID = { name: 'test', email: 'a@b.com' }; - const opt = { curve: 'ed25519', userIDs: [userID], format: 'object', subkeys:[] }; + const opt = { curve: 'ed25519Legacy', userIDs: [userID], format: 'object', subkeys:[] }; const { privateKey } = await openpgp.generateKey(opt); const total = privateKey.subkeys.length; let newPrivateKey = await privateKey.addSubkey({ type: 'rsa' }); diff --git a/test/general/openpgp.js b/test/general/openpgp.js index d59c4cd1..008cc713 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -1012,6 +1012,24 @@ export default () => describe('OpenPGP.js public api tests', function() { }); describe('generateKey - unit tests', function() { + it('should still support curve="curve25519" for ECC key type (v4 key)', function() { + const opt = { + userIDs: { name: 'Test User', email: 'text@example.com' }, + type: 'ecc', + curve: 'curve25519', + format: 'object' + }; + return openpgp.generateKey(opt).then(async function({ privateKey: key }) { + expect(key).to.exist; + expect(key.getAlgorithmInfo().rsaBits).to.equal(undefined); + expect(key.getAlgorithmInfo().algorithm).to.equal('eddsaLegacy'); + expect(key.getAlgorithmInfo().curve).to.equal('ed25519Legacy'); + expect(key.subkeys[0].getAlgorithmInfo().rsaBits).to.equal(undefined); + expect(key.subkeys[0].getAlgorithmInfo().algorithm).to.equal('ecdh'); + expect(key.subkeys[0].getAlgorithmInfo().curve).to.equal('curve25519Legacy'); + }); + }); + it('should have default params set (v4 key)', function() { const now = util.normalizeDate(new Date()); const opt = { @@ -1028,12 +1046,12 @@ export default () => describe('OpenPGP.js public api tests', function() { expect(key.users[0].userID.name).to.equal('Test User'); expect(key.users[0].userID.email).to.equal('text@example.com'); expect(key.getAlgorithmInfo().rsaBits).to.equal(undefined); - expect(key.getAlgorithmInfo().curve).to.equal('ed25519'); + expect(key.getAlgorithmInfo().curve).to.equal('ed25519Legacy'); expect(+key.getCreationTime()).to.equal(+now); expect(await key.getExpirationTime()).to.equal(Infinity); expect(key.subkeys.length).to.equal(1); expect(key.subkeys[0].getAlgorithmInfo().rsaBits).to.equal(undefined); - expect(key.subkeys[0].getAlgorithmInfo().curve).to.equal('curve25519'); + expect(key.subkeys[0].getAlgorithmInfo().curve).to.equal('curve25519Legacy'); expect(+key.subkeys[0].getCreationTime()).to.equal(+now); expect(await key.subkeys[0].getExpirationTime()).to.equal(Infinity); } @@ -4777,7 +4795,7 @@ sEj+v9LKoMTYZGMfp3qDVFLtkBE88eVmVjgJOoLhrsv7yh0PAA== }); describe('Sign and verify with each curve', function() { - const curves = ['secp256k1' , 'p256', 'p384', 'p521', 'curve25519', 'brainpoolP256r1', 'brainpoolP384r1', 'brainpoolP512r1']; + const curves = ['secp256k1' , 'p256', 'p384', 'p521', 'curve25519Legacy', 'brainpoolP256r1', 'brainpoolP384r1', 'brainpoolP512r1']; curves.forEach(curve => { it(`sign/verify with ${curve}`, async function() { const config = { rejectCurves: new Set() }; diff --git a/test/general/x25519.js b/test/general/x25519.js index f197c595..93bc8c26 100644 --- a/test/general/x25519.js +++ b/test/general/x25519.js @@ -219,7 +219,7 @@ export default () => (openpgp.config.ci ? describe.skip : describe)('X25519 Cryp describe('Ed25519 Test Vectors from RFC8032', function () { // https://tools.ietf.org/html/rfc8032#section-7.1 function testVector(vector) { - const curve = new elliptic.CurveWithOID('ed25519'); + const curve = new elliptic.CurveWithOID(openpgp.enums.curve.ed25519Legacy); const { publicKey } = nacl.sign.keyPair.fromSeed(util.hexToUint8Array(vector.SECRET_KEY)); expect(publicKey).to.deep.equal(util.hexToUint8Array(vector.PUBLIC_KEY)); const data = vector.MESSAGE; @@ -382,7 +382,7 @@ function omnibus() { it('Omnibus Ed25519/Curve25519 Test', function() { const options = { userIDs: { name: 'Hi', email: 'hi@hel.lo' }, - curve: 'ed25519', + curve: 'ed25519Legacy', format: 'object' }; return openpgp.generateKey(options).then(async function({ privateKey, publicKey }) { @@ -395,10 +395,10 @@ function omnibus() { const hi = privateKey; const primaryKey = hi.keyPacket; const subkey = hi.subkeys[0]; - expect(hi.getAlgorithmInfo().curve).to.equal('ed25519'); expect(hi.getAlgorithmInfo().algorithm).to.equal('eddsaLegacy'); - expect(subkey.getAlgorithmInfo().curve).to.equal('curve25519'); + expect(hi.getAlgorithmInfo().curve).to.equal('ed25519Legacy'); expect(subkey.getAlgorithmInfo().algorithm).to.equal('ecdh'); + expect(subkey.getAlgorithmInfo().curve).to.equal('curve25519Legacy'); // Verify that self Certificate is valid const user = hi.users[0]; @@ -410,15 +410,15 @@ function omnibus() { const options = { userIDs: { name: 'Bye', email: 'bye@good.bye' }, - curve: 'curve25519', + curve: 'curve25519Legacy', format: 'object' }; return openpgp.generateKey(options).then(async function({ privateKey: bye }) { - expect(bye.getAlgorithmInfo().curve).to.equal('ed25519'); expect(bye.getAlgorithmInfo().algorithm).to.equal('eddsaLegacy'); - expect(bye.subkeys[0].getAlgorithmInfo().curve).to.equal('curve25519'); + expect(bye.getAlgorithmInfo().curve).to.equal('ed25519Legacy'); expect(bye.subkeys[0].getAlgorithmInfo().algorithm).to.equal('ecdh'); + expect(bye.subkeys[0].getAlgorithmInfo().curve).to.equal('curve25519Legacy'); // Verify that self Certificate is valid const user = bye.users[0]; From a9fae5ff12bf96f5f232eea05e702abe65121034 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Fri, 6 Oct 2023 16:14:59 +0200 Subject: [PATCH 073/201] Replace indutny-elliptic lib with noble-curves Unlike elliptic, noble-curves targets algorithmic constant time, and it relies on the native BigInts when available, resulting in a smaller bundle and improved performance. Also, expand testing of fallback elliptic implementation. --- package-lock.json | 97 ------------ package.json | 1 - src/crypto/public_key/elliptic/ecdh.js | 71 ++++----- src/crypto/public_key/elliptic/ecdsa.js | 35 ++--- src/crypto/public_key/elliptic/indutnyKey.js | 44 ------ src/crypto/public_key/elliptic/oid_curves.js | 103 +++++++------ test/crypto/ecdh.js | 27 ++-- test/crypto/elliptic.js | 153 +++++++++---------- test/crypto/elliptic_data.js | 14 ++ test/general/brainpool.js | 4 - 10 files changed, 204 insertions(+), 345 deletions(-) delete mode 100644 src/crypto/public_key/elliptic/indutnyKey.js diff --git a/package-lock.json b/package-lock.json index a1264117..0c0cc051 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,6 @@ }, "devDependencies": { "@openpgp/asmcrypto.js": "^3.0.0", - "@openpgp/elliptic": "^6.5.1", "@openpgp/jsdoc": "^3.6.11", "@openpgp/noble-curves": "^1.2.1-0", "@openpgp/noble-hashes": "^1.3.3-0", @@ -572,21 +571,6 @@ "integrity": "sha512-X/DPYy7uHe+dlY2Botb99uXwb2kXR6HTv0hQOnnI0TVEqOIMQyzCDWAzlX00AacsYryDAphuOndg6mk6wtJCNg==", "dev": true }, - "node_modules/@openpgp/elliptic": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@openpgp/elliptic/-/elliptic-6.5.1.tgz", - "integrity": "sha512-VR20QWndMXoZTAzCUqauDT4dLrHO4RTnyVV3szuRHllQSU/JZToLvWtFxpEQth4XWyqlxHPwq7tljE5V97+n1g==", - "dev": true, - "dependencies": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" - } - }, "node_modules/@openpgp/jsdoc": { "version": "3.6.11", "resolved": "https://registry.npmjs.org/@openpgp/jsdoc/-/jsdoc-3.6.11.tgz", @@ -1489,12 +1473,6 @@ "node": ">=8" } }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, "node_modules/browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", @@ -3465,16 +3443,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/hash.js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", - "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" - } - }, "node_modules/hasha": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", @@ -3496,17 +3464,6 @@ "he": "bin/he" } }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, "node_modules/hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", @@ -4975,12 +4932,6 @@ "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=" }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -7993,21 +7944,6 @@ "integrity": "sha512-X/DPYy7uHe+dlY2Botb99uXwb2kXR6HTv0hQOnnI0TVEqOIMQyzCDWAzlX00AacsYryDAphuOndg6mk6wtJCNg==", "dev": true }, - "@openpgp/elliptic": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@openpgp/elliptic/-/elliptic-6.5.1.tgz", - "integrity": "sha512-VR20QWndMXoZTAzCUqauDT4dLrHO4RTnyVV3szuRHllQSU/JZToLvWtFxpEQth4XWyqlxHPwq7tljE5V97+n1g==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" - } - }, "@openpgp/jsdoc": { "version": "3.6.11", "resolved": "https://registry.npmjs.org/@openpgp/jsdoc/-/jsdoc-3.6.11.tgz", @@ -8699,12 +8635,6 @@ "fill-range": "^7.0.1" } }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, "browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", @@ -10238,16 +10168,6 @@ "has-symbols": "^1.0.2" } }, - "hash.js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", - "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" - } - }, "hasha": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", @@ -10263,17 +10183,6 @@ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, "hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", @@ -11425,12 +11334,6 @@ "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=" }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", diff --git a/package.json b/package.json index c8b4f351..90cd6346 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,6 @@ "devDependencies": { "@openpgp/asmcrypto.js": "^3.0.0", "@openpgp/noble-curves": "^1.2.1-0", - "@openpgp/elliptic": "^6.5.1", "@openpgp/jsdoc": "^3.6.11", "@openpgp/noble-hashes": "^1.3.3-0", "@openpgp/seek-bzip": "^1.0.5-git", diff --git a/src/crypto/public_key/elliptic/ecdh.js b/src/crypto/public_key/elliptic/ecdh.js index 37001916..ed370578 100644 --- a/src/crypto/public_key/elliptic/ecdh.js +++ b/src/crypto/public_key/elliptic/ecdh.js @@ -21,7 +21,7 @@ */ import nacl from '@openpgp/tweetnacl/nacl-fast-light'; -import { CurveWithOID, jwkToRawPublic, rawPublicToJWK, privateToJWK, validateStandardParams } from './oid_curves'; +import { CurveWithOID, jwkToRawPublic, rawPublicToJWK, privateToJWK, validateStandardParams, getNobleCurve } from './oid_curves'; import * as aesKW from '../../aes_kw'; import { getRandomBytes } from '../../random'; import hash from '../../hash'; @@ -29,7 +29,6 @@ import enums from '../../../enums'; import util from '../../../util'; import { b64ToUint8Array } from '../../../encoding/base64'; import * as pkcs5 from '../../pkcs5'; -import { keyFromPublic, keyFromPrivate, getIndutnyCurve } from './indutnyKey'; import getCipher from '../../cipher/getCipher'; const webCrypto = util.getWebCrypto(); @@ -105,13 +104,16 @@ async function genPublicEphemeralKey(curve, Q) { return await webPublicEphemeralKey(curve, Q); } catch (err) { util.printDebugError(err); + return jsPublicEphemeralKey(curve, Q); } } break; case 'node': return nodePublicEphemeralKey(curve, Q); + default: { + return jsPublicEphemeralKey(curve, Q); + } } - return ellipticPublicEphemeralKey(curve, Q); } /** @@ -165,13 +167,16 @@ async function genPrivateEphemeralKey(curve, V, Q, d) { return await webPrivateEphemeralKey(curve, V, Q, d); } catch (err) { util.printDebugError(err); + return jsPrivateEphemeralKey(curve, V, d); } } break; case 'node': return nodePrivateEphemeralKey(curve, V, d); + default: { + return jsPrivateEphemeralKey(curve, V, d); + } } - return ellipticPrivateEphemeralKey(curve, V, d); } /** @@ -205,6 +210,24 @@ export async function decrypt(oid, kdfParams, V, C, Q, d, fingerprint) { throw err; } +function jsPrivateEphemeralKey(curve, V, d) { + const nobleCurve = getNobleCurve(curve.name); + // The output includes parity byte + const sharedSecretWithParity = nobleCurve.getSharedSecret(d, V); + const sharedKey = sharedSecretWithParity.subarray(1); + return { secretKey: d, sharedKey }; +} + +async function jsPublicEphemeralKey(curve, Q) { + const nobleCurve = getNobleCurve(curve.name); + const { publicKey: V, privateKey: v } = await curve.genKeyPair(); + + // The output includes parity byte + const sharedSecretWithParity = nobleCurve.getSharedSecret(v, Q); + const sharedKey = sharedSecretWithParity.subarray(1); + return { publicKey: V, sharedKey }; +} + /** * Generate ECDHE secret from private key and public part of ephemeral key using webCrypto * @@ -306,46 +329,6 @@ async function webPublicEphemeralKey(curve, Q) { return { publicKey, sharedKey }; } -/** - * Generate ECDHE secret from private key and public part of ephemeral key using indutny/elliptic - * - * @param {CurveWithOID} curve - Elliptic curve object - * @param {Uint8Array} V - Public part of ephemeral key - * @param {Uint8Array} d - Recipient private key - * @returns {Promise<{secretKey: Uint8Array, sharedKey: Uint8Array}>} - * @async - */ -async function ellipticPrivateEphemeralKey(curve, V, d) { - const indutnyCurve = await getIndutnyCurve(curve.name); - V = keyFromPublic(indutnyCurve, V); - d = keyFromPrivate(indutnyCurve, d); - const secretKey = new Uint8Array(d.getPrivate()); - const S = d.derive(V.getPublic()); - const len = indutnyCurve.curve.p.byteLength(); - const sharedKey = S.toArrayLike(Uint8Array, 'be', len); - return { secretKey, sharedKey }; -} - -/** - * Generate ECDHE ephemeral key and secret from public key using indutny/elliptic - * - * @param {CurveWithOID} curve - Elliptic curve object - * @param {Uint8Array} Q - Recipient public key - * @returns {Promise<{publicKey: Uint8Array, sharedKey: Uint8Array}>} - * @async - */ -async function ellipticPublicEphemeralKey(curve, Q) { - const indutnyCurve = await getIndutnyCurve(curve.name); - const v = await curve.genKeyPair(); - Q = keyFromPublic(indutnyCurve, Q); - const V = keyFromPrivate(indutnyCurve, v.privateKey); - const publicKey = v.publicKey; - const S = V.derive(Q.getPublic()); - const len = indutnyCurve.curve.p.byteLength(); - const sharedKey = S.toArrayLike(Uint8Array, 'be', len); - return { publicKey, sharedKey }; -} - /** * Generate ECDHE secret from private key and public part of ephemeral key using nodeCrypto * diff --git a/src/crypto/public_key/elliptic/ecdsa.js b/src/crypto/public_key/elliptic/ecdsa.js index 19412aa1..d000bf01 100644 --- a/src/crypto/public_key/elliptic/ecdsa.js +++ b/src/crypto/public_key/elliptic/ecdsa.js @@ -24,8 +24,7 @@ import enums from '../../../enums'; import util from '../../../util'; import { getRandomBytes } from '../../random'; import hash from '../../hash'; -import { CurveWithOID, webCurves, privateToJWK, rawPublicToJWK, validateStandardParams } from './oid_curves'; -import { getIndutnyCurve, keyFromPrivate, keyFromPublic } from './indutnyKey'; +import { CurveWithOID, webCurves, privateToJWK, rawPublicToJWK, validateStandardParams, getNobleCurve } from './oid_curves'; const webCrypto = util.getWebCrypto(); const nodeCrypto = util.getNodeCrypto(); @@ -74,7 +73,14 @@ export async function sign(oid, hashAlgo, message, publicKey, privateKey, hashed } } } - return ellipticSign(curve, hashed, privateKey); + + const nobleCurve = getNobleCurve(curve.name); + // lowS: non-canonical sig: https://stackoverflow.com/questions/74338846/ecdsa-signature-verification-mismatch + const signature = nobleCurve.sign(hashed, privateKey, { lowS: false }); + return { + r: signature.r.toUint8Array('be', curve.payloadSize), + s: signature.s.toUint8Array('be', curve.payloadSize) + }; } /** @@ -111,8 +117,10 @@ export async function verify(oid, hashAlgo, signature, message, publicKey, hashe return nodeVerify(curve, hashAlgo, signature, message, publicKey); } } - const digest = (typeof hashAlgo === 'undefined') ? message : hashed; - return ellipticVerify(curve, signature, digest, publicKey); + + const nobleCurve = getNobleCurve(curve.name); + // lowS: non-canonical sig: https://stackoverflow.com/questions/74338846/ecdsa-signature-verification-mismatch + return nobleCurve.verify(util.concatUint8Array([signature.r, signature.s]), hashed, publicKey, { lowS: false }); } /** @@ -156,23 +164,6 @@ export async function validateParams(oid, Q, d) { // Helper functions // // // ////////////////////////// - -async function ellipticSign(curve, hashed, privateKey) { - const indutnyCurve = await getIndutnyCurve(curve.name); - const key = keyFromPrivate(indutnyCurve, privateKey); - const signature = key.sign(hashed); - return { - r: signature.r.toArrayLike(Uint8Array), - s: signature.s.toArrayLike(Uint8Array) - }; -} - -async function ellipticVerify(curve, signature, digest, publicKey) { - const indutnyCurve = await getIndutnyCurve(curve.name); - const key = keyFromPublic(indutnyCurve, publicKey); - return key.verify(digest, signature); -} - async function webSign(curve, hashAlgo, message, keyPair) { const len = curve.payloadSize; const jwk = privateToJWK(curve.payloadSize, webCurves[curve.name], keyPair.publicKey, keyPair.privateKey); diff --git a/src/crypto/public_key/elliptic/indutnyKey.js b/src/crypto/public_key/elliptic/indutnyKey.js deleted file mode 100644 index ddfc6aa7..00000000 --- a/src/crypto/public_key/elliptic/indutnyKey.js +++ /dev/null @@ -1,44 +0,0 @@ -// OpenPGP.js - An OpenPGP implementation in javascript -// Copyright (C) 2015-2016 Decentral -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3.0 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -/** - * @fileoverview Wrapper for a KeyPair of an curve from indutny/elliptic library - * @module crypto/public_key/elliptic/indutnyKey - */ - -import config from '../../../config'; - -export function keyFromPrivate(indutnyCurve, priv) { - const keyPair = indutnyCurve.keyPair({ priv: priv }); - return keyPair; -} - -export function keyFromPublic(indutnyCurve, pub) { - const keyPair = indutnyCurve.keyPair({ pub: pub }); - if (keyPair.validate().result !== true) { - throw new Error('Invalid elliptic public key'); - } - return keyPair; -} - -export async function getIndutnyCurve(name) { - if (!config.useIndutnyElliptic) { - throw new Error('This curve is only supported in the full build of OpenPGP.js'); - } - const { default: elliptic } = await import('@openpgp/elliptic'); - return new elliptic.ec(name); -} diff --git a/src/crypto/public_key/elliptic/oid_curves.js b/src/crypto/public_key/elliptic/oid_curves.js index 4d40e25b..d6561d5a 100644 --- a/src/crypto/public_key/elliptic/oid_curves.js +++ b/src/crypto/public_key/elliptic/oid_curves.js @@ -19,37 +19,58 @@ * @fileoverview Wrapper of an instance of an Elliptic Curve * @module crypto/public_key/elliptic/curve */ -import { BigInteger } from '@openpgp/noble-hashes/biginteger'; import nacl from '@openpgp/tweetnacl/nacl-fast-light'; +import { p256 } from '@openpgp/noble-curves/p256'; +import { p384 } from '@openpgp/noble-curves/p384'; +import { p521 } from '@openpgp/noble-curves/p521'; +import { brainpoolP256r1 } from '@openpgp/noble-curves/brainpoolP256r1'; +import { brainpoolP384r1 } from '@openpgp/noble-curves/brainpoolP384r1'; +import { brainpoolP512r1 } from '@openpgp/noble-curves/brainpoolP512r1'; +import { secp256k1 } from '@openpgp/noble-curves/secp256k1'; import { getRandomBytes } from '../../random'; import enums from '../../../enums'; import util from '../../../util'; import { uint8ArrayToB64, b64ToUint8Array } from '../../../encoding/base64'; import OID from '../../../type/oid'; -import { keyFromPublic, keyFromPrivate, getIndutnyCurve } from './indutnyKey'; import { UnsupportedError } from '../../../packet/packet'; const webCrypto = util.getWebCrypto(); const nodeCrypto = util.getNodeCrypto(); const webCurves = { - 'p256': 'P-256', - 'p384': 'P-384', - 'p521': 'P-521' + [enums.curve.p256]: 'P-256', + [enums.curve.p384]: 'P-384', + [enums.curve.p521]: 'P-521' }; const knownCurves = nodeCrypto ? nodeCrypto.getCurves() : []; const nodeCurves = nodeCrypto ? { - secp256k1: knownCurves.includes('secp256k1') ? 'secp256k1' : undefined, - p256: knownCurves.includes('prime256v1') ? 'prime256v1' : undefined, - p384: knownCurves.includes('secp384r1') ? 'secp384r1' : undefined, - p521: knownCurves.includes('secp521r1') ? 'secp521r1' : undefined, - ed25519: knownCurves.includes('ED25519') ? 'ED25519' : undefined, - curve25519: knownCurves.includes('X25519') ? 'X25519' : undefined, - brainpoolP256r1: knownCurves.includes('brainpoolP256r1') ? 'brainpoolP256r1' : undefined, - brainpoolP384r1: knownCurves.includes('brainpoolP384r1') ? 'brainpoolP384r1' : undefined, - brainpoolP512r1: knownCurves.includes('brainpoolP512r1') ? 'brainpoolP512r1' : undefined + [enums.curve.secp256k1]: knownCurves.includes('secp256k1') ? 'secp256k1' : undefined, + [enums.curve.p256]: knownCurves.includes('prime256v1') ? 'prime256v1' : undefined, + [enums.curve.p384]: knownCurves.includes('secp384r1') ? 'secp384r1' : undefined, + [enums.curve.p521]: knownCurves.includes('secp521r1') ? 'secp521r1' : undefined, + [enums.curve.ed25519Legacy]: knownCurves.includes('ED25519') ? 'ED25519' : undefined, + [enums.curve.curve25519Legacy]: knownCurves.includes('X25519') ? 'X25519' : undefined, + [enums.curve.brainpoolP256r1]: knownCurves.includes('brainpoolP256r1') ? 'brainpoolP256r1' : undefined, + [enums.curve.brainpoolP384r1]: knownCurves.includes('brainpoolP384r1') ? 'brainpoolP384r1' : undefined, + [enums.curve.brainpoolP512r1]: knownCurves.includes('brainpoolP512r1') ? 'brainpoolP512r1' : undefined } : {}; +const nobleCurvess = { + [enums.curve.p256]: p256, + [enums.curve.p384]: p384, + [enums.curve.p521]: p521, + [enums.curve.secp256k1]: secp256k1, + [enums.curve.brainpoolP256r1]: brainpoolP256r1, + [enums.curve.brainpoolP384r1]: brainpoolP384r1, + [enums.curve.brainpoolP512r1]: brainpoolP512r1 +}; +export const getNobleCurve = curveName => { + const curve = nobleCurvess[curveName]; + if (!curve) throw new Error('Unsupported curve'); + return curve; +}; + + const curves = { p256: { oid: [0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07], @@ -169,14 +190,13 @@ class CurveWithOID { } async genKeyPair() { - let keyPair; switch (this.type) { case 'web': try { return await webGenKeyPair(this.name); } catch (err) { util.printDebugError('Browser did not support generating ec key ' + err.message); - break; + return jsGenKeyPair(this.name); } case 'node': return nodeGenKeyPair(this.name); @@ -185,8 +205,8 @@ class CurveWithOID { privateKey[0] = (privateKey[0] & 127) | 64; privateKey[31] &= 248; const secretKey = privateKey.slice().reverse(); - keyPair = nacl.box.keyPair.fromSecretKey(secretKey); - const publicKey = util.concatUint8Array([new Uint8Array([0x40]), keyPair.publicKey]); + const { publicKey: rawPublicKey } = nacl.box.keyPair.fromSecretKey(secretKey); + const publicKey = util.concatUint8Array([new Uint8Array([0x40]), rawPublicKey]); return { publicKey, privateKey }; } case 'ed25519Legacy': { @@ -195,26 +215,23 @@ class CurveWithOID { const publicKey = util.concatUint8Array([new Uint8Array([0x40]), keyPair.publicKey]); return { publicKey, privateKey }; } + default: { + return jsGenKeyPair(this.name); + } } - const indutnyCurve = await getIndutnyCurve(this.name); - keyPair = await indutnyCurve.genKeyPair({ - entropy: util.uint8ArrayToString(getRandomBytes(32)) - }); - return { publicKey: new Uint8Array(keyPair.getPublic('array', false)), privateKey: keyPair.getPrivate().toArrayLike(Uint8Array) }; } } -async function generate(curve) { - curve = new CurveWithOID(curve); +async function generate(curveName) { + const curve = new CurveWithOID(curveName); + const { oid, hash, cipher } = curve; const keyPair = await curve.genKeyPair(); - const Q = BigInteger.new(keyPair.publicKey).toUint8Array(); - const secret = BigInteger.new(keyPair.privateKey).toUint8Array('be', curve.payloadSize); return { - oid: curve.oid, - Q, - secret, - hash: curve.hash, - cipher: curve.cipher + oid, + Q: keyPair.publicKey, + secret: util.leftPad(keyPair.privateKey, curve.payloadSize), + hash, + cipher }; } @@ -269,20 +286,13 @@ async function validateStandardParams(algo, oid, Q, d) { return true; } - const curve = await getIndutnyCurve(curveName); - try { - // Parse Q and check that it is on the curve but not at infinity - Q = keyFromPublic(curve, Q).getPublic(); - } catch (validationErrors) { - return false; - } - - /** + const nobleCurve = getNobleCurve(enums.write(enums.curve, oid.toHex())); + /* * Re-derive public point Q' = dG from private key * Expect Q == Q' */ - const dG = keyFromPrivate(curve, d).getPublic(); - if (!dG.eq(Q)) { + const dG = nobleCurve.getPublicKey(d, false); + if (!util.equalsUint8Array(dG, Q)) { return false; } @@ -298,7 +308,12 @@ export { // Helper functions // // // ////////////////////////// - +function jsGenKeyPair(name) { + const nobleCurve = getNobleCurve(name); + const privateKey = nobleCurve.utils.randomPrivateKey(); + const publicKey = nobleCurve.getPublicKey(privateKey, false); + return { publicKey, privateKey }; +} async function webGenKeyPair(name) { // Note: keys generated with ECDSA and ECDH are structurally equivalent diff --git a/test/crypto/ecdh.js b/test/crypto/ecdh.js index 85eba9fa..c3b4536f 100644 --- a/test/crypto/ecdh.js +++ b/test/crypto/ecdh.js @@ -77,7 +77,7 @@ export default () => describe('ECDH key exchange @lightweight', function () { } expect(decrypt_message( 'secp256k1', 2, 7, [], [], [], [], [] - )).to.be.rejectedWith(Error, /Private key is not valid for specified curve|Unknown point format/).notify(done); + )).to.be.rejectedWith(Error, /Private key is not valid for specified curve|second arg must be public key/).notify(done); }); it('Invalid elliptic public key', function (done) { if (!openpgp.config.useIndutnyElliptic && !util.getNodeCrypto()) { @@ -85,7 +85,7 @@ export default () => describe('ECDH key exchange @lightweight', function () { } expect(decrypt_message( 'secp256k1', 2, 7, secp256k1_value, secp256k1_point, secp256k1_invalid_point, secp256k1_data, [] - )).to.be.rejectedWith(Error, /Public key is not valid for specified curve|Failed to translate Buffer to a EC_POINT|Invalid elliptic public key/).notify(done); + )).to.be.rejectedWith(/Public key is not valid for specified curve|Failed to translate Buffer to a EC_POINT|bad point/).notify(done); }); it('Invalid key data integrity', function (done) { if (!openpgp.config.useIndutnyElliptic && !util.getNodeCrypto()) { @@ -93,7 +93,7 @@ export default () => describe('ECDH key exchange @lightweight', function () { } expect(decrypt_message( 'secp256k1', 2, 7, secp256k1_value, secp256k1_point, secp256k1_point, secp256k1_data, [] - )).to.be.rejectedWith(Error, /Key Data Integrity failed/).notify(done); + )).to.be.rejectedWith(/Key Data Integrity failed/).notify(done); }); const Q1 = new Uint8Array([ @@ -143,9 +143,9 @@ export default () => describe('ECDH key exchange @lightweight', function () { const oid = new OID(curve.oid); const kdfParams = new KDFParams({ hash: curve.hash, cipher: curve.cipher }); const data = util.stringToUint8Array('test'); - expect( - ecdh.encrypt(oid, kdfParams, data, Q1, fingerprint1) - ).to.be.rejectedWith(Error, /Public key is not valid for specified curve|Failed to translate Buffer to a EC_POINT|Unknown point format/); + await expect( + ecdh.encrypt(oid, kdfParams, data, Q1.subarray(1), fingerprint1) + ).to.be.rejectedWith(/Public key is not valid for specified curve|Failed to translate Buffer to a EC_POINT|second arg must be public key/); }); it('Different keys', async function () { @@ -199,8 +199,9 @@ export default () => describe('ECDH key exchange @lightweight', function () { expect(await ecdhX.decrypt(openpgp.enums.publicKey.x448, ephemeralPublicKey, wrappedKey, K_B, b)).to.deep.equal(data); }); - ['p256', 'p384', 'p521'].forEach(curveName => { - it(`NIST ${curveName} - Successful exchange`, async function () { + const allCurves = ['secp256k1', 'p256', 'p384', 'p521', 'brainpoolP256r1', 'brainpoolP384r1', 'brainpoolP512r1']; + allCurves.forEach(curveName => { + it(`${curveName} - Successful exchange`, async function () { const curve = new elliptic_curves.CurveWithOID(curveName); const oid = new OID(curve.oid); const kdfParams = new KDFParams({ hash: curve.hash, cipher: curve.cipher }); @@ -236,14 +237,16 @@ export default () => describe('ECDH key exchange @lightweight', function () { getNodeCryptoStub && getNodeCryptoStub.restore(); }; - ['p256', 'p384', 'p521'].forEach(curveName => { - it(`NIST ${curveName}`, async function () { + allCurves.forEach(curveName => { + it(`${curveName}`, async function () { const nodeCrypto = util.getNodeCrypto(); const webCrypto = util.getWebCrypto(); if (!nodeCrypto && !webCrypto) { this.skip(); } + const expectNativeWeb = new Set(['p256', 'p384']); // older versions of safari do not implement p521 + const curve = new elliptic_curves.CurveWithOID(curveName); const oid = new OID(curve.oid); const kdfParams = new KDFParams({ hash: curve.hash, cipher: curve.cipher }); @@ -254,9 +257,11 @@ export default () => describe('ECDH key exchange @lightweight', function () { const nativeDecryptSpy = webCrypto ? sinonSandbox.spy(webCrypto, 'deriveBits') : sinonSandbox.spy(nodeCrypto, 'createECDH'); expect(await ecdh.decrypt(oid, kdfParams, V, C, Q, d, fingerprint1)).to.deep.equal(data); + const expectedNativeCallCount = nativeDecryptSpy.callCount; disableNative(); expect(await ecdh.decrypt(oid, kdfParams, V, C, Q, d, fingerprint1)).to.deep.equal(data); - if (curveName !== 'p521') { // safari does not implement p521 in webcrypto + expect(nativeDecryptSpy.callCount).to.equal(expectedNativeCallCount); // assert that fallback implementation was called + if (expectNativeWeb.has(curveName)) { expect(nativeDecryptSpy.calledOnce).to.be.true; } }); diff --git a/test/crypto/elliptic.js b/test/crypto/elliptic.js index 048413fd..a434c543 100644 --- a/test/crypto/elliptic.js +++ b/test/crypto/elliptic.js @@ -122,6 +122,21 @@ export default () => describe('Elliptic Curve Cryptography @lightweight', functi getNodeCryptoStub && getNodeCryptoStub.restore(); }; + const testNativeAndFallback = async fn => { + const webCrypto = util.getWebCrypto(); + const nodeCrypto = util.getNodeCrypto(); + const nativeSpy = webCrypto ? sinonSandbox.spy(webCrypto, 'importKey') : sinonSandbox.spy(nodeCrypto, 'createVerify'); // spy on function used on verification, since that's used by all tests calling `testNativeAndFallback` + + // if native not available, fallback will be tested twice (not possible to automatically check native algo availability) + enableNative(); + await fn(); + const expectedNativeCallCount = nativeSpy.callCount; + disableNative(); + await fn(); + expect(nativeSpy.callCount).to.equal(expectedNativeCallCount); + enableNative(); + }; + const verify_signature = async function (oid, hash, r, s, message, pub) { if (util.isString(message)) { message = util.stringToUint8Array(message); @@ -162,99 +177,81 @@ export default () => describe('Elliptic Curve Cryptography @lightweight', functi 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]); - it('Invalid curve oid', function () { - return Promise.all([ - expect(verify_signature( - 'invalid oid', 8, [], [], [], [] - )).to.be.rejectedWith(Error, /Unknown curve/), - expect(verify_signature( - '\x00', 8, [], [], [], [] - )).to.be.rejectedWith(Error, /Unknown curve/) - ]); + it('Invalid curve oid', async function () { + await expect(verify_signature( + 'invalid oid', 8, [], [], [], [] + )).to.be.rejectedWith(Error, /Unknown curve/); + await expect(verify_signature( + '\x00', 8, [], [], [], [] + )).to.be.rejectedWith(Error, /Unknown curve/); }); - it('Invalid public key', async function () { + it('secp256k1 - Invalid public key', async function () { if (!config.useIndutnyElliptic && !util.getNodeCrypto()) { - this.skip(); // webcrypto does not implement secp256k1 - } - if (util.getNodeCrypto()) { - await expect(verify_signature( - 'secp256k1', 8, [], [], [], [] - )).to.eventually.be.false; - await expect(verify_signature( - 'secp256k1', 8, [], [], [], secp256k1_invalid_point_format - )).to.eventually.be.false; - } - if (config.useIndutnyElliptic) { - disableNative(); - await expect(verify_signature( - 'secp256k1', 8, [], [], [], [] - )).to.be.rejectedWith(Error, /Unknown point format/); - await expect(verify_signature( - 'secp256k1', 8, [], [], [], secp256k1_invalid_point_format - )).to.be.rejectedWith(Error, /Unknown point format/); + this.skip(); // webcrypto does not implement secp256k1: JS fallback tested instead } + await expect(verify_signature( + 'secp256k1', 8, [], [], [], [] + )).to.eventually.be.false; + await expect(verify_signature( + 'secp256k1', 8, [], [], [], secp256k1_invalid_point_format + )).to.eventually.be.false; }); - it('Invalid point', async function () { + it('secp256k1 - Invalid point', async function () { if (!config.useIndutnyElliptic && !util.getNodeCrypto()) { - this.skip(); - } - if (util.getNodeCrypto()) { - await expect(verify_signature( - 'secp256k1', 8, [], [], [], secp256k1_invalid_point - )).to.eventually.be.false; - } - if (config.useIndutnyElliptic) { - disableNative(); - await expect(verify_signature( - 'secp256k1', 8, [], [], [], secp256k1_invalid_point - )).to.be.rejectedWith(Error, /Invalid elliptic public key/); + this.skip(); // webcrypto does not implement secp256k1: JS fallback tested instead } + await expect(verify_signature( + 'secp256k1', 8, [], [], [], secp256k1_invalid_point + )).to.eventually.be.false; }); - it('Invalid signature', function (done) { + it('secp256k1 - Invalid signature', function (done) { if (!config.useIndutnyElliptic && !util.getNodeCrypto()) { - this.skip(); + this.skip(); // webcrypto does not implement secp256k1: JS fallback tested instead } expect(verify_signature( 'secp256k1', 8, [], [], [], secp256k1_point )).to.eventually.be.false.notify(done); }); - const p384_message = new Uint8Array([ - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF - ]); - const p384_r = new Uint8Array([ - 0x9D, 0x07, 0xCA, 0xA5, 0x9F, 0xBE, 0xB8, 0x76, - 0xA9, 0xB9, 0x66, 0x0F, 0xA0, 0x64, 0x70, 0x5D, - 0xE6, 0x37, 0x40, 0x43, 0xD0, 0x8E, 0x40, 0xA8, - 0x8B, 0x37, 0x83, 0xE7, 0xBC, 0x1C, 0x4C, 0x86, - 0xCB, 0x3C, 0xD5, 0x9B, 0x68, 0xF0, 0x65, 0xEB, - 0x3A, 0xB6, 0xD6, 0xA6, 0xCF, 0x85, 0x3D, 0xA9 - ]); - const p384_s = new Uint8Array([ - 0x32, 0x85, 0x78, 0xCC, 0xEA, 0xC5, 0x22, 0x83, - 0x10, 0x73, 0x1C, 0xCF, 0x10, 0x8A, 0x52, 0x11, - 0x8E, 0x49, 0x9E, 0xCF, 0x7E, 0x17, 0x18, 0xC3, - 0x11, 0x11, 0xBC, 0x0F, 0x6D, 0x98, 0xE2, 0x16, - 0x68, 0x58, 0x23, 0x1D, 0x11, 0xEF, 0x3D, 0x21, - 0x30, 0x75, 0x24, 0x39, 0x48, 0x89, 0x03, 0xDC - ]); - it('Valid signature', function (done) { - expect(verify_signature('p384', 8, p384_r, p384_s, p384_message, key_data.p384.pub)) - .to.eventually.be.true.notify(done); + it('P-384 - Valid signature', async function () { + const p384_r = new Uint8Array([ + 0x9D, 0x07, 0xCA, 0xA5, 0x9F, 0xBE, 0xB8, 0x76, + 0xA9, 0xB9, 0x66, 0x0F, 0xA0, 0x64, 0x70, 0x5D, + 0xE6, 0x37, 0x40, 0x43, 0xD0, 0x8E, 0x40, 0xA8, + 0x8B, 0x37, 0x83, 0xE7, 0xBC, 0x1C, 0x4C, 0x86, + 0xCB, 0x3C, 0xD5, 0x9B, 0x68, 0xF0, 0x65, 0xEB, + 0x3A, 0xB6, 0xD6, 0xA6, 0xCF, 0x85, 0x3D, 0xA9 + ]); + const p384_s = new Uint8Array([ + 0x32, 0x85, 0x78, 0xCC, 0xEA, 0xC5, 0x22, 0x83, + 0x10, 0x73, 0x1C, 0xCF, 0x10, 0x8A, 0x52, 0x11, + 0x8E, 0x49, 0x9E, 0xCF, 0x7E, 0x17, 0x18, 0xC3, + 0x11, 0x11, 0xBC, 0x0F, 0x6D, 0x98, 0xE2, 0x16, + 0x68, 0x58, 0x23, 0x1D, 0x11, 0xEF, 0x3D, 0x21, + 0x30, 0x75, 0x24, 0x39, 0x48, 0x89, 0x03, 0xDC + ]); + const p384_message = new Uint8Array([ + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF + ]); + + await testNativeAndFallback( + () => expect(verify_signature('p384', 8, p384_r, p384_s, p384_message, key_data.p384.pub)).to.eventually.be.true + ); }); - it('Sign and verify message', function () { - const curve = new elliptic_curves.CurveWithOID('p521'); - return curve.genKeyPair().then(async keyPair => { - const keyPublic = new Uint8Array(keyPair.publicKey); - const keyPrivate = new Uint8Array(keyPair.privateKey); - const oid = curve.oid; - const message = p384_message; - return elliptic_curves.ecdsa.sign(oid, 10, message, keyPublic, keyPrivate, await hashMod.digest(10, message)).then(async signature => { - await expect(elliptic_curves.ecdsa.verify(oid, 10, signature, message, keyPublic, await hashMod.digest(10, message))) - .to.eventually.be.true; - }); + const curves = ['secp256k1' , 'p256', 'p384', 'p521', 'brainpoolP256r1', 'brainpoolP384r1', 'brainpoolP512r1']; + curves.forEach(curveName => it(`${curveName} - Sign and verify message`, async function () { + const curve = new elliptic_curves.CurveWithOID(curveName); + const { publicKey: keyPublic, privateKey: keyPrivate } = await curve.genKeyPair(); + const message = new Uint8Array([ + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF + ]); + const messageDigest = await hashMod.digest(openpgp.enums.hash.sha512, message); + await testNativeAndFallback(async () => { + const signature = await elliptic_curves.ecdsa.sign(curve.oid, openpgp.enums.hash.sha512, message, keyPublic, keyPrivate, messageDigest); + await expect(elliptic_curves.ecdsa.verify(curve.oid, openpgp.enums.hash.sha512, signature, message, keyPublic, messageDigest)).to.eventually.be.true; }); - }); + })); }); }); diff --git a/test/crypto/elliptic_data.js b/test/crypto/elliptic_data.js index 61eba7d9..1fbc64d0 100644 --- a/test/crypto/elliptic_data.js +++ b/test/crypto/elliptic_data.js @@ -1,3 +1,5 @@ +import util from '../../src/util.js'; + const elliptic_data = { key_data: { p256: { @@ -95,6 +97,18 @@ const elliptic_data = { 0xB8, 0xFD, 0x0B, 0xDF, 0x76, 0xCE, 0xBC, 0x95, 0x4B, 0x92, 0x26, 0xFC, 0xAA, 0x7A, 0x7C, 0x3F ]) + }, + brainpoolP256r1: { + priv: util.hexToUint8Array('8b426897130e1e5e70a4d6320c4002bb1642a5e57ade066e060464137dfd5e05'), + pub: util.hexToUint8Array('042a43d8cc20e5a3fbd75d3a5a9b17d867bba80f11334d0665f0c641d13460a52aa3373a4ccfaa7d76765a689bd9fe15a4fd107ef1ec9ac980234c31647170c81a') + }, + brainpoolP384r1: { + priv: util.hexToUint8Array('7ccc97acdf4b775606c5c994a37a8b28086167046ac0d55664ede4097d8de79dec56e69dfff5776d53fcbd2147bbae9f'), + pub: util.hexToUint8Array('043809fa0c74ec9817cb73eba67db71e01663528fb9fbe6a123f8339346c37efc9ff7cd116074a80684448e44ee9204c795c88ad634ad272585c0b4e3093b11e6c99a6c0ca9c278f83ef57e2ed802502aee76f4529bcb873eef754bec894a5032f') + }, + brainpoolP512r1: { + priv: util.hexToUint8Array('0a32459d1ecf8815397a66f6cdb18692c6f79a3c6059b4c344d0162416c7603a82a9a938568edafb132c7433ffeeab4cf201d9542209eb28070bea56ab6b8938'), + pub: util.hexToUint8Array('040f64473d9b3597752e3a87095c0b219dd85f56a79c3b2dc8fb2b0c95b60f4be45c41a8a7ea31d60e15fea6275eb7db93856bc2eb30cc8876513335d43812bd2c4e195e05679ac667a2f7fb05c5842779d18fa411500e43e2f291ea8348f061db15382d4db1cfcf106a29f46e1c00e7d63e635c51293f69c0dd4f6a61da589b2a') } } }; diff --git a/test/general/brainpool.js b/test/general/brainpool.js index e22dae58..903e4a66 100644 --- a/test/general/brainpool.js +++ b/test/general/brainpool.js @@ -256,10 +256,6 @@ EJ4QcD/oQ6x1M/8X/iKQCtxZP8RnlrbH7ExkNON5s5g= expect(await result.signatures[0].verified).to.be.true; }); it('Decrypt and verify message with leading zero in hash signed with old elliptic algorithm', async function () { - //this test would not work with nodeCrypto, since message is signed with leading zero stripped from the hash - if (util.getNodeCrypto()) { - this.skip(); // eslint-disable-line no-invalid-this - } const juliet = await load_priv_key('juliet'); const romeo = await load_pub_key('romeo'); const msg = await openpgp.readMessage({ armoredMessage: data.romeo.message_encrypted_with_leading_zero_in_hash_signed_by_elliptic_with_old_implementation }); From 909d44f43687d10bcc89506c6e24b0a4eecee81b Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Fri, 6 Oct 2023 17:21:50 +0200 Subject: [PATCH 074/201] Add back support for verification of some invalid ECDSA sigs affected by old lib bug At some point we used to generate invalid ECDSA sigs with the js (non-native) elliptic lib, if the signature digest had leading zeros: https://github.com/openpgpjs/openpgpjs/pull/948 . Brainpool curves are the most likely to have been affected by the bug, since they do not have WebCrypto support (unlike NIST curves). This commit reintroduces support on web to verify such invalid signatures (support for this was previously built-in in the indutny-elliptic library). It also expands the fix to work in Node. --- src/crypto/public_key/elliptic/ecdsa.js | 37 +++++++++++++++++++++---- 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/src/crypto/public_key/elliptic/ecdsa.js b/src/crypto/public_key/elliptic/ecdsa.js index d000bf01..33f22232 100644 --- a/src/crypto/public_key/elliptic/ecdsa.js +++ b/src/crypto/public_key/elliptic/ecdsa.js @@ -97,12 +97,25 @@ export async function sign(oid, hashAlgo, message, publicKey, privateKey, hashed */ export async function verify(oid, hashAlgo, signature, message, publicKey, hashed) { const curve = new CurveWithOID(oid); + // See https://github.com/openpgpjs/openpgpjs/pull/948. + // NB: the impact was more likely limited to Brainpool curves, since thanks + // to WebCrypto availability, NIST curve should not have been affected. + // Similarly, secp256k1 should have been used rarely enough. + // However, we implement the fix for all curves, since it's only needed in case of + // verification failure, which is unexpected, hence a minor slowdown is acceptable. + const tryFallbackVerificationForOldBug = () => ( + hashed[0] === 0 ? + jsVerify(curve, signature, hashed.subarray(1), publicKey) : + false + ); + if (message && !util.isStream(message)) { switch (curve.type) { case 'web': try { // Need to await to make sure browser succeeds - return await webVerify(curve, hashAlgo, signature, message, publicKey); + const verified = await webVerify(curve, hashAlgo, signature, message, publicKey); + return verified || tryFallbackVerificationForOldBug(); } catch (err) { // We do not fallback if the error is related to key integrity // Unfortunately Safari does not support p521 and throws a DataError when using it @@ -113,14 +126,15 @@ export async function verify(oid, hashAlgo, signature, message, publicKey, hashe util.printDebugError('Browser did not support verifying: ' + err.message); } break; - case 'node': - return nodeVerify(curve, hashAlgo, signature, message, publicKey); + case 'node': { + const verified = await nodeVerify(curve, hashAlgo, signature, message, publicKey); + return verified || tryFallbackVerificationForOldBug(); + } } } - const nobleCurve = getNobleCurve(curve.name); - // lowS: non-canonical sig: https://stackoverflow.com/questions/74338846/ecdsa-signature-verification-mismatch - return nobleCurve.verify(util.concatUint8Array([signature.r, signature.s]), hashed, publicKey, { lowS: false }); + const verified = jsVerify(curve, signature, hashed, publicKey); + return verified || tryFallbackVerificationForOldBug(); } /** @@ -164,6 +178,17 @@ export async function validateParams(oid, Q, d) { // Helper functions // // // ////////////////////////// + +/** + * Fallback javascript implementation of ECDSA verification. + * To be used if no native implementation is available for the given curve/operation. + */ +function jsVerify(curve, signature, hashed, publicKey) { + const nobleCurve = getNobleCurve(curve.name); + // lowS: non-canonical sig: https://stackoverflow.com/questions/74338846/ecdsa-signature-verification-mismatch + return nobleCurve.verify(util.concatUint8Array([signature.r, signature.s]), hashed, publicKey, { lowS: false }); +} + async function webSign(curve, hashAlgo, message, keyPair) { const len = curve.payloadSize; const jwk = privateToJWK(curve.payloadSize, webCurves[curve.name], keyPair.publicKey, keyPair.privateKey); From 7295a2e7b34d4990a2b6b839d5ae9ab5a825e078 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Fri, 6 Oct 2023 17:23:55 +0200 Subject: [PATCH 075/201] Rename `config.useIndutnyElliptic` to `.useEllipticFallback` To reflect change of underlying library --- openpgp.d.ts | 2 +- src/config/config.js | 7 +++---- src/crypto/public_key/elliptic/oid_curves.js | 5 +++++ test/crypto/ecdh.js | 8 ++++---- test/crypto/elliptic.js | 10 +++++----- test/general/brainpool.js | 4 ++-- test/general/ecc_secp256k1.js | 2 +- 7 files changed, 21 insertions(+), 17 deletions(-) diff --git a/openpgp.d.ts b/openpgp.d.ts index 3082030f..d50d8a49 100644 --- a/openpgp.d.ts +++ b/openpgp.d.ts @@ -336,7 +336,7 @@ interface Config { s2kArgon2Params: { passes: number, parallelism: number; memoryExponent: number; }; maxUserIDLength: number; knownNotations: string[]; - useIndutnyElliptic: boolean; + useEllipticFallback: boolean; rejectHashAlgorithms: Set; rejectMessageHashAlgorithms: Set; rejectPublicKeyAlgorithms: Set; diff --git a/src/config/config.js b/src/config/config.js index e448cbda..c03c0cad 100644 --- a/src/config/config.js +++ b/src/config/config.js @@ -246,13 +246,12 @@ export default { */ knownNotations: [], /** - * Whether to use the indutny/elliptic library for curves (other than Curve25519) that are not supported by the available native crypto API. + * Whether to use the the noble-curves library for curves (other than Curve25519) that are not supported by the available native crypto API. * When false, certain standard curves will not be supported (depending on the platform). - * Note: the indutny/elliptic curve library is not designed to be constant time. * @memberof module:config - * @property {Boolean} useIndutnyElliptic + * @property {Boolean} useEllipticFallback */ - useIndutnyElliptic: true, + useEllipticFallback: true, /** * Reject insecure hash algorithms * @memberof module:config diff --git a/src/crypto/public_key/elliptic/oid_curves.js b/src/crypto/public_key/elliptic/oid_curves.js index d6561d5a..0ad88cba 100644 --- a/src/crypto/public_key/elliptic/oid_curves.js +++ b/src/crypto/public_key/elliptic/oid_curves.js @@ -33,6 +33,7 @@ import util from '../../../util'; import { uint8ArrayToB64, b64ToUint8Array } from '../../../encoding/base64'; import OID from '../../../type/oid'; import { UnsupportedError } from '../../../packet/packet'; +import defaultConfig from '../../../config'; const webCrypto = util.getWebCrypto(); const nodeCrypto = util.getNodeCrypto(); @@ -65,6 +66,10 @@ const nobleCurvess = { [enums.curve.brainpoolP512r1]: brainpoolP512r1 }; export const getNobleCurve = curveName => { + if (!defaultConfig.useEllipticFallback) { + // TODO make import dynamic + throw new Error('This curve is only supported in the full build of OpenPGP.js'); + } const curve = nobleCurvess[curveName]; if (!curve) throw new Error('Unsupported curve'); return curve; diff --git a/test/crypto/ecdh.js b/test/crypto/ecdh.js index c3b4536f..8b4c7a82 100644 --- a/test/crypto/ecdh.js +++ b/test/crypto/ecdh.js @@ -72,7 +72,7 @@ export default () => describe('ECDH key exchange @lightweight', function () { )).to.be.rejectedWith(Error, /Unknown curve/).notify(done); }); it('Invalid ephemeral key', function (done) { - if (!openpgp.config.useIndutnyElliptic && !util.getNodeCrypto()) { + if (!openpgp.config.useEllipticFallback && !util.getNodeCrypto()) { this.skip(); } expect(decrypt_message( @@ -80,7 +80,7 @@ export default () => describe('ECDH key exchange @lightweight', function () { )).to.be.rejectedWith(Error, /Private key is not valid for specified curve|second arg must be public key/).notify(done); }); it('Invalid elliptic public key', function (done) { - if (!openpgp.config.useIndutnyElliptic && !util.getNodeCrypto()) { + if (!openpgp.config.useEllipticFallback && !util.getNodeCrypto()) { this.skip(); } expect(decrypt_message( @@ -88,7 +88,7 @@ export default () => describe('ECDH key exchange @lightweight', function () { )).to.be.rejectedWith(/Public key is not valid for specified curve|Failed to translate Buffer to a EC_POINT|bad point/).notify(done); }); it('Invalid key data integrity', function (done) { - if (!openpgp.config.useIndutnyElliptic && !util.getNodeCrypto()) { + if (!openpgp.config.useEllipticFallback && !util.getNodeCrypto()) { this.skip(); } expect(decrypt_message( @@ -136,7 +136,7 @@ export default () => describe('ECDH key exchange @lightweight', function () { const ecdh = elliptic_curves.ecdh; it('Invalid curve', async function () { - if (!openpgp.config.useIndutnyElliptic && !util.getNodeCrypto()) { + if (!openpgp.config.useEllipticFallback && !util.getNodeCrypto()) { this.skip(); } const curve = new elliptic_curves.CurveWithOID('secp256k1'); diff --git a/test/crypto/elliptic.js b/test/crypto/elliptic.js index a434c543..c755524e 100644 --- a/test/crypto/elliptic.js +++ b/test/crypto/elliptic.js @@ -68,10 +68,10 @@ export default () => describe('Elliptic Curve Cryptography @lightweight', functi done(); }); it('Creating KeyPair', function () { - if (!config.useIndutnyElliptic && !util.getNodeCrypto()) { + if (!config.useEllipticFallback && !util.getNodeCrypto()) { this.skip(); } - const names = config.useIndutnyElliptic ? ['p256', 'p384', 'p521', 'secp256k1', 'curve25519Legacy', 'brainpoolP256r1', 'brainpoolP384r1', 'brainpoolP512r1'] : + const names = config.useEllipticFallback ? ['p256', 'p384', 'p521', 'secp256k1', 'curve25519Legacy', 'brainpoolP256r1', 'brainpoolP384r1', 'brainpoolP512r1'] : ['p256', 'p384', 'p521', 'curve25519Legacy']; return Promise.all(names.map(function (name) { const curve = new elliptic_curves.CurveWithOID(name); @@ -186,7 +186,7 @@ export default () => describe('Elliptic Curve Cryptography @lightweight', functi )).to.be.rejectedWith(Error, /Unknown curve/); }); it('secp256k1 - Invalid public key', async function () { - if (!config.useIndutnyElliptic && !util.getNodeCrypto()) { + if (!config.useEllipticFallback && !util.getNodeCrypto()) { this.skip(); // webcrypto does not implement secp256k1: JS fallback tested instead } await expect(verify_signature( @@ -197,7 +197,7 @@ export default () => describe('Elliptic Curve Cryptography @lightweight', functi )).to.eventually.be.false; }); it('secp256k1 - Invalid point', async function () { - if (!config.useIndutnyElliptic && !util.getNodeCrypto()) { + if (!config.useEllipticFallback && !util.getNodeCrypto()) { this.skip(); // webcrypto does not implement secp256k1: JS fallback tested instead } await expect(verify_signature( @@ -205,7 +205,7 @@ export default () => describe('Elliptic Curve Cryptography @lightweight', functi )).to.eventually.be.false; }); it('secp256k1 - Invalid signature', function (done) { - if (!config.useIndutnyElliptic && !util.getNodeCrypto()) { + if (!config.useEllipticFallback && !util.getNodeCrypto()) { this.skip(); // webcrypto does not implement secp256k1: JS fallback tested instead } expect(verify_signature( diff --git a/test/general/brainpool.js b/test/general/brainpool.js index 903e4a66..1cd3f78f 100644 --- a/test/general/brainpool.js +++ b/test/general/brainpool.js @@ -13,7 +13,7 @@ export default () => (openpgp.config.ci ? describe.skip : describe)('Brainpool C let rejectCurvesVal; before(function() { //only x25519 crypto is fully functional in lightbuild - if (!openpgp.config.useIndutnyElliptic && !util.getNodeCrypto()) { + if (!openpgp.config.useEllipticFallback && !util.getNodeCrypto()) { this.skip(); // eslint-disable-line no-invalid-this } }); @@ -283,7 +283,7 @@ EJ4QcD/oQ6x1M/8X/iKQCtxZP8RnlrbH7ExkNON5s5g= }); tryTests('Brainpool Omnibus Tests @lightweight', omnibus, { - if: openpgp.config.useIndutnyElliptic || util.getNodeCrypto() + if: openpgp.config.useEllipticFallback || util.getNodeCrypto() }); }); diff --git a/test/general/ecc_secp256k1.js b/test/general/ecc_secp256k1.js index da457640..8b4674d8 100644 --- a/test/general/ecc_secp256k1.js +++ b/test/general/ecc_secp256k1.js @@ -6,7 +6,7 @@ import openpgp from '../initOpenpgp.js'; import util from '../../src/util.js'; export default () => describe('Elliptic Curve Cryptography for secp256k1 curve @lightweight', function () { - if (!openpgp.config.useIndutnyElliptic && !util.getNodeCrypto()) { + if (!openpgp.config.useEllipticFallback && !util.getNodeCrypto()) { before(function() { this.skip(); // eslint-disable-line no-invalid-this }); From a56a4a16e8c07a0a67209b4ae610c5c102b37210 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Thu, 12 Oct 2023 13:56:02 +0200 Subject: [PATCH 076/201] Use internal tweetnacl SHA-512 implementation Instead of relying on externally provided one (no async loading supported) --- package-lock.json | 14 +++++++------- package.json | 2 +- src/crypto/public_key/elliptic/ecdh.js | 2 +- src/crypto/public_key/elliptic/ecdh_x.js | 2 +- src/crypto/public_key/elliptic/eddsa.js | 2 +- src/crypto/public_key/elliptic/eddsa_legacy.js | 5 +---- src/crypto/public_key/elliptic/oid_curves.js | 2 +- src/crypto/public_key/index.js | 5 +---- 8 files changed, 14 insertions(+), 20 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0c0cc051..8c3b047c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,7 @@ "@openpgp/noble-curves": "^1.2.1-0", "@openpgp/noble-hashes": "^1.3.3-0", "@openpgp/seek-bzip": "^1.0.5-git", - "@openpgp/tweetnacl": "^1.0.3", + "@openpgp/tweetnacl": "^1.0.4-1", "@openpgp/web-stream-tools": "^0.0.14", "@rollup/plugin-alias": "^5.0.0", "@rollup/plugin-commonjs": "^24.0.1", @@ -663,9 +663,9 @@ } }, "node_modules/@openpgp/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@openpgp/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-KGXNhU/mRg+uTsLGva55V340jwbX2pC8LndjOVI2oQ8vewPVTS2KnDOIXQ8O6KyT/c9Qy16KUQ5mwewe72m1Yw==", + "version": "1.0.4-1", + "resolved": "https://registry.npmjs.org/@openpgp/tweetnacl/-/tweetnacl-1.0.4-1.tgz", + "integrity": "sha512-coYo04Op1+g4h6yE6q0GglGdvWkdfvpQWKmR9nDIrW+LqdTtwHFXIyIQGs5cosR4tCajxRn9aF/+WK207zxFrg==", "dev": true }, "node_modules/@openpgp/web-stream-tools": { @@ -8010,9 +8010,9 @@ } }, "@openpgp/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@openpgp/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-KGXNhU/mRg+uTsLGva55V340jwbX2pC8LndjOVI2oQ8vewPVTS2KnDOIXQ8O6KyT/c9Qy16KUQ5mwewe72m1Yw==", + "version": "1.0.4-1", + "resolved": "https://registry.npmjs.org/@openpgp/tweetnacl/-/tweetnacl-1.0.4-1.tgz", + "integrity": "sha512-coYo04Op1+g4h6yE6q0GglGdvWkdfvpQWKmR9nDIrW+LqdTtwHFXIyIQGs5cosR4tCajxRn9aF/+WK207zxFrg==", "dev": true }, "@openpgp/web-stream-tools": { diff --git a/package.json b/package.json index 90cd6346..f1bf3b30 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "@openpgp/jsdoc": "^3.6.11", "@openpgp/noble-hashes": "^1.3.3-0", "@openpgp/seek-bzip": "^1.0.5-git", - "@openpgp/tweetnacl": "^1.0.3", + "@openpgp/tweetnacl": "^1.0.4-1", "@openpgp/web-stream-tools": "^0.0.14", "@rollup/plugin-alias": "^5.0.0", "@rollup/plugin-commonjs": "^24.0.1", diff --git a/src/crypto/public_key/elliptic/ecdh.js b/src/crypto/public_key/elliptic/ecdh.js index ed370578..9039833a 100644 --- a/src/crypto/public_key/elliptic/ecdh.js +++ b/src/crypto/public_key/elliptic/ecdh.js @@ -20,7 +20,7 @@ * @module crypto/public_key/elliptic/ecdh */ -import nacl from '@openpgp/tweetnacl/nacl-fast-light'; +import nacl from '@openpgp/tweetnacl'; import { CurveWithOID, jwkToRawPublic, rawPublicToJWK, privateToJWK, validateStandardParams, getNobleCurve } from './oid_curves'; import * as aesKW from '../../aes_kw'; import { getRandomBytes } from '../../random'; diff --git a/src/crypto/public_key/elliptic/ecdh_x.js b/src/crypto/public_key/elliptic/ecdh_x.js index decdeaab..2d9ffe3e 100644 --- a/src/crypto/public_key/elliptic/ecdh_x.js +++ b/src/crypto/public_key/elliptic/ecdh_x.js @@ -3,7 +3,7 @@ * @module crypto/public_key/elliptic/ecdh */ -import x25519 from '@openpgp/tweetnacl/nacl-fast-light'; +import x25519 from '@openpgp/tweetnacl'; import { x448 } from '@openpgp/noble-curves/ed448'; import * as aesKW from '../../aes_kw'; import { getRandomBytes } from '../../random'; diff --git a/src/crypto/public_key/elliptic/eddsa.js b/src/crypto/public_key/elliptic/eddsa.js index 8b08a671..28c33f0c 100644 --- a/src/crypto/public_key/elliptic/eddsa.js +++ b/src/crypto/public_key/elliptic/eddsa.js @@ -21,7 +21,7 @@ */ import { sha512 } from '@openpgp/noble-hashes/sha512'; -import ed25519 from '@openpgp/tweetnacl/nacl-fast-light'; +import ed25519 from '@openpgp/tweetnacl'; import { ed448 } from '@openpgp/noble-curves/ed448'; import util from '../../../util'; import enums from '../../../enums'; diff --git a/src/crypto/public_key/elliptic/eddsa_legacy.js b/src/crypto/public_key/elliptic/eddsa_legacy.js index d90e0f9c..966f8dbe 100644 --- a/src/crypto/public_key/elliptic/eddsa_legacy.js +++ b/src/crypto/public_key/elliptic/eddsa_legacy.js @@ -21,14 +21,11 @@ * @module crypto/public_key/elliptic/eddsa_legacy */ -import { sha512 } from '@openpgp/noble-hashes/sha512'; -import nacl from '@openpgp/tweetnacl/nacl-fast-light'; +import nacl from '@openpgp/tweetnacl'; import util from '../../../util'; import enums from '../../../enums'; import hash from '../../hash'; -nacl.hash = bytes => sha512(bytes); - /** * Sign a message using the provided legacy EdDSA key * @param {module:type/oid} oid - Elliptic curve object identifier diff --git a/src/crypto/public_key/elliptic/oid_curves.js b/src/crypto/public_key/elliptic/oid_curves.js index 0ad88cba..f5716d02 100644 --- a/src/crypto/public_key/elliptic/oid_curves.js +++ b/src/crypto/public_key/elliptic/oid_curves.js @@ -19,7 +19,7 @@ * @fileoverview Wrapper of an instance of an Elliptic Curve * @module crypto/public_key/elliptic/curve */ -import nacl from '@openpgp/tweetnacl/nacl-fast-light'; +import nacl from '@openpgp/tweetnacl'; import { p256 } from '@openpgp/noble-curves/p256'; import { p384 } from '@openpgp/noble-curves/p384'; import { p521 } from '@openpgp/noble-curves/p521'; diff --git a/src/crypto/public_key/index.js b/src/crypto/public_key/index.js index ac34ab76..ffcf73cc 100644 --- a/src/crypto/public_key/index.js +++ b/src/crypto/public_key/index.js @@ -3,7 +3,6 @@ * @module crypto/public_key */ -import nacl from '@openpgp/tweetnacl/nacl-fast-light'; import * as rsa from './rsa'; import * as elgamal from './elgamal'; import * as elliptic from './elliptic'; @@ -17,7 +16,5 @@ export default { /** @see module:crypto/public_key/elliptic */ elliptic: elliptic, /** @see module:crypto/public_key/dsa */ - dsa: dsa, - /** @see tweetnacl */ - nacl: nacl + dsa: dsa }; From 545621126647e4dc67a13393686e8792136a9ba3 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Wed, 18 Oct 2023 16:51:18 +0200 Subject: [PATCH 077/201] Simplify userID parsing based on conventions, drop third-party parsing lib Follow conventions as per https://datatracker.ietf.org/doc/draft-dkg-openpgp-userid-conventions --- package-lock.json | 13 ---------- package.json | 1 - src/packet/userid.js | 29 ++++++++++++++++------ test/general/packet.js | 56 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 77 insertions(+), 22 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8c3b047c..bff38d5e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,7 +31,6 @@ "bn.js": "^4.11.8", "chai": "^4.3.7", "chai-as-promised": "^7.1.1", - "email-addresses": "3.1.0", "eslint": "^8.34.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-base": "^15.0.0", @@ -2103,12 +2102,6 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", "dev": true }, - "node_modules/email-addresses": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-3.1.0.tgz", - "integrity": "sha512-k0/r7GrWVL32kZlGwfPNgB2Y/mMXVTq/decgLczm/j34whdaspNrZO8CnXPf1laaHxI6ptUlsnAxN+UAPw+fzg==", - "dev": true - }, "node_modules/emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", @@ -9131,12 +9124,6 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", "dev": true }, - "email-addresses": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-3.1.0.tgz", - "integrity": "sha512-k0/r7GrWVL32kZlGwfPNgB2Y/mMXVTq/decgLczm/j34whdaspNrZO8CnXPf1laaHxI6ptUlsnAxN+UAPw+fzg==", - "dev": true - }, "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", diff --git a/package.json b/package.json index f1bf3b30..5befcbc0 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,6 @@ "bn.js": "^4.11.8", "chai": "^4.3.7", "chai-as-promised": "^7.1.1", - "email-addresses": "3.1.0", "eslint": "^8.34.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-base": "^15.0.0", diff --git a/src/packet/userid.js b/src/packet/userid.js index 4c89fecc..4a092d8c 100644 --- a/src/packet/userid.js +++ b/src/packet/userid.js @@ -15,8 +15,6 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -import emailAddresses from 'email-addresses'; - import enums from '../enums'; import util from '../util'; import defaultConfig from '../config'; @@ -79,12 +77,27 @@ class UserIDPacket { if (userID.length > config.maxUserIDLength) { throw new Error('User ID string is too long'); } - try { - const { name, address: email, comments } = emailAddresses.parseOneAddress({ input: userID, atInDisplayName: true }); - this.comment = comments.replace(/^\(|\)$/g, ''); - this.name = name; - this.email = email; - } catch (e) {} + + /** + * We support the conventional cases described in https://www.ietf.org/id/draft-dkg-openpgp-userid-conventions-00.html#section-4.1, + * as well comments placed between the name (if present) and the bracketed email address: + * - name (comment) + * - email + * In the first case, the `email` is the only required part, and it must contain the `@` symbol. + * The `name` and `comment` parts can include any letters, whitespace, and symbols, except for `(` and `)`, + * since they interfere with `comment` parsing. + */ + const re = /^(?[^()]+\s+)?(?\([^()]+\)\s+)?(?<\S+@\S+>)$/; + const matches = re.exec(userID); + if (matches !== null) { + const { name, comment, email } = matches.groups; + this.comment = comment?.replace(/^\(|\)|\s$/g, '').trim() || ''; // remove parenthesis and separating whiltespace + this.name = name?.trim() || ''; + this.email = email.substring(1, email.length - 1); // remove brackets + } else if (/^[^\s@]+@[^\s@]+$/.test(userID)) { // unbracketed email: enforce single @ and no whitespace + this.email = userID; + } + this.userID = userID; } diff --git a/test/general/packet.js b/test/general/packet.js index f3a4e9b7..0cf26d7b 100644 --- a/test/general/packet.js +++ b/test/general/packet.js @@ -1565,4 +1565,60 @@ kePFjAnu9cpynKXu3usf8+FuBw2zLsg1Id1n7ttxoAte416KjBN9lFBt8mcu expect(otherPackets[0].constructor.tag).to.equal(openpgp.enums.packet.userID); }); }); + + describe('UserID', () => { + it('parse conventional userID', () => { + const userID = 'Mr. Ed, the Talking Horse '; + + const packet = new openpgp.UserIDPacket(); + packet.read(new TextEncoder().encode(userID)); + expect(packet.comment).to.equal(''); + expect(packet.email).to.equal('ed@example.org'); + expect(packet.userID).to.equal(userID); + }); + + it('parse userID with comment', () => { + const userID = 'Alice Jones (the Great) '; + + const packet = new openpgp.UserIDPacket(); + packet.read(new TextEncoder().encode(userID)); + expect(packet.name).to.equal('Alice Jones'); + expect(packet.comment).to.equal('the Great'); + expect(packet.email).to.equal('alice@example.org'); + expect(packet.userID).to.equal(userID); + }); + + it('parse userID with unbracketed email address', () => { + const userID = 'alice@example.org'; + + const packet = new openpgp.UserIDPacket(); + packet.read(new TextEncoder().encode(userID)); + expect(packet.name).to.equal(''); + expect(packet.comment).to.equal(''); + expect(packet.email).to.equal('alice@example.org'); + expect(packet.userID).to.equal(userID); + }); + + it('parse userID with whitespace between parts', () => { + const userID = ' A name surrounded by whitespace ( a comment surrounded too ) '; + + const packet = new openpgp.UserIDPacket(); + packet.read(new TextEncoder().encode(userID)); + expect(packet.name).to.equal('A name surrounded by whitespace'); + expect(packet.comment).to.equal('a comment surrounded too'); + expect(packet.email).to.equal('ed@example.org'); + expect(packet.userID).to.equal(userID); + }); + + it('store userID without parts if parsing fails', () => { + const userID = 'Name only'; + + const packet = new openpgp.UserIDPacket(); + packet.read(new TextEncoder().encode(userID)); + expect(packet.name).to.equal(''); + expect(packet.comment).to.equal(''); + expect(packet.email).to.equal(''); + expect(packet.userID).to.equal(userID); + }); + }); }); From 9e1962f00608070d2b8fdffd9ec39cee4b543c3f Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Tue, 10 Oct 2023 11:23:03 +0200 Subject: [PATCH 078/201] Import noble-hashes, noble-curves and BN.js only on demand This primarily affects the lightweight build, which will not include these (fairly large) libs in the main bundle file. This allows fetching their code only if required: - Noble-curves is only needed for curves other than curve25519. - Noble-hashes is needed for streamed hashing and e.g. SHA3 on web. - BN.js is used by the above libs, and it's also separately needed for platforms without native BigInt support. --- src/biginteger.js | 39 ++++++++++++++ src/crypto/hash/index.js | 52 ++++++++----------- src/crypto/hash/noble_hashes.js | 22 ++++++++ src/crypto/public_key/dsa.js | 7 ++- src/crypto/public_key/elgamal.js | 8 ++- src/crypto/public_key/elliptic/ecdh.js | 8 +-- src/crypto/public_key/elliptic/ecdh_x.js | 5 +- src/crypto/public_key/elliptic/ecdsa.js | 12 ++--- src/crypto/public_key/elliptic/eddsa.js | 11 ++-- .../public_key/elliptic/noble_curves.js | 27 ++++++++++ src/crypto/public_key/elliptic/oid_curves.js | 34 ++---------- src/crypto/public_key/prime.js | 10 +++- src/crypto/public_key/rsa.js | 15 +++++- src/crypto/random.js | 3 +- src/util.js | 33 ++++++++++++ 15 files changed, 206 insertions(+), 80 deletions(-) create mode 100644 src/biginteger.js create mode 100644 src/crypto/hash/noble_hashes.js create mode 100644 src/crypto/public_key/elliptic/noble_curves.js diff --git a/src/biginteger.js b/src/biginteger.js new file mode 100644 index 00000000..b869e50e --- /dev/null +++ b/src/biginteger.js @@ -0,0 +1,39 @@ +/** + * This is a vanilla JS copy of @openpgp/noble-hashes/esm/biginteger/interface.ts . + * We need to duplicate the file, instead of importing it, since in that case the BigIntegerInterface instance + * would be shared with noble-hashes, which separately calls `setImplementation()` on load, causing it to throw due to + * duplicate initialization. + */ +class BigInteger { + static setImplementation(Implementation, replace = false) { + if (BigInteger.Implementation && !replace) { + throw new Error('Implementation already set'); + } + BigInteger.Implementation = Implementation; + } + + static new(n) { + return new BigInteger.Implementation(n); + } +} + +const detectBigInt = () => typeof BigInt !== 'undefined'; +export async function getBigInteger() { + if (BigInteger.Implementation) { + return BigInteger; + } + + // TODOOOOO replace = true needed in case of concurrent class loading, how to fix without removing wrapper class? + + if (detectBigInt()) { + // NativeBigInteger is small, so it's imported in isolation (it could also be imported at the top level) + const { default: NativeBigInteger } = await import('@openpgp/noble-hashes/esm/biginteger/native.interface'); + BigInteger.setImplementation(NativeBigInteger, true); + } else { + // FallbackBigInteger relies on large BN.js lib, which is also used by noble-hashes and noble-curves + const { default: FallbackBigInteger } = await import('@openpgp/noble-hashes/esm/biginteger/bn.interface'); + BigInteger.setImplementation(FallbackBigInteger, true); + } + + return BigInteger; +} diff --git a/src/crypto/hash/index.js b/src/crypto/hash/index.js index 0943b82f..3332a1ce 100644 --- a/src/crypto/hash/index.js +++ b/src/crypto/hash/index.js @@ -5,11 +5,6 @@ * @module crypto/hash */ -import { sha1 } from '@openpgp/noble-hashes/sha1'; -import { sha224, sha256 } from '@openpgp/noble-hashes/sha256'; -import { sha384, sha512 } from '@openpgp/noble-hashes/sha512'; -import { sha3_256, sha3_512 } from '@openpgp/noble-hashes/sha3'; -import { ripemd160 } from '@openpgp/noble-hashes/ripemd160'; import * as stream from '@openpgp/web-stream-tools'; import md5 from './md5'; import util from '../../util'; @@ -31,48 +26,47 @@ function nodeHash(type) { }; } -function nobleHash(hash, webCryptoHash) { +function nobleHash(nobleHashName, webCryptoHashName) { + const getNobleHash = async () => { + const { nobleHashes } = await import('./noble_hashes'); + const hash = nobleHashes.get(nobleHashName); + if (!hash) throw new Error('Unsupported hash'); + return hash; + }; + return async function(data) { if (stream.isArrayStream(data)) { data = await stream.readToEnd(data); } if (util.isStream(data)) { + const hash = await getNobleHash(); + const hashInstance = hash.create(); return stream.transform(data, value => { hashInstance.update(value); }, () => hashInstance.digest()); - } else if (webCrypto && webCryptoHash) { - return new Uint8Array(await webCrypto.digest(webCryptoHash, data)); + } else if (webCrypto && webCryptoHashName) { + return new Uint8Array(await webCrypto.digest(webCryptoHashName, data)); } else { + const hash = await getNobleHash(); + return hash(data); } }; } -const hashFunctions = { - md5: nodeHash('md5') || md5, - sha1: nodeHash('sha1') || nobleHash(sha1, 'SHA-1'), - sha224: nodeHash('sha224') || nobleHash(sha224), - sha256: nodeHash('sha256') || nobleHash(sha256, 'SHA-256'), - sha384: nodeHash('sha384') || nobleHash(sha384, 'SHA-384'), - sha512: nodeHash('sha512') || nobleHash(sha512, 'SHA-512'), - ripemd: nodeHash('ripemd160') || nobleHash(ripemd160), - sha3_256: nodeHash('sha3-256') || nobleHash(sha3_256), - sha3_512: nodeHash('sha3-512') || nobleHash(sha3_512) -}; - export default { /** @see module:md5 */ - md5: hashFunctions.md5, - sha1: hashFunctions.sha1, - sha224: hashFunctions.sha224, - sha256: hashFunctions.sha256, - sha384: hashFunctions.sha384, - sha512: hashFunctions.sha512, - ripemd: hashFunctions.ripemd, - sha3_256: hashFunctions.sha3_256, - sha3_512: hashFunctions.sha3_512, + md5: nodeHash('md5') || md5, + sha1: nodeHash('sha1') || nobleHash('sha1', 'SHA-1'), + sha224: nodeHash('sha224') || nobleHash('sha224'), + sha256: nodeHash('sha256') || nobleHash('sha256', 'SHA-256'), + sha384: nodeHash('sha384') || nobleHash('sha384', 'SHA-384'), + sha512: nodeHash('sha512') || nobleHash('sha512', 'SHA-512'), + ripemd: nodeHash('ripemd160') || nobleHash('ripemd160'), + sha3_256: nodeHash('sha3-256') || nobleHash('sha3_256'), + sha3_512: nodeHash('sha3-512') || nobleHash('sha3_512'), /** * Create a hash on the specified data using the specified algorithm diff --git a/src/crypto/hash/noble_hashes.js b/src/crypto/hash/noble_hashes.js new file mode 100644 index 00000000..0d589a78 --- /dev/null +++ b/src/crypto/hash/noble_hashes.js @@ -0,0 +1,22 @@ +/** + * This file is needed to dynamic import the noble-hashes. + * Separate dynamic imports are not convenient as they result in too many chunks, + * which share a lot of code anyway. + */ + +import { sha1 } from '@openpgp/noble-hashes/sha1'; +import { sha224, sha256 } from '@openpgp/noble-hashes/sha256'; +import { sha384, sha512 } from '@openpgp/noble-hashes/sha512'; +import { sha3_256, sha3_512 } from '@openpgp/noble-hashes/sha3'; +import { ripemd160 } from '@openpgp/noble-hashes/ripemd160'; + +export const nobleHashes = new Map(Object.entries({ + sha1, + sha224, + sha256, + sha384, + sha512, + sha3_256, + sha3_512, + ripemd160 +})); diff --git a/src/crypto/public_key/dsa.js b/src/crypto/public_key/dsa.js index b48a4d97..b315da5f 100644 --- a/src/crypto/public_key/dsa.js +++ b/src/crypto/public_key/dsa.js @@ -19,7 +19,6 @@ * @fileoverview A Digital signature algorithm implementation * @module crypto/public_key/dsa */ -import { BigInteger } from '@openpgp/noble-hashes/biginteger'; import { getRandomBigInteger } from '../random'; import util from '../../util'; import { isProbablePrime } from './prime'; @@ -42,6 +41,8 @@ import { isProbablePrime } from './prime'; * @async */ export async function sign(hashAlgo, hashed, g, p, q, x) { + const BigInteger = await util.getBigInteger(); + const one = BigInteger.new(1); p = BigInteger.new(p); q = BigInteger.new(q); @@ -100,6 +101,8 @@ export async function sign(hashAlgo, hashed, g, p, q, x) { * @async */ export async function verify(hashAlgo, r, s, hashed, g, p, q, y) { + const BigInteger = await util.getBigInteger(); + const zero = BigInteger.new(0); r = BigInteger.new(r); s = BigInteger.new(s); @@ -142,6 +145,8 @@ export async function verify(hashAlgo, r, s, hashed, g, p, q, y) { * @async */ export async function validateParams(p, q, g, y, x) { + const BigInteger = await util.getBigInteger(); + p = BigInteger.new(p); q = BigInteger.new(q); g = BigInteger.new(g); diff --git a/src/crypto/public_key/elgamal.js b/src/crypto/public_key/elgamal.js index e9d66865..7e6790d6 100644 --- a/src/crypto/public_key/elgamal.js +++ b/src/crypto/public_key/elgamal.js @@ -19,9 +19,9 @@ * @fileoverview ElGamal implementation * @module crypto/public_key/elgamal */ -import { BigInteger } from '@openpgp/noble-hashes/biginteger'; import { getRandomBigInteger } from '../random'; import { emeEncode, emeDecode } from '../pkcs1'; +import util from '../../util'; /** * ElGamal Encryption function @@ -34,6 +34,8 @@ import { emeEncode, emeDecode } from '../pkcs1'; * @async */ export async function encrypt(data, p, g, y) { + const BigInteger = await util.getBigInteger(); + p = BigInteger.new(p); g = BigInteger.new(g); y = BigInteger.new(y); @@ -63,6 +65,8 @@ export async function encrypt(data, p, g, y) { * @async */ export async function decrypt(c1, c2, p, x, randomPayload) { + const BigInteger = await util.getBigInteger(); + c1 = BigInteger.new(c1); c2 = BigInteger.new(c2); p = BigInteger.new(p); @@ -82,6 +86,8 @@ export async function decrypt(c1, c2, p, x, randomPayload) { * @async */ export async function validateParams(p, g, y, x) { + const BigInteger = await util.getBigInteger(); + p = BigInteger.new(p); g = BigInteger.new(g); y = BigInteger.new(y); diff --git a/src/crypto/public_key/elliptic/ecdh.js b/src/crypto/public_key/elliptic/ecdh.js index 9039833a..3ea593d7 100644 --- a/src/crypto/public_key/elliptic/ecdh.js +++ b/src/crypto/public_key/elliptic/ecdh.js @@ -21,7 +21,7 @@ */ import nacl from '@openpgp/tweetnacl'; -import { CurveWithOID, jwkToRawPublic, rawPublicToJWK, privateToJWK, validateStandardParams, getNobleCurve } from './oid_curves'; +import { CurveWithOID, jwkToRawPublic, rawPublicToJWK, privateToJWK, validateStandardParams } from './oid_curves'; import * as aesKW from '../../aes_kw'; import { getRandomBytes } from '../../random'; import hash from '../../hash'; @@ -210,8 +210,8 @@ export async function decrypt(oid, kdfParams, V, C, Q, d, fingerprint) { throw err; } -function jsPrivateEphemeralKey(curve, V, d) { - const nobleCurve = getNobleCurve(curve.name); +async function jsPrivateEphemeralKey(curve, V, d) { + const nobleCurve = await util.getNobleCurve(enums.publicKey.ecdh, curve.name); // The output includes parity byte const sharedSecretWithParity = nobleCurve.getSharedSecret(d, V); const sharedKey = sharedSecretWithParity.subarray(1); @@ -219,7 +219,7 @@ function jsPrivateEphemeralKey(curve, V, d) { } async function jsPublicEphemeralKey(curve, Q) { - const nobleCurve = getNobleCurve(curve.name); + const nobleCurve = await util.getNobleCurve(enums.publicKey.ecdh, curve.name); const { publicKey: V, privateKey: v } = await curve.genKeyPair(); // The output includes parity byte diff --git a/src/crypto/public_key/elliptic/ecdh_x.js b/src/crypto/public_key/elliptic/ecdh_x.js index 2d9ffe3e..a517e88a 100644 --- a/src/crypto/public_key/elliptic/ecdh_x.js +++ b/src/crypto/public_key/elliptic/ecdh_x.js @@ -4,7 +4,6 @@ */ import x25519 from '@openpgp/tweetnacl'; -import { x448 } from '@openpgp/noble-curves/ed448'; import * as aesKW from '../../aes_kw'; import { getRandomBytes } from '../../random'; @@ -32,6 +31,7 @@ export async function generate(algo) { return { A, k }; } case enums.publicKey.x448: { + const x448 = await util.getNobleCurve(enums.publicKey.x448); const k = x448.utils.randomPrivateKey(); const A = x448.getPublicKey(k); return { A, k }; @@ -60,6 +60,7 @@ export async function validateParams(algo, A, k) { return util.equalsUint8Array(A, publicKey); } case enums.publicKey.x448: { + const x448 = await util.getNobleCurve(enums.publicKey.x448); /** * Derive public point A' from private key * and expect A == A' @@ -102,6 +103,7 @@ export async function encrypt(algo, data, recipientA) { return { ephemeralPublicKey, wrappedKey }; } case enums.publicKey.x448: { + const x448 = await util.getNobleCurve(enums.publicKey.x448); const ephemeralSecretKey = x448.utils.randomPrivateKey(); const sharedSecret = x448.getSharedSecret(ephemeralSecretKey, recipientA); const ephemeralPublicKey = x448.getPublicKey(ephemeralSecretKey); @@ -146,6 +148,7 @@ export async function decrypt(algo, ephemeralPublicKey, wrappedKey, A, k) { return aesKW.unwrap(encryptionKey, wrappedKey); } case enums.publicKey.x448: { + const x448 = await util.getNobleCurve(enums.publicKey.x448); const sharedSecret = x448.getSharedSecret(k, ephemeralPublicKey); const hkdfInput = util.concatUint8Array([ ephemeralPublicKey, diff --git a/src/crypto/public_key/elliptic/ecdsa.js b/src/crypto/public_key/elliptic/ecdsa.js index 33f22232..b90bed2b 100644 --- a/src/crypto/public_key/elliptic/ecdsa.js +++ b/src/crypto/public_key/elliptic/ecdsa.js @@ -24,7 +24,7 @@ import enums from '../../../enums'; import util from '../../../util'; import { getRandomBytes } from '../../random'; import hash from '../../hash'; -import { CurveWithOID, webCurves, privateToJWK, rawPublicToJWK, validateStandardParams, getNobleCurve } from './oid_curves'; +import { CurveWithOID, webCurves, privateToJWK, rawPublicToJWK, validateStandardParams } from './oid_curves'; const webCrypto = util.getWebCrypto(); const nodeCrypto = util.getNodeCrypto(); @@ -74,7 +74,7 @@ export async function sign(oid, hashAlgo, message, publicKey, privateKey, hashed } } - const nobleCurve = getNobleCurve(curve.name); + const nobleCurve = await util.getNobleCurve(enums.publicKey.ecdsa, curve.name); // lowS: non-canonical sig: https://stackoverflow.com/questions/74338846/ecdsa-signature-verification-mismatch const signature = nobleCurve.sign(hashed, privateKey, { lowS: false }); return { @@ -103,7 +103,7 @@ export async function verify(oid, hashAlgo, signature, message, publicKey, hashe // Similarly, secp256k1 should have been used rarely enough. // However, we implement the fix for all curves, since it's only needed in case of // verification failure, which is unexpected, hence a minor slowdown is acceptable. - const tryFallbackVerificationForOldBug = () => ( + const tryFallbackVerificationForOldBug = async () => ( hashed[0] === 0 ? jsVerify(curve, signature, hashed.subarray(1), publicKey) : false @@ -133,7 +133,7 @@ export async function verify(oid, hashAlgo, signature, message, publicKey, hashe } } - const verified = jsVerify(curve, signature, hashed, publicKey); + const verified = await jsVerify(curve, signature, hashed, publicKey); return verified || tryFallbackVerificationForOldBug(); } @@ -183,8 +183,8 @@ export async function validateParams(oid, Q, d) { * Fallback javascript implementation of ECDSA verification. * To be used if no native implementation is available for the given curve/operation. */ -function jsVerify(curve, signature, hashed, publicKey) { - const nobleCurve = getNobleCurve(curve.name); +async function jsVerify(curve, signature, hashed, publicKey) { + const nobleCurve = await util.getNobleCurve(enums.publicKey.ecdsa, curve.name); // lowS: non-canonical sig: https://stackoverflow.com/questions/74338846/ecdsa-signature-verification-mismatch return nobleCurve.verify(util.concatUint8Array([signature.r, signature.s]), hashed, publicKey, { lowS: false }); } diff --git a/src/crypto/public_key/elliptic/eddsa.js b/src/crypto/public_key/elliptic/eddsa.js index 28c33f0c..c13665ea 100644 --- a/src/crypto/public_key/elliptic/eddsa.js +++ b/src/crypto/public_key/elliptic/eddsa.js @@ -20,15 +20,12 @@ * @module crypto/public_key/elliptic/eddsa */ -import { sha512 } from '@openpgp/noble-hashes/sha512'; import ed25519 from '@openpgp/tweetnacl'; -import { ed448 } from '@openpgp/noble-curves/ed448'; import util from '../../../util'; import enums from '../../../enums'; import hash from '../../hash'; import { getRandomBytes } from '../../random'; -ed25519.hash = bytes => sha512(bytes); /** * Generate (non-legacy) EdDSA key @@ -43,6 +40,7 @@ export async function generate(algo) { return { A, seed }; } case enums.publicKey.ed448: { + const ed448 = await util.getNobleCurve(enums.publicKey.ed448); const seed = ed448.utils.randomPrivateKey(); const A = ed448.getPublicKey(seed); return { A, seed }; @@ -76,6 +74,7 @@ export async function sign(algo, hashAlgo, message, publicKey, privateKey, hashe return { RS: signature }; } case enums.publicKey.ed448: { + const ed448 = await util.getNobleCurve(enums.publicKey.ed448); const signature = ed448.sign(hashed, privateKey); return { RS: signature }; } @@ -104,8 +103,10 @@ export async function verify(algo, hashAlgo, { RS }, m, publicKey, hashed) { case enums.publicKey.ed25519: { return ed25519.sign.detached.verify(hashed, RS, publicKey); } - case enums.publicKey.ed448: + case enums.publicKey.ed448: { + const ed448 = await util.getNobleCurve(enums.publicKey.ed448); return ed448.verify(RS, hashed, publicKey); + } default: throw new Error('Unsupported EdDSA algorithm'); } @@ -131,6 +132,8 @@ export async function validateParams(algo, A, seed) { } case enums.publicKey.ed448: { + const ed448 = await util.getNobleCurve(enums.publicKey.ed448); + const publicKey = ed448.getPublicKey(seed); return util.equalsUint8Array(A, publicKey); } diff --git a/src/crypto/public_key/elliptic/noble_curves.js b/src/crypto/public_key/elliptic/noble_curves.js new file mode 100644 index 00000000..22a80fba --- /dev/null +++ b/src/crypto/public_key/elliptic/noble_curves.js @@ -0,0 +1,27 @@ +/** + * This file is needed to dynamic import the noble-curves. + * Separate dynamic imports are not convenient as they result in too many chunks, + * which share a lot of code anyway. + */ + +import { p256 } from '@openpgp/noble-curves/p256'; +import { p384 } from '@openpgp/noble-curves/p384'; +import { p521 } from '@openpgp/noble-curves/p521'; +import { brainpoolP256r1 } from '@openpgp/noble-curves/brainpoolP256r1'; +import { brainpoolP384r1 } from '@openpgp/noble-curves/brainpoolP384r1'; +import { brainpoolP512r1 } from '@openpgp/noble-curves/brainpoolP512r1'; +import { x448, ed448 } from '@openpgp/noble-curves/ed448'; +import { secp256k1 } from '@openpgp/noble-curves/secp256k1'; + +export const nobleCurves = new Map(Object.entries({ + p256, + p384, + p521, + brainpoolP256r1, + brainpoolP384r1, + brainpoolP512r1, + secp256k1, + x448, + ed448 +})); + diff --git a/src/crypto/public_key/elliptic/oid_curves.js b/src/crypto/public_key/elliptic/oid_curves.js index f5716d02..75c23827 100644 --- a/src/crypto/public_key/elliptic/oid_curves.js +++ b/src/crypto/public_key/elliptic/oid_curves.js @@ -20,20 +20,12 @@ * @module crypto/public_key/elliptic/curve */ import nacl from '@openpgp/tweetnacl'; -import { p256 } from '@openpgp/noble-curves/p256'; -import { p384 } from '@openpgp/noble-curves/p384'; -import { p521 } from '@openpgp/noble-curves/p521'; -import { brainpoolP256r1 } from '@openpgp/noble-curves/brainpoolP256r1'; -import { brainpoolP384r1 } from '@openpgp/noble-curves/brainpoolP384r1'; -import { brainpoolP512r1 } from '@openpgp/noble-curves/brainpoolP512r1'; -import { secp256k1 } from '@openpgp/noble-curves/secp256k1'; import { getRandomBytes } from '../../random'; import enums from '../../../enums'; import util from '../../../util'; import { uint8ArrayToB64, b64ToUint8Array } from '../../../encoding/base64'; import OID from '../../../type/oid'; import { UnsupportedError } from '../../../packet/packet'; -import defaultConfig from '../../../config'; const webCrypto = util.getWebCrypto(); const nodeCrypto = util.getNodeCrypto(); @@ -56,26 +48,6 @@ const nodeCurves = nodeCrypto ? { [enums.curve.brainpoolP512r1]: knownCurves.includes('brainpoolP512r1') ? 'brainpoolP512r1' : undefined } : {}; -const nobleCurvess = { - [enums.curve.p256]: p256, - [enums.curve.p384]: p384, - [enums.curve.p521]: p521, - [enums.curve.secp256k1]: secp256k1, - [enums.curve.brainpoolP256r1]: brainpoolP256r1, - [enums.curve.brainpoolP384r1]: brainpoolP384r1, - [enums.curve.brainpoolP512r1]: brainpoolP512r1 -}; -export const getNobleCurve = curveName => { - if (!defaultConfig.useEllipticFallback) { - // TODO make import dynamic - throw new Error('This curve is only supported in the full build of OpenPGP.js'); - } - const curve = nobleCurvess[curveName]; - if (!curve) throw new Error('Unsupported curve'); - return curve; -}; - - const curves = { p256: { oid: [0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07], @@ -291,7 +263,7 @@ async function validateStandardParams(algo, oid, Q, d) { return true; } - const nobleCurve = getNobleCurve(enums.write(enums.curve, oid.toHex())); + const nobleCurve = await util.getNobleCurve(enums.publicKey.ecdsa, enums.write(enums.curve, oid.toHex())); // excluding curve25519Legacy, ecdh and ecdsa use the same curves /* * Re-derive public point Q' = dG from private key * Expect Q == Q' @@ -313,8 +285,8 @@ export { // Helper functions // // // ////////////////////////// -function jsGenKeyPair(name) { - const nobleCurve = getNobleCurve(name); +async function jsGenKeyPair(name) { + const nobleCurve = await util.getNobleCurve(enums.publicKey.ecdsa, name); // excluding curve25519Legacy, ecdh and ecdsa use the same curves const privateKey = nobleCurve.utils.randomPrivateKey(); const publicKey = nobleCurve.getPublicKey(privateKey, false); return { publicKey, privateKey }; diff --git a/src/crypto/public_key/prime.js b/src/crypto/public_key/prime.js index 8e0bd13d..18d3250e 100644 --- a/src/crypto/public_key/prime.js +++ b/src/crypto/public_key/prime.js @@ -19,7 +19,7 @@ * @fileoverview Algorithms for probabilistic random prime generation * @module crypto/public_key/prime */ -import { BigInteger } from '@openpgp/noble-hashes/biginteger'; +import util from '../../util'; import { getRandomBigInteger } from '../random'; /** @@ -31,6 +31,8 @@ import { getRandomBigInteger } from '../random'; * @async */ export async function randomProbablePrime(bits, e, k) { + const BigInteger = await util.getBigInteger(); + const one = BigInteger.new(1); const min = one.leftShift(BigInteger.new(bits - 1)); const thirty = BigInteger.new(30); @@ -91,11 +93,15 @@ export async function isProbablePrime(n, e, k) { * @returns {boolean} */ export async function fermat(n, b) { + const BigInteger = await util.getBigInteger(); + b = b || BigInteger.new(2); return b.modExp(n.dec(), n).isOne(); } export async function divisionTest(n) { + const BigInteger = await util.getBigInteger(); + return smallPrimes.every(m => { return n.mod(BigInteger.new(m)) !== 0; }); @@ -224,6 +230,8 @@ const smallPrimes = [ * @async */ export async function millerRabin(n, k, rand) { + const BigInteger = await util.getBigInteger(); + const len = n.bitLength(); if (!k) { diff --git a/src/crypto/public_key/rsa.js b/src/crypto/public_key/rsa.js index 180a3326..9050edcc 100644 --- a/src/crypto/public_key/rsa.js +++ b/src/crypto/public_key/rsa.js @@ -19,7 +19,6 @@ * @fileoverview RSA implementation * @module crypto/public_key/rsa */ -import { BigInteger } from '@openpgp/noble-hashes/biginteger'; import { randomProbablePrime } from './prime'; import { getRandomBigInteger } from '../random'; import util from '../../util'; @@ -159,6 +158,8 @@ export async function decrypt(data, n, e, d, p, q, u, randomPayload) { * @async */ export async function generate(bits, e) { + const BigInteger = await util.getBigInteger(); + e = BigInteger.new(e); // Native RSA keygen using Web Crypto @@ -262,6 +263,8 @@ export async function generate(bits, e) { * @async */ export async function validateParams(n, e, d, p, q, u) { + const BigInteger = await util.getBigInteger(); + n = BigInteger.new(n); p = BigInteger.new(p); q = BigInteger.new(q); @@ -300,6 +303,8 @@ export async function validateParams(n, e, d, p, q, u) { } async function bnSign(hashAlgo, n, d, hashed) { + const BigInteger = await util.getBigInteger(); + n = BigInteger.new(n); const m = BigInteger.new(await emsaEncode(hashAlgo, hashed, n.byteLength())); d = BigInteger.new(d); @@ -360,6 +365,8 @@ async function nodeSign(hashAlgo, data, n, e, d, p, q, u) { } async function bnVerify(hashAlgo, s, n, e, hashed) { + const BigInteger = await util.getBigInteger(); + n = BigInteger.new(n); s = BigInteger.new(s); e = BigInteger.new(e); @@ -427,6 +434,8 @@ async function nodeEncrypt(data, n, e) { } async function bnEncrypt(data, n, e) { + const BigInteger = await util.getBigInteger(); + n = BigInteger.new(n); data = BigInteger.new(emeEncode(data, n.byteLength())); e = BigInteger.new(e); @@ -478,6 +487,8 @@ async function nodeDecrypt(data, n, e, d, p, q, u, randomPayload) { } async function bnDecrypt(data, n, e, d, p, q, u, randomPayload) { + const BigInteger = await util.getBigInteger(); + data = BigInteger.new(data); n = BigInteger.new(n); e = BigInteger.new(e); @@ -519,6 +530,8 @@ async function bnDecrypt(data, n, e, d, p, q, u, randomPayload) { * @param {Uint8Array} u */ async function privateToJWK(n, e, d, p, q, u) { + const BigInteger = await util.getBigInteger(); + const pNum = BigInteger.new(p); const qNum = BigInteger.new(q); const dNum = BigInteger.new(d); diff --git a/src/crypto/random.js b/src/crypto/random.js index 8c7ad418..1f5f8142 100644 --- a/src/crypto/random.js +++ b/src/crypto/random.js @@ -21,7 +21,6 @@ * @fileoverview Provides tools for retrieving secure randomness from browsers or Node.js * @module crypto/random */ -import { BigInteger } from '@openpgp/noble-hashes/biginteger'; import util from '../util'; const nodeCrypto = util.getNodeCrypto(); @@ -52,6 +51,8 @@ export function getRandomBytes(length) { * @async */ export async function getRandomBigInteger(min, max) { + const BigInteger = await util.getBigInteger(); + if (max.lt(min)) { throw new Error('Illegal parameter value: max <= min'); } diff --git a/src/util.js b/src/util.js index f0ee7f63..0a1c721d 100644 --- a/src/util.js +++ b/src/util.js @@ -25,6 +25,8 @@ import * as stream from '@openpgp/web-stream-tools'; import { createRequire } from 'module'; // Must be stripped in browser built import enums from './enums'; +import defaultConfig from './config'; +import { getBigInteger } from './biginteger'; const debugMode = (() => { try { @@ -48,6 +50,37 @@ const util = { isStream: stream.isStream, + getBigInteger, + + /** + * Load noble-curves lib on demand and return the requested curve function + * @param {enums.publicKey} publicKeyAlgo + * @param {enums.curve} [curveName] - for algos supporting different curves (e.g. ECDSA) + * @returns curve implementation + * @throws on unrecognized curve, or curve not implemented by noble-curve + */ + getNobleCurve: async (publicKeyAlgo, curveName) => { + if (!defaultConfig.useEllipticFallback) { + throw new Error('This curve is only supported in the full build of OpenPGP.js'); + } + + const { nobleCurves } = await import('./crypto/public_key/elliptic/noble_curves'); + switch (publicKeyAlgo) { + case enums.publicKey.ecdh: + case enums.publicKey.ecdsa: { + const curve = nobleCurves.get(curveName); + if (!curve) throw new Error('Unsupported curve'); + return curve; + } + case enums.publicKey.x448: + return nobleCurves.get('x448'); + case enums.publicKey.ed448: + return nobleCurves.get('ed448'); + default: + throw new Error('Unsupported curve'); + } + }, + readNumber: function (bytes) { let n = 0; for (let i = 0; i < bytes.length; i++) { From 4ee9deae626f2bdd5b005a7848d7408b69114ec4 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Thu, 12 Oct 2023 11:16:55 +0200 Subject: [PATCH 079/201] Switch back to using standard BigInteger class instead of wrapper Using a wrapper requires adding some handling code to fix race conditions, but it does not provide advantages until we switch to TS. --- src/biginteger.js | 35 +++++-------------- src/crypto/public_key/dsa.js | 46 ++++++++++++------------- src/crypto/public_key/elgamal.js | 38 ++++++++++----------- src/crypto/public_key/prime.js | 16 ++++----- src/crypto/public_key/rsa.js | 58 ++++++++++++++++---------------- src/crypto/random.js | 2 +- 6 files changed, 88 insertions(+), 107 deletions(-) diff --git a/src/biginteger.js b/src/biginteger.js index b869e50e..bd114984 100644 --- a/src/biginteger.js +++ b/src/biginteger.js @@ -1,39 +1,20 @@ /** - * This is a vanilla JS copy of @openpgp/noble-hashes/esm/biginteger/interface.ts . - * We need to duplicate the file, instead of importing it, since in that case the BigIntegerInterface instance - * would be shared with noble-hashes, which separately calls `setImplementation()` on load, causing it to throw due to - * duplicate initialization. + * We don't use the BigIntegerInterface wrapper from noble-hashes because: + * - importing the instance results in it being shared with noble-hashes, which separately calls `setImplementation()` + * on load, causing it to throw due to duplicate initialization. + * - even duplicating the interface code here to keep a separate instance requires handing a race-conditions the first time + * `getBigInteger` is called, when the code needs to check if the implementation is set, and initialize it if not. + * Ultimately, the interface provides no advantages and it's only needed because of TS. */ -class BigInteger { - static setImplementation(Implementation, replace = false) { - if (BigInteger.Implementation && !replace) { - throw new Error('Implementation already set'); - } - BigInteger.Implementation = Implementation; - } - - static new(n) { - return new BigInteger.Implementation(n); - } -} - const detectBigInt = () => typeof BigInt !== 'undefined'; export async function getBigInteger() { - if (BigInteger.Implementation) { - return BigInteger; - } - - // TODOOOOO replace = true needed in case of concurrent class loading, how to fix without removing wrapper class? - if (detectBigInt()) { // NativeBigInteger is small, so it's imported in isolation (it could also be imported at the top level) const { default: NativeBigInteger } = await import('@openpgp/noble-hashes/esm/biginteger/native.interface'); - BigInteger.setImplementation(NativeBigInteger, true); + return NativeBigInteger; } else { // FallbackBigInteger relies on large BN.js lib, which is also used by noble-hashes and noble-curves const { default: FallbackBigInteger } = await import('@openpgp/noble-hashes/esm/biginteger/bn.interface'); - BigInteger.setImplementation(FallbackBigInteger, true); + return FallbackBigInteger; } - - return BigInteger; } diff --git a/src/crypto/public_key/dsa.js b/src/crypto/public_key/dsa.js index b315da5f..d3fb6e8c 100644 --- a/src/crypto/public_key/dsa.js +++ b/src/crypto/public_key/dsa.js @@ -43,11 +43,11 @@ import { isProbablePrime } from './prime'; export async function sign(hashAlgo, hashed, g, p, q, x) { const BigInteger = await util.getBigInteger(); - const one = BigInteger.new(1); - p = BigInteger.new(p); - q = BigInteger.new(q); - g = BigInteger.new(g); - x = BigInteger.new(x); + const one = new BigInteger(1); + p = new BigInteger(p); + q = new BigInteger(q); + g = new BigInteger(g); + x = new BigInteger(x); let k; let r; @@ -60,7 +60,7 @@ export async function sign(hashAlgo, hashed, g, p, q, x) { // of leftmost bits equal to the number of bits of q. This (possibly // truncated) hash function result is treated as a number and used // directly in the DSA signature algorithm. - const h = BigInteger.new(hashed.subarray(0, q.byteLength())).mod(q); + const h = new BigInteger(hashed.subarray(0, q.byteLength())).mod(q); // FIPS-186-4, section 4.6: // The values of r and s shall be checked to determine if r = 0 or s = 0. // If either r = 0 or s = 0, a new value of k shall be generated, and the @@ -103,21 +103,21 @@ export async function sign(hashAlgo, hashed, g, p, q, x) { export async function verify(hashAlgo, r, s, hashed, g, p, q, y) { const BigInteger = await util.getBigInteger(); - const zero = BigInteger.new(0); - r = BigInteger.new(r); - s = BigInteger.new(s); + const zero = new BigInteger(0); + r = new BigInteger(r); + s = new BigInteger(s); - p = BigInteger.new(p); - q = BigInteger.new(q); - g = BigInteger.new(g); - y = BigInteger.new(y); + p = new BigInteger(p); + q = new BigInteger(q); + g = new BigInteger(g); + y = new BigInteger(y); if (r.lte(zero) || r.gte(q) || s.lte(zero) || s.gte(q)) { util.printDebug('invalid DSA Signature'); return false; } - const h = BigInteger.new(hashed.subarray(0, q.byteLength())).imod(q); + const h = new BigInteger(hashed.subarray(0, q.byteLength())).imod(q); const w = s.modInv(q); // s**-1 mod q if (w.isZero()) { util.printDebug('invalid DSA Signature'); @@ -147,11 +147,11 @@ export async function verify(hashAlgo, r, s, hashed, g, p, q, y) { export async function validateParams(p, q, g, y, x) { const BigInteger = await util.getBigInteger(); - p = BigInteger.new(p); - q = BigInteger.new(q); - g = BigInteger.new(g); - y = BigInteger.new(y); - const one = BigInteger.new(1); + p = new BigInteger(p); + q = new BigInteger(q); + g = new BigInteger(g); + y = new BigInteger(y); + const one = new BigInteger(1); // Check that 1 < g < p if (g.lte(one) || g.gte(p)) { return false; @@ -175,8 +175,8 @@ export async function validateParams(p, q, g, y, x) { /** * Check q is large and probably prime (we mainly want to avoid small factors) */ - const qSize = BigInteger.new(q.bitLength()); - const n150 = BigInteger.new(150); + const qSize = new BigInteger(q.bitLength()); + const n150 = new BigInteger(150); if (qSize.lt(n150) || !(await isProbablePrime(q, null, 32))) { return false; } @@ -187,8 +187,8 @@ export async function validateParams(p, q, g, y, x) { * * Blinded exponentiation computes g**{rq + x} to compare to y */ - x = BigInteger.new(x); - const two = BigInteger.new(2); + x = new BigInteger(x); + const two = new BigInteger(2); const r = await getRandomBigInteger(two.leftShift(qSize.dec()), two.leftShift(qSize)); // draw r of same size as q const rqx = q.mul(r).add(x); if (!y.equal(g.modExp(rqx, p))) { diff --git a/src/crypto/public_key/elgamal.js b/src/crypto/public_key/elgamal.js index 7e6790d6..2dc2c2fd 100644 --- a/src/crypto/public_key/elgamal.js +++ b/src/crypto/public_key/elgamal.js @@ -36,16 +36,16 @@ import util from '../../util'; export async function encrypt(data, p, g, y) { const BigInteger = await util.getBigInteger(); - p = BigInteger.new(p); - g = BigInteger.new(g); - y = BigInteger.new(y); + p = new BigInteger(p); + g = new BigInteger(g); + y = new BigInteger(y); const padded = emeEncode(data, p.byteLength()); - const m = BigInteger.new(padded); + const m = new BigInteger(padded); // OpenPGP uses a "special" version of ElGamal where g is generator of the full group Z/pZ* // hence g has order p-1, and to avoid that k = 0 mod p-1, we need to pick k in [1, p-2] - const k = await getRandomBigInteger(BigInteger.new(1), p.dec()); + const k = await getRandomBigInteger(new BigInteger(1), p.dec()); return { c1: g.modExp(k, p).toUint8Array(), c2: y.modExp(k, p).imul(m).imod(p).toUint8Array() @@ -67,10 +67,10 @@ export async function encrypt(data, p, g, y) { export async function decrypt(c1, c2, p, x, randomPayload) { const BigInteger = await util.getBigInteger(); - c1 = BigInteger.new(c1); - c2 = BigInteger.new(c2); - p = BigInteger.new(p); - x = BigInteger.new(x); + c1 = new BigInteger(c1); + c2 = new BigInteger(c2); + p = new BigInteger(p); + x = new BigInteger(x); const padded = c1.modExp(x, p).modInv(p).imul(c2).imod(p); return emeDecode(padded.toUint8Array('be', p.byteLength()), randomPayload); @@ -88,19 +88,19 @@ export async function decrypt(c1, c2, p, x, randomPayload) { export async function validateParams(p, g, y, x) { const BigInteger = await util.getBigInteger(); - p = BigInteger.new(p); - g = BigInteger.new(g); - y = BigInteger.new(y); + p = new BigInteger(p); + g = new BigInteger(g); + y = new BigInteger(y); - const one = BigInteger.new(1); + const one = new BigInteger(1); // Check that 1 < g < p if (g.lte(one) || g.gte(p)) { return false; } // Expect p-1 to be large - const pSize = BigInteger.new(p.bitLength()); - const n1023 = BigInteger.new(1023); + const pSize = new BigInteger(p.bitLength()); + const n1023 = new BigInteger(1023); if (pSize.lt(n1023)) { return false; } @@ -120,8 +120,8 @@ export async function validateParams(p, g, y, x) { * We just check g**i != 1 for all i up to a threshold */ let res = g; - const i = BigInteger.new(1); - const threshold = BigInteger.new(2).leftShift(BigInteger.new(17)); // we want order > threshold + const i = new BigInteger(1); + const threshold = new BigInteger(2).leftShift(new BigInteger(17)); // we want order > threshold while (i.lt(threshold)) { res = res.mul(g).imod(p); if (res.isOne()) { @@ -136,8 +136,8 @@ export async function validateParams(p, g, y, x) { * * Blinded exponentiation computes g**{r(p-1) + x} to compare to y */ - x = BigInteger.new(x); - const two = BigInteger.new(2); + x = new BigInteger(x); + const two = new BigInteger(2); const r = await getRandomBigInteger(two.leftShift(pSize.dec()), two.leftShift(pSize)); // draw r of same size as p-1 const rqx = p.dec().imul(r).iadd(x); if (!y.equal(g.modExp(rqx, p))) { diff --git a/src/crypto/public_key/prime.js b/src/crypto/public_key/prime.js index 18d3250e..8045f638 100644 --- a/src/crypto/public_key/prime.js +++ b/src/crypto/public_key/prime.js @@ -33,9 +33,9 @@ import { getRandomBigInteger } from '../random'; export async function randomProbablePrime(bits, e, k) { const BigInteger = await util.getBigInteger(); - const one = BigInteger.new(1); - const min = one.leftShift(BigInteger.new(bits - 1)); - const thirty = BigInteger.new(30); + const one = new BigInteger(1); + const min = one.leftShift(new BigInteger(bits - 1)); + const thirty = new BigInteger(30); /* * We can avoid any multiples of 3 and 5 by looking at n mod 30 * n mod 30 = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 @@ -48,7 +48,7 @@ export async function randomProbablePrime(bits, e, k) { let i = n.mod(thirty).toNumber(); do { - n.iadd(BigInteger.new(adds[i])); + n.iadd(new BigInteger(adds[i])); i = (i + adds[i]) % adds.length; // If reached the maximum, go back to the minimum. if (n.bitLength() > bits) { @@ -95,7 +95,7 @@ export async function isProbablePrime(n, e, k) { export async function fermat(n, b) { const BigInteger = await util.getBigInteger(); - b = b || BigInteger.new(2); + b = b || new BigInteger(2); return b.modExp(n.dec(), n).isOne(); } @@ -103,7 +103,7 @@ export async function divisionTest(n) { const BigInteger = await util.getBigInteger(); return smallPrimes.every(m => { - return n.mod(BigInteger.new(m)) !== 0; + return n.mod(new BigInteger(m)) !== 0; }); } @@ -243,10 +243,10 @@ export async function millerRabin(n, k, rand) { // Find d and s, (n - 1) = (2 ^ s) * d; let s = 0; while (!n1.getBit(s)) { s++; } - const d = n.rightShift(BigInteger.new(s)); + const d = n.rightShift(new BigInteger(s)); for (; k > 0; k--) { - const a = rand ? rand() : await getRandomBigInteger(BigInteger.new(2), n1); + const a = rand ? rand() : await getRandomBigInteger(new BigInteger(2), n1); let x = a.modExp(d, n); if (x.isOne() || x.equal(n1)) { diff --git a/src/crypto/public_key/rsa.js b/src/crypto/public_key/rsa.js index 9050edcc..6387bc25 100644 --- a/src/crypto/public_key/rsa.js +++ b/src/crypto/public_key/rsa.js @@ -160,7 +160,7 @@ export async function decrypt(data, n, e, d, p, q, u, randomPayload) { export async function generate(bits, e) { const BigInteger = await util.getBigInteger(); - e = BigInteger.new(e); + e = new BigInteger(e); // Native RSA keygen using Web Crypto if (util.getWebCrypto()) { @@ -265,24 +265,24 @@ export async function generate(bits, e) { export async function validateParams(n, e, d, p, q, u) { const BigInteger = await util.getBigInteger(); - n = BigInteger.new(n); - p = BigInteger.new(p); - q = BigInteger.new(q); + n = new BigInteger(n); + p = new BigInteger(p); + q = new BigInteger(q); // expect pq = n if (!p.mul(q).equal(n)) { return false; } - const two = BigInteger.new(2); + const two = new BigInteger(2); // expect p*u = 1 mod q - u = BigInteger.new(u); + u = new BigInteger(u); if (!p.mul(u).mod(q).isOne()) { return false; } - e = BigInteger.new(e); - d = BigInteger.new(d); + e = new BigInteger(e); + d = new BigInteger(d); /** * In RSA pkcs#1 the exponents (d, e) are inverses modulo lcm(p-1, q-1) * We check that [de = 1 mod (p-1)] and [de = 1 mod (q-1)] @@ -290,7 +290,7 @@ export async function validateParams(n, e, d, p, q, u) { * * We blind the multiplication with r, and check that rde = r mod lcm(p-1, q-1) */ - const nSizeOver3 = BigInteger.new(Math.floor(n.bitLength() / 3)); + const nSizeOver3 = new BigInteger(Math.floor(n.bitLength() / 3)); const r = await getRandomBigInteger(two, two.leftShift(nSizeOver3)); // r in [ 2, 2^{|n|/3} ) < p and q const rde = r.mul(d).mul(e); @@ -305,9 +305,9 @@ export async function validateParams(n, e, d, p, q, u) { async function bnSign(hashAlgo, n, d, hashed) { const BigInteger = await util.getBigInteger(); - n = BigInteger.new(n); - const m = BigInteger.new(await emsaEncode(hashAlgo, hashed, n.byteLength())); - d = BigInteger.new(d); + n = new BigInteger(n); + const m = new BigInteger(await emsaEncode(hashAlgo, hashed, n.byteLength())); + d = new BigInteger(d); if (m.gte(n)) { throw new Error('Message size cannot exceed modulus size'); } @@ -367,9 +367,9 @@ async function nodeSign(hashAlgo, data, n, e, d, p, q, u) { async function bnVerify(hashAlgo, s, n, e, hashed) { const BigInteger = await util.getBigInteger(); - n = BigInteger.new(n); - s = BigInteger.new(s); - e = BigInteger.new(e); + n = new BigInteger(n); + s = new BigInteger(s); + e = new BigInteger(e); if (s.gte(n)) { throw new Error('Signature size cannot exceed modulus size'); } @@ -436,9 +436,9 @@ async function nodeEncrypt(data, n, e) { async function bnEncrypt(data, n, e) { const BigInteger = await util.getBigInteger(); - n = BigInteger.new(n); - data = BigInteger.new(emeEncode(data, n.byteLength())); - e = BigInteger.new(e); + n = new BigInteger(n); + data = new BigInteger(emeEncode(data, n.byteLength())); + e = new BigInteger(e); if (data.gte(n)) { throw new Error('Message size cannot exceed modulus size'); } @@ -489,20 +489,20 @@ async function nodeDecrypt(data, n, e, d, p, q, u, randomPayload) { async function bnDecrypt(data, n, e, d, p, q, u, randomPayload) { const BigInteger = await util.getBigInteger(); - data = BigInteger.new(data); - n = BigInteger.new(n); - e = BigInteger.new(e); - d = BigInteger.new(d); - p = BigInteger.new(p); - q = BigInteger.new(q); - u = BigInteger.new(u); + data = new BigInteger(data); + n = new BigInteger(n); + e = new BigInteger(e); + d = new BigInteger(d); + p = new BigInteger(p); + q = new BigInteger(q); + u = new BigInteger(u); if (data.gte(n)) { throw new Error('Data too large.'); } const dq = d.mod(q.dec()); // d mod (q-1) const dp = d.mod(p.dec()); // d mod (p-1) - const unblinder = (await getRandomBigInteger(BigInteger.new(2), n)).mod(n); + const unblinder = (await getRandomBigInteger(new BigInteger(2), n)).mod(n); const blinder = unblinder.modInv(n).modExp(e, n); data = data.mul(blinder).mod(n); @@ -532,9 +532,9 @@ async function bnDecrypt(data, n, e, d, p, q, u, randomPayload) { async function privateToJWK(n, e, d, p, q, u) { const BigInteger = await util.getBigInteger(); - const pNum = BigInteger.new(p); - const qNum = BigInteger.new(q); - const dNum = BigInteger.new(d); + const pNum = new BigInteger(p); + const qNum = new BigInteger(q); + const dNum = new BigInteger(d); let dq = dNum.mod(qNum.dec()); // d mod (q-1) let dp = dNum.mod(pNum.dec()); // d mod (p-1) diff --git a/src/crypto/random.js b/src/crypto/random.js index 1f5f8142..4936c97e 100644 --- a/src/crypto/random.js +++ b/src/crypto/random.js @@ -63,6 +63,6 @@ export async function getRandomBigInteger(min, max) { // Using a while loop is necessary to avoid bias introduced by the mod operation. // However, we request 64 extra random bits so that the bias is negligible. // Section B.1.1 here: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf - const r = BigInteger.new(await getRandomBytes(bytes + 8)); + const r = new BigInteger(getRandomBytes(bytes + 8)); return r.mod(modulus).add(min); } From 86f5a8b71bf3784229258014b409b02510ce991e Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Mon, 23 Oct 2023 17:34:04 +0200 Subject: [PATCH 080/201] Rollup: use `preserveEntrySignatures = 'exports-only'` setting in lightweight build This is the default setting and it ensures that the main chunk does not include additional exports, which is is important when importing the module as `import *` as shown in the readme. In practice, this change does not affect the chunking with the current code. --- rollup.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rollup.config.js b/rollup.config.js index 1d723d6f..d8091f78 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -98,7 +98,7 @@ export default Object.assign([ { dir: 'dist/lightweight', entryFileNames: 'openpgp.mjs', chunkFileNames: chunkInfo => getChunkFileName(chunkInfo, 'mjs'), format: 'es', banner, intro }, { dir: 'dist/lightweight', entryFileNames: 'openpgp.min.mjs', chunkFileNames: chunkInfo => getChunkFileName(chunkInfo, 'min.mjs'), format: 'es', banner, intro, plugins: [terser(terserOptions)], sourcemap: true } ], - preserveEntrySignatures: 'allow-extension', + preserveEntrySignatures: 'exports-only', plugins: [ resolve({ browser: true From 9a547b4553d5e469388243659b0b95322109a649 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Wed, 18 Oct 2023 19:32:11 +0200 Subject: [PATCH 081/201] Update rollup to v3 --- package-lock.json | 17 +++++++++-------- package.json | 2 +- rollup.config.js | 14 +++++++------- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index bff38d5e..df83d7e4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -48,7 +48,7 @@ "mocha": "^10.2.0", "nyc": "^14.1.1", "playwright": "^1.30.0", - "rollup": "^2.79.1", + "rollup": "^3.29.4", "sinon": "^15.1.0", "ts-node": "^10.9.1", "typescript": "^4.1.2", @@ -6140,15 +6140,16 @@ } }, "node_modules/rollup": { - "version": "2.79.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", - "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "version": "3.29.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", + "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", "dev": true, "bin": { "rollup": "dist/bin/rollup" }, "engines": { - "node": ">=10.0.0" + "node": ">=14.18.0", + "npm": ">=8.0.0" }, "optionalDependencies": { "fsevents": "~2.3.2" @@ -12236,9 +12237,9 @@ } }, "rollup": { - "version": "2.79.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", - "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "version": "3.29.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", + "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", "dev": true, "requires": { "fsevents": "~2.3.2" diff --git a/package.json b/package.json index 5befcbc0..98d3a89a 100644 --- a/package.json +++ b/package.json @@ -98,7 +98,7 @@ "mocha": "^10.2.0", "nyc": "^14.1.1", "playwright": "^1.30.0", - "rollup": "^2.79.1", + "rollup": "^3.29.4", "sinon": "^15.1.0", "ts-node": "^10.9.1", "typescript": "^4.1.2", diff --git a/rollup.config.js b/rollup.config.js index d8091f78..22a1b6c5 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,6 +1,7 @@ /* eslint-disable no-process-env */ import { builtinModules } from 'module'; +import { readFileSync } from 'fs'; import alias from '@rollup/plugin-alias'; import resolve from '@rollup/plugin-node-resolve'; @@ -9,7 +10,9 @@ import replace from '@rollup/plugin-replace'; import terser from '@rollup/plugin-terser'; import { wasm } from '@rollup/plugin-wasm'; -import pkg from './package.json'; +// ESlint does not support JSON module imports yet, see https://github.com/eslint/eslint/discussions/15305 +// import pkg from './package.json' assert { type: 'json' }; +const pkg = JSON.parse(readFileSync('./package.json')); const nodeDependencies = Object.keys(pkg.dependencies); const nodeBuiltinModules = builtinModules.concat(['module']); @@ -55,8 +58,7 @@ export default Object.assign([ { file: 'dist/openpgp.min.js', format: 'iife', name: pkg.name, banner, intro, plugins: [terser(terserOptions)], sourcemap: true }, { file: 'dist/openpgp.mjs', format: 'es', banner, intro }, { file: 'dist/openpgp.min.mjs', format: 'es', banner, intro, plugins: [terser(terserOptions)], sourcemap: true } - ], - inlineDynamicImports: true, + ].map(options => ({ ...options, inlineDynamicImports: true })), plugins: [ resolve({ browser: true @@ -74,14 +76,13 @@ export default Object.assign([ }, { input: 'src/index.js', - inlineDynamicImports: true, external: nodeBuiltinModules.concat(nodeDependencies), output: [ { file: 'dist/node/openpgp.cjs', format: 'cjs', name: pkg.name, banner, intro }, { file: 'dist/node/openpgp.min.cjs', format: 'cjs', name: pkg.name, banner, intro, plugins: [terser(terserOptions)], sourcemap: true }, { file: 'dist/node/openpgp.mjs', format: 'es', banner, intro }, { file: 'dist/node/openpgp.min.mjs', format: 'es', banner, intro, plugins: [terser(terserOptions)], sourcemap: true } - ], + ].map(options => ({ ...options, inlineDynamicImports: true })), plugins: [ resolve(), commonjs(), @@ -117,9 +118,8 @@ export default Object.assign([ { input: 'test/unittests.js', output: [ - { file: 'test/lib/unittests-bundle.js', format: 'es', intro, sourcemap: true } + { file: 'test/lib/unittests-bundle.js', format: 'es', intro, sourcemap: true, inlineDynamicImports: true } ], - inlineDynamicImports: true, external: nodeBuiltinModules.concat(nodeDependencies), plugins: [ alias({ From 690346a854f77c454725983f187651015f25b12c Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Mon, 11 Sep 2023 17:32:01 +0200 Subject: [PATCH 082/201] Refuse to use keys without key flags, add `config.allowMissingKeyFlags` Key flags are needed to restrict key usage to specific purposes: https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#section-5.2.3.29 . Some older keys (e.g. from OpenPGP.js v1) do not declare any key flags. In previous OpenPGP.js versions, we've allowed such keys to be used for any operation for which they were compatible. This behaviour has now changed, and these keys are not allowed to be used for any operation. The setting `config.allowMissingKeyFlags` has been added to selectively revert to the past behaviour. --- openpgp.d.ts | 1 + src/config/config.js | 9 +++++- src/key/helper.js | 61 +++++++++++++++++++++++++-------------- src/key/key.js | 6 ++-- test/general/key.js | 6 ++-- test/general/signature.js | 2 +- 6 files changed, 57 insertions(+), 28 deletions(-) diff --git a/openpgp.d.ts b/openpgp.d.ts index d50d8a49..2b5509b4 100644 --- a/openpgp.d.ts +++ b/openpgp.d.ts @@ -326,6 +326,7 @@ interface Config { commentString: string; allowInsecureDecryptionWithSigningKeys: boolean; allowInsecureVerificationWithReformattedKeys: boolean; + allowMissingKeyFlags: boolean; constantTimePKCS1Decryption: boolean; constantTimePKCS1DecryptionSupportedSymmetricAlgorithms: Set; v6Keys: boolean; diff --git a/src/config/config.js b/src/config/config.js index c03c0cad..fe944d7a 100644 --- a/src/config/config.js +++ b/src/config/config.js @@ -174,7 +174,14 @@ export default { * @property {Boolean} allowInsecureDecryptionWithSigningKeys */ allowInsecureVerificationWithReformattedKeys: false, - + /** + * Allow using keys that do not have any key flags set. + * Key flags are needed to restrict key usage to specific purposes: for instance, a signing key could only be allowed to certify other keys, and not sign messages + * (see https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#section-5.2.3.29). + * Some older keys do not declare any key flags, which means they are not allowed to be used for any operation. + * This setting allows using such keys for any operation for which they are compatible, based on their public key algorithm. + */ + allowMissingKeyFlags: false, /** * Enable constant-time decryption of RSA- and ElGamal-encrypted session keys, to hinder Bleichenbacher-like attacks (https://link.springer.com/chapter/10.1007/BFb0055716). * This setting has measurable performance impact and it is only helpful in application scenarios where both of the following conditions apply: diff --git a/src/key/helper.js b/src/key/helper.js index babaf3e6..f2f48e38 100644 --- a/src/key/helper.js +++ b/src/key/helper.js @@ -357,32 +357,51 @@ export function sanitizeKeyOptions(options, subkeyDefaults = {}) { return options; } -export function isValidSigningKeyPacket(keyPacket, signature) { - const keyAlgo = keyPacket.algorithm; - return keyAlgo !== enums.publicKey.rsaEncrypt && - keyAlgo !== enums.publicKey.elgamal && - keyAlgo !== enums.publicKey.ecdh && - keyAlgo !== enums.publicKey.x25519 && - keyAlgo !== enums.publicKey.x448 && - (!signature.keyFlags || - (signature.keyFlags[0] & enums.keyFlags.signData) !== 0); +export function isValidSigningKeyPacket(keyPacket, signature, config) { + switch (keyPacket.algorithm) { + case enums.publicKey.rsaEncryptSign: + case enums.publicKey.rsaSign: + case enums.publicKey.dsa: + case enums.publicKey.ecdsa: + case enums.publicKey.eddsaLegacy: + case enums.publicKey.ed25519: + case enums.publicKey.ed448: { + if (!signature.keyFlags && !config.allowMissingKeyFlags) { + throw new Error('None of the key flags is set: consider passing `config.allowMissingKeyFlags`'); + } + + return !signature.keyFlags || + (signature.keyFlags[0] & enums.keyFlags.signData) !== 0; + } + } } -export function isValidEncryptionKeyPacket(keyPacket, signature) { - const keyAlgo = keyPacket.algorithm; - return keyAlgo !== enums.publicKey.dsa && - keyAlgo !== enums.publicKey.rsaSign && - keyAlgo !== enums.publicKey.ecdsa && - keyAlgo !== enums.publicKey.eddsaLegacy && - keyAlgo !== enums.publicKey.ed25519 && - keyAlgo !== enums.publicKey.ed448 && - (!signature.keyFlags || - (signature.keyFlags[0] & enums.keyFlags.encryptCommunication) !== 0 || - (signature.keyFlags[0] & enums.keyFlags.encryptStorage) !== 0); +export function isValidEncryptionKeyPacket(keyPacket, signature, config) { + switch (keyPacket.algorithm) { + case enums.publicKey.rsaEncryptSign: + case enums.publicKey.rsaEncrypt: + case enums.publicKey.elgamal: + case enums.publicKey.ecdh: + case enums.publicKey.x25519: + case enums.publicKey.x448: { + if (!signature.keyFlags && !config.allowMissingKeyFlags) { + throw new Error('None of the key flags is set: consider passing `config.allowMissingKeyFlags`'); + } + + return !signature.keyFlags || + (signature.keyFlags[0] & enums.keyFlags.encryptCommunication) !== 0 || + (signature.keyFlags[0] & enums.keyFlags.encryptStorage) !== 0; + } + } } export function isValidDecryptionKeyPacket(signature, config) { - if (config.allowInsecureDecryptionWithSigningKeys) { + if (!signature.keyFlags && !config.allowMissingKeyFlags) { + throw new Error('None of the key flags is set: consider passing `config.allowMissingKeyFlags`'); + } + + const isValidSigningKeyPacket = !signature.keyFlags || (signature.keyFlags[0] & enums.keyFlags.signData) !== 0; + if (isValidSigningKeyPacket && config.allowInsecureDecryptionWithSigningKeys) { // This is only relevant for RSA keys, all other signing algorithms cannot decrypt return true; } diff --git a/src/key/key.js b/src/key/key.js index 3b1ed8c2..0349ae96 100644 --- a/src/key/key.js +++ b/src/key/key.js @@ -269,7 +269,7 @@ class Key { const bindingSignature = await helper.getLatestValidSignature( subkey.bindingSignatures, primaryKey, enums.signature.subkeyBinding, dataToVerify, date, config ); - if (!helper.isValidSigningKeyPacket(subkey.keyPacket, bindingSignature)) { + if (!helper.isValidSigningKeyPacket(subkey.keyPacket, bindingSignature, config)) { continue; } if (!bindingSignature.embeddedSignature) { @@ -322,7 +322,7 @@ class Key { await subkey.verify(date, config); const dataToVerify = { key: primaryKey, bind: subkey.keyPacket }; const bindingSignature = await helper.getLatestValidSignature(subkey.bindingSignatures, primaryKey, enums.signature.subkeyBinding, dataToVerify, date, config); - if (helper.isValidEncryptionKeyPacket(subkey.keyPacket, bindingSignature)) { + if (helper.isValidEncryptionKeyPacket(subkey.keyPacket, bindingSignature, config)) { helper.checkKeyRequirements(subkey.keyPacket, config); return subkey; } @@ -336,7 +336,7 @@ class Key { // if no valid subkey for encryption, evaluate primary key const selfCertification = await this.getPrimarySelfSignature(date, userID, config); if ((!keyID || primaryKey.getKeyID().equals(keyID)) && - helper.isValidEncryptionKeyPacket(primaryKey, selfCertification)) { + helper.isValidEncryptionKeyPacket(primaryKey, selfCertification, config)) { helper.checkKeyRequirements(primaryKey, config); return this; } diff --git a/test/general/key.js b/test/general/key.js index f1ee51a1..341b95d8 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -3402,7 +3402,7 @@ PzIEeL7UH3trraFmi+Gq8u4kAA== expect(selfCertification.valid).to.be.true; const certifyingKey = await openpgp.readKey({ armoredKey: certifying_key }); - const certifyingSigningKey = await certifyingKey.getSigningKey(); + const certifyingSigningKey = await certifyingKey.getSigningKey(undefined, undefined, undefined, { ...openpgp.config, allowMissingKeyFlags: true }); const signatures = await pubKey.verifyPrimaryUser([certifyingKey]); expect(signatures.length).to.equal(2); expect(signatures[0].keyID.toHex()).to.equal(publicSigningKey.getKeyID().toHex()); @@ -3411,7 +3411,9 @@ PzIEeL7UH3trraFmi+Gq8u4kAA== expect(signatures[1].valid).to.be.false; const { user } = await pubKey.getPrimaryUser(); - await expect(user.verifyCertificate(user.otherCertifications[0], [certifyingKey], undefined, openpgp.config)).to.be.rejectedWith('User certificate is revoked'); + await expect( + user.verifyCertificate(user.otherCertifications[0], [certifyingKey], undefined, { ...openpgp.config, allowMissingKeyFlags: true }) + ).to.be.rejectedWith('User certificate is revoked'); } finally { openpgp.config.rejectPublicKeyAlgorithms = rejectPublicKeyAlgorithms; } diff --git a/test/general/signature.js b/test/general/signature.js index 63ce14ba..01a3a0c0 100644 --- a/test/general/signature.js +++ b/test/general/signature.js @@ -2188,7 +2188,7 @@ uDvEBgD+LCEUOPejUTCMqPyd04ssdOq1AlMJOmUGUwLk7kFP7Aw= const message = await openpgp.createMessage({ text: content }); await message.appendSignature(detachedSig); - const { data, signatures } = await openpgp.verify({ verificationKeys:[publicKey], message, config: { minRSABits: 1024 } }); + const { data, signatures } = await openpgp.verify({ verificationKeys:[publicKey], message, config: { minRSABits: 1024, allowMissingKeyFlags: true } }); expect(data).to.equal(content); expect(signatures).to.have.length(1); expect(await signatures[0].verified).to.be.true; From 917faa56f55b7a3322a30c0451b4b1f6c3ae9aa0 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Mon, 18 Sep 2023 16:21:57 +0200 Subject: [PATCH 083/201] Rename internal functions, filter key algos on decryption --- src/key/helper.js | 61 +++++++++++++++++++++++++----------------- src/key/key.js | 8 +++--- src/key/private_key.js | 4 +-- 3 files changed, 42 insertions(+), 31 deletions(-) diff --git a/src/key/helper.js b/src/key/helper.js index f2f48e38..d440cab2 100644 --- a/src/key/helper.js +++ b/src/key/helper.js @@ -357,7 +357,7 @@ export function sanitizeKeyOptions(options, subkeyDefaults = {}) { return options; } -export function isValidSigningKeyPacket(keyPacket, signature, config) { +export function validateSigningKeyPacket(keyPacket, signature, config) { switch (keyPacket.algorithm) { case enums.publicKey.rsaEncryptSign: case enums.publicKey.rsaSign: @@ -365,18 +365,41 @@ export function isValidSigningKeyPacket(keyPacket, signature, config) { case enums.publicKey.ecdsa: case enums.publicKey.eddsaLegacy: case enums.publicKey.ed25519: - case enums.publicKey.ed448: { + case enums.publicKey.ed448: if (!signature.keyFlags && !config.allowMissingKeyFlags) { throw new Error('None of the key flags is set: consider passing `config.allowMissingKeyFlags`'); } - return !signature.keyFlags || (signature.keyFlags[0] & enums.keyFlags.signData) !== 0; - } + default: + return false; } } -export function isValidEncryptionKeyPacket(keyPacket, signature, config) { +export function validateEncryptionKeyPacket(keyPacket, signature, config) { + switch (keyPacket.algorithm) { + case enums.publicKey.rsaEncryptSign: + case enums.publicKey.rsaEncrypt: + case enums.publicKey.elgamal: + case enums.publicKey.ecdh: + case enums.publicKey.x25519: + case enums.publicKey.x448: + if (!signature.keyFlags && !config.allowMissingKeyFlags) { + throw new Error('None of the key flags is set: consider passing `config.allowMissingKeyFlags`'); + } + return !signature.keyFlags || + (signature.keyFlags[0] & enums.keyFlags.encryptCommunication) !== 0 || + (signature.keyFlags[0] & enums.keyFlags.encryptStorage) !== 0; + default: + return false; + } +} + +export function validateDecryptionKeyPacket(keyPacket, signature, config) { + if (!signature.keyFlags && !config.allowMissingKeyFlags) { + throw new Error('None of the key flags is set: consider passing `config.allowMissingKeyFlags`'); + } + switch (keyPacket.algorithm) { case enums.publicKey.rsaEncryptSign: case enums.publicKey.rsaEncrypt: @@ -384,33 +407,21 @@ export function isValidEncryptionKeyPacket(keyPacket, signature, config) { case enums.publicKey.ecdh: case enums.publicKey.x25519: case enums.publicKey.x448: { - if (!signature.keyFlags && !config.allowMissingKeyFlags) { - throw new Error('None of the key flags is set: consider passing `config.allowMissingKeyFlags`'); + const isValidSigningKeyPacket = !signature.keyFlags || (signature.keyFlags[0] & enums.keyFlags.signData) !== 0; + if (isValidSigningKeyPacket && config.allowInsecureDecryptionWithSigningKeys) { + // This is only relevant for RSA keys, all other signing algorithms cannot decrypt + return true; } return !signature.keyFlags || - (signature.keyFlags[0] & enums.keyFlags.encryptCommunication) !== 0 || - (signature.keyFlags[0] & enums.keyFlags.encryptStorage) !== 0; + (signature.keyFlags[0] & enums.keyFlags.encryptCommunication) !== 0 || + (signature.keyFlags[0] & enums.keyFlags.encryptStorage) !== 0; } + default: + return false; } } -export function isValidDecryptionKeyPacket(signature, config) { - if (!signature.keyFlags && !config.allowMissingKeyFlags) { - throw new Error('None of the key flags is set: consider passing `config.allowMissingKeyFlags`'); - } - - const isValidSigningKeyPacket = !signature.keyFlags || (signature.keyFlags[0] & enums.keyFlags.signData) !== 0; - if (isValidSigningKeyPacket && config.allowInsecureDecryptionWithSigningKeys) { - // This is only relevant for RSA keys, all other signing algorithms cannot decrypt - return true; - } - - return !signature.keyFlags || - (signature.keyFlags[0] & enums.keyFlags.encryptCommunication) !== 0 || - (signature.keyFlags[0] & enums.keyFlags.encryptStorage) !== 0; -} - /** * Check key against blacklisted algorithms and minimum strength requirements. * @param {SecretKeyPacket|PublicKeyPacket| diff --git a/src/key/key.js b/src/key/key.js index 0349ae96..43154a88 100644 --- a/src/key/key.js +++ b/src/key/key.js @@ -269,7 +269,7 @@ class Key { const bindingSignature = await helper.getLatestValidSignature( subkey.bindingSignatures, primaryKey, enums.signature.subkeyBinding, dataToVerify, date, config ); - if (!helper.isValidSigningKeyPacket(subkey.keyPacket, bindingSignature, config)) { + if (!helper.validateSigningKeyPacket(subkey.keyPacket, bindingSignature, config)) { continue; } if (!bindingSignature.embeddedSignature) { @@ -290,7 +290,7 @@ class Key { try { const selfCertification = await this.getPrimarySelfSignature(date, userID, config); if ((!keyID || primaryKey.getKeyID().equals(keyID)) && - helper.isValidSigningKeyPacket(primaryKey, selfCertification, config)) { + helper.validateSigningKeyPacket(primaryKey, selfCertification, config)) { helper.checkKeyRequirements(primaryKey, config); return this; } @@ -322,7 +322,7 @@ class Key { await subkey.verify(date, config); const dataToVerify = { key: primaryKey, bind: subkey.keyPacket }; const bindingSignature = await helper.getLatestValidSignature(subkey.bindingSignatures, primaryKey, enums.signature.subkeyBinding, dataToVerify, date, config); - if (helper.isValidEncryptionKeyPacket(subkey.keyPacket, bindingSignature, config)) { + if (helper.validateEncryptionKeyPacket(subkey.keyPacket, bindingSignature, config)) { helper.checkKeyRequirements(subkey.keyPacket, config); return subkey; } @@ -336,7 +336,7 @@ class Key { // if no valid subkey for encryption, evaluate primary key const selfCertification = await this.getPrimarySelfSignature(date, userID, config); if ((!keyID || primaryKey.getKeyID().equals(keyID)) && - helper.isValidEncryptionKeyPacket(primaryKey, selfCertification, config)) { + helper.validateEncryptionKeyPacket(primaryKey, selfCertification, config)) { helper.checkKeyRequirements(primaryKey, config); return this; } diff --git a/src/key/private_key.js b/src/key/private_key.js index 9fe89ca9..3c6fe474 100644 --- a/src/key/private_key.js +++ b/src/key/private_key.js @@ -85,7 +85,7 @@ class PrivateKey extends PublicKey { try { const dataToVerify = { key: primaryKey, bind: this.subkeys[i].keyPacket }; const bindingSignature = await helper.getLatestValidSignature(this.subkeys[i].bindingSignatures, primaryKey, enums.signature.subkeyBinding, dataToVerify, date, config); - if (helper.isValidDecryptionKeyPacket(bindingSignature, config)) { + if (helper.validateDecryptionKeyPacket(this.subkeys[i].keyPacket, bindingSignature, config)) { keys.push(this.subkeys[i]); } } catch (e) {} @@ -95,7 +95,7 @@ class PrivateKey extends PublicKey { // evaluate primary key const selfCertification = await this.getPrimarySelfSignature(date, userID, config); if ((!keyID || primaryKey.getKeyID().equals(keyID, true)) && - helper.isValidDecryptionKeyPacket(selfCertification, config)) { + helper.validateDecryptionKeyPacket(primaryKey, selfCertification, config)) { keys.push(this); } From 30635c72e8862e89278accf917cdb0b2ec974890 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Thu, 19 Oct 2023 15:04:41 +0200 Subject: [PATCH 084/201] Lint: error on unnecessary switch-case braces Also fix some indent issues with armoring code detected after required ESLint update. s --- .eslintrc.cjs | 4 +- package-lock.json | 1089 ++++++++++++----- package.json | 1 + src/crypto/crypto.js | 3 +- src/crypto/public_key/elliptic/ecdh.js | 7 +- src/crypto/public_key/elliptic/ecdsa.js | 3 +- src/crypto/public_key/elliptic/eddsa.js | 3 +- src/crypto/public_key/elliptic/oid_curves.js | 3 +- src/crypto/signature.js | 3 +- src/encoding/armor.js | 12 +- .../public_key_encrypted_session_key.js | 3 +- 11 files changed, 775 insertions(+), 356 deletions(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 7d077cba..2dd0f1c4 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -13,7 +13,8 @@ module.exports = { 'plugins': [ 'chai-friendly', - 'import' + 'import', + 'unicorn' ], 'globals': { // TODO are all these necessary? @@ -118,6 +119,7 @@ module.exports = { 'max-lines': [2, { 'max': 620, 'skipBlankLines': true, 'skipComments': true }], 'no-unused-expressions': 0, 'chai-friendly/no-unused-expressions': [2, { 'allowShortCircuit': true }], + 'unicorn/switch-case-braces': ['error', 'avoid'], // Custom warnings: 'no-console': 1 diff --git a/package-lock.json b/package-lock.json index df83d7e4..1c9d18f1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,6 +36,7 @@ "eslint-config-airbnb-base": "^15.0.0", "eslint-plugin-chai-friendly": "^0.7.2", "eslint-plugin-import": "^2.27.5", + "eslint-plugin-unicorn": "^48.0.1", "fflate": "^0.7.4", "http-server": "^14.1.1", "karma": "^6.4.0", @@ -58,6 +59,15 @@ "node": ">= 16.0.0" } }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/@babel/code-frame": { "version": "7.21.4", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", @@ -141,9 +151,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true, "engines": { "node": ">=6.9.0" @@ -336,15 +346,39 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.9.1.tgz", + "integrity": "sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, "node_modules/@eslint/eslintrc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", - "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", + "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.4.0", + "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -383,9 +417,9 @@ } }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -415,10 +449,19 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "node_modules/@eslint/js": { + "version": "8.51.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.51.0.tgz", + "integrity": "sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.8", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", - "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "version": "0.11.11", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", + "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", @@ -791,18 +834,6 @@ } } }, - "node_modules/@rollup/plugin-node-resolve/node_modules/builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@rollup/plugin-node-resolve/node_modules/is-builtin-module": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", @@ -1053,6 +1084,12 @@ "integrity": "sha512-LB2R1Oyhpg8gu4SON/mfforE525+Hi/M1ineICEDftqNVTyFg1aRIeGuTvXAoWHc4nbrFncWtJgMmoyRvuGh7A==", "dev": true }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.3.tgz", + "integrity": "sha512-ehPtgRgaULsFG8x0NeYJvmyH1hmlfsNLujHe9dQEia/7MAJYdzMSi19JtchUHjmBA6XC/75dK55mzZH+RyieSg==", + "dev": true + }, "node_modules/@types/resolve": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", @@ -1073,9 +1110,9 @@ } }, "node_modules/acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -1551,12 +1588,15 @@ "dev": true }, "node_modules/builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/bytes": { @@ -1734,6 +1774,18 @@ "node": ">=8" } }, + "node_modules/clean-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", + "integrity": "sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/cliui": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", @@ -2304,49 +2356,47 @@ } }, "node_modules/eslint": { - "version": "8.34.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.34.0.tgz", - "integrity": "sha512-1Z8iFsucw+7kSqXNZVslXS8Ioa4u2KM7GPwuKtkTFAqZ/cHMcEaR+1+Br0wLlot49cNxIiZk5wp8EAbPcYZxTg==", + "version": "8.51.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.51.0.tgz", + "integrity": "sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.4.1", - "@humanwhocodes/config-array": "^0.11.8", + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "8.51.0", + "@humanwhocodes/config-array": "^0.11.11", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "globals": "^13.19.0", - "grapheme-splitter": "^1.0.4", + "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "bin": { @@ -2646,10 +2696,84 @@ "semver": "bin/semver.js" } }, + "node_modules/eslint-plugin-unicorn": { + "version": "48.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-48.0.1.tgz", + "integrity": "sha512-FW+4r20myG/DqFcCSzoumaddKBicIPeFnTrifon2mWIzlfyvzwyqZjqVP7m4Cqr/ZYisS2aiLghkUWaPg6vtCw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.5", + "@eslint-community/eslint-utils": "^4.4.0", + "ci-info": "^3.8.0", + "clean-regexp": "^1.0.0", + "esquery": "^1.5.0", + "indent-string": "^4.0.0", + "is-builtin-module": "^3.2.1", + "jsesc": "^3.0.2", + "lodash": "^4.17.21", + "pluralize": "^8.0.0", + "read-pkg-up": "^7.0.1", + "regexp-tree": "^0.1.27", + "regjsparser": "^0.10.0", + "semver": "^7.5.4", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" + }, + "peerDependencies": { + "eslint": ">=8.44.0" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, + "dependencies": { + "builtin-modules": "^3.3.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", @@ -2657,33 +2781,21 @@ }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" + "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "engines": { - "node": ">=10" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint/node_modules/argparse": { @@ -2733,15 +2845,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, "node_modules/eslint/node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -2788,14 +2891,14 @@ "dev": true }, "node_modules/espree": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", - "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "dependencies": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2804,15 +2907,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, "node_modules/esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", @@ -2827,9 +2921,9 @@ } }, "node_modules/esquery": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.2.tgz", - "integrity": "sha512-JVSoLdTlTDkmjFmab7H/9SL9qGSyjElT3myyKp7krqjVFQCDLmj1QFaCLRFBszBKI0XVZaiiXvuPIX3ZwHe1Ng==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "dependencies": { "estraverse": "^5.1.0" @@ -3054,15 +3148,6 @@ "node": ">=6" } }, - "node_modules/find-cache-dir/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/find-cache-dir/node_modules/path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", @@ -3361,10 +3446,10 @@ "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", "dev": true }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, "node_modules/has": { @@ -3618,6 +3703,15 @@ "node": ">=0.8.19" } }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -3693,18 +3787,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-builtin-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", - "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", - "dev": true, - "dependencies": { - "builtin-modules": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -4142,16 +4224,6 @@ "node": ">=6" } }, - "node_modules/js-sdsl": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", - "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/js-sdsl" - } - }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -4198,6 +4270,12 @@ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -4605,6 +4683,12 @@ "node": ">= 0.8.0" } }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, "node_modules/linkify-it": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", @@ -4764,6 +4848,24 @@ "get-func-name": "^2.0.0" } }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lru-cache/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/magic-string": { "version": "0.27.0", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", @@ -4920,6 +5022,15 @@ "node": ">= 0.6" } }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/minimalistic-assert": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", @@ -5323,13 +5434,13 @@ } }, "node_modules/normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, "dependencies": { "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", + "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" } @@ -5434,15 +5545,6 @@ "node": ">=6" } }, - "node_modules/nyc/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/nyc/node_modules/path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", @@ -5603,17 +5705,17 @@ } }, "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "type-check": "^0.4.0" }, "engines": { "node": ">= 0.8.0" @@ -5658,6 +5760,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/package-hash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-3.0.0.tgz", @@ -5691,6 +5802,24 @@ "node": ">=6" } }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -5806,6 +5935,15 @@ "node": ">=14" } }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/portfinder": { "version": "1.0.28", "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", @@ -5992,6 +6130,108 @@ "dev": true, "peer": true }, + "node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -6011,6 +6251,15 @@ "dev": true, "peer": true }, + "node_modules/regexp-tree": { + "version": "0.1.27", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", + "integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==", + "dev": true, + "bin": { + "regexp-tree": "bin/regexp-tree" + } + }, "node_modules/regexp.prototype.flags": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", @@ -6028,16 +6277,25 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "node_modules/regjsparser": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.10.0.tgz", + "integrity": "sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "jsesc": "~0.5.0" }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" } }, "node_modules/release-zalgo": { @@ -6648,6 +6906,18 @@ "node": ">=4" } }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -6829,15 +7099,6 @@ "node": ">=6" } }, - "node_modules/test-exclude/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/test-exclude/node_modules/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -7272,15 +7533,6 @@ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/workerpool": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", @@ -7498,15 +7750,6 @@ "node": ">=6" } }, - "node_modules/yargs/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/yargs/node_modules/path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", @@ -7539,6 +7782,12 @@ } }, "dependencies": { + "@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true + }, "@babel/code-frame": { "version": "7.21.4", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", @@ -7601,9 +7850,9 @@ "dev": true }, "@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true }, "@babel/highlight": { @@ -7759,15 +8008,30 @@ } } }, + "@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^3.3.0" + } + }, + "@eslint-community/regexpp": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.9.1.tgz", + "integrity": "sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==", + "dev": true + }, "@eslint/eslintrc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", - "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", + "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.4.0", + "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -7792,9 +8056,9 @@ } }, "globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -7817,10 +8081,16 @@ } } }, + "@eslint/js": { + "version": "8.51.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.51.0.tgz", + "integrity": "sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg==", + "dev": true + }, "@humanwhocodes/config-array": { - "version": "0.11.8", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", - "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "version": "0.11.11", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", + "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.1", @@ -8086,12 +8356,6 @@ "resolve": "^1.22.1" }, "dependencies": { - "builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", - "dev": true - }, "is-builtin-module": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", @@ -8299,6 +8563,12 @@ "integrity": "sha512-LB2R1Oyhpg8gu4SON/mfforE525+Hi/M1ineICEDftqNVTyFg1aRIeGuTvXAoWHc4nbrFncWtJgMmoyRvuGh7A==", "dev": true }, + "@types/normalize-package-data": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.3.tgz", + "integrity": "sha512-ehPtgRgaULsFG8x0NeYJvmyH1hmlfsNLujHe9dQEia/7MAJYdzMSi19JtchUHjmBA6XC/75dK55mzZH+RyieSg==", + "dev": true + }, "@types/resolve": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", @@ -8316,9 +8586,9 @@ } }, "acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", "dev": true }, "acorn-jsx": { @@ -8696,9 +8966,9 @@ "dev": true }, "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", "dev": true }, "bytes": { @@ -8825,6 +9095,15 @@ "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", "dev": true }, + "clean-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", + "integrity": "sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, "cliui": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", @@ -9291,49 +9570,47 @@ "dev": true }, "eslint": { - "version": "8.34.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.34.0.tgz", - "integrity": "sha512-1Z8iFsucw+7kSqXNZVslXS8Ioa4u2KM7GPwuKtkTFAqZ/cHMcEaR+1+Br0wLlot49cNxIiZk5wp8EAbPcYZxTg==", + "version": "8.51.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.51.0.tgz", + "integrity": "sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.4.1", - "@humanwhocodes/config-array": "^0.11.8", + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "8.51.0", + "@humanwhocodes/config-array": "^0.11.11", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "globals": "^13.19.0", - "grapheme-splitter": "^1.0.4", + "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "dependencies": { @@ -9367,12 +9644,6 @@ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, - "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true - }, "glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -9636,50 +9907,80 @@ "peer": true, "requires": {} }, + "eslint-plugin-unicorn": { + "version": "48.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-48.0.1.tgz", + "integrity": "sha512-FW+4r20myG/DqFcCSzoumaddKBicIPeFnTrifon2mWIzlfyvzwyqZjqVP7m4Cqr/ZYisS2aiLghkUWaPg6vtCw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.22.5", + "@eslint-community/eslint-utils": "^4.4.0", + "ci-info": "^3.8.0", + "clean-regexp": "^1.0.0", + "esquery": "^1.5.0", + "indent-string": "^4.0.0", + "is-builtin-module": "^3.2.1", + "jsesc": "^3.0.2", + "lodash": "^4.17.21", + "pluralize": "^8.0.0", + "read-pkg-up": "^7.0.1", + "regexp-tree": "^0.1.27", + "regjsparser": "^0.10.0", + "semver": "^7.5.4", + "strip-indent": "^3.0.0" + }, + "dependencies": { + "is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, + "requires": { + "builtin-modules": "^3.3.0" + } + }, + "jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true + }, + "semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, "eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "requires": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - } - } + "eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true }, "espree": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", - "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "requires": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true - } + "eslint-visitor-keys": "^3.4.1" } }, "esprima": { @@ -9689,9 +9990,9 @@ "dev": true }, "esquery": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.2.tgz", - "integrity": "sha512-JVSoLdTlTDkmjFmab7H/9SL9qGSyjElT3myyKp7krqjVFQCDLmj1QFaCLRFBszBKI0XVZaiiXvuPIX3ZwHe1Ng==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "requires": { "estraverse": "^5.1.0" @@ -9876,12 +10177,6 @@ "p-limit": "^2.0.0" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", @@ -10105,10 +10400,10 @@ "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", "dev": true }, - "grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, "has": { @@ -10302,6 +10597,12 @@ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -10362,15 +10663,6 @@ "has-tostringtag": "^1.0.0" } }, - "is-builtin-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", - "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", - "dev": true, - "requires": { - "builtin-modules": "^1.0.0" - } - }, "is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -10684,12 +10976,6 @@ "html-escaper": "^2.0.0" } }, - "js-sdsl": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", - "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==", - "dev": true - }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -10727,6 +11013,12 @@ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -11063,6 +11355,12 @@ "type-check": "~0.4.0" } }, + "lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, "linkify-it": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", @@ -11194,6 +11492,23 @@ "get-func-name": "^2.0.0" } }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + }, + "dependencies": { + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, "magic-string": { "version": "0.27.0", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", @@ -11317,6 +11632,12 @@ "mime-db": "1.51.0" } }, + "min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true + }, "minimalistic-assert": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", @@ -11633,13 +11954,13 @@ } }, "normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, "requires": { "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", + "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" } @@ -11720,12 +12041,6 @@ "p-limit": "^2.0.0" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", @@ -11843,17 +12158,17 @@ "dev": true }, "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "requires": { + "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "type-check": "^0.4.0" } }, "os-homedir": { @@ -11880,6 +12195,12 @@ "p-limit": "^3.0.2" } }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, "package-hash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-3.0.0.tgz", @@ -11909,6 +12230,18 @@ "callsites": "^3.0.0" } }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -11990,6 +12323,12 @@ "integrity": "sha512-7AnRmTCf+GVYhHbLJsGUtskWTE33SwMZkybJ0v6rqR1boxq2x36U7p1vDRV7HO2IwTZgmycracLxPEJI49wu4g==", "dev": true }, + "pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true + }, "portfinder": { "version": "1.0.28", "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", @@ -12129,6 +12468,82 @@ "dev": true, "peer": true }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, "readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -12145,6 +12560,12 @@ "dev": true, "peer": true }, + "regexp-tree": { + "version": "0.1.27", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", + "integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==", + "dev": true + }, "regexp.prototype.flags": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", @@ -12156,11 +12577,22 @@ "functions-have-names": "^1.2.2" } }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true + "regjsparser": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.10.0.tgz", + "integrity": "sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "dev": true + } + } }, "release-zalgo": { "version": "1.0.0", @@ -12639,6 +13071,15 @@ "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true }, + "strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "requires": { + "min-indent": "^1.0.0" + } + }, "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -12775,12 +13216,6 @@ "p-limit": "^2.0.0" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -13097,12 +13532,6 @@ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, - "word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true - }, "workerpool": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", @@ -13232,12 +13661,6 @@ "p-limit": "^2.0.0" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", diff --git a/package.json b/package.json index 98d3a89a..cd04fb7a 100644 --- a/package.json +++ b/package.json @@ -86,6 +86,7 @@ "eslint-config-airbnb-base": "^15.0.0", "eslint-plugin-chai-friendly": "^0.7.2", "eslint-plugin-import": "^2.27.5", + "eslint-plugin-unicorn": "^48.0.1", "fflate": "^0.7.4", "http-server": "^14.1.1", "karma": "^6.4.0", diff --git a/src/crypto/crypto.js b/src/crypto/crypto.js index 2576bd88..f24c4a74 100644 --- a/src/crypto/crypto.js +++ b/src/crypto/crypto.js @@ -331,12 +331,11 @@ export function generateParams(algo, bits, oid) { switch (algo) { case enums.publicKey.rsaEncrypt: case enums.publicKey.rsaEncryptSign: - case enums.publicKey.rsaSign: { + case enums.publicKey.rsaSign: return publicKey.rsa.generate(bits, 65537).then(({ n, e, d, p, q, u }) => ({ privateParams: { d, p, q, u }, publicParams: { n, e } })); - } case enums.publicKey.ecdsa: return publicKey.elliptic.generate(oid).then(({ oid, Q, secret }) => ({ privateParams: { d: secret }, diff --git a/src/crypto/public_key/elliptic/ecdh.js b/src/crypto/public_key/elliptic/ecdh.js index 3ea593d7..7d749d63 100644 --- a/src/crypto/public_key/elliptic/ecdh.js +++ b/src/crypto/public_key/elliptic/ecdh.js @@ -110,9 +110,9 @@ async function genPublicEphemeralKey(curve, Q) { break; case 'node': return nodePublicEphemeralKey(curve, Q); - default: { + default: return jsPublicEphemeralKey(curve, Q); - } + } } @@ -173,9 +173,8 @@ async function genPrivateEphemeralKey(curve, V, Q, d) { break; case 'node': return nodePrivateEphemeralKey(curve, V, d); - default: { + default: return jsPrivateEphemeralKey(curve, V, d); - } } } diff --git a/src/crypto/public_key/elliptic/ecdsa.js b/src/crypto/public_key/elliptic/ecdsa.js index b90bed2b..8c186d46 100644 --- a/src/crypto/public_key/elliptic/ecdsa.js +++ b/src/crypto/public_key/elliptic/ecdsa.js @@ -48,7 +48,7 @@ export async function sign(oid, hashAlgo, message, publicKey, privateKey, hashed if (message && !util.isStream(message)) { const keyPair = { publicKey, privateKey }; switch (curve.type) { - case 'web': { + case 'web': // If browser doesn't support a curve, we'll catch it try { // Need to await to make sure browser succeeds @@ -63,7 +63,6 @@ export async function sign(oid, hashAlgo, message, publicKey, privateKey, hashed util.printDebugError('Browser did not support signing: ' + err.message); } break; - } case 'node': { const signature = await nodeSign(curve, hashAlgo, message, keyPair); return { diff --git a/src/crypto/public_key/elliptic/eddsa.js b/src/crypto/public_key/elliptic/eddsa.js index c13665ea..1e6aac2f 100644 --- a/src/crypto/public_key/elliptic/eddsa.js +++ b/src/crypto/public_key/elliptic/eddsa.js @@ -100,9 +100,8 @@ export async function verify(algo, hashAlgo, { RS }, m, publicKey, hashed) { throw new Error('Hash algorithm too weak for EdDSA.'); } switch (algo) { - case enums.publicKey.ed25519: { + case enums.publicKey.ed25519: return ed25519.sign.detached.verify(hashed, RS, publicKey); - } case enums.publicKey.ed448: { const ed448 = await util.getNobleCurve(enums.publicKey.ed448); return ed448.verify(RS, hashed, publicKey); diff --git a/src/crypto/public_key/elliptic/oid_curves.js b/src/crypto/public_key/elliptic/oid_curves.js index 75c23827..57bcc4df 100644 --- a/src/crypto/public_key/elliptic/oid_curves.js +++ b/src/crypto/public_key/elliptic/oid_curves.js @@ -192,9 +192,8 @@ class CurveWithOID { const publicKey = util.concatUint8Array([new Uint8Array([0x40]), keyPair.publicKey]); return { publicKey, privateKey }; } - default: { + default: return jsGenKeyPair(this.name); - } } } } diff --git a/src/crypto/signature.js b/src/crypto/signature.js index 5f0ceeab..d9574ad1 100644 --- a/src/crypto/signature.js +++ b/src/crypto/signature.js @@ -153,9 +153,8 @@ export async function sign(algo, hashAlgo, publicKeyParams, privateKeyParams, da const { x } = privateKeyParams; return publicKey.dsa.sign(hashAlgo, hashed, g, p, q, x); } - case enums.publicKey.elgamal: { + case enums.publicKey.elgamal: throw new Error('Signing with Elgamal is not defined in the OpenPGP standard.'); - } case enums.publicKey.ecdsa: { const { oid, Q } = publicKeyParams; const { d } = privateKeyParams; diff --git a/src/encoding/armor.js b/src/encoding/armor.js index 2177683f..8686d131 100644 --- a/src/encoding/armor.js +++ b/src/encoding/armor.js @@ -47,33 +47,33 @@ function getType(text) { // parts, and this is the Xth part out of Y. if (/MESSAGE, PART \d+\/\d+/.test(header[1])) { return enums.armor.multipartSection; - } else + } // BEGIN PGP MESSAGE, PART X // Used for multi-part messages, where this is the Xth part of an // unspecified number of parts. Requires the MESSAGE-ID Armor // Header to be used. if (/MESSAGE, PART \d+/.test(header[1])) { return enums.armor.multipartLast; - } else + } // BEGIN PGP SIGNED MESSAGE if (/SIGNED MESSAGE/.test(header[1])) { return enums.armor.signed; - } else + } // BEGIN PGP MESSAGE // Used for signed, encrypted, or compressed files. if (/MESSAGE/.test(header[1])) { return enums.armor.message; - } else + } // BEGIN PGP PUBLIC KEY BLOCK // Used for armoring public keys. if (/PUBLIC KEY BLOCK/.test(header[1])) { return enums.armor.publicKey; - } else + } // BEGIN PGP PRIVATE KEY BLOCK // Used for armoring private keys. if (/PRIVATE KEY BLOCK/.test(header[1])) { return enums.armor.privateKey; - } else + } // BEGIN PGP SIGNATURE // Used for detached signatures, OpenPGP/MIME signatures, and // cleartext signatures. Note that PGP 2.x uses BEGIN PGP MESSAGE diff --git a/src/packet/public_key_encrypted_session_key.js b/src/packet/public_key_encrypted_session_key.js index 2618ce32..1f6c1d04 100644 --- a/src/packet/public_key_encrypted_session_key.js +++ b/src/packet/public_key_encrypted_session_key.js @@ -218,14 +218,13 @@ function encodeSessionKey(version, keyAlgo, cipherAlgo, sessionKeyData) { case enums.publicKey.rsaEncrypt: case enums.publicKey.rsaEncryptSign: case enums.publicKey.elgamal: - case enums.publicKey.ecdh: { + case enums.publicKey.ecdh: // add checksum return util.concatUint8Array([ new Uint8Array(version === 6 ? [] : [cipherAlgo]), sessionKeyData, util.writeChecksum(sessionKeyData.subarray(sessionKeyData.length % 8)) ]); - } case enums.publicKey.x25519: case enums.publicKey.x448: return sessionKeyData; From 0da131cd9aa7791d64f9c2507cb845d819a2fbc0 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Tue, 24 Oct 2023 17:19:10 +0200 Subject: [PATCH 085/201] Update README --- README.md | 52 +++++++++++++++++++++++++--------------------------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 030ff800..72e5bf2f 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ OpenPGP.js [![BrowserStack Status](https://automate.browserstack.com/badge.svg?badge_key=N1l2eHFOanVBMU9wYWxJM3ZnWERnc1lidkt5UkRqa3BralV3SWVhOGpGTT0tLVljSjE4Z3dzVmdiQjl6RWgxb2c3T2c9PQ==--5864052cd523f751b6b907d547ac9c4c5f88c8a3)](https://automate.browserstack.com/public-build/N1l2eHFOanVBMU9wYWxJM3ZnWERnc1lidkt5UkRqa3BralV3SWVhOGpGTT0tLVljSjE4Z3dzVmdiQjl6RWgxb2c3T2c9PQ==--5864052cd523f751b6b907d547ac9c4c5f88c8a3) [![Join the chat on Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/openpgpjs/openpgpjs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) ========== -[OpenPGP.js](https://openpgpjs.org/) is a JavaScript implementation of the OpenPGP protocol. It implements [RFC4880](https://tools.ietf.org/html/rfc4880) and parts of [RFC4880bis](https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-10). +[OpenPGP.js](https://openpgpjs.org/) is a JavaScript implementation of the OpenPGP protocol. It implements the [crypto-refresh](https://datatracker.ietf.org/doc/draft-ietf-openpgp-crypto-refresh) (superseding [RFC4880](https://tools.ietf.org/html/rfc4880) and [RFC4880bis](https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-10)). **Table of Contents** @@ -33,22 +33,22 @@ OpenPGP.js [![BrowserStack Status](https://automate.browserstack.com/badge.svg?b ### Platform Support -* The `dist/openpgp.min.js` bundle works well with recent versions of Chrome, Firefox, Safari and Edge. +* The `dist/openpgp.min.js` (or `.mjs`) bundle works with recent versions of Chrome, Firefox, Edge and Safari 13+. -* The `dist/node/openpgp.min.js` bundle works well in Node.js. It is used by default when you `require('openpgp')` in Node.js. +* The `dist/node/openpgp.min.mjs` (or `.cjs`) bundle works in Node.js v16+: it is used by default when you `import ... from 'openpgp'` (resp. `require('openpgp')`). -* Currently, Chrome, Safari and Edge have partial implementations of the -[Streams specification](https://streams.spec.whatwg.org/), and Firefox -has a partial implementation behind feature flags. Chrome is the only -browser that implements `TransformStream`s, which we need, so we include -a [polyfill](https://github.com/MattiasBuelens/web-streams-polyfill) for -all other browsers. Please note that in those browsers, the global -`ReadableStream` property gets overwritten with the polyfill version if -it exists. In some edge cases, you might need to use the native +* Streaming support: the latest versions of Chrome, Firefox, Edge and Safari implement the +[Streams specification](https://streams.spec.whatwg.org/), including `TransformStream`s. +These are needed if you use the library with streamed inputs. +In previous versions of OpenPGP.js, WebStreams were automatically polyfilled by the library, +but from v6 this task is left up to the library user, due to the more extensive browser support, and the +polyfilling side-effects. If you're working with [older browsers versions which do not implement e.g. TransformStreams](https://developer.mozilla.org/en-US/docs/Web/API/TransformStream), you can manually +load [WebStream polyfill](https://github.com/MattiasBuelens/web-streams-polyfills). +Please note that when you load the polyfills, the global `ReadableStream` property (if it exists) gets overwritten with the polyfill version. +In some edge cases, you might need to use the native `ReadableStream` (for example when using it to create a `Response` object), in which case you should store a reference to it before loading -OpenPGP.js. There is also the -[web-streams-adapter](https://github.com/MattiasBuelens/web-streams-adapter) +the polyfills. There is also the [web-streams-adapter](https://github.com/MattiasBuelens/web-streams-adapter) library to convert back and forth between them. ### Performance @@ -71,21 +71,20 @@ library to convert back and forth between them. \** the curve25519 and ed25519 implementations are algorithmically constant-time, but may not be constant-time after optimizations of the JavaScript compiler \*** these curves are only constant-time if the underlying native implementation is available and constant-time -* Version 2.x of the library has been built from the ground up with Uint8Arrays. This allows for much better performance and memory usage than strings. - * If the user's browser supports [native WebCrypto](https://caniuse.com/#feat=cryptography) via the `window.crypto.subtle` API, this will be used. Under Node.js the native [crypto module](https://nodejs.org/api/crypto.html#crypto_crypto) is used. -* The library implements the [IETF proposal](https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-10) for authenticated encryption using native AES-EAX, OCB, or GCM. This makes symmetric encryption up to 30x faster on supported platforms. Since the specification has not been finalized and other OpenPGP implementations haven't adopted it yet, the feature is currently behind a flag. **Note: activating this setting can break compatibility with other OpenPGP implementations, and also with future versions of OpenPGP.js. Don't use it with messages you want to store on disk or in a database.** You can enable it by setting `openpgp.config.aeadProtect = true`. +* The library implements authenticated encryption (AEAD) as per the ["crypto refresh" draft standard](https://datatracker.ietf.org/doc/draft-ietf-openpgp-crypto-refresh) using AES-OCB, EAX, or GCM. This makes symmetric encryption faster on platforms with native implementations. However, since the specification is very recent and other OpenPGP implementations are in the process of adopting it, the feature is currently behind a flag. **Note: activating this setting can break compatibility with other OpenPGP implementations which have yet to implement the feature.** You can enable it by setting `openpgp.config.aeadProtect = true`. +Note that this setting has a different effect from the one in OpenPGP.js v5, which implemented support for a provisional version of AEAD from [RFC4880bis](https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-10), which was modified in a later draft of the crypto refresh. You can change the AEAD mode by setting one of the following options: ``` - openpgp.config.preferredAEADAlgorithm = openpgp.enums.aead.eax // Default, native - openpgp.config.preferredAEADAlgorithm = openpgp.enums.aead.ocb // Non-native - openpgp.config.preferredAEADAlgorithm = openpgp.enums.aead.experimentalGCM // **Non-standard**, fastest + openpgp.config.preferredAEADAlgorithm = openpgp.enums.aead.ocb; // Default (widest ecosystem support), non-native + openpgp.config.preferredAEADAlgorithm = openpgp.enums.aead.gcm; // Native in WebCrypto and Node.js + openpgp.config.preferredAEADAlgorithm = openpgp.enums.aead.eax; // Native in Node.js ``` -* For environments that don't provide native crypto, the library falls back to [asm.js](https://caniuse.com/#feat=asmjs) implementations of AES, SHA-1, and SHA-256. +* For environments that don't provide native crypto, the library falls back to [asm.js](https://caniuse.com/#feat=asmjs) AES and AEAD implementations. ### Getting started @@ -98,18 +97,17 @@ Install OpenPGP.js using npm and save it in your dependencies: npm install --save openpgp ``` -And import it as a CommonJS module: +And import it as an ES module, from a .mjs file: +```js +import * as openpgp from 'openpgp'; +``` + +Or as a CommonJS module: ```js const openpgp = require('openpgp'); ``` -Or as an ES6 module, from an .mjs file: - -```js -import * as openpgp from 'openpgp'; -``` - #### Deno (experimental) Import as an ES6 module, using /dist/openpgp.mjs. From 7881b850ec303df735acff4614aa4dd31663a5ad Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Wed, 25 Oct 2023 12:55:43 +0200 Subject: [PATCH 086/201] 6.0.0-alpha.0 --- docs/AEADEncryptedDataPacket.html | 227 +- docs/Argon2S2K.html | 986 +++ docs/CleartextMessage.html | 16 +- docs/CompressedDataPacket.html | 22 +- docs/Key.html | 300 +- docs/LiteralDataPacket.html | 24 +- docs/MarkerPacket.html | 8 +- docs/Message.html | 79 +- docs/OnePassSignaturePacket.html | 156 +- docs/PacketList.html | 18 +- docs/PaddingPacket.html | 600 ++ docs/PrivateKey.html | 36 +- docs/PublicKey.html | 12 +- docs/PublicKeyEncryptedSessionKeyPacket.html | 18 +- docs/PublicKeyPacket.html | 50 +- docs/PublicSubkeyPacket.html | 50 +- docs/SecretKeyPacket.html | 76 +- docs/SecretSubkeyPacket.html | 76 +- docs/Signature.html | 12 +- docs/SignaturePacket.html | 28 +- ...EncryptedIntegrityProtectedDataPacket.html | 154 +- docs/SymEncryptedSessionKeyPacket.html | 20 +- docs/SymmetricallyEncryptedDataPacket.html | 14 +- docs/TrustPacket.html | 8 +- docs/UserAttributePacket.html | 12 +- docs/UserIDPacket.html | 14 +- docs/global.html | 1035 ++- docs/index.html | 52 +- docs/module-config.html | 672 +- docs/module-crypto.html | 184 + docs/module-crypto_aes_kw.html | 553 ++ docs/module-crypto_cipher.html | 1430 ++++ docs/module-crypto_cmac.html | 413 ++ docs/module-crypto_crypto.html | 3000 ++++++++ docs/module-crypto_hash.html | 596 ++ docs/module-crypto_hkdf.html | 167 + docs/module-crypto_mode.html | 439 ++ docs/module-crypto_mode_cfb.html | 548 ++ docs/module-crypto_mode_eax.html | 748 ++ docs/module-crypto_mode_gcm.html | 334 + docs/module-crypto_mode_ocb.html | 747 ++ docs/module-crypto_pkcs1.html | 882 +++ docs/module-crypto_public_key.html | 439 ++ docs/module-crypto_public_key_dsa.html | 1084 +++ docs/module-crypto_public_key_elgamal.html | 981 +++ docs/module-crypto_public_key_elliptic.html | 180 + ...dule-crypto_public_key_elliptic_curve.html | 1149 ++++ ...odule-crypto_public_key_elliptic_ecdh.html | 6011 +++++++++++++++++ ...dule-crypto_public_key_elliptic_ecdsa.html | 1017 +++ ...dule-crypto_public_key_elliptic_eddsa.html | 1106 +++ ...ypto_public_key_elliptic_eddsa_legacy.html | 927 +++ docs/module-crypto_public_key_prime.html | 954 +++ docs/module-crypto_public_key_rsa.html | 2279 +++++++ docs/module-crypto_random.html | 516 ++ docs/module-crypto_signature.html | 917 +++ docs/module-encoding_base64.html | 769 +++ docs/module-enums.html | 272 +- docs/module-key_Subkey-Subkey.html | 47 +- docs/module-key_Subkey.html | 92 + docs/module-key_User-User.html | 27 +- docs/module-key_User.html | 92 + docs/module-key_helper.html | 2867 ++++++++ docs/module-packet_packet.html | 866 +++ docs/module-type_ecdh_symkey.html | 167 + docs/module-type_kdf_params-KDFParams.html | 10 +- docs/module-type_keyid-KeyID.html | 21 +- docs/module-type_keyid.html | 92 + docs/module-type_oid.html | 178 + ...K.html => module-type_s2k-GenericS2K.html} | 29 +- docs/module-type_s2k.html | 180 + docs/module-type_x25519x448_symkey.html | 6 +- docs/module-util.html | 167 + package-lock.json | 4 +- package.json | 2 +- 74 files changed, 37225 insertions(+), 1039 deletions(-) create mode 100644 docs/Argon2S2K.html create mode 100644 docs/PaddingPacket.html create mode 100644 docs/module-crypto.html create mode 100644 docs/module-crypto_aes_kw.html create mode 100644 docs/module-crypto_cipher.html create mode 100644 docs/module-crypto_cmac.html create mode 100644 docs/module-crypto_crypto.html create mode 100644 docs/module-crypto_hash.html create mode 100644 docs/module-crypto_hkdf.html create mode 100644 docs/module-crypto_mode.html create mode 100644 docs/module-crypto_mode_cfb.html create mode 100644 docs/module-crypto_mode_eax.html create mode 100644 docs/module-crypto_mode_gcm.html create mode 100644 docs/module-crypto_mode_ocb.html create mode 100644 docs/module-crypto_pkcs1.html create mode 100644 docs/module-crypto_public_key.html create mode 100644 docs/module-crypto_public_key_dsa.html create mode 100644 docs/module-crypto_public_key_elgamal.html create mode 100644 docs/module-crypto_public_key_elliptic.html create mode 100644 docs/module-crypto_public_key_elliptic_curve.html create mode 100644 docs/module-crypto_public_key_elliptic_ecdh.html create mode 100644 docs/module-crypto_public_key_elliptic_ecdsa.html create mode 100644 docs/module-crypto_public_key_elliptic_eddsa.html create mode 100644 docs/module-crypto_public_key_elliptic_eddsa_legacy.html create mode 100644 docs/module-crypto_public_key_prime.html create mode 100644 docs/module-crypto_public_key_rsa.html create mode 100644 docs/module-crypto_random.html create mode 100644 docs/module-crypto_signature.html create mode 100644 docs/module-encoding_base64.html create mode 100644 docs/module-key_Subkey.html create mode 100644 docs/module-key_User.html create mode 100644 docs/module-key_helper.html create mode 100644 docs/module-packet_packet.html create mode 100644 docs/module-type_ecdh_symkey.html create mode 100644 docs/module-type_keyid.html create mode 100644 docs/module-type_oid.html rename docs/{module-type_s2k-S2K.html => module-type_s2k-GenericS2K.html} (51%) create mode 100644 docs/module-type_s2k.html create mode 100644 docs/module-util.html diff --git a/docs/AEADEncryptedDataPacket.html b/docs/AEADEncryptedDataPacket.html index cd95975d..da6470c6 100644 --- a/docs/AEADEncryptedDataPacket.html +++ b/docs/AEADEncryptedDataPacket.html @@ -98,7 +98,7 @@ AEAD Protected Data Packet

Source:
@@ -200,7 +200,7 @@ AEAD Protected Data Packet

Source:
@@ -270,7 +270,7 @@ AEAD Protected Data Packet

Source:
@@ -298,215 +298,6 @@ AEAD Protected Data Packet

-

(async) crypt(fn, key, data) → {Promise.<(Uint8Array|ReadableStream.<Uint8Array>)>}

- - - - - - -
-

En/decrypt the payload.

-
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
fn - - -encrypt -| - -decrypt - - - -

Whether to encrypt or decrypt

key - - -Uint8Array - - - -

The session key used to en/decrypt the payload

data - - -Uint8Array -| - -ReadableStream.<Uint8Array> - - - -

The data to en/decrypt

- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Promise.<(Uint8Array|ReadableStream.<Uint8Array>)> - - -
-
- - - - - - - - - - - - -

(async) decrypt(sessionKeyAlgorithm, key, configopt)

@@ -684,7 +475,7 @@ AEAD Protected Data Packet

Source:
@@ -926,7 +717,7 @@ AEAD Protected Data Packet

Source:
@@ -1097,7 +888,7 @@ AEAD Protected Data Packet

Source:
@@ -1216,7 +1007,7 @@ AEAD Protected Data Packet

Source:
@@ -1287,13 +1078,13 @@ AEAD Protected Data Packet


diff --git a/docs/Argon2S2K.html b/docs/Argon2S2K.html new file mode 100644 index 00000000..7cbeb4ff --- /dev/null +++ b/docs/Argon2S2K.html @@ -0,0 +1,986 @@ + + + + + JSDoc: Class: Argon2S2K + + + + + + + + + + +
+ +

Class: Argon2S2K

+ + + + + + +
+ +
+ +

Argon2S2K(configopt)

+ + +
+ +
+
+ + + + + + +

new Argon2S2K(configopt)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDescription
config + + +Object + + + + + + <optional>
+ + + + + +

Full configuration, defaults to openpgp.config

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +

Members

+ + + +

encodedM :Integer

+ + + + +
+

exponent indicating memory size

+
+ + + +
Type:
+
    +
  • + +Integer + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

p :Integer

+ + + + +
+

degree of parallelism (lanes)

+
+ + + +
Type:
+
    +
  • + +Integer + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

salt :Uint8Array

+ + + + +
+

16 bytes of salt

+
+ + + +
Type:
+
    +
  • + +Uint8Array + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

t :Integer

+ + + + +
+

number of passes

+
+ + + +
Type:
+
    +
  • + +Integer + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + +

Methods

+ + + + + + + +

(async) produceKey(passphrase) → {Promise.<Uint8Array>}

+ + + + + + +
+

Produces a key using the specified passphrase and the defined +hashAlgorithm

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
passphrase + + +String + + + +

Passphrase containing user input

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Throws:
+ + + +
+ + +Argon2OutOfMemoryError +| + +Errors + + + +
+ + + + + +
Returns:
+ + +
+

Produced key with a length corresponding to keySize

+
+ + + +
+
+ Type +
+
+ +Promise.<Uint8Array> + + +
+
+ + + + + + + + + + + + + +

read(bytes) → {Integer}

+ + + + + + +
+

Parsing function for argon2 string-to-key specifier.

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
bytes + + +Uint8Array + + + +

Payload of argon2 string-to-key specifier

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Actual length of the object.

+
+ + + +
+
+ Type +
+
+ +Integer + + +
+
+ + + + + + + + + + + + + +

write() → {Uint8Array}

+ + + + + + +
+

Serializes s2k information

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Binary representation of s2k.

+
+ + + +
+
+ Type +
+
+ +Uint8Array + + +
+
+ + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/CleartextMessage.html b/docs/CleartextMessage.html index f58f77cc..1d6fba9e 100644 --- a/docs/CleartextMessage.html +++ b/docs/CleartextMessage.html @@ -168,7 +168,7 @@ See https://tools.ietf.o
Source:
@@ -346,7 +346,7 @@ See https://tools.ietf.o
Source:
@@ -461,7 +461,7 @@ See https://tools.ietf.o
Source:
@@ -573,7 +573,7 @@ See https://tools.ietf.o
Source:
@@ -974,7 +974,7 @@ See https://tools.ietf.o
Source:
@@ -1211,7 +1211,7 @@ See https://tools.ietf.o
Source:
@@ -1279,13 +1279,13 @@ See https://tools.ietf.o
diff --git a/docs/CompressedDataPacket.html b/docs/CompressedDataPacket.html index f6c10968..2a8a0504 100644 --- a/docs/CompressedDataPacket.html +++ b/docs/CompressedDataPacket.html @@ -160,7 +160,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

Source:
@@ -266,7 +266,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

Source:
@@ -343,7 +343,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

Source:
@@ -407,7 +407,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

Source:
@@ -481,7 +481,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

Source:
@@ -563,7 +563,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

Source:
@@ -715,7 +715,7 @@ read by read_packet

Source:
@@ -900,7 +900,7 @@ read by read_packet

Source:
@@ -990,7 +990,7 @@ read by read_packet

Source:
@@ -1061,13 +1061,13 @@ read by read_packet


diff --git a/docs/Key.html b/docs/Key.html index 96d8e75a..4eafe297 100644 --- a/docs/Key.html +++ b/docs/Key.html @@ -96,7 +96,7 @@ Can contain additional subkeys, signatures, user ids, user attributes.

Source:
@@ -333,7 +333,7 @@ if it is a valid revocation signature.

Source:
@@ -514,7 +514,7 @@ if it is a valid revocation signature.

Source:
@@ -626,7 +626,7 @@ if it is a valid revocation signature.

Source:
@@ -738,7 +738,7 @@ if it is a valid revocation signature.

Source:
@@ -1006,7 +1006,7 @@ if it is a valid revocation signature.

Source:
@@ -1225,7 +1225,7 @@ Returns Infinity if the key doesn't expire, or null if
Source:
@@ -1333,7 +1333,7 @@ Returns Infinity if the key doesn't expire, or null if
Source:
@@ -1445,7 +1445,7 @@ Returns Infinity if the key doesn't expire, or null if
Source:
@@ -1557,7 +1557,7 @@ Returns Infinity if the key doesn't expire, or null if
Source:
@@ -1735,7 +1735,7 @@ If no keyID is given, returns all keys, starting with the primary key.

Source:
@@ -1793,6 +1793,248 @@ If no keyID is given, returns all keys, starting with the primary key.

+

(async) getPrimarySelfSignature(dateopt, userIDopt, configopt) → {Promise.<SignaturePacket>}

+ + + + + + +
+

For V4 keys, returns the self-signature of the primary user. +For V5 keys, returns the latest valid direct-key self-signature. +This self-signature is to be used to check the key expiration, +algorithm preferences, and so on.

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDescription
date + + +Date + + + + + + <optional>
+ + + + + +

Use the given date for verification instead of the current time

userID + + +Object + + + + + + <optional>
+ + + + + +

User ID to get instead of the primary user for V4 keys, if it exists

config + + +Object + + + + + + <optional>
+ + + + + +

Full configuration, defaults to openpgp.config

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

The primary self-signature

+
+ + + +
+
+ Type +
+
+ +Promise.<SignaturePacket> + + +
+
+ + + + + + + + + + + + +

(async) getPrimaryUser(dateopt, userIDopt, configopt) → {Promise.<{user: User, selfCertification: SignaturePacket}>}

@@ -1978,7 +2220,7 @@ If no keyID is given, returns all keys, starting with the primary key.

Source:
@@ -2183,7 +2425,7 @@ If no keyID is given, returns all keys, starting with the primary key.

Source:
@@ -2475,7 +2717,7 @@ If no keyID is given, returns all keys, starting with the primary key.

Source:
@@ -2669,7 +2911,7 @@ If no keyID is given, returns all subkeys.

Source:
@@ -2781,7 +3023,7 @@ If no keyID is given, returns all subkeys.

Source:
@@ -2893,7 +3135,7 @@ If no keyID is given, returns all subkeys.

Source:
@@ -3170,7 +3412,7 @@ If no keyID is given, returns all subkeys.

Source:
@@ -3354,7 +3596,7 @@ If no keyID is given, returns all subkeys.

Source:
@@ -3569,7 +3811,7 @@ If no keyID is given, returns all subkeys.

Source:
@@ -3839,7 +4081,7 @@ If no keyID is given, returns all subkeys.

Source:
@@ -3951,7 +4193,7 @@ If no keyID is given, returns all subkeys.

Source:
@@ -4192,7 +4434,7 @@ a private key is returned.

Source:
@@ -4435,7 +4677,7 @@ a private key is returned.

Source:
@@ -4676,7 +4918,7 @@ and valid self signature. Throws if the primary key is invalid.

Source:
@@ -4959,7 +5201,7 @@ and valid self signature. Throws if the primary key is invalid.

Source:
@@ -5072,7 +5314,7 @@ Signature validity is null if the verification keys do not correspond to the cer
Source:
@@ -5140,13 +5382,13 @@ Signature validity is null if the verification keys do not correspond to the cer
diff --git a/docs/LiteralDataPacket.html b/docs/LiteralDataPacket.html index 91a1c9a0..c3d734a8 100644 --- a/docs/LiteralDataPacket.html +++ b/docs/LiteralDataPacket.html @@ -147,7 +147,7 @@ further interpreted.

Source:
@@ -326,7 +326,7 @@ further interpreted.

Source:
@@ -441,7 +441,7 @@ further interpreted.

Source:
@@ -623,7 +623,7 @@ with normalized end of line to \n

Source:
@@ -790,7 +790,7 @@ with normalized end of line to \n

Source:
@@ -977,7 +977,7 @@ with normalized end of line to \n

Source:
@@ -1116,7 +1116,7 @@ with normalized end of line to \n

Source:
@@ -1302,7 +1302,7 @@ will be normalized to \r\n and by default text is converted to UTF8

Source:
@@ -1392,7 +1392,7 @@ will be normalized to \r\n and by default text is converted to UTF8

Source:
@@ -1507,7 +1507,7 @@ will be normalized to \r\n and by default text is converted to UTF8

Source:
@@ -1575,13 +1575,13 @@ will be normalized to \r\n and by default text is converted to UTF8


diff --git a/docs/MarkerPacket.html b/docs/MarkerPacket.html index c93faeec..d41e366f 100644 --- a/docs/MarkerPacket.html +++ b/docs/MarkerPacket.html @@ -106,7 +106,7 @@ software is necessary to process the message.

Source:
@@ -265,7 +265,7 @@ software is necessary to process the message.

Source:
@@ -333,13 +333,13 @@ software is necessary to process the message.


diff --git a/docs/Message.html b/docs/Message.html index d01d613e..47b41564 100644 --- a/docs/Message.html +++ b/docs/Message.html @@ -146,7 +146,7 @@ See https://tools.iet
Source:
@@ -661,7 +661,7 @@ See https://tools.iet
Source:
@@ -933,7 +933,7 @@ See https://tools.iet
Source:
@@ -1140,7 +1140,7 @@ See https://tools.iet
Source:
@@ -1291,7 +1291,7 @@ See https://tools.iet
Source:
@@ -1495,7 +1495,7 @@ See https://tools.iet
Source:
@@ -1800,7 +1800,7 @@ See https://tools.iet
Source:
@@ -1858,7 +1858,7 @@ See https://tools.iet -

(async) decryptSessionKeys(decryptionKeysopt, passwordsopt, dateopt, configopt) → {Promise.<Array.<{data: Uint8Array, algorithm: String}>>}

+

(async) decryptSessionKeys(decryptionKeysopt, passwordsopt, expectedSymmetricAlgorithmopt, dateopt, configopt) → {Promise.<Array.<{data: Uint8Array, algorithm: String}>>}

@@ -1968,6 +1968,39 @@ See
https://tools.iet + + + expectedSymmetricAlgorithm + + + + + +enums.symmetric + + + + + + + + + <optional>
+ + + + + + + + + + +

The symmetric algorithm the SEIPDv2 / AEAD packet is encrypted with (if applicable)

+ + + + date @@ -2072,7 +2105,7 @@ See
https://tools.iet
Source:
@@ -2512,7 +2545,7 @@ See https://tools.iet
Source:
@@ -2624,7 +2657,7 @@ See https://tools.iet
Source:
@@ -2736,7 +2769,7 @@ See https://tools.iet
Source:
@@ -2851,7 +2884,7 @@ See https://tools.iet
Source:
@@ -2966,7 +2999,7 @@ See https://tools.iet
Source:
@@ -3078,7 +3111,7 @@ See https://tools.iet
Source:
@@ -3482,7 +3515,7 @@ See https://tools.iet
Source:
@@ -3883,7 +3916,7 @@ See https://tools.iet
Source:
@@ -3995,7 +4028,7 @@ See https://tools.iet
Source:
@@ -4232,7 +4265,7 @@ See https://tools.iet
Source:
@@ -4498,7 +4531,7 @@ See https://tools.iet
Source:
@@ -4610,7 +4643,7 @@ See https://tools.iet
Source:
@@ -4678,13 +4711,13 @@ See https://tools.iet
diff --git a/docs/OnePassSignaturePacket.html b/docs/OnePassSignaturePacket.html index 75d42bad..0d385ee7 100644 --- a/docs/OnePassSignaturePacket.html +++ b/docs/OnePassSignaturePacket.html @@ -101,7 +101,7 @@ can compute the entire signed message in one pass.

Source:
@@ -199,7 +199,7 @@ that describes another signature to be applied to the same message data.

Source:
@@ -273,7 +273,7 @@ that describes another signature to be applied to the same message data.

Source:
@@ -298,13 +298,13 @@ that describes another signature to be applied to the same message data.

-

issuerKeyID

+

issuerFingerprint

-

An eight-octet number holding the Key ID of the signing key.

+

Only for v6 packets, 32 octets of the fingerprint of the signing key.

@@ -344,7 +344,71 @@ that describes another signature to be applied to the same message data.

Source:
+ + + + + + + + + + + + + + + + +

issuerKeyID

+ + + + +
+

Only for v3 packets, an eight-octet number holding the Key ID of the signing key.

+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
@@ -418,7 +482,7 @@ that describes another signature to be applied to the same message data.

Source:
@@ -443,6 +507,70 @@ that describes another signature to be applied to the same message data.

+

salt

+ + + + +
+

Only for v6, a variable-length field containing the salt.

+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + +

signatureType :enums.signature

@@ -501,7 +629,7 @@ Signature types are described in
Source:
@@ -525,7 +653,7 @@ Signature types are described in
-

A one-octet version number. The current version is 3.

+

A one-octet version number. The current versions are 3 and 6.

@@ -565,7 +693,7 @@ Signature types are described in
Source:
@@ -696,7 +824,7 @@ Signature types are described in
Source:
@@ -808,7 +936,7 @@ Signature types are described in
Source:
@@ -876,13 +1004,13 @@ Signature types are described in
diff --git a/docs/PacketList.html b/docs/PacketList.html index 2b1e9744..26512388 100644 --- a/docs/PacketList.html +++ b/docs/PacketList.html @@ -97,7 +97,7 @@ are stored as numerical indices.

Source:
@@ -345,7 +345,7 @@ Equivalent to calling read on an empty PacketList instance.

Source:
@@ -530,7 +530,7 @@ Equivalent to calling read on an empty PacketList instance.

Source:
@@ -687,7 +687,7 @@ Equivalent to calling read on an empty PacketList instance.

Source:
@@ -859,7 +859,7 @@ Equivalent to calling read on an empty PacketList instance.

Source:
@@ -1097,7 +1097,7 @@ Equivalent to calling read on an empty PacketList instance.

Source:
@@ -1200,7 +1200,7 @@ class instance.

Source:
@@ -1268,13 +1268,13 @@ class instance.


diff --git a/docs/PaddingPacket.html b/docs/PaddingPacket.html new file mode 100644 index 00000000..f61bf58f --- /dev/null +++ b/docs/PaddingPacket.html @@ -0,0 +1,600 @@ + + + + + JSDoc: Class: PaddingPacket + + + + + + + + + + +
+ +

Class: PaddingPacket

+ + + + + + +
+ +
+ +

PaddingPacket()

+ + + + +
+ +
+
+ + + + +

Constructor

+ + + +

new PaddingPacket()

+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

(async) createPadding(length)

+ + + + + + +
+

Create random padding.

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
length + + +Number + + + +

The length of padding to be generated.

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Throws:
+ + + +
+
+
+

if padding generation was not successful

+
+
+
+
+
+
+ Type +
+
+ +Error + + +
+
+
+
+
+ + + + + + + + + + + + + + + + +

read(bytes)

+ + + + + + +
+

Read a padding packet

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
bytes + + +Uint8Array +| + +ReadableStream.<Uint8Array> + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

write() → {Uint8Array}

+ + + + + + +
+

Write the padding packet

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

The padding packet.

+
+ + + +
+
+ Type +
+
+ +Uint8Array + + +
+
+ + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/PrivateKey.html b/docs/PrivateKey.html index 8b9799c3..492f3427 100644 --- a/docs/PrivateKey.html +++ b/docs/PrivateKey.html @@ -144,7 +144,7 @@
Source:
@@ -209,7 +209,8 @@

Generates a new OpenPGP subkey, and returns a clone of the Key object with the new subkey added. -Supports RSA and ECC keys. Defaults to the algorithm and bit size/curve of the primary key. DSA primary keys default to RSA subkeys.

+Supports RSA and ECC keys, as well as the newer Curve448 and Curve25519. +Defaults to the algorithm and bit size/curve of the primary key. DSA primary keys default to RSA subkeys.

@@ -255,6 +256,12 @@ Supports RSA and ECC keys. Defaults to the algorithm and bit size/curve of the p | rsa +| + +curve25519 +| + +curve448 @@ -264,7 +271,8 @@ Supports RSA and ECC keys. Defaults to the algorithm and bit size/curve of the p -

The subkey algorithm: ECC or RSA

+

The subkey algorithm: ECC, RSA, Curve448 or Curve25519 (new format). +Note: Curve448 and Curve25519 are not widely supported yet.

@@ -445,7 +453,7 @@ Supports RSA and ECC keys. Defaults to the algorithm and bit size/curve of the p
Source:
@@ -614,7 +622,7 @@ Supports RSA and ECC keys. Defaults to the algorithm and bit size/curve of the p
Source:
@@ -726,7 +734,7 @@ Supports RSA and ECC keys. Defaults to the algorithm and bit size/curve of the p
Source:
@@ -971,7 +979,7 @@ This is useful to retrieve keys for session key decryption

Source:
@@ -1084,7 +1092,7 @@ A dummy key is considered encrypted.

Source:
@@ -1174,7 +1182,7 @@ A dummy key is considered encrypted.

Source:
@@ -1477,7 +1485,7 @@ A dummy key is considered encrypted.

Source:
@@ -1589,7 +1597,7 @@ A dummy key is considered encrypted.

Source:
@@ -1766,7 +1774,7 @@ If only gnu-dummy keys are found, we cannot properly validate so we throw an err
Source:
@@ -1841,13 +1849,13 @@ If only gnu-dummy keys are found, we cannot properly validate so we throw an err
diff --git a/docs/PublicKey.html b/docs/PublicKey.html index c8edd749..0719a06c 100644 --- a/docs/PublicKey.html +++ b/docs/PublicKey.html @@ -144,7 +144,7 @@
Source:
@@ -315,7 +315,7 @@
Source:
@@ -427,7 +427,7 @@
Source:
@@ -535,7 +535,7 @@
Source:
@@ -603,13 +603,13 @@
diff --git a/docs/PublicKeyEncryptedSessionKeyPacket.html b/docs/PublicKeyEncryptedSessionKeyPacket.html index 337ea927..c9f05bd5 100644 --- a/docs/PublicKeyEncryptedSessionKeyPacket.html +++ b/docs/PublicKeyEncryptedSessionKeyPacket.html @@ -107,7 +107,7 @@ decrypt the message.

Source:
@@ -209,7 +209,7 @@ decrypt the message.

Source:
@@ -283,7 +283,7 @@ decrypt the message.

Source:
@@ -458,7 +458,7 @@ This is needed for constant-time processing. Expected object of the form: { sess
Source:
@@ -626,7 +626,7 @@ This is needed for constant-time processing. Expected object of the form: { sess
Source:
@@ -794,7 +794,7 @@ This is needed for constant-time processing. Expected object of the form: { sess
Source:
@@ -884,7 +884,7 @@ This is needed for constant-time processing. Expected object of the form: { sess
Source:
@@ -952,13 +952,13 @@ This is needed for constant-time processing. Expected object of the form: { sess
diff --git a/docs/PublicKeyPacket.html b/docs/PublicKeyPacket.html index a3063b29..476c16f1 100644 --- a/docs/PublicKeyPacket.html +++ b/docs/PublicKeyPacket.html @@ -195,7 +195,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -301,7 +301,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -375,7 +375,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -449,7 +449,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -523,7 +523,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -597,7 +597,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -671,7 +671,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -735,7 +735,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -816,7 +816,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -880,7 +880,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -1018,7 +1018,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -1130,7 +1130,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -1220,7 +1220,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -1310,7 +1310,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -1422,7 +1422,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -1530,7 +1530,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -1642,7 +1642,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -1754,7 +1754,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -1866,7 +1866,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -1978,7 +1978,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -2138,7 +2138,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -2250,7 +2250,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -2411,7 +2411,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -2457,13 +2457,13 @@ key (sometimes called an OpenPGP certificate).


diff --git a/docs/PublicSubkeyPacket.html b/docs/PublicSubkeyPacket.html index 4b838083..2725ce91 100644 --- a/docs/PublicSubkeyPacket.html +++ b/docs/PublicSubkeyPacket.html @@ -193,7 +193,7 @@ services.

Source:
@@ -315,7 +315,7 @@ services.

Source:
@@ -394,7 +394,7 @@ services.

Source:
@@ -473,7 +473,7 @@ services.

Source:
@@ -552,7 +552,7 @@ services.

Source:
@@ -631,7 +631,7 @@ services.

Source:
@@ -710,7 +710,7 @@ services.

Source:
@@ -779,7 +779,7 @@ services.

Source:
@@ -865,7 +865,7 @@ services.

Source:
@@ -934,7 +934,7 @@ services.

Source:
@@ -1072,7 +1072,7 @@ services.

Source:
@@ -1189,7 +1189,7 @@ services.

Source:
@@ -1284,7 +1284,7 @@ services.

Source:
@@ -1379,7 +1379,7 @@ services.

Source:
@@ -1496,7 +1496,7 @@ services.

Source:
@@ -1609,7 +1609,7 @@ services.

Source:
@@ -1726,7 +1726,7 @@ services.

Source:
@@ -1843,7 +1843,7 @@ services.

Source:
@@ -1960,7 +1960,7 @@ services.

Source:
@@ -2077,7 +2077,7 @@ services.

Source:
@@ -2242,7 +2242,7 @@ services.

Source:
@@ -2359,7 +2359,7 @@ services.

Source:
@@ -2525,7 +2525,7 @@ services.

Source:
@@ -2571,13 +2571,13 @@ services.


diff --git a/docs/SecretKeyPacket.html b/docs/SecretKeyPacket.html index b87b7bdf..59097cb0 100644 --- a/docs/SecretKeyPacket.html +++ b/docs/SecretKeyPacket.html @@ -191,7 +191,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -308,7 +308,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -387,7 +387,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -466,7 +466,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -545,7 +545,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -624,7 +624,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -688,7 +688,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -767,7 +767,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -831,7 +831,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -905,7 +905,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -984,7 +984,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -1053,7 +1053,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -1134,7 +1134,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -1208,7 +1208,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -1282,7 +1282,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -1361,7 +1361,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -1430,7 +1430,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -1519,7 +1519,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -1614,7 +1614,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -1709,7 +1709,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -1851,7 +1851,7 @@ otherwise calls to this function will throw an error.

Source:
@@ -2065,7 +2065,7 @@ This can be used to remove passphrase protection after calling decrypt().

Source:
@@ -2189,7 +2189,7 @@ This can be used to remove passphrase protection after calling decrypt().

Source:
@@ -2306,7 +2306,7 @@ This can be used to remove passphrase protection after calling decrypt().

Source:
@@ -2419,7 +2419,7 @@ This can be used to remove passphrase protection after calling decrypt().

Source:
@@ -2536,7 +2536,7 @@ This can be used to remove passphrase protection after calling decrypt().

Source:
@@ -2653,7 +2653,7 @@ This can be used to remove passphrase protection after calling decrypt().

Source:
@@ -2770,7 +2770,7 @@ This can be used to remove passphrase protection after calling decrypt().

Source:
@@ -2888,7 +2888,7 @@ Returns false for gnu-dummy keys and null for public keys.

Source:
@@ -2999,7 +2999,7 @@ Returns false for gnu-dummy keys and null for public keys.

Source:
@@ -3114,7 +3114,7 @@ Such keys are:

Source:
@@ -3266,7 +3266,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
Source:
@@ -3411,7 +3411,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
Source:
@@ -3501,7 +3501,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
Source:
@@ -3625,7 +3625,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
Source:
@@ -3791,7 +3791,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
Source:
@@ -3837,13 +3837,13 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
diff --git a/docs/SecretSubkeyPacket.html b/docs/SecretSubkeyPacket.html index 1c2050af..63f9b9b3 100644 --- a/docs/SecretSubkeyPacket.html +++ b/docs/SecretSubkeyPacket.html @@ -190,7 +190,7 @@ Key packet and has exactly the same format.

Source:
@@ -312,7 +312,7 @@ Key packet and has exactly the same format.

Source:
@@ -391,7 +391,7 @@ Key packet and has exactly the same format.

Source:
@@ -470,7 +470,7 @@ Key packet and has exactly the same format.

Source:
@@ -549,7 +549,7 @@ Key packet and has exactly the same format.

Source:
@@ -628,7 +628,7 @@ Key packet and has exactly the same format.

Source:
@@ -697,7 +697,7 @@ Key packet and has exactly the same format.

Source:
@@ -776,7 +776,7 @@ Key packet and has exactly the same format.

Source:
@@ -845,7 +845,7 @@ Key packet and has exactly the same format.

Source:
@@ -924,7 +924,7 @@ Key packet and has exactly the same format.

Source:
@@ -1003,7 +1003,7 @@ Key packet and has exactly the same format.

Source:
@@ -1072,7 +1072,7 @@ Key packet and has exactly the same format.

Source:
@@ -1158,7 +1158,7 @@ Key packet and has exactly the same format.

Source:
@@ -1237,7 +1237,7 @@ Key packet and has exactly the same format.

Source:
@@ -1316,7 +1316,7 @@ Key packet and has exactly the same format.

Source:
@@ -1395,7 +1395,7 @@ Key packet and has exactly the same format.

Source:
@@ -1464,7 +1464,7 @@ Key packet and has exactly the same format.

Source:
@@ -1558,7 +1558,7 @@ Key packet and has exactly the same format.

Source:
@@ -1653,7 +1653,7 @@ Key packet and has exactly the same format.

Source:
@@ -1748,7 +1748,7 @@ Key packet and has exactly the same format.

Source:
@@ -1895,7 +1895,7 @@ otherwise calls to this function will throw an error.

Source:
@@ -2114,7 +2114,7 @@ This can be used to remove passphrase protection after calling decrypt().

Source:
@@ -2238,7 +2238,7 @@ This can be used to remove passphrase protection after calling decrypt().

Source:
@@ -2355,7 +2355,7 @@ This can be used to remove passphrase protection after calling decrypt().

Source:
@@ -2468,7 +2468,7 @@ This can be used to remove passphrase protection after calling decrypt().

Source:
@@ -2585,7 +2585,7 @@ This can be used to remove passphrase protection after calling decrypt().

Source:
@@ -2702,7 +2702,7 @@ This can be used to remove passphrase protection after calling decrypt().

Source:
@@ -2819,7 +2819,7 @@ This can be used to remove passphrase protection after calling decrypt().

Source:
@@ -2937,7 +2937,7 @@ Returns false for gnu-dummy keys and null for public keys.

Source:
@@ -3053,7 +3053,7 @@ Returns false for gnu-dummy keys and null for public keys.

Source:
@@ -3173,7 +3173,7 @@ Such keys are:

Source:
@@ -3330,7 +3330,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
Source:
@@ -3475,7 +3475,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
Source:
@@ -3570,7 +3570,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
Source:
@@ -3694,7 +3694,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
Source:
@@ -3860,7 +3860,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
Source:
@@ -3906,13 +3906,13 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
diff --git a/docs/Signature.html b/docs/Signature.html index 71ab0cc2..16b92a51 100644 --- a/docs/Signature.html +++ b/docs/Signature.html @@ -144,7 +144,7 @@
Source:
@@ -322,7 +322,7 @@
Source:
@@ -434,7 +434,7 @@
Source:
@@ -546,7 +546,7 @@
Source:
@@ -614,13 +614,13 @@
diff --git a/docs/SignaturePacket.html b/docs/SignaturePacket.html index 6adcfe0b..f1b23612 100644 --- a/docs/SignaturePacket.html +++ b/docs/SignaturePacket.html @@ -99,7 +99,7 @@ block of text, and a signature that is a certification of a User ID.

Source:
@@ -201,7 +201,7 @@ block of text, and a signature that is a certification of a User ID.

Source:
@@ -271,7 +271,7 @@ block of text, and a signature that is a certification of a User ID.

Source:
@@ -341,7 +341,7 @@ block of text, and a signature that is a certification of a User ID.

Source:
@@ -423,7 +423,7 @@ block of text, and a signature that is a certification of a User ID.

Source:
@@ -599,7 +599,7 @@ block of text, and a signature that is a certification of a User ID.

Source:
@@ -760,7 +760,7 @@ block of text, and a signature that is a certification of a User ID.

Source:
@@ -1048,7 +1048,7 @@ block of text, and a signature that is a certification of a User ID.

Source:
@@ -1427,7 +1427,7 @@ block of text, and a signature that is a certification of a User ID.

Source:
@@ -1546,7 +1546,7 @@ block of text, and a signature that is a certification of a User ID.

Source:
@@ -1654,7 +1654,7 @@ block of text, and a signature that is a certification of a User ID.

Source:
@@ -1765,7 +1765,7 @@ block of text, and a signature that is a certification of a User ID.

Source:
@@ -1833,13 +1833,13 @@ block of text, and a signature that is a certification of a User ID.


diff --git a/docs/SymEncryptedIntegrityProtectedDataPacket.html b/docs/SymEncryptedIntegrityProtectedDataPacket.html index f3c948c2..04cfd19d 100644 --- a/docs/SymEncryptedIntegrityProtectedDataPacket.html +++ b/docs/SymEncryptedIntegrityProtectedDataPacket.html @@ -101,7 +101,7 @@ packet.

Source:
@@ -147,6 +147,150 @@ packet.

+

Members

+ + + +

aeadAlgorithm :enums.aead

+ + + + + + +
Type:
+
    +
  • + +enums.aead + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

cipherAlgorithm :enums.symmetric

+ + + + + + +
Type:
+
    +
  • + +enums.symmetric + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + +

Methods

@@ -334,7 +478,7 @@ packet.

Source:
@@ -594,7 +738,7 @@ packet.

Source:
@@ -687,13 +831,13 @@ packet.


diff --git a/docs/SymEncryptedSessionKeyPacket.html b/docs/SymEncryptedSessionKeyPacket.html index 370d50d7..a2b46c0d 100644 --- a/docs/SymEncryptedSessionKeyPacket.html +++ b/docs/SymEncryptedSessionKeyPacket.html @@ -165,7 +165,7 @@ the Symmetric-Key Encrypted Session Key packet.

Source:
@@ -271,7 +271,7 @@ the Symmetric-Key Encrypted Session Key packet.

Source:
@@ -345,7 +345,7 @@ the Symmetric-Key Encrypted Session Key packet.

Source:
@@ -419,7 +419,7 @@ the Symmetric-Key Encrypted Session Key packet.

Source:
@@ -550,7 +550,7 @@ the Symmetric-Key Encrypted Session Key packet.

Source:
@@ -761,7 +761,7 @@ the Symmetric-Key Encrypted Session Key packet.

Source:
@@ -929,7 +929,7 @@ the Symmetric-Key Encrypted Session Key packet.

Source:
@@ -1019,7 +1019,7 @@ the Symmetric-Key Encrypted Session Key packet.

Source:
@@ -1087,13 +1087,13 @@ the Symmetric-Key Encrypted Session Key packet.


diff --git a/docs/SymmetricallyEncryptedDataPacket.html b/docs/SymmetricallyEncryptedDataPacket.html index 55718315..c7c01bec 100644 --- a/docs/SymmetricallyEncryptedDataPacket.html +++ b/docs/SymmetricallyEncryptedDataPacket.html @@ -101,7 +101,7 @@ that form whole OpenPGP messages).

Source:
@@ -197,7 +197,7 @@ that form whole OpenPGP messages).

Source:
@@ -271,7 +271,7 @@ that form whole OpenPGP messages).

Source:
@@ -477,7 +477,7 @@ See RFC 4880 9.2 f
Source:
@@ -720,7 +720,7 @@ See RFC 4880 9.2 f
Source:
@@ -795,13 +795,13 @@ See RFC 4880 9.2 f
diff --git a/docs/TrustPacket.html b/docs/TrustPacket.html index b2cbafa4..f9ce4086 100644 --- a/docs/TrustPacket.html +++ b/docs/TrustPacket.html @@ -105,7 +105,7 @@ other than local keyring files.

Source:
@@ -216,7 +216,7 @@ Currently not implemented as we ignore trust packets

Source:
@@ -262,13 +262,13 @@ Currently not implemented as we ignore trust packets


diff --git a/docs/UserAttributePacket.html b/docs/UserAttributePacket.html index d48d3906..1e485667 100644 --- a/docs/UserAttributePacket.html +++ b/docs/UserAttributePacket.html @@ -107,7 +107,7 @@ an implementation may use any method desired.

Source:
@@ -266,7 +266,7 @@ an implementation may use any method desired.

Source:
@@ -427,7 +427,7 @@ an implementation may use any method desired.

Source:
@@ -517,7 +517,7 @@ an implementation may use any method desired.

Source:
@@ -585,13 +585,13 @@ an implementation may use any method desired.


diff --git a/docs/UserIDPacket.html b/docs/UserIDPacket.html index 746a0779..78afa335 100644 --- a/docs/UserIDPacket.html +++ b/docs/UserIDPacket.html @@ -100,7 +100,7 @@ specifies the length of the User ID.

Source:
@@ -207,7 +207,7 @@ John Doe john@example.com

Source:
@@ -338,7 +338,7 @@ John Doe john@example.com

Source:
@@ -495,7 +495,7 @@ John Doe john@example.com

Source:
@@ -585,7 +585,7 @@ John Doe john@example.com

Source:
@@ -653,13 +653,13 @@ John Doe john@example.com


diff --git a/docs/global.html b/docs/global.html index 53c0c87b..c2ff19a6 100644 --- a/docs/global.html +++ b/docs/global.html @@ -161,7 +161,7 @@ This is used as fallback if the native Crypto APIs are not available.

Source:
@@ -443,7 +443,7 @@ This is used as fallback if the native Crypto APIs are not available.

Source:
@@ -656,7 +656,7 @@ This is used as fallback if the native Crypto APIs are not available.

Source:
@@ -795,7 +795,7 @@ This is used as fallback if the native Crypto APIs are not available.

Source:
@@ -1204,7 +1204,7 @@ This is used as fallback if the native Crypto APIs are not available.

Source:
@@ -1785,7 +1785,7 @@ One of decryptionKeys, sessionkeys or passwords<
Source:
@@ -1828,7 +1828,8 @@ One of decryptionKeys, sessionkeys or passwords< ] } -where `signatures` contains a separate entry for each signature packet found in the input message. +where `signatures` contains a separate entry for each signature packet found in the input message. +
@@ -2087,7 +2088,7 @@ This method does not change the original key.

Source:
@@ -2446,7 +2447,7 @@ One of decryptionKeys or passwords must be specified.<
Source:
@@ -2511,6 +2512,103 @@ One of decryptionKeys or passwords must be specified.< + + + + + + +

detectBigInt()

+ + + + + + +
+

We don't use the BigIntegerInterface wrapper from noble-hashes because:

+
    +
  • importing the instance results in it being shared with noble-hashes, which separately calls setImplementation() +on load, causing it to throw due to duplicate initialization.
  • +
  • even duplicating the interface code here to keep a separate instance requires handing a race-conditions the first time +getBigInteger is called, when the code needs to check if the implementation is set, and initialize it if not. +Ultimately, the interface provides no advantages and it's only needed because of TS.
  • +
+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + @@ -3250,7 +3348,7 @@ must be specified. If signing keys are specified, those will be used to sign the
Source:
@@ -3538,7 +3636,7 @@ This method does not change the original key.

Source:
@@ -4158,7 +4256,7 @@ At least one of encryptionKeys or passwords must be sp
Source:
@@ -4374,7 +4472,7 @@ At least one of encryptionKeys or passwords must be sp
Source:
@@ -4442,7 +4540,8 @@ At least one of encryptionKeys or passwords must be sp
-

Generates a new OpenPGP key pair. Supports RSA and ECC keys. By default, primary and subkeys will be of same type. +

Generates a new OpenPGP key pair. Supports RSA and ECC keys, as well as the newer Curve448 and Curve25519 keys. +By default, primary and subkeys will be of same type. The generated primary key will have signing capabilities. By default, one subkey with encryption capabilities is also generated.

@@ -4573,6 +4672,12 @@ The generated primary key will have signing capabilities. By default, one subkey | 'rsa' +| + +'curve448' +| + +'curve25519' @@ -4598,7 +4703,8 @@ The generated primary key will have signing capabilities. By default, one subkey -

The primary key algorithm type: ECC (default) or RSA

+

The primary key algorithm type: ECC (default for v4 keys), RSA, Curve448 or Curve25519 (new format, default for v6 keys). +Note: Curve448 and Curve25519 (new format) are not widely supported yet.

@@ -4710,13 +4816,13 @@ The generated primary key will have signing capabilities. By default, one subkey - 'curve25519' + 'curve25519Legacy'

Elliptic curve for ECC keys: -curve25519 (default), p256, p384, p521, secp256k1, +curve25519Legacy (default), p256, p384, p521, secp256k1, brainpoolP256r1, brainpoolP384r1, or brainpoolP512r1

@@ -4967,7 +5073,7 @@ default to main key options, except for sign parameter that default
Source:
@@ -5317,7 +5423,7 @@ default to main key options, except for sign parameter that default
Source:
@@ -5501,7 +5607,7 @@ default to main key options, except for sign parameter that default
Source:
@@ -5591,6 +5697,653 @@ default to main key options, except for sign parameter that default +

newS2KFromConfig() → {Object}

+ + + + + + +
+

Instantiate a new S2K instance based on the config settings

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Throws:
+ + + +
+
+
+

for unknown or unsupported types

+
+
+
+
+
+
+ Type +
+
+ +Error + + +
+
+
+
+
+ + + + + +
Returns:
+ + +
+

New s2k object

+
+ + + +
+
+ Type +
+
+ +Object + + +
+
+ + + + + + + + + + + + + +

newS2KFromType(type) → {Object}

+ + + + + + +
+

Instantiate a new S2K instance of the given type

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
type + + +module:enums.s2k + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Throws:
+ + + +
+
+
+

for unknown or unsupported types

+
+
+
+
+
+
+ Type +
+
+ +Error + + +
+
+
+
+
+ + + + + +
Returns:
+ + +
+

New s2k object

+
+ + + +
+
+ Type +
+
+ +Object + + +
+
+ + + + + + + + + + + + + +

(async) produceEncryptionKey(keyVersion, s2k, passphrase, cipherAlgo, aeadModeopt, serializedPacketTag)

+ + + + + + +
+

Derive encryption key

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDescription
keyVersion + + +Number + + + + + + + + + +

key derivation differs for v5 keys

s2k + + +module:type/s2k + + + + + + + + + +
passphrase + + +String + + + + + + + + + +
cipherAlgo + + +module:enums.symmetric + + + + + + + + + +
aeadMode + + +module:enums.aead + + + + + + <optional>
+ + + + + +

for AEAD-encrypted keys only (excluding v5)

serializedPacketTag + + +Uint8Array + + + + + + + + + +

for AEAD-encrypted keys only (excluding v5)

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

encryption key

+
+ + + + + + + + + + + + + + +

(async) readCleartextMessage(options) → {Promise.<CleartextMessage>}

@@ -5786,7 +6539,7 @@ default to main key options, except for sign parameter that default
Source:
@@ -6074,7 +6827,7 @@ default to main key options, except for sign parameter that default
Source:
@@ -6362,7 +7115,7 @@ default to main key options, except for sign parameter that default
Source:
@@ -6656,7 +7409,7 @@ default to main key options, except for sign parameter that default
Source:
@@ -6944,7 +7697,7 @@ default to main key options, except for sign parameter that default
Source:
@@ -7232,7 +7985,7 @@ default to main key options, except for sign parameter that default
Source:
@@ -7520,7 +8273,7 @@ default to main key options, except for sign parameter that default
Source:
@@ -7982,7 +8735,7 @@ to set the same date as the key creation time to ensure that old message signatu
Source:
@@ -8511,7 +9264,7 @@ If a revocation certificate is passed, the reasonForRevocation parameter will be
Source:
@@ -8571,6 +9324,215 @@ If a revocation certificate is passed, the reasonForRevocation parameter will be +

(async) runAEAD(fn, key, data) → {Promise.<(Uint8Array|ReadableStream.<Uint8Array>)>}

+ + + + + + +
+

En/decrypt the payload.

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
fn + + +encrypt +| + +decrypt + + + +

Whether to encrypt or decrypt

key + + +Uint8Array + + + +

The session key used to en/decrypt the payload

data + + +Uint8Array +| + +ReadableStream.<Uint8Array> + + + +

The data to en/decrypt

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Promise.<(Uint8Array|ReadableStream.<Uint8Array>)> + + +
+
+ + + + + + + + + + + + +

(async) sign(options) → {Promise.<MaybeStream.<(String|Uint8Array)>>}

@@ -9066,7 +10028,7 @@ If a revocation certificate is passed, the reasonForRevocation parameter will be
Source:
@@ -9228,7 +10190,7 @@ the encoded bytes

Source:
@@ -9690,7 +10652,7 @@ an attribute "data" containing a stream of bytes and "type"
Source:
@@ -9732,7 +10694,8 @@ an attribute "data" containing a stream of bytes and "type" ] } -where `signatures` contains a separate entry for each signature packet found in the input message. +where `signatures` contains a separate entry for each signature packet found in the input message. + @@ -9934,7 +10897,7 @@ The new key includes a revocation certificate that must be removed before return
Source:
@@ -9998,13 +10961,13 @@ The new key includes a revocation certificate that must be removed before return
diff --git a/docs/index.html b/docs/index.html index 8a2c2ba6..275ca440 100644 --- a/docs/index.html +++ b/docs/index.html @@ -44,7 +44,7 @@

OpenPGP.js BrowserStack Status Join the chat on Gitter

-

OpenPGP.js is a JavaScript implementation of the OpenPGP protocol. It implements RFC4880 and parts of RFC4880bis.

+

OpenPGP.js is a JavaScript implementation of the OpenPGP protocol. It implements the crypto-refresh (superseding RFC4880 and RFC4880bis).

Table of Contents

  • OpenPGP.js @@ -85,24 +85,24 @@

    Platform Support

    • -

      The dist/openpgp.min.js bundle works well with recent versions of Chrome, Firefox, Safari and Edge.

      +

      The dist/openpgp.min.js (or .mjs) bundle works with recent versions of Chrome, Firefox, Edge and Safari 13+.

    • -

      The dist/node/openpgp.min.js bundle works well in Node.js. It is used by default when you require('openpgp') in Node.js.

      +

      The dist/node/openpgp.min.mjs (or .cjs) bundle works in Node.js v16+: it is used by default when you import ... from 'openpgp' (resp. require('openpgp')).

    • -

      Currently, Chrome, Safari and Edge have partial implementations of the -Streams specification, and Firefox -has a partial implementation behind feature flags. Chrome is the only -browser that implements TransformStreams, which we need, so we include -a polyfill for -all other browsers. Please note that in those browsers, the global -ReadableStream property gets overwritten with the polyfill version if -it exists. In some edge cases, you might need to use the native +

      Streaming support: the latest versions of Chrome, Firefox, Edge and Safari implement the +Streams specification, including TransformStreams. +These are needed if you use the library with streamed inputs. +In previous versions of OpenPGP.js, WebStreams were automatically polyfilled by the library, +but from v6 this task is left up to the library user, due to the more extensive browser support, and the +polyfilling side-effects. If you're working with older browsers versions which do not implement e.g. TransformStreams, you can manually +load WebStream polyfill. +Please note that when you load the polyfills, the global ReadableStream property (if it exists) gets overwritten with the polyfill version. +In some edge cases, you might need to use the native ReadableStream (for example when using it to create a Response object), in which case you should store a reference to it before loading -OpenPGP.js. There is also the -web-streams-adapter +the polyfills. There is also the web-streams-adapter library to convert back and forth between them.

    @@ -201,21 +201,19 @@ library to convert back and forth between them.

    *** these curves are only constant-time if the underlying native implementation is available and constant-time

  • -

    Version 2.x of the library has been built from the ground up with Uint8Arrays. This allows for much better performance and memory usage than strings.

    -
  • -
  • If the user's browser supports native WebCrypto via the window.crypto.subtle API, this will be used. Under Node.js the native crypto module is used.

  • -

    The library implements the IETF proposal for authenticated encryption using native AES-EAX, OCB, or GCM. This makes symmetric encryption up to 30x faster on supported platforms. Since the specification has not been finalized and other OpenPGP implementations haven't adopted it yet, the feature is currently behind a flag. Note: activating this setting can break compatibility with other OpenPGP implementations, and also with future versions of OpenPGP.js. Don't use it with messages you want to store on disk or in a database. You can enable it by setting openpgp.config.aeadProtect = true.

    +

    The library implements authenticated encryption (AEAD) as per the "crypto refresh" draft standard using AES-OCB, EAX, or GCM. This makes symmetric encryption faster on platforms with native implementations. However, since the specification is very recent and other OpenPGP implementations are in the process of adopting it, the feature is currently behind a flag. Note: activating this setting can break compatibility with other OpenPGP implementations which have yet to implement the feature. You can enable it by setting openpgp.config.aeadProtect = true. +Note that this setting has a different effect from the one in OpenPGP.js v5, which implemented support for a provisional version of AEAD from RFC4880bis, which was modified in a later draft of the crypto refresh.

    You can change the AEAD mode by setting one of the following options:

    -
    openpgp.config.preferredAEADAlgorithm = openpgp.enums.aead.eax // Default, native
    -openpgp.config.preferredAEADAlgorithm = openpgp.enums.aead.ocb // Non-native
    -openpgp.config.preferredAEADAlgorithm = openpgp.enums.aead.experimentalGCM // **Non-standard**, fastest
    +
    openpgp.config.preferredAEADAlgorithm = openpgp.enums.aead.ocb; // Default (widest ecosystem support), non-native
    +openpgp.config.preferredAEADAlgorithm = openpgp.enums.aead.gcm; // Native in WebCrypto and Node.js
    +openpgp.config.preferredAEADAlgorithm = openpgp.enums.aead.eax; // Native in Node.js
     
  • -

    For environments that don't provide native crypto, the library falls back to asm.js implementations of AES, SHA-1, and SHA-256.

    +

    For environments that don't provide native crypto, the library falls back to asm.js AES and AEAD implementations.

Getting started

@@ -223,12 +221,12 @@ openpgp.config.preferredAEADAlgorithm = openpgp.enums.aead.experimentalGCM // **

Install OpenPGP.js using npm and save it in your dependencies:

npm install --save openpgp
 
-

And import it as a CommonJS module:

-
const openpgp = require('openpgp');
-
-

Or as an ES6 module, from an .mjs file:

+

And import it as an ES module, from a .mjs file:

import * as openpgp from 'openpgp';
 
+

Or as a CommonJS module:

+
const openpgp = require('openpgp');
+

Deno (experimental)

Import as an ES6 module, using /dist/openpgp.mjs.

import * as openpgp from './openpgpjs/dist/openpgp.mjs';
@@ -708,13 +706,13 @@ and a subkey for encryption using Curve25519.


diff --git a/docs/module-config.html b/docs/module-config.html index 51fef1bb..315e5010 100644 --- a/docs/module-config.html +++ b/docs/module-config.html @@ -89,7 +89,7 @@
Source:
@@ -247,7 +247,7 @@ as a global config setting, but can be used for specific function calls (e.g. de
Source:
@@ -365,7 +365,7 @@ Must be an integer value from 0 to 56.

Source:
@@ -390,8 +390,14 @@ Must be an integer value from 0 to 56.

Use Authenticated Encryption with Additional Data (AEAD) protection for symmetric encryption. -Note: not all OpenPGP implementations are compatible with this option. -FUTURE OPENPGP.JS VERSIONS MAY BREAK COMPATIBILITY WHEN USING THIS OPTION

+This option is applicable to:

+
    +
  • key generation (encryption key preferences),
  • +
  • password-based message encryption, and
  • +
  • private key encryption. +In the case of message encryption using public keys, the encryption key preferences are respected instead. +Note: not all OpenPGP implementations are compatible with this option.
  • +
@@ -483,7 +489,7 @@ Note: not all OpenPGP implementations are compatible with this option.
Source:
@@ -493,7 +499,7 @@ Note: not all OpenPGP implementations are compatible with this option.
See:
@@ -608,7 +614,7 @@ where key flags were ignored when selecting a key for encryption.

Source:
@@ -727,7 +733,7 @@ and have self-signature's creation date that does not match the primary key crea
Source:
@@ -848,7 +854,7 @@ This is an insecure setting:

Source:
@@ -875,7 +881,13 @@ This is an insecure setting:

Allow streaming unauthenticated data before its integrity has been checked. This would allow the application to process large streams while limiting memory usage by releasing the decrypted chunks as soon as possible and deferring checking their integrity until the decrypted stream has been read in full.

-

This setting is insecure if the partially decrypted message is processed further or displayed to the user.

+

This setting is insecure if the encrypted data has been corrupted by a malicious entity:

+
    +
  • if the partially decrypted message is processed further or displayed to the user, it opens up the possibility of attacks such as EFAIL +(see https://efail.de/).
  • +
  • an attacker with access to traces or timing info of internal processing errors could learn some info about the data.
  • +
+

NB: this setting does not apply to AEAD-encrypted data, where the AEAD data chunk is never released until integrity is confirmed.

@@ -967,119 +979,7 @@ and deferring checking their integrity until the decrypted stream has been read
Source:
- - - - - - - -
- - - - - - - - -

(static) checksumRequired

- - - - - - - - - - -
Properties:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
checksumRequired - - -Boolean - - - -

Do not throw error when armor is missing a checksum

- - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
@@ -1191,7 +1091,7 @@ and deferring checking their integrity until the decrypted stream has been read
Source:
@@ -1313,7 +1213,7 @@ See also constantTimePKCS1DecryptionSupportedSymmetricAlgorithms.Source:
@@ -1431,7 +1331,7 @@ However, the more algorithms are added, the slower the decryption procedure beco
Source:
@@ -1543,7 +1443,7 @@ However, the more algorithms are added, the slower the decryption procedure beco
Source:
@@ -1655,7 +1555,7 @@ However, the more algorithms are added, the slower the decryption procedure beco
Source:
@@ -1767,7 +1667,7 @@ However, the more algorithms are added, the slower the decryption procedure beco
Source:
@@ -1884,7 +1784,7 @@ validation error when the notation is marked as critical.

Source:
@@ -2000,119 +1900,7 @@ validation error when the notation is marked as critical.

Source:
- - - - - - - -
- - - - - - - - -

(static) minBytesForWebCrypto

- - - - - - - - - - -
Properties:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
minBytesForWebCrypto - - -Integer - - - -

The minimum amount of bytes for which to use native WebCrypto APIs when available

- - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
@@ -2229,7 +2017,7 @@ The default is 2047 since due to a bug, previous versions of OpenPGP.js could ge
Source:
@@ -2346,7 +2134,7 @@ The default is 2047 since due to a bug, previous versions of OpenPGP.js could ge
Source:
@@ -2463,7 +2251,7 @@ Only has an effect when aeadProtect is set to true.

Source:
@@ -2575,7 +2363,7 @@ Only has an effect when aeadProtect is set to true.

Source:
@@ -2687,7 +2475,7 @@ Only has an effect when aeadProtect is set to true.

Source:
@@ -2799,7 +2587,7 @@ Only has an effect when aeadProtect is set to true.

Source:
@@ -2915,7 +2703,7 @@ Only has an effect when aeadProtect is set to true.

Source:
@@ -3031,7 +2819,7 @@ Only has an effect when aeadProtect is set to true.

Source:
@@ -3147,7 +2935,7 @@ Only has an effect when aeadProtect is set to true.

Source:
@@ -3263,7 +3051,7 @@ Only has an effect when aeadProtect is set to true.

Source:
@@ -3375,7 +3163,222 @@ Only has an effect when aeadProtect is set to true.

Source:
+ + + + + + + +
+ + + + + + + + +

(static) s2kArgon2Params

+ + + + +
+

draft-crypto-refresh 3.7.1.4: +Argon2 parameters for S2K (String to Key). +Only relevant if config.s2kType is set to enums.s2k.argon2. +Default settings correspond to the second recommendation from RFC9106 ("uniformly safe option"), +to ensure compatibility with memory-constrained environments. +For more details on the choice of parameters, see https://tools.ietf.org/html/rfc9106#section-4.

+
+ + + + + + + +
Properties:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
params + + +Object + + + + +
Properties
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
passes + + +Integer + + + +

number of iterations t

parallelism + + +Integer + + + +

degree of parallelism p

memoryExponent + + +Integer + + + +

one-octet exponent indicating the memory size, which will be: 2**memoryExponent kibibytes.

+ +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
@@ -3399,8 +3402,10 @@ Only has an effect when aeadProtect is set to true.

-

RFC4880 3.7.1.3: -Iteration Count Byte for S2K (String to Key)

+

RFC4880 3.7.1.3: +Iteration Count Byte for Iterated and Salted S2K (String to Key). +Only relevant if config.s2kType is set to enums.s2k.iterated. +Note: this is the exponent value, not the final number of iterations (refer to specs for more details).

@@ -3492,7 +3497,129 @@ Iteration Count Byte for S2K (String to Key)

Source:
+ + + + + + + +
+ + + + + + + + +

(static) s2kType

+ + + + +
+

S2K (String to Key) type, used for key derivation in the context of secret key encryption +and password-encrypted data. Weaker s2k options are not allowed. +Note: Argon2 is the strongest option but not all OpenPGP implementations are compatible with it +(pending standardisation).

+
+ + + + + + + +
Properties:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
s2kType + + +enums.s2k.argon2 +| + +enums.s2k.iterated + + + +

module:enums.s2k

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
@@ -3604,7 +3731,7 @@ Iteration Count Byte for S2K (String to Key)

Source:
@@ -3716,7 +3843,7 @@ Iteration Count Byte for S2K (String to Key)

Source:
@@ -3734,15 +3861,14 @@ Iteration Count Byte for S2K (String to Key)

-

(static) useIndutnyElliptic

+

(static) useEllipticFallback

-

Whether to use the indutny/elliptic library for curves (other than Curve25519) that are not supported by the available native crypto API. -When false, certain standard curves will not be supported (depending on the platform). -Note: the indutny/elliptic curve library is not designed to be constant time.

+

Whether to use the the noble-curves library for curves (other than Curve25519) that are not supported by the available native crypto API. +When false, certain standard curves will not be supported (depending on the platform).

@@ -3777,7 +3903,7 @@ Note: the indutny/elliptic curve library is not designed to be constant time.

- useIndutnyElliptic + useEllipticFallback @@ -3834,7 +3960,7 @@ Note: the indutny/elliptic curve library is not designed to be constant time.

Source:
@@ -3852,13 +3978,13 @@ Note: the indutny/elliptic curve library is not designed to be constant time.

(static) v5Keys +

(static) v6Keys

-

Use V5 keys. +

Use v6 keys. Note: not all OpenPGP implementations are compatible with this option. FUTURE OPENPGP.JS VERSIONS MAY BREAK COMPATIBILITY WHEN USING THIS OPTION

@@ -3895,7 +4021,7 @@ Note: not all OpenPGP implementations are compatible with this option. - v5Keys + v6Keys @@ -3952,7 +4078,7 @@ Note: not all OpenPGP implementations are compatible with this option.
Source:
@@ -4064,7 +4190,7 @@ Note: not all OpenPGP implementations are compatible with this option.
Source:
@@ -4098,13 +4224,13 @@ Note: not all OpenPGP implementations are compatible with this option.
diff --git a/docs/module-crypto.html b/docs/module-crypto.html new file mode 100644 index 00000000..6360dce9 --- /dev/null +++ b/docs/module-crypto.html @@ -0,0 +1,184 @@ + + + + + JSDoc: Module: crypto + + + + + + + + + + +
+ +

Module: crypto

+ + + + + + +
+ +
+ + + + + +
+ + + +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-crypto_aes_kw.html b/docs/module-crypto_aes_kw.html new file mode 100644 index 00000000..2150278b --- /dev/null +++ b/docs/module-crypto_aes_kw.html @@ -0,0 +1,553 @@ + + + + + JSDoc: Module: crypto/aes_kw + + + + + + + + + + +
+ +

Module: crypto/aes_kw

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +

Implementation of RFC 3394 AES Key Wrap & Key Unwrap funcions

+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

(static) unwrap(key, data) → {Uint8Array}

+ + + + + + +
+

AES key unwrap

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
key + + +String + + + +
data + + +String + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Throws:
+ + + +
+ + +Error + + + +
+ + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Uint8Array + + +
+
+ + + + + + + + + + + + + +

(static) wrap(key, data) → {Uint8Array}

+ + + + + + +
+

AES key wrap

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
key + + +Uint8Array + + + +
data + + +Uint8Array + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Uint8Array + + +
+
+ + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-crypto_cipher.html b/docs/module-crypto_cipher.html new file mode 100644 index 00000000..089085be --- /dev/null +++ b/docs/module-crypto_cipher.html @@ -0,0 +1,1430 @@ + + + + + JSDoc: Module: crypto/cipher + + + + + + + + + + +
+ +

Module: crypto/cipher

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +

Symmetric cryptography functions

+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

(static) aes128(key) → {Object}

+ + + + + + +
+

AES-128 encryption and decryption (ID 7)

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
key + + +String + + + +

128-bit key

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Object + + +
+
+ + + + + + + + + + + + + +

(static) aes192(key) → {Object}

+ + + + + + +
+

AES-128 Block Cipher (ID 8)

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
key + + +String + + + +

192-bit key

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Object + + +
+
+ + + + + + + + + + + + + +

(static) aes256(key) → {Object}

+ + + + + + +
+

AES-128 Block Cipher (ID 9)

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
key + + +String + + + +

256-bit key

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Object + + +
+
+ + + + + + + + + + + + + +

(static) blowfish(key) → {Object}

+ + + + + + +
+

Blowfish Block Cipher (ID 4)

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
key + + +String + + + +

128-bit key

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Object + + +
+
+ + + + + + + + + + + + + +

(static) cast5(key) → {Object}

+ + + + + + +
+

CAST-128 Block Cipher (ID 3)

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
key + + +String + + + +

128-bit key

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Object + + +
+
+ + + + + + + + + + + + + +

(static) idea()

+ + + + + + +
+

Not implemented

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Throws:
+ + + +
+ + +Error + + + +
+ + + + + + + + + + + + + + + + +

(static) tripledes(key) → {Object}

+ + + + + + +
+

Triple DES Block Cipher (ID 2)

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
key + + +String + + + +

192-bit key

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Object + + +
+
+ + + + + + + + + + + + + +

(static) twofish(key) → {Object}

+ + + + + + +
+

Twofish Block Cipher (ID 10)

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
key + + +String + + + +

256-bit key

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Object + + +
+
+ + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-crypto_cmac.html b/docs/module-crypto_cmac.html new file mode 100644 index 00000000..31aaadf1 --- /dev/null +++ b/docs/module-crypto_cmac.html @@ -0,0 +1,413 @@ + + + + + JSDoc: Module: crypto/cmac + + + + + + + + + + +
+ +

Module: crypto/cmac

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +

This module implements AES-CMAC on top of +native AES-CBC using either the WebCrypto API or Node.js' crypto API.

+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +

Members

+ + + +

(inner, constant) blockLength

+ + + + +
+

This implementation of CMAC is based on the description of OMAC in +http://web.cs.ucdavis.edu/~rogaway/papers/eax.pdf. As per that +document:

+

We have made a small modification to the OMAC algorithm as it was +originally presented, changing one of its two constants. +Specifically, the constant 4 at line 85 was the constant 1/2 (the +multiplicative inverse of 2) in the original definition of OMAC [14]. +The OMAC authors indicate that they will promulgate this modification +[15], which slightly simplifies implementations.

+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + +

Methods

+ + + + + + + +

(inner) rightXORMut(data, padding)

+ + + + + + +
+

xor padding into the end of data. This function implements "the +operation xor→ [which] xors the shorter string into the end of longer +one". Since data is always as least as long as padding, we can +simplify the implementation.

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
data + + +Uint8Array + + + +
padding + + +Uint8Array + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-crypto_crypto.html b/docs/module-crypto_crypto.html new file mode 100644 index 00000000..a0105d17 --- /dev/null +++ b/docs/module-crypto_crypto.html @@ -0,0 +1,3000 @@ + + + + + JSDoc: Module: crypto/crypto + + + + + + + + + + +
+ +

Module: crypto/crypto

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +

Provides functions for asymmetric encryption and decryption as +well as key generation and parameter handling for all public-key cryptosystems.

+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

(async, static) generateParams(algo, bits, oid) → {Promise.<{publicParams: {Object}, privateParams: {Object}}>}

+ + + + + + +
+

Generate algorithm-specific key parameters

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +module:enums.publicKey + + + +

The public key algorithm

bits + + +Integer + + + +

Bit length for RSA keys

oid + + +module:type/oid + + + +

Object identifier for ECC keys

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

The parameters referenced by name.

+
+ + + +
+
+ Type +
+
+ +Promise.<{publicParams: {Object}, privateParams: {Object}}> + + +
+
+ + + + + + + + + + + + + +

(static) generateSessionKey(algo) → {Uint8Array}

+ + + + + + +
+

Generating a session key for the specified symmetric algorithm +See RFC 4880 9.2 for algorithms.

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +module:enums.symmetric + + + +

Symmetric encryption algorithm

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Random bytes as a string to be used as a key.

+
+ + + +
+
+ Type +
+
+ +Uint8Array + + +
+
+ + + + + + + + + + + + + +

(static) getAEADMode(algo) → {Object}

+ + + + + + +
+

Get implementation of the given AEAD mode

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +enums.aead + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Throws:
+ + + +
+
+
+

on invalid algo

+
+
+
+
+
+
+ Type +
+
+ +Error + + +
+
+
+
+
+ + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Object + + +
+
+ + + + + + + + + + + + + +

(static) getCurvePayloadSize(algo, oidopt)

+ + + + + + +
+

Get encoded secret size for a given elliptic algo

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDescription
algo + + +module:enums.publicKey + + + + + + + + + +

alrogithm identifier

oid + + +module:type/oid + + + + + + <optional>
+ + + + + +

curve OID if needed by algo

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(static) getPreferredCurveHashAlgo(algo, oidopt)

+ + + + + + +
+

Get preferred signing hash algo for a given elliptic algo

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDescription
algo + + +module:enums.publicKey + + + + + + + + + +

alrogithm identifier

oid + + +module:type/oid + + + + + + <optional>
+ + + + + +

curve OID if needed by algo

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(async, static) getPrefixRandom(algo) → {Promise.<Uint8Array>}

+ + + + + + +
+

Generates a random byte prefix for the specified algorithm +See RFC 4880 9.2 for algorithms.

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +module:enums.symmetric + + + +

Symmetric encryption algorithm

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Random bytes with length equal to the block size of the cipher, plus the last two bytes repeated.

+
+ + + +
+
+ Type +
+
+ +Promise.<Uint8Array> + + +
+
+ + + + + + + + + + + + + +

(static) parseEncSessionKeyParams(algo, bytes) → {Object}

+ + + + + + +
+

Returns the types comprising the encrypted session key of an algorithm

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +module:enums.publicKey + + + +

The key algorithm

bytes + + +Uint8Array + + + +

The key material to parse

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

The session key parameters referenced by name.

+
+ + + +
+
+ Type +
+
+ +Object + + +
+
+ + + + + + + + + + + + + +

(static) parsePrivateKeyParams(algo, bytes, publicParams) → {Object}

+ + + + + + +
+

Parse private key material in binary form to get the key parameters

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +module:enums.publicKey + + + +

The key algorithm

bytes + + +Uint8Array + + + +

The key material to parse

publicParams + + +Object + + + +

(ECC only) public params, needed to format some private params

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Number of read bytes plus the key parameters referenced by name.

+
+ + + +
+
+ Type +
+
+ +Object + + +
+
+ + + + + + + + + + + + + +

(static) parsePublicKeyParams(algo, bytes) → {Object}

+ + + + + + +
+

Parse public key material in binary form to get the key parameters

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +module:enums.publicKey + + + +

The key algorithm

bytes + + +Uint8Array + + + +

The key material to parse

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Number of read bytes plus key parameters referenced by name.

+
+ + + +
+
+ Type +
+
+ +Object + + +
+
+ + + + + + + + + + + + + +

(async, static) publicKeyDecrypt(algo, publicKeyParams, privateKeyParams, sessionKeyParams, fingerprint, randomPayloadopt) → {Promise.<Uint8Array>}

+ + + + + + +
+

Decrypts data using specified algorithm and private key parameters. +See RFC 4880 5.5.3

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDescription
algo + + +module:enums.publicKey + + + + + + + + + +

Public key algorithm

publicKeyParams + + +Object + + + + + + + + + +

Algorithm-specific public key parameters

privateKeyParams + + +Object + + + + + + + + + +

Algorithm-specific private key parameters

sessionKeyParams + + +Object + + + + + + + + + +

Encrypted session key parameters

fingerprint + + +Uint8Array + + + + + + + + + +

Recipient fingerprint

randomPayload + + +Uint8Array + + + + + + <optional>
+ + + + + +

Data to return on decryption error, instead of throwing +(needed for constant-time processing in RSA and ElGamal)

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Throws:
+ + + +
+
+
+

on sensitive decryption error, unless randomPayload is given

+
+
+
+
+
+
+ Type +
+
+ +Error + + +
+
+
+
+
+ + + + + +
Returns:
+ + +
+

Decrypted data.

+
+ + + +
+
+ Type +
+
+ +Promise.<Uint8Array> + + +
+
+ + + + + + + + + + + + + +

(async, static) publicKeyEncrypt(keyAlgo, symmetricAlgo, publicParams, data, fingerprint) → {Promise.<Object>}

+ + + + + + +
+

Encrypts data using specified algorithm and public key parameters. +See RFC 4880 9.1 for public key algorithms.

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
keyAlgo + + +module:enums.publicKey + + + +

Public key algorithm

symmetricAlgo + + +module:enums.symmetric + + + +

Cipher algorithm

publicParams + + +Object + + + +

Algorithm-specific public key parameters

data + + +Uint8Array + + + +

Session key data to be encrypted

fingerprint + + +Uint8Array + + + +

Recipient fingerprint

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Encrypted session key parameters.

+
+ + + +
+
+ Type +
+
+ +Promise.<Object> + + +
+
+ + + + + + + + + + + + + +

(static) serializeParams(algo, params) → {Uint8Array}

+ + + + + + +
+

Convert params to MPI and serializes them in the proper order

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +module:enums.publicKey + + + +

The public key algorithm

params + + +Object + + + +

The key parameters indexed by name

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

The array containing the MPIs.

+
+ + + +
+
+ Type +
+
+ +Uint8Array + + +
+
+ + + + + + + + + + + + + +

(async, static) validateParams(algo, publicParams, privateParams) → {Promise.<Boolean>}

+ + + + + + +
+

Validate algorithm-specific key parameters

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +module:enums.publicKey + + + +

The public key algorithm

publicParams + + +Object + + + +

Algorithm-specific public key parameters

privateParams + + +Object + + + +

Algorithm-specific private key parameters

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Whether the parameters are valid.

+
+ + + +
+
+ Type +
+
+ +Promise.<Boolean> + + +
+
+ + + + + + + + + + + + + +

(inner) checkSupportedCurve(oid)

+ + + + + + +
+

Check whether the given curve OID is supported

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
oid + + +module:type/oid + + + +

EC object identifier

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Throws:
+ + + +
+
+
+

if curve is not supported

+
+
+
+
+
+
+ Type +
+
+ +UnsupportedError + + +
+
+
+
+
+ + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-crypto_hash.html b/docs/module-crypto_hash.html new file mode 100644 index 00000000..1e4de57d --- /dev/null +++ b/docs/module-crypto_hash.html @@ -0,0 +1,596 @@ + + + + + JSDoc: Module: crypto/hash + + + + + + + + + + +
+ +

Module: crypto/hash

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +

Provides an interface to hashing functions available in Node.js or external libraries.

+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +

Members

+ + + +

(static) md5

+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+
    +
  • module:md5
  • +
+
+ + + +
+ + + + + + + + + + +

Methods

+ + + + + + + +

(static) digest(algo, data) → {Promise.<Uint8Array>}

+ + + + + + +
+

Create a hash on the specified data using the specified algorithm

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +module:enums.hash + + + +

Hash algorithm type (see RFC 4880 9.4)

data + + +Uint8Array + + + +

Data to be hashed

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Hash value.

+
+ + + +
+
+ Type +
+
+ +Promise.<Uint8Array> + + +
+
+ + + + + + + + + + + + + +

(static) getHashByteLength(algo) → {Integer}

+ + + + + + +
+

Returns the hash size in bytes of the specified hash algorithm type

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +module:enums.hash + + + +

Hash algorithm type (See RFC 4880 9.4)

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Size in bytes of the resulting hash.

+
+ + + +
+
+ Type +
+
+ +Integer + + +
+
+ + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-crypto_hkdf.html b/docs/module-crypto_hkdf.html new file mode 100644 index 00000000..08e03208 --- /dev/null +++ b/docs/module-crypto_hkdf.html @@ -0,0 +1,167 @@ + + + + + JSDoc: Module: crypto/hkdf + + + + + + + + + + +
+ +

Module: crypto/hkdf

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +

This module implements HKDF using either the WebCrypto API or Node.js' crypto API.

+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-crypto_mode.html b/docs/module-crypto_mode.html new file mode 100644 index 00000000..766568b7 --- /dev/null +++ b/docs/module-crypto_mode.html @@ -0,0 +1,439 @@ + + + + + JSDoc: Module: crypto/mode + + + + + + + + + + +
+ +

Module: crypto/mode

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +

Cipher modes

+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +

Members

+ + + +

(static) cfb

+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + + + + + +

(static) eax

+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + + + + + +

(static) gcm

+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + + + + + +

(static) ocb

+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-crypto_mode_cfb.html b/docs/module-crypto_mode_cfb.html new file mode 100644 index 00000000..2aa1d209 --- /dev/null +++ b/docs/module-crypto_mode_cfb.html @@ -0,0 +1,548 @@ + + + + + JSDoc: Module: crypto/mode/cfb + + + + + + + + + + +
+ +

Module: crypto/mode/cfb

+ + + + + + +
+ +
+ + + +
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

(static) decrypt(algo, key, ciphertext, iv)

+ + + + + + +
+

CFB decryption

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +enums.symmetric + + + +

block cipher algorithm

key + + +Uint8Array + + + +
ciphertext + + +MaybeStream.<Uint8Array> + + + +
iv + + +Uint8Array + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

MaybeStream

+
+ + + + + + + + + + + + + + + +

(static) encrypt(algo, key, plaintext, iv, config)

+ + + + + + +
+

CFB encryption

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +enums.symmetric + + + +

block cipher algorithm

key + + +Uint8Array + + + +
plaintext + + +MaybeStream.<Uint8Array> + + + +
iv + + +Uint8Array + + + +
config + + +Object + + + +

full configuration, defaults to openpgp.config

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

MaybeStream

+
+ + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-crypto_mode_eax.html b/docs/module-crypto_mode_eax.html new file mode 100644 index 00000000..76aa3551 --- /dev/null +++ b/docs/module-crypto_mode_eax.html @@ -0,0 +1,748 @@ + + + + + JSDoc: Module: crypto/mode/eax + + + + + + + + + + +
+ +

Module: crypto/mode/eax

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +

This module implements AES-EAX en/decryption on top of +native AES-CTR using either the WebCrypto API or Node.js' crypto API.

+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

(inner) decrypt(ciphertext, nonce, adata) → {Promise.<Uint8Array>}

+ + + + + + +
+

Decrypt ciphertext input.

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
ciphertext + + +Uint8Array + + + +

The ciphertext input to be decrypted

nonce + + +Uint8Array + + + +

The nonce (16 bytes)

adata + + +Uint8Array + + + +

Associated data to verify

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

The plaintext output.

+
+ + + +
+
+ Type +
+
+ +Promise.<Uint8Array> + + +
+
+ + + + + + + + + + + + + +

(async, inner) EAX(cipher, key)

+ + + + + + +
+

Class to en/decrypt using EAX mode.

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
cipher + + +enums.symmetric + + + +

The symmetric cipher algorithm to use

key + + +Uint8Array + + + +

The encryption key

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(inner) encrypt(plaintext, nonce, adata) → {Promise.<Uint8Array>}

+ + + + + + +
+

Encrypt plaintext input.

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
plaintext + + +Uint8Array + + + +

The cleartext input to be encrypted

nonce + + +Uint8Array + + + +

The nonce (16 bytes)

adata + + +Uint8Array + + + +

Associated data to sign

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

The ciphertext output.

+
+ + + +
+
+ Type +
+
+ +Promise.<Uint8Array> + + +
+
+ + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-crypto_mode_gcm.html b/docs/module-crypto_mode_gcm.html new file mode 100644 index 00000000..c9911464 --- /dev/null +++ b/docs/module-crypto_mode_gcm.html @@ -0,0 +1,334 @@ + + + + + JSDoc: Module: crypto/mode/gcm + + + + + + + + + + +
+ +

Module: crypto/mode/gcm

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +

This module wraps native AES-GCM en/decryption for both +the WebCrypto api as well as node.js' crypto api.

+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

(async, inner) GCM(cipher, key)

+ + + + + + +
+

Class to en/decrypt using GCM mode.

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
cipher + + +enums.symmetric + + + +

The symmetric cipher algorithm to use

key + + +Uint8Array + + + +

The encryption key

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-crypto_mode_ocb.html b/docs/module-crypto_mode_ocb.html new file mode 100644 index 00000000..19dceb00 --- /dev/null +++ b/docs/module-crypto_mode_ocb.html @@ -0,0 +1,747 @@ + + + + + JSDoc: Module: crypto/mode/ocb + + + + + + + + + + +
+ +

Module: crypto/mode/ocb

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +

This module implements AES-OCB en/decryption.

+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

(inner) decrypt(ciphertext, nonce, adata) → {Promise.<Uint8Array>}

+ + + + + + +
+

Decrypt ciphertext input.

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
ciphertext + + +Uint8Array + + + +

The ciphertext input to be decrypted

nonce + + +Uint8Array + + + +

The nonce (15 bytes)

adata + + +Uint8Array + + + +

Associated data to sign

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

The ciphertext output.

+
+ + + +
+
+ Type +
+
+ +Promise.<Uint8Array> + + +
+
+ + + + + + + + + + + + + +

(inner) encrypt(plaintext, nonce, adata) → {Promise.<Uint8Array>}

+ + + + + + +
+

Encrypt plaintext input.

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
plaintext + + +Uint8Array + + + +

The cleartext input to be encrypted

nonce + + +Uint8Array + + + +

The nonce (15 bytes)

adata + + +Uint8Array + + + +

Associated data to sign

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

The ciphertext output.

+
+ + + +
+
+ Type +
+
+ +Promise.<Uint8Array> + + +
+
+ + + + + + + + + + + + + +

(async, inner) OCB(cipher, key)

+ + + + + + +
+

Class to en/decrypt using OCB mode.

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
cipher + + +enums.symmetric + + + +

The symmetric cipher algorithm to use

key + + +Uint8Array + + + +

The encryption key

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-crypto_pkcs1.html b/docs/module-crypto_pkcs1.html new file mode 100644 index 00000000..2a8616b5 --- /dev/null +++ b/docs/module-crypto_pkcs1.html @@ -0,0 +1,882 @@ + + + + + JSDoc: Module: crypto/pkcs1 + + + + + + + + + + +
+ +

Module: crypto/pkcs1

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +

Provides EME-PKCS1-v1_5 encoding and decoding and EMSA-PKCS1-v1_5 encoding function

+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +

Members

+ + + +

(inner, constant) hash_headers

+ + + + +
+

ASN1 object identifiers for hashes

+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + + + + + + + +

Methods

+ + + + + + + +

(static) emeDecode(encoded, randomPayload) → {Uint8Array}

+ + + + + + +
+

Decode a EME-PKCS1-v1_5 padded message

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
encoded + + +Uint8Array + + + +

Encoded message bytes

randomPayload + + +Uint8Array + + + +

Data to return in case of decoding error (needed for constant-time processing)

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + + + + + + + + + + +
Throws:
+ + + +
+
+
+

on decoding failure, unless randomPayload is provided

+
+
+
+
+
+
+ Type +
+
+ +Error + + +
+
+
+
+
+ + + + + +
Returns:
+ + +
+

decoded data or randomPayload (on error, if given)

+
+ + + +
+
+ Type +
+
+ +Uint8Array + + +
+
+ + + + + + + + + + + + + +

(static) emeEncode(message, keyLength) → {Uint8Array}

+ + + + + + +
+

Create a EME-PKCS1-v1_5 padded message

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
message + + +Uint8Array + + + +

Message to be encoded

keyLength + + +Integer + + + +

The length in octets of the key modulus

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

EME-PKCS1 padded message.

+
+ + + +
+
+ Type +
+
+ +Uint8Array + + +
+
+ + + + + + + + + + + + + +

(static) emsaEncode(algo, hashed, emLen) → {Uint8Array}

+ + + + + + +
+

Create a EMSA-PKCS1-v1_5 padded message

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +Integer + + + +

Hash algorithm type used

hashed + + +Uint8Array + + + +

Message to be encoded

emLen + + +Integer + + + +

Intended length in octets of the encoded message

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Encoded message.

+
+ + + +
+
+ Type +
+
+ +Uint8Array + + +
+
+ + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-crypto_public_key.html b/docs/module-crypto_public_key.html new file mode 100644 index 00000000..c052971f --- /dev/null +++ b/docs/module-crypto_public_key.html @@ -0,0 +1,439 @@ + + + + + JSDoc: Module: crypto/public_key + + + + + + + + + + +
+ +

Module: crypto/public_key

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +

Asymmetric cryptography functions

+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +

Members

+ + + +

(static) dsa

+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + + + + + +

(static) elgamal

+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + + + + + +

(static) elliptic

+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + + + + + +

(static) rsa

+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-crypto_public_key_dsa.html b/docs/module-crypto_public_key_dsa.html new file mode 100644 index 00000000..aa017bee --- /dev/null +++ b/docs/module-crypto_public_key_dsa.html @@ -0,0 +1,1084 @@ + + + + + JSDoc: Module: crypto/public_key/dsa + + + + + + + + + + +
+ +

Module: crypto/public_key/dsa

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +

A Digital signature algorithm implementation

+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +

Members

+ + + +

(inner) x

+ + + + +
+

Re-derive public key y' = g ** x mod p +Expect y == y'

+

Blinded exponentiation computes g**{rq + x} to compare to y

+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + +

Methods

+ + + + + + + +

(async, static) sign(hashAlgo, hashed, g, p, q, x) → {Promise.<{r: Uint8Array, s: Uint8Array}>}

+ + + + + + +
+

DSA Sign function

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
hashAlgo + + +Integer + + + +
hashed + + +Uint8Array + + + +
g + + +Uint8Array + + + +
p + + +Uint8Array + + + +
q + + +Uint8Array + + + +
x + + +Uint8Array + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Promise.<{r: Uint8Array, s: Uint8Array}> + + +
+
+ + + + + + + + + + + + + +

(async, static) validateParams(p, q, g, y, x) → {Promise.<Boolean>}

+ + + + + + +
+

Validate DSA parameters

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
p + + +Uint8Array + + + +

DSA prime

q + + +Uint8Array + + + +

DSA group order

g + + +Uint8Array + + + +

DSA sub-group generator

y + + +Uint8Array + + + +

DSA public key

x + + +Uint8Array + + + +

DSA private key

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Whether params are valid.

+
+ + + +
+
+ Type +
+
+ +Promise.<Boolean> + + +
+
+ + + + + + + + + + + + + +

(async, static) verify(hashAlgo, r, s, hashed, g, p, q, y) → {boolean}

+ + + + + + +
+

DSA Verify function

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
hashAlgo + + +Integer + + + +
r + + +Uint8Array + + + +
s + + +Uint8Array + + + +
hashed + + +Uint8Array + + + +
g + + +Uint8Array + + + +
p + + +Uint8Array + + + +
q + + +Uint8Array + + + +
y + + +Uint8Array + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-crypto_public_key_elgamal.html b/docs/module-crypto_public_key_elgamal.html new file mode 100644 index 00000000..a4e8c423 --- /dev/null +++ b/docs/module-crypto_public_key_elgamal.html @@ -0,0 +1,981 @@ + + + + + JSDoc: Module: crypto/public_key/elgamal + + + + + + + + + + +
+ +

Module: crypto/public_key/elgamal

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +

ElGamal implementation

+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +

Members

+ + + +

(inner) x

+ + + + +
+

Re-derive public key y' = g ** x mod p +Expect y == y'

+

Blinded exponentiation computes g**{r(p-1) + x} to compare to y

+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + +

Methods

+ + + + + + + +

(async, static) decrypt(c1, c2, p, x, randomPayload) → {Promise.<Uint8Array>}

+ + + + + + +
+

ElGamal Encryption function

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
c1 + + +Uint8Array + + + +
c2 + + +Uint8Array + + + +
p + + +Uint8Array + + + +
x + + +Uint8Array + + + +
randomPayload + + +Uint8Array + + + +

Data to return on unpadding error, instead of throwing +(needed for constant-time processing)

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Throws:
+ + + +
+
+
+

on decryption error, unless randomPayload is given

+
+
+
+
+
+
+ Type +
+
+ +Error + + +
+
+
+
+
+ + + + + +
Returns:
+ + +
+

Unpadded message.

+
+ + + +
+
+ Type +
+
+ +Promise.<Uint8Array> + + +
+
+ + + + + + + + + + + + + +

(async, static) encrypt(data, p, g, y) → {Promise.<{c1: Uint8Array, c2: Uint8Array}>}

+ + + + + + +
+

ElGamal Encryption function +Note that in OpenPGP, the message needs to be padded with PKCS#1 (same as RSA)

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
data + + +Uint8Array + + + +

To be padded and encrypted

p + + +Uint8Array + + + +
g + + +Uint8Array + + + +
y + + +Uint8Array + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Promise.<{c1: Uint8Array, c2: Uint8Array}> + + +
+
+ + + + + + + + + + + + + +

(async, static) validateParams(p, g, y, x) → {Promise.<Boolean>}

+ + + + + + +
+

Validate ElGamal parameters

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
p + + +Uint8Array + + + +

ElGamal prime

g + + +Uint8Array + + + +

ElGamal group generator

y + + +Uint8Array + + + +

ElGamal public key

x + + +Uint8Array + + + +

ElGamal private exponent

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Whether params are valid.

+
+ + + +
+
+ Type +
+
+ +Promise.<Boolean> + + +
+
+ + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-crypto_public_key_elliptic.html b/docs/module-crypto_public_key_elliptic.html new file mode 100644 index 00000000..f116206b --- /dev/null +++ b/docs/module-crypto_public_key_elliptic.html @@ -0,0 +1,180 @@ + + + + + JSDoc: Module: crypto/public_key/elliptic + + + + + + + + + + +
+ +

Module: crypto/public_key/elliptic

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +

Functions to access Elliptic Curve Cryptography

+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-crypto_public_key_elliptic_curve.html b/docs/module-crypto_public_key_elliptic_curve.html new file mode 100644 index 00000000..b925f144 --- /dev/null +++ b/docs/module-crypto_public_key_elliptic_curve.html @@ -0,0 +1,1149 @@ + + + + + JSDoc: Module: crypto/public_key/elliptic/curve + + + + + + + + + + +
+ +

Module: crypto/public_key/elliptic/curve

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +

Wrapper of an instance of an Elliptic Curve

+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

(inner) getPreferredHashAlgo(oid) → {enums.hash}

+ + + + + + +
+

Get preferred hash algo to use with the given curve

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
oid + + +module:type/oid + + + +

curve oid

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

hash algorithm

+
+ + + +
+
+ Type +
+
+ +enums.hash + + +
+
+ + + + + + + + + + + + + +

(inner) jwkToRawPublic(jwk) → {Uint8Array}

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
jwk + + +JsonWebKey + + + +

key for conversion

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Raw public key.

+
+ + + +
+
+ Type +
+
+ +Uint8Array + + +
+
+ + + + + + + + + + + + + +

(inner) privateToJWK(payloadSize, name, publicKey, privateKey) → {JsonWebKey}

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
payloadSize + + +Integer + + + +

ec payload size

name + + +String + + + +

curve name

publicKey + + +Uint8Array + + + +

public key

privateKey + + +Uint8Array + + + +

private key

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Private key in jwk format.

+
+ + + +
+
+ Type +
+
+ +JsonWebKey + + +
+
+ + + + + + + + + + + + + +

(inner) rawPublicToJWK(payloadSize, name, publicKey) → {JsonWebKey}

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
payloadSize + + +Integer + + + +

ec payload size

name + + +String + + + +

curve name

publicKey + + +Uint8Array + + + +

public key

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Public key in jwk format.

+
+ + + +
+
+ Type +
+
+ +JsonWebKey + + +
+
+ + + + + + + + + + + + + +

(async, inner) validateStandardParams(algo, oid, Q, d) → {Promise.<Boolean>}

+ + + + + + +
+

Validate ECDH and ECDSA parameters +Not suitable for EdDSA (different secret key format)

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +module:enums.publicKey + + + +

EC algorithm, to filter supported curves

oid + + +module:type/oid + + + +

EC object identifier

Q + + +Uint8Array + + + +

EC public point

d + + +Uint8Array + + + +

EC secret scalar

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Whether params are valid.

+
+ + + +
+
+ Type +
+
+ +Promise.<Boolean> + + +
+
+ + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-crypto_public_key_elliptic_ecdh.html b/docs/module-crypto_public_key_elliptic_ecdh.html new file mode 100644 index 00000000..8c83d512 --- /dev/null +++ b/docs/module-crypto_public_key_elliptic_ecdh.html @@ -0,0 +1,6011 @@ + + + + + JSDoc: Module: crypto/public_key/elliptic/ecdh + + + + + + + + + + +
+ +

Module: crypto/public_key/elliptic/ecdh

+ + + + + + +
+ +
+ + + + + + + +
+ +
+
+ + +

Key encryption and decryption for RFC 6637 ECDH

+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

(async, static) decrypt(oid, kdfParams, V, C, Q, d, fingerprint) → {Promise.<Uint8Array>}

+ + + + + + +
+

Decrypt and unwrap the value derived from session key

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
oid + + +module:type/oid + + + +

Elliptic curve object identifier

kdfParams + + +module:type/kdf_params + + + +

KDF params including cipher and algorithm to use

V + + +Uint8Array + + + +

Public part of ephemeral key

C + + +Uint8Array + + + +

Encrypted and wrapped value derived from session key

Q + + +Uint8Array + + + +

Recipient public key

d + + +Uint8Array + + + +

Recipient private key

fingerprint + + +Uint8Array + + + +

Recipient fingerprint

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Value derived from session key.

+
+ + + +
+
+ Type +
+
+ +Promise.<Uint8Array> + + +
+
+ + + + + + + + + + + + + +

(async, static) decrypt(algo, ephemeralPublicKey, wrappedKey,, A, k) → {Promise.<Uint8Array>}

+ + + + + + +
+

Decrypt and unwrap the session key

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +module:enums.publicKey + + + +

Algorithm identifier

ephemeralPublicKey + + +Uint8Array + + + +

(K_A)

wrappedKey, + + +Uint8Array + + + +
A + + +Uint8Array + + + +

Recipient public key (K_b), needed for KDF

k + + +Uint8Array + + + +

Recipient secret key (b)

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

decrypted session key data

+
+ + + +
+
+ Type +
+
+ +Promise.<Uint8Array> + + +
+
+ + + + + + + + + + + + + +

(async, static) encrypt(oid, kdfParams, data, Q, fingerprint) → {Promise.<{publicKey: Uint8Array, wrappedKey: Uint8Array}>}

+ + + + + + +
+

Encrypt and wrap a session key

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
oid + + +module:type/oid + + + +

Elliptic curve object identifier

kdfParams + + +module:type/kdf_params + + + +

KDF params including cipher and algorithm to use

data + + +Uint8Array + + + +

Unpadded session key data

Q + + +Uint8Array + + + +

Recipient public key

fingerprint + + +Uint8Array + + + +

Recipient fingerprint

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Promise.<{publicKey: Uint8Array, wrappedKey: Uint8Array}> + + +
+
+ + + + + + + + + + + + + +

(async, static) encrypt(algo, data, recipientA) → {Promise.<{ephemeralPublicKey: Uint8Array, wrappedKey: Uint8Array}>}

+ + + + + + +
+

Wrap and encrypt a session key

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +module:enums.publicKey + + + +

Algorithm identifier

data + + +Uint8Array + + + +

session key data to be encrypted

recipientA + + +Uint8Array + + + +

Recipient public key (K_B)

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

ephemeral public key (K_A) and encrypted key

+
+ + + +
+
+ Type +
+
+ +Promise.<{ephemeralPublicKey: Uint8Array, wrappedKey: Uint8Array}> + + +
+
+ + + + + + + + + + + + + +

(static) generate(algo) → {Promise.<{A: Uint8Array, k: Uint8Array}>}

+ + + + + + +
+

Generate ECDH key for Montgomery curves

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +module:enums.publicKey + + + +

Algorithm identifier

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Promise.<{A: Uint8Array, k: Uint8Array}> + + +
+
+ + + + + + + + + + + + + +

(async, static) validateParams(oid, Q, d) → {Promise.<Boolean>}

+ + + + + + +
+

Validate ECDH parameters

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
oid + + +module:type/oid + + + +

Elliptic curve object identifier

Q + + +Uint8Array + + + +

ECDH public point

d + + +Uint8Array + + + +

ECDH secret scalar

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Whether params are valid.

+
+ + + +
+
+ Type +
+
+ +Promise.<Boolean> + + +
+
+ + + + + + + + + + + + + +

(async, static) validateParams(algo, A, k) → {Promise.<Boolean>}

+ + + + + + +
+

Validate ECDH parameters

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +module:enums.publicKey + + + +

Algorithm identifier

A + + +Uint8Array + + + +

ECDH public point

k + + +Uint8Array + + + +

ECDH secret scalar

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Whether params are valid.

+
+ + + +
+
+ Type +
+
+ +Promise.<Boolean> + + +
+
+ + + + + + + + + + + + + +

(async, inner) genPrivateEphemeralKey(curve, V, Q, d) → {Promise.<{secretKey: Uint8Array, sharedKey: Uint8Array}>}

+ + + + + + +
+

Generate ECDHE secret from private key and public part of ephemeral key

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
curve + + +CurveWithOID + + + +

Elliptic curve object

V + + +Uint8Array + + + +

Public part of ephemeral key

Q + + +Uint8Array + + + +

Recipient public key

d + + +Uint8Array + + + +

Recipient private key

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Promise.<{secretKey: Uint8Array, sharedKey: Uint8Array}> + + +
+
+ + + + + + + + + + + + + +

(async, inner) genPublicEphemeralKey(curve, Q) → {Promise.<{publicKey: Uint8Array, sharedKey: Uint8Array}>}

+ + + + + + +
+

Generate ECDHE ephemeral key and secret from public key

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
curve + + +CurveWithOID + + + +

Elliptic curve object

Q + + +Uint8Array + + + +

Recipient public key

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Promise.<{publicKey: Uint8Array, sharedKey: Uint8Array}> + + +
+
+ + + + + + + + + + + + + +

(async, inner) nodePrivateEphemeralKey(curve, V, d) → {Promise.<{secretKey: Uint8Array, sharedKey: Uint8Array}>}

+ + + + + + +
+

Generate ECDHE secret from private key and public part of ephemeral key using nodeCrypto

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
curve + + +CurveWithOID + + + +

Elliptic curve object

V + + +Uint8Array + + + +

Public part of ephemeral key

d + + +Uint8Array + + + +

Recipient private key

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Promise.<{secretKey: Uint8Array, sharedKey: Uint8Array}> + + +
+
+ + + + + + + + + + + + + +

(async, inner) nodePublicEphemeralKey(curve, Q) → {Promise.<{publicKey: Uint8Array, sharedKey: Uint8Array}>}

+ + + + + + +
+

Generate ECDHE ephemeral key and secret from public key using nodeCrypto

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
curve + + +CurveWithOID + + + +

Elliptic curve object

Q + + +Uint8Array + + + +

Recipient public key

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Promise.<{publicKey: Uint8Array, sharedKey: Uint8Array}> + + +
+
+ + + + + + + + + + + + + +

(async, inner) webPrivateEphemeralKey(curve, V, Q, d) → {Promise.<{secretKey: Uint8Array, sharedKey: Uint8Array}>}

+ + + + + + +
+

Generate ECDHE secret from private key and public part of ephemeral key using webCrypto

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
curve + + +CurveWithOID + + + +

Elliptic curve object

V + + +Uint8Array + + + +

Public part of ephemeral key

Q + + +Uint8Array + + + +

Recipient public key

d + + +Uint8Array + + + +

Recipient private key

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Promise.<{secretKey: Uint8Array, sharedKey: Uint8Array}> + + +
+
+ + + + + + + + + + + + + +

(async, inner) webPublicEphemeralKey(curve, Q) → {Promise.<{publicKey: Uint8Array, sharedKey: Uint8Array}>}

+ + + + + + +
+

Generate ECDHE ephemeral key and secret from public key using webCrypto

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
curve + + +CurveWithOID + + + +

Elliptic curve object

Q + + +Uint8Array + + + +

Recipient public key

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Promise.<{publicKey: Uint8Array, sharedKey: Uint8Array}> + + +
+
+ + + + + + + + + + + + + +
+ +
+ + + + + + + +
+ +
+ + + + + + + +
+ +
+
+ + +

Key encryption and decryption for RFC 6637 ECDH

+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

(async, static) decrypt(oid, kdfParams, V, C, Q, d, fingerprint) → {Promise.<Uint8Array>}

+ + + + + + +
+

Decrypt and unwrap the value derived from session key

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
oid + + +module:type/oid + + + +

Elliptic curve object identifier

kdfParams + + +module:type/kdf_params + + + +

KDF params including cipher and algorithm to use

V + + +Uint8Array + + + +

Public part of ephemeral key

C + + +Uint8Array + + + +

Encrypted and wrapped value derived from session key

Q + + +Uint8Array + + + +

Recipient public key

d + + +Uint8Array + + + +

Recipient private key

fingerprint + + +Uint8Array + + + +

Recipient fingerprint

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Value derived from session key.

+
+ + + +
+
+ Type +
+
+ +Promise.<Uint8Array> + + +
+
+ + + + + + + + + + + + + +

(async, static) decrypt(algo, ephemeralPublicKey, wrappedKey,, A, k) → {Promise.<Uint8Array>}

+ + + + + + +
+

Decrypt and unwrap the session key

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +module:enums.publicKey + + + +

Algorithm identifier

ephemeralPublicKey + + +Uint8Array + + + +

(K_A)

wrappedKey, + + +Uint8Array + + + +
A + + +Uint8Array + + + +

Recipient public key (K_b), needed for KDF

k + + +Uint8Array + + + +

Recipient secret key (b)

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

decrypted session key data

+
+ + + +
+
+ Type +
+
+ +Promise.<Uint8Array> + + +
+
+ + + + + + + + + + + + + +

(async, static) encrypt(oid, kdfParams, data, Q, fingerprint) → {Promise.<{publicKey: Uint8Array, wrappedKey: Uint8Array}>}

+ + + + + + +
+

Encrypt and wrap a session key

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
oid + + +module:type/oid + + + +

Elliptic curve object identifier

kdfParams + + +module:type/kdf_params + + + +

KDF params including cipher and algorithm to use

data + + +Uint8Array + + + +

Unpadded session key data

Q + + +Uint8Array + + + +

Recipient public key

fingerprint + + +Uint8Array + + + +

Recipient fingerprint

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Promise.<{publicKey: Uint8Array, wrappedKey: Uint8Array}> + + +
+
+ + + + + + + + + + + + + +

(async, static) encrypt(algo, data, recipientA) → {Promise.<{ephemeralPublicKey: Uint8Array, wrappedKey: Uint8Array}>}

+ + + + + + +
+

Wrap and encrypt a session key

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +module:enums.publicKey + + + +

Algorithm identifier

data + + +Uint8Array + + + +

session key data to be encrypted

recipientA + + +Uint8Array + + + +

Recipient public key (K_B)

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

ephemeral public key (K_A) and encrypted key

+
+ + + +
+
+ Type +
+
+ +Promise.<{ephemeralPublicKey: Uint8Array, wrappedKey: Uint8Array}> + + +
+
+ + + + + + + + + + + + + +

(static) generate(algo) → {Promise.<{A: Uint8Array, k: Uint8Array}>}

+ + + + + + +
+

Generate ECDH key for Montgomery curves

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +module:enums.publicKey + + + +

Algorithm identifier

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Promise.<{A: Uint8Array, k: Uint8Array}> + + +
+
+ + + + + + + + + + + + + +

(async, static) validateParams(oid, Q, d) → {Promise.<Boolean>}

+ + + + + + +
+

Validate ECDH parameters

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
oid + + +module:type/oid + + + +

Elliptic curve object identifier

Q + + +Uint8Array + + + +

ECDH public point

d + + +Uint8Array + + + +

ECDH secret scalar

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Whether params are valid.

+
+ + + +
+
+ Type +
+
+ +Promise.<Boolean> + + +
+
+ + + + + + + + + + + + + +

(async, static) validateParams(algo, A, k) → {Promise.<Boolean>}

+ + + + + + +
+

Validate ECDH parameters

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +module:enums.publicKey + + + +

Algorithm identifier

A + + +Uint8Array + + + +

ECDH public point

k + + +Uint8Array + + + +

ECDH secret scalar

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Whether params are valid.

+
+ + + +
+
+ Type +
+
+ +Promise.<Boolean> + + +
+
+ + + + + + + + + + + + + +

(async, inner) genPrivateEphemeralKey(curve, V, Q, d) → {Promise.<{secretKey: Uint8Array, sharedKey: Uint8Array}>}

+ + + + + + +
+

Generate ECDHE secret from private key and public part of ephemeral key

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
curve + + +CurveWithOID + + + +

Elliptic curve object

V + + +Uint8Array + + + +

Public part of ephemeral key

Q + + +Uint8Array + + + +

Recipient public key

d + + +Uint8Array + + + +

Recipient private key

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Promise.<{secretKey: Uint8Array, sharedKey: Uint8Array}> + + +
+
+ + + + + + + + + + + + + +

(async, inner) genPublicEphemeralKey(curve, Q) → {Promise.<{publicKey: Uint8Array, sharedKey: Uint8Array}>}

+ + + + + + +
+

Generate ECDHE ephemeral key and secret from public key

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
curve + + +CurveWithOID + + + +

Elliptic curve object

Q + + +Uint8Array + + + +

Recipient public key

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Promise.<{publicKey: Uint8Array, sharedKey: Uint8Array}> + + +
+
+ + + + + + + + + + + + + +

(async, inner) nodePrivateEphemeralKey(curve, V, d) → {Promise.<{secretKey: Uint8Array, sharedKey: Uint8Array}>}

+ + + + + + +
+

Generate ECDHE secret from private key and public part of ephemeral key using nodeCrypto

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
curve + + +CurveWithOID + + + +

Elliptic curve object

V + + +Uint8Array + + + +

Public part of ephemeral key

d + + +Uint8Array + + + +

Recipient private key

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Promise.<{secretKey: Uint8Array, sharedKey: Uint8Array}> + + +
+
+ + + + + + + + + + + + + +

(async, inner) nodePublicEphemeralKey(curve, Q) → {Promise.<{publicKey: Uint8Array, sharedKey: Uint8Array}>}

+ + + + + + +
+

Generate ECDHE ephemeral key and secret from public key using nodeCrypto

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
curve + + +CurveWithOID + + + +

Elliptic curve object

Q + + +Uint8Array + + + +

Recipient public key

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Promise.<{publicKey: Uint8Array, sharedKey: Uint8Array}> + + +
+
+ + + + + + + + + + + + + +

(async, inner) webPrivateEphemeralKey(curve, V, Q, d) → {Promise.<{secretKey: Uint8Array, sharedKey: Uint8Array}>}

+ + + + + + +
+

Generate ECDHE secret from private key and public part of ephemeral key using webCrypto

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
curve + + +CurveWithOID + + + +

Elliptic curve object

V + + +Uint8Array + + + +

Public part of ephemeral key

Q + + +Uint8Array + + + +

Recipient public key

d + + +Uint8Array + + + +

Recipient private key

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Promise.<{secretKey: Uint8Array, sharedKey: Uint8Array}> + + +
+
+ + + + + + + + + + + + + +

(async, inner) webPublicEphemeralKey(curve, Q) → {Promise.<{publicKey: Uint8Array, sharedKey: Uint8Array}>}

+ + + + + + +
+

Generate ECDHE ephemeral key and secret from public key using webCrypto

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
curve + + +CurveWithOID + + + +

Elliptic curve object

Q + + +Uint8Array + + + +

Recipient public key

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Promise.<{publicKey: Uint8Array, sharedKey: Uint8Array}> + + +
+
+ + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-crypto_public_key_elliptic_ecdsa.html b/docs/module-crypto_public_key_elliptic_ecdsa.html new file mode 100644 index 00000000..ff155f0b --- /dev/null +++ b/docs/module-crypto_public_key_elliptic_ecdsa.html @@ -0,0 +1,1017 @@ + + + + + JSDoc: Module: crypto/public_key/elliptic/ecdsa + + + + + + + + + + +
+ +

Module: crypto/public_key/elliptic/ecdsa

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +

Implementation of ECDSA following RFC6637 for Openpgpjs

+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

(async, static) sign(oid, hashAlgo, message, publicKey, privateKey, hashed) → {Promise.<{r: Uint8Array, s: Uint8Array}>}

+ + + + + + +
+

Sign a message using the provided key

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
oid + + +module:type/oid + + + +

Elliptic curve object identifier

hashAlgo + + +module:enums.hash + + + +

Hash algorithm used to sign

message + + +Uint8Array + + + +

Message to sign

publicKey + + +Uint8Array + + + +

Public key

privateKey + + +Uint8Array + + + +

Private key used to sign the message

hashed + + +Uint8Array + + + +

The hashed message

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Signature of the message

+
+ + + +
+
+ Type +
+
+ +Promise.<{r: Uint8Array, s: Uint8Array}> + + +
+
+ + + + + + + + + + + + + +

(async, static) validateParams(oid, Q, d) → {Promise.<Boolean>}

+ + + + + + +
+

Validate ECDSA parameters

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
oid + + +module:type/oid + + + +

Elliptic curve object identifier

Q + + +Uint8Array + + + +

ECDSA public point

d + + +Uint8Array + + + +

ECDSA secret scalar

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Whether params are valid.

+
+ + + +
+
+ Type +
+
+ +Promise.<Boolean> + + +
+
+ + + + + + + + + + + + + +

(async, static) verify(oid, hashAlgo, signature, message, publicKey, hashed) → {Boolean}

+ + + + + + +
+

Verifies if a signature is valid for a message

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
oid + + +module:type/oid + + + +

Elliptic curve object identifier

hashAlgo + + +module:enums.hash + + + +

Hash algorithm used in the signature

signature + + +Object + + + +

Signature to verify

message + + +Uint8Array + + + +

Message to verify

publicKey + + +Uint8Array + + + +

Public key used to verify the message

hashed + + +Uint8Array + + + +

The hashed message

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Boolean + + +
+
+ + + + + + + + + + + + + +

(async, inner) jsVerify()

+ + + + + + +
+

Fallback javascript implementation of ECDSA verification. +To be used if no native implementation is available for the given curve/operation.

+
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-crypto_public_key_elliptic_eddsa.html b/docs/module-crypto_public_key_elliptic_eddsa.html new file mode 100644 index 00000000..21bb2eb8 --- /dev/null +++ b/docs/module-crypto_public_key_elliptic_eddsa.html @@ -0,0 +1,1106 @@ + + + + + JSDoc: Module: crypto/public_key/elliptic/eddsa + + + + + + + + + + +
+ +

Module: crypto/public_key/elliptic/eddsa

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +

Implementation of EdDSA following RFC4880bis-03 for OpenPGP

+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

(static) generate(algo) → {Promise.<{A: Uint8Array, seed: Uint8Array}>}

+ + + + + + +
+

Generate (non-legacy) EdDSA key

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +module:enums.publicKey + + + +

Algorithm identifier

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Promise.<{A: Uint8Array, seed: Uint8Array}> + + +
+
+ + + + + + + + + + + + + +

(async, static) sign(algo, hashAlgo, message, publicKey, privateKey, hashed) → {Promise.<{RS: Uint8Array}>}

+ + + + + + +
+

Sign a message using the provided key

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +module:enums.publicKey + + + +

Algorithm identifier

hashAlgo + + +module:enums.hash + + + +

Hash algorithm used to sign (must be sha256 or stronger)

message + + +Uint8Array + + + +

Message to sign

publicKey + + +Uint8Array + + + +

Public key

privateKey + + +Uint8Array + + + +

Private key used to sign the message

hashed + + +Uint8Array + + + +

The hashed message

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Signature of the message

+
+ + + +
+
+ Type +
+
+ +Promise.<{RS: Uint8Array}> + + +
+
+ + + + + + + + + + + + + +

(async, static) validateParams(algo, A, seed, oid) → {Promise.<Boolean>}

+ + + + + + +
+

Validate (non-legacy) EdDSA parameters

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +module:enums.publicKey + + + +

Algorithm identifier

A + + +Uint8Array + + + +

EdDSA public point

seed + + +Uint8Array + + + +

EdDSA secret seed

oid + + +Uint8Array + + + +

(legacy only) EdDSA OID

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Whether params are valid.

+
+ + + +
+
+ Type +
+
+ +Promise.<Boolean> + + +
+
+ + + + + + + + + + + + + +

(async, static) verify(algo, hashAlgo, signature, m, publicKey, hashed) → {Boolean}

+ + + + + + +
+

Verifies if a signature is valid for a message

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +module:enums.publicKey + + + +

Algorithm identifier

hashAlgo + + +module:enums.hash + + + +

Hash algorithm used in the signature

signature + + +Object + + + +

Signature to verify the message

m + + +Uint8Array + + + +

Message to verify

publicKey + + +Uint8Array + + + +

Public key used to verify the message

hashed + + +Uint8Array + + + +

The hashed message

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Boolean + + +
+
+ + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-crypto_public_key_elliptic_eddsa_legacy.html b/docs/module-crypto_public_key_elliptic_eddsa_legacy.html new file mode 100644 index 00000000..b9a68f12 --- /dev/null +++ b/docs/module-crypto_public_key_elliptic_eddsa_legacy.html @@ -0,0 +1,927 @@ + + + + + JSDoc: Module: crypto/public_key/elliptic/eddsa_legacy + + + + + + + + + + +
+ +

Module: crypto/public_key/elliptic/eddsa_legacy

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +

Implementation of legacy EdDSA following RFC4880bis-03 for OpenPGP. +This key type has been deprecated by the crypto-refresh RFC.

+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

(async, static) sign(oid, hashAlgo, message, publicKey, privateKey, hashed) → {Promise.<{r: Uint8Array, s: Uint8Array}>}

+ + + + + + +
+

Sign a message using the provided legacy EdDSA key

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
oid + + +module:type/oid + + + +

Elliptic curve object identifier

hashAlgo + + +module:enums.hash + + + +

Hash algorithm used to sign (must be sha256 or stronger)

message + + +Uint8Array + + + +

Message to sign

publicKey + + +Uint8Array + + + +

Public key

privateKey + + +Uint8Array + + + +

Private key used to sign the message

hashed + + +Uint8Array + + + +

The hashed message

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Signature of the message

+
+ + + +
+
+ Type +
+
+ +Promise.<{r: Uint8Array, s: Uint8Array}> + + +
+
+ + + + + + + + + + + + + +

(async, static) validateParams(oid, Q, k) → {Promise.<Boolean>}

+ + + + + + +
+

Validate legacy EdDSA parameters

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
oid + + +module:type/oid + + + +

Elliptic curve object identifier

Q + + +Uint8Array + + + +

EdDSA public point

k + + +Uint8Array + + + +

EdDSA secret seed

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Whether params are valid.

+
+ + + +
+
+ Type +
+
+ +Promise.<Boolean> + + +
+
+ + + + + + + + + + + + + +

(async, static) verify(oid, hashAlgo, signature, m, publicKey, hashed) → {Boolean}

+ + + + + + +
+

Verifies if a legacy EdDSA signature is valid for a message

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
oid + + +module:type/oid + + + +

Elliptic curve object identifier

hashAlgo + + +module:enums.hash + + + +

Hash algorithm used in the signature

signature + + +Object + + + +

Signature to verify the message

m + + +Uint8Array + + + +

Message to verify

publicKey + + +Uint8Array + + + +

Public key used to verify the message

hashed + + +Uint8Array + + + +

The hashed message

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Boolean + + +
+
+ + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-crypto_public_key_prime.html b/docs/module-crypto_public_key_prime.html new file mode 100644 index 00000000..f26a9c24 --- /dev/null +++ b/docs/module-crypto_public_key_prime.html @@ -0,0 +1,954 @@ + + + + + JSDoc: Module: crypto/public_key/prime + + + + + + + + + + +
+ +

Module: crypto/public_key/prime

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +

Algorithms for probabilistic random prime generation

+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

(static) fermat(n, b) → {boolean}

+ + + + + + +
+

Tests whether n is probably prime or not using Fermat's test with b = 2. +Fails if b^(n-1) mod n != 1.

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
n + + +BigInteger + + + +

Number to test

b + + +BigInteger + + + +

Optional Fermat test base

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + + + + + + + + + + +

(async, static) isProbablePrime(n, e, k) → {boolean}

+ + + + + + +
+

Probabilistic primality testing

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
n + + +BigInteger + + + +

Number to test

e + + +BigInteger + + + +

Optional RSA exponent to check against the prime

k + + +Integer + + + +

Optional number of iterations of Miller-Rabin test

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + + + + + + + + + + +

(async, static) millerRabin(n, k, rand) → {boolean}

+ + + + + + +
+

Tests whether n is probably prime or not using the Miller-Rabin test. +See HAC Remark 4.28.

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
n + + +BigInteger + + + +

Number to test

k + + +Integer + + + +

Optional number of iterations of Miller-Rabin test

rand + + +function + + + +

Optional function to generate potential witnesses

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + + + + + + + + + + +

(async, static) randomProbablePrime(bits, e, k)

+ + + + + + +
+

Generate a probably prime random number

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
bits + + +Integer + + + +

Bit length of the prime

e + + +BigInteger + + + +

Optional RSA exponent to check against the prime

k + + +Integer + + + +

Optional number of iterations of Miller-Rabin test

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

BigInteger

+
+ + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-crypto_public_key_rsa.html b/docs/module-crypto_public_key_rsa.html new file mode 100644 index 00000000..7cc1eccf --- /dev/null +++ b/docs/module-crypto_public_key_rsa.html @@ -0,0 +1,2279 @@ + + + + + JSDoc: Module: crypto/public_key/rsa + + + + + + + + + + +
+ +

Module: crypto/public_key/rsa

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +

RSA implementation

+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

(async, static) decrypt(m, n, e, d, p, q, u, randomPayload) → {Promise.<String>}

+ + + + + + +
+

Decrypt RSA message

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
m + + +Uint8Array + + + +

Message

n + + +Uint8Array + + + +

RSA public modulus

e + + +Uint8Array + + + +

RSA public exponent

d + + +Uint8Array + + + +

RSA private exponent

p + + +Uint8Array + + + +

RSA private prime p

q + + +Uint8Array + + + +

RSA private prime q

u + + +Uint8Array + + + +

RSA private coefficient

randomPayload + + +Uint8Array + + + +

Data to return on decryption error, instead of throwing +(needed for constant-time processing)

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Throws:
+ + + +
+
+
+

on decryption error, unless randomPayload is given

+
+
+
+
+
+
+ Type +
+
+ +Error + + +
+
+
+
+
+ + + + + +
Returns:
+ + +
+

RSA Plaintext.

+
+ + + +
+
+ Type +
+
+ +Promise.<String> + + +
+
+ + + + + + + + + + + + + +

(async, static) encrypt(data, n, e) → {Promise.<Uint8Array>}

+ + + + + + +
+

Encrypt message

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
data + + +Uint8Array + + + +

Message

n + + +Uint8Array + + + +

RSA public modulus

e + + +Uint8Array + + + +

RSA public exponent

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

RSA Ciphertext.

+
+ + + +
+
+ Type +
+
+ +Promise.<Uint8Array> + + +
+
+ + + + + + + + + + + + + +

(async, static) generate(bits, e) → {Object}

+ + + + + + +
+

Generate a new random private key B bits long with public exponent E.

+

When possible, webCrypto or nodeCrypto is used. Otherwise, primes are generated using +40 rounds of the Miller-Rabin probabilistic random prime generation algorithm.

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
bits + + +Integer + + + +

RSA bit length

e + + +Integer + + + +

RSA public exponent

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

RSA public modulus, RSA public exponent, RSA private exponent, +RSA private prime p, RSA private prime q, u = p ** -1 mod q

+
+ + + +
+
+ Type +
+
+ +Object + + +
+
+ + + + + + + + + + + + + +

(async, static) sign(hashAlgo, data, n, e, d, p, q, u, hashed) → {Promise.<Uint8Array>}

+ + + + + + +
+

Create signature

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
hashAlgo + + +module:enums.hash + + + +

Hash algorithm

data + + +Uint8Array + + + +

Message

n + + +Uint8Array + + + +

RSA public modulus

e + + +Uint8Array + + + +

RSA public exponent

d + + +Uint8Array + + + +

RSA private exponent

p + + +Uint8Array + + + +

RSA private prime p

q + + +Uint8Array + + + +

RSA private prime q

u + + +Uint8Array + + + +

RSA private coefficient

hashed + + +Uint8Array + + + +

Hashed message

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

RSA Signature.

+
+ + + +
+
+ Type +
+
+ +Promise.<Uint8Array> + + +
+
+ + + + + + + + + + + + + +

(async, static) validateParams(n, e, d, p, q, u) → {Promise.<Boolean>}

+ + + + + + +
+

Validate RSA parameters

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
n + + +Uint8Array + + + +

RSA public modulus

e + + +Uint8Array + + + +

RSA public exponent

d + + +Uint8Array + + + +

RSA private exponent

p + + +Uint8Array + + + +

RSA private prime p

q + + +Uint8Array + + + +

RSA private prime q

u + + +Uint8Array + + + +

RSA inverse of p w.r.t. q

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Whether params are valid.

+
+ + + +
+
+ Type +
+
+ +Promise.<Boolean> + + +
+
+ + + + + + + + + + + + + +

(async, static) verify(hashAlgo, data, s, n, e, hashed) → {Boolean}

+ + + + + + +
+

Verify signature

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
hashAlgo + + +module:enums.hash + + + +

Hash algorithm

data + + +Uint8Array + + + +

Message

s + + +Uint8Array + + + +

Signature

n + + +Uint8Array + + + +

RSA public modulus

e + + +Uint8Array + + + +

RSA public exponent

hashed + + +Uint8Array + + + +

Hashed message

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Boolean + + +
+
+ + + + + + + + + + + + + +

(async, inner) privateToJWK(hashAlgo, n, e, d, p, q, u)

+ + + + + + +
+

Convert Openpgp private key params to jwk key according to

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
hashAlgo + + +String + + + +
n + + +Uint8Array + + + +
e + + +Uint8Array + + + +
d + + +Uint8Array + + + +
p + + +Uint8Array + + + +
q + + +Uint8Array + + + +
u + + +Uint8Array + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(inner) publicToJWK(hashAlgo, n, e)

+ + + + + + +
+

Convert Openpgp key public params to jwk key according to

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
hashAlgo + + +String + + + +
n + + +Uint8Array + + + +
e + + +Uint8Array + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-crypto_random.html b/docs/module-crypto_random.html new file mode 100644 index 00000000..fa8b2c6c --- /dev/null +++ b/docs/module-crypto_random.html @@ -0,0 +1,516 @@ + + + + + JSDoc: Module: crypto/random + + + + + + + + + + +
+ +

Module: crypto/random

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +

Provides tools for retrieving secure randomness from browsers or Node.js

+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

(async, static) getRandomBigInteger(min, max) → {Promise.<module:BigInteger>}

+ + + + + + +
+

Create a secure random BigInteger that is greater than or equal to min and less than max.

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
min + + +module:BigInteger + + + +

Lower bound, included

max + + +module:BigInteger + + + +

Upper bound, excluded

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Random BigInteger.

+
+ + + +
+
+ Type +
+
+ +Promise.<module:BigInteger> + + +
+
+ + + + + + + + + + + + + +

(static) getRandomBytes(length) → {Uint8Array}

+ + + + + + +
+

Retrieve secure random byte array of the specified length

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
length + + +Integer + + + +

Length in bytes to generate

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Random byte array.

+
+ + + +
+
+ Type +
+
+ +Uint8Array + + +
+
+ + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-crypto_signature.html b/docs/module-crypto_signature.html new file mode 100644 index 00000000..accef42e --- /dev/null +++ b/docs/module-crypto_signature.html @@ -0,0 +1,917 @@ + + + + + JSDoc: Module: crypto/signature + + + + + + + + + + +
+ +

Module: crypto/signature

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +

Provides functions for asymmetric signing and signature verification

+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

(async, static) parseSignatureParams(algo, signature) → {Promise.<Object>}

+ + + + + + +
+

Parse signature in binary form to get the parameters. +The returned values are only padded for EdDSA, since in the other cases their expected length +depends on the key params, hence we delegate the padding to the signature verification function. +See RFC 4880 9.1 +See RFC 4880 5.2.2.

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +module:enums.publicKey + + + +

Public key algorithm

signature + + +Uint8Array + + + +

Data for which the signature was created

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

True if signature is valid.

+
+ + + +
+
+ Type +
+
+ +Promise.<Object> + + +
+
+ + + + + + + + + + + + + +

(async, static) sign(algo, hashAlgo, publicKeyParams, privateKeyParams, data, hashed) → {Promise.<Object>}

+ + + + + + +
+

Creates a signature on data using specified algorithms and private key parameters. +See RFC 4880 9.1 +and RFC 4880 9.4 +for public key and hash algorithms.

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +module:enums.publicKey + + + +

Public key algorithm

hashAlgo + + +module:enums.hash + + + +

Hash algorithm

publicKeyParams + + +Object + + + +

Algorithm-specific public and private key parameters

privateKeyParams + + +Object + + + +

Algorithm-specific public and private key parameters

data + + +Uint8Array + + + +

Data to be signed

hashed + + +Uint8Array + + + +

The hashed data

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Signature Object containing named signature parameters.

+
+ + + +
+
+ Type +
+
+ +Promise.<Object> + + +
+
+ + + + + + + + + + + + + +

(async, static) verify(algo, hashAlgo, signature, publicParams, data, hashed) → {Promise.<Boolean>}

+ + + + + + +
+

Verifies the signature provided for data using specified algorithms and public key parameters. +See RFC 4880 9.1 +and RFC 4880 9.4 +for public key and hash algorithms.

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +module:enums.publicKey + + + +

Public key algorithm

hashAlgo + + +module:enums.hash + + + +

Hash algorithm

signature + + +Object + + + +

Named algorithm-specific signature parameters

publicParams + + +Object + + + +

Algorithm-specific public key parameters

data + + +Uint8Array + + + +

Data for which the signature was created

hashed + + +Uint8Array + + + +

The hashed data

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

True if signature is valid.

+
+ + + +
+
+ Type +
+
+ +Promise.<Boolean> + + +
+
+ + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-encoding_base64.html b/docs/module-encoding_base64.html new file mode 100644 index 00000000..11035aa0 --- /dev/null +++ b/docs/module-encoding_base64.html @@ -0,0 +1,769 @@ + + + + + JSDoc: Module: encoding/base64 + + + + + + + + + + +
+ +

Module: encoding/base64

+ + + + + + +
+ +
+ + + +
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

(static) b64ToUint8Array(base64) → {Uint8Array}

+ + + + + + +
+

Convert a Base-64 encoded string an array of 8-bit integer

+

Note: accepts both Radix-64 and URL-safe strings

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
base64 + + +String + + + +

Base-64 encoded string to convert

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

An array of 8-bit integers.

+
+ + + +
+
+ Type +
+
+ +Uint8Array + + +
+
+ + + + + + + + + + + + + +

(static) decode(data) → {Uint8Array|ReadableStream.<Uint8Array>}

+ + + + + + +
+

Convert radix-64 to binary array

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
data + + +String +| + +ReadableStream.<String> + + + +

Radix-64 string to convert

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Binary array version of input string.

+
+ + + +
+
+ Type +
+
+ +Uint8Array +| + +ReadableStream.<Uint8Array> + + +
+
+ + + + + + + + + + + + + +

(static) encode(data) → {String|ReadableStream.<String>}

+ + + + + + +
+

Convert binary array to radix-64

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
data + + +Uint8Array +| + +ReadableStream.<Uint8Array> + + + +

Uint8Array to convert

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Radix-64 version of input string.

+
+ + + +
+
+ Type +
+
+ +String +| + +ReadableStream.<String> + + +
+
+ + + + + + + + + + + + + +

(static) uint8ArrayToB64(bytes, url) → {String}

+ + + + + + +
+

Convert an array of 8-bit integer to a Base-64 encoded string

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
bytes + + +Uint8Array + + + +

An array of 8-bit integers to convert

url + + +bool + + + +

If true, output is URL-safe

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Base-64 encoded string.

+
+ + + +
+
+ Type +
+
+ +String + + +
+
+ + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-enums.html b/docs/module-enums.html index 848ff729..af3da952 100644 --- a/docs/module-enums.html +++ b/docs/module-enums.html @@ -148,6 +148,29 @@ + + + + + + + + gcm + + + + + +Integer + + + + + + + + + @@ -212,7 +235,7 @@
Source:
@@ -476,7 +499,7 @@
Source:
@@ -671,7 +694,7 @@
Source:
@@ -1924,7 +1947,7 @@
Source:
@@ -2068,6 +2091,29 @@ fingerprint format

+ + + + seipdv2 + + + + + +Integer + + + + + + + + + + + + + @@ -2105,7 +2151,7 @@ fingerprint format

Source:
@@ -2328,6 +2374,52 @@ fingerprint format

+ + + + + + + + sha3_256 + + + + + +Integer + + + + + + + + + + + + + + + + + sha3_512 + + + + + +Integer + + + + + + + + + @@ -2369,7 +2461,7 @@ fingerprint format

Source:
@@ -2635,7 +2727,7 @@ possession of more than one person.

Source:
@@ -2830,7 +2922,7 @@ possession of more than one person.

Source:
@@ -3306,6 +3398,29 @@ possession of more than one person.

+ + + + + + + + padding + + + + + +Integer + + + + + + + + + @@ -3347,7 +3462,7 @@ possession of more than one person.

Source:
@@ -3599,52 +3714,6 @@ possession of more than one person.

- - - ed25519Legacy - - - - - -Integer - - - - - - - - - - - - - - - - - eddsa - - - - - -Integer - - - - - - - - - - - - - - aedh @@ -3819,7 +3888,7 @@ possession of more than one person.

Source:
@@ -4037,7 +4106,7 @@ possession of more than one person.

Source:
@@ -4168,6 +4237,29 @@ possession of more than one person.

+ + + + + + + + argon2 + + + + + +Integer + + + + + + + + + @@ -4232,7 +4324,7 @@ possession of more than one person.

Source:
@@ -4749,7 +4841,7 @@ document) that cannot include a target subpacket.

Source:
@@ -5048,7 +5140,7 @@ document) that cannot include a target subpacket.

- issuer + issuerKeyID @@ -5409,6 +5501,29 @@ document) that cannot include a target subpacket.

+ + + + + + + + preferredCipherSuites + + + + + +Integer + + + + + + + + + @@ -5450,7 +5565,7 @@ document) that cannot include a target subpacket.

Source:
@@ -5517,29 +5632,6 @@ document) that cannot include a target subpacket.

- - - plaintext - - - - - -Integer - - - - - - - - - - - - - - idea @@ -5760,7 +5852,7 @@ document) that cannot include a target subpacket.

Source:
@@ -5956,7 +6048,7 @@ document) that cannot include a target subpacket.

Source:
@@ -6110,7 +6202,7 @@ document) that cannot include a target subpacket.

Source:
@@ -6326,7 +6418,7 @@ document) that cannot include a target subpacket.

Source:
@@ -6423,13 +6515,13 @@ document) that cannot include a target subpacket.


diff --git a/docs/module-key_Subkey-Subkey.html b/docs/module-key_Subkey-Subkey.html index 5f486957..87f2ab7f 100644 --- a/docs/module-key_Subkey-Subkey.html +++ b/docs/module-key_Subkey-Subkey.html @@ -28,7 +28,8 @@
-

Subkey(subkeyPacket, mainKey)

+

+ key/Subkey~Subkey(subkeyPacket, mainKey)

Class that represents a subkey packet and the relevant signatures.

@@ -170,7 +171,7 @@
Source:
@@ -280,7 +281,7 @@
Source:
@@ -393,7 +394,7 @@
Source:
@@ -510,7 +511,7 @@
Source:
@@ -627,7 +628,7 @@
Source:
@@ -740,7 +741,7 @@
Source:
@@ -941,7 +942,7 @@ Returns null if the subkey is invalid.

Source:
@@ -1054,7 +1055,7 @@ Returns null if the subkey is invalid.

Source:
@@ -1171,7 +1172,7 @@ Returns null if the subkey is invalid.

Source:
@@ -1288,7 +1289,7 @@ Returns null if the subkey is invalid.

Source:
@@ -1405,7 +1406,7 @@ Returns null if the subkey is invalid.

Source:
@@ -1522,7 +1523,7 @@ Returns null if the subkey is invalid.

Source:
@@ -1639,7 +1640,7 @@ Returns null if the subkey is invalid.

Source:
@@ -1756,7 +1757,7 @@ Returns null if the subkey is invalid.

Source:
@@ -1872,7 +1873,7 @@ Returns null if the subkey is invalid.

Source:
@@ -2148,7 +2149,7 @@ Returns null if the subkey is invalid.

Source:
@@ -2486,7 +2487,7 @@ Returns null if the subkey is invalid.

Source:
@@ -2598,7 +2599,7 @@ Returns null if the subkey is invalid.

Source:
@@ -2831,7 +2832,7 @@ Returns null if the subkey is invalid.

Source:
@@ -3043,7 +3044,7 @@ and valid binding signature.

Source:
@@ -3136,13 +3137,13 @@ and valid binding signature.


diff --git a/docs/module-key_Subkey.html b/docs/module-key_Subkey.html new file mode 100644 index 00000000..681d225d --- /dev/null +++ b/docs/module-key_Subkey.html @@ -0,0 +1,92 @@ + + + + + JSDoc: Module: key/Subkey + + + + + + + + + + +
+ +

Module: key/Subkey

+ + + + + + +
+ +
+ + + +
+ +
+
+ + + + + +
+ + + + + + +

Classes

+ +
+
Subkey
+
+
+ + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-key_User-User.html b/docs/module-key_User-User.html index 363373c9..8ef2f320 100644 --- a/docs/module-key_User-User.html +++ b/docs/module-key_User-User.html @@ -28,7 +28,8 @@
-

User(userPacket, mainKey)

+

+ key/User~User(userPacket, mainKey)

Class that represents an user ID or attribute packet and the relevant signatures.

@@ -170,7 +171,7 @@
Source:
@@ -403,7 +404,7 @@
Source:
@@ -515,7 +516,7 @@
Source:
@@ -788,7 +789,7 @@
Source:
@@ -1126,7 +1127,7 @@
Source:
@@ -1238,7 +1239,7 @@
Source:
@@ -1441,7 +1442,7 @@
Source:
@@ -1622,7 +1623,7 @@ and validity of self signature.

Source:
@@ -1886,7 +1887,7 @@ and validity of self signature.

Source:
@@ -2153,7 +2154,7 @@ Signature validity is null if the verification keys do not correspond to the cer
Source:
@@ -2233,13 +2234,13 @@ Signature validity is null if the verification keys do not correspond to the cer
diff --git a/docs/module-key_User.html b/docs/module-key_User.html new file mode 100644 index 00000000..298131b9 --- /dev/null +++ b/docs/module-key_User.html @@ -0,0 +1,92 @@ + + + + + JSDoc: Module: key/User + + + + + + + + + + +
+ +

Module: key/User

+ + + + + + +
+ +
+ + + +
+ +
+
+ + + + + +
+ + + + + + +

Classes

+ +
+
User
+
+
+ + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-key_helper.html b/docs/module-key_helper.html new file mode 100644 index 00000000..45f9f817 --- /dev/null +++ b/docs/module-key_helper.html @@ -0,0 +1,2867 @@ + + + + + JSDoc: Module: key/helper + + + + + + + + + + +
+ +

Module: key/helper

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +

Provides helpers methods for key module

+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

(static) checkKeyRequirements(keyPacket, config)

+ + + + + + +
+

Check key against blacklisted algorithms and minimum strength requirements.

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
keyPacket + + +SecretKeyPacket +| + +PublicKeyPacket +| + +SecretSubkeyPacket +| + +PublicSubkeyPacket + + + +
config + + +Config + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Throws:
+ + + +
+
+
+

if the key packet does not meet the requirements

+
+
+
+
+
+
+ Type +
+
+ +Error + + +
+
+
+
+
+ + + + + + + + + + + + + + + + +

(static) createBindingSignature(subkey, primaryKey, options, config)

+ + + + + + +
+

Create Binding signature to the key according to the https://tools.ietf.org/html/rfc4880#section-5.2.1

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
subkey + + +SecretSubkeyPacket + + + +

Subkey key packet

primaryKey + + +SecretKeyPacket + + + +

Primary key packet

options + + +Object + + + +
config + + +Object + + + +

Full configuration

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(static) createSignaturePacket(dataToSign, privateKey, signingKeyPacket, signaturePropertiesopt, dateopt, userIDopt, notationsopt, detachedopt, config) → {Promise.<SignaturePacket>}

+ + + + + + +
+

Create signature packet

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDescription
dataToSign + + +Object + + + + + + + + + +

Contains packets to be signed

privateKey + + +PrivateKey + + + + + + + + + +

key to get preferences from

signingKeyPacket + + +SecretKeyPacket +| + +SecretSubkeyPacket + + + + + + + + + +

secret key packet for signing

signatureProperties + + +Object + + + + + + <optional>
+ + + + + +

Properties to write on the signature packet before signing

date + + +Date + + + + + + <optional>
+ + + + + +

Override the creationtime of the signature

userID + + +Object + + + + + + <optional>
+ + + + + +

User ID

notations + + +Array + + + + + + <optional>
+ + + + + +

Notation Data to add to the signature, e.g. [{ name: 'test@example.org', value: new TextEncoder().encode('test'), humanReadable: true, critical: false }]

detached + + +Object + + + + + + <optional>
+ + + + + +

Whether to create a detached signature packet

config + + +Object + + + + + + + + + +

full configuration

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Signature packet.

+
+ + + +
+
+ Type +
+
+ +Promise.<SignaturePacket> + + +
+
+ + + + + + + + + + + + + +

(static) getKeyExpirationTime(keyPacket, signature) → {Date|Infinity}

+ + + + + + +
+

Returns key expiration time based on the given certification signature. +The expiration time of the signature is ignored.

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
keyPacket + + +PublicSubkeyPacket +| + +PublicKeyPacket + + + +

key to check

signature + + +SignaturePacket + + + +

signature to process

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

expiration time or infinity if the key does not expire

+
+ + + +
+
+ Type +
+
+ +Date +| + +Infinity + + +
+
+ + + + + + + + + + + + + +

(async, static) getLatestValidSignature(signatures, publicKey, date, config) → {Promise.<SignaturePacket>}

+ + + + + + +
+

Returns the valid and non-expired signature that has the latest creation date, while ignoring signatures created in the future.

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
signatures + + +Array.<SignaturePacket> + + + +

List of signatures

publicKey + + +PublicKeyPacket +| + +PublicSubkeyPacket + + + +

Public key packet to verify the signature

date + + +Date + + + +

Use the given date instead of the current time

config + + +Object + + + +

full configuration

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

The latest valid signature.

+
+ + + +
+
+ Type +
+
+ +Promise.<SignaturePacket> + + +
+
+ + + + + + + + + + + + + +

(async, static) getPreferredCipherSuite(keysopt, dateopt, userIDsopt, configopt) → {Promise.<{symmetricAlgo: module:enums.symmetric, aeadAlgo: (module:enums.aead|undefined)}>}

+ + + + + + +
+

Returns the preferred symmetric and AEAD algorithm (if any) for a set of keys

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDescription
keys + + +Array.<Key> + + + + + + <optional>
+ + + + + +

Set of keys

date + + +Date + + + + + + <optional>
+ + + + + +

Use the given date for verification instead of the current time

userIDs + + +Array + + + + + + <optional>
+ + + + + +

User IDs

config + + +Object + + + + + + <optional>
+ + + + + +

Full configuration, defaults to openpgp.config

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Object containing the preferred symmetric algorithm, and the preferred AEAD algorithm, or undefined if CFB is preferred

+
+ + + +
+
+ Type +
+
+ +Promise.<{symmetricAlgo: module:enums.symmetric, aeadAlgo: (module:enums.aead|undefined)}> + + +
+
+ + + + + + + + + + + + + +

(async, static) getPreferredCompressionAlgo(keysopt, dateopt, userIDsopt, configopt) → {Promise.<module:enums.compression>}

+ + + + + + +
+

Returns the preferred compression algorithm for a set of keys

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDescription
keys + + +Array.<Key> + + + + + + <optional>
+ + + + + +

Set of keys

date + + +Date + + + + + + <optional>
+ + + + + +

Use the given date for verification instead of the current time

userIDs + + +Array + + + + + + <optional>
+ + + + + +

User IDs

config + + +Object + + + + + + <optional>
+ + + + + +

Full configuration, defaults to openpgp.config

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Preferred compression algorithm

+
+ + + +
+
+ Type +
+
+ +Promise.<module:enums.compression> + + +
+
+ + + + + + + + + + + + + +

(async, static) getPreferredHashAlgo(keyopt, keyPacket, dateopt, userIDopt, config) → {Promise.<enums.hash>}

+ + + + + + +
+

Returns the preferred signature hash algorithm of a key

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDescription
key + + +Key + + + + + + <optional>
+ + + + + +

The key to get preferences from

keyPacket + + +SecretKeyPacket +| + +SecretSubkeyPacket + + + + + + + + + +

key packet used for signing

date + + +Date + + + + + + <optional>
+ + + + + +

Use the given date for verification instead of the current time

userID + + +Object + + + + + + <optional>
+ + + + + +

User ID

config + + +Object + + + + + + + + + +

full configuration

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Promise.<enums.hash> + + +
+
+ + + + + + + + + + + + + +

(async, static) isDataRevoked(primaryKey, dataToVerify, revocations, signature, key,, date, config) → {Promise.<Boolean>}

+ + + + + + +
+

Checks if a given certificate or binding signature is revoked

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
primaryKey + + +SecretKeyPacket +| + +PublicKeyPacket + + + +

The primary key packet

dataToVerify + + +Object + + + +

The data to check

revocations + + +Array.<SignaturePacket> + + + +

The revocation signatures to check

signature + + +SignaturePacket + + + +

The certificate or signature to check

key, + + +PublicSubkeyPacket +| + +SecretSubkeyPacket +| + +PublicKeyPacket +| + +SecretKeyPacket + + + +

optional The key packet to verify the signature, instead of the primary key

date + + +Date + + + +

Use the given date instead of the current time

config + + +Object + + + +

Full configuration

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

True if the signature revokes the data.

+
+ + + +
+
+ Type +
+
+ +Promise.<Boolean> + + +
+
+ + + + + + + + + + + + + +

(static) mergeSignatures(source, dest, attr, dateopt, checkFnopt)

+ + + + + + +
+

Merges signatures from source[attr] to dest[attr]

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDescription
source + + +Object + + + + + + + + + +
dest + + +Object + + + + + + + + + +
attr + + +String + + + + + + + + + +
date + + +Date + + + + + + <optional>
+ + + + + +

date to use for signature expiration check, instead of the current time

checkFn + + +function + + + + + + <optional>
+ + + + + +

signature only merged if true

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-packet_packet.html b/docs/module-packet_packet.html new file mode 100644 index 00000000..9215d135 --- /dev/null +++ b/docs/module-packet_packet.html @@ -0,0 +1,866 @@ + + + + + JSDoc: Module: packet/packet + + + + + + + + + + +
+ +

Module: packet/packet

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +

Functions for reading and writing packets

+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

(static) readPackets(input, callback) → {Boolean}

+ + + + + + +
+

Generic static Packet Parser function

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
input + + +Uint8Array +| + +ReadableStream.<Uint8Array> + + + +

Input stream as string

callback + + +function + + + +

Function to call with the parsed packet

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

Returns false if the stream was empty and parsing is done, and true otherwise.

+
+ + + +
+
+ Type +
+
+ +Boolean + + +
+
+ + + + + + + + + + + + + +

(static) supportsStreaming(tag) → {Boolean}

+ + + + + + +
+

Whether the packet type supports partial lengths per RFC4880

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
tag + + +Integer + + + +

Tag type

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

String of the header.

+
+ + + +
+
+ Type +
+
+ +Boolean + + +
+
+ + + + + + + + + + + + + +

(static) writeHeader(tag_type, length) → {String}

+ + + + + + +
+

Writes a packet header version 4 with the given tag_type and length to a +string

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
tag_type + + +Integer + + + +

Tag type

length + + +Integer + + + +

Length of the payload

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

String of the header.

+
+ + + +
+
+ Type +
+
+ +String + + +
+
+ + + + + + + + + + + + + +

(static) writeSimpleLength(length) → {Uint8Array}

+ + + + + + +
+

Encodes a given integer of length to the openpgp length specifier to a +string

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
length + + +Integer + + + +

The length to encode

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

String with openpgp length representation.

+
+ + + +
+
+ Type +
+
+ +Uint8Array + + +
+
+ + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-type_ecdh_symkey.html b/docs/module-type_ecdh_symkey.html new file mode 100644 index 00000000..1849b1da --- /dev/null +++ b/docs/module-type_ecdh_symkey.html @@ -0,0 +1,167 @@ + + + + + JSDoc: Module: type/ecdh_symkey + + + + + + + + + + +
+ +

Module: type/ecdh_symkey

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +

Encoded symmetric key for ECDH (incl. legacy x25519)

+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-type_kdf_params-KDFParams.html b/docs/module-type_kdf_params-KDFParams.html index 62c65074..efa1ab8f 100644 --- a/docs/module-type_kdf_params-KDFParams.html +++ b/docs/module-type_kdf_params-KDFParams.html @@ -163,7 +163,7 @@
Source:
@@ -322,7 +322,7 @@
Source:
@@ -434,7 +434,7 @@
Source:
@@ -502,13 +502,13 @@
diff --git a/docs/module-type_keyid-KeyID.html b/docs/module-type_keyid-KeyID.html index fc2120c4..bb3e2898 100644 --- a/docs/module-type_keyid-KeyID.html +++ b/docs/module-type_keyid-KeyID.html @@ -28,7 +28,8 @@
-

KeyID()

+

+ type/keyid~KeyID()

Implementation of type key id

RFC4880 3.3: @@ -100,7 +101,7 @@ formed.

Source:
@@ -294,7 +295,7 @@ formed.

Source:
@@ -384,7 +385,7 @@ formed.

Source:
@@ -496,7 +497,7 @@ formed.

Source:
@@ -657,7 +658,7 @@ formed.

Source:
@@ -747,7 +748,7 @@ formed.

Source:
@@ -859,7 +860,7 @@ formed.

Source:
@@ -927,13 +928,13 @@ formed.


diff --git a/docs/module-type_keyid.html b/docs/module-type_keyid.html new file mode 100644 index 00000000..35a85bf5 --- /dev/null +++ b/docs/module-type_keyid.html @@ -0,0 +1,92 @@ + + + + + JSDoc: Module: type/keyid + + + + + + + + + + +
+ +

Module: type/keyid

+ + + + + + +
+ +
+ + + +
+ +
+
+ + + + + +
+ + + + + + +

Classes

+ +
+
KeyID
+
+
+ + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-type_oid.html b/docs/module-type_oid.html new file mode 100644 index 00000000..27a5dcd4 --- /dev/null +++ b/docs/module-type_oid.html @@ -0,0 +1,178 @@ + + + + + JSDoc: Module: type/oid + + + + + + + + + + +
+ +

Module: type/oid

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +

Wrapper to an OID value

+

RFC6637, section 11: +The sequence of octets in the third column is the result of applying +the Distinguished Encoding Rules (DER) to the ASN.1 Object Identifier +with subsequent truncation. The truncation removes the two fields of +encoded Object Identifier. The first omitted field is one octet +representing the Object Identifier tag, and the second omitted field +is the length of the Object Identifier body. For example, the +complete ASN.1 DER encoding for the NIST P-256 curve OID is "06 08 2A +86 48 CE 3D 03 01 07", from which the first entry in the table above +is constructed by omitting the first two octets. Only the truncated +sequence of octets is the valid representation of a curve OID.

+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-type_s2k-S2K.html b/docs/module-type_s2k-GenericS2K.html similarity index 51% rename from docs/module-type_s2k-S2K.html rename to docs/module-type_s2k-GenericS2K.html index 50233346..07287091 100644 --- a/docs/module-type_s2k-S2K.html +++ b/docs/module-type_s2k-GenericS2K.html @@ -2,7 +2,7 @@ - JSDoc: Class: S2K + JSDoc: Class: GenericS2K @@ -17,7 +17,7 @@
-

Class: S2K

+

Class: GenericS2K

@@ -28,7 +28,8 @@
-

S2K(configopt)

+

+ type/s2k~GenericS2K(configopt)

@@ -41,7 +42,7 @@ -

new S2K(configopt)

+

new GenericS2K(configopt)

@@ -152,7 +153,7 @@
Source:
@@ -261,7 +262,7 @@
Source:
@@ -331,7 +332,7 @@
Source:
@@ -405,7 +406,7 @@
Source:
@@ -479,7 +480,7 @@
Source:
@@ -611,7 +612,7 @@ hashAlgorithm

Source:
@@ -773,7 +774,7 @@ hashAlgorithm hash length

Source:
@@ -885,7 +886,7 @@ hashAlgorithm hash length

Source:
@@ -953,13 +954,13 @@ hashAlgorithm hash length


diff --git a/docs/module-type_s2k.html b/docs/module-type_s2k.html new file mode 100644 index 00000000..25caf336 --- /dev/null +++ b/docs/module-type_s2k.html @@ -0,0 +1,180 @@ + + + + + JSDoc: Module: type/s2k + + + + + + + + + + +
+ +

Module: type/s2k

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +

Implementation of the String-to-key specifier

+

RFC4880 3.7: +String-to-key (S2K) specifiers are used to convert passphrase strings +into symmetric-key encryption/decryption keys. They are used in two +places, currently: to encrypt the secret part of private keys in the +private keyring, and to convert passphrases to encryption keys for +symmetrically encrypted messages.

+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +

Classes

+ +
+
GenericS2K
+
+
+ + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-type_x25519x448_symkey.html b/docs/module-type_x25519x448_symkey.html index 76ed380e..4e92f253 100644 --- a/docs/module-type_x25519x448_symkey.html +++ b/docs/module-type_x25519x448_symkey.html @@ -91,7 +91,7 @@ the former includes an algorithm byte preceeding the encrypted session key.

<
Source:
@@ -154,13 +154,13 @@ the former includes an algorithm byte preceeding the encrypted session key.

<
diff --git a/docs/module-util.html b/docs/module-util.html new file mode 100644 index 00000000..977a0736 --- /dev/null +++ b/docs/module-util.html @@ -0,0 +1,167 @@ + + + + + JSDoc: Module: util + + + + + + + + + + +
+ +

Module: util

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +

This object contains utility functions

+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 1c9d18f1..243cd2ff 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "openpgp", - "version": "5.11.0", + "version": "6.0.0-alpha.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "openpgp", - "version": "5.11.0", + "version": "6.0.0-alpha.0", "license": "LGPL-3.0+", "dependencies": { "asn1.js": "^5.0.0" diff --git a/package.json b/package.json index cd04fb7a..d55dedc6 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "openpgp", "description": "OpenPGP.js is a Javascript implementation of the OpenPGP protocol. This is defined in RFC 4880.", - "version": "5.11.0", + "version": "6.0.0-alpha.0", "license": "LGPL-3.0+", "homepage": "https://openpgpjs.org/", "engines": { From 54fc2c8fbd7e8a877e3995672fc9b8c9c74361b9 Mon Sep 17 00:00:00 2001 From: Ryan Date: Thu, 2 Nov 2023 09:16:40 -0400 Subject: [PATCH 087/201] Add SHA3-256 and SHA3-512 to preferred hash algos on key generation (#1696) This is to signal support to senders who wish to use these algos. Note that SHA256 remains as first default preference, followed by SHA512, as in the context of OpenPGP signatures they provide better performance/security ratio than their SHA3 counterparts. --- openpgp.d.ts | 4 +++- src/key/factory.js | 4 +++- test/general/key.js | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/openpgp.d.ts b/openpgp.d.ts index 2b5509b4..76a4072c 100644 --- a/openpgp.d.ts +++ b/openpgp.d.ts @@ -782,7 +782,7 @@ export namespace enums { bzip2 = 3, } - export type hashNames = 'md5' | 'sha1' | 'ripemd' | 'sha256' | 'sha384' | 'sha512' | 'sha224'; + export type hashNames = 'md5' | 'sha1' | 'ripemd' | 'sha256' | 'sha384' | 'sha512' | 'sha224' | 'sha3_256' | 'sha3_512'; enum hash { md5 = 1, sha1 = 2, @@ -791,6 +791,8 @@ export namespace enums { sha384 = 9, sha512 = 10, sha224 = 11, + sha3_256 = 12, + sha3_512 = 14 } export type packetNames = 'publicKeyEncryptedSessionKey' | 'signature' | 'symEncryptedSessionKey' | 'onePassSignature' | 'secretKey' | 'publicKey' diff --git a/src/key/factory.js b/src/key/factory.js index c485b35c..43f07c06 100644 --- a/src/key/factory.js +++ b/src/key/factory.js @@ -216,7 +216,9 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, conf signatureProperties.preferredHashAlgorithms = createPreferredAlgos([ // prefer fast asm.js implementations (SHA-256) enums.hash.sha256, - enums.hash.sha512 + enums.hash.sha512, + enums.hash.sha3_256, + enums.hash.sha3_512 ], config.preferredHashAlgorithm); signatureProperties.preferredCompressionAlgorithms = createPreferredAlgos([ enums.compression.uncompressed diff --git a/test/general/key.js b/test/general/key.js index 341b95d8..07c7b092 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -2262,7 +2262,7 @@ function versionSpecificTests() { ]); } const hash = openpgp.enums.hash; - expect(selfSignature.preferredHashAlgorithms).to.eql([hash.sha256, hash.sha512]); + expect(selfSignature.preferredHashAlgorithms).to.eql([hash.sha256, hash.sha512, hash.sha3_256, hash.sha3_512]); const compr = openpgp.enums.compression; expect(selfSignature.preferredCompressionAlgorithms).to.eql([compr.uncompressed]); @@ -2317,7 +2317,7 @@ function versionSpecificTests() { ]); } const hash = openpgp.enums.hash; - expect(selfSignature.preferredHashAlgorithms).to.eql([hash.sha224, hash.sha256, hash.sha512]); + expect(selfSignature.preferredHashAlgorithms).to.eql([hash.sha224, hash.sha256, hash.sha512, hash.sha3_256, hash.sha3_512]); const compr = openpgp.enums.compression; expect(selfSignature.preferredCompressionAlgorithms).to.eql([compr.zlib, compr.uncompressed]); From e93702bb8dfdca99cc411c36ded269cab0177cf7 Mon Sep 17 00:00:00 2001 From: larabr Date: Tue, 21 Nov 2023 13:16:40 +0100 Subject: [PATCH 088/201] Fix types path for lightweight build [skip ci] --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d55dedc6..a6ad71ab 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "browser": "./dist/openpgp.min.mjs" }, "./lightweight": { - "types": "../openpgp.d.ts", + "types": "./openpgp.d.ts", "browser": "./dist/lightweight/openpgp.min.mjs" } }, From ff4181ad5a42c3fcbe775a8607cc10db08908e59 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Fri, 8 Dec 2023 14:00:22 +0100 Subject: [PATCH 089/201] Add back zlib and zip to preferred compression algos on key generation To signal support, despite "no compression" being preferred by default, for security reasons. --- src/key/factory.js | 4 +++- test/general/key.js | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/key/factory.js b/src/key/factory.js index 43f07c06..37ee2a77 100644 --- a/src/key/factory.js +++ b/src/key/factory.js @@ -221,7 +221,9 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, conf enums.hash.sha3_512 ], config.preferredHashAlgorithm); signatureProperties.preferredCompressionAlgorithms = createPreferredAlgos([ - enums.compression.uncompressed + enums.compression.uncompressed, + enums.compression.zlib, + enums.compression.zip ], config.preferredCompressionAlgorithm); // integrity protection always enabled signatureProperties.features = [0]; diff --git a/test/general/key.js b/test/general/key.js index 07c7b092..34442073 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -2264,7 +2264,7 @@ function versionSpecificTests() { const hash = openpgp.enums.hash; expect(selfSignature.preferredHashAlgorithms).to.eql([hash.sha256, hash.sha512, hash.sha3_256, hash.sha3_512]); const compr = openpgp.enums.compression; - expect(selfSignature.preferredCompressionAlgorithms).to.eql([compr.uncompressed]); + expect(selfSignature.preferredCompressionAlgorithms).to.eql([compr.uncompressed, compr.zlib, compr.zip]); let expectedFeatures = 0x01; // SEIPDv1 if (openpgp.config.aeadProtect) { @@ -2319,7 +2319,7 @@ function versionSpecificTests() { const hash = openpgp.enums.hash; expect(selfSignature.preferredHashAlgorithms).to.eql([hash.sha224, hash.sha256, hash.sha512, hash.sha3_256, hash.sha3_512]); const compr = openpgp.enums.compression; - expect(selfSignature.preferredCompressionAlgorithms).to.eql([compr.zlib, compr.uncompressed]); + expect(selfSignature.preferredCompressionAlgorithms).to.eql([compr.zlib, compr.uncompressed, compr.zip]); let expectedFeatures = 0x01; // SEIPDv1 if (openpgp.config.aeadProtect) { From 90a2af9fe232c3239d3b124eb71de1770b53516b Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Fri, 8 Dec 2023 14:46:41 +0100 Subject: [PATCH 090/201] Tests: fix flaky elliptic curve test in Node `genKeyPair()` does not pad the returned values. This caused random test failures in Node as some secret keys are 1 byte short. --- test/crypto/elliptic.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/crypto/elliptic.js b/test/crypto/elliptic.js index c755524e..c93a89c4 100644 --- a/test/crypto/elliptic.js +++ b/test/crypto/elliptic.js @@ -242,7 +242,7 @@ export default () => describe('Elliptic Curve Cryptography @lightweight', functi const curves = ['secp256k1' , 'p256', 'p384', 'p521', 'brainpoolP256r1', 'brainpoolP384r1', 'brainpoolP512r1']; curves.forEach(curveName => it(`${curveName} - Sign and verify message`, async function () { const curve = new elliptic_curves.CurveWithOID(curveName); - const { publicKey: keyPublic, privateKey: keyPrivate } = await curve.genKeyPair(); + const { Q: keyPublic, secret: keyPrivate } = await elliptic_curves.generate(curveName); const message = new Uint8Array([ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF From c754fac10f5186cbdc912cc3806311814a83804d Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Fri, 8 Dec 2023 14:53:19 +0100 Subject: [PATCH 091/201] CI: replace nyc with c8 as coverage tool Unclear if nyc is still actively maintained, and it does not seem to work with ESM out of the box. --- .gitignore | 2 +- package-lock.json | 2776 +++++++++------------------------------------ package.json | 6 +- 3 files changed, 510 insertions(+), 2274 deletions(-) diff --git a/.gitignore b/.gitignore index 805fe8d3..5781473f 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,4 @@ test/lib/ test/typescript/definitions.js dist/ openpgp.store/ -.nyc_output/ +coverage diff --git a/package-lock.json b/package-lock.json index 243cd2ff..d2c111e4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,6 +29,7 @@ "argon2id": "^1.0.1", "benchmark": "^2.1.4", "bn.js": "^4.11.8", + "c8": "^8.0.1", "chai": "^4.3.7", "chai-as-promised": "^7.1.1", "eslint": "^8.34.0", @@ -47,7 +48,6 @@ "karma-mocha-reporter": "^2.2.5", "karma-webkit-launcher": "^2.1.0", "mocha": "^10.2.0", - "nyc": "^14.1.1", "playwright": "^1.30.0", "rollup": "^3.29.4", "sinon": "^15.1.0", @@ -69,85 +69,54 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", - "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", "dev": true, "dependencies": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/generator": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.5.tgz", - "integrity": "sha512-SrKK/sRv8GesIW1bDagf9cCG38IOMYZusoe1dfg0D8aiUe3Amvoj1QtjTPAWcfrZFvIwlleLb0gxzQidL9w14w==", + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "dependencies": { - "@babel/types": "^7.21.5", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" + "color-convert": "^1.9.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=4" } }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.21.5.tgz", - "integrity": "sha512-IYl4gZ3ETsWocUWgsFZLM5i1BYx9SoemminVEXadgLBa9TdeorzgLKm8wWLA6J1N/kT3Kch8XIk1laNzYoHKvQ==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", - "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "dependencies": { - "@babel/template": "^7.20.7", - "@babel/types": "^7.21.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=4" } }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "dependencies": { - "@babel/types": "^7.18.6" + "has-flag": "^3.0.0" }, "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.21.5.tgz", - "integrity": "sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==", - "dev": true, - "engines": { - "node": ">=6.9.0" + "node": ">=4" } }, "node_modules/@babel/helper-validator-identifier": { @@ -160,13 +129,13 @@ } }, "node_modules/@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { @@ -212,9 +181,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.21.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.8.tgz", - "integrity": "sha512-6zavDGdzG3gUqAdWvlLFfk+36RilI+Pwyuuh7HItyeScCWP3k6i8vKclAQ0bM/0y/Kz/xiwvxhMv9MgTJP5gmA==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz", + "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -250,71 +219,12 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/template": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", - "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.5.tgz", - "integrity": "sha512-AhQoI3YjWi6u/y/ntv7k48mcrCXmus0t79J9qPNlk/lAsFlCiJ047RmbfMOawySTHtywXhbXgpx/8nXMYd+oFw==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.5", - "@babel/helper-environment-visitor": "^7.21.5", - "@babel/helper-function-name": "^7.21.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.21.5", - "@babel/types": "^7.21.5", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse/node_modules/debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/@babel/traverse/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "node_modules/@babel/types": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.5.tgz", - "integrity": "sha512-m4AfNvVF2mVC/F7fDEdH2El3HzUg9It/XsCxZiOTTA3m3qYfcSVSbTfM6Q9xG+hYDniZssYhlXKKUMD5m8tF4Q==", - "dev": true, - "dependencies": { - "@babel/helper-string-parser": "^7.21.5", - "@babel/helper-validator-identifier": "^7.19.1", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -514,6 +424,15 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", @@ -1050,6 +969,12 @@ "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", "dev": true }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -1225,24 +1150,6 @@ "node": ">= 8" } }, - "node_modules/append-transform": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", - "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", - "dev": true, - "dependencies": { - "default-require-extensions": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", - "dev": true - }, "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -1255,15 +1162,6 @@ "integrity": "sha512-rsiD3lX+0L0CsiZARp3bf9EGxprtuWAT7PpiJd+Fk53URV0/USOQkBIP1dLTV8t6aui0ECbymQ9W9YCcTd6XgA==", "dev": true }, - "node_modules/argparse": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", - "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, "node_modules/aria-query": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", @@ -1608,30 +1506,219 @@ "node": ">= 0.8" } }, - "node_modules/caching-transform": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-3.0.2.tgz", - "integrity": "sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w==", + "node_modules/c8": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/c8/-/c8-8.0.1.tgz", + "integrity": "sha512-EINpopxZNH1mETuI0DzRA4MZpAUH+IFiRhnmFD3vFr3vdrgxqi3VfE3KL0AIL+zDq8rC9bZqwM/VDmmoe04y7w==", "dev": true, "dependencies": { - "hasha": "^3.0.0", - "make-dir": "^2.0.0", - "package-hash": "^3.0.0", - "write-file-atomic": "^2.4.2" + "@bcoe/v8-coverage": "^0.2.3", + "@istanbuljs/schema": "^0.1.3", + "find-up": "^5.0.0", + "foreground-child": "^2.0.0", + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.1.6", + "rimraf": "^3.0.2", + "test-exclude": "^6.0.0", + "v8-to-istanbul": "^9.0.0", + "yargs": "^17.7.2", + "yargs-parser": "^21.1.1" + }, + "bin": { + "c8": "bin/c8.js" }, "engines": { - "node": ">=6" + "node": ">=12" } }, - "node_modules/caching-transform/node_modules/write-file-atomic": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "node_modules/c8/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, "dependencies": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/c8/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/c8/node_modules/foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/c8/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/c8/node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/c8/node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/c8/node_modules/istanbul-reports": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/c8/node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/c8/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/c8/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/c8/node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/c8/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/c8/node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/c8/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/c8/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" } }, "node_modules/call-bind": { @@ -1656,15 +1743,6 @@ "node": ">=6" } }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/catharsis": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", @@ -1786,38 +1864,6 @@ "node": ">=4" } }, - "node_modules/cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "node_modules/cliui/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/color-convert": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", @@ -1887,15 +1933,6 @@ "node": ">= 0.6" } }, - "node_modules/convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.1" - } - }, "node_modules/cookie": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", @@ -1939,31 +1976,6 @@ "node": ">= 0.4.0" } }, - "node_modules/cp-file": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-6.2.0.tgz", - "integrity": "sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "make-dir": "^2.0.0", - "nested-error-stacks": "^2.0.0", - "pify": "^4.0.1", - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/cp-file/node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -2030,15 +2042,6 @@ "ms": "2.0.0" } }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/deep-eql": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", @@ -2066,18 +2069,6 @@ "node": ">=0.10.0" } }, - "node_modules/default-require-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", - "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", - "dev": true, - "dependencies": { - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/define-properties": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", @@ -2154,12 +2145,6 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", "dev": true }, - "node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -2310,12 +2295,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true - }, "node_modules/es6-promise": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", @@ -2907,19 +2886,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/esquery": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", @@ -3082,93 +3048,6 @@ "node": ">= 0.8" } }, - "node_modules/find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/find-cache-dir/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/find-cache-dir/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/find-cache-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/find-cache-dir/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/find-cache-dir/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/find-cache-dir/node_modules/pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "dependencies": { - "find-up": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -3233,36 +3112,6 @@ } } }, - "node_modules/foreground-child": { - "version": "1.5.6", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", - "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=", - "dev": true, - "dependencies": { - "cross-spawn": "^4", - "signal-exit": "^3.0.0" - } - }, - "node_modules/foreground-child/node_modules/cross-spawn": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", - "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", - "dev": true, - "dependencies": { - "lru-cache": "^4.0.1", - "which": "^1.2.9" - } - }, - "node_modules/foreground-child/node_modules/lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, "node_modules/from": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", @@ -3422,15 +3271,6 @@ "node": ">= 6" } }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/graceful-fs": { "version": "4.1.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", @@ -3521,18 +3361,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/hasha": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", - "integrity": "sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk=", - "dev": true, - "dependencies": { - "is-stream": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -3862,15 +3690,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -3986,15 +3805,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-string": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", @@ -4085,164 +3895,12 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, - "node_modules/istanbul-lib-coverage": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", - "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/istanbul-lib-hook": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz", - "integrity": "sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==", - "dev": true, - "dependencies": { - "append-transform": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", - "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", - "dev": true, - "dependencies": { - "@babel/generator": "^7.4.0", - "@babel/parser": "^7.4.3", - "@babel/template": "^7.4.0", - "@babel/traverse": "^7.4.3", - "@babel/types": "^7.4.0", - "istanbul-lib-coverage": "^2.0.5", - "semver": "^6.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/istanbul-lib-report": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", - "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", - "dev": true, - "dependencies": { - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "supports-color": "^6.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/istanbul-lib-report/node_modules/supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", - "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "rimraf": "^2.6.3", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/istanbul-lib-source-maps/node_modules/debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/istanbul-lib-source-maps/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/istanbul-lib-source-maps/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/istanbul-lib-source-maps/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/istanbul-reports": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz", - "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==", - "dev": true, - "dependencies": { - "html-escaper": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, - "node_modules/js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/js2xmlparser": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", @@ -4252,24 +3910,6 @@ "xmlcreate": "^2.0.4" } }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -4719,12 +4359,6 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, - "node_modules/lodash.flattendeep": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", - "dev": true - }, "node_modules/lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", @@ -4878,28 +4512,6 @@ "node": ">=12" } }, - "node_modules/make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/make-dir/node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", @@ -4971,24 +4583,6 @@ "node": ">= 0.6" } }, - "node_modules/merge-source-map": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", - "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", - "dev": true, - "dependencies": { - "source-map": "^0.6.1" - } - }, - "node_modules/merge-source-map/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/mime": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", @@ -5405,12 +4999,6 @@ "node": ">= 0.6" } }, - "node_modules/nested-error-stacks": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz", - "integrity": "sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==", - "dev": true - }, "node_modules/nise": { "version": "5.1.4", "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.4.tgz", @@ -5454,118 +5042,6 @@ "node": ">=0.10.0" } }, - "node_modules/nyc": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-14.1.1.tgz", - "integrity": "sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw==", - "dev": true, - "dependencies": { - "archy": "^1.0.0", - "caching-transform": "^3.0.2", - "convert-source-map": "^1.6.0", - "cp-file": "^6.2.0", - "find-cache-dir": "^2.1.0", - "find-up": "^3.0.0", - "foreground-child": "^1.5.6", - "glob": "^7.1.3", - "istanbul-lib-coverage": "^2.0.5", - "istanbul-lib-hook": "^2.0.7", - "istanbul-lib-instrument": "^3.3.0", - "istanbul-lib-report": "^2.0.8", - "istanbul-lib-source-maps": "^3.0.6", - "istanbul-reports": "^2.2.4", - "js-yaml": "^3.13.1", - "make-dir": "^2.1.0", - "merge-source-map": "^1.1.0", - "resolve-from": "^4.0.0", - "rimraf": "^2.6.3", - "signal-exit": "^3.0.2", - "spawn-wrap": "^1.4.2", - "test-exclude": "^5.2.3", - "uuid": "^3.3.2", - "yargs": "^13.2.2", - "yargs-parser": "^13.0.0" - }, - "bin": { - "nyc": "bin/nyc.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/nyc/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/nyc/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/nyc/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/nyc/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/nyc/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/nyc/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -5721,15 +5197,6 @@ "node": ">= 0.8.0" } }, - "node_modules/os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -5769,27 +5236,6 @@ "node": ">=6" } }, - "node_modules/package-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-3.0.0.tgz", - "integrity": "sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.15", - "hasha": "^3.0.0", - "lodash.flattendeep": "^4.4.0", - "release-zalgo": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/package-hash/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -6009,12 +5455,6 @@ "node": ">= 0.10" } }, - "node_modules/pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, "node_modules/punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", @@ -6298,18 +5738,6 @@ "jsesc": "bin/jsesc" } }, - "node_modules/release-zalgo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", - "dev": true, - "dependencies": { - "es6-error": "^4.0.1" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -6319,12 +5747,6 @@ "node": ">=0.10.0" } }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -6477,12 +5899,6 @@ "semver": "bin/semver" } }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -6670,44 +6086,6 @@ "node": ">=0.10.0" } }, - "node_modules/spawn-wrap": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.3.tgz", - "integrity": "sha512-IgB8md0QW/+tWqcavuFgKYR/qIRvJkRLPJDFaoXtLLUaVcCDK0+HeFTkmQHj3eprcYhc+gOl0aEA1w7qZlYezw==", - "dev": true, - "dependencies": { - "foreground-child": "^1.5.6", - "mkdirp": "^0.5.0", - "os-homedir": "^1.0.1", - "rimraf": "^2.6.2", - "signal-exit": "^3.0.2", - "which": "^1.3.0" - } - }, - "node_modules/spawn-wrap/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/spawn-wrap/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, "node_modules/spdx-correct": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", @@ -6741,12 +6119,6 @@ "node": "*" } }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, "node_modules/statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", @@ -6802,41 +6174,6 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/string-width/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/string-width/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/string.prototype.matchall": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz", @@ -7017,158 +6354,6 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, - "node_modules/test-exclude": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", - "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", - "dev": true, - "dependencies": { - "glob": "^7.1.3", - "minimatch": "^3.0.4", - "read-pkg-up": "^4.0.0", - "require-main-filename": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/test-exclude/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/test-exclude/node_modules/load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/test-exclude/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/test-exclude/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/test-exclude/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/test-exclude/node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/test-exclude/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/test-exclude/node_modules/path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "dependencies": { - "pify": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/test-exclude/node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/test-exclude/node_modules/read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", - "dev": true, - "dependencies": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/test-exclude/node_modules/read-pkg-up": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", - "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", - "dev": true, - "dependencies": { - "find-up": "^3.0.0", - "read-pkg": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -7181,15 +6366,6 @@ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -7422,22 +6598,32 @@ "node": ">= 0.4.0" } }, - "node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "bin": { - "uuid": "bin/uuid" - } - }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "dev": true }, + "node_modules/v8-to-istanbul": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", + "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/v8-to-istanbul/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, "node_modules/validate-npm-package-license": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", @@ -7527,65 +6713,12 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, "node_modules/workerpool": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", "dev": true }, - "node_modules/wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -7619,46 +6752,6 @@ "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", "dev": true }, - "node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "node_modules/yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - }, - "node_modules/yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "dependencies": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "node_modules/yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, "node_modules/yargs-unparser": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", @@ -7698,67 +6791,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/yargs/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yargs/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", @@ -7789,66 +6821,46 @@ "dev": true }, "@babel/code-frame": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", - "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", "dev": true, "requires": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, - "@babel/generator": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.5.tgz", - "integrity": "sha512-SrKK/sRv8GesIW1bDagf9cCG38IOMYZusoe1dfg0D8aiUe3Amvoj1QtjTPAWcfrZFvIwlleLb0gxzQidL9w14w==", - "dev": true, - "requires": { - "@babel/types": "^7.21.5", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" - } - }, - "@babel/helper-environment-visitor": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.21.5.tgz", - "integrity": "sha512-IYl4gZ3ETsWocUWgsFZLM5i1BYx9SoemminVEXadgLBa9TdeorzgLKm8wWLA6J1N/kT3Kch8XIk1laNzYoHKvQ==", - "dev": true - }, - "@babel/helper-function-name": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", - "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", - "dev": true, - "requires": { - "@babel/template": "^7.20.7", - "@babel/types": "^7.21.0" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-string-parser": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.21.5.tgz", - "integrity": "sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==", - "dev": true - }, "@babel/helper-validator-identifier": { "version": "7.22.20", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", @@ -7856,13 +6868,13 @@ "dev": true }, "@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "dependencies": { @@ -7898,9 +6910,9 @@ } }, "@babel/parser": { - "version": "7.21.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.8.tgz", - "integrity": "sha512-6zavDGdzG3gUqAdWvlLFfk+36RilI+Pwyuuh7HItyeScCWP3k6i8vKclAQ0bM/0y/Kz/xiwvxhMv9MgTJP5gmA==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz", + "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==", "dev": true }, "@babel/runtime": { @@ -7924,62 +6936,11 @@ "regenerator-runtime": "^0.13.4" } }, - "@babel/template": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", - "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7" - } - }, - "@babel/traverse": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.5.tgz", - "integrity": "sha512-AhQoI3YjWi6u/y/ntv7k48mcrCXmus0t79J9qPNlk/lAsFlCiJ047RmbfMOawySTHtywXhbXgpx/8nXMYd+oFw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.5", - "@babel/helper-environment-visitor": "^7.21.5", - "@babel/helper-function-name": "^7.21.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.21.5", - "@babel/types": "^7.21.5", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "@babel/types": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.5.tgz", - "integrity": "sha512-m4AfNvVF2mVC/F7fDEdH2El3HzUg9It/XsCxZiOTTA3m3qYfcSVSbTfM6Q9xG+hYDniZssYhlXKKUMD5m8tF4Q==", - "dev": true, - "requires": { - "@babel/helper-string-parser": "^7.21.5", - "@babel/helper-validator-identifier": "^7.19.1", - "to-fast-properties": "^2.0.0" - } + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true }, "@colors/colors": { "version": "1.5.0", @@ -8127,6 +7088,12 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true + }, "@jridgewell/gen-mapping": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", @@ -8529,6 +7496,12 @@ "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", "dev": true }, + "@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true + }, "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -8667,21 +7640,6 @@ "picomatch": "^2.0.4" } }, - "append-transform": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", - "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", - "dev": true, - "requires": { - "default-require-extensions": "^2.0.0" - } - }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", - "dev": true - }, "arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -8694,15 +7652,6 @@ "integrity": "sha512-rsiD3lX+0L0CsiZARp3bf9EGxprtuWAT7PpiJd+Fk53URV0/USOQkBIP1dLTV8t6aui0ECbymQ9W9YCcTd6XgA==", "dev": true }, - "argparse": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", - "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, "aria-query": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", @@ -8977,28 +7926,163 @@ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true }, - "caching-transform": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-3.0.2.tgz", - "integrity": "sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w==", + "c8": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/c8/-/c8-8.0.1.tgz", + "integrity": "sha512-EINpopxZNH1mETuI0DzRA4MZpAUH+IFiRhnmFD3vFr3vdrgxqi3VfE3KL0AIL+zDq8rC9bZqwM/VDmmoe04y7w==", "dev": true, "requires": { - "hasha": "^3.0.0", - "make-dir": "^2.0.0", - "package-hash": "^3.0.0", - "write-file-atomic": "^2.4.2" + "@bcoe/v8-coverage": "^0.2.3", + "@istanbuljs/schema": "^0.1.3", + "find-up": "^5.0.0", + "foreground-child": "^2.0.0", + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.1.6", + "rimraf": "^3.0.2", + "test-exclude": "^6.0.0", + "v8-to-istanbul": "^9.0.0", + "yargs": "^17.7.2", + "yargs-parser": "^21.1.1" }, "dependencies": { - "write-file-atomic": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, "requires": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", "signal-exit": "^3.0.2" } + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true + }, + "istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + } + }, + "istanbul-reports": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "requires": { + "semver": "^7.5.3" + } + }, + "semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true } } }, @@ -9018,12 +8102,6 @@ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, "catharsis": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", @@ -9104,34 +8182,6 @@ "escape-string-regexp": "^1.0.5" } }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, "color-convert": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", @@ -9192,15 +8242,6 @@ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", "dev": true }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - } - }, "cookie": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", @@ -9230,27 +8271,6 @@ "integrity": "sha1-jtolLsqrWEDc2XXOuQ2TcMgZ/4c=", "dev": true }, - "cp-file": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-6.2.0.tgz", - "integrity": "sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "make-dir": "^2.0.0", - "nested-error-stacks": "^2.0.0", - "pify": "^4.0.1", - "safe-buffer": "^5.0.1" - }, - "dependencies": { - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - } - } - }, "create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -9307,12 +8327,6 @@ "ms": "2.0.0" } }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, "deep-eql": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", @@ -9334,15 +8348,6 @@ "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true }, - "default-require-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", - "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", - "dev": true, - "requires": { - "strip-bom": "^3.0.0" - } - }, "define-properties": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", @@ -9404,12 +8409,6 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", "dev": true }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -9530,12 +8529,6 @@ "is-symbol": "^1.0.2" } }, - "es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true - }, "es6-promise": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", @@ -9983,12 +8976,6 @@ "eslint-visitor-keys": "^3.4.1" } }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, "esquery": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", @@ -10129,71 +9116,6 @@ "unpipe": "~1.0.0" } }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - } - } - }, "find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -10232,38 +9154,6 @@ "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", "dev": true }, - "foreground-child": { - "version": "1.5.6", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", - "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=", - "dev": true, - "requires": { - "cross-spawn": "^4", - "signal-exit": "^3.0.0" - }, - "dependencies": { - "cross-spawn": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", - "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "which": "^1.2.9" - } - }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - } - } - }, "from": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", @@ -10382,12 +9272,6 @@ "is-glob": "^4.0.1" } }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - }, "graceful-fs": { "version": "4.1.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", @@ -10451,15 +9335,6 @@ "has-symbols": "^1.0.2" } }, - "hasha": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", - "integrity": "sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk=", - "dev": true, - "requires": { - "is-stream": "^1.0.1" - } - }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -10708,12 +9583,6 @@ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -10796,12 +9665,6 @@ "call-bind": "^1.0.2" } }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, "is-string": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", @@ -10862,136 +9725,12 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, - "istanbul-lib-coverage": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", - "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", - "dev": true - }, - "istanbul-lib-hook": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz", - "integrity": "sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==", - "dev": true, - "requires": { - "append-transform": "^1.0.0" - } - }, - "istanbul-lib-instrument": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", - "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", - "dev": true, - "requires": { - "@babel/generator": "^7.4.0", - "@babel/parser": "^7.4.3", - "@babel/template": "^7.4.0", - "@babel/traverse": "^7.4.3", - "@babel/types": "^7.4.0", - "istanbul-lib-coverage": "^2.0.5", - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "istanbul-lib-report": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", - "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "supports-color": "^6.1.0" - }, - "dependencies": { - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "istanbul-lib-source-maps": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", - "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "rimraf": "^2.6.3", - "source-map": "^0.6.1" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "istanbul-reports": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz", - "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==", - "dev": true, - "requires": { - "html-escaper": "^2.0.0" - } - }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, "js2xmlparser": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", @@ -11001,18 +9740,6 @@ "xmlcreate": "^2.0.4" } }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, "json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -11385,12 +10112,6 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, - "lodash.flattendeep": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", - "dev": true - }, "lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", @@ -11518,24 +10239,6 @@ "@jridgewell/sourcemap-codec": "^1.4.13" } }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - } - } - }, "make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", @@ -11594,23 +10297,6 @@ "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", "dev": true }, - "merge-source-map": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", - "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, "mime": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", @@ -11923,12 +10609,6 @@ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "dev": true }, - "nested-error-stacks": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz", - "integrity": "sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==", - "dev": true - }, "nise": { "version": "5.1.4", "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.4.tgz", @@ -11971,93 +10651,6 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, - "nyc": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-14.1.1.tgz", - "integrity": "sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw==", - "dev": true, - "requires": { - "archy": "^1.0.0", - "caching-transform": "^3.0.2", - "convert-source-map": "^1.6.0", - "cp-file": "^6.2.0", - "find-cache-dir": "^2.1.0", - "find-up": "^3.0.0", - "foreground-child": "^1.5.6", - "glob": "^7.1.3", - "istanbul-lib-coverage": "^2.0.5", - "istanbul-lib-hook": "^2.0.7", - "istanbul-lib-instrument": "^3.3.0", - "istanbul-lib-report": "^2.0.8", - "istanbul-lib-source-maps": "^3.0.6", - "istanbul-reports": "^2.2.4", - "js-yaml": "^3.13.1", - "make-dir": "^2.1.0", - "merge-source-map": "^1.1.0", - "resolve-from": "^4.0.0", - "rimraf": "^2.6.3", - "signal-exit": "^3.0.2", - "spawn-wrap": "^1.4.2", - "test-exclude": "^5.2.3", - "uuid": "^3.3.2", - "yargs": "^13.2.2", - "yargs-parser": "^13.0.0" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -12171,12 +10764,6 @@ "type-check": "^0.4.0" } }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -12201,26 +10788,6 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, - "package-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-3.0.0.tgz", - "integrity": "sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.15", - "hasha": "^3.0.0", - "lodash.flattendeep": "^4.4.0", - "release-zalgo": "^1.0.0" - }, - "dependencies": { - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - } - } - }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -12384,12 +10951,6 @@ "event-stream": "=3.3.4" } }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, "punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", @@ -12594,27 +11155,12 @@ } } }, - "release-zalgo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", - "dev": true, - "requires": { - "es6-error": "^4.0.1" - } - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -12721,12 +11267,6 @@ "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, "setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -12876,40 +11416,6 @@ } } }, - "spawn-wrap": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.3.tgz", - "integrity": "sha512-IgB8md0QW/+tWqcavuFgKYR/qIRvJkRLPJDFaoXtLLUaVcCDK0+HeFTkmQHj3eprcYhc+gOl0aEA1w7qZlYezw==", - "dev": true, - "requires": { - "foreground-child": "^1.5.6", - "mkdirp": "^0.5.0", - "os-homedir": "^1.0.1", - "rimraf": "^2.6.2", - "signal-exit": "^3.0.2", - "which": "^1.3.0" - }, - "dependencies": { - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, "spdx-correct": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", @@ -12940,12 +11446,6 @@ "through": "2" } }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, "statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", @@ -12989,34 +11489,6 @@ } } }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, "string.prototype.matchall": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz", @@ -13155,121 +11627,6 @@ } } }, - "test-exclude": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", - "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", - "dev": true, - "requires": { - "glob": "^7.1.3", - "minimatch": "^3.0.4", - "read-pkg-up": "^4.0.0", - "require-main-filename": "^2.0.0" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - } - }, - "read-pkg-up": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", - "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", - "dev": true, - "requires": { - "find-up": "^3.0.0", - "read-pkg": "^3.0.0" - } - } - } - }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -13282,12 +11639,6 @@ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true - }, "toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -13444,18 +11795,31 @@ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", "dev": true }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true - }, "v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "dev": true }, + "v8-to-istanbul": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", + "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "dependencies": { + "convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + } + } + }, "validate-npm-package-license": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", @@ -13526,55 +11890,12 @@ "is-symbol": "^1.0.3" } }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, "workerpool": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", "dev": true }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -13594,91 +11915,6 @@ "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", "dev": true }, - "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, "yargs-unparser": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", diff --git a/package.json b/package.json index a6ad71ab..b7a5b31d 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "browsertest": "npm start -- -o test/unittests.html", "test-browser": "karma start test/karma.conf.cjs", "test-browserstack": "karma start test/karma.conf.cjs --browsers bs_safari_latest,bs_ios_14,bs_safari_13_1", - "coverage": "nyc npm test", + "coverage": "c8 npm test", "lint": "eslint .", "docs": "jsdoc --configure .jsdocrc.cjs --destination docs --recurse README.md src && printf '%s' 'docs.openpgpjs.org' > docs/CNAME", "preversion": "rm -rf dist docs node_modules && npm ci && npm test", @@ -63,8 +63,8 @@ }, "devDependencies": { "@openpgp/asmcrypto.js": "^3.0.0", - "@openpgp/noble-curves": "^1.2.1-0", "@openpgp/jsdoc": "^3.6.11", + "@openpgp/noble-curves": "^1.2.1-0", "@openpgp/noble-hashes": "^1.3.3-0", "@openpgp/seek-bzip": "^1.0.5-git", "@openpgp/tweetnacl": "^1.0.4-1", @@ -79,6 +79,7 @@ "argon2id": "^1.0.1", "benchmark": "^2.1.4", "bn.js": "^4.11.8", + "c8": "^8.0.1", "chai": "^4.3.7", "chai-as-promised": "^7.1.1", "eslint": "^8.34.0", @@ -97,7 +98,6 @@ "karma-mocha-reporter": "^2.2.5", "karma-webkit-launcher": "^2.1.0", "mocha": "^10.2.0", - "nyc": "^14.1.1", "playwright": "^1.30.0", "rollup": "^3.29.4", "sinon": "^15.1.0", From e92b44bc843df3dcd46eb5a39ec120fab414e98f Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Fri, 8 Dec 2023 15:10:27 +0100 Subject: [PATCH 092/201] CI (temp): fix typescript test runner failure due to ts-node bug This fix triggers some warnings about experimental features, and it's meant to be temporary until ts-node shares a long-term solutio . See https://github.com/TypeStrong/ts-node/issues/2094. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b7a5b31d..f28f888e 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "build-test": "npm run build --build-only=test", "prepare": "npm run build", "test": "mocha --timeout 120000 test/unittests.js", - "test-type-definitions": "ts-node --esm test/typescript/definitions.ts", + "test-type-definitions": "node --loader ts-node/esm test/typescript/definitions.ts", "benchmark-time": "node test/benchmarks/time.js", "benchmark-memory-usage": "node test/benchmarks/memory_usage.js", "start": "http-server", From 19cb6ee52138f6e89a3d594eddfbf83fe9205a69 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Mon, 18 Dec 2023 15:52:19 +0100 Subject: [PATCH 093/201] Lint: make 'space-before-function-paren' rule stricter to reflect enforced style --- .eslintrc.cjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 2dd0f1c4..ac607366 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -89,7 +89,7 @@ module.exports = { 'prefer-template': 'off', 'quote-props': 'off', 'quotes': ['error', 'single', { 'avoidEscape': true }], - 'space-before-function-paren': 'off', + 'space-before-function-paren': ['error', { 'anonymous': 'ignore', 'named': 'never', 'asyncArrow': 'always' }], 'spaced-comment': 'off', 'indent': ['error', 2, { 'SwitchCase': 1 }], 'no-unused-vars': 'error', From f77da9cdb0573b2c73e07cf61fc5c38426ae2c3f Mon Sep 17 00:00:00 2001 From: larabr Date: Fri, 12 Jan 2024 16:29:56 +0100 Subject: [PATCH 094/201] Add `config.parseAEADEncryptedV4KeysAsLegacy ` to support AEAD-encrypted v4 keys from OpenPGP.js v5 or older (#1672) The config option must be set when reading v4 private keys (e.g. those generated in OpenPGP.js by default, without setting `config.v5Keys = true`) which were encrypted by OpenPGP.js v5 (or older) using `config.aeadProtect = true`. Otherwise, key parsing and/or key decryption will fail. Additional context: OpenPGP.js up to v5 used to support encrypting v4 keys using AEAD as specified by draft RFC4880bis (https://www.ietf.org/archive/id/draft-ietf-openpgp-rfc4880bis-10.html#section-5.5.3-3.5). Said AEAD mechanism was not standardized as-is, and it's been replaced in the crypto-refresh with a new version that guarantees full key integrity on decryption. The legacy AEAD format is incompatible, but fundamentally indistinguishable, from that of the crypto-refresh for v4 keys. Thus, we rely on the caller to instruct us to process the key as legacy, via the new config flag. Co-authored-by: Daniel Huigens --- src/config/config.js | 8 ++++++++ src/packet/secret_key.js | 38 ++++++++++++++++++++++++++-------- test/general/key.js | 44 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 80 insertions(+), 10 deletions(-) diff --git a/src/config/config.js b/src/config/config.js index fe944d7a..91f29014 100644 --- a/src/config/config.js +++ b/src/config/config.js @@ -55,6 +55,14 @@ export default { * @property {Boolean} aeadProtect */ aeadProtect: false, + /** + * When reading OpenPGP v4 private keys (e.g. those generated in OpenPGP.js when not setting `config.v5Keys = true`) + * which were encrypted by OpenPGP.js v5 (or older) using `config.aeadProtect = true`, + * this option must be set, otherwise key parsing and/or key decryption will fail. + * Note: only set this flag if you know that the keys are of the legacy type, as non-legacy keys + * will be processed incorrectly. + */ + parseAEADEncryptedV4KeysAsLegacy: false, /** * Default Authenticated Encryption with Additional Data (AEAD) encryption mode * Only has an effect when aeadProtect is set to true. diff --git a/src/packet/secret_key.js b/src/packet/secret_key.js index acebd0a6..59d2a0af 100644 --- a/src/packet/secret_key.js +++ b/src/packet/secret_key.js @@ -69,6 +69,15 @@ class SecretKeyPacket extends PublicKeyPacket { * @type {enums.aead} */ this.aead = null; + /** + * Whether the key is encrypted using the legacy AEAD format proposal from RFC4880bis + * (i.e. it was encrypted with the flag `config.aeadProtect` in OpenPGP.js v5 or older). + * This value is only relevant to know how to decrypt the key: + * if AEAD is enabled, a v4 key is always re-encrypted using the standard AEAD mechanism. + * @type {Boolean} + * @private + */ + this.isLegacyAEAD = null; /** * Decrypted private parameters, referenced by name * @type {Object} @@ -84,7 +93,7 @@ class SecretKeyPacket extends PublicKeyPacket { * @param {Uint8Array} bytes - Input string to read the packet from * @async */ - async read(bytes) { + async read(bytes, config = defaultConfig) { // - A Public-Key or Public-Subkey packet, as described above. let i = await this.readPublicKey(bytes); const startOfSecretKeyData = i; @@ -143,12 +152,19 @@ class SecretKeyPacket extends PublicKeyPacket { if (this.s2kUsage) { + // OpenPGP.js up to v5 used to support encrypting v4 keys using AEAD as specified by draft RFC4880bis (https://www.ietf.org/archive/id/draft-ietf-openpgp-rfc4880bis-10.html#section-5.5.3-3.5). + // This legacy format is incompatible, but fundamentally indistinguishable, from that of the crypto-refresh for v4 keys (v5 keys are always in legacy format). + // While parsing the key may succeed (if IV and AES block sizes match), key decryption will always + // fail if the key was parsed according to the wrong format, since the keys are processed differently. + // Thus, for v4 keys, we rely on the caller to instruct us to process the key as legacy, via config flag. + this.isLegacyAEAD = this.s2kUsage === 253 && ( + this.version === 5 || (this.version === 4 && config.parseAEADEncryptedV4KeysAsLegacy)); // - crypto-refresh: If string-to-key usage octet was 255, 254 [..], an initialization vector (IV) // of the same length as the cipher's block size. // - RFC4880bis (v5 keys, regardless of AEAD): an Initial Vector (IV) of the same length as the // cipher's block size. If string-to-key usage octet was 253 the IV is used as the nonce for the AEAD algorithm. // If the AEAD algorithm requires a shorter nonce, the high-order bits of the IV are used and the remaining bits MUST be zero - if (this.s2kUsage !== 253 || this.version === 5) { + if (this.s2kUsage !== 253 || this.isLegacyAEAD) { this.iv = bytes.subarray( i, i + crypto.getCipher(this.symmetric).blockSize @@ -330,6 +346,7 @@ class SecretKeyPacket extends PublicKeyPacket { this.s2k.type = 'gnu-dummy'; this.s2kUsage = 254; this.symmetric = enums.symmetric.aes256; + this.isLegacyAEAD = null; } /** @@ -366,13 +383,14 @@ class SecretKeyPacket extends PublicKeyPacket { this.s2kUsage = 253; this.aead = enums.aead.eax; const mode = crypto.getAEADMode(this.aead); + this.isLegacyAEAD = this.version === 5; // v4 is always re-encrypted with standard format instead. const serializedPacketTag = writeTag(this.constructor.tag); const key = await produceEncryptionKey(this.version, this.s2k, passphrase, this.symmetric, this.aead, serializedPacketTag); const modeInstance = await mode(this.symmetric, key); - this.iv = (this.version === 5) ? crypto.random.getRandomBytes(blockSize) : crypto.random.getRandomBytes(mode.ivLength); - const associateData = this.version === 5 ? + this.iv = this.isLegacyAEAD ? crypto.random.getRandomBytes(blockSize) : crypto.random.getRandomBytes(mode.ivLength); + const associateData = this.isLegacyAEAD ? new Uint8Array() : util.concatUint8Array([serializedPacketTag, this.writePublicKey()]); @@ -414,7 +432,7 @@ class SecretKeyPacket extends PublicKeyPacket { const serializedPacketTag = writeTag(this.constructor.tag); // relevant for AEAD only if (this.s2kUsage === 254 || this.s2kUsage === 253) { key = await produceEncryptionKey( - this.version, this.s2k, passphrase, this.symmetric, this.aead, serializedPacketTag); + this.version, this.s2k, passphrase, this.symmetric, this.aead, serializedPacketTag, this.isLegacyAEAD); } else if (this.s2kUsage === 255) { throw new Error('Encrypted private key is authenticated using an insecure two-byte hash'); } else { @@ -426,7 +444,7 @@ class SecretKeyPacket extends PublicKeyPacket { const mode = crypto.getAEADMode(this.aead); const modeInstance = await mode(this.symmetric, key); try { - const associateData = this.version === 5 ? + const associateData = this.isLegacyAEAD ? new Uint8Array() : util.concatUint8Array([serializedPacketTag, this.writePublicKey()]); cleartext = await modeInstance.decrypt(this.keyMaterial, this.iv.subarray(0, mode.ivLength), associateData); @@ -458,6 +476,7 @@ class SecretKeyPacket extends PublicKeyPacket { this.s2kUsage = 0; this.aead = null; this.symmetric = null; + this.isLegacyAEAD = null; } /** @@ -526,13 +545,14 @@ class SecretKeyPacket extends PublicKeyPacket { * @param {String} passphrase * @param {module:enums.symmetric} cipherAlgo * @param {module:enums.aead} [aeadMode] - for AEAD-encrypted keys only (excluding v5) - * @param {Uint8Array} serializedPacketTag - for AEAD-encrypted keys only (excluding v5) + * @param {Uint8Array} [serializedPacketTag] - for AEAD-encrypted keys only (excluding v5) + * @param {Boolean} [isLegacyAEAD] - for AEAD-encrypted keys from RFC4880bis (v4 and v5 only) * @returns encryption key */ -async function produceEncryptionKey(keyVersion, s2k, passphrase, cipherAlgo, aeadMode, serializedPacketTag) { +async function produceEncryptionKey(keyVersion, s2k, passphrase, cipherAlgo, aeadMode, serializedPacketTag, isLegacyAEAD) { const { keySize } = crypto.getCipher(cipherAlgo); const derivedKey = await s2k.produceKey(passphrase, keySize); - if (!aeadMode || keyVersion === 5) { + if (!aeadMode || keyVersion === 5 || isLegacyAEAD) { return derivedKey; } const info = util.concatUint8Array([ diff --git a/test/general/key.js b/test/general/key.js index 34442073..3dd6320e 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -10,7 +10,6 @@ import util from '../../src/util.js'; import { getPreferredCipherSuite } from '../../src/key'; import KeyID from '../../src/type/keyid.js'; - const priv_key_arm2 = ['-----BEGIN PGP PRIVATE KEY BLOCK-----', 'Version: GnuPG v2.0.19 (GNU/Linux)', @@ -3084,6 +3083,49 @@ T/efFOC6BDkAAHcjAPwIPNHnR9bKmkVop6cE05dCIpZ/W8zXDGnjKYrrC4Hb expect(redecryptedKey.write()).to.deep.equal(decryptedKey.write()); }); + it('Parsing, decrypting, encrypting and serializing V4 key (AEAD-encrypted, deprecated/legacy format from RFC4880bis)', async function() { + // v4 key from OpenPGP.js v5, generated with config.aeadProtect flag (https://www.ietf.org/archive/id/draft-ietf-openpgp-rfc4880bis-10.html#section-5.5.3-3.5) + const armoredKey = `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xYMEZPXfehYJKwYBBAHaRw8BAQdAw/62MUaSzRSY5gR18DOlfeo/m8eKUkbr +ZSRqS4wtss39CQEDCGHd70SYYYPkAAALGg1YptTjEuIk4wiBreDE9U/urf3J +6Z8fP3oy+plzBRKs+8k+kzXY/643Ayesfy3qXA4zM6fqNrrlS6AqT8wDys0A +wpAEEBYKAEIFgmT133oECwkHCAmQB4Z/qOo0isgDFQgKBBYAAgECGQECmwMC +HgMWIQQm7YhFQvi0bx7ixrQHhn+o6jSKyAMiAQIAADQZAP9kECruRBva4izE +9ZET1iQ6i1HiisUKrO6miHfjsxDycgD9EXvtbpi1AORIrYO/pPpGUHpUt25n +JM+rgWhJwOHw1g3HiARk9d96EgorBgEEAZdVAQUBAQdAiVNiLZRC9wZG9/ef +V9eu8VKEoHqAFjci3Lu2N+8hQQoDAQgH/QkBAwh+kYDhbTGARwBZRY0lR39D +EriFZ1N5PKW1TAdxTMNecP3sOyUWRutHQgRrxuF0512fCnelgr2a3of5bQHC +0XWFfbac2d91VEP2mqrCeAQYFggAKgWCZPXfegmQB4Z/qOo0isgCmwwWIQQm +7YhFQvi0bx7ixrQHhn+o6jSKyAAAkN4A/31Hm3vy7FHFGJh+VYdqmeESo7mr +18jzxSbxd71FGTw7AQDqfERTB7zZzk1EqNSAqfrg3hbI7+4XXgHz6qnA3vFm +Cg== +=mTGB +-----END PGP PRIVATE KEY BLOCK-----`; + const binaryKey = (await openpgp.unarmor(armoredKey)).data; + const passphrase = 'passphrase'; + const encryptedKey = await openpgp.readKey({ armoredKey, config: { parseAEADEncryptedV4KeysAsLegacy: true } }); + expect(encryptedKey.keyPacket.isLegacyAEAD).to.be.true; + expect(encryptedKey.write()).to.deep.equal(binaryKey); + + const decryptedKey = await openpgp.decryptKey({ + privateKey: encryptedKey, + passphrase + }); + const reecryptedKey = await openpgp.encryptKey({ + privateKey: decryptedKey, + passphrase, + config: { aeadProtect: true } + }); + expect(reecryptedKey.keyPacket.s2kUsage).to.equal(253); + expect(reecryptedKey.keyPacket.isLegacyAEAD).to.be.false; + const redecryptedKey = await openpgp.decryptKey({ + privateKey: reecryptedKey, + passphrase + }); + expect(redecryptedKey.write()).to.deep.equal(decryptedKey.write()); + }); + it('Parsing, decrypting, encrypting and serializing V4 key (AEAD-encrypted)', async function() { // key from gopenpgp const armoredKey = `-----BEGIN PGP PRIVATE KEY BLOCK----- From 591b9399a8e028ce652ec1a081ba0c07c02ad034 Mon Sep 17 00:00:00 2001 From: larabr Date: Mon, 15 Jan 2024 15:07:09 +0100 Subject: [PATCH 095/201] Skip key validation for keys encrypted with non-legacy AEAD mechanism (#1713) The public key material integrity is guaranteed by the new encryption mechanism, hence `.validate()` does not need to run further checks. --- src/packet/secret_key.js | 18 +++++++++++ test/general/key.js | 64 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/src/packet/secret_key.js b/src/packet/secret_key.js index 59d2a0af..a80feba7 100644 --- a/src/packet/secret_key.js +++ b/src/packet/secret_key.js @@ -83,6 +83,13 @@ class SecretKeyPacket extends PublicKeyPacket { * @type {Object} */ this.privateParams = null; + /** + * `true` for keys whose integrity is already confirmed, based on + * the AEAD encryption mechanism + * @type {Boolean} + * @private + */ + this.usedModernAEAD = null; } // 5.5.3. Secret-Key Packet Formats @@ -169,6 +176,7 @@ class SecretKeyPacket extends PublicKeyPacket { i, i + crypto.getCipher(this.symmetric).blockSize ); + this.usedModernAEAD = false; } else { // crypto-refresh: If string-to-key usage octet was 253 (that is, the secret data is AEAD-encrypted), // an initialization vector (IV) of size specified by the AEAD algorithm (see Section 5.13.2), which @@ -177,6 +185,8 @@ class SecretKeyPacket extends PublicKeyPacket { i, i + crypto.getAEADMode(this.aead).ivLength ); + // the non-legacy AEAD encryption mechanism also authenticates public key params; no need for manual validation. + this.usedModernAEAD = true; } i += this.iv.length; @@ -347,6 +357,7 @@ class SecretKeyPacket extends PublicKeyPacket { this.s2kUsage = 254; this.symmetric = enums.symmetric.aes256; this.isLegacyAEAD = null; + this.usedModernAEAD = null; } /** @@ -384,6 +395,7 @@ class SecretKeyPacket extends PublicKeyPacket { this.aead = enums.aead.eax; const mode = crypto.getAEADMode(this.aead); this.isLegacyAEAD = this.version === 5; // v4 is always re-encrypted with standard format instead. + this.usedModernAEAD = !this.isLegacyAEAD; // legacy AEAD does not guarantee integrity of public key material const serializedPacketTag = writeTag(this.constructor.tag); const key = await produceEncryptionKey(this.version, this.s2k, passphrase, this.symmetric, this.aead, serializedPacketTag); @@ -397,6 +409,7 @@ class SecretKeyPacket extends PublicKeyPacket { this.keyMaterial = await modeInstance.encrypt(cleartext, this.iv.subarray(0, mode.ivLength), associateData); } else { this.s2kUsage = 254; + this.usedModernAEAD = false; const key = await produceEncryptionKey(this.version, this.s2k, passphrase, this.symmetric); this.iv = crypto.random.getRandomBytes(blockSize); this.keyMaterial = await crypto.mode.cfb.encrypt(this.symmetric, key, util.concatUint8Array([ @@ -493,6 +506,11 @@ class SecretKeyPacket extends PublicKeyPacket { throw new Error('Key is not decrypted'); } + if (this.usedModernAEAD) { + // key integrity confirmed by successful AEAD decryption + return; + } + let validParams; try { // this can throw if some parameters are undefined diff --git a/test/general/key.js b/test/general/key.js index 3dd6320e..caeec0f9 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -3106,6 +3106,7 @@ Cg== const passphrase = 'passphrase'; const encryptedKey = await openpgp.readKey({ armoredKey, config: { parseAEADEncryptedV4KeysAsLegacy: true } }); expect(encryptedKey.keyPacket.isLegacyAEAD).to.be.true; + expect(encryptedKey.keyPacket.usedModernAEAD).to.be.false; // legacy AEAD does not guarantee integrity of public key material expect(encryptedKey.write()).to.deep.equal(binaryKey); const decryptedKey = await openpgp.decryptKey({ @@ -3578,6 +3579,69 @@ PzIEeL7UH3trraFmi+Gq8u4kAA== await expect(key.validate()).to.be.rejectedWith('Key is invalid'); }); + it('validate() - should skip for AEAD-encrypted key (non-legacy)', async function() { + const v4KeyWithAEAD = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xYMEZaAFFxYJKwYBBAHaRw8BAQdA/C3ybUC91HiWAGd/KtPtjmYwWk7VmB+X +GXhQY9yyZkf9CQEDCBpqDPXSr+aPAGoAsXz/V2uY7EE0Xlutx3MVMEbqWz6m +fRRUn3/mtGr+PCdj9bbl0rVK+fR62kTbwATUpNdL4rrt1cNgOTlDtq1ZCc0P +PGFlYWRAdGVzdC5jb20+wpsEEBYKAE0FgmWgBRcDCwkHCZB2ZM+malVbdgUV +CAoMDgQWAAIBAhkBApsDAh4JFiEE8e8z3IJRZ+bZze8ldmTPpmpVW3YNJwkD +BwMJAQcBCQIHAgAAplYBALLKSm4Q0dPoX4mBgEuOMgtAEewfyUhp8MJdJvCa +9KIMAP9f3Qxf4ykXQwgL/e1pn1nNQgiQ7x33LXQ2vHynPkOyDceIBGWgBRcS +CisGAQQBl1UBBQEBB0Bfk/JMj2ONL/1hi31q3OePnDHLmo8IsafeG0RZY8wF +OgMBCAf9CQEDCHS8bQidEDvkAP6LovPpHodzcF7F+zbKlJKTI3l6xK4t2Dj6 +BIgBQov9zJ4OK2xFbyraXSLqStQJOQV7XBfIYKHYdIBtxj6cfTYtBMJ4BBgW +CgAqBYJloAUXCZB2ZM+malVbdgKbDBYhBPHvM9yCUWfm2c3vJXZkz6ZqVVt2 +AAA+gQD9EpMMjlBFvvyACsKwQRmIqUNTfCy4uHL1Ee1fJ4ur9ZQBAP2CiOSN +CNa5yq6lyexhsn2Vs8DsX+SOSUyNJiy5FyIJ +-----END PGP PRIVATE KEY BLOCK-----` }); + const passphrase = 'passphrase'; + // sanity checks about key encryption mechanism + expect(v4KeyWithAEAD.keyPacket.aead).to.not.be.null; + expect(v4KeyWithAEAD.keyPacket.isLegacyAEAD).to.be.false; + expect(v4KeyWithAEAD.keyPacket.usedModernAEAD).to.be.true; + + const decryptedKey = await openpgp.decryptKey({ privateKey: v4KeyWithAEAD, passphrase }); + decryptedKey.keyPacket.privateParams.seed = new Uint8Array(1); // corrupt key to confirm that the actual validation is skipped + await expect(decryptedKey.validate()).to.be.fulfilled; + }); + + it('validate() - should be run if AEAD-encrypted key gets re-encrypted without AEAD', async function() { + const v4KeyWithAEAD = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xYMEZaAFFxYJKwYBBAHaRw8BAQdA/C3ybUC91HiWAGd/KtPtjmYwWk7VmB+X +GXhQY9yyZkf9CQEDCBpqDPXSr+aPAGoAsXz/V2uY7EE0Xlutx3MVMEbqWz6m +fRRUn3/mtGr+PCdj9bbl0rVK+fR62kTbwATUpNdL4rrt1cNgOTlDtq1ZCc0P +PGFlYWRAdGVzdC5jb20+wpsEEBYKAE0FgmWgBRcDCwkHCZB2ZM+malVbdgUV +CAoMDgQWAAIBAhkBApsDAh4JFiEE8e8z3IJRZ+bZze8ldmTPpmpVW3YNJwkD +BwMJAQcBCQIHAgAAplYBALLKSm4Q0dPoX4mBgEuOMgtAEewfyUhp8MJdJvCa +9KIMAP9f3Qxf4ykXQwgL/e1pn1nNQgiQ7x33LXQ2vHynPkOyDceIBGWgBRcS +CisGAQQBl1UBBQEBB0Bfk/JMj2ONL/1hi31q3OePnDHLmo8IsafeG0RZY8wF +OgMBCAf9CQEDCHS8bQidEDvkAP6LovPpHodzcF7F+zbKlJKTI3l6xK4t2Dj6 +BIgBQov9zJ4OK2xFbyraXSLqStQJOQV7XBfIYKHYdIBtxj6cfTYtBMJ4BBgW +CgAqBYJloAUXCZB2ZM+malVbdgKbDBYhBPHvM9yCUWfm2c3vJXZkz6ZqVVt2 +AAA+gQD9EpMMjlBFvvyACsKwQRmIqUNTfCy4uHL1Ee1fJ4ur9ZQBAP2CiOSN +CNa5yq6lyexhsn2Vs8DsX+SOSUyNJiy5FyIJ +-----END PGP PRIVATE KEY BLOCK-----` }); + const passphrase = 'passphrase'; + // sanity checks about key encryption mechanism + expect(v4KeyWithAEAD.keyPacket.aead).to.not.be.null; + expect(v4KeyWithAEAD.keyPacket.isLegacyAEAD).to.be.false; + expect(v4KeyWithAEAD.keyPacket.usedModernAEAD).to.be.true; + + const reEncryptedKey = await openpgp.encryptKey({ + privateKey: await openpgp.decryptKey({ privateKey: v4KeyWithAEAD, passphrase }), + passphrase, + config: { aeadProtect: false } + }); + + expect(reEncryptedKey.keyPacket.usedModernAEAD).to.be.false; + const reDecryptedKey = await openpgp.decryptKey({ privateKey: reEncryptedKey, passphrase }); + reDecryptedKey.keyPacket.privateParams.seed = new Uint8Array(1); // corrupt key to confirm that the actual validation is now run + await expect(reDecryptedKey.validate()).to.be.rejectedWith('Key is invalid'); + }); + it('isDecrypted() - should reflect whether all (sub)keys are encrypted', async function() { const passphrase = '12345678'; const { privateKey: key } = await openpgp.generateKey({ userIDs: {}, curve: 'ed25519Legacy', passphrase, format: 'object' }); From 99899d1d5c159fc50f4fb43125c4cb476fd309c4 Mon Sep 17 00:00:00 2001 From: larabr Date: Fri, 26 Jan 2024 17:52:29 +0100 Subject: [PATCH 096/201] Drop support for native Node Readable stream: require passing Node Web Streams (#1716) Breaking change: all functions taking streams as inputs will now require passing Web Streams in Node.js . If given a native `stream.Readable` input, they will throw. The browser build is unaffected by this change. Utils to convert from and to Web Streams in Node are available from v17, see https://nodejs.org/api/stream.html#streamreadabletowebstreamreadable-options . Previously, we automatically converted between Node native streams and custom, Web-like Readable streams. This led to occasional issues. --- .github/workflows/benchmark.yml | 2 + openpgp.d.ts | 75 ++++++++++++------------- package-lock.json | 97 ++++++++++++++++++++------------- package.json | 8 +-- src/openpgp.js | 19 ++----- src/packet/compressed_data.js | 31 +---------- test/benchmarks/memory_usage.js | 56 +++++++------------ test/general/openpgp.js | 4 +- test/general/streaming.js | 22 ++++---- test/typescript/definitions.ts | 11 ++-- test/unittests.js | 5 +- 11 files changed, 155 insertions(+), 175 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 7f3482e3..70eff19f 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -20,6 +20,8 @@ jobs: ref: main path: main - uses: actions/setup-node@v3 + with: + node-version: '>=20.6.0' - name: Run pull request time benchmark run: cd pr && npm install && npm run --silent benchmark-time > benchmarks.txt && cat benchmarks.txt diff --git a/openpgp.d.ts b/openpgp.d.ts index 76a4072c..9fa6c4d3 100644 --- a/openpgp.d.ts +++ b/openpgp.d.ts @@ -7,9 +7,19 @@ * - Errietta Kostala */ -import type { WebStream as GenericWebStream, NodeStream as GenericNodeStream } from '@openpgp/web-stream-tools'; +import type { WebStream as GenericWebStream, NodeWebStream as GenericNodeWebStream } from '@openpgp/web-stream-tools'; -/* ############## v5 KEY #################### */ +/* ############## STREAM #################### */ +type Data = Uint8Array | string; +// web-stream-tools might end up supporting additional data types, so we re-declare the types +// to enforce the type contraint that we need. +export type WebStream = GenericWebStream; +export type NodeWebStream = GenericNodeWebStream; +export type Stream = WebStream | NodeWebStream; +export type MaybeStream = T | Stream; +type MaybeArray = T | Array; + +/* ############## KEY #################### */ // The Key and PublicKey types can be used interchangably since TS cannot detect the difference, as they have the same class properties. // The declared readKey(s) return type is Key instead of a PublicKey since it seems more obvious that a Key can be cast to a PrivateKey. export function readKey(options: { armoredKey: string, config?: PartialConfig }): Promise; @@ -118,13 +128,13 @@ export interface PrimaryUser { selfCertification: SignaturePacket; } -type AlgorithmInfo = { +export type AlgorithmInfo = { algorithm: enums.publicKeyNames; bits?: number; curve?: EllipticCurveName; }; -/* ############## v5 SIG #################### */ +/* ############## SIG #################### */ export function readSignature(options: { armoredSignature: string, config?: PartialConfig }): Promise; export function readSignature(options: { binarySignature: Uint8Array, config?: PartialConfig }): Promise; @@ -143,7 +153,7 @@ interface VerificationResult { signature: Promise; } -/* ############## v5 CLEARTEXT #################### */ +/* ############## CLEARTEXT #################### */ export function readCleartextMessage(options: { cleartextMessage: string, config?: PartialConfig }): Promise; @@ -176,7 +186,7 @@ export class CleartextMessage { verify(keys: PublicKey[], date?: Date, config?: Config): Promise; } -/* ############## v5 MSG #################### */ +/* ############## MSG #################### */ export function generateSessionKey(options: { encryptionKeys: MaybeArray, date?: Date, encryptionUserIDs?: MaybeArray, config?: PartialConfig }): Promise; export function encryptSessionKey(options: EncryptSessionKeyOptions & { format?: 'armored' }): Promise; export function encryptSessionKey(options: EncryptSessionKeyOptions & { format: 'binary' }): Promise; @@ -191,24 +201,24 @@ export function createMessage>(options: { bina export function encrypt>(options: EncryptOptions & { message: Message, format?: 'armored' }): Promise< T extends WebStream ? WebStream : - T extends NodeStream ? NodeStream : + T extends NodeWebStream ? NodeWebStream : string >; export function encrypt>(options: EncryptOptions & { message: Message, format: 'binary' }): Promise< T extends WebStream ? WebStream : - T extends NodeStream ? NodeStream : + T extends NodeWebStream ? NodeWebStream : Uint8Array >; export function encrypt>(options: EncryptOptions & { message: Message, format: 'object' }): Promise>; export function sign>(options: SignOptions & { message: Message, format?: 'armored' }): Promise< T extends WebStream ? WebStream : - T extends NodeStream ? NodeStream : + T extends NodeWebStream ? NodeWebStream : string >; export function sign>(options: SignOptions & { message: Message, format: 'binary' }): Promise< T extends WebStream ? WebStream : - T extends NodeStream ? NodeStream : + T extends NodeWebStream ? NodeWebStream : Uint8Array >; export function sign>(options: SignOptions & { message: Message, format: 'object' }): Promise>; @@ -218,25 +228,25 @@ export function sign(options: SignOptions & { message: CleartextMessage, format: export function decrypt>(options: DecryptOptions & { message: Message, format: 'binary' }): Promise ? WebStream : - T extends NodeStream ? NodeStream : + T extends NodeWebStream ? NodeWebStream : Uint8Array }>; export function decrypt>(options: DecryptOptions & { message: Message }): Promise ? WebStream : - T extends NodeStream ? NodeStream : + T extends NodeWebStream ? NodeWebStream : string }>; export function verify(options: VerifyOptions & { message: CleartextMessage, format?: 'utf8' }): Promise>; export function verify>(options: VerifyOptions & { message: Message, format: 'binary' }): Promise ? WebStream : - T extends NodeStream ? NodeStream : + T extends NodeWebStream ? NodeWebStream : Uint8Array >>; export function verify>(options: VerifyOptions & { message: Message }): Promise ? WebStream : - T extends NodeStream ? NodeStream : + T extends NodeWebStream ? NodeWebStream : string >>; @@ -305,7 +315,7 @@ export class Message> { } -/* ############## v5 CONFIG #################### */ +/* ############## CONFIG #################### */ interface Config { preferredHashAlgorithm: enums.hash; @@ -347,11 +357,11 @@ export var config: Config; // PartialConfig has the same properties as Config, but declared as optional. // This interface is relevant for top-level functions, which accept a subset of configuration options -interface PartialConfig extends Partial {} +export interface PartialConfig extends Partial {} -/* ############## v5 PACKET #################### */ +/* ############## PACKET #################### */ -declare abstract class BasePacket { +export declare abstract class BasePacket { static readonly tag: enums.packet; public read(bytes: Uint8Array): void; public write(): Uint8Array; @@ -561,16 +571,7 @@ export class PacketList extends Array { public findPacket(tag: enums.packet): T | undefined; } -/* ############## v5 STREAM #################### */ - -type Data = Uint8Array | string; -export interface WebStream extends GenericWebStream {} -export interface NodeStream extends GenericNodeStream {} -export type Stream = WebStream | NodeStream; -export type MaybeStream = T | Stream; - -/* ############## v5 GENERAL #################### */ -type MaybeArray = T | Array; +/* ############## GENERAL #################### */ export interface UserID { name?: string; email?: string; comment?: string; } export interface SessionKey { @@ -586,7 +587,7 @@ export interface DecryptedSessionKey { export interface ReasonForRevocation { flag?: enums.reasonForRevocation, string?: string } -interface EncryptOptions { +export interface EncryptOptions { /** message to be encrypted as created by createMessage */ message: Message>; /** (optional) array of keys or single key, used to encrypt the message */ @@ -618,7 +619,7 @@ interface EncryptOptions { config?: PartialConfig; } -interface DecryptOptions { +export interface DecryptOptions { /** the message object with the encrypted data */ message: Message>; /** (optional) private keys with decrypted secret key data or session key */ @@ -640,7 +641,7 @@ interface DecryptOptions { config?: PartialConfig; } -interface SignOptions { +export interface SignOptions { message: CleartextMessage | Message>; signingKeys: MaybeArray; format?: 'armored' | 'binary' | 'object'; @@ -652,7 +653,7 @@ interface SignOptions { config?: PartialConfig; } -interface VerifyOptions { +export interface VerifyOptions { /** (cleartext) message object with signatures */ message: CleartextMessage | Message>; /** array of publicKeys or single key, to verify signatures */ @@ -668,7 +669,7 @@ interface VerifyOptions { config?: PartialConfig; } -interface EncryptSessionKeyOptions extends SessionKey { +export interface EncryptSessionKeyOptions extends SessionKey { encryptionKeys?: MaybeArray, passwords?: MaybeArray, format?: 'armored' | 'binary' | 'object', @@ -704,7 +705,7 @@ interface GenerateKeyOptions { } export type KeyOptions = GenerateKeyOptions; -interface SubkeyOptions { +export interface SubkeyOptions { type?: 'ecc' | 'rsa'; curve?: EllipticCurveName; rsaBits?: number; @@ -714,20 +715,20 @@ interface SubkeyOptions { config?: PartialConfig; } -declare class KeyID { +export declare class KeyID { bytes: string; equals(keyID: KeyID, matchWildcard?: boolean): boolean; toHex(): string; static fromID(hex: string): KeyID; } -interface DecryptMessageResult { +export interface DecryptMessageResult { data: MaybeStream; signatures: VerificationResult[]; filename: string; } -interface VerifyMessageResult = MaybeStream> { +export interface VerifyMessageResult = MaybeStream> { data: T; signatures: VerificationResult[]; } diff --git a/package-lock.json b/package-lock.json index d2c111e4..f1197d32 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,10 +18,10 @@ "@openpgp/noble-hashes": "^1.3.3-0", "@openpgp/seek-bzip": "^1.0.5-git", "@openpgp/tweetnacl": "^1.0.4-1", - "@openpgp/web-stream-tools": "^0.0.14", + "@openpgp/web-stream-tools": "~0.1.1", "@rollup/plugin-alias": "^5.0.0", "@rollup/plugin-commonjs": "^24.0.1", - "@rollup/plugin-node-resolve": "^15.0.1", + "@rollup/plugin-node-resolve": "^15.2.1", "@rollup/plugin-replace": "^5.0.2", "@rollup/plugin-terser": "^0.4.0", "@rollup/plugin-wasm": "^6.1.2", @@ -52,11 +52,11 @@ "rollup": "^3.29.4", "sinon": "^15.1.0", "ts-node": "^10.9.1", - "typescript": "^4.1.2", + "typescript": "^5.3.3", "web-streams-polyfill": "^3.2.0" }, "engines": { - "node": ">= 16.0.0" + "node": ">= 16.5.0" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -630,10 +630,13 @@ "dev": true }, "node_modules/@openpgp/web-stream-tools": { - "version": "0.0.14", - "resolved": "https://registry.npmjs.org/@openpgp/web-stream-tools/-/web-stream-tools-0.0.14.tgz", - "integrity": "sha512-6btCNVf6YSsmlyIS7yw+IbzXeXCEcJxeSpxvSxkDuZj9B/ekt4fXkZj4oOaIxG4SKTftIK1svnlVroJ1cCMT4g==", + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@openpgp/web-stream-tools/-/web-stream-tools-0.1.1.tgz", + "integrity": "sha512-1WkV+z78S8DJNlUiCPxSjsna6gfAGCVuepL2KUDlBztXzhvplwWr4lAvsWcYzFkHykaFoCSOV9ssiRRq7QzydQ==", "dev": true, + "engines": { + "node": ">= 16.5.0" + }, "peerDependencies": { "typescript": ">=4.2" }, @@ -729,9 +732,9 @@ } }, "node_modules/@rollup/plugin-node-resolve": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.0.2.tgz", - "integrity": "sha512-Y35fRGUjC3FaurG722uhUuG8YHOJRJQbI6/CkbRkdPotSpDj9NtIN85z1zrcyDcCQIW4qp5mgG72U+gJ0TAFEg==", + "version": "15.2.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz", + "integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==", "dev": true, "dependencies": { "@rollup/pluginutils": "^5.0.1", @@ -745,7 +748,7 @@ "node": ">=14.0.0" }, "peerDependencies": { - "rollup": "^2.78.0||^3.0.0" + "rollup": "^2.78.0||^3.0.0||^4.0.0" }, "peerDependenciesMeta": { "rollup": { @@ -1004,10 +1007,13 @@ "dev": true }, "node_modules/@types/node": { - "version": "13.13.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.2.tgz", - "integrity": "sha512-LB2R1Oyhpg8gu4SON/mfforE525+Hi/M1ineICEDftqNVTyFg1aRIeGuTvXAoWHc4nbrFncWtJgMmoyRvuGh7A==", - "dev": true + "version": "20.11.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.4.tgz", + "integrity": "sha512-6I0fMH8Aoy2lOejL3s4LhyIYX34DPwY8bl5xlNjBvUEk8OHrcuzsFt+Ied4LvJihbtXPM+8zUqdydfIti86v9g==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } }, "node_modules/@types/normalize-package-data": { "version": "2.4.3", @@ -3145,9 +3151,9 @@ "dev": true }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, "optional": true, @@ -6486,16 +6492,16 @@ } }, "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=14.17" } }, "node_modules/ua-parser-js": { @@ -6544,6 +6550,12 @@ "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", "dev": true }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "node_modules/union": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", @@ -7247,9 +7259,9 @@ "dev": true }, "@openpgp/web-stream-tools": { - "version": "0.0.14", - "resolved": "https://registry.npmjs.org/@openpgp/web-stream-tools/-/web-stream-tools-0.0.14.tgz", - "integrity": "sha512-6btCNVf6YSsmlyIS7yw+IbzXeXCEcJxeSpxvSxkDuZj9B/ekt4fXkZj4oOaIxG4SKTftIK1svnlVroJ1cCMT4g==", + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@openpgp/web-stream-tools/-/web-stream-tools-0.1.1.tgz", + "integrity": "sha512-1WkV+z78S8DJNlUiCPxSjsna6gfAGCVuepL2KUDlBztXzhvplwWr4lAvsWcYzFkHykaFoCSOV9ssiRRq7QzydQ==", "dev": true, "requires": {} }, @@ -7310,9 +7322,9 @@ } }, "@rollup/plugin-node-resolve": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.0.2.tgz", - "integrity": "sha512-Y35fRGUjC3FaurG722uhUuG8YHOJRJQbI6/CkbRkdPotSpDj9NtIN85z1zrcyDcCQIW4qp5mgG72U+gJ0TAFEg==", + "version": "15.2.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz", + "integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==", "dev": true, "requires": { "@rollup/pluginutils": "^5.0.1", @@ -7531,10 +7543,13 @@ "dev": true }, "@types/node": { - "version": "13.13.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.2.tgz", - "integrity": "sha512-LB2R1Oyhpg8gu4SON/mfforE525+Hi/M1ineICEDftqNVTyFg1aRIeGuTvXAoWHc4nbrFncWtJgMmoyRvuGh7A==", - "dev": true + "version": "20.11.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.4.tgz", + "integrity": "sha512-6I0fMH8Aoy2lOejL3s4LhyIYX34DPwY8bl5xlNjBvUEk8OHrcuzsFt+Ied4LvJihbtXPM+8zUqdydfIti86v9g==", + "dev": true, + "requires": { + "undici-types": "~5.26.4" + } }, "@types/normalize-package-data": { "version": "2.4.3", @@ -9186,9 +9201,9 @@ "dev": true }, "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "optional": true }, @@ -11718,9 +11733,9 @@ } }, "typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", "dev": true }, "ua-parser-js": { @@ -11753,6 +11768,12 @@ "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", "dev": true }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "union": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", diff --git a/package.json b/package.json index f28f888e..edf883e4 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "license": "LGPL-3.0+", "homepage": "https://openpgpjs.org/", "engines": { - "node": ">= 16.0.0" + "node": ">= 16.5.0" }, "keywords": [ "crypto", @@ -68,10 +68,10 @@ "@openpgp/noble-hashes": "^1.3.3-0", "@openpgp/seek-bzip": "^1.0.5-git", "@openpgp/tweetnacl": "^1.0.4-1", - "@openpgp/web-stream-tools": "^0.0.14", + "@openpgp/web-stream-tools": "~0.1.1", "@rollup/plugin-alias": "^5.0.0", "@rollup/plugin-commonjs": "^24.0.1", - "@rollup/plugin-node-resolve": "^15.0.1", + "@rollup/plugin-node-resolve": "^15.2.1", "@rollup/plugin-replace": "^5.0.2", "@rollup/plugin-terser": "^0.4.0", "@rollup/plugin-wasm": "^6.1.2", @@ -102,7 +102,7 @@ "rollup": "^3.29.4", "sinon": "^15.1.0", "ts-node": "^10.9.1", - "typescript": "^4.1.2", + "typescript": "^5.3.3", "web-streams-polyfill": "^3.2.0" }, "dependencies": { diff --git a/src/openpgp.js b/src/openpgp.js index 408eb3e2..18f2ce09 100644 --- a/src/openpgp.js +++ b/src/openpgp.js @@ -287,7 +287,7 @@ export async function encrypt({ message, encryptionKeys, signingKeys, passwords, if (!signingKeys) { signingKeys = []; } - const streaming = message.fromStream; + try { if (signingKeys.length || signature) { // sign the message only if signing keys or signature is specified message = await message.sign(signingKeys, signature, signingKeyIDs, date, signingUserIDs, signatureNotations, config); @@ -301,7 +301,7 @@ export async function encrypt({ message, encryptionKeys, signingKeys, passwords, // serialize data const armor = format === 'armored'; const data = armor ? message.armor(config) : message.write(); - return convertStream(data, streaming, armor ? 'utf8' : 'binary'); + return convertStream(data); } catch (err) { throw util.wrapError('Error encrypting message', err); } @@ -372,7 +372,7 @@ export async function decrypt({ message, decryptionKeys, passwords, sessionKeys, }) ]); } - result.data = await convertStream(result.data, message.fromStream, format); + result.data = await convertStream(result.data); return result; } catch (err) { throw util.wrapError('Error decrypting message', err); @@ -438,7 +438,7 @@ export async function sign({ message, signingKeys, format = 'armored', detached ]); }); } - return convertStream(signature, message.fromStream, armor ? 'utf8' : 'binary'); + return convertStream(signature); } catch (err) { throw util.wrapError('Error signing message', err); } @@ -501,7 +501,7 @@ export async function verify({ message, verificationKeys, expectSigned = false, }) ]); } - result.data = await convertStream(result.data, message.fromStream, format); + result.data = await convertStream(result.data); return result; } catch (err) { throw util.wrapError('Error verifying signed message', err); @@ -672,22 +672,15 @@ function toArray(param) { /** * Convert data to or from Stream * @param {Object} data - the data to convert - * @param {'web'|'node'|false} streaming - Whether to return a ReadableStream, and of what type - * @param {'utf8'|'binary'} [encoding] - How to return data in Node Readable streams * @returns {Promise} The data in the respective format. * @async * @private */ -async function convertStream(data, streaming, encoding = 'utf8') { +async function convertStream(data) { const streamType = util.isStream(data); if (streamType === 'array') { return stream.readToEnd(data); } - if (streaming === 'node') { - data = stream.webToNode(data); - if (encoding !== 'binary') data.setEncoding(encoding); - return data; - } return data; } diff --git a/src/packet/compressed_data.js b/src/packet/compressed_data.js index 778027e7..d5af3b71 100644 --- a/src/packet/compressed_data.js +++ b/src/packet/compressed_data.js @@ -143,29 +143,10 @@ export default CompressedDataPacket; // // ////////////////////////// - -const nodeZlib = util.getNodeZlib(); - function uncompressed(data) { return data; } -function node_zlib(func, create, options = {}) { - return function (data) { - if (!util.isStream(data) || stream.isArrayStream(data)) { - return stream.fromAsync(() => stream.readToEnd(data).then(data => { - return new Promise((resolve, reject) => { - func(data, options, (err, result) => { - if (err) return reject(err); - resolve(result); - }); - }); - })); - } - return stream.nodeToWeb(stream.webToNode(data).pipe(create(options))); - }; -} - function fflate_zlib(ZlibStreamedConstructor, options) { return data => { if (!util.isStream(data) || stream.isArrayStream(data)) { @@ -216,20 +197,12 @@ function bzip2(func) { }; } -const compress_fns = nodeZlib ? { - zip: /*#__PURE__*/ (compressed, level) => node_zlib(nodeZlib.deflateRaw, nodeZlib.createDeflateRaw, { level })(compressed), - zlib: /*#__PURE__*/ (compressed, level) => node_zlib(nodeZlib.deflate, nodeZlib.createDeflate, { level })(compressed) -} : { +const compress_fns = { zip: /*#__PURE__*/ (compressed, level) => fflate_zlib(Deflate, { level })(compressed), zlib: /*#__PURE__*/ (compressed, level) => fflate_zlib(Zlib, { level })(compressed) }; -const decompress_fns = nodeZlib ? { - uncompressed: uncompressed, - zip: /*#__PURE__*/ node_zlib(nodeZlib.inflateRaw, nodeZlib.createInflateRaw), - zlib: /*#__PURE__*/ node_zlib(nodeZlib.inflate, nodeZlib.createInflate), - bzip2: /*#__PURE__*/ bzip2(BunzipDecode) -} : { +const decompress_fns = { uncompressed: uncompressed, zip: /*#__PURE__*/ fflate_zlib(Inflate), zlib: /*#__PURE__*/ fflate_zlib(Unzlib), diff --git a/test/benchmarks/memory_usage.js b/test/benchmarks/memory_usage.js index 323ae475..50673b67 100644 --- a/test/benchmarks/memory_usage.js +++ b/test/benchmarks/memory_usage.js @@ -173,7 +173,7 @@ class MemoryBenchamrkSuite { const passwords = 'password'; const config = { aeadProtect: false, preferredCompressionAlgorithm: openpgp.enums.compression.uncompressed }; - const inputStream = require('stream').Readable.from(largeDataGenerator({ chunk: new Uint8Array(ONE_MEGABYTE), numberOfChunks: 1 })); + const inputStream = require('stream/web').ReadableStream.from(largeDataGenerator({ chunk: new Uint8Array(ONE_MEGABYTE), numberOfChunks: 1 })); const plaintextMessage = await openpgp.createMessage({ binary: inputStream }); assert(plaintextMessage.fromStream); @@ -183,10 +183,8 @@ class MemoryBenchamrkSuite { assert.ok(encryptedMessage.packets[1].version === 1); const { data: decryptedData } = await openpgp.decrypt({ message: encryptedMessage, passwords, config }); // read out output stream to trigger decryption - await new Promise(resolve => { - decryptedData.pipe(require('fs').createWriteStream('/dev/null')); - decryptedData.on('end', resolve); - }); + const sink = require('stream').Writable.toWeb(require('fs').createWriteStream('/dev/null')); + await decryptedData.pipeTo(sink); }); suite.add('openpgp.encrypt/decrypt (CFB, text, with streaming)', async () => { @@ -199,7 +197,7 @@ class MemoryBenchamrkSuite { const passwords = 'password'; const config = { aeadProtect: false, preferredCompressionAlgorithm: openpgp.enums.compression.uncompressed }; - const inputStream = require('stream').Readable.from(largeDataGenerator({ chunk: 'a'.repeat(ONE_MEGABYTE / 2), numberOfChunks: 1 })); + const inputStream = require('stream/web').ReadableStream.from(largeDataGenerator({ chunk: 'a'.repeat(ONE_MEGABYTE / 2), numberOfChunks: 1 })); const plaintextMessage = await openpgp.createMessage({ text: inputStream }); assert(plaintextMessage.fromStream); @@ -209,10 +207,8 @@ class MemoryBenchamrkSuite { assert.ok(encryptedMessage.packets[1].version === 1); const { data: decryptedData } = await openpgp.decrypt({ message: encryptedMessage, passwords, config }); // read out output stream to trigger decryption - await new Promise(resolve => { - decryptedData.pipe(require('fs').createWriteStream('/dev/null')); - decryptedData.on('end', resolve); - }); + const sink = require('stream').Writable.toWeb(require('fs').createWriteStream('/dev/null')); + await decryptedData.pipeTo(sink); }); suite.add('openpgp.encrypt/decrypt (AEAD, binary, with streaming)', async () => { @@ -225,7 +221,7 @@ class MemoryBenchamrkSuite { const passwords = 'password'; const config = { aeadProtect: true, preferredCompressionAlgorithm: openpgp.enums.compression.uncompressed }; - const inputStream = require('stream').Readable.from(largeDataGenerator({ chunk: new Uint8Array(ONE_MEGABYTE), numberOfChunks: 1 })); + const inputStream = require('stream/web').ReadableStream.from(largeDataGenerator({ chunk: new Uint8Array(ONE_MEGABYTE), numberOfChunks: 1 })); const plaintextMessage = await openpgp.createMessage({ binary:inputStream }); assert(plaintextMessage.fromStream); @@ -235,10 +231,8 @@ class MemoryBenchamrkSuite { assert.ok(encryptedMessage.packets[1].version === 2); const { data: decryptedData } = await openpgp.decrypt({ message: encryptedMessage, passwords, config }); // read out output stream to trigger decryption - await new Promise(resolve => { - decryptedData.pipe(require('fs').createWriteStream('/dev/null')); - decryptedData.on('end', resolve); - }); + const sink = require('stream').Writable.toWeb(require('fs').createWriteStream('/dev/null')); + await decryptedData.pipeTo(sink); }); suite.add('openpgp.encrypt/decrypt (AEAD, text, with streaming)', async () => { @@ -251,7 +245,7 @@ class MemoryBenchamrkSuite { const passwords = 'password'; const config = { aeadProtect: true, preferredCompressionAlgorithm: openpgp.enums.compression.uncompressed }; - const inputStream = require('stream').Readable.from(largeDataGenerator({ chunk: 'a'.repeat(ONE_MEGABYTE / 2), numberOfChunks: 1 })); + const inputStream = require('stream/web').ReadableStream.from(largeDataGenerator({ chunk: 'a'.repeat(ONE_MEGABYTE / 2), numberOfChunks: 1 })); const plaintextMessage = await openpgp.createMessage({ text: inputStream }); assert(plaintextMessage.fromStream); @@ -261,10 +255,8 @@ class MemoryBenchamrkSuite { assert.ok(encryptedMessage.packets[1].version === 2); const { data: decryptedData } = await openpgp.decrypt({ message: encryptedMessage, passwords, config }); // read out output stream to trigger decryption - await new Promise(resolve => { - decryptedData.pipe(require('fs').createWriteStream('/dev/null')); - decryptedData.on('end', resolve); - }); + const sink = require('stream').Writable.toWeb(require('fs').createWriteStream('/dev/null')); + await decryptedData.pipeTo(sink); }); suite.add('openpgp.encrypt/decrypt (CFB, text @ 10MB, with streaming)', async () => { @@ -277,7 +269,7 @@ class MemoryBenchamrkSuite { const passwords = 'password'; const config = { aeadProtect: false, preferredCompressionAlgorithm: openpgp.enums.compression.uncompressed }; - const inputStream = require('stream').Readable.from(largeDataGenerator({ chunk: 'a'.repeat(ONE_MEGABYTE / 2), numberOfChunks: 20 })); + const inputStream = require('stream/web').ReadableStream.from(largeDataGenerator({ chunk: 'a'.repeat(ONE_MEGABYTE / 2), numberOfChunks: 20 })); const plaintextMessage = await openpgp.createMessage({ text: inputStream }); assert(plaintextMessage.fromStream); @@ -287,10 +279,8 @@ class MemoryBenchamrkSuite { assert.ok(encryptedMessage.packets[1].version === 1); const { data: decryptedData } = await openpgp.decrypt({ message: encryptedMessage, passwords, config }); // read out output stream to trigger decryption - await new Promise(resolve => { - decryptedData.pipe(require('fs').createWriteStream('/dev/null')); - decryptedData.on('end', resolve); - }); + const sink = require('stream').Writable.toWeb(require('fs').createWriteStream('/dev/null')); + await decryptedData.pipeTo(sink); }); suite.add('openpgp.encrypt/decrypt (CFB, text @ 10MB, with unauthenticated streaming)', async () => { @@ -303,7 +293,7 @@ class MemoryBenchamrkSuite { const passwords = 'password'; const config = { aeadProtect: false, preferredCompressionAlgorithm: openpgp.enums.compression.uncompressed }; - const inputStream = require('stream').Readable.from(largeDataGenerator({ chunk: 'a'.repeat(ONE_MEGABYTE / 2), numberOfChunks: 20 })); + const inputStream = require('stream/web').ReadableStream.from(largeDataGenerator({ chunk: 'a'.repeat(ONE_MEGABYTE / 2), numberOfChunks: 20 })); const plaintextMessage = await openpgp.createMessage({ text: inputStream }); assert(plaintextMessage.fromStream); @@ -317,10 +307,8 @@ class MemoryBenchamrkSuite { config: { ...config, allowUnauthenticatedStream: true } }); // read out output stream to trigger decryption - await new Promise(resolve => { - decryptedData.pipe(require('fs').createWriteStream('/dev/null')); - decryptedData.on('end', resolve); - }); + const sink = require('stream').Writable.toWeb(require('fs').createWriteStream('/dev/null')); + await decryptedData.pipeTo(sink); }); suite.add('openpgp.encrypt/decrypt (AEAD, text @ 10MB, with streaming)', async () => { @@ -333,7 +321,7 @@ class MemoryBenchamrkSuite { const passwords = 'password'; const config = { aeadProtect: true, preferredCompressionAlgorithm: openpgp.enums.compression.uncompressed }; - const inputStream = require('stream').Readable.from(largeDataGenerator({ chunk: 'a'.repeat(ONE_MEGABYTE / 2), numberOfChunks: 20 })); + const inputStream = require('stream/web').ReadableStream.from(largeDataGenerator({ chunk: 'a'.repeat(ONE_MEGABYTE / 2), numberOfChunks: 20 })); const plaintextMessage = await openpgp.createMessage({ text: inputStream }); assert(plaintextMessage.fromStream); @@ -343,10 +331,8 @@ class MemoryBenchamrkSuite { assert.ok(encryptedMessage.packets[1].version === 2); const { data: decryptedData } = await openpgp.decrypt({ message: encryptedMessage, passwords, config }); // read out output stream to trigger decryption - await new Promise(resolve => { - decryptedData.pipe(require('fs').createWriteStream('/dev/null')); - decryptedData.on('end', resolve); - }); + const sink = require('stream').Writable.toWeb(require('fs').createWriteStream('/dev/null')); + await decryptedData.pipeTo(sink); }); const stats = await suite.run(); diff --git a/test/general/openpgp.js b/test/general/openpgp.js index 008cc713..1c4eb283 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -3840,9 +3840,7 @@ XfA3pqV4mTzF packets.push(message.packets.findPacket(openpgp.enums.packet.signature)); packets.push(message.packets.findPacket(openpgp.enums.packet.literalData)); verifyOpt.message = await openpgp.readMessage({ - binaryMessage: stream[ - globalThis.ReadableStream ? 'toStream' : 'webToNode' - ](packets.write()) + binaryMessage: stream.toStream(packets.write()) }); return openpgp.verify(verifyOpt); }).then(async function (verified) { diff --git a/test/general/streaming.js b/test/general/streaming.js index 3489656a..85761f57 100644 --- a/test/general/streaming.js +++ b/test/general/streaming.js @@ -416,7 +416,7 @@ function tests() { expect(stream.isStream(encrypted)).to.equal(expectedType); const message = await openpgp.readMessage({ - armoredMessage: stream[expectedType === 'node' ? 'webToNode' : 'toStream'](stream.transform(encrypted, value => { + armoredMessage: stream.toStream(stream.transform(encrypted, value => { value += ''; const newlineIndex = value.indexOf('\n', 500); if (value.length > 1000) return value.slice(0, newlineIndex - 1) + (value[newlineIndex - 1] === 'a' ? 'b' : 'a') + value.slice(newlineIndex); @@ -453,7 +453,7 @@ function tests() { expect(stream.isStream(encrypted)).to.equal(expectedType); const message = await openpgp.readMessage({ - armoredMessage: stream[expectedType === 'node' ? 'webToNode' : 'toStream'](stream.transform(encrypted, value => { + armoredMessage: stream.toStream(stream.transform(encrypted, value => { value += ''; const newlineIndex = value.indexOf('\n', 500); if (value.length > 1000) return value.slice(0, newlineIndex - 1) + (value[newlineIndex - 1] === 'a' ? 'b' : 'a') + value.slice(newlineIndex); @@ -486,7 +486,7 @@ function tests() { expect(stream.isStream(signed)).to.equal(expectedType); const message = await openpgp.readMessage({ - armoredMessage: stream[expectedType === 'node' ? 'webToNode' : 'toStream'](stream.transform(signed, value => { + armoredMessage: stream.toStream(stream.transform(signed, value => { value += ''; const newlineIndex = value.indexOf('\n', 500); if (value.length > 1000) return value.slice(0, newlineIndex - 1) + (value[newlineIndex - 1] === 'a' ? 'b' : 'a') + value.slice(newlineIndex); @@ -872,6 +872,7 @@ function tests() { export default () => describe('Streaming', function() { let currentTest = 0; + const needsStreamPolyfills = !globalThis.ReadableStream; before(async function() { pubKey = await openpgp.readKey({ armoredKey: pub_key }); @@ -916,40 +917,41 @@ export default () => describe('Streaming', function() { tests(); - if (detectNode()) { + if (detectNode() && !needsStreamPolyfills) { // ReadableStream polyfills interfere with these tests const fs = util.nodeRequire('fs'); + const { Readable: NodeReadableStream } = util.nodeRequire('stream'); const { fileURLToPath } = util.nodeRequire('url'); const __filename = fileURLToPath(import.meta.url); it('Node: Encrypt and decrypt text message roundtrip', async function() { dataArrived(); // Do not wait until data arrived. const plaintext = fs.readFileSync(__filename.replace('streaming.js', 'openpgp.js'), 'utf8'); // eslint-disable-line no-sync - const data = fs.createReadStream(__filename.replace('streaming.js', 'openpgp.js'), { encoding: 'utf8' }); + const data = NodeReadableStream.toWeb(fs.createReadStream(__filename.replace('streaming.js', 'openpgp.js'), { encoding: 'utf8' })); const encrypted = await openpgp.encrypt({ message: await openpgp.createMessage({ text: data }), passwords: ['test'] }); - expect(stream.isStream(encrypted)).to.equal('node'); + expect(stream.isStream(encrypted)).to.equal('web'); const message = await openpgp.readMessage({ armoredMessage: encrypted }); const decrypted = await openpgp.decrypt({ passwords: ['test'], message }); - expect(stream.isStream(decrypted.data)).to.equal('node'); + expect(stream.isStream(decrypted.data)).to.equal('web'); expect(await stream.readToEnd(decrypted.data)).to.equal(plaintext); }); it('Node: Encrypt and decrypt binary message roundtrip', async function() { dataArrived(); // Do not wait until data arrived. const plaintext = fs.readFileSync(__filename.replace('streaming.js', 'openpgp.js')); // eslint-disable-line no-sync - const data = fs.createReadStream(__filename.replace('streaming.js', 'openpgp.js')); + const data = NodeReadableStream.toWeb(fs.createReadStream(__filename.replace('streaming.js', 'openpgp.js'))); const encrypted = await openpgp.encrypt({ message: await openpgp.createMessage({ binary: data }), passwords: ['test'], format: 'binary' }); - expect(stream.isStream(encrypted)).to.equal('node'); + expect(stream.isStream(encrypted)).to.equal('web'); const message = await openpgp.readMessage({ binaryMessage: encrypted }); const decrypted = await openpgp.decrypt({ @@ -957,7 +959,7 @@ export default () => describe('Streaming', function() { message, format: 'binary' }); - expect(stream.isStream(decrypted.data)).to.equal('node'); + expect(stream.isStream(decrypted.data)).to.equal('web'); expect(await stream.readToEnd(decrypted.data)).to.deep.equal(plaintext); }); } diff --git a/test/typescript/definitions.ts b/test/typescript/definitions.ts index 94983043..5258154d 100644 --- a/test/typescript/definitions.ts +++ b/test/typescript/definitions.ts @@ -7,6 +7,7 @@ */ import { ReadableStream as WebReadableStream } from 'web-streams-polyfill'; import { createReadStream } from 'fs'; +import { Readable as NodeNativeReadableStream } from 'stream'; import { expect } from 'chai'; import { @@ -15,7 +16,7 @@ import { encrypt, decrypt, sign, verify, config, enums, generateSessionKey, encryptSessionKey, decryptSessionKeys, LiteralDataPacket, PacketList, CompressedDataPacket, PublicKeyPacket, PublicSubkeyPacket, SecretKeyPacket, SecretSubkeyPacket, CleartextMessage, - WebStream, NodeStream, + WebStream, NodeWebStream, } from 'openpgp'; (async () => { @@ -207,9 +208,9 @@ import { // Streaming - encrypt text message (armored output) try { - const nodeTextStream = createReadStream('non-existent-file', { encoding: 'utf8' }); + const nodeTextStream = NodeNativeReadableStream.toWeb(createReadStream('non-existent-file', { encoding: 'utf8' })); const messageFromNodeTextStream = await createMessage({ text: nodeTextStream }); - (await encrypt({ message: messageFromNodeTextStream, passwords: 'password', format: 'armored' })) as NodeStream; + (await encrypt({ message: messageFromNodeTextStream, passwords: 'password', format: 'armored' })) as NodeWebStream; } catch (err) {} const webTextStream = new WebReadableStream(); const messageFromWebTextStream = await createMessage({ text: webTextStream }); @@ -219,9 +220,9 @@ import { // Streaming - encrypt binary message (binary output) try { - const nodeBinaryStream = createReadStream('non-existent-file'); + const nodeBinaryStream = NodeNativeReadableStream.toWeb(createReadStream('non-existent-file')); const messageFromNodeBinaryStream = await createMessage({ binary: nodeBinaryStream }); - (await encrypt({ message: messageFromNodeBinaryStream, passwords: 'password', format: 'binary' })) as NodeStream; + (await encrypt({ message: messageFromNodeBinaryStream, passwords: 'password', format: 'binary' })) as NodeWebStream; } catch (err) {} const webBinaryStream = new WebReadableStream(); const messageFromWebBinaryStream = await createMessage({ binary: webBinaryStream }); diff --git a/test/unittests.js b/test/unittests.js index 54f63c3c..de16574c 100644 --- a/test/unittests.js +++ b/test/unittests.js @@ -27,7 +27,10 @@ globalThis.tryTests = function(name, tests, options) { }; globalThis.loadStreamsPolyfill = function() { - return import('web-streams-polyfill'); + // do not polyfill Node + const detectNodeWebStreams = () => typeof globalThis.process === 'object' && typeof globalThis.process.versions === 'object' && globalThis.ReadableStream; + + return detectNodeWebStreams() || import('web-streams-polyfill'); }; import runWorkerTests from './worker'; From 959956cfc99ce55005d085dc081de910bca18d3d Mon Sep 17 00:00:00 2001 From: larabr Date: Thu, 1 Feb 2024 09:42:16 +0100 Subject: [PATCH 097/201] Use Compression Stream API when available, drop `config.deflateLevel` (#1717) Breaking change: the `config.deflateLevel` is removed as the API does not accept a deflate level in input, and the setting is of limited importance. Plus, using compression is discouraged on security grounds. --- openpgp.d.ts | 1 - src/config/config.js | 5 --- src/packet/compressed_data.js | 59 ++++++++++++++++++++++++----------- test/general/config.js | 3 +- 4 files changed, 42 insertions(+), 26 deletions(-) diff --git a/openpgp.d.ts b/openpgp.d.ts index 9fa6c4d3..702564fd 100644 --- a/openpgp.d.ts +++ b/openpgp.d.ts @@ -323,7 +323,6 @@ interface Config { preferredCompressionAlgorithm: enums.compression; showVersion: boolean; showComment: boolean; - deflateLevel: number; aeadProtect: boolean; allowUnauthenticatedMessages: boolean; allowUnauthenticatedStream: boolean; diff --git a/src/config/config.js b/src/config/config.js index 91f29014..b006a3f4 100644 --- a/src/config/config.js +++ b/src/config/config.js @@ -37,11 +37,6 @@ export default { * @property {Integer} compression Default compression algorithm {@link module:enums.compression} */ preferredCompressionAlgorithm: enums.compression.uncompressed, - /** - * @memberof module:config - * @property {Integer} deflateLevel Default zip/zlib compression level, between 1 and 9 - */ - deflateLevel: 6, /** * Use Authenticated Encryption with Additional Data (AEAD) protection for symmetric encryption. * This option is applicable to: diff --git a/src/packet/compressed_data.js b/src/packet/compressed_data.js index d5af3b71..9a46cd87 100644 --- a/src/packet/compressed_data.js +++ b/src/packet/compressed_data.js @@ -67,11 +67,6 @@ class CompressedDataPacket { * @type {Uint8Array | ReadableStream} */ this.compressed = null; - - /** - * zip/zlib compression level, between 1 and 9 - */ - this.deflateLevel = config.deflateLevel; } /** @@ -131,7 +126,7 @@ class CompressedDataPacket { throw new Error(`${compressionName} compression not supported`); } - this.compressed = compressionFn(this.packets.write(), this.deflateLevel); + this.compressed = compressionFn(this.packets.write()); } } @@ -143,16 +138,18 @@ export default CompressedDataPacket; // // ////////////////////////// -function uncompressed(data) { - return data; -} - -function fflate_zlib(ZlibStreamedConstructor, options) { +/** + * Zlib processor relying on Compression Stream API if available, or falling back to fflate otherwise. + * @param {function(): CompressionStream|function(): DecompressionStream} compressionStreamInstantiator + * @param {FunctionConstructor} ZlibStreamedConstructor - fflate constructor + * @returns {ReadableStream} compressed or decompressed data + */ +function zlib(compressionStreamInstantiator, ZlibStreamedConstructor) { return data => { if (!util.isStream(data) || stream.isArrayStream(data)) { return stream.fromAsync(() => stream.readToEnd(data).then(inputData => { return new Promise((resolve, reject) => { - const zlibStream = new ZlibStreamedConstructor(options); + const zlibStream = new ZlibStreamedConstructor(); zlibStream.ondata = processedData => { resolve(processedData); }; @@ -165,8 +162,22 @@ function fflate_zlib(ZlibStreamedConstructor, options) { })); } + // Use Compression Streams API if available (see https://developer.mozilla.org/en-US/docs/Web/API/Compression_Streams_API) + if (compressionStreamInstantiator) { + try { + const compressorOrDecompressor = compressionStreamInstantiator(); + return data.pipeThrough(compressorOrDecompressor); + } catch (err) { + // If format is unsupported in Compression/DecompressionStream, then a TypeError in thrown, and we fallback to fflate. + if (err.name !== 'TypeError') { + throw err; + } + } + } + + // JS fallback const inputReader = data.getReader(); - const zlibStream = new ZlibStreamedConstructor(options); + const zlibStream = new ZlibStreamedConstructor(); return new ReadableStream({ async start(controller) { @@ -197,15 +208,27 @@ function bzip2(func) { }; } +/** + * Get Compression Stream API instatiators if the constructors are implemented. + * NB: the return instatiator functions will throw when called if the provided `compressionFormat` is not supported + * (supported formats cannot be determined in advance). + * @param {'deflate-raw'|'deflate'|'gzip'|string} compressionFormat + * @returns {{ compressor: function(): CompressionStream | false, decompressor: function(): DecompressionStream | false }} + */ +const getCompressionStreamInstantiators = compressionFormat => ({ + compressor: typeof CompressionStream !== 'undefined' && (() => new CompressionStream(compressionFormat)), + decompressor: typeof DecompressionStream !== 'undefined' && (() => new DecompressionStream(compressionFormat)) +}); + const compress_fns = { - zip: /*#__PURE__*/ (compressed, level) => fflate_zlib(Deflate, { level })(compressed), - zlib: /*#__PURE__*/ (compressed, level) => fflate_zlib(Zlib, { level })(compressed) + zip: /*#__PURE__*/ zlib(getCompressionStreamInstantiators('deflate-raw').compressor, Deflate), + zlib: /*#__PURE__*/ zlib(getCompressionStreamInstantiators('deflate').compressor, Zlib) }; const decompress_fns = { - uncompressed: uncompressed, - zip: /*#__PURE__*/ fflate_zlib(Inflate), - zlib: /*#__PURE__*/ fflate_zlib(Unzlib), + uncompressed: data => data, + zip: /*#__PURE__*/ zlib(getCompressionStreamInstantiators('deflate-raw').decompressor, Inflate), + zlib: /*#__PURE__*/ zlib(getCompressionStreamInstantiators('deflate').decompressor, Unzlib), bzip2: /*#__PURE__*/ bzip2(BunzipDecode) }; diff --git a/test/general/config.js b/test/general/config.js index 55120a30..34e8a1fa 100644 --- a/test/general/config.js +++ b/test/general/config.js @@ -278,8 +278,7 @@ n9/quqtmyOtYOA6gXNCw0Fal3iANKBmsPmYI const config = { aeadProtect: true, - preferredCompressionAlgorithm: openpgp.enums.compression.zip, - deflateLevel: 1 + preferredCompressionAlgorithm: openpgp.enums.compression.zip }; const armored2 = await openpgp.encrypt({ message, passwords, config }); const encrypted2 = await openpgp.readMessage({ armoredMessage: armored2 }); From 6bfb557ca63c788047137d3124a02fe0c39c2fb2 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Thu, 1 Feb 2024 10:23:50 +0100 Subject: [PATCH 098/201] Update Rollup to v4 --- package-lock.json | 632 +++++++++++++++++++++++++++++++++------------- package.json | 14 +- 2 files changed, 460 insertions(+), 186 deletions(-) diff --git a/package-lock.json b/package-lock.json index f1197d32..c07ccb96 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,12 +19,12 @@ "@openpgp/seek-bzip": "^1.0.5-git", "@openpgp/tweetnacl": "^1.0.4-1", "@openpgp/web-stream-tools": "~0.1.1", - "@rollup/plugin-alias": "^5.0.0", - "@rollup/plugin-commonjs": "^24.0.1", - "@rollup/plugin-node-resolve": "^15.2.1", - "@rollup/plugin-replace": "^5.0.2", - "@rollup/plugin-terser": "^0.4.0", - "@rollup/plugin-wasm": "^6.1.2", + "@rollup/plugin-alias": "^5.1.0", + "@rollup/plugin-commonjs": "^25.0.7", + "@rollup/plugin-node-resolve": "^15.2.3", + "@rollup/plugin-replace": "^5.0.5", + "@rollup/plugin-terser": "^0.4.4", + "@rollup/plugin-wasm": "^6.2.2", "@types/chai": "^4.2.14", "argon2id": "^1.0.1", "benchmark": "^2.1.4", @@ -49,7 +49,7 @@ "karma-webkit-launcher": "^2.1.0", "mocha": "^10.2.0", "playwright": "^1.30.0", - "rollup": "^3.29.4", + "rollup": "^4.9.5", "sinon": "^15.1.0", "ts-node": "^10.9.1", "typescript": "^5.3.3", @@ -434,9 +434,9 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", "dev": true, "dependencies": { "@jridgewell/set-array": "^1.0.1", @@ -466,9 +466,9 @@ } }, "node_modules/@jridgewell/source-map": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", - "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.0", @@ -647,9 +647,9 @@ } }, "node_modules/@rollup/plugin-alias": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.0.0.tgz", - "integrity": "sha512-l9hY5chSCjuFRPsnRm16twWBiSApl2uYFLsepQYwtBuAxNMQ/1dJqADld40P0Jkqm65GRTLy/AC6hnpVebtLsA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.1.0.tgz", + "integrity": "sha512-lpA3RZ9PdIG7qqhEfv79tBffNaoDuukFDrmhLqg9ifv99u/ehn+lOg30x2zmhf8AQqQUZaMk/B9fZraQ6/acDQ==", "dev": true, "dependencies": { "slash": "^4.0.0" @@ -658,7 +658,7 @@ "node": ">=14.0.0" }, "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0" + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "peerDependenciesMeta": { "rollup": { @@ -667,9 +667,9 @@ } }, "node_modules/@rollup/plugin-commonjs": { - "version": "24.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-24.1.0.tgz", - "integrity": "sha512-eSL45hjhCWI0jCCXcNtLVqM5N1JlBGvlFfY0m6oOYnLCJ6N0qEXoZql4sY2MOUArzhH4SA/qBpTxvvZp2Sc+DQ==", + "version": "25.0.7", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.7.tgz", + "integrity": "sha512-nEvcR+LRjEjsaSsc4x3XZfCCvZIaSMenZu/OiwOKGN2UhQpAYI7ru7czFvyWbErlpoGjnSX3D5Ch5FcMA3kRWQ==", "dev": true, "dependencies": { "@rollup/pluginutils": "^5.0.1", @@ -677,13 +677,13 @@ "estree-walker": "^2.0.2", "glob": "^8.0.3", "is-reference": "1.2.1", - "magic-string": "^0.27.0" + "magic-string": "^0.30.3" }, "engines": { "node": ">=14.0.0" }, "peerDependencies": { - "rollup": "^2.68.0||^3.0.0" + "rollup": "^2.68.0||^3.0.0||^4.0.0" }, "peerDependenciesMeta": { "rollup": { @@ -772,19 +772,19 @@ } }, "node_modules/@rollup/plugin-replace": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-5.0.2.tgz", - "integrity": "sha512-M9YXNekv/C/iHHK+cvORzfRYfPbq0RDD8r0G+bMiTXjNGKulPnCT9O3Ss46WfhI6ZOCgApOP7xAdmCQJ+U2LAA==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-5.0.5.tgz", + "integrity": "sha512-rYO4fOi8lMaTg/z5Jb+hKnrHHVn8j2lwkqwyS4kTRhKyWOLf2wST2sWXr4WzWiTcoHTp2sTjqUbqIj2E39slKQ==", "dev": true, "dependencies": { "@rollup/pluginutils": "^5.0.1", - "magic-string": "^0.27.0" + "magic-string": "^0.30.3" }, "engines": { "node": ">=14.0.0" }, "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0" + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "peerDependenciesMeta": { "rollup": { @@ -793,20 +793,20 @@ } }, "node_modules/@rollup/plugin-terser": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.1.tgz", - "integrity": "sha512-aKS32sw5a7hy+fEXVy+5T95aDIwjpGHCTv833HXVtyKMDoVS7pBr5K3L9hEQoNqbJFjfANPrNpIXlTQ7is00eA==", + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", + "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", "dev": true, "dependencies": { - "serialize-javascript": "^6.0.0", - "smob": "^0.0.6", - "terser": "^5.15.1" + "serialize-javascript": "^6.0.1", + "smob": "^1.0.0", + "terser": "^5.17.4" }, "engines": { "node": ">=14.0.0" }, "peerDependencies": { - "rollup": "^2.x || ^3.x" + "rollup": "^2.0.0||^3.0.0||^4.0.0" }, "peerDependenciesMeta": { "rollup": { @@ -824,15 +824,18 @@ } }, "node_modules/@rollup/plugin-wasm": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-wasm/-/plugin-wasm-6.1.3.tgz", - "integrity": "sha512-7ItTTeyauE6lwdDtQWceEHZ9+txbi4RRy0mYPFn9BW7rD7YdgBDu7HTHsLtHrRzJc313RM/1m6GKgV3np/aEaw==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-wasm/-/plugin-wasm-6.2.2.tgz", + "integrity": "sha512-gpC4R1G9Ni92ZIRTexqbhX7U+9estZrbhP+9SRb0DW9xpB9g7j34r+J2hqrcW/lRI7dJaU84MxZM0Rt82tqYPQ==", "dev": true, + "dependencies": { + "@rollup/pluginutils": "^5.0.2" + }, "engines": { "node": ">=14.0.0" }, "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0" + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "peerDependenciesMeta": { "rollup": { @@ -841,9 +844,9 @@ } }, "node_modules/@rollup/pluginutils": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", - "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", + "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", "dev": true, "dependencies": { "@types/estree": "^1.0.0", @@ -854,7 +857,7 @@ "node": ">=14.0.0" }, "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0" + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "peerDependenciesMeta": { "rollup": { @@ -862,6 +865,175 @@ } } }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.9.6.tgz", + "integrity": "sha512-MVNXSSYN6QXOulbHpLMKYi60ppyO13W9my1qogeiAqtjb2yR4LSmfU2+POvDkLzhjYLXz9Rf9+9a3zFHW1Lecg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.9.6.tgz", + "integrity": "sha512-T14aNLpqJ5wzKNf5jEDpv5zgyIqcpn1MlwCrUXLrwoADr2RkWA0vOWP4XxbO9aiO3dvMCQICZdKeDrFl7UMClw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.9.6.tgz", + "integrity": "sha512-CqNNAyhRkTbo8VVZ5R85X73H3R5NX9ONnKbXuHisGWC0qRbTTxnF1U4V9NafzJbgGM0sHZpdO83pLPzq8uOZFw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.9.6.tgz", + "integrity": "sha512-zRDtdJuRvA1dc9Mp6BWYqAsU5oeLixdfUvkTHuiYOHwqYuQ4YgSmi6+/lPvSsqc/I0Omw3DdICx4Tfacdzmhog==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.9.6.tgz", + "integrity": "sha512-oNk8YXDDnNyG4qlNb6is1ojTOGL/tRhbbKeE/YuccItzerEZT68Z9gHrY3ROh7axDc974+zYAPxK5SH0j/G+QQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.9.6.tgz", + "integrity": "sha512-Z3O60yxPtuCYobrtzjo0wlmvDdx2qZfeAWTyfOjEDqd08kthDKexLpV97KfAeUXPosENKd8uyJMRDfFMxcYkDQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.9.6.tgz", + "integrity": "sha512-gpiG0qQJNdYEVad+1iAsGAbgAnZ8j07FapmnIAQgODKcOTjLEWM9sRb+MbQyVsYCnA0Im6M6QIq6ax7liws6eQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.9.6.tgz", + "integrity": "sha512-+uCOcvVmFUYvVDr27aiyun9WgZk0tXe7ThuzoUTAukZJOwS5MrGbmSlNOhx1j80GdpqbOty05XqSl5w4dQvcOA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.9.6.tgz", + "integrity": "sha512-HUNqM32dGzfBKuaDUBqFB7tP6VMN74eLZ33Q9Y1TBqRDn+qDonkAUyKWwF9BR9unV7QUzffLnz9GrnKvMqC/fw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.9.6.tgz", + "integrity": "sha512-ch7M+9Tr5R4FK40FHQk8VnML0Szi2KRujUgHXd/HjuH9ifH72GUmw6lStZBo3c3GB82vHa0ZoUfjfcM7JiiMrQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.9.6.tgz", + "integrity": "sha512-VD6qnR99dhmTQ1mJhIzXsRcTBvTjbfbGGwKAHcu+52cVl15AC/kplkhxzW/uT0Xl62Y/meBKDZvoJSJN+vTeGA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.9.6.tgz", + "integrity": "sha512-J9AFDq/xiRI58eR2NIDfyVmTYGyIZmRcvcAoJ48oDld/NTR8wyiPUu2X/v1navJ+N/FGg68LEbX3Ejd6l8B7MQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.9.6.tgz", + "integrity": "sha512-jqzNLhNDvIZOrt69Ce4UjGRpXJBzhUBzawMwnaDAwyHriki3XollsewxWzOzz+4yOFDkuJHtTsZFwMxhYJWmLQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@sinonjs/commons": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", @@ -967,9 +1139,9 @@ } }, "node_modules/@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, "node_modules/@types/istanbul-lib-coverage": { @@ -1007,13 +1179,10 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.11.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.4.tgz", - "integrity": "sha512-6I0fMH8Aoy2lOejL3s4LhyIYX34DPwY8bl5xlNjBvUEk8OHrcuzsFt+Ied4LvJihbtXPM+8zUqdydfIti86v9g==", - "dev": true, - "dependencies": { - "undici-types": "~5.26.4" - } + "version": "13.13.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.2.tgz", + "integrity": "sha512-LB2R1Oyhpg8gu4SON/mfforE525+Hi/M1ineICEDftqNVTyFg1aRIeGuTvXAoWHc4nbrFncWtJgMmoyRvuGh7A==", + "dev": true }, "node_modules/@types/normalize-package-data": { "version": "2.4.3", @@ -3099,9 +3268,9 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", "dev": true, "funding": [ { @@ -3151,9 +3320,9 @@ "dev": true }, "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, "hasInstallScript": true, "optional": true, @@ -4202,15 +4371,6 @@ "node": ">=8" } }, - "node_modules/karma/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/karma/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -4507,17 +4667,23 @@ "dev": true }, "node_modules/magic-string": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", - "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", + "version": "0.30.6", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.6.tgz", + "integrity": "sha512-n62qCLbPjNjyo+owKtveQxZFZTBm+Ms6YoGD23Wew6Vw337PElFNifQpknPruVRQV57kVShPnLGo9vWxVhpPvA==", "dev": true, "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.13" + "@jridgewell/sourcemap-codec": "^1.4.15" }, "engines": { "node": ">=12" } }, + "node_modules/magic-string/node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", @@ -5826,18 +5992,34 @@ } }, "node_modules/rollup": { - "version": "3.29.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", - "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.9.6.tgz", + "integrity": "sha512-05lzkCS2uASX0CiLFybYfVkwNbKZG5NFQ6Go0VWyogFTXXbR039UVsegViTntkk4OglHBdF54ccApXRRuXRbsg==", "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, "bin": { "rollup": "dist/bin/rollup" }, "engines": { - "node": ">=14.18.0", + "node": ">=18.0.0", "npm": ">=8.0.0" }, "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.9.6", + "@rollup/rollup-android-arm64": "4.9.6", + "@rollup/rollup-darwin-arm64": "4.9.6", + "@rollup/rollup-darwin-x64": "4.9.6", + "@rollup/rollup-linux-arm-gnueabihf": "4.9.6", + "@rollup/rollup-linux-arm64-gnu": "4.9.6", + "@rollup/rollup-linux-arm64-musl": "4.9.6", + "@rollup/rollup-linux-riscv64-gnu": "4.9.6", + "@rollup/rollup-linux-x64-gnu": "4.9.6", + "@rollup/rollup-linux-x64-musl": "4.9.6", + "@rollup/rollup-win32-arm64-msvc": "4.9.6", + "@rollup/rollup-win32-ia32-msvc": "4.9.6", + "@rollup/rollup-win32-x64-msvc": "4.9.6", "fsevents": "~2.3.2" } }, @@ -5983,9 +6165,9 @@ } }, "node_modules/smob": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/smob/-/smob-0.0.6.tgz", - "integrity": "sha512-V21+XeNni+tTyiST1MHsa84AQhT1aFZipzPpOFAVB8DkHzwJyjjAmt9bgwnuZiZWnIbMo2duE29wybxv/7HWUw==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/smob/-/smob-1.4.1.tgz", + "integrity": "sha512-9LK+E7Hv5R9u4g4C3p+jjLstaLe11MDsL21UpYaCNmapvMkYhqCV4A/f/3gyH8QjMyh6l68q9xC85vihY9ahMQ==", "dev": true }, "node_modules/socket.io": { @@ -6073,6 +6255,15 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-support": { "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", @@ -6083,15 +6274,6 @@ "source-map": "^0.6.0" } }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/spdx-correct": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", @@ -6337,13 +6519,13 @@ } }, "node_modules/terser": { - "version": "5.16.4", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.4.tgz", - "integrity": "sha512-5yEGuZ3DZradbogeYQ1NaGz7rXVBDWujWlx1PT8efXO6Txn+eWbfKqB2bTDVmFXmePFkoLU6XI8UektMIEA0ug==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.27.0.tgz", + "integrity": "sha512-bi1HRwVRskAjheeYl291n3JC4GgO/Ty4z1nVs5AAsmonJulGxpSektecnNedrwK9C7vpvVtcX3cw00VSLt7U2A==", "dev": true, "dependencies": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, @@ -6550,12 +6732,6 @@ "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", "dev": true }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true - }, "node_modules/union": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", @@ -7107,9 +7283,9 @@ "dev": true }, "@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", "dev": true, "requires": { "@jridgewell/set-array": "^1.0.1", @@ -7130,9 +7306,9 @@ "dev": true }, "@jridgewell/source-map": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", - "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", "dev": true, "requires": { "@jridgewell/gen-mapping": "^0.3.0", @@ -7266,18 +7442,18 @@ "requires": {} }, "@rollup/plugin-alias": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.0.0.tgz", - "integrity": "sha512-l9hY5chSCjuFRPsnRm16twWBiSApl2uYFLsepQYwtBuAxNMQ/1dJqADld40P0Jkqm65GRTLy/AC6hnpVebtLsA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.1.0.tgz", + "integrity": "sha512-lpA3RZ9PdIG7qqhEfv79tBffNaoDuukFDrmhLqg9ifv99u/ehn+lOg30x2zmhf8AQqQUZaMk/B9fZraQ6/acDQ==", "dev": true, "requires": { "slash": "^4.0.0" } }, "@rollup/plugin-commonjs": { - "version": "24.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-24.1.0.tgz", - "integrity": "sha512-eSL45hjhCWI0jCCXcNtLVqM5N1JlBGvlFfY0m6oOYnLCJ6N0qEXoZql4sY2MOUArzhH4SA/qBpTxvvZp2Sc+DQ==", + "version": "25.0.7", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.7.tgz", + "integrity": "sha512-nEvcR+LRjEjsaSsc4x3XZfCCvZIaSMenZu/OiwOKGN2UhQpAYI7ru7czFvyWbErlpoGjnSX3D5Ch5FcMA3kRWQ==", "dev": true, "requires": { "@rollup/pluginutils": "^5.0.1", @@ -7285,7 +7461,7 @@ "estree-walker": "^2.0.2", "glob": "^8.0.3", "is-reference": "1.2.1", - "magic-string": "^0.27.0" + "magic-string": "^0.30.3" }, "dependencies": { "brace-expansion": { @@ -7347,24 +7523,24 @@ } }, "@rollup/plugin-replace": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-5.0.2.tgz", - "integrity": "sha512-M9YXNekv/C/iHHK+cvORzfRYfPbq0RDD8r0G+bMiTXjNGKulPnCT9O3Ss46WfhI6ZOCgApOP7xAdmCQJ+U2LAA==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-5.0.5.tgz", + "integrity": "sha512-rYO4fOi8lMaTg/z5Jb+hKnrHHVn8j2lwkqwyS4kTRhKyWOLf2wST2sWXr4WzWiTcoHTp2sTjqUbqIj2E39slKQ==", "dev": true, "requires": { "@rollup/pluginutils": "^5.0.1", - "magic-string": "^0.27.0" + "magic-string": "^0.30.3" } }, "@rollup/plugin-terser": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.1.tgz", - "integrity": "sha512-aKS32sw5a7hy+fEXVy+5T95aDIwjpGHCTv833HXVtyKMDoVS7pBr5K3L9hEQoNqbJFjfANPrNpIXlTQ7is00eA==", + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", + "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", "dev": true, "requires": { - "serialize-javascript": "^6.0.0", - "smob": "^0.0.6", - "terser": "^5.15.1" + "serialize-javascript": "^6.0.1", + "smob": "^1.0.0", + "terser": "^5.17.4" }, "dependencies": { "serialize-javascript": { @@ -7379,16 +7555,18 @@ } }, "@rollup/plugin-wasm": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-wasm/-/plugin-wasm-6.1.3.tgz", - "integrity": "sha512-7ItTTeyauE6lwdDtQWceEHZ9+txbi4RRy0mYPFn9BW7rD7YdgBDu7HTHsLtHrRzJc313RM/1m6GKgV3np/aEaw==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-wasm/-/plugin-wasm-6.2.2.tgz", + "integrity": "sha512-gpC4R1G9Ni92ZIRTexqbhX7U+9estZrbhP+9SRb0DW9xpB9g7j34r+J2hqrcW/lRI7dJaU84MxZM0Rt82tqYPQ==", "dev": true, - "requires": {} + "requires": { + "@rollup/pluginutils": "^5.0.2" + } }, "@rollup/pluginutils": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", - "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", + "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", "dev": true, "requires": { "@types/estree": "^1.0.0", @@ -7396,6 +7574,97 @@ "picomatch": "^2.3.1" } }, + "@rollup/rollup-android-arm-eabi": { + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.9.6.tgz", + "integrity": "sha512-MVNXSSYN6QXOulbHpLMKYi60ppyO13W9my1qogeiAqtjb2yR4LSmfU2+POvDkLzhjYLXz9Rf9+9a3zFHW1Lecg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-android-arm64": { + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.9.6.tgz", + "integrity": "sha512-T14aNLpqJ5wzKNf5jEDpv5zgyIqcpn1MlwCrUXLrwoADr2RkWA0vOWP4XxbO9aiO3dvMCQICZdKeDrFl7UMClw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-darwin-arm64": { + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.9.6.tgz", + "integrity": "sha512-CqNNAyhRkTbo8VVZ5R85X73H3R5NX9ONnKbXuHisGWC0qRbTTxnF1U4V9NafzJbgGM0sHZpdO83pLPzq8uOZFw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-darwin-x64": { + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.9.6.tgz", + "integrity": "sha512-zRDtdJuRvA1dc9Mp6BWYqAsU5oeLixdfUvkTHuiYOHwqYuQ4YgSmi6+/lPvSsqc/I0Omw3DdICx4Tfacdzmhog==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.9.6.tgz", + "integrity": "sha512-oNk8YXDDnNyG4qlNb6is1ojTOGL/tRhbbKeE/YuccItzerEZT68Z9gHrY3ROh7axDc974+zYAPxK5SH0j/G+QQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm64-gnu": { + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.9.6.tgz", + "integrity": "sha512-Z3O60yxPtuCYobrtzjo0wlmvDdx2qZfeAWTyfOjEDqd08kthDKexLpV97KfAeUXPosENKd8uyJMRDfFMxcYkDQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm64-musl": { + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.9.6.tgz", + "integrity": "sha512-gpiG0qQJNdYEVad+1iAsGAbgAnZ8j07FapmnIAQgODKcOTjLEWM9sRb+MbQyVsYCnA0Im6M6QIq6ax7liws6eQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-riscv64-gnu": { + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.9.6.tgz", + "integrity": "sha512-+uCOcvVmFUYvVDr27aiyun9WgZk0tXe7ThuzoUTAukZJOwS5MrGbmSlNOhx1j80GdpqbOty05XqSl5w4dQvcOA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-x64-gnu": { + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.9.6.tgz", + "integrity": "sha512-HUNqM32dGzfBKuaDUBqFB7tP6VMN74eLZ33Q9Y1TBqRDn+qDonkAUyKWwF9BR9unV7QUzffLnz9GrnKvMqC/fw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-x64-musl": { + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.9.6.tgz", + "integrity": "sha512-ch7M+9Tr5R4FK40FHQk8VnML0Szi2KRujUgHXd/HjuH9ifH72GUmw6lStZBo3c3GB82vHa0ZoUfjfcM7JiiMrQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-arm64-msvc": { + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.9.6.tgz", + "integrity": "sha512-VD6qnR99dhmTQ1mJhIzXsRcTBvTjbfbGGwKAHcu+52cVl15AC/kplkhxzW/uT0Xl62Y/meBKDZvoJSJN+vTeGA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-ia32-msvc": { + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.9.6.tgz", + "integrity": "sha512-J9AFDq/xiRI58eR2NIDfyVmTYGyIZmRcvcAoJ48oDld/NTR8wyiPUu2X/v1navJ+N/FGg68LEbX3Ejd6l8B7MQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-x64-msvc": { + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.9.6.tgz", + "integrity": "sha512-jqzNLhNDvIZOrt69Ce4UjGRpXJBzhUBzawMwnaDAwyHriki3XollsewxWzOzz+4yOFDkuJHtTsZFwMxhYJWmLQ==", + "dev": true, + "optional": true + }, "@sinonjs/commons": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", @@ -7503,9 +7772,9 @@ } }, "@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, "@types/istanbul-lib-coverage": { @@ -7543,13 +7812,10 @@ "dev": true }, "@types/node": { - "version": "20.11.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.4.tgz", - "integrity": "sha512-6I0fMH8Aoy2lOejL3s4LhyIYX34DPwY8bl5xlNjBvUEk8OHrcuzsFt+Ied4LvJihbtXPM+8zUqdydfIti86v9g==", - "dev": true, - "requires": { - "undici-types": "~5.26.4" - } + "version": "13.13.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.2.tgz", + "integrity": "sha512-LB2R1Oyhpg8gu4SON/mfforE525+Hi/M1ineICEDftqNVTyFg1aRIeGuTvXAoWHc4nbrFncWtJgMmoyRvuGh7A==", + "dev": true }, "@types/normalize-package-data": { "version": "2.4.3", @@ -9164,9 +9430,9 @@ "dev": true }, "follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", "dev": true }, "from": { @@ -9201,9 +9467,9 @@ "dev": true }, "fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, "optional": true }, @@ -9870,12 +10136,6 @@ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, "string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -10246,12 +10506,20 @@ } }, "magic-string": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", - "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", + "version": "0.30.6", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.6.tgz", + "integrity": "sha512-n62qCLbPjNjyo+owKtveQxZFZTBm+Ms6YoGD23Wew6Vw337PElFNifQpknPruVRQV57kVShPnLGo9vWxVhpPvA==", "dev": true, "requires": { - "@jridgewell/sourcemap-codec": "^1.4.13" + "@jridgewell/sourcemap-codec": "^1.4.15" + }, + "dependencies": { + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + } } }, "make-error": { @@ -11230,11 +11498,25 @@ } }, "rollup": { - "version": "3.29.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", - "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.9.6.tgz", + "integrity": "sha512-05lzkCS2uASX0CiLFybYfVkwNbKZG5NFQ6Go0VWyogFTXXbR039UVsegViTntkk4OglHBdF54ccApXRRuXRbsg==", "dev": true, "requires": { + "@rollup/rollup-android-arm-eabi": "4.9.6", + "@rollup/rollup-android-arm64": "4.9.6", + "@rollup/rollup-darwin-arm64": "4.9.6", + "@rollup/rollup-darwin-x64": "4.9.6", + "@rollup/rollup-linux-arm-gnueabihf": "4.9.6", + "@rollup/rollup-linux-arm64-gnu": "4.9.6", + "@rollup/rollup-linux-arm64-musl": "4.9.6", + "@rollup/rollup-linux-riscv64-gnu": "4.9.6", + "@rollup/rollup-linux-x64-gnu": "4.9.6", + "@rollup/rollup-linux-x64-musl": "4.9.6", + "@rollup/rollup-win32-arm64-msvc": "4.9.6", + "@rollup/rollup-win32-ia32-msvc": "4.9.6", + "@rollup/rollup-win32-x64-msvc": "4.9.6", + "@types/estree": "1.0.5", "fsevents": "~2.3.2" } }, @@ -11341,9 +11623,9 @@ "dev": true }, "smob": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/smob/-/smob-0.0.6.tgz", - "integrity": "sha512-V21+XeNni+tTyiST1MHsa84AQhT1aFZipzPpOFAVB8DkHzwJyjjAmt9bgwnuZiZWnIbMo2duE29wybxv/7HWUw==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/smob/-/smob-1.4.1.tgz", + "integrity": "sha512-9LK+E7Hv5R9u4g4C3p+jjLstaLe11MDsL21UpYaCNmapvMkYhqCV4A/f/3gyH8QjMyh6l68q9xC85vihY9ahMQ==", "dev": true }, "socket.io": { @@ -11413,6 +11695,12 @@ } } }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, "source-map-support": { "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", @@ -11421,14 +11709,6 @@ "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } } }, "spdx-correct": { @@ -11623,13 +11903,13 @@ } }, "terser": { - "version": "5.16.4", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.4.tgz", - "integrity": "sha512-5yEGuZ3DZradbogeYQ1NaGz7rXVBDWujWlx1PT8efXO6Txn+eWbfKqB2bTDVmFXmePFkoLU6XI8UektMIEA0ug==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.27.0.tgz", + "integrity": "sha512-bi1HRwVRskAjheeYl291n3JC4GgO/Ty4z1nVs5AAsmonJulGxpSektecnNedrwK9C7vpvVtcX3cw00VSLt7U2A==", "dev": true, "requires": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, @@ -11768,12 +12048,6 @@ "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", "dev": true }, - "undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true - }, "union": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", diff --git a/package.json b/package.json index edf883e4..f9a895da 100644 --- a/package.json +++ b/package.json @@ -69,12 +69,12 @@ "@openpgp/seek-bzip": "^1.0.5-git", "@openpgp/tweetnacl": "^1.0.4-1", "@openpgp/web-stream-tools": "~0.1.1", - "@rollup/plugin-alias": "^5.0.0", - "@rollup/plugin-commonjs": "^24.0.1", - "@rollup/plugin-node-resolve": "^15.2.1", - "@rollup/plugin-replace": "^5.0.2", - "@rollup/plugin-terser": "^0.4.0", - "@rollup/plugin-wasm": "^6.1.2", + "@rollup/plugin-alias": "^5.1.0", + "@rollup/plugin-commonjs": "^25.0.7", + "@rollup/plugin-node-resolve": "^15.2.3", + "@rollup/plugin-replace": "^5.0.5", + "@rollup/plugin-terser": "^0.4.4", + "@rollup/plugin-wasm": "^6.2.2", "@types/chai": "^4.2.14", "argon2id": "^1.0.1", "benchmark": "^2.1.4", @@ -99,7 +99,7 @@ "karma-webkit-launcher": "^2.1.0", "mocha": "^10.2.0", "playwright": "^1.30.0", - "rollup": "^3.29.4", + "rollup": "^4.9.5", "sinon": "^15.1.0", "ts-node": "^10.9.1", "typescript": "^5.3.3", From 6370e0b2d3319e28a38ec7f38d0f506860f8546a Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Thu, 1 Feb 2024 10:38:01 +0100 Subject: [PATCH 099/201] CI: fix typescript test runner issues by switching to tsx from ts-node ts-node is still needed for mocha to work with the different versions of Node (passing --import in NODE_OPTIONS is not supported in older versions). --- package-lock.json | 677 +++++++++++++++++++++++++++++++++++++++++++++- package.json | 3 +- 2 files changed, 673 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index c07ccb96..b8f99878 100644 --- a/package-lock.json +++ b/package-lock.json @@ -52,6 +52,7 @@ "rollup": "^4.9.5", "sinon": "^15.1.0", "ts-node": "^10.9.1", + "tsx": "^4.7.0", "typescript": "^5.3.3", "web-streams-polyfill": "^3.2.0" }, @@ -256,6 +257,374 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", + "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", + "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", + "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", + "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", + "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", + "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", + "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", + "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", + "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", + "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", + "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", + "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", + "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", + "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", + "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", + "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", + "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", + "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", + "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", + "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", + "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", + "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", + "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -2485,6 +2854,44 @@ "es6-promise": "^4.0.3" } }, + "node_modules/esbuild": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", + "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.19.12", + "@esbuild/android-arm": "0.19.12", + "@esbuild/android-arm64": "0.19.12", + "@esbuild/android-x64": "0.19.12", + "@esbuild/darwin-arm64": "0.19.12", + "@esbuild/darwin-x64": "0.19.12", + "@esbuild/freebsd-arm64": "0.19.12", + "@esbuild/freebsd-x64": "0.19.12", + "@esbuild/linux-arm": "0.19.12", + "@esbuild/linux-arm64": "0.19.12", + "@esbuild/linux-ia32": "0.19.12", + "@esbuild/linux-loong64": "0.19.12", + "@esbuild/linux-mips64el": "0.19.12", + "@esbuild/linux-ppc64": "0.19.12", + "@esbuild/linux-riscv64": "0.19.12", + "@esbuild/linux-s390x": "0.19.12", + "@esbuild/linux-x64": "0.19.12", + "@esbuild/netbsd-x64": "0.19.12", + "@esbuild/openbsd-x64": "0.19.12", + "@esbuild/sunos-x64": "0.19.12", + "@esbuild/win32-arm64": "0.19.12", + "@esbuild/win32-ia32": "0.19.12", + "@esbuild/win32-x64": "0.19.12" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -3320,9 +3727,9 @@ "dev": true }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, "optional": true, @@ -3414,6 +3821,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-tsconfig": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.2.tgz", + "integrity": "sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==", + "dev": true, + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -5960,6 +6379,15 @@ "node": ">=4" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -6627,6 +7055,25 @@ "strip-bom": "^3.0.0" } }, + "node_modules/tsx": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.0.tgz", + "integrity": "sha512-I+t79RYPlEYlHn9a+KzwrvEwhJg35h/1zHsLC2JXvhC2mdynMv6Zxzvhv5EMV6VF5qJlLlkSnMVvdZV3PSIGcg==", + "dev": true, + "dependencies": { + "esbuild": "~0.19.10", + "get-tsconfig": "^4.7.2" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -7157,6 +7604,167 @@ } } }, + "@esbuild/aix-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", + "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", + "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", + "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "dev": true, + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", + "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", + "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", + "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", + "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", + "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", + "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", + "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", + "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", + "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", + "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", + "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", + "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", + "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", + "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", + "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", + "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "dev": true, + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", + "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "dev": true, + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", + "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "dev": true, + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", + "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "dev": true, + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", + "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", + "dev": true, + "optional": true + }, "@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -8825,6 +9433,37 @@ "es6-promise": "^4.0.3" } }, + "esbuild": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", + "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", + "dev": true, + "requires": { + "@esbuild/aix-ppc64": "0.19.12", + "@esbuild/android-arm": "0.19.12", + "@esbuild/android-arm64": "0.19.12", + "@esbuild/android-x64": "0.19.12", + "@esbuild/darwin-arm64": "0.19.12", + "@esbuild/darwin-x64": "0.19.12", + "@esbuild/freebsd-arm64": "0.19.12", + "@esbuild/freebsd-x64": "0.19.12", + "@esbuild/linux-arm": "0.19.12", + "@esbuild/linux-arm64": "0.19.12", + "@esbuild/linux-ia32": "0.19.12", + "@esbuild/linux-loong64": "0.19.12", + "@esbuild/linux-mips64el": "0.19.12", + "@esbuild/linux-ppc64": "0.19.12", + "@esbuild/linux-riscv64": "0.19.12", + "@esbuild/linux-s390x": "0.19.12", + "@esbuild/linux-x64": "0.19.12", + "@esbuild/netbsd-x64": "0.19.12", + "@esbuild/openbsd-x64": "0.19.12", + "@esbuild/sunos-x64": "0.19.12", + "@esbuild/win32-arm64": "0.19.12", + "@esbuild/win32-ia32": "0.19.12", + "@esbuild/win32-x64": "0.19.12" + } + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -9467,9 +10106,9 @@ "dev": true }, "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "optional": true }, @@ -9530,6 +10169,15 @@ "get-intrinsic": "^1.1.1" } }, + "get-tsconfig": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.2.tgz", + "integrity": "sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==", + "dev": true, + "requires": { + "resolve-pkg-maps": "^1.0.0" + } + }, "glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -11476,6 +12124,12 @@ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, + "resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true + }, "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -11981,6 +12635,17 @@ "strip-bom": "^3.0.0" } }, + "tsx": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.0.tgz", + "integrity": "sha512-I+t79RYPlEYlHn9a+KzwrvEwhJg35h/1zHsLC2JXvhC2mdynMv6Zxzvhv5EMV6VF5qJlLlkSnMVvdZV3PSIGcg==", + "dev": true, + "requires": { + "esbuild": "~0.19.10", + "fsevents": "~2.3.3", + "get-tsconfig": "^4.7.2" + } + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", diff --git a/package.json b/package.json index f9a895da..d370f10e 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "build-test": "npm run build --build-only=test", "prepare": "npm run build", "test": "mocha --timeout 120000 test/unittests.js", - "test-type-definitions": "node --loader ts-node/esm test/typescript/definitions.ts", + "test-type-definitions": "tsx test/typescript/definitions.ts", "benchmark-time": "node test/benchmarks/time.js", "benchmark-memory-usage": "node test/benchmarks/memory_usage.js", "start": "http-server", @@ -102,6 +102,7 @@ "rollup": "^4.9.5", "sinon": "^15.1.0", "ts-node": "^10.9.1", + "tsx": "^4.7.0", "typescript": "^5.3.3", "web-streams-polyfill": "^3.2.0" }, From f64dc3f35ffe5a23827c16439cd5e6f8b0854373 Mon Sep 17 00:00:00 2001 From: larabr Date: Fri, 2 Feb 2024 12:54:24 +0100 Subject: [PATCH 100/201] `enums.curve`: rename NIST curves (`p256`,p384`,`p521`) and clean up unused internal values (#1721) This is a breaking change, as NIST curves identifiers and values in `enums.curves` have been renamed: - the identifiers `enums.curve.p256`, `.p384`, `.p521` are now marked as `@deprecated` - the new identifiers are, respectively: `enums.curve.nistP256`, `.nistP384`, `.nistP521`. - the corresponding values have been changed from `'p256'`,`'p384'`,`'p521'` to `'nistP256'`, `'nistP384'`, `'nistP521'`. Affected high-level API functions: - in `generateKey`, the `options.curve` argument will expect the updated string values - `Key.getAlgorithmInfo()` will return the updated `curve` values --- README.md | 8 +- openpgp.d.ts | 14 ++- src/crypto/public_key/elliptic/ecdh.js | 26 +++--- src/crypto/public_key/elliptic/ecdsa.js | 8 +- .../public_key/elliptic/noble_curves.js | 12 +-- src/crypto/public_key/elliptic/oid_curves.js | 93 +++++++++---------- src/enums.js | 55 +++-------- src/openpgp.js | 2 +- src/type/oid.js | 23 ++++- test/crypto/ecdh.js | 4 +- test/crypto/elliptic.js | 21 ++--- test/crypto/elliptic_data.js | 6 +- test/crypto/validate.js | 4 +- test/general/ecc_nist.js | 10 +- test/general/key.js | 6 +- test/general/openpgp.js | 2 +- 16 files changed, 136 insertions(+), 158 deletions(-) diff --git a/README.md b/README.md index 72e5bf2f..a06ff88f 100644 --- a/README.md +++ b/README.md @@ -59,9 +59,9 @@ library to convert back and forth between them. |:---------------:|:----------:|:---------:|:----------:|:---------:|:-----------------:| | curve25519 | ECDH | N/A | No | No | Algorithmically** | | ed25519 | N/A | EdDSA | No | No | Algorithmically** | - | p256 | ECDH | ECDSA | Yes* | Yes* | If native*** | - | p384 | ECDH | ECDSA | Yes* | Yes* | If native*** | - | p521 | ECDH | ECDSA | Yes* | Yes* | If native*** | + | nistP256 | ECDH | ECDSA | Yes* | Yes* | If native*** | + | nistP384 | ECDH | ECDSA | Yes* | Yes* | If native*** | + | nistP521 | ECDH | ECDSA | Yes* | Yes* | If native*** | | brainpoolP256r1 | ECDH | ECDSA | Yes* | No | If native*** | | brainpoolP384r1 | ECDH | ECDSA | Yes* | No | If native*** | | brainpoolP512r1 | ECDH | ECDSA | Yes* | No | If native*** | @@ -451,7 +451,7 @@ can `.pipe()` to a `Writable` stream, for example. ECC keys (smaller and faster to generate): -Possible values for `curve` are: `curve25519`, `ed25519`, `p256`, `p384`, `p521`, +Possible values for `curve` are: `curve25519`, `ed25519`, `nistP256`, `nistP384`, `nistP521`, `brainpoolP256r1`, `brainpoolP384r1`, `brainpoolP512r1`, and `secp256k1`. Note that both the `curve25519` and `ed25519` options generate a primary key for signing using Ed25519 and a subkey for encryption using Curve25519. diff --git a/openpgp.d.ts b/openpgp.d.ts index 702564fd..871a707d 100644 --- a/openpgp.d.ts +++ b/openpgp.d.ts @@ -688,7 +688,7 @@ interface KeyPair { publicKey: PublicKey; } -export type EllipticCurveName = 'ed25519Legacy' | 'curve25519Legacy' | 'p256' | 'p384' | 'p521' | 'secp256k1' | 'brainpoolP256r1' | 'brainpoolP384r1' | 'brainpoolP512r1'; +export type EllipticCurveName = 'ed25519Legacy' | 'curve25519Legacy' | 'nistP256' | 'nistP384' | 'nistP521' | 'secp256k1' | 'brainpoolP256r1' | 'brainpoolP384r1' | 'brainpoolP512r1'; interface GenerateKeyOptions { userIDs: MaybeArray; @@ -838,9 +838,15 @@ export namespace enums { } enum curve { - p256 = 'p256', - p384 = 'p384', - p521 = 'p521', + /** @deprecated use `nistP256` instead */ + p256 = 'nistP256', + nistP256 = 'nistP256', + /** @deprecated use `nistP384` instead */ + p384 = 'nistP384', + nistP384 = 'nistP384', + /** @deprecated use `nistP521` instead */ + p521 = 'nistP521', + nistP521 = 'nistP521', /** @deprecated use `ed25519Legacy` instead */ ed25519 = 'ed25519Legacy', ed25519Legacy = 'ed25519Legacy', diff --git a/src/crypto/public_key/elliptic/ecdh.js b/src/crypto/public_key/elliptic/ecdh.js index 7d749d63..cc4d3952 100644 --- a/src/crypto/public_key/elliptic/ecdh.js +++ b/src/crypto/public_key/elliptic/ecdh.js @@ -238,24 +238,24 @@ async function jsPublicEphemeralKey(curve, Q) { * @async */ async function webPrivateEphemeralKey(curve, V, Q, d) { - const recipient = privateToJWK(curve.payloadSize, curve.web.web, Q, d); + const recipient = privateToJWK(curve.payloadSize, curve.web, Q, d); let privateKey = webCrypto.importKey( 'jwk', recipient, { name: 'ECDH', - namedCurve: curve.web.web + namedCurve: curve.web }, true, ['deriveKey', 'deriveBits'] ); - const jwk = rawPublicToJWK(curve.payloadSize, curve.web.web, V); + const jwk = rawPublicToJWK(curve.payloadSize, curve.web, V); let sender = webCrypto.importKey( 'jwk', jwk, { name: 'ECDH', - namedCurve: curve.web.web + namedCurve: curve.web }, true, [] @@ -264,11 +264,11 @@ async function webPrivateEphemeralKey(curve, V, Q, d) { let S = webCrypto.deriveBits( { name: 'ECDH', - namedCurve: curve.web.web, + namedCurve: curve.web, public: sender }, privateKey, - curve.web.sharedSize + curve.sharedSize ); let secret = webCrypto.exportKey( 'jwk', @@ -289,11 +289,11 @@ async function webPrivateEphemeralKey(curve, V, Q, d) { * @async */ async function webPublicEphemeralKey(curve, Q) { - const jwk = rawPublicToJWK(curve.payloadSize, curve.web.web, Q); + const jwk = rawPublicToJWK(curve.payloadSize, curve.web, Q); let keyPair = webCrypto.generateKey( { name: 'ECDH', - namedCurve: curve.web.web + namedCurve: curve.web }, true, ['deriveKey', 'deriveBits'] @@ -303,7 +303,7 @@ async function webPublicEphemeralKey(curve, Q) { jwk, { name: 'ECDH', - namedCurve: curve.web.web + namedCurve: curve.web }, false, [] @@ -312,11 +312,11 @@ async function webPublicEphemeralKey(curve, Q) { let s = webCrypto.deriveBits( { name: 'ECDH', - namedCurve: curve.web.web, + namedCurve: curve.web, public: recipient }, keyPair.privateKey, - curve.web.sharedSize + curve.sharedSize ); let p = webCrypto.exportKey( 'jwk', @@ -338,7 +338,7 @@ async function webPublicEphemeralKey(curve, Q) { * @async */ async function nodePrivateEphemeralKey(curve, V, d) { - const recipient = nodeCrypto.createECDH(curve.node.node); + const recipient = nodeCrypto.createECDH(curve.node); recipient.setPrivateKey(d); const sharedKey = new Uint8Array(recipient.computeSecret(V)); const secretKey = new Uint8Array(recipient.getPrivateKey()); @@ -354,7 +354,7 @@ async function nodePrivateEphemeralKey(curve, V, d) { * @async */ async function nodePublicEphemeralKey(curve, Q) { - const sender = nodeCrypto.createECDH(curve.node.node); + const sender = nodeCrypto.createECDH(curve.node); sender.generateKeys(); const sharedKey = new Uint8Array(sender.computeSecret(Q)); const publicKey = new Uint8Array(sender.getPublicKey()); diff --git a/src/crypto/public_key/elliptic/ecdsa.js b/src/crypto/public_key/elliptic/ecdsa.js index 8c186d46..44d63755 100644 --- a/src/crypto/public_key/elliptic/ecdsa.js +++ b/src/crypto/public_key/elliptic/ecdsa.js @@ -55,9 +55,9 @@ export async function sign(oid, hashAlgo, message, publicKey, privateKey, hashed return await webSign(curve, hashAlgo, message, keyPair); } catch (err) { // We do not fallback if the error is related to key integrity - // Unfortunaley Safari does not support p521 and throws a DataError when using it + // Unfortunaley Safari does not support nistP521 and throws a DataError when using it // So we need to always fallback for that curve - if (curve.name !== 'p521' && (err.name === 'DataError' || err.name === 'OperationError')) { + if (curve.name !== 'nistP521' && (err.name === 'DataError' || err.name === 'OperationError')) { throw err; } util.printDebugError('Browser did not support signing: ' + err.message); @@ -117,9 +117,9 @@ export async function verify(oid, hashAlgo, signature, message, publicKey, hashe return verified || tryFallbackVerificationForOldBug(); } catch (err) { // We do not fallback if the error is related to key integrity - // Unfortunately Safari does not support p521 and throws a DataError when using it + // Unfortunately Safari does not support nistP521 and throws a DataError when using it // So we need to always fallback for that curve - if (curve.name !== 'p521' && (err.name === 'DataError' || err.name === 'OperationError')) { + if (curve.name !== 'nistP521' && (err.name === 'DataError' || err.name === 'OperationError')) { throw err; } util.printDebugError('Browser did not support verifying: ' + err.message); diff --git a/src/crypto/public_key/elliptic/noble_curves.js b/src/crypto/public_key/elliptic/noble_curves.js index 22a80fba..4e7703d5 100644 --- a/src/crypto/public_key/elliptic/noble_curves.js +++ b/src/crypto/public_key/elliptic/noble_curves.js @@ -4,9 +4,9 @@ * which share a lot of code anyway. */ -import { p256 } from '@openpgp/noble-curves/p256'; -import { p384 } from '@openpgp/noble-curves/p384'; -import { p521 } from '@openpgp/noble-curves/p521'; +import { p256 as nistP256 } from '@openpgp/noble-curves/p256'; +import { p384 as nistP384 } from '@openpgp/noble-curves/p384'; +import { p521 as nistP521 } from '@openpgp/noble-curves/p521'; import { brainpoolP256r1 } from '@openpgp/noble-curves/brainpoolP256r1'; import { brainpoolP384r1 } from '@openpgp/noble-curves/brainpoolP384r1'; import { brainpoolP512r1 } from '@openpgp/noble-curves/brainpoolP512r1'; @@ -14,9 +14,9 @@ import { x448, ed448 } from '@openpgp/noble-curves/ed448'; import { secp256k1 } from '@openpgp/noble-curves/secp256k1'; export const nobleCurves = new Map(Object.entries({ - p256, - p384, - p521, + nistP256, + nistP384, + nistP521, brainpoolP256r1, brainpoolP384r1, brainpoolP512r1, diff --git a/src/crypto/public_key/elliptic/oid_curves.js b/src/crypto/public_key/elliptic/oid_curves.js index 57bcc4df..5aeddfb6 100644 --- a/src/crypto/public_key/elliptic/oid_curves.js +++ b/src/crypto/public_key/elliptic/oid_curves.js @@ -31,16 +31,16 @@ const webCrypto = util.getWebCrypto(); const nodeCrypto = util.getNodeCrypto(); const webCurves = { - [enums.curve.p256]: 'P-256', - [enums.curve.p384]: 'P-384', - [enums.curve.p521]: 'P-521' + [enums.curve.nistP256]: 'P-256', + [enums.curve.nistP384]: 'P-384', + [enums.curve.nistP521]: 'P-521' }; const knownCurves = nodeCrypto ? nodeCrypto.getCurves() : []; const nodeCurves = nodeCrypto ? { [enums.curve.secp256k1]: knownCurves.includes('secp256k1') ? 'secp256k1' : undefined, - [enums.curve.p256]: knownCurves.includes('prime256v1') ? 'prime256v1' : undefined, - [enums.curve.p384]: knownCurves.includes('secp384r1') ? 'secp384r1' : undefined, - [enums.curve.p521]: knownCurves.includes('secp521r1') ? 'secp521r1' : undefined, + [enums.curve.nistP256]: knownCurves.includes('prime256v1') ? 'prime256v1' : undefined, + [enums.curve.nistP384]: knownCurves.includes('secp384r1') ? 'secp384r1' : undefined, + [enums.curve.nistP521]: knownCurves.includes('secp521r1') ? 'secp521r1' : undefined, [enums.curve.ed25519Legacy]: knownCurves.includes('ED25519') ? 'ED25519' : undefined, [enums.curve.curve25519Legacy]: knownCurves.includes('X25519') ? 'X25519' : undefined, [enums.curve.brainpoolP256r1]: knownCurves.includes('brainpoolP256r1') ? 'brainpoolP256r1' : undefined, @@ -49,52 +49,52 @@ const nodeCurves = nodeCrypto ? { } : {}; const curves = { - p256: { + [enums.curve.nistP256]: { oid: [0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07], keyType: enums.publicKey.ecdsa, hash: enums.hash.sha256, cipher: enums.symmetric.aes128, - node: nodeCurves.p256, - web: webCurves.p256, + node: nodeCurves[enums.curve.nistP256], + web: webCurves[enums.curve.nistP256], payloadSize: 32, sharedSize: 256 }, - p384: { + [enums.curve.nistP384]: { oid: [0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22], keyType: enums.publicKey.ecdsa, hash: enums.hash.sha384, cipher: enums.symmetric.aes192, - node: nodeCurves.p384, - web: webCurves.p384, + node: nodeCurves[enums.curve.nistP384], + web: webCurves[enums.curve.nistP384], payloadSize: 48, sharedSize: 384 }, - p521: { + [enums.curve.nistP521]: { oid: [0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x23], keyType: enums.publicKey.ecdsa, hash: enums.hash.sha512, cipher: enums.symmetric.aes256, - node: nodeCurves.p521, - web: webCurves.p521, + node: nodeCurves[enums.curve.nistP521], + web: webCurves[enums.curve.nistP521], payloadSize: 66, sharedSize: 528 }, - secp256k1: { + [enums.curve.secp256k1]: { oid: [0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x0A], keyType: enums.publicKey.ecdsa, hash: enums.hash.sha256, cipher: enums.symmetric.aes128, - node: nodeCurves.secp256k1, + node: nodeCurves[enums.curve.secp256k1], payloadSize: 32 }, - ed25519Legacy: { + [enums.curve.ed25519Legacy]: { oid: [0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, 0x01, 0xDA, 0x47, 0x0F, 0x01], keyType: enums.publicKey.eddsaLegacy, hash: enums.hash.sha512, node: false, // nodeCurves.ed25519 TODO payloadSize: 32 }, - curve25519Legacy: { + [enums.curve.curve25519Legacy]: { oid: [0x06, 0x0A, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01], keyType: enums.publicKey.ecdh, hash: enums.hash.sha256, @@ -102,59 +102,52 @@ const curves = { node: false, // nodeCurves.curve25519 TODO payloadSize: 32 }, - brainpoolP256r1: { + [enums.curve.brainpoolP256r1]: { oid: [0x06, 0x09, 0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x07], keyType: enums.publicKey.ecdsa, hash: enums.hash.sha256, cipher: enums.symmetric.aes128, - node: nodeCurves.brainpoolP256r1, + node: nodeCurves[enums.curve.brainpoolP256r1], payloadSize: 32 }, - brainpoolP384r1: { + [enums.curve.brainpoolP384r1]: { oid: [0x06, 0x09, 0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0B], keyType: enums.publicKey.ecdsa, hash: enums.hash.sha384, cipher: enums.symmetric.aes192, - node: nodeCurves.brainpoolP384r1, + node: nodeCurves[enums.curve.brainpoolP384r1], payloadSize: 48 }, - brainpoolP512r1: { + [enums.curve.brainpoolP512r1]: { oid: [0x06, 0x09, 0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0D], keyType: enums.publicKey.ecdsa, hash: enums.hash.sha512, cipher: enums.symmetric.aes256, - node: nodeCurves.brainpoolP512r1, + node: nodeCurves[enums.curve.brainpoolP512r1], payloadSize: 64 } }; class CurveWithOID { - constructor(oidOrName, params) { + constructor(oidOrName) { try { - if (util.isArray(oidOrName) || - util.isUint8Array(oidOrName)) { - // by oid byte array - oidOrName = new OID(oidOrName); - } - if (oidOrName instanceof OID) { - // by curve OID - oidOrName = oidOrName.getName(); - } - // by curve name or oid string - this.name = enums.write(enums.curve, oidOrName); + this.name = oidOrName instanceof OID ? + oidOrName.getName() : + enums.write(enums.curve,oidOrName); } catch (err) { throw new UnsupportedError('Unknown curve'); } - params = params || curves[this.name]; + const params = curves[this.name]; this.keyType = params.keyType; this.oid = params.oid; this.hash = params.hash; this.cipher = params.cipher; - this.node = params.node && curves[this.name]; - this.web = params.web && curves[this.name]; + this.node = params.node; + this.web = params.web; this.payloadSize = params.payloadSize; + this.sharedSize = params.sharedSize; if (this.web && util.getWebCrypto()) { this.type = 'web'; } else if (this.node && util.getNodeCrypto()) { @@ -217,7 +210,7 @@ async function generate(curveName) { * @returns {enums.hash} hash algorithm */ function getPreferredHashAlgo(oid) { - return curves[enums.write(enums.curve, oid.toHex())].hash; + return curves[oid.getName()].hash; } /** @@ -232,14 +225,14 @@ function getPreferredHashAlgo(oid) { */ async function validateStandardParams(algo, oid, Q, d) { const supportedCurves = { - p256: true, - p384: true, - p521: true, - secp256k1: true, - curve25519Legacy: algo === enums.publicKey.ecdh, - brainpoolP256r1: true, - brainpoolP384r1: true, - brainpoolP512r1: true + [enums.curve.nistP256]: true, + [enums.curve.nistP384]: true, + [enums.curve.nistP521]: true, + [enums.curve.secp256k1]: true, + [enums.curve.curve25519Legacy]: algo === enums.publicKey.ecdh, + [enums.curve.brainpoolP256r1]: true, + [enums.curve.brainpoolP384r1]: true, + [enums.curve.brainpoolP512r1]: true }; // Check whether the given curve is supported @@ -262,7 +255,7 @@ async function validateStandardParams(algo, oid, Q, d) { return true; } - const nobleCurve = await util.getNobleCurve(enums.publicKey.ecdsa, enums.write(enums.curve, oid.toHex())); // excluding curve25519Legacy, ecdh and ecdsa use the same curves + const nobleCurve = await util.getNobleCurve(enums.publicKey.ecdsa, curveName); // excluding curve25519Legacy, ecdh and ecdsa use the same curves /* * Re-derive public point Q' = dG from private key * Expect Q == Q' diff --git a/src/enums.js b/src/enums.js index 8a417ec0..b9ea1e2b 100644 --- a/src/enums.js +++ b/src/enums.js @@ -13,74 +13,41 @@ export default { */ curve: { /** NIST P-256 Curve */ - 'p256': 'p256', - 'P-256': 'p256', - 'secp256r1': 'p256', - 'prime256v1': 'p256', - '1.2.840.10045.3.1.7': 'p256', - '2a8648ce3d030107': 'p256', - '2A8648CE3D030107': 'p256', + 'nistP256': 'nistP256', + /** @deprecated use `nistP256` instead */ + 'p256': 'nistP256', /** NIST P-384 Curve */ - 'p384': 'p384', - 'P-384': 'p384', - 'secp384r1': 'p384', - '1.3.132.0.34': 'p384', - '2b81040022': 'p384', - '2B81040022': 'p384', + 'nistP384': 'nistP384', + /** @deprecated use `nistP384` instead */ + 'p384': 'nistP384', /** NIST P-521 Curve */ - 'p521': 'p521', - 'P-521': 'p521', - 'secp521r1': 'p521', - '1.3.132.0.35': 'p521', - '2b81040023': 'p521', - '2B81040023': 'p521', + 'nistP521': 'nistP521', + /** @deprecated use `nistP521` instead */ + 'p521': 'nistP521', /** SECG SECP256k1 Curve */ - 'secp256k1': 'secp256k1', - '1.3.132.0.10': 'secp256k1', - '2b8104000a': 'secp256k1', - '2B8104000A': 'secp256k1', + 'secp256k1': 'secp256k1', /** Ed25519 - deprecated by crypto-refresh (replaced by standaone Ed25519 algo) */ 'ed25519Legacy': 'ed25519Legacy', - 'ED25519': 'ed25519Legacy', /** @deprecated use `ed25519Legacy` instead */ 'ed25519': 'ed25519Legacy', - 'Ed25519': 'ed25519Legacy', - '1.3.6.1.4.1.11591.15.1': 'ed25519Legacy', - '2b06010401da470f01': 'ed25519Legacy', - '2B06010401DA470F01': 'ed25519Legacy', /** Curve25519 - deprecated by crypto-refresh (replaced by standaone X25519 algo) */ 'curve25519Legacy': 'curve25519Legacy', - 'X25519': 'curve25519Legacy', - 'cv25519': 'curve25519Legacy', /** @deprecated use `curve25519Legacy` instead */ 'curve25519': 'curve25519Legacy', - 'Curve25519': 'curve25519Legacy', - '1.3.6.1.4.1.3029.1.5.1': 'curve25519Legacy', - '2b060104019755010501': 'curve25519Legacy', - '2B060104019755010501': 'curve25519Legacy', /** BrainpoolP256r1 Curve */ 'brainpoolP256r1': 'brainpoolP256r1', - '1.3.36.3.3.2.8.1.1.7': 'brainpoolP256r1', - '2b2403030208010107': 'brainpoolP256r1', - '2B2403030208010107': 'brainpoolP256r1', /** BrainpoolP384r1 Curve */ 'brainpoolP384r1': 'brainpoolP384r1', - '1.3.36.3.3.2.8.1.1.11': 'brainpoolP384r1', - '2b240303020801010b': 'brainpoolP384r1', - '2B240303020801010B': 'brainpoolP384r1', /** BrainpoolP512r1 Curve */ - 'brainpoolP512r1': 'brainpoolP512r1', - '1.3.36.3.3.2.8.1.1.13': 'brainpoolP512r1', - '2b240303020801010d': 'brainpoolP512r1', - '2B240303020801010D': 'brainpoolP512r1' + 'brainpoolP512r1': 'brainpoolP512r1' }, /** A string to key specifier type diff --git a/src/openpgp.js b/src/openpgp.js index 18f2ce09..c645eb93 100644 --- a/src/openpgp.js +++ b/src/openpgp.js @@ -42,7 +42,7 @@ import { checkKeyRequirements } from './key/helper'; * @param {String} [options.passphrase=(not protected)] - The passphrase used to encrypt the generated private key. If omitted or empty, the key won't be encrypted. * @param {Number} [options.rsaBits=4096] - Number of bits for RSA keys * @param {String} [options.curve='curve25519Legacy'] - Elliptic curve for ECC keys: - * curve25519Legacy (default), p256, p384, p521, secp256k1, + * curve25519Legacy (default), nistP256, nistP384, nistP521, secp256k1, * brainpoolP256r1, brainpoolP384r1, or brainpoolP512r1 * @param {Date} [options.date=current date] - Override the creation date of the key and the key signatures * @param {Number} [options.keyExpirationTime=0 (never expires)] - Number of seconds from the key creation time after which the key expires diff --git a/src/type/oid.js b/src/type/oid.js index 370f583a..bd45672b 100644 --- a/src/type/oid.js +++ b/src/type/oid.js @@ -35,6 +35,18 @@ import util from '../util'; import enums from '../enums'; +const knownOIDs = { + '2a8648ce3d030107': enums.curve.nistP256, + '2b81040022': enums.curve.nistP384, + '2b81040023': enums.curve.nistP521, + '2b8104000a': enums.curve.secp256k1, + '2b06010401da470f01': enums.curve.ed25519Legacy, + '2b060104019755010501': enums.curve.curve25519Legacy, + '2b2403030208010107': enums.curve.brainpoolP256r1, + '2b240303020801010b': enums.curve.brainpoolP384r1, + '2b240303020801010d': enums.curve.brainpoolP512r1 +}; + class OID { constructor(oid) { if (oid instanceof OID) { @@ -88,15 +100,16 @@ class OID { /** * If a known curve object identifier, return the canonical name of the curve - * @returns {string} String with the canonical name of the curve. + * @returns {enums.curve} String with the canonical name of the curve + * @throws if unknown */ getName() { - const hex = this.toHex(); - if (enums.curve[hex]) { - return enums.write(enums.curve, hex); - } else { + const name = knownOIDs[this.toHex()]; + if (!name) { throw new Error('Unknown curve object identifier.'); } + + return name; } } diff --git a/test/crypto/ecdh.js b/test/crypto/ecdh.js index 8b4c7a82..6e2cc189 100644 --- a/test/crypto/ecdh.js +++ b/test/crypto/ecdh.js @@ -199,7 +199,7 @@ export default () => describe('ECDH key exchange @lightweight', function () { expect(await ecdhX.decrypt(openpgp.enums.publicKey.x448, ephemeralPublicKey, wrappedKey, K_B, b)).to.deep.equal(data); }); - const allCurves = ['secp256k1', 'p256', 'p384', 'p521', 'brainpoolP256r1', 'brainpoolP384r1', 'brainpoolP512r1']; + const allCurves = ['secp256k1', 'nistP256', 'nistP384', 'nistP521', 'brainpoolP256r1', 'brainpoolP384r1', 'brainpoolP512r1']; allCurves.forEach(curveName => { it(`${curveName} - Successful exchange`, async function () { const curve = new elliptic_curves.CurveWithOID(curveName); @@ -245,7 +245,7 @@ export default () => describe('ECDH key exchange @lightweight', function () { this.skip(); } - const expectNativeWeb = new Set(['p256', 'p384']); // older versions of safari do not implement p521 + const expectNativeWeb = new Set(['nistP256', 'nistP384']); // older versions of safari do not implement nistP521 const curve = new elliptic_curves.CurveWithOID(curveName); const oid = new OID(curve.oid); diff --git a/test/crypto/elliptic.js b/test/crypto/elliptic.js index c93a89c4..3f0a6383 100644 --- a/test/crypto/elliptic.js +++ b/test/crypto/elliptic.js @@ -71,8 +71,8 @@ export default () => describe('Elliptic Curve Cryptography @lightweight', functi if (!config.useEllipticFallback && !util.getNodeCrypto()) { this.skip(); } - const names = config.useEllipticFallback ? ['p256', 'p384', 'p521', 'secp256k1', 'curve25519Legacy', 'brainpoolP256r1', 'brainpoolP384r1', 'brainpoolP512r1'] : - ['p256', 'p384', 'p521', 'curve25519Legacy']; + const names = config.useEllipticFallback ? ['nistP256', 'nistP384', 'nistP521', 'secp256k1', 'curve25519Legacy', 'brainpoolP256r1', 'brainpoolP384r1', 'brainpoolP512r1'] : + ['nistP256', 'nistP384', 'nistP521', 'curve25519Legacy']; return Promise.all(names.map(function (name) { const curve = new elliptic_curves.CurveWithOID(name); return curve.genKeyPair().then(keyPair => { @@ -82,18 +82,18 @@ export default () => describe('Elliptic Curve Cryptography @lightweight', functi }); it('Signature verification', function (done) { expect( - elliptic_curves.ecdsa.verify('p256', 8, signature_data.signature, signature_data.message, signature_data.pub, signature_data.hashed) + elliptic_curves.ecdsa.verify('nistP256', 8, signature_data.signature, signature_data.message, signature_data.pub, signature_data.hashed) ).to.eventually.be.true.notify(done); }); it('Invalid signature', function (done) { expect( - elliptic_curves.ecdsa.verify('p256', 8, signature_data.signature, signature_data.message, key_data.p256.pub, signature_data.hashed) + elliptic_curves.ecdsa.verify('nistP256', 8, signature_data.signature, signature_data.message, key_data.nistP256.pub, signature_data.hashed) ).to.eventually.be.false.notify(done); }); it('Signature generation', function () { - return elliptic_curves.ecdsa.sign('p256', 8, signature_data.message, key_data.p256.pub, key_data.p256.priv, signature_data.hashed).then(async signature => { + return elliptic_curves.ecdsa.sign('nistP256', 8, signature_data.message, key_data.nistP256.pub, key_data.nistP256.priv, signature_data.hashed).then(async signature => { await expect( - elliptic_curves.ecdsa.verify('p256', 8, signature, signature_data.message, key_data.p256.pub, signature_data.hashed) + elliptic_curves.ecdsa.verify('nistP256', 8, signature, signature_data.message, key_data.nistP256.pub, signature_data.hashed) ).to.eventually.be.true; }); }); @@ -236,12 +236,11 @@ export default () => describe('Elliptic Curve Cryptography @lightweight', functi ]); await testNativeAndFallback( - () => expect(verify_signature('p384', 8, p384_r, p384_s, p384_message, key_data.p384.pub)).to.eventually.be.true + () => expect(verify_signature('nistP384', 8, p384_r, p384_s, p384_message, key_data.nistP384.pub)).to.eventually.be.true ); }); - const curves = ['secp256k1' , 'p256', 'p384', 'p521', 'brainpoolP256r1', 'brainpoolP384r1', 'brainpoolP512r1']; + const curves = ['secp256k1' , 'nistP256', 'nistP384', 'nistP521', 'brainpoolP256r1', 'brainpoolP384r1', 'brainpoolP512r1']; curves.forEach(curveName => it(`${curveName} - Sign and verify message`, async function () { - const curve = new elliptic_curves.CurveWithOID(curveName); const { Q: keyPublic, secret: keyPrivate } = await elliptic_curves.generate(curveName); const message = new Uint8Array([ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, @@ -249,8 +248,8 @@ export default () => describe('Elliptic Curve Cryptography @lightweight', functi ]); const messageDigest = await hashMod.digest(openpgp.enums.hash.sha512, message); await testNativeAndFallback(async () => { - const signature = await elliptic_curves.ecdsa.sign(curve.oid, openpgp.enums.hash.sha512, message, keyPublic, keyPrivate, messageDigest); - await expect(elliptic_curves.ecdsa.verify(curve.oid, openpgp.enums.hash.sha512, signature, message, keyPublic, messageDigest)).to.eventually.be.true; + const signature = await elliptic_curves.ecdsa.sign(curveName, openpgp.enums.hash.sha512, message, keyPublic, keyPrivate, messageDigest); + await expect(elliptic_curves.ecdsa.verify(curveName, openpgp.enums.hash.sha512, signature, message, keyPublic, messageDigest)).to.eventually.be.true; }); })); }); diff --git a/test/crypto/elliptic_data.js b/test/crypto/elliptic_data.js index 1fbc64d0..ce04b32f 100644 --- a/test/crypto/elliptic_data.js +++ b/test/crypto/elliptic_data.js @@ -2,7 +2,7 @@ import util from '../../src/util.js'; const elliptic_data = { key_data: { - p256: { + nistP256: { priv: new Uint8Array([ 0x2B, 0x48, 0x2B, 0xE9, 0x88, 0x74, 0xE9, 0x49, 0x1F, 0x89, 0xCC, 0xFF, 0x0A, 0x26, 0x05, 0xA2, @@ -21,7 +21,7 @@ const elliptic_data = { 0x67, 0xC2, 0x09, 0xF9, 0xEF, 0xE7, 0x9E, 0x56 ]) }, - p384: { + nistP384: { priv: new Uint8Array([ 0xB5, 0x38, 0xDA, 0xF3, 0x77, 0x58, 0x3F, 0x94, 0x5B, 0xC2, 0xCA, 0xC6, 0xA9, 0xFC, 0xAA, 0x3F, @@ -46,7 +46,7 @@ const elliptic_data = { 0xFA, 0x85, 0x8A, 0x4B, 0x58, 0x7C, 0x61, 0x39 ]) }, - p521: { + nistP521: { priv: new Uint8Array([ 0x00, 0xBB, 0x35, 0x27, 0xBC, 0xD6, 0x7E, 0x35, 0xD5, 0xC5, 0x99, 0xC9, 0xB4, 0x6C, 0xEE, 0xDE, diff --git a/test/crypto/validate.js b/test/crypto/validate.js index ee4fa29e..6a46d030 100644 --- a/test/crypto/validate.js +++ b/test/crypto/validate.js @@ -117,7 +117,7 @@ export default () => { before(async () => { eddsaKey = await generatePrivateKeyObject({ curve: 'ed25519Legacy' }); ecdhKey = eddsaKey.subkeys[0]; - ecdsaKey = await generatePrivateKeyObject({ curve: 'p256' }); + ecdsaKey = await generatePrivateKeyObject({ curve: 'nistP256' }); }); it('EdDSA params are not valid for ECDH', async function() { @@ -193,7 +193,7 @@ export default () => { }); }); - const curves = ['curve25519Legacy', 'p256', 'p384', 'p521', 'secp256k1', 'brainpoolP256r1', 'brainpoolP384r1', 'brainpoolP512r1']; + const curves = ['curve25519Legacy', 'nistP256', 'nistP384', 'nistP521', 'secp256k1', 'brainpoolP256r1', 'brainpoolP384r1', 'brainpoolP512r1']; curves.forEach(curve => { describe(`ECC ${curve} parameter validation`, () => { let ecdsaKey; diff --git a/test/general/ecc_nist.js b/test/general/ecc_nist.js index 1838e031..aecfe062 100644 --- a/test/general/ecc_nist.js +++ b/test/general/ecc_nist.js @@ -14,8 +14,8 @@ export default () => describe('Elliptic Curve Cryptography for NIST P-256,P-384, const testData = input.createSomeMessage(); const testData2 = input.createSomeMessage(); - const { privateKey: hi, publicKey: pubHi } = await openpgp.generateKey({ userIDs: { name: 'Hi', email: 'hi@hel.lo' }, curve: 'p256', format: 'object' }); - const { privateKey: bye, publicKey: pubBye } = await openpgp.generateKey({ userIDs: { name: 'Bye', email: 'bye@good.bye' }, curve: 'p256', format: 'object' }); + const { privateKey: hi, publicKey: pubHi } = await openpgp.generateKey({ userIDs: { name: 'Hi', email: 'hi@hel.lo' }, curve: 'nistP256', format: 'object' }); + const { privateKey: bye, publicKey: pubBye } = await openpgp.generateKey({ userIDs: { name: 'Bye', email: 'bye@good.bye' }, curve: 'nistP256', format: 'object' }); const cleartextMessage = await openpgp.sign({ message: await openpgp.createCleartextMessage({ text: testData }), signingKeys: hi }); await openpgp.verify({ @@ -51,7 +51,7 @@ export default () => describe('Elliptic Curve Cryptography for NIST P-256,P-384, it('Sign message', async function () { const testData = input.createSomeMessage(); - const options = { userIDs: { name: 'Hi', email: 'hi@hel.lo' }, curve: 'p256', format: 'object' }; + const options = { userIDs: { name: 'Hi', email: 'hi@hel.lo' }, curve: 'nistP256', format: 'object' }; const { privateKey, publicKey } = await openpgp.generateKey(options); const signature = await openpgp.sign({ message: await openpgp.createCleartextMessage({ text: testData }), signingKeys: privateKey }); const msg = await openpgp.readCleartextMessage({ cleartextMessage: signature }); @@ -61,9 +61,9 @@ export default () => describe('Elliptic Curve Cryptography for NIST P-256,P-384, it('Encrypt and sign message', async function () { const testData = input.createSomeMessage(); - let options = { userIDs: { name: 'Hi', email: 'hi@hel.lo' }, curve: 'p256', format: 'object' }; + let options = { userIDs: { name: 'Hi', email: 'hi@hel.lo' }, curve: 'nistP256', format: 'object' }; const firstKey = await openpgp.generateKey(options); - options = { userIDs: { name: 'Bye', email: 'bye@good.bye' }, curve: 'p256', format: 'object' }; + options = { userIDs: { name: 'Bye', email: 'bye@good.bye' }, curve: 'nistP256', format: 'object' }; const secondKey = await openpgp.generateKey(options); const encrypted = await openpgp.encrypt({ message: await openpgp.createMessage({ text: testData }), diff --git a/test/general/key.js b/test/general/key.js index caeec0f9..6a9668da 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -2606,7 +2606,7 @@ function versionSpecificTests() { openpgp.config.minRSABits = rsaBits; const userID = { name: 'test', email: 'a@b.com' }; - const opt = { type: 'rsa', rsaBits, userIDs: [userID], passphrase: '123', format: 'object', subkeys:[{ type: 'ecc', curve: 'p256' }] }; + const opt = { type: 'rsa', rsaBits, userIDs: [userID], passphrase: '123', format: 'object', subkeys:[{ type: 'ecc', curve: 'nistP256' }] }; try { const { privateKey: key } = await openpgp.generateKey(opt); expect(key.users.length).to.equal(1); @@ -4503,13 +4503,13 @@ I8kWVkXU6vFOi+HWvv/ira7ofJu16NnoUkhclkUrk0mXubZvyl4GBg== const userID = { name: 'test', email: 'a@b.com' }; const { privateKey } = await openpgp.generateKey({ curve: 'ed25519Legacy', userIDs: [userID], format: 'object', subkeys:[] }); const total = privateKey.subkeys.length; - let newPrivateKey = await privateKey.addSubkey({ curve: 'p256', sign: true }); + let newPrivateKey = await privateKey.addSubkey({ curve: 'nistP256', sign: true }); newPrivateKey = await openpgp.readKey({ armoredKey: newPrivateKey.armor() }); const subkey = newPrivateKey.subkeys[total]; expect(subkey).to.exist; expect(newPrivateKey.subkeys.length).to.be.equal(total + 1); expect(newPrivateKey.getAlgorithmInfo().curve).to.be.equal('ed25519Legacy'); - expect(subkey.getAlgorithmInfo().curve).to.be.equal('p256'); + expect(subkey.getAlgorithmInfo().curve).to.be.equal('nistP256'); expect(newPrivateKey.getAlgorithmInfo().algorithm).to.be.equal('eddsaLegacy'); expect(subkey.getAlgorithmInfo().algorithm).to.be.equal('ecdsa'); diff --git a/test/general/openpgp.js b/test/general/openpgp.js index 1c4eb283..90b70fe5 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -4793,7 +4793,7 @@ sEj+v9LKoMTYZGMfp3qDVFLtkBE88eVmVjgJOoLhrsv7yh0PAA== }); describe('Sign and verify with each curve', function() { - const curves = ['secp256k1' , 'p256', 'p384', 'p521', 'curve25519Legacy', 'brainpoolP256r1', 'brainpoolP384r1', 'brainpoolP512r1']; + const curves = ['secp256k1' , 'nistP256', 'nistP384', 'nistP521', 'curve25519Legacy', 'brainpoolP256r1', 'brainpoolP384r1', 'brainpoolP512r1']; curves.forEach(curve => { it(`sign/verify with ${curve}`, async function() { const config = { rejectCurves: new Set() }; From 22c2682574b6b806662d9847fde438cfc198a5e6 Mon Sep 17 00:00:00 2001 From: larabr Date: Fri, 2 Feb 2024 14:50:32 +0100 Subject: [PATCH 101/201] Ensure primary key meets strength and algo requirements when encrypting/verifying/signing using subkeys (#1719) Breaking change: the requirements of `config.minRSABits`, `rejectPublicKeyAlgorithms` and `rejectCurves` are now applied to the primary key, aside from the selected subkey. The motivation is that the subkeys are certified by the primary key, but if the latter is weak, arbitrary subkeys could potentially be added. Note that the change does not affect decryption, to allow decrypting older messages. --- src/key/key.js | 10 ++++++++++ test/general/config.js | 21 ++++++++++++++++++--- test/general/key.js | 8 +++----- test/general/openpgp.js | 2 +- test/general/signature.js | 3 ++- 5 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/key/key.js b/src/key/key.js index 43154a88..3c7475ad 100644 --- a/src/key/key.js +++ b/src/key/key.js @@ -259,6 +259,11 @@ class Key { async getSigningKey(keyID = null, date = new Date(), userID = {}, config = defaultConfig) { await this.verifyPrimaryKey(date, userID, config); const primaryKey = this.keyPacket; + try { + helper.checkKeyRequirements(primaryKey, config); + } catch (err) { + throw util.wrapError('Could not verify primary key', err); + } const subkeys = this.subkeys.slice().sort((a, b) => b.keyPacket.created - a.keyPacket.created); let exception; for (const subkey of subkeys) { @@ -313,6 +318,11 @@ class Key { async getEncryptionKey(keyID, date = new Date(), userID = {}, config = defaultConfig) { await this.verifyPrimaryKey(date, userID, config); const primaryKey = this.keyPacket; + try { + helper.checkKeyRequirements(primaryKey, config); + } catch (err) { + throw util.wrapError('Could not verify primary key', err); + } // V4: by convention subkeys are preferred for encryption service const subkeys = this.subkeys.slice().sort((a, b) => b.keyPacket.created - a.keyPacket.created); let exception; diff --git a/test/general/config.js b/test/general/config.js index 34e8a1fa..c9080ea0 100644 --- a/test/general/config.js +++ b/test/general/config.js @@ -300,10 +300,25 @@ n9/quqtmyOtYOA6gXNCw0Fal3iANKBmsPmYI message, encryptionKeys: [key], config: { rejectCurves: new Set([openpgp.enums.curve.curve25519Legacy]) } })).to.be.eventually.rejectedWith(/Support for ecdh keys using curve curve25519Legacy is disabled/); - const echdEncrypted = await openpgp.encrypt({ + await expect(openpgp.encrypt({ message, encryptionKeys: [key], config: { rejectCurves: new Set([openpgp.enums.curve.ed25519Legacy]) } - }); - expect(echdEncrypted).to.match(/---BEGIN PGP MESSAGE---/); + })).to.be.eventually.rejectedWith(/Could not verify primary key: Support for eddsaLegacy keys using curve ed25519Legacy is disabled/); + + // RSA 512 bits primary key, ECC subkey + const weakPrimaryKey = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PUBLIC KEY BLOCK----- + +xk0EZbuUkQECAOVRTj4yGjMTk94lHaJGJZpwAnPJzSLr0lsqRzbsaeL+JeUr +HtKQyv8wEnqN0o7j39DXdFBI8f2/T0DkC4gkbQsAEQEAAc0OPHRlc3RAdGVz +dC5pdD7CiwQQAQgAPwWCZbuUkQMLCQcJkL/AJzZtSewrBRUICgwOBBYAAgEC +GQECmwMCHgEWIQSUuxkscrvIncEIj8K/wCc2bUnsKwAABpYCAMsq3UDscj6W +IVz8+VubCuJma95dgMXjqDGd2XGLUthYzKQ+k0USut3nwrt5aJOiQGse7W9O +Mjr/KnRCNGrJdm7OOARlu5SREgorBgEEAZdVAQUBAQdAkDQHPjXorB969PXZ +p09HqVCOqcOAzKi4KLL7I3QosmsDAQgHwnYEGAEIACoFgmW7lJEJkL/AJzZt +SewrApsMFiEElLsZLHK7yJ3BCI/Cv8AnNm1J7CsAAJ6VAf9uBYUWIM2LFx1L +c1HGHD56KA0Mu4eQksKNEugotEyBuWiZCVO+LBrDUFztC1IwXaNPL3bCjYaD +5f5A+c8qOY1f +-----END PGP PUBLIC KEY BLOCK-----` }); + await expect(openpgp.encrypt({ message, encryptionKeys: weakPrimaryKey, config: { minRSABits: 2048 } })).to.be.rejectedWith(/Could not verify primary key: RSA keys shorter than 2048 bits are considered too weak./); } finally { openpgp.config.aeadProtect = aeadProtectVal; openpgp.config.preferredCompressionAlgorithm = preferredCompressionAlgorithmVal; diff --git a/test/general/key.js b/test/general/key.js index 6a9668da..5e20a31e 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -4284,11 +4284,9 @@ VYGdb3eNlV8CfoEC it('Reject encryption with key revoked with appended revocation cert', async function() { const key = await openpgp.readKey({ armoredKey: pub_revoked_with_cert }); - return openpgp.encrypt({ encryptionKeys: [key], message: await openpgp.createMessage({ text: 'random data' }) }).then(() => { - throw new Error('encryptSessionKey should not encrypt with revoked public key'); - }).catch(function(error) { - expect(error.message).to.equal('Error encrypting message: Primary key is revoked'); - }); + await expect( + openpgp.encrypt({ encryptionKeys: [key], message: await openpgp.createMessage({ text: 'random data' }) }) + ).to.be.rejectedWith(/Primary key is revoked/); }); it('Merge key with another key with non-ID user attributes', async function() { diff --git a/test/general/openpgp.js b/test/general/openpgp.js index 90b70fe5..6c1e7903 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -3990,7 +3990,7 @@ XfA3pqV4mTzF }).then(function() { throw new Error('Should not encrypt with revoked key'); }).catch(function(error) { - expect(error.message).to.match(/Error encrypting message: Primary key is revoked/); + expect(error.message).to.match(/Primary key is revoked/); }); }); }); diff --git a/test/general/signature.js b/test/general/signature.js index 01a3a0c0..a66b71b5 100644 --- a/test/general/signature.js +++ b/test/general/signature.js @@ -895,7 +895,8 @@ DQmhI0SZoTKy4EGhS0bNJ+g2+dJ8Y22fKzLWXwo= await expect(openpgp.sign({ signingKeys: key, date: new Date(key.keyPacket.created - 3600), - message: await openpgp.createMessage({ text: 'Hello World' }) + message: await openpgp.createMessage({ text: 'Hello World' }), + config: { minRSABits: 1024 } })).to.be.rejectedWith(/Signature creation time is in the future/); }); From 3320eaccb2ad78955dfd01a9a0fcdb5f2accd1d3 Mon Sep 17 00:00:00 2001 From: larabr Date: Fri, 2 Feb 2024 15:04:34 +0100 Subject: [PATCH 102/201] Relax constraints for UserID email address validity (#1641) New checks align with the HTML5 W3C spec and should be more lax than the existing ones (meaning, addresses which passed validation before should continue to be valid). Addresses such as `@localhost` are now allowed too, since presence of "." is no longer enforced. These checks should not be considered exhaustive: library users are encouraged to implement separate checks for email validity if needed. Co-authored-by: Daniel Huigens --- src/util.js | 8 +++++++- test/general/openpgp.js | 10 +--------- test/general/util.js | 18 +++++++++++------- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/util.js b/src/util.js index 0a1c721d..188a86fa 100644 --- a/src/util.js +++ b/src/util.js @@ -457,11 +457,17 @@ const util = { return os.cpus().length; }, + /** + * Test email format based on W3C HTML5 specification. + * This check is not exaustive, and does not match RFC 5322 exactly + * (see https://html.spec.whatwg.org/multipage/input.html#email-state-(type=email)), + * but is commonly used for email address validation. + */ isEmailAddress: function(data) { if (!util.isString(data)) { return false; } - const re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+([a-zA-Z]{2,}[0-9]*|xn--[a-zA-Z\-0-9]+)))$/; + const re = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/; return re.test(data); }, diff --git a/test/general/openpgp.js b/test/general/openpgp.js index 6c1e7903..49cc76b1 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -958,7 +958,7 @@ export default () => describe('OpenPGP.js public api tests', function() { await expect(test).to.eventually.be.rejectedWith(/Invalid user ID format/); }); - it('should fail for invalid user email address', async function() { + it('should fail for invalid user email address (missing @)', async function() { const opt = { userIDs: [{ name: 'Test User', email: 'textexample.com' }] }; @@ -966,14 +966,6 @@ export default () => describe('OpenPGP.js public api tests', function() { await expect(test).to.eventually.be.rejectedWith(/Invalid user ID format/); }); - it('should fail for invalid user email address', async function() { - const opt = { - userIDs: [{ name: 'Test User', email: 'text@examplecom' }] - }; - const test = openpgp.generateKey(opt); - await expect(test).to.eventually.be.rejectedWith(/Invalid user ID format/); - }); - it('should fail for string user ID', async function() { const opt = { userIDs: 'Test User ' diff --git a/test/general/util.js b/test/general/util.js index 25dab192..c17b88c8 100644 --- a/test/general/util.js +++ b/test/general/util.js @@ -108,19 +108,23 @@ export default () => describe('Util unit tests', function() { const data = 'test@example.com'; expect(util.isEmailAddress(data)).to.be.true; }); - it('should return true for valid email address', function() { + it('should return true for valid email address (internationalized domain name)', function() { const data = 'test@xn--wgv.xn--q9jyb4c'; expect(util.isEmailAddress(data)).to.be.true; }); - it('should return false for invalid email address', function() { + it('should return true for valid email address (trailing numbers in domain)', function() { + const data = 'test1@com.com09'; + expect(util.isEmailAddress(data)).to.be.true; + }); + it('should return true for valid email address (no . in domain part)', function() { + const data = 'test@localhost'; + expect(util.isEmailAddress(data)).to.be.true; + }); + it('should return false for invalid email address (full userID)', function() { const data = 'Test User '; expect(util.isEmailAddress(data)).to.be.false; }); - it('should return false for invalid email address', function() { - const data = 'test@examplecom'; - expect(util.isEmailAddress(data)).to.be.false; - }); - it('should return false for invalid email address', function() { + it('should return false for invalid email address (missing @)', function() { const data = 'testexamplecom'; expect(util.isEmailAddress(data)).to.be.false; }); From 280828dae65b0b5aae923510049fe4da8c471333 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Tue, 6 Feb 2024 15:41:40 +0100 Subject: [PATCH 103/201] Throw if WebCrypto API is not available It was already required, this simply makes errors more clear. --- src/crypto/hkdf.js | 6 ++---- src/util.js | 13 ++++++++++--- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/crypto/hkdf.js b/src/crypto/hkdf.js index 91ff9a2e..361703b1 100644 --- a/src/crypto/hkdf.js +++ b/src/crypto/hkdf.js @@ -7,14 +7,12 @@ import enums from '../enums'; import util from '../util'; const webCrypto = util.getWebCrypto(); -const nodeCrypto = util.getNodeCrypto(); export default async function computeHKDF(hashAlgo, inputKey, salt, info, outLen) { const hash = enums.read(enums.webHash, hashAlgo); if (!hash) throw new Error('Hash algo not supported with HKDF'); - const crypto = webCrypto || nodeCrypto.webcrypto.subtle; - const importedKey = await crypto.importKey('raw', inputKey, 'HKDF', false, ['deriveBits']); - const bits = await crypto.deriveBits({ name: 'HKDF', hash, salt, info }, importedKey, outLen * 8); + const importedKey = await webCrypto.importKey('raw', inputKey, 'HKDF', false, ['deriveBits']); + const bits = await webCrypto.deriveBits({ name: 'HKDF', hash, salt, info }, importedKey, outLen * 8); return new Uint8Array(bits); } diff --git a/src/util.js b/src/util.js index 188a86fa..47363c97 100644 --- a/src/util.js +++ b/src/util.js @@ -420,11 +420,18 @@ const util = { }, /** - * Get native Web Cryptography api, only the current version of the spec. - * @returns {Object} The SubtleCrypto api or 'undefined'. + * Get native Web Cryptography API. + * @returns {Object} The SubtleCrypto API + * @throws if the API is not available */ getWebCrypto: function() { - return typeof globalThis !== 'undefined' && globalThis.crypto && globalThis.crypto.subtle; + const globalWebCrypto = typeof globalThis !== 'undefined' && globalThis.crypto && globalThis.crypto.subtle; + // Fallback for Node 16, which does not expose WebCrypto as a global + const webCrypto = globalWebCrypto || this.getNodeCrypto()?.webcrypto.subtle; + if (!webCrypto) { + throw new Error('The WebCrypto API is not available'); + } + return webCrypto; }, /** From b413a113f99cfce602e192adb467680e31081777 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Mon, 12 Feb 2024 13:53:46 +0100 Subject: [PATCH 104/201] CI: update actions to Node 20 --- .github/workflows/benchmark.yml | 6 +++--- .github/workflows/docs.yml | 4 ++-- .github/workflows/sop-test-suite.yml | 8 ++++---- .github/workflows/tests.yml | 24 ++++++++++++------------ 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 70eff19f..81f6145f 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -11,15 +11,15 @@ jobs: steps: # check out pull request branch - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: path: pr # check out main branch (to compare performance) - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: ref: main path: main - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: '>=20.6.0' diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index b0bc6afd..a8b7941c 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 - run: npm ci --ignore-scripts - run: npm run docs diff --git a/.github/workflows/sop-test-suite.yml b/.github/workflows/sop-test-suite.yml index cf1701b4..bd336dbf 100644 --- a/.github/workflows/sop-test-suite.yml +++ b/.github/workflows/sop-test-suite.yml @@ -16,10 +16,10 @@ jobs: password: ${{ secrets.github_token }} steps: # check out repo for scripts - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 # check out pull request branch - name: Checkout openpgpjs-branch - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: path: openpgpjs-branch - name: Install openpgpjs-branch @@ -30,7 +30,7 @@ jobs: OPENPGPJS_PATH: ${{ github.workspace }}/openpgpjs-branch # check out main branch - name: Checkout openpgpjs-main - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: ref: main path: openpgpjs-main @@ -72,7 +72,7 @@ jobs: needs: test-suite steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Download test results json artifact id: download-test-results uses: actions/download-artifact@v3 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 53feed35..cd4ce7ab 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -11,8 +11,8 @@ jobs: name: Build runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 - name: Check for cached folders id: cache-full uses: actions/cache@v3 @@ -38,8 +38,8 @@ jobs: runs-on: ubuntu-latest needs: build steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} - run: npm ci --ignore-scripts # for mocha @@ -61,8 +61,8 @@ jobs: needs: build steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 - name: Retrieve cached built folders uses: actions/cache/restore@v3 @@ -116,8 +116,8 @@ jobs: BROWSERSTACK_ACCESS_KEY: VjgBVRMxNVBj7SjJFiau steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 - name: Install dependencies run: npm ci --ignore-scripts @@ -154,8 +154,8 @@ jobs: needs: build steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 - run: npm ci --ignore-scripts # TS - name: Retrieve cached folders uses: actions/cache/restore@v3 @@ -173,8 +173,8 @@ jobs: needs: build steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 - run: npm ci --ignore-scripts # linter - name: Retrieve cached folders uses: actions/cache/restore@v3 From db15f6d6a16430b4f1723dae981d121bf6409474 Mon Sep 17 00:00:00 2001 From: larabr Date: Mon, 26 Feb 2024 15:37:50 +0100 Subject: [PATCH 105/201] Import legacy ciphers (CAST5, TwoFish, BlowFish, DES) only on demand (#1723) This primarily affects the lightweight build, which will not include these (fairly large) modules in the main bundle file. --- src/crypto/aes_kw.js | 12 +- src/crypto/cipher/getCipher.js | 13 -- src/crypto/cipher/index.js | 137 +++++++++--------- src/crypto/cipher/legacy_ciphers.js | 17 +++ src/crypto/crypto.js | 11 +- src/crypto/mode/cfb.js | 10 +- src/crypto/mode/ocb.js | 11 +- src/crypto/public_key/elliptic/ecdh.js | 10 +- src/crypto/public_key/elliptic/ecdh_x.js | 22 +-- src/packet/secret_key.js | 6 +- .../sym_encrypted_integrity_protected_data.js | 6 +- src/packet/sym_encrypted_session_key.js | 4 +- src/packet/symmetrically_encrypted_data.js | 4 +- test/crypto/aes_kw.js | 21 ++- test/crypto/cipher/aes.js | 21 ++- test/crypto/crypto.js | 2 +- 16 files changed, 158 insertions(+), 149 deletions(-) delete mode 100644 src/crypto/cipher/getCipher.js create mode 100644 src/crypto/cipher/legacy_ciphers.js diff --git a/src/crypto/aes_kw.js b/src/crypto/aes_kw.js index e747ecc3..dcd116d7 100644 --- a/src/crypto/aes_kw.js +++ b/src/crypto/aes_kw.js @@ -21,7 +21,7 @@ * @module crypto/aes_kw */ -import * as cipher from './cipher'; +import { getCipher } from './cipher'; import util from '../util'; /** @@ -31,8 +31,9 @@ import util from '../util'; * @param {Uint8Array} data * @returns {Uint8Array} */ -export function wrap(key, data) { - const aes = new cipher['aes' + (key.length * 8)](key); +export async function wrap(algo, key, data) { + const Cipher = await getCipher(algo); + const aes = new Cipher(key); const IV = new Uint32Array([0xA6A6A6A6, 0xA6A6A6A6]); const P = unpack(data); let A = IV; @@ -71,8 +72,9 @@ export function wrap(key, data) { * @returns {Uint8Array} * @throws {Error} */ -export function unwrap(key, data) { - const aes = new cipher['aes' + (key.length * 8)](key); +export async function unwrap(algo, key, data) { + const Cipher = await getCipher(algo); + const aes = new Cipher(key); const IV = new Uint32Array([0xA6A6A6A6, 0xA6A6A6A6]); const C = unpack(data); let A = C.subarray(0, 2); diff --git a/src/crypto/cipher/getCipher.js b/src/crypto/cipher/getCipher.js deleted file mode 100644 index a74ef75a..00000000 --- a/src/crypto/cipher/getCipher.js +++ /dev/null @@ -1,13 +0,0 @@ -import * as cipher from '.'; -import enums from '../../enums'; - -/** - * Get implementation of the given cipher - * @param {enums.symmetric} algo - * @returns {Object} - * @throws {Error} on invalid algo - */ -export default function getCipher(algo) { - const algoName = enums.read(enums.symmetric, algo); - return cipher[algoName]; -} diff --git a/src/crypto/cipher/index.js b/src/crypto/cipher/index.js index d40c8e08..878b05c0 100644 --- a/src/crypto/cipher/index.js +++ b/src/crypto/cipher/index.js @@ -1,80 +1,73 @@ -/** - * @fileoverview Symmetric cryptography functions - * @module crypto/cipher - */ +import aes from './aes'; // can be imported dynamically once Web Crypto is used for AES-KW too +import enums from '../../enums'; -import aes from './aes'; -import { DES, TripleDES } from './des'; -import CAST5 from './cast5'; -import TF from './twofish'; -import BF from './blowfish'; +export async function getCipher(algo) { + switch (algo) { + case enums.symmetric.aes128: + case enums.symmetric.aes192: + case enums.symmetric.aes256: + return aes(getCipherKeySize(algo)); + case enums.symmetric.cast5: + case enums.symmetric.blowfish: + case enums.symmetric.twofish: + case enums.symmetric.tripledes: { + const { legacyCiphers } = await import('./legacy_ciphers'); + const cipher = legacyCiphers.get(algo); + if (!cipher) { + throw new Error('Unsupported cipher algorithm'); + } + return cipher; + } + default: + throw new Error('Unsupported cipher algorithm'); + } +} /** - * AES-128 encryption and decryption (ID 7) - * @function - * @param {String} key - 128-bit key - * @see {@link https://github.com/asmcrypto/asmcrypto.js|asmCrypto} - * @see {@link https://csrc.nist.gov/publications/fips/fips197/fips-197.pdf|NIST FIPS-197} - * @returns {Object} + * Get block size for given cipher algo + * @param {module:enums.symmetric} algo - alrogithm identifier */ -export const aes128 = aes(128); +function getCipherBlockSize(algo) { + switch (algo) { + case enums.symmetric.aes128: + case enums.symmetric.aes192: + case enums.symmetric.aes256: + case enums.symmetric.twofish: + return 16; + case enums.symmetric.blowfish: + case enums.symmetric.cast5: + case enums.symmetric.tripledes: + return 8; + default: + throw new Error('Unsupported cipher'); + } +} + /** - * AES-128 Block Cipher (ID 8) - * @function - * @param {String} key - 192-bit key - * @see {@link https://github.com/asmcrypto/asmcrypto.js|asmCrypto} - * @see {@link https://csrc.nist.gov/publications/fips/fips197/fips-197.pdf|NIST FIPS-197} - * @returns {Object} + * Get key size for given cipher algo + * @param {module:enums.symmetric} algo - alrogithm identifier */ -export const aes192 = aes(192); +function getCipherKeySize(algo) { + switch (algo) { + case enums.symmetric.aes128: + case enums.symmetric.blowfish: + case enums.symmetric.cast5: + return 16; + case enums.symmetric.aes192: + case enums.symmetric.tripledes: + return 24; + case enums.symmetric.aes256: + case enums.symmetric.twofish: + return 32; + default: + throw new Error('Unsupported cipher'); + } +} + /** - * AES-128 Block Cipher (ID 9) - * @function - * @param {String} key - 256-bit key - * @see {@link https://github.com/asmcrypto/asmcrypto.js|asmCrypto} - * @see {@link https://csrc.nist.gov/publications/fips/fips197/fips-197.pdf|NIST FIPS-197} - * @returns {Object} + * Get block and key size for given cipher algo + * @param {module:enums.symmetric} algo - alrogithm identifier */ -export const aes256 = aes(256); -// Not in OpenPGP specifications -export const des = DES; -/** - * Triple DES Block Cipher (ID 2) - * @function - * @param {String} key - 192-bit key - * @see {@link https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-67r2.pdf|NIST SP 800-67} - * @returns {Object} - */ -export const tripledes = TripleDES; -/** - * CAST-128 Block Cipher (ID 3) - * @function - * @param {String} key - 128-bit key - * @see {@link https://tools.ietf.org/html/rfc2144|The CAST-128 Encryption Algorithm} - * @returns {Object} - */ -export const cast5 = CAST5; -/** - * Twofish Block Cipher (ID 10) - * @function - * @param {String} key - 256-bit key - * @see {@link https://tools.ietf.org/html/rfc4880#ref-TWOFISH|TWOFISH} - * @returns {Object} - */ -export const twofish = TF; -/** - * Blowfish Block Cipher (ID 4) - * @function - * @param {String} key - 128-bit key - * @see {@link https://tools.ietf.org/html/rfc4880#ref-BLOWFISH|BLOWFISH} - * @returns {Object} - */ -export const blowfish = BF; -/** - * Not implemented - * @function - * @throws {Error} - */ -export const idea = function() { - throw new Error('IDEA symmetric-key algorithm not implemented'); -}; +export function getCipherParams(algo) { + return { keySize: getCipherKeySize(algo), blockSize: getCipherBlockSize(algo) }; +} diff --git a/src/crypto/cipher/legacy_ciphers.js b/src/crypto/cipher/legacy_ciphers.js new file mode 100644 index 00000000..f091d471 --- /dev/null +++ b/src/crypto/cipher/legacy_ciphers.js @@ -0,0 +1,17 @@ +/** + * This file is needed to dynamic import the legacy ciphers. + * Separate dynamic imports are not convenient as they result in multiple chunks. + */ + +import { TripleDES } from './des'; +import CAST5 from './cast5'; +import TwoFish from './twofish'; +import BlowFish from './blowfish'; +import enums from '../../enums'; + +export const legacyCiphers = new Map([ + [enums.symmetric.tripledes, TripleDES], + [enums.symmetric.cast5, CAST5], + [enums.symmetric.blowfish, BlowFish], + [enums.symmetric.twofish, TwoFish] +]); diff --git a/src/crypto/crypto.js b/src/crypto/crypto.js index f24c4a74..486c4c11 100644 --- a/src/crypto/crypto.js +++ b/src/crypto/crypto.js @@ -26,7 +26,7 @@ import publicKey from './public_key'; import mode from './mode'; import { getRandomBytes } from './random'; -import getCipher from './cipher/getCipher'; +import { getCipher, getCipherParams } from './cipher'; import ECDHSymkey from '../type/ecdh_symkey'; import KDFParams from '../type/kdf_params'; import enums from '../enums'; @@ -442,7 +442,7 @@ export async function validateParams(algo, publicParams, privateParams) { * @async */ export async function getPrefixRandom(algo) { - const { blockSize } = getCipher(algo); + const { blockSize } = getCipherParams(algo); const prefixrandom = await getRandomBytes(blockSize); const repeat = new Uint8Array([prefixrandom[prefixrandom.length - 2], prefixrandom[prefixrandom.length - 1]]); return util.concat([prefixrandom, repeat]); @@ -455,7 +455,7 @@ export async function getPrefixRandom(algo) { * @returns {Uint8Array} Random bytes as a string to be used as a key. */ export function generateSessionKey(algo) { - const { keySize } = getCipher(algo); + const { keySize } = getCipherParams(algo); return getRandomBytes(keySize); } @@ -470,8 +470,6 @@ export function getAEADMode(algo) { return mode[algoName]; } -export { getCipher }; - /** * Check whether the given curve OID is supported * @param {module:type/oid} oid - EC object identifier @@ -524,3 +522,6 @@ export function getPreferredCurveHashAlgo(algo, oid) { throw new Error('Unknown elliptic signing algo'); } } + + +export { getCipher, getCipherParams }; diff --git a/src/crypto/mode/cfb.js b/src/crypto/mode/cfb.js index 6fce90c1..30fea08b 100644 --- a/src/crypto/mode/cfb.js +++ b/src/crypto/mode/cfb.js @@ -23,9 +23,9 @@ import { AES_CFB } from '@openpgp/asmcrypto.js/aes/cfb.js'; import * as stream from '@openpgp/web-stream-tools'; -import getCipher from '../cipher/getCipher'; import util from '../../util'; import enums from '../../enums'; +import { getCipher, getCipherParams } from '../cipher'; const webCrypto = util.getWebCrypto(); const nodeCrypto = util.getNodeCrypto(); @@ -60,7 +60,7 @@ export async function encrypt(algo, key, plaintext, iv, config) { return aesEncrypt(algo, key, plaintext, iv, config); } - const Cipher = getCipher(algo); + const Cipher = await getCipher(algo); const cipherfn = new Cipher(key); const block_size = cipherfn.blockSize; @@ -103,7 +103,7 @@ export async function decrypt(algo, key, ciphertext, iv) { return aesDecrypt(algo, key, ciphertext, iv); } - const Cipher = getCipher(algo); + const Cipher = await getCipher(algo); const cipherfn = new Cipher(key); const block_size = cipherfn.blockSize; @@ -131,7 +131,7 @@ export async function decrypt(algo, key, ciphertext, iv) { class WebCryptoEncryptor { constructor(algo, key, iv) { - const { blockSize } = getCipher(algo); + const { blockSize } = getCipherParams(algo); this.key = key; this.prevBlock = iv; this.nextBlock = new Uint8Array(blockSize); @@ -141,7 +141,7 @@ class WebCryptoEncryptor { } static async isSupported(algo) { - const { keySize } = getCipher(algo); + const { keySize } = getCipherParams(algo); return webCrypto.importKey('raw', new Uint8Array(keySize), 'aes-cbc', false, ['encrypt']) .then(() => true, () => false); } diff --git a/src/crypto/mode/ocb.js b/src/crypto/mode/ocb.js index 3cd1926c..7c60921a 100644 --- a/src/crypto/mode/ocb.js +++ b/src/crypto/mode/ocb.js @@ -20,9 +20,8 @@ * @module crypto/mode/ocb */ -import * as ciphers from '../cipher'; +import { getCipher } from '../cipher'; import util from '../../util'; -import enums from '../../enums'; const blockLength = 16; const ivLength = 15; @@ -68,11 +67,11 @@ async function OCB(cipher, key) { let decipher; let mask; - constructKeyVariables(cipher, key); + await constructKeyVariables(cipher, key); - function constructKeyVariables(cipher, key) { - const cipherName = enums.read(enums.symmetric, cipher); - const aes = new ciphers[cipherName](key); + async function constructKeyVariables(cipher, key) { + const Cipher = await getCipher(cipher); + const aes = new Cipher(key); encipher = aes.encrypt.bind(aes); decipher = aes.decrypt.bind(aes); diff --git a/src/crypto/public_key/elliptic/ecdh.js b/src/crypto/public_key/elliptic/ecdh.js index cc4d3952..8bd03f82 100644 --- a/src/crypto/public_key/elliptic/ecdh.js +++ b/src/crypto/public_key/elliptic/ecdh.js @@ -29,7 +29,7 @@ import enums from '../../../enums'; import util from '../../../util'; import { b64ToUint8Array } from '../../../encoding/base64'; import * as pkcs5 from '../../pkcs5'; -import getCipher from '../../cipher/getCipher'; +import { getCipherParams } from '../../cipher'; const webCrypto = util.getWebCrypto(); const nodeCrypto = util.getNodeCrypto(); @@ -133,9 +133,9 @@ export async function encrypt(oid, kdfParams, data, Q, fingerprint) { const curve = new CurveWithOID(oid); const { publicKey, sharedKey } = await genPublicEphemeralKey(curve, Q); const param = buildEcdhParam(enums.publicKey.ecdh, oid, kdfParams, fingerprint); - const { keySize } = getCipher(kdfParams.cipher); + const { keySize } = getCipherParams(kdfParams.cipher); const Z = await kdf(kdfParams.hash, sharedKey, keySize, param); - const wrappedKey = aesKW.wrap(Z, m); + const wrappedKey = await aesKW.wrap(kdfParams.cipher, Z, m); return { publicKey, wrappedKey }; } @@ -195,13 +195,13 @@ export async function decrypt(oid, kdfParams, V, C, Q, d, fingerprint) { const curve = new CurveWithOID(oid); const { sharedKey } = await genPrivateEphemeralKey(curve, V, Q, d); const param = buildEcdhParam(enums.publicKey.ecdh, oid, kdfParams, fingerprint); - const { keySize } = getCipher(kdfParams.cipher); + const { keySize } = getCipherParams(kdfParams.cipher); let err; for (let i = 0; i < 3; i++) { try { // Work around old go crypto bug and old OpenPGP.js bug, respectively. const Z = await kdf(kdfParams.hash, sharedKey, keySize, param, i === 1, i === 2); - return pkcs5.decode(aesKW.unwrap(Z, C)); + return pkcs5.decode(await aesKW.unwrap(kdfParams.cipher, Z, C)); } catch (e) { err = e; } diff --git a/src/crypto/public_key/elliptic/ecdh_x.js b/src/crypto/public_key/elliptic/ecdh_x.js index a517e88a..641af020 100644 --- a/src/crypto/public_key/elliptic/ecdh_x.js +++ b/src/crypto/public_key/elliptic/ecdh_x.js @@ -9,8 +9,8 @@ import { getRandomBytes } from '../../random'; import enums from '../../../enums'; import util from '../../../util'; -import getCipher from '../../cipher/getCipher'; import computeHKDF from '../../hkdf'; +import { getCipherParams } from '../../cipher'; const HKDF_INFO = { x25519: util.encodeUTF8('OpenPGP X25519'), @@ -97,9 +97,10 @@ export async function encrypt(algo, data, recipientA) { recipientA, sharedSecret ]); - const { keySize } = getCipher(enums.symmetric.aes128); + const cipherAlgo = enums.symmetric.aes128; + const { keySize } = getCipherParams(cipherAlgo); const encryptionKey = await computeHKDF(enums.hash.sha256, hkdfInput, new Uint8Array(), HKDF_INFO.x25519, keySize); - const wrappedKey = aesKW.wrap(encryptionKey, data); + const wrappedKey = await aesKW.wrap(cipherAlgo, encryptionKey, data); return { ephemeralPublicKey, wrappedKey }; } case enums.publicKey.x448: { @@ -112,9 +113,10 @@ export async function encrypt(algo, data, recipientA) { recipientA, sharedSecret ]); - const { keySize } = getCipher(enums.symmetric.aes256); + const cipherAlgo = enums.symmetric.aes256; + const { keySize } = getCipherParams(enums.symmetric.aes256); const encryptionKey = await computeHKDF(enums.hash.sha512, hkdfInput, new Uint8Array(), HKDF_INFO.x448, keySize); - const wrappedKey = aesKW.wrap(encryptionKey, data); + const wrappedKey = await aesKW.wrap(cipherAlgo, encryptionKey, data); return { ephemeralPublicKey, wrappedKey }; } @@ -143,9 +145,10 @@ export async function decrypt(algo, ephemeralPublicKey, wrappedKey, A, k) { A, sharedSecret ]); - const { keySize } = getCipher(enums.symmetric.aes128); + const cipherAlgo = enums.symmetric.aes128; + const { keySize } = getCipherParams(cipherAlgo); const encryptionKey = await computeHKDF(enums.hash.sha256, hkdfInput, new Uint8Array(), HKDF_INFO.x25519, keySize); - return aesKW.unwrap(encryptionKey, wrappedKey); + return aesKW.unwrap(cipherAlgo, encryptionKey, wrappedKey); } case enums.publicKey.x448: { const x448 = await util.getNobleCurve(enums.publicKey.x448); @@ -155,9 +158,10 @@ export async function decrypt(algo, ephemeralPublicKey, wrappedKey, A, k) { A, sharedSecret ]); - const { keySize } = getCipher(enums.symmetric.aes256); + const cipherAlgo = enums.symmetric.aes256; + const { keySize } = getCipherParams(enums.symmetric.aes256); const encryptionKey = await computeHKDF(enums.hash.sha512, hkdfInput, new Uint8Array(), HKDF_INFO.x448, keySize); - return aesKW.unwrap(encryptionKey, wrappedKey); + return aesKW.unwrap(cipherAlgo, encryptionKey, wrappedKey); } default: throw new Error('Unsupported ECDH algorithm'); diff --git a/src/packet/secret_key.js b/src/packet/secret_key.js index a80feba7..2cdac5b6 100644 --- a/src/packet/secret_key.js +++ b/src/packet/secret_key.js @@ -174,7 +174,7 @@ class SecretKeyPacket extends PublicKeyPacket { if (this.s2kUsage !== 253 || this.isLegacyAEAD) { this.iv = bytes.subarray( i, - i + crypto.getCipher(this.symmetric).blockSize + i + crypto.getCipherParams(this.symmetric).blockSize ); this.usedModernAEAD = false; } else { @@ -388,7 +388,7 @@ class SecretKeyPacket extends PublicKeyPacket { const cleartext = crypto.serializeParams(this.algorithm, this.privateParams); this.symmetric = enums.symmetric.aes256; - const { blockSize } = crypto.getCipher(this.symmetric); + const { blockSize } = crypto.getCipherParams(this.symmetric); if (config.aeadProtect) { this.s2kUsage = 253; @@ -568,7 +568,7 @@ class SecretKeyPacket extends PublicKeyPacket { * @returns encryption key */ async function produceEncryptionKey(keyVersion, s2k, passphrase, cipherAlgo, aeadMode, serializedPacketTag, isLegacyAEAD) { - const { keySize } = crypto.getCipher(cipherAlgo); + const { keySize } = crypto.getCipherParams(cipherAlgo); const derivedKey = await s2k.produceKey(passphrase, keySize); if (!aeadMode || keyVersion === 5 || isLegacyAEAD) { return derivedKey; diff --git a/src/packet/sym_encrypted_integrity_protected_data.js b/src/packet/sym_encrypted_integrity_protected_data.js index f7c70646..764c0f6a 100644 --- a/src/packet/sym_encrypted_integrity_protected_data.js +++ b/src/packet/sym_encrypted_integrity_protected_data.js @@ -138,7 +138,7 @@ class SymEncryptedIntegrityProtectedDataPacket { this.chunkSizeByte = config.aeadChunkSizeByte; this.encrypted = await runAEAD(this, 'encrypt', key, bytes); } else { - const { blockSize } = crypto.getCipher(sessionKeyAlgorithm); + const { blockSize } = crypto.getCipherParams(sessionKeyAlgorithm); const prefix = await crypto.getPrefixRandom(sessionKeyAlgorithm); const mdc = new Uint8Array([0xD3, 0x14]); // modification detection code packet @@ -169,7 +169,7 @@ class SymEncryptedIntegrityProtectedDataPacket { if (this.version === 2) { packetbytes = await runAEAD(this, 'decrypt', key, encrypted); } else { - const { blockSize } = crypto.getCipher(sessionKeyAlgorithm); + const { blockSize } = crypto.getCipherParams(sessionKeyAlgorithm); const decrypted = await crypto.mode.cfb.decrypt(sessionKeyAlgorithm, key, encrypted, new Uint8Array(blockSize)); // there must be a modification detection code packet as the @@ -231,7 +231,7 @@ export async function runAEAD(packet, fn, key, data) { let iv; let ivView; if (isSEIPDv2) { - const { keySize } = crypto.getCipher(packet.cipherAlgorithm); + const { keySize } = crypto.getCipherParams(packet.cipherAlgorithm); const { ivLength } = mode; const info = new Uint8Array(adataBuffer, 0, 5); const derived = await computeHKDF(enums.hash.sha256, key, packet.salt, info, keySize + ivLength); diff --git a/src/packet/sym_encrypted_session_key.js b/src/packet/sym_encrypted_session_key.js index 2dcfea54..464be72e 100644 --- a/src/packet/sym_encrypted_session_key.js +++ b/src/packet/sym_encrypted_session_key.js @@ -163,7 +163,7 @@ class SymEncryptedSessionKeyPacket { this.sessionKeyEncryptionAlgorithm : this.sessionKeyAlgorithm; - const { blockSize, keySize } = crypto.getCipher(algo); + const { blockSize, keySize } = crypto.getCipherParams(algo); const key = await this.s2k.produceKey(passphrase, keySize); if (this.version >= 5) { @@ -199,7 +199,7 @@ class SymEncryptedSessionKeyPacket { this.s2k = newS2KFromConfig(config); this.s2k.generateSalt(); - const { blockSize, keySize } = crypto.getCipher(algo); + const { blockSize, keySize } = crypto.getCipherParams(algo); const key = await this.s2k.produceKey(passphrase, keySize); if (this.sessionKey === null) { diff --git a/src/packet/symmetrically_encrypted_data.js b/src/packet/symmetrically_encrypted_data.js index ff4fd3d3..41e3cae7 100644 --- a/src/packet/symmetrically_encrypted_data.js +++ b/src/packet/symmetrically_encrypted_data.js @@ -86,7 +86,7 @@ class SymmetricallyEncryptedDataPacket { throw new Error('Message is not authenticated.'); } - const { blockSize } = crypto.getCipher(sessionKeyAlgorithm); + const { blockSize } = crypto.getCipherParams(sessionKeyAlgorithm); const encrypted = await stream.readToEnd(stream.clone(this.encrypted)); const decrypted = await crypto.mode.cfb.decrypt(sessionKeyAlgorithm, key, encrypted.subarray(blockSize + 2), @@ -107,7 +107,7 @@ class SymmetricallyEncryptedDataPacket { */ async encrypt(sessionKeyAlgorithm, key, config = defaultConfig) { const data = this.packets.write(); - const { blockSize } = crypto.getCipher(sessionKeyAlgorithm); + const { blockSize } = crypto.getCipherParams(sessionKeyAlgorithm); const prefix = await crypto.getPrefixRandom(sessionKeyAlgorithm); const FRE = await crypto.mode.cfb.encrypt(sessionKeyAlgorithm, key, prefix, new Uint8Array(blockSize), config); diff --git a/test/crypto/aes_kw.js b/test/crypto/aes_kw.js index 1a3b04c4..7c7cb60b 100644 --- a/test/crypto/aes_kw.js +++ b/test/crypto/aes_kw.js @@ -2,41 +2,48 @@ import { expect } from 'chai'; import * as aesKW from '../../src/crypto/aes_kw.js'; import util from '../../src/util.js'; +import enums from '../../src/enums.js'; export default () => describe('AES Key Wrap and Unwrap', function () { const test_vectors = [ [ '128 bits of Key Data with a 128-bit KEK', + enums.symmetric.aes128, '000102030405060708090A0B0C0D0E0F', '00112233445566778899AABBCCDDEEFF', '1FA68B0A8112B447 AEF34BD8FB5A7B82 9D3E862371D2CFE5' ], [ '128 bits of Key Data with a 192-bit KEK', + enums.symmetric.aes192, '000102030405060708090A0B0C0D0E0F1011121314151617', '00112233445566778899AABBCCDDEEFF', '96778B25AE6CA435 F92B5B97C050AED2 468AB8A17AD84E5D' ], [ '128 bits of Key Data with a 256-bit KEK', + enums.symmetric.aes256, '000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F', '00112233445566778899AABBCCDDEEFF', '64E8C3F9CE0F5BA2 63E9777905818A2A 93C8191E7D6E8AE7' ], [ '192 bits of Key Data with a 192-bit KEK', + enums.symmetric.aes192, '000102030405060708090A0B0C0D0E0F1011121314151617', '00112233445566778899AABBCCDDEEFF0001020304050607', '031D33264E15D332 68F24EC260743EDC E1C6C7DDEE725A93 6BA814915C6762D2' ], [ '192 bits of Key Data with a 256-bit KEK', + enums.symmetric.aes256, '000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F', '00112233445566778899AABBCCDDEEFF0001020304050607', 'A8F9BC1612C68B3F F6E6F4FBE30E71E4 769C8B80A32CB895 8CD5D17D6B254DA1' ], [ '256 bits of Key Data with a 256-bit KEK', + enums.symmetric.aes256, '000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F', '00112233445566778899AABBCCDDEEFF000102030405060708090A0B0C0D0E0F', '28C9F404C4B810F4 CBCCB35CFB87F826 3F5786E2D80ED326 CBC7F0E71A99F43B FB988B9B7A02DD21' @@ -44,15 +51,15 @@ export default () => describe('AES Key Wrap and Unwrap', function () { ]; test_vectors.forEach(function(test) { - it(test[0], function(done) { - const kek = util.hexToUint8Array(test[1]); - const input = test[2].replace(/\s/g, ''); + it(test[0], async function() { + const algo = test[1]; + const kek = util.hexToUint8Array(test[2]); + const input = test[3].replace(/\s/g, ''); const input_bin = util.uint8ArrayToString(util.hexToUint8Array(input)); - const output = test[3].replace(/\s/g, ''); + const output = test[4].replace(/\s/g, ''); const output_bin = util.uint8ArrayToString(util.hexToUint8Array(output)); - expect(util.uint8ArrayToHex(aesKW.wrap(kek, input_bin)).toUpperCase()).to.equal(output); - expect(util.uint8ArrayToHex(aesKW.unwrap(kek, output_bin)).toUpperCase()).to.equal(input); - done(); + expect(util.uint8ArrayToHex(await aesKW.wrap(algo, kek, input_bin)).toUpperCase()).to.equal(output); + expect(util.uint8ArrayToHex(await aesKW.unwrap(algo, kek, output_bin)).toUpperCase()).to.equal(input); }); }); }); diff --git a/test/crypto/cipher/aes.js b/test/crypto/cipher/aes.js index 6ec39863..7f97648c 100644 --- a/test/crypto/cipher/aes.js +++ b/test/crypto/cipher/aes.js @@ -1,9 +1,11 @@ import { expect } from 'chai'; -import { aes128 as AES128 } from '../../../src/crypto/cipher'; +import enums from '../../../src/enums'; +import { getCipher } from '../../../src/crypto/cipher'; export default () => describe('AES Rijndael cipher test with test vectors from ecb_tbl.txt', function() { - function test_aes(input, key, output) { + async function test_aes(input, key, output) { + const AES128 = await getCipher(enums.symmetric.aes128); const aes = new AES128(new Uint8Array(key)); const encrypted = aes.encrypt(new Uint8Array(input)); @@ -61,24 +63,21 @@ export default () => describe('AES Rijndael cipher test with test vectors from e [[0x08,0x09,0x0A,0x0B,0x0D,0x0E,0x0F,0x10,0x12,0x13,0x14,0x15,0x17,0x18,0x19,0x1A,0x1C,0x1D,0x1E,0x1F,0x21,0x22,0x23,0x24,0x26,0x27,0x28,0x29,0x2B,0x2C,0x2D,0x2E],[0x06,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F,0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x21],[0x08,0x0E,0x95,0x17,0xEB,0x16,0x77,0x71,0x9A,0xCF,0x72,0x80,0x86,0x04,0x0A,0xE3]], [[0x30,0x31,0x32,0x33,0x35,0x36,0x37,0x38,0x3A,0x3B,0x3C,0x3D,0x3F,0x40,0x41,0x42,0x44,0x45,0x46,0x47,0x49,0x4A,0x4B,0x4C,0x4E,0x4F,0x50,0x51,0x53,0x54,0x55,0x56],[0x72,0x61,0x65,0xC1,0x72,0x3F,0xBC,0xF6,0xC0,0x26,0xD7,0xD0,0x0B,0x09,0x10,0x27],[0x7C,0x17,0x00,0x21,0x1A,0x39,0x91,0xFC,0x0E,0xCD,0xED,0x0A,0xB3,0xE5,0x76,0xB0]]]; - it('128 bit key', function (done) { + it('128 bit key', async function () { for (let i = 0; i < testvectors128.length; i++) { - test_aes(testvectors128[i][1],testvectors128[i][0],testvectors128[i][2]); + await test_aes(testvectors128[i][1],testvectors128[i][0],testvectors128[i][2]); } - done(); }); - it('192 bit key', function (done) { + it('192 bit key', async function () { for (let i = 0; i < testvectors192.length; i++) { - test_aes(testvectors192[i][1],testvectors192[i][0],testvectors192[i][2]); + await test_aes(testvectors192[i][1],testvectors192[i][0],testvectors192[i][2]); } - done(); }); - it('256 bit key', function (done) { + it('256 bit key', async function () { for (let i = 0; i < testvectors256.length; i++) { - test_aes(testvectors256[i][1],testvectors256[i][0],testvectors256[i][2]); + await test_aes(testvectors256[i][1],testvectors256[i][0],testvectors256[i][2]); } - done(); }); }); diff --git a/test/crypto/crypto.js b/test/crypto/crypto.js index 1d017d84..c6bd5828 100644 --- a/test/crypto/crypto.js +++ b/test/crypto/crypto.js @@ -254,7 +254,7 @@ export default () => describe('API functional testing', function() { async function testCFB(plaintext, config = openpgp.config) { await Promise.all(symmAlgoNames.map(async function(algoName) { const algo = openpgp.enums.write(openpgp.enums.symmetric, algoName); - const { blockSize } = crypto.getCipher(algo); + const { blockSize } = crypto.getCipherParams(algo); const symmKey = crypto.generateSessionKey(algo); const IV = new Uint8Array(blockSize); const symmencData = await crypto.mode.cfb.encrypt(algo, symmKey, util.stringToUint8Array(plaintext), IV, config); From 9c758459448532184cf2b6c386080cb319bf2d66 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Wed, 7 Feb 2024 16:46:04 +0100 Subject: [PATCH 106/201] Use WebCrypto for AES-KW Fallback needed for AES192, due to missing Chromium support. --- src/crypto/aes_kw.js | 84 ++++++++++++++++++++++++++++++++++--------- test/crypto/aes_kw.js | 4 +-- test/crypto/ecdh.js | 15 ++++---- 3 files changed, 78 insertions(+), 25 deletions(-) diff --git a/src/crypto/aes_kw.js b/src/crypto/aes_kw.js index dcd116d7..ced18ae0 100644 --- a/src/crypto/aes_kw.js +++ b/src/crypto/aes_kw.js @@ -24,15 +24,75 @@ import { getCipher } from './cipher'; import util from '../util'; +const webCrypto = util.getWebCrypto(); /** * AES key wrap - * @function - * @param {Uint8Array} key - * @param {Uint8Array} data - * @returns {Uint8Array} + * @param {enums.symmetric.aes128|enums.symmetric.aes256|enums.symmetric.aes192} algo - AES algo + * @param {Uint8Array} key - wrapping key + * @param {Uint8Array} dataToWrap + * @returns {Uint8Array} wrapped key */ -export async function wrap(algo, key, data) { - const Cipher = await getCipher(algo); +export async function wrap(algo, key, dataToWrap) { + if (!util.isAES(algo)) { + throw new Error('AES algorithm expected'); + } + + try { + const wrappingKey = await webCrypto.importKey('raw', key, { name: 'AES-KW' }, false, ['wrapKey']); + // Import data as HMAC key, as it has no key length requirements + const keyToWrap = await webCrypto.importKey('raw', dataToWrap, { name: 'HMAC', hash: 'SHA-256' }, true, ['sign']); + const wrapped = await webCrypto.wrapKey('raw', keyToWrap, wrappingKey, { name: 'AES-KW' }); + return new Uint8Array(wrapped); + } catch (err) { + // no 192 bit support in Chromium, which throws `OperationError`, see: https://www.chromium.org/blink/webcrypto#TOC-AES-support + if (err.name !== 'NotSupportedError' && + !(key.length === 24 && err.name === 'OperationError')) { + throw err; + } + util.printDebugError('Browser did not support operation: ' + err.message); + } + + return asmcryptoWrap(algo, key, dataToWrap); +} + +/** + * AES key unwrap + * @param {enums.symmetric.aes128|enums.symmetric.aes256|enums.symmetric.aes192} algo - AES algo + * @param {Uint8Array} key - wrapping key + * @param {Uint8Array} wrappedData + * @returns {Uint8Array} unwrapped data + */ +export async function unwrap(algo, key, wrappedData) { + if (!util.isAES(algo)) { + throw new Error('AES algorithm expected'); + } + + let wrappingKey; + try { + wrappingKey = await webCrypto.importKey('raw', key, { name: 'AES-KW' }, false, ['unwrapKey']); + } catch (err) { + // no 192 bit support in Chromium, which throws `OperationError`, see: https://www.chromium.org/blink/webcrypto#TOC-AES-support + if (err.name !== 'NotSupportedError' && + !(key.length === 24 && err.name === 'OperationError')) { + throw err; + } + util.printDebugError('Browser did not support operation: ' + err.message); + return asmcryptoUnwrap(algo, key, wrappedData); + } + + try { + const unwrapped = await webCrypto.unwrapKey('raw', wrappedData, wrappingKey, { name: 'AES-KW' }, { name: 'HMAC', hash: 'SHA-256' }, true, ['sign']); + return new Uint8Array(await webCrypto.exportKey('raw', unwrapped)); + } catch (err) { + if (err.name === 'OperationError') { + throw new Error('Key Data Integrity failed'); + } + throw err; + } +} + +async function asmcryptoWrap(aesAlgo, key, data) { + const Cipher = await getCipher(aesAlgo); const aes = new Cipher(key); const IV = new Uint32Array([0xA6A6A6A6, 0xA6A6A6A6]); const P = unpack(data); @@ -64,16 +124,8 @@ export async function wrap(algo, key, data) { return pack(A, R); } -/** - * AES key unwrap - * @function - * @param {String} key - * @param {String} data - * @returns {Uint8Array} - * @throws {Error} - */ -export async function unwrap(algo, key, data) { - const Cipher = await getCipher(algo); +async function asmcryptoUnwrap(aesAlgo, key, data) { + const Cipher = await getCipher(aesAlgo); const aes = new Cipher(key); const IV = new Uint32Array([0xA6A6A6A6, 0xA6A6A6A6]); const C = unpack(data); diff --git a/test/crypto/aes_kw.js b/test/crypto/aes_kw.js index 7c7cb60b..d85fd1f6 100644 --- a/test/crypto/aes_kw.js +++ b/test/crypto/aes_kw.js @@ -55,9 +55,9 @@ export default () => describe('AES Key Wrap and Unwrap', function () { const algo = test[1]; const kek = util.hexToUint8Array(test[2]); const input = test[3].replace(/\s/g, ''); - const input_bin = util.uint8ArrayToString(util.hexToUint8Array(input)); + const input_bin = util.hexToUint8Array(input); const output = test[4].replace(/\s/g, ''); - const output_bin = util.uint8ArrayToString(util.hexToUint8Array(output)); + const output_bin = util.hexToUint8Array(output); expect(util.uint8ArrayToHex(await aesKW.wrap(algo, kek, input_bin)).toUpperCase()).to.equal(output); expect(util.uint8ArrayToHex(await aesKW.unwrap(algo, kek, output_bin)).toUpperCase()).to.equal(input); }); diff --git a/test/crypto/ecdh.js b/test/crypto/ecdh.js index 6e2cc189..f4dede03 100644 --- a/test/crypto/ecdh.js +++ b/test/crypto/ecdh.js @@ -62,6 +62,7 @@ export default () => describe('ECDH key exchange @lightweight', function () { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]); const secp256k1_data = new Uint8Array([ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]); @@ -142,7 +143,7 @@ export default () => describe('ECDH key exchange @lightweight', function () { const curve = new elliptic_curves.CurveWithOID('secp256k1'); const oid = new OID(curve.oid); const kdfParams = new KDFParams({ hash: curve.hash, cipher: curve.cipher }); - const data = util.stringToUint8Array('test'); + const data = random.getRandomBytes(16); await expect( ecdh.encrypt(oid, kdfParams, data, Q1.subarray(1), fingerprint1) ).to.be.rejectedWith(/Public key is not valid for specified curve|Failed to translate Buffer to a EC_POINT|second arg must be public key/); @@ -152,7 +153,7 @@ export default () => describe('ECDH key exchange @lightweight', function () { const curve = new elliptic_curves.CurveWithOID(openpgp.enums.curve.curve25519Legacy); const oid = new OID(curve.oid); const kdfParams = new KDFParams({ hash: curve.hash, cipher: curve.cipher }); - const data = util.stringToUint8Array('test'); + const data = random.getRandomBytes(16); const { publicKey: V, wrappedKey: C } = await ecdh.encrypt(oid, kdfParams, data, Q1, fingerprint1); await expect( ecdh.decrypt(oid, kdfParams, V, C, Q2, d2, fingerprint1) @@ -163,7 +164,7 @@ export default () => describe('ECDH key exchange @lightweight', function () { const curve = new elliptic_curves.CurveWithOID(openpgp.enums.curve.curve25519Legacy); const oid = new OID(curve.oid); const kdfParams = new KDFParams({ hash: curve.hash, cipher: curve.cipher }); - const data = util.stringToUint8Array('test'); + const data = random.getRandomBytes(16); const { publicKey: V, wrappedKey: C } = await ecdh.encrypt(oid, kdfParams, data, Q2, fingerprint1); await expect( ecdh.decrypt(oid, kdfParams, V, C, Q2, d2, fingerprint2) @@ -174,7 +175,7 @@ export default () => describe('ECDH key exchange @lightweight', function () { const curve = new elliptic_curves.CurveWithOID(openpgp.enums.curve.curve25519Legacy); const oid = new OID(curve.oid); const kdfParams = new KDFParams({ hash: curve.hash, cipher: curve.cipher }); - const data = util.stringToUint8Array('test'); + const data = random.getRandomBytes(16); const { publicKey: V, wrappedKey: C } = await ecdh.encrypt(oid, kdfParams, data, Q1, fingerprint1); expect(await ecdh.decrypt(oid, kdfParams, V, C, Q1, d1, fingerprint1)).to.deep.equal(data); }); @@ -191,7 +192,7 @@ export default () => describe('ECDH key exchange @lightweight', function () { it('Successful exchange x448', async function () { const { ecdhX } = elliptic_curves; - const data = random.getRandomBytes(); + const data = random.getRandomBytes(16); // Bob's keys from https://www.rfc-editor.org/rfc/rfc7748#section-6.2 const b = util.hexToUint8Array('1c306a7ac2a0e2e0990b294470cba339e6453772b075811d8fad0d1d6927c120bb5ee8972b0d3e21374c9c921b09d1b0366f10b65173992d'); const K_B = util.hexToUint8Array('3eb7a829b0cd20f5bcfc0b599b6feccf6da4627107bdb0d4f345b43027d8b972fc3e34fb4232a13ca706dcb57aec3dae07bdc1c67bf33609'); @@ -205,7 +206,7 @@ export default () => describe('ECDH key exchange @lightweight', function () { const curve = new elliptic_curves.CurveWithOID(curveName); const oid = new OID(curve.oid); const kdfParams = new KDFParams({ hash: curve.hash, cipher: curve.cipher }); - const data = util.stringToUint8Array('test'); + const data = random.getRandomBytes(16); const Q = key_data[curveName].pub; const d = key_data[curveName].priv; const { publicKey: V, wrappedKey: C } = await ecdh.encrypt(oid, kdfParams, data, Q, fingerprint1); @@ -250,7 +251,7 @@ export default () => describe('ECDH key exchange @lightweight', function () { const curve = new elliptic_curves.CurveWithOID(curveName); const oid = new OID(curve.oid); const kdfParams = new KDFParams({ hash: curve.hash, cipher: curve.cipher }); - const data = util.stringToUint8Array('test'); + const data = random.getRandomBytes(16); const Q = key_data[curveName].pub; const d = key_data[curveName].priv; const { publicKey: V, wrappedKey: C } = await ecdh.encrypt(oid, kdfParams, data, Q, fingerprint1); From a6283e64cc3490a31c4143d6fe2e46bb6693995f Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Wed, 7 Feb 2024 17:28:03 +0100 Subject: [PATCH 107/201] Drop internal `cipher/aes` module The module was barely used, and its presence confusing, since WebCrypto or asmcrypto are often directly used and usable instead. Also, use AES_CBC instead of AES_ECB for single-block encryption, so that we can drop support for the latter in the asmcrypto lib. --- package-lock.json | 14 +++---- package.json | 2 +- src/crypto/aes_kw.js | 49 +++++++++------------- src/crypto/cipher/aes.js | 26 ------------ src/crypto/cipher/index.js | 5 +-- src/crypto/crypto.js | 4 +- src/crypto/mode/cfb.js | 10 ++--- src/crypto/mode/ocb.js | 25 ++++++----- test/crypto/cipher/aes.js | 83 ------------------------------------- test/crypto/cipher/index.js | 2 - 10 files changed, 51 insertions(+), 169 deletions(-) delete mode 100644 src/crypto/cipher/aes.js delete mode 100644 test/crypto/cipher/aes.js diff --git a/package-lock.json b/package-lock.json index b8f99878..0425d70a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "asn1.js": "^5.0.0" }, "devDependencies": { - "@openpgp/asmcrypto.js": "^3.0.0", + "@openpgp/asmcrypto.js": "^3.1.0", "@openpgp/jsdoc": "^3.6.11", "@openpgp/noble-curves": "^1.2.1-0", "@openpgp/noble-hashes": "^1.3.3-0", @@ -896,9 +896,9 @@ } }, "node_modules/@openpgp/asmcrypto.js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@openpgp/asmcrypto.js/-/asmcrypto.js-3.0.0.tgz", - "integrity": "sha512-X/DPYy7uHe+dlY2Botb99uXwb2kXR6HTv0hQOnnI0TVEqOIMQyzCDWAzlX00AacsYryDAphuOndg6mk6wtJCNg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@openpgp/asmcrypto.js/-/asmcrypto.js-3.1.0.tgz", + "integrity": "sha512-LlQZE/Vtkx/KFnJxg7BB0iwD7oYKDeC8eRECHxKLhYyL2Ad0+xT137VZwv8SZTJB2euPqpx7xkj04ieV0Q665w==", "dev": true }, "node_modules/@openpgp/jsdoc": { @@ -7966,9 +7966,9 @@ } }, "@openpgp/asmcrypto.js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@openpgp/asmcrypto.js/-/asmcrypto.js-3.0.0.tgz", - "integrity": "sha512-X/DPYy7uHe+dlY2Botb99uXwb2kXR6HTv0hQOnnI0TVEqOIMQyzCDWAzlX00AacsYryDAphuOndg6mk6wtJCNg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@openpgp/asmcrypto.js/-/asmcrypto.js-3.1.0.tgz", + "integrity": "sha512-LlQZE/Vtkx/KFnJxg7BB0iwD7oYKDeC8eRECHxKLhYyL2Ad0+xT137VZwv8SZTJB2euPqpx7xkj04ieV0Q665w==", "dev": true }, "@openpgp/jsdoc": { diff --git a/package.json b/package.json index d370f10e..f23b435c 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "postversion": "git push && git push --tags && npm publish" }, "devDependencies": { - "@openpgp/asmcrypto.js": "^3.0.0", + "@openpgp/asmcrypto.js": "^3.1.0", "@openpgp/jsdoc": "^3.6.11", "@openpgp/noble-curves": "^1.2.1-0", "@openpgp/noble-hashes": "^1.3.3-0", diff --git a/src/crypto/aes_kw.js b/src/crypto/aes_kw.js index ced18ae0..52288b31 100644 --- a/src/crypto/aes_kw.js +++ b/src/crypto/aes_kw.js @@ -21,7 +21,8 @@ * @module crypto/aes_kw */ -import { getCipher } from './cipher'; +import { AES_CBC } from '@openpgp/asmcrypto.js/aes/cbc.js'; +import { getCipherParams } from './cipher'; import util from '../util'; const webCrypto = util.getWebCrypto(); @@ -33,8 +34,10 @@ const webCrypto = util.getWebCrypto(); * @returns {Uint8Array} wrapped key */ export async function wrap(algo, key, dataToWrap) { - if (!util.isAES(algo)) { - throw new Error('AES algorithm expected'); + const { keySize } = getCipherParams(algo); + // sanity checks, since WebCrypto does not use the `algo` input + if (!util.isAES(algo) || key.length !== keySize) { + throw new Error('Unexpected algorithm or key size'); } try { @@ -63,8 +66,10 @@ export async function wrap(algo, key, dataToWrap) { * @returns {Uint8Array} unwrapped data */ export async function unwrap(algo, key, wrappedData) { - if (!util.isAES(algo)) { - throw new Error('AES algorithm expected'); + const { keySize } = getCipherParams(algo); + // sanity checks, since WebCrypto does not use the `algo` input + if (!util.isAES(algo) || key.length !== keySize) { + throw new Error('Unexpected algorithm or key size'); } let wrappingKey; @@ -91,9 +96,8 @@ export async function unwrap(algo, key, wrappedData) { } } -async function asmcryptoWrap(aesAlgo, key, data) { - const Cipher = await getCipher(aesAlgo); - const aes = new Cipher(key); +function asmcryptoWrap(aesAlgo, key, data) { + const aesInstance = new AES_CBC(key, new Uint8Array(16), false); const IV = new Uint32Array([0xA6A6A6A6, 0xA6A6A6A6]); const P = unpack(data); let A = IV; @@ -111,7 +115,7 @@ async function asmcryptoWrap(aesAlgo, key, data) { B[2] = R[2 * i]; B[3] = R[2 * i + 1]; // B = AES(K, B) - B = unpack(aes.encrypt(pack(B))); + B = unpack(aesInstance.encrypt(pack(B))); // A = MSB(64, B) ^ t A = B.subarray(0, 2); A[0] ^= t[0]; @@ -124,9 +128,8 @@ async function asmcryptoWrap(aesAlgo, key, data) { return pack(A, R); } -async function asmcryptoUnwrap(aesAlgo, key, data) { - const Cipher = await getCipher(aesAlgo); - const aes = new Cipher(key); +function asmcryptoUnwrap(aesAlgo, key, data) { + const aesInstance = new AES_CBC(key, new Uint8Array(16), false); const IV = new Uint32Array([0xA6A6A6A6, 0xA6A6A6A6]); const C = unpack(data); let A = C.subarray(0, 2); @@ -144,7 +147,7 @@ async function asmcryptoUnwrap(aesAlgo, key, data) { B[2] = R[2 * i]; B[3] = R[2 * i + 1]; // B = AES-1(B) - B = unpack(aes.decrypt(pack(B))); + B = unpack(aesInstance.decrypt(pack(B))); // A = MSB(64, B) A = B.subarray(0, 2); // R[i] = LSB(64, B) @@ -158,25 +161,11 @@ async function asmcryptoUnwrap(aesAlgo, key, data) { throw new Error('Key Data Integrity failed'); } -function createArrayBuffer(data) { - if (util.isString(data)) { - const { length } = data; - const buffer = new ArrayBuffer(length); - const view = new Uint8Array(buffer); - for (let j = 0; j < length; ++j) { - view[j] = data.charCodeAt(j); - } - return buffer; - } - return new Uint8Array(data).buffer; -} - function unpack(data) { - const { length } = data; - const buffer = createArrayBuffer(data); + const buffer = data.buffer; const view = new DataView(buffer); - const arr = new Uint32Array(length / 4); - for (let i = 0; i < length / 4; ++i) { + const arr = new Uint32Array(data.length / 4); + for (let i = 0; i < data.length / 4; ++i) { arr[i] = view.getUint32(4 * i); } return arr; diff --git a/src/crypto/cipher/aes.js b/src/crypto/cipher/aes.js deleted file mode 100644 index 0ef89041..00000000 --- a/src/crypto/cipher/aes.js +++ /dev/null @@ -1,26 +0,0 @@ -import { AES_ECB } from '@openpgp/asmcrypto.js/aes/ecb.js'; - -/** - * Javascript AES implementation. - * This is used as fallback if the native Crypto APIs are not available. - */ -function aes(length) { - const C = function(key) { - const aesECB = new AES_ECB(key); - - this.encrypt = function(block) { - return aesECB.encrypt(block); - }; - - this.decrypt = function(block) { - return aesECB.decrypt(block); - }; - }; - - C.blockSize = C.prototype.blockSize = 16; - C.keySize = C.prototype.keySize = length / 8; - - return C; -} - -export default aes; diff --git a/src/crypto/cipher/index.js b/src/crypto/cipher/index.js index 878b05c0..88c1b9cb 100644 --- a/src/crypto/cipher/index.js +++ b/src/crypto/cipher/index.js @@ -1,12 +1,11 @@ -import aes from './aes'; // can be imported dynamically once Web Crypto is used for AES-KW too import enums from '../../enums'; -export async function getCipher(algo) { +export async function getLegacyCipher(algo) { switch (algo) { case enums.symmetric.aes128: case enums.symmetric.aes192: case enums.symmetric.aes256: - return aes(getCipherKeySize(algo)); + throw new Error('Not a legacy cipher'); case enums.symmetric.cast5: case enums.symmetric.blowfish: case enums.symmetric.twofish: diff --git a/src/crypto/crypto.js b/src/crypto/crypto.js index 486c4c11..04e2fe39 100644 --- a/src/crypto/crypto.js +++ b/src/crypto/crypto.js @@ -26,7 +26,7 @@ import publicKey from './public_key'; import mode from './mode'; import { getRandomBytes } from './random'; -import { getCipher, getCipherParams } from './cipher'; +import { getCipherParams } from './cipher'; import ECDHSymkey from '../type/ecdh_symkey'; import KDFParams from '../type/kdf_params'; import enums from '../enums'; @@ -524,4 +524,4 @@ export function getPreferredCurveHashAlgo(algo, oid) { } -export { getCipher, getCipherParams }; +export { getCipherParams }; diff --git a/src/crypto/mode/cfb.js b/src/crypto/mode/cfb.js index 30fea08b..128b28e9 100644 --- a/src/crypto/mode/cfb.js +++ b/src/crypto/mode/cfb.js @@ -25,7 +25,7 @@ import { AES_CFB } from '@openpgp/asmcrypto.js/aes/cfb.js'; import * as stream from '@openpgp/web-stream-tools'; import util from '../../util'; import enums from '../../enums'; -import { getCipher, getCipherParams } from '../cipher'; +import { getLegacyCipher, getCipherParams } from '../cipher'; const webCrypto = util.getWebCrypto(); const nodeCrypto = util.getNodeCrypto(); @@ -60,8 +60,8 @@ export async function encrypt(algo, key, plaintext, iv, config) { return aesEncrypt(algo, key, plaintext, iv, config); } - const Cipher = await getCipher(algo); - const cipherfn = new Cipher(key); + const LegacyCipher = await getLegacyCipher(algo); + const cipherfn = new LegacyCipher(key); const block_size = cipherfn.blockSize; const blockc = iv.slice(); @@ -103,8 +103,8 @@ export async function decrypt(algo, key, ciphertext, iv) { return aesDecrypt(algo, key, ciphertext, iv); } - const Cipher = await getCipher(algo); - const cipherfn = new Cipher(key); + const LegacyCipher = await getLegacyCipher(algo); + const cipherfn = new LegacyCipher(key); const block_size = cipherfn.blockSize; let blockp = iv; diff --git a/src/crypto/mode/ocb.js b/src/crypto/mode/ocb.js index 7c60921a..868c67b9 100644 --- a/src/crypto/mode/ocb.js +++ b/src/crypto/mode/ocb.js @@ -20,7 +20,8 @@ * @module crypto/mode/ocb */ -import { getCipher } from '../cipher'; +import { AES_CBC } from '@openpgp/asmcrypto.js/aes/cbc.js'; +import { getCipherParams } from '../cipher'; import util from '../../util'; const blockLength = 16; @@ -61,20 +62,24 @@ const one = new Uint8Array([1]); * @param {Uint8Array} key - The encryption key */ async function OCB(cipher, key) { + const { keySize } = getCipherParams(cipher); + // sanity checks + if (!util.isAES(cipher) || key.length !== keySize) { + throw new Error('Unexpected algorithm or key size'); + } let maxNtz = 0; - let encipher; - let decipher; + + // `encipher` and `decipher` cannot be async, since `crypt` shares state across calls, + // hence its execution cannot be broken up. + // As a result, WebCrypto cannot currently be used for `encipher`. + const encipher = block => AES_CBC.encrypt(block, key, false); + const decipher = block => AES_CBC.decrypt(block, key, false); let mask; - await constructKeyVariables(cipher, key); - - async function constructKeyVariables(cipher, key) { - const Cipher = await getCipher(cipher); - const aes = new Cipher(key); - encipher = aes.encrypt.bind(aes); - decipher = aes.decrypt.bind(aes); + constructKeyVariables(cipher, key); + function constructKeyVariables() { const mask_x = encipher(zeroBlock); const mask_$ = util.double(mask_x); mask = []; diff --git a/test/crypto/cipher/aes.js b/test/crypto/cipher/aes.js deleted file mode 100644 index 7f97648c..00000000 --- a/test/crypto/cipher/aes.js +++ /dev/null @@ -1,83 +0,0 @@ -import { expect } from 'chai'; - -import enums from '../../../src/enums'; -import { getCipher } from '../../../src/crypto/cipher'; - -export default () => describe('AES Rijndael cipher test with test vectors from ecb_tbl.txt', function() { - async function test_aes(input, key, output) { - const AES128 = await getCipher(enums.symmetric.aes128); - const aes = new AES128(new Uint8Array(key)); - - const encrypted = aes.encrypt(new Uint8Array(input)); - expect(encrypted).to.deep.equal(new Uint8Array(output)); - - const decrypted = aes.decrypt(new Uint8Array(output)); - expect(decrypted).to.deep.equal(new Uint8Array(input)); - } - - const testvectors128 = [[[0x00,0x01,0x02,0x03,0x05,0x06,0x07,0x08,0x0A,0x0B,0x0C,0x0D,0x0F,0x10,0x11,0x12],[0x50,0x68,0x12,0xA4,0x5F,0x08,0xC8,0x89,0xB9,0x7F,0x59,0x80,0x03,0x8B,0x83,0x59],[0xD8,0xF5,0x32,0x53,0x82,0x89,0xEF,0x7D,0x06,0xB5,0x06,0xA4,0xFD,0x5B,0xE9,0xC9]], - [[0x14,0x15,0x16,0x17,0x19,0x1A,0x1B,0x1C,0x1E,0x1F,0x20,0x21,0x23,0x24,0x25,0x26],[0x5C,0x6D,0x71,0xCA,0x30,0xDE,0x8B,0x8B,0x00,0x54,0x99,0x84,0xD2,0xEC,0x7D,0x4B],[0x59,0xAB,0x30,0xF4,0xD4,0xEE,0x6E,0x4F,0xF9,0x90,0x7E,0xF6,0x5B,0x1F,0xB6,0x8C]], - [[0x28,0x29,0x2A,0x2B,0x2D,0x2E,0x2F,0x30,0x32,0x33,0x34,0x35,0x37,0x38,0x39,0x3A],[0x53,0xF3,0xF4,0xC6,0x4F,0x86,0x16,0xE4,0xE7,0xC5,0x61,0x99,0xF4,0x8F,0x21,0xF6],[0xBF,0x1E,0xD2,0xFC,0xB2,0xAF,0x3F,0xD4,0x14,0x43,0xB5,0x6D,0x85,0x02,0x5C,0xB1]], - [[0x3C,0x3D,0x3E,0x3F,0x41,0x42,0x43,0x44,0x46,0x47,0x48,0x49,0x4B,0x4C,0x4D,0x4E],[0xA1,0xEB,0x65,0xA3,0x48,0x71,0x65,0xFB,0x0F,0x1C,0x27,0xFF,0x99,0x59,0xF7,0x03],[0x73,0x16,0x63,0x2D,0x5C,0x32,0x23,0x3E,0xDC,0xB0,0x78,0x05,0x60,0xEA,0xE8,0xB2]], - [[0x50,0x51,0x52,0x53,0x55,0x56,0x57,0x58,0x5A,0x5B,0x5C,0x5D,0x5F,0x60,0x61,0x62],[0x35,0x53,0xEC,0xF0,0xB1,0x73,0x95,0x58,0xB0,0x8E,0x35,0x0A,0x98,0xA3,0x9B,0xFA],[0x40,0x8C,0x07,0x3E,0x3E,0x25,0x38,0x07,0x2B,0x72,0x62,0x5E,0x68,0xB8,0x36,0x4B]], - [[0x64,0x65,0x66,0x67,0x69,0x6A,0x6B,0x6C,0x6E,0x6F,0x70,0x71,0x73,0x74,0x75,0x76],[0x67,0x42,0x99,0x69,0x49,0x0B,0x97,0x11,0xAE,0x2B,0x01,0xDC,0x49,0x7A,0xFD,0xE8],[0xE1,0xF9,0x4D,0xFA,0x77,0x65,0x97,0xBE,0xAC,0xA2,0x62,0xF2,0xF6,0x36,0x6F,0xEA]], - [[0x78,0x79,0x7A,0x7B,0x7D,0x7E,0x7F,0x80,0x82,0x83,0x84,0x85,0x87,0x88,0x89,0x8A],[0x93,0x38,0x5C,0x1F,0x2A,0xEC,0x8B,0xED,0x19,0x2F,0x5A,0x8E,0x16,0x1D,0xD5,0x08],[0xF2,0x9E,0x98,0x6C,0x6A,0x1C,0x27,0xD7,0xB2,0x9F,0xFD,0x7E,0xE9,0x2B,0x75,0xF1]], - [[0x8C,0x8D,0x8E,0x8F,0x91,0x92,0x93,0x94,0x96,0x97,0x98,0x99,0x9B,0x9C,0x9D,0x9E],[0xB5,0xBF,0x94,0x6B,0xE1,0x9B,0xEB,0x8D,0xB3,0x98,0x3B,0x5F,0x4C,0x6E,0x8D,0xDB],[0x13,0x1C,0x88,0x6A,0x57,0xF8,0xC2,0xE7,0x13,0xAB,0xA6,0x95,0x5E,0x2B,0x55,0xB5]], - [[0xA0,0xA1,0xA2,0xA3,0xA5,0xA6,0xA7,0xA8,0xAA,0xAB,0xAC,0xAD,0xAF,0xB0,0xB1,0xB2],[0x41,0x32,0x1E,0xE1,0x0E,0x21,0xBD,0x90,0x72,0x27,0xC4,0x45,0x0F,0xF4,0x23,0x24],[0xD2,0xAB,0x76,0x62,0xDF,0x9B,0x8C,0x74,0x02,0x10,0xE5,0xEE,0xB6,0x1C,0x19,0x9D]], - [[0xB4,0xB5,0xB6,0xB7,0xB9,0xBA,0xBB,0xBC,0xBE,0xBF,0xC0,0xC1,0xC3,0xC4,0xC5,0xC6],[0x00,0xA8,0x2F,0x59,0xC9,0x1C,0x84,0x86,0xD1,0x2C,0x0A,0x80,0x12,0x4F,0x60,0x89],[0x14,0xC1,0x05,0x54,0xB2,0x85,0x9C,0x48,0x4C,0xAB,0x58,0x69,0xBB,0xE7,0xC4,0x70]], - [[0xC8,0xC9,0xCA,0xCB,0xCD,0xCE,0xCF,0xD0,0xD2,0xD3,0xD4,0xD5,0xD7,0xD8,0xD9,0xDA],[0x7C,0xE0,0xFD,0x07,0x67,0x54,0x69,0x1B,0x4B,0xBD,0x9F,0xAF,0x8A,0x13,0x72,0xFE],[0xDB,0x4D,0x49,0x8F,0x0A,0x49,0xCF,0x55,0x44,0x5D,0x50,0x2C,0x1F,0x9A,0xB3,0xB5]], - [[0xDC,0xDD,0xDE,0xDF,0xE1,0xE2,0xE3,0xE4,0xE6,0xE7,0xE8,0xE9,0xEB,0xEC,0xED,0xEE],[0x23,0x60,0x5A,0x82,0x43,0xD0,0x77,0x64,0x54,0x1B,0xC5,0xAD,0x35,0x5B,0x31,0x29],[0x6D,0x96,0xFE,0xF7,0xD6,0x65,0x90,0xA7,0x7A,0x77,0xBB,0x20,0x56,0x66,0x7F,0x7F]], - [[0xF0,0xF1,0xF2,0xF3,0xF5,0xF6,0xF7,0xF8,0xFA,0xFB,0xFC,0xFD,0xFE,0x01,0x00,0x02],[0x12,0xA8,0xCF,0xA2,0x3E,0xA7,0x64,0xFD,0x87,0x62,0x32,0xB4,0xE8,0x42,0xBC,0x44],[0x31,0x6F,0xB6,0x8E,0xDB,0xA7,0x36,0xC5,0x3E,0x78,0x47,0x7B,0xF9,0x13,0x72,0x5C]], - [[0x04,0x05,0x06,0x07,0x09,0x0A,0x0B,0x0C,0x0E,0x0F,0x10,0x11,0x13,0x14,0x15,0x16],[0xBC,0xAF,0x32,0x41,0x5E,0x83,0x08,0xB3,0x72,0x3E,0x5F,0xDD,0x85,0x3C,0xCC,0x80],[0x69,0x36,0xF2,0xB9,0x3A,0xF8,0x39,0x7F,0xD3,0xA7,0x71,0xFC,0x01,0x1C,0x8C,0x37]], - [[0x2C,0x2D,0x2E,0x2F,0x31,0x32,0x33,0x34,0x36,0x37,0x38,0x39,0x3B,0x3C,0x3D,0x3E],[0x89,0xAF,0xAE,0x68,0x5D,0x80,0x1A,0xD7,0x47,0xAC,0xE9,0x1F,0xC4,0x9A,0xDD,0xE0],[0xF3,0xF9,0x2F,0x7A,0x9C,0x59,0x17,0x9C,0x1F,0xCC,0x2C,0x2B,0xA0,0xB0,0x82,0xCD]]]; - - const testvectors192 = [[[0x00,0x01,0x02,0x03,0x05,0x06,0x07,0x08,0x0A,0x0B,0x0C,0x0D,0x0F,0x10,0x11,0x12,0x14,0x15,0x16,0x17,0x19,0x1A,0x1B,0x1C],[0x2D,0x33,0xEE,0xF2,0xC0,0x43,0x0A,0x8A,0x9E,0xBF,0x45,0xE8,0x09,0xC4,0x0B,0xB6],[0xDF,0xF4,0x94,0x5E,0x03,0x36,0xDF,0x4C,0x1C,0x56,0xBC,0x70,0x0E,0xFF,0x83,0x7F]], - [[0x1E,0x1F,0x20,0x21,0x23,0x24,0x25,0x26,0x28,0x29,0x2A,0x2B,0x2D,0x2E,0x2F,0x30,0x32,0x33,0x34,0x35,0x37,0x38,0x39,0x3A],[0x6A,0xA3,0x75,0xD1,0xFA,0x15,0x5A,0x61,0xFB,0x72,0x35,0x3E,0x0A,0x5A,0x87,0x56],[0xB6,0xFD,0xDE,0xF4,0x75,0x27,0x65,0xE3,0x47,0xD5,0xD2,0xDC,0x19,0x6D,0x12,0x52]], - [[0x3C,0x3D,0x3E,0x3F,0x41,0x42,0x43,0x44,0x46,0x47,0x48,0x49,0x4B,0x4C,0x4D,0x4E,0x50,0x51,0x52,0x53,0x55,0x56,0x57,0x58],[0xBC,0x37,0x36,0x51,0x8B,0x94,0x90,0xDC,0xB8,0xED,0x60,0xEB,0x26,0x75,0x8E,0xD4],[0xD2,0x36,0x84,0xE3,0xD9,0x63,0xB3,0xAF,0xCF,0x1A,0x11,0x4A,0xCA,0x90,0xCB,0xD6]], - [[0x5A,0x5B,0x5C,0x5D,0x5F,0x60,0x61,0x62,0x64,0x65,0x66,0x67,0x69,0x6A,0x6B,0x6C,0x6E,0x6F,0x70,0x71,0x73,0x74,0x75,0x76],[0xAA,0x21,0x44,0x02,0xB4,0x6C,0xFF,0xB9,0xF7,0x61,0xEC,0x11,0x26,0x3A,0x31,0x1E],[0x3A,0x7A,0xC0,0x27,0x75,0x3E,0x2A,0x18,0xC2,0xCE,0xAB,0x9E,0x17,0xC1,0x1F,0xD0]], - [[0x78,0x79,0x7A,0x7B,0x7D,0x7E,0x7F,0x80,0x82,0x83,0x84,0x85,0x87,0x88,0x89,0x8A,0x8C,0x8D,0x8E,0x8F,0x91,0x92,0x93,0x94],[0x02,0xAE,0xA8,0x6E,0x57,0x2E,0xEA,0xB6,0x6B,0x2C,0x3A,0xF5,0xE9,0xA4,0x6F,0xD6],[0x8F,0x67,0x86,0xBD,0x00,0x75,0x28,0xBA,0x26,0x60,0x3C,0x16,0x01,0xCD,0xD0,0xD8]], - [[0x96,0x97,0x98,0x99,0x9B,0x9C,0x9D,0x9E,0xA0,0xA1,0xA2,0xA3,0xA5,0xA6,0xA7,0xA8,0xAA,0xAB,0xAC,0xAD,0xAF,0xB0,0xB1,0xB2],[0xE2,0xAE,0xF6,0xAC,0xC3,0x3B,0x96,0x5C,0x4F,0xA1,0xF9,0x1C,0x75,0xFF,0x6F,0x36],[0xD1,0x7D,0x07,0x3B,0x01,0xE7,0x15,0x02,0xE2,0x8B,0x47,0xAB,0x55,0x11,0x68,0xB3]], - [[0xB4,0xB5,0xB6,0xB7,0xB9,0xBA,0xBB,0xBC,0xBE,0xBF,0xC0,0xC1,0xC3,0xC4,0xC5,0xC6,0xC8,0xC9,0xCA,0xCB,0xCD,0xCE,0xCF,0xD0],[0x06,0x59,0xDF,0x46,0x42,0x71,0x62,0xB9,0x43,0x48,0x65,0xDD,0x94,0x99,0xF9,0x1D],[0xA4,0x69,0xDA,0x51,0x71,0x19,0xFA,0xB9,0x58,0x76,0xF4,0x1D,0x06,0xD4,0x0F,0xFA]], - [[0xD2,0xD3,0xD4,0xD5,0xD7,0xD8,0xD9,0xDA,0xDC,0xDD,0xDE,0xDF,0xE1,0xE2,0xE3,0xE4,0xE6,0xE7,0xE8,0xE9,0xEB,0xEC,0xED,0xEE],[0x49,0xA4,0x42,0x39,0xC7,0x48,0xFE,0xB4,0x56,0xF5,0x9C,0x27,0x6A,0x56,0x58,0xDF],[0x60,0x91,0xAA,0x3B,0x69,0x5C,0x11,0xF5,0xC0,0xB6,0xAD,0x26,0xD3,0xD8,0x62,0xFF]], - [[0xF0,0xF1,0xF2,0xF3,0xF5,0xF6,0xF7,0xF8,0xFA,0xFB,0xFC,0xFD,0xFE,0x01,0x00,0x02,0x04,0x05,0x06,0x07,0x09,0x0A,0x0B,0x0C],[0x66,0x20,0x8F,0x6E,0x9D,0x04,0x52,0x5B,0xDE,0xDB,0x27,0x33,0xB6,0xA6,0xBE,0x37],[0x70,0xF9,0xE6,0x7F,0x9F,0x8D,0xF1,0x29,0x41,0x31,0x66,0x2D,0xC6,0xE6,0x93,0x64]], - [[0x0E,0x0F,0x10,0x11,0x13,0x14,0x15,0x16,0x18,0x19,0x1A,0x1B,0x1D,0x1E,0x1F,0x20,0x22,0x23,0x24,0x25,0x27,0x28,0x29,0x2A],[0x33,0x93,0xF8,0xDF,0xC7,0x29,0xC9,0x7F,0x54,0x80,0xB9,0x50,0xBC,0x96,0x66,0xB0],[0xD1,0x54,0xDC,0xAF,0xAD,0x8B,0x20,0x7F,0xA5,0xCB,0xC9,0x5E,0x99,0x96,0xB5,0x59]], - [[0x2C,0x2D,0x2E,0x2F,0x31,0x32,0x33,0x34,0x36,0x37,0x38,0x39,0x3B,0x3C,0x3D,0x3E,0x40,0x41,0x42,0x43,0x45,0x46,0x47,0x48],[0x60,0x68,0x34,0xC8,0xCE,0x06,0x3F,0x32,0x34,0xCF,0x11,0x45,0x32,0x5D,0xBD,0x71],[0x49,0x34,0xD5,0x41,0xE8,0xB4,0x6F,0xA3,0x39,0xC8,0x05,0xA7,0xAE,0xB9,0xE5,0xDA]], - [[0x4A,0x4B,0x4C,0x4D,0x4F,0x50,0x51,0x52,0x54,0x55,0x56,0x57,0x59,0x5A,0x5B,0x5C,0x5E,0x5F,0x60,0x61,0x63,0x64,0x65,0x66],[0xFE,0xC1,0xC0,0x4F,0x52,0x9B,0xBD,0x17,0xD8,0xCE,0xCF,0xCC,0x47,0x18,0xB1,0x7F],[0x62,0x56,0x4C,0x73,0x8F,0x3E,0xFE,0x18,0x6E,0x1A,0x12,0x7A,0x0C,0x4D,0x3C,0x61]], - [[0x68,0x69,0x6A,0x6B,0x6D,0x6E,0x6F,0x70,0x72,0x73,0x74,0x75,0x77,0x78,0x79,0x7A,0x7C,0x7D,0x7E,0x7F,0x81,0x82,0x83,0x84],[0x32,0xDF,0x99,0xB4,0x31,0xED,0x5D,0xC5,0xAC,0xF8,0xCA,0xF6,0xDC,0x6C,0xE4,0x75],[0x07,0x80,0x5A,0xA0,0x43,0x98,0x6E,0xB2,0x36,0x93,0xE2,0x3B,0xEF,0x8F,0x34,0x38]], - [[0x86,0x87,0x88,0x89,0x8B,0x8C,0x8D,0x8E,0x90,0x91,0x92,0x93,0x95,0x96,0x97,0x98,0x9A,0x9B,0x9C,0x9D,0x9F,0xA0,0xA1,0xA2],[0x7F,0xDC,0x2B,0x74,0x6F,0x3F,0x66,0x52,0x96,0x94,0x3B,0x83,0x71,0x0D,0x1F,0x82],[0xDF,0x0B,0x49,0x31,0x03,0x8B,0xAD,0xE8,0x48,0xDE,0xE3,0xB4,0xB8,0x5A,0xA4,0x4B]], - [[0xA4,0xA5,0xA6,0xA7,0xA9,0xAA,0xAB,0xAC,0xAE,0xAF,0xB0,0xB1,0xB3,0xB4,0xB5,0xB6,0xB8,0xB9,0xBA,0xBB,0xBD,0xBE,0xBF,0xC0],[0x8F,0xBA,0x15,0x10,0xA3,0xC5,0xB8,0x7E,0x2E,0xAA,0x3F,0x7A,0x91,0x45,0x5C,0xA2],[0x59,0x2D,0x5F,0xDE,0xD7,0x65,0x82,0xE4,0x14,0x3C,0x65,0x09,0x93,0x09,0x47,0x7C]]]; - - const testvectors256 = [[[0x00,0x01,0x02,0x03,0x05,0x06,0x07,0x08,0x0A,0x0B,0x0C,0x0D,0x0F,0x10,0x11,0x12,0x14,0x15,0x16,0x17,0x19,0x1A,0x1B,0x1C,0x1E,0x1F,0x20,0x21,0x23,0x24,0x25,0x26],[0x83,0x4E,0xAD,0xFC,0xCA,0xC7,0xE1,0xB3,0x06,0x64,0xB1,0xAB,0xA4,0x48,0x15,0xAB],[0x19,0x46,0xDA,0xBF,0x6A,0x03,0xA2,0xA2,0xC3,0xD0,0xB0,0x50,0x80,0xAE,0xD6,0xFC]], - [[0x28,0x29,0x2A,0x2B,0x2D,0x2E,0x2F,0x30,0x32,0x33,0x34,0x35,0x37,0x38,0x39,0x3A,0x3C,0x3D,0x3E,0x3F,0x41,0x42,0x43,0x44,0x46,0x47,0x48,0x49,0x4B,0x4C,0x4D,0x4E],[0xD9,0xDC,0x4D,0xBA,0x30,0x21,0xB0,0x5D,0x67,0xC0,0x51,0x8F,0x72,0xB6,0x2B,0xF1],[0x5E,0xD3,0x01,0xD7,0x47,0xD3,0xCC,0x71,0x54,0x45,0xEB,0xDE,0xC6,0x2F,0x2F,0xB4]], - [[0x50,0x51,0x52,0x53,0x55,0x56,0x57,0x58,0x5A,0x5B,0x5C,0x5D,0x5F,0x60,0x61,0x62,0x64,0x65,0x66,0x67,0x69,0x6A,0x6B,0x6C,0x6E,0x6F,0x70,0x71,0x73,0x74,0x75,0x76],[0xA2,0x91,0xD8,0x63,0x01,0xA4,0xA7,0x39,0xF7,0x39,0x21,0x73,0xAA,0x3C,0x60,0x4C],[0x65,0x85,0xC8,0xF4,0x3D,0x13,0xA6,0xBE,0xAB,0x64,0x19,0xFC,0x59,0x35,0xB9,0xD0]], - [[0x78,0x79,0x7A,0x7B,0x7D,0x7E,0x7F,0x80,0x82,0x83,0x84,0x85,0x87,0x88,0x89,0x8A,0x8C,0x8D,0x8E,0x8F,0x91,0x92,0x93,0x94,0x96,0x97,0x98,0x99,0x9B,0x9C,0x9D,0x9E],[0x42,0x64,0xB2,0x69,0x64,0x98,0xDE,0x4D,0xF7,0x97,0x88,0xA9,0xF8,0x3E,0x93,0x90],[0x2A,0x5B,0x56,0xA5,0x96,0x68,0x0F,0xCC,0x0E,0x05,0xF5,0xE0,0xF1,0x51,0xEC,0xAE]], - [[0xA0,0xA1,0xA2,0xA3,0xA5,0xA6,0xA7,0xA8,0xAA,0xAB,0xAC,0xAD,0xAF,0xB0,0xB1,0xB2,0xB4,0xB5,0xB6,0xB7,0xB9,0xBA,0xBB,0xBC,0xBE,0xBF,0xC0,0xC1,0xC3,0xC4,0xC5,0xC6],[0xEE,0x99,0x32,0xB3,0x72,0x18,0x04,0xD5,0xA8,0x3E,0xF5,0x94,0x92,0x45,0xB6,0xF6],[0xF5,0xD6,0xFF,0x41,0x4F,0xD2,0xC6,0x18,0x14,0x94,0xD2,0x0C,0x37,0xF2,0xB8,0xC4]], - [[0xC8,0xC9,0xCA,0xCB,0xCD,0xCE,0xCF,0xD0,0xD2,0xD3,0xD4,0xD5,0xD7,0xD8,0xD9,0xDA,0xDC,0xDD,0xDE,0xDF,0xE1,0xE2,0xE3,0xE4,0xE6,0xE7,0xE8,0xE9,0xEB,0xEC,0xED,0xEE],[0xE6,0x24,0x8F,0x55,0xC5,0xFD,0xCB,0xCA,0x9C,0xBB,0xB0,0x1C,0x88,0xA2,0xEA,0x77],[0x85,0x39,0x9C,0x01,0xF5,0x9F,0xFF,0xB5,0x20,0x4F,0x19,0xF8,0x48,0x2F,0x00,0xB8]], - [[0xF0,0xF1,0xF2,0xF3,0xF5,0xF6,0xF7,0xF8,0xFA,0xFB,0xFC,0xFD,0xFE,0x01,0x00,0x02,0x04,0x05,0x06,0x07,0x09,0x0A,0x0B,0x0C,0x0E,0x0F,0x10,0x11,0x13,0x14,0x15,0x16],[0xB8,0x35,0x8E,0x41,0xB9,0xDF,0xF6,0x5F,0xD4,0x61,0xD5,0x5A,0x99,0x26,0x62,0x47],[0x92,0x09,0x7B,0x4C,0x88,0xA0,0x41,0xDD,0xF9,0x81,0x44,0xBC,0x8D,0x22,0xE8,0xE7]], - [[0x18,0x19,0x1A,0x1B,0x1D,0x1E,0x1F,0x20,0x22,0x23,0x24,0x25,0x27,0x28,0x29,0x2A,0x2C,0x2D,0x2E,0x2F,0x31,0x32,0x33,0x34,0x36,0x37,0x38,0x39,0x3B,0x3C,0x3D,0x3E],[0xF0,0xE2,0xD7,0x22,0x60,0xAF,0x58,0xE2,0x1E,0x01,0x5A,0xB3,0xA4,0xC0,0xD9,0x06],[0x89,0xBD,0x5B,0x73,0xB3,0x56,0xAB,0x41,0x2A,0xEF,0x9F,0x76,0xCE,0xA2,0xD6,0x5C]], - [[0x40,0x41,0x42,0x43,0x45,0x46,0x47,0x48,0x4A,0x4B,0x4C,0x4D,0x4F,0x50,0x51,0x52,0x54,0x55,0x56,0x57,0x59,0x5A,0x5B,0x5C,0x5E,0x5F,0x60,0x61,0x63,0x64,0x65,0x66],[0x47,0x5B,0x8B,0x82,0x3C,0xE8,0x89,0x3D,0xB3,0xC4,0x4A,0x9F,0x2A,0x37,0x9F,0xF7],[0x25,0x36,0x96,0x90,0x93,0xC5,0x5F,0xF9,0x45,0x46,0x92,0xF2,0xFA,0xC2,0xF5,0x30]], - [[0x68,0x69,0x6A,0x6B,0x6D,0x6E,0x6F,0x70,0x72,0x73,0x74,0x75,0x77,0x78,0x79,0x7A,0x7C,0x7D,0x7E,0x7F,0x81,0x82,0x83,0x84,0x86,0x87,0x88,0x89,0x8B,0x8C,0x8D,0x8E],[0x68,0x8F,0x52,0x81,0x94,0x58,0x12,0x86,0x2F,0x5F,0x30,0x76,0xCF,0x80,0x41,0x2F],[0x07,0xFC,0x76,0xA8,0x72,0x84,0x3F,0x3F,0x6E,0x00,0x81,0xEE,0x93,0x96,0xD6,0x37]], - [[0x90,0x91,0x92,0x93,0x95,0x96,0x97,0x98,0x9A,0x9B,0x9C,0x9D,0x9F,0xA0,0xA1,0xA2,0xA4,0xA5,0xA6,0xA7,0xA9,0xAA,0xAB,0xAC,0xAE,0xAF,0xB0,0xB1,0xB3,0xB4,0xB5,0xB6],[0x08,0xD1,0xD2,0xBC,0x75,0x0A,0xF5,0x53,0x36,0x5D,0x35,0xE7,0x5A,0xFA,0xCE,0xAA],[0xE3,0x8B,0xA8,0xEC,0x2A,0xA7,0x41,0x35,0x8D,0xCC,0x93,0xE8,0xF1,0x41,0xC4,0x91]], - [[0xB8,0xB9,0xBA,0xBB,0xBD,0xBE,0xBF,0xC0,0xC2,0xC3,0xC4,0xC5,0xC7,0xC8,0xC9,0xCA,0xCC,0xCD,0xCE,0xCF,0xD1,0xD2,0xD3,0xD4,0xD6,0xD7,0xD8,0xD9,0xDB,0xDC,0xDD,0xDE],[0x87,0x07,0x12,0x1F,0x47,0xCC,0x3E,0xFC,0xEC,0xA5,0xF9,0xA8,0x47,0x49,0x50,0xA1],[0xD0,0x28,0xEE,0x23,0xE4,0xA8,0x90,0x75,0xD0,0xB0,0x3E,0x86,0x8D,0x7D,0x3A,0x42]], - [[0xE0,0xE1,0xE2,0xE3,0xE5,0xE6,0xE7,0xE8,0xEA,0xEB,0xEC,0xED,0xEF,0xF0,0xF1,0xF2,0xF4,0xF5,0xF6,0xF7,0xF9,0xFA,0xFB,0xFC,0xFE,0xFE,0x01,0x01,0x03,0x04,0x05,0x06],[0xE5,0x1A,0xA0,0xB1,0x35,0xDB,0xA5,0x66,0x93,0x9C,0x3B,0x63,0x59,0xA9,0x80,0xC5],[0x8C,0xD9,0x42,0x3D,0xFC,0x45,0x9E,0x54,0x71,0x55,0xC5,0xD1,0xD5,0x22,0xE5,0x40]], - [[0x08,0x09,0x0A,0x0B,0x0D,0x0E,0x0F,0x10,0x12,0x13,0x14,0x15,0x17,0x18,0x19,0x1A,0x1C,0x1D,0x1E,0x1F,0x21,0x22,0x23,0x24,0x26,0x27,0x28,0x29,0x2B,0x2C,0x2D,0x2E],[0x06,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F,0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x21],[0x08,0x0E,0x95,0x17,0xEB,0x16,0x77,0x71,0x9A,0xCF,0x72,0x80,0x86,0x04,0x0A,0xE3]], - [[0x30,0x31,0x32,0x33,0x35,0x36,0x37,0x38,0x3A,0x3B,0x3C,0x3D,0x3F,0x40,0x41,0x42,0x44,0x45,0x46,0x47,0x49,0x4A,0x4B,0x4C,0x4E,0x4F,0x50,0x51,0x53,0x54,0x55,0x56],[0x72,0x61,0x65,0xC1,0x72,0x3F,0xBC,0xF6,0xC0,0x26,0xD7,0xD0,0x0B,0x09,0x10,0x27],[0x7C,0x17,0x00,0x21,0x1A,0x39,0x91,0xFC,0x0E,0xCD,0xED,0x0A,0xB3,0xE5,0x76,0xB0]]]; - - it('128 bit key', async function () { - for (let i = 0; i < testvectors128.length; i++) { - await test_aes(testvectors128[i][1],testvectors128[i][0],testvectors128[i][2]); - } - }); - - it('192 bit key', async function () { - for (let i = 0; i < testvectors192.length; i++) { - await test_aes(testvectors192[i][1],testvectors192[i][0],testvectors192[i][2]); - } - }); - - it('256 bit key', async function () { - for (let i = 0; i < testvectors256.length; i++) { - await test_aes(testvectors256[i][1],testvectors256[i][0],testvectors256[i][2]); - } - }); -}); diff --git a/test/crypto/cipher/index.js b/test/crypto/cipher/index.js index 7f852f20..5ecefe31 100644 --- a/test/crypto/cipher/index.js +++ b/test/crypto/cipher/index.js @@ -1,11 +1,9 @@ -import testAES from './aes'; import testBlowfish from './blowfish'; import testCAST5 from './cast5'; import testDES from './des'; import testTwofish from './twofish'; export default () => describe('Cipher', function () { - testAES(); testBlowfish(); testCAST5(); testDES(); From 151f15e2823e78797976cf8a15f8e08fd76e8632 Mon Sep 17 00:00:00 2001 From: larabr Date: Tue, 27 Feb 2024 14:56:07 +0100 Subject: [PATCH 108/201] Node: drop asn1.js dependency (#1722) asn1.js is a fairly large lib and was simply needed to handle DER encodings in some NodeCrypto operations. This change replaces the dependency by moving to: - JWT encoding for RSA (support added in Node v15) - a much lighter dependency (eckey-utils) for ECDSA, where JWT cannot be used for now, as Node has yet to add decoding support for Brainpool curves. The change also allows us to drop BN.js as a direct dependency, optimising the BigInteger-related chunking in the lightweight build. --- package-lock.json | 59 +++----- package.json | 5 +- rollup.config.js | 2 +- src/crypto/public_key/elliptic/ecdsa.js | 101 ++++---------- src/crypto/public_key/rsa.js | 172 +++++------------------- test/crypto/validate.js | 17 +-- 6 files changed, 92 insertions(+), 264 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0425d70a..cd610457 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,9 +8,6 @@ "name": "openpgp", "version": "6.0.0-alpha.0", "license": "LGPL-3.0+", - "dependencies": { - "asn1.js": "^5.0.0" - }, "devDependencies": { "@openpgp/asmcrypto.js": "^3.1.0", "@openpgp/jsdoc": "^3.6.11", @@ -28,10 +25,10 @@ "@types/chai": "^4.2.14", "argon2id": "^1.0.1", "benchmark": "^2.1.4", - "bn.js": "^4.11.8", "c8": "^8.0.1", "chai": "^4.3.7", "chai-as-promised": "^7.1.1", + "eckey-utils": "^0.7.14", "eslint": "^8.34.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-base": "^15.0.0", @@ -1775,16 +1772,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/asn1.js": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.0.0.tgz", - "integrity": "sha512-Y+FKviD0uyIWWo/xE0XkUl0x1allKFhzEVJ+//2Dgqpy+n+B77MlPNqvyk7Vx50M9XyVzjnRhDqJAEAsyivlbA==", - "dependencies": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, "node_modules/assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", @@ -1882,7 +1869,8 @@ "node_modules/bn.js": { "version": "4.11.8", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "dev": true }, "node_modules/body-parser": { "version": "1.19.2", @@ -2683,6 +2671,12 @@ "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", "dev": true }, + "node_modules/eckey-utils": { + "version": "0.7.14", + "resolved": "https://registry.npmjs.org/eckey-utils/-/eckey-utils-0.7.14.tgz", + "integrity": "sha512-s/mENS+mMnJjDSydy0muBQQHMTWJ1nPe8EiphANZrf+lv/1u35aP9WvWHTWqCBJ21blNIurGF7UoLjtaOpoCFw==", + "dev": true + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -4147,7 +4141,8 @@ "node_modules/inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true }, "node_modules/internal-slot": { "version": "1.0.3", @@ -5216,11 +5211,6 @@ "node": ">=4" } }, - "node_modules/minimalistic-assert": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", - "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=" - }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -8589,16 +8579,6 @@ "es-shim-unscopables": "^1.0.0" } }, - "asn1.js": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.0.0.tgz", - "integrity": "sha512-Y+FKviD0uyIWWo/xE0XkUl0x1allKFhzEVJ+//2Dgqpy+n+B77MlPNqvyk7Vx50M9XyVzjnRhDqJAEAsyivlbA==", - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, "assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", @@ -8681,7 +8661,8 @@ "bn.js": { "version": "4.11.8", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "dev": true }, "body-parser": { "version": "1.19.2", @@ -9292,6 +9273,12 @@ "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", "dev": true }, + "eckey-utils": { + "version": "0.7.14", + "resolved": "https://registry.npmjs.org/eckey-utils/-/eckey-utils-0.7.14.tgz", + "integrity": "sha512-s/mENS+mMnJjDSydy0muBQQHMTWJ1nPe8EiphANZrf+lv/1u35aP9WvWHTWqCBJ21blNIurGF7UoLjtaOpoCFw==", + "dev": true + }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -10420,7 +10407,8 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true }, "internal-slot": { "version": "1.0.3", @@ -11255,11 +11243,6 @@ "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", "dev": true }, - "minimalistic-assert": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", - "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=" - }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", diff --git a/package.json b/package.json index f23b435c..f1ae1e42 100644 --- a/package.json +++ b/package.json @@ -78,10 +78,10 @@ "@types/chai": "^4.2.14", "argon2id": "^1.0.1", "benchmark": "^2.1.4", - "bn.js": "^4.11.8", "c8": "^8.0.1", "chai": "^4.3.7", "chai-as-promised": "^7.1.1", + "eckey-utils": "^0.7.14", "eslint": "^8.34.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-base": "^15.0.0", @@ -106,9 +106,6 @@ "typescript": "^5.3.3", "web-streams-polyfill": "^3.2.0" }, - "dependencies": { - "asn1.js": "^5.0.0" - }, "repository": { "type": "git", "url": "https://github.com/openpgpjs/openpgpjs" diff --git a/rollup.config.js b/rollup.config.js index 22a1b6c5..c29e0e51 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -14,7 +14,7 @@ import { wasm } from '@rollup/plugin-wasm'; // import pkg from './package.json' assert { type: 'json' }; const pkg = JSON.parse(readFileSync('./package.json')); -const nodeDependencies = Object.keys(pkg.dependencies); +const nodeDependencies = Object.keys(pkg.dependencies || {}); const nodeBuiltinModules = builtinModules.concat(['module']); const wasmOptions = { diff --git a/src/crypto/public_key/elliptic/ecdsa.js b/src/crypto/public_key/elliptic/ecdsa.js index 44d63755..35d3c080 100644 --- a/src/crypto/public_key/elliptic/ecdsa.js +++ b/src/crypto/public_key/elliptic/ecdsa.js @@ -24,7 +24,7 @@ import enums from '../../../enums'; import util from '../../../util'; import { getRandomBytes } from '../../random'; import hash from '../../hash'; -import { CurveWithOID, webCurves, privateToJWK, rawPublicToJWK, validateStandardParams } from './oid_curves'; +import { CurveWithOID, webCurves, privateToJWK, rawPublicToJWK, validateStandardParams, nodeCurves } from './oid_curves'; const webCrypto = util.getWebCrypto(); const nodeCrypto = util.getNodeCrypto(); @@ -63,13 +63,8 @@ export async function sign(oid, hashAlgo, message, publicKey, privateKey, hashed util.printDebugError('Browser did not support signing: ' + err.message); } break; - case 'node': { - const signature = await nodeSign(curve, hashAlgo, message, keyPair); - return { - r: signature.r.toArrayLike(Uint8Array), - s: signature.s.toArrayLike(Uint8Array) - }; - } + case 'node': + return nodeSign(curve, hashAlgo, message, privateKey); } } @@ -247,85 +242,45 @@ async function webVerify(curve, hashAlgo, { r, s }, message, publicKey) { ); } -async function nodeSign(curve, hashAlgo, message, keyPair) { +async function nodeSign(curve, hashAlgo, message, privateKey) { + // JWT encoding cannot be used for now, as Brainpool curves are not supported + const ecKeyUtils = util.nodeRequire('eckey-utils'); + const nodeBuffer = util.getNodeBuffer(); + const { privateKey: derPrivateKey } = ecKeyUtils.generateDer({ + curveName: nodeCurves[curve.name], + privateKey: nodeBuffer.from(privateKey) + }); + const sign = nodeCrypto.createSign(enums.read(enums.hash, hashAlgo)); sign.write(message); sign.end(); - const key = ECPrivateKey.encode({ - version: 1, - parameters: curve.oid, - privateKey: Array.from(keyPair.privateKey), - publicKey: { unused: 0, data: Array.from(keyPair.publicKey) } - }, 'pem', { - label: 'EC PRIVATE KEY' - }); - return ECDSASignature.decode(sign.sign(key), 'der'); + const signature = new Uint8Array(sign.sign({ key: derPrivateKey, format: 'der', type: 'sec1', dsaEncoding: 'ieee-p1363' })); + const len = curve.payloadSize; + + return { + r: signature.subarray(0, len), + s: signature.subarray(len, len << 1) + }; } async function nodeVerify(curve, hashAlgo, { r, s }, message, publicKey) { - const { default: BN } = await import('bn.js'); + const ecKeyUtils = util.nodeRequire('eckey-utils'); + const nodeBuffer = util.getNodeBuffer(); + const { publicKey: derPublicKey } = ecKeyUtils.generateDer({ + curveName: nodeCurves[curve.name], + publicKey: nodeBuffer.from(publicKey) + }); const verify = nodeCrypto.createVerify(enums.read(enums.hash, hashAlgo)); verify.write(message); verify.end(); - const key = SubjectPublicKeyInfo.encode({ - algorithm: { - algorithm: [1, 2, 840, 10045, 2, 1], - parameters: curve.oid - }, - subjectPublicKey: { unused: 0, data: Array.from(publicKey) } - }, 'pem', { - label: 'PUBLIC KEY' - }); - const signature = ECDSASignature.encode({ - r: new BN(r), s: new BN(s) - }, 'der'); + + const signature = util.concatUint8Array([r, s]); try { - return verify.verify(key, signature); + return verify.verify({ key: derPublicKey, format: 'der', type: 'spki', dsaEncoding: 'ieee-p1363' }, signature); } catch (err) { return false; } } - -// Originally written by Owen Smith https://github.com/omsmith -// Adapted on Feb 2018 from https://github.com/Brightspace/node-jwk-to-pem/ - -/* eslint-disable no-invalid-this */ - -const asn1 = nodeCrypto ? util.nodeRequire('asn1.js') : undefined; - -const ECDSASignature = nodeCrypto ? - asn1.define('ECDSASignature', function() { - this.seq().obj( - this.key('r').int(), - this.key('s').int() - ); - }) : undefined; - -const ECPrivateKey = nodeCrypto ? - asn1.define('ECPrivateKey', function() { - this.seq().obj( - this.key('version').int(), - this.key('privateKey').octstr(), - this.key('parameters').explicit(0).optional().any(), - this.key('publicKey').explicit(1).optional().bitstr() - ); - }) : undefined; - -const AlgorithmIdentifier = nodeCrypto ? - asn1.define('AlgorithmIdentifier', function() { - this.seq().obj( - this.key('algorithm').objid(), - this.key('parameters').optional().any() - ); - }) : undefined; - -const SubjectPublicKeyInfo = nodeCrypto ? - asn1.define('SubjectPublicKeyInfo', function() { - this.seq().obj( - this.key('algorithm').use(AlgorithmIdentifier), - this.key('subjectPublicKey').bitstr() - ); - }) : undefined; diff --git a/src/crypto/public_key/rsa.js b/src/crypto/public_key/rsa.js index 6387bc25..79826f23 100644 --- a/src/crypto/public_key/rsa.js +++ b/src/crypto/public_key/rsa.js @@ -28,30 +28,6 @@ import enums from '../../enums'; const webCrypto = util.getWebCrypto(); const nodeCrypto = util.getNodeCrypto(); -const asn1 = nodeCrypto ? util.nodeRequire('asn1.js') : undefined; - -/* eslint-disable no-invalid-this */ -const RSAPrivateKey = nodeCrypto ? asn1.define('RSAPrivateKey', function () { - this.seq().obj( // used for native NodeJS crypto - this.key('version').int(), // 0 - this.key('modulus').int(), // n - this.key('publicExponent').int(), // e - this.key('privateExponent').int(), // d - this.key('prime1').int(), // p - this.key('prime2').int(), // q - this.key('exponent1').int(), // dp - this.key('exponent2').int(), // dq - this.key('coefficient').int() // u - ); -}) : undefined; - -const RSAPublicKey = nodeCrypto ? asn1.define('RSAPubliceKey', function () { - this.seq().obj( // used for native NodeJS crypto - this.key('modulus').int(), // n - this.key('publicExponent').int() // e - ); -}) : undefined; -/* eslint-enable no-invalid-this */ /** Create signature * @param {module:enums.hash} hashAlgo - Hash algorithm @@ -178,47 +154,24 @@ export async function generate(bits, e) { // https://tools.ietf.org/html/draft-ietf-jose-json-web-key-33 const jwk = await webCrypto.exportKey('jwk', keyPair.privateKey); // map JWK parameters to corresponding OpenPGP names - return { - n: b64ToUint8Array(jwk.n), - e: e.toUint8Array(), - d: b64ToUint8Array(jwk.d), - // switch p and q - p: b64ToUint8Array(jwk.q), - q: b64ToUint8Array(jwk.p), - // Since p and q are switched in places, u is the inverse of jwk.q - u: b64ToUint8Array(jwk.qi) - }; - } else if (util.getNodeCrypto() && nodeCrypto.generateKeyPair && RSAPrivateKey) { + return jwkToPrivate(jwk, e); + } else if (util.getNodeCrypto()) { const opts = { modulusLength: bits, publicExponent: e.toNumber(), - publicKeyEncoding: { type: 'pkcs1', format: 'der' }, - privateKeyEncoding: { type: 'pkcs1', format: 'der' } + publicKeyEncoding: { type: 'pkcs1', format: 'jwk' }, + privateKeyEncoding: { type: 'pkcs1', format: 'jwk' } }; - const prv = await new Promise((resolve, reject) => { - nodeCrypto.generateKeyPair('rsa', opts, (err, _, der) => { + const jwk = await new Promise((resolve, reject) => { + nodeCrypto.generateKeyPair('rsa', opts, (err, _, jwkPrivateKey) => { if (err) { reject(err); } else { - resolve(RSAPrivateKey.decode(der, 'der')); + resolve(jwkPrivateKey); } }); }); - /** - * OpenPGP spec differs from DER spec, DER: `u = (inverse of q) mod p`, OpenPGP: `u = (inverse of p) mod q`. - * @link https://tools.ietf.org/html/rfc3447#section-3.2 - * @link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-08#section-5.6.1 - */ - return { - n: prv.modulus.toArrayLike(Uint8Array), - e: prv.publicExponent.toArrayLike(Uint8Array), - d: prv.privateExponent.toArrayLike(Uint8Array), - // switch p and q - p: prv.prime2.toArrayLike(Uint8Array), - q: prv.prime1.toArrayLike(Uint8Array), - // Since p and q are switched in places, we can keep u as defined by DER - u: prv.coefficient.toArrayLike(Uint8Array) - }; + return jwkToPrivate(jwk, e); } // RSA keygen fallback using 40 iterations of the Miller-Rabin test @@ -332,36 +285,12 @@ async function webSign(hashName, data, n, e, d, p, q, u) { } async function nodeSign(hashAlgo, data, n, e, d, p, q, u) { - const { default: BN } = await import('bn.js'); - const pBNum = new BN(p); - const qBNum = new BN(q); - const dBNum = new BN(d); - const dq = dBNum.mod(qBNum.subn(1)); // d mod (q-1) - const dp = dBNum.mod(pBNum.subn(1)); // d mod (p-1) const sign = nodeCrypto.createSign(enums.read(enums.hash, hashAlgo)); sign.write(data); sign.end(); - const keyObject = { - version: 0, - modulus: new BN(n), - publicExponent: new BN(e), - privateExponent: new BN(d), - // switch p and q - prime1: new BN(q), - prime2: new BN(p), - // switch dp and dq - exponent1: dq, - exponent2: dp, - coefficient: new BN(u) - }; - if (typeof nodeCrypto.createPrivateKey !== 'undefined') { //from version 11.6.0 Node supports der encoded key objects - const der = RSAPrivateKey.encode(keyObject, 'der'); - return new Uint8Array(sign.sign({ key: der, format: 'der', type: 'pkcs1' })); - } - const pem = RSAPrivateKey.encode(keyObject, 'pem', { - label: 'RSA PRIVATE KEY' - }); - return new Uint8Array(sign.sign(pem)); + + const jwk = await privateToJWK(n, e, d, p, q, u); + return new Uint8Array(sign.sign({ key: jwk, format: 'jwk', type: 'pkcs1' })); } async function bnVerify(hashAlgo, s, n, e, hashed) { @@ -388,24 +317,13 @@ async function webVerify(hashName, data, s, n, e) { } async function nodeVerify(hashAlgo, data, s, n, e) { - const { default: BN } = await import('bn.js'); + const jwk = publicToJWK(n, e); + const key = { key: jwk, format: 'jwk', type: 'pkcs1' }; const verify = nodeCrypto.createVerify(enums.read(enums.hash, hashAlgo)); verify.write(data); verify.end(); - const keyObject = { - modulus: new BN(n), - publicExponent: new BN(e) - }; - let key; - if (typeof nodeCrypto.createPrivateKey !== 'undefined') { //from version 11.6.0 Node supports der encoded key objects - const der = RSAPublicKey.encode(keyObject, 'der'); - key = { key: der, format: 'der', type: 'pkcs1' }; - } else { - key = RSAPublicKey.encode(keyObject, 'pem', { - label: 'RSA PUBLIC KEY' - }); - } + try { return await verify.verify(key, s); } catch (err) { @@ -414,22 +332,9 @@ async function nodeVerify(hashAlgo, data, s, n, e) { } async function nodeEncrypt(data, n, e) { - const { default: BN } = await import('bn.js'); + const jwk = publicToJWK(n, e); + const key = { key: jwk, format: 'jwk', type: 'pkcs1', padding: nodeCrypto.constants.RSA_PKCS1_PADDING }; - const keyObject = { - modulus: new BN(n), - publicExponent: new BN(e) - }; - let key; - if (typeof nodeCrypto.createPrivateKey !== 'undefined') { - const der = RSAPublicKey.encode(keyObject, 'der'); - key = { key: der, format: 'der', type: 'pkcs1', padding: nodeCrypto.constants.RSA_PKCS1_PADDING }; - } else { - const pem = RSAPublicKey.encode(keyObject, 'pem', { - label: 'RSA PUBLIC KEY' - }); - key = { key: pem, padding: nodeCrypto.constants.RSA_PKCS1_PADDING }; - } return new Uint8Array(nodeCrypto.publicEncrypt(key, data)); } @@ -446,36 +351,9 @@ async function bnEncrypt(data, n, e) { } async function nodeDecrypt(data, n, e, d, p, q, u, randomPayload) { - const { default: BN } = await import('bn.js'); + const jwk = await privateToJWK(n, e, d, p, q, u); + const key = { key: jwk, format: 'jwk' , type: 'pkcs1', padding: nodeCrypto.constants.RSA_PKCS1_PADDING }; - const pBNum = new BN(p); - const qBNum = new BN(q); - const dBNum = new BN(d); - const dq = dBNum.mod(qBNum.subn(1)); // d mod (q-1) - const dp = dBNum.mod(pBNum.subn(1)); // d mod (p-1) - const keyObject = { - version: 0, - modulus: new BN(n), - publicExponent: new BN(e), - privateExponent: new BN(d), - // switch p and q - prime1: new BN(q), - prime2: new BN(p), - // switch dp and dq - exponent1: dq, - exponent2: dp, - coefficient: new BN(u) - }; - let key; - if (typeof nodeCrypto.createPrivateKey !== 'undefined') { - const der = RSAPrivateKey.encode(keyObject, 'der'); - key = { key: der, format: 'der' , type: 'pkcs1', padding: nodeCrypto.constants.RSA_PKCS1_PADDING }; - } else { - const pem = RSAPrivateKey.encode(keyObject, 'pem', { - label: 'RSA PRIVATE KEY' - }); - key = { key: pem, padding: nodeCrypto.constants.RSA_PKCS1_PADDING }; - } try { return new Uint8Array(nodeCrypto.privateDecrypt(key, data)); } catch (err) { @@ -570,3 +448,17 @@ function publicToJWK(n, e) { ext: true }; } + +/** Convert JWK private key to OpenPGP private key params */ +function jwkToPrivate(jwk, e) { + return { + n: b64ToUint8Array(jwk.n), + e: e.toUint8Array(), + d: b64ToUint8Array(jwk.d), + // switch p and q + p: b64ToUint8Array(jwk.q), + q: b64ToUint8Array(jwk.p), + // Since p and q are switched in places, u is the inverse of jwk.q + u: b64ToUint8Array(jwk.qi) + }; +} diff --git a/test/crypto/validate.js b/test/crypto/validate.js index 6a46d030..e76e4947 100644 --- a/test/crypto/validate.js +++ b/test/crypto/validate.js @@ -1,9 +1,9 @@ -import BN from 'bn.js'; import { use as chaiUse, expect } from 'chai'; import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import chaiUse(chaiAsPromised); import openpgp from '../initOpenpgp.js'; +import util from '../../src/util.js'; const armoredDSAKey = `-----BEGIN PGP PRIVATE KEY BLOCK----- @@ -387,15 +387,16 @@ export default () => { }); it('detect g with small order', async function() { - const keyPacket = await cloneKeyPacket(egKey); - const p = keyPacket.publicParams.p; - const g = keyPacket.publicParams.g; + const BigInteger = await util.getBigInteger(); - const pBN = new BN(p); - const gModP = new BN(g).toRed(new BN.red(pBN)); + const keyPacket = await cloneKeyPacket(egKey); + const { p, g } = keyPacket.publicParams; + + const pBN = new BigInteger(p); + const gBN = new BigInteger(g); // g**(p-1)/2 has order 2 - const gOrd2 = gModP.redPow(pBN.subn(1).shrn(1)); - keyPacket.publicParams.g = gOrd2.toArrayLike(Uint8Array, 'be'); + const gOrd2 = gBN.modExp(pBN.dec().irightShift(new BigInteger(1)), pBN); + keyPacket.publicParams.g = gOrd2.toUint8Array(); await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid'); }); }); From 15adf84a7dcec0bf2b33a59034339272f610135c Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Wed, 28 Feb 2024 12:44:05 +0100 Subject: [PATCH 109/201] Run npm update --- package-lock.json | 8306 ++++++++++++++++++++++++++------------------- package.json | 34 +- 2 files changed, 4823 insertions(+), 3517 deletions(-) diff --git a/package-lock.json b/package-lock.json index cd610457..eca4d50a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,8 +11,8 @@ "devDependencies": { "@openpgp/asmcrypto.js": "^3.1.0", "@openpgp/jsdoc": "^3.6.11", - "@openpgp/noble-curves": "^1.2.1-0", - "@openpgp/noble-hashes": "^1.3.3-0", + "@openpgp/noble-curves": "^1.3.0", + "@openpgp/noble-hashes": "^1.3.3", "@openpgp/seek-bzip": "^1.0.5-git", "@openpgp/tweetnacl": "^1.0.4-1", "@openpgp/web-stream-tools": "~0.1.1", @@ -22,36 +22,36 @@ "@rollup/plugin-replace": "^5.0.5", "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-wasm": "^6.2.2", - "@types/chai": "^4.2.14", + "@types/chai": "^4.3.12", "argon2id": "^1.0.1", "benchmark": "^2.1.4", "c8": "^8.0.1", - "chai": "^4.3.7", + "chai": "^4.4.1", "chai-as-promised": "^7.1.1", "eckey-utils": "^0.7.14", - "eslint": "^8.34.0", + "eslint": "^8.57.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-base": "^15.0.0", - "eslint-plugin-chai-friendly": "^0.7.2", - "eslint-plugin-import": "^2.27.5", + "eslint-plugin-chai-friendly": "^0.7.4", + "eslint-plugin-import": "^2.29.1", "eslint-plugin-unicorn": "^48.0.1", "fflate": "^0.7.4", "http-server": "^14.1.1", - "karma": "^6.4.0", + "karma": "^6.4.3", "karma-browserstack-launcher": "^1.6.0", - "karma-chrome-launcher": "^3.1.1", + "karma-chrome-launcher": "^3.2.0", "karma-firefox-launcher": "^2.1.2", "karma-mocha": "^2.0.1", "karma-mocha-reporter": "^2.2.5", - "karma-webkit-launcher": "^2.1.0", - "mocha": "^10.2.0", - "playwright": "^1.30.0", - "rollup": "^4.9.5", - "sinon": "^15.1.0", - "ts-node": "^10.9.1", - "tsx": "^4.7.0", + "karma-webkit-launcher": "^2.4.0", + "mocha": "^10.3.0", + "playwright": "^1.42.0", + "rollup": "^4.12.0", + "sinon": "^15.2.0", + "ts-node": "^10.9.2", + "tsx": "^4.7.1", "typescript": "^5.3.3", - "web-streams-polyfill": "^3.2.0" + "web-streams-polyfill": "^3.3.3" }, "engines": { "node": ">= 16.5.0" @@ -105,6 +105,39 @@ "node": ">=4" } }, + "node_modules/@babel/code-frame/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/code-frame/node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -166,6 +199,39 @@ "node": ">=4" } }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/highlight/node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -179,9 +245,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz", - "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==", + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz", + "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -191,27 +257,13 @@ } }, "node_modules/@babel/runtime": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.4.tgz", - "integrity": "sha512-EXpLCrk55f+cYqmHsSR+yD/0gAIMxxA9QK9lnQWzhMCvt+YmoBN7Zx94s++Kv0+unHk39vxNO8t+CMA2WSS3wA==", + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz", + "integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==", "dev": true, "peer": true, "dependencies": { - "regenerator-runtime": "^0.13.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/runtime-corejs3": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.19.4.tgz", - "integrity": "sha512-HzjQ8+dzdx7dmZy4DQ8KV8aHi/74AjEbBGTFutBmg/pd3dY5/q1sfuOGPTFGEytlQhWoeVXqcK5BwMgIkRkNDQ==", - "dev": true, - "peer": true, - "dependencies": { - "core-js-pure": "^3.25.1", - "regenerator-runtime": "^0.13.4" + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" @@ -638,18 +690,18 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.9.1.tgz", - "integrity": "sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", - "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", @@ -669,108 +721,29 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/@eslint/eslintrc/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/@eslint/eslintrc/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.23.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", - "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@eslint/eslintrc/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@eslint/eslintrc/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/@eslint/js": { - "version": "8.51.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.51.0.tgz", - "integrity": "sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.11", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", - "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", "minimatch": "^3.0.5" }, "engines": { "node": ">=10.10.0" } }, - "node_modules/@humanwhocodes/config-array/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -785,11 +758,101 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", "dev": true }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", @@ -800,9 +863,9 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.4.tgz", + "integrity": "sha512-Oud2QPM5dHviZNn4y/WhhYKSXksv+1xLEIsNrAbGcFzUN3ubqWRFT5gwPchNc5NuzILOU4tPBDTZ4VwhL8Y7cw==", "dev": true, "dependencies": { "@jridgewell/set-array": "^1.0.1", @@ -814,9 +877,9 @@ } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, "engines": { "node": ">=6.0.0" @@ -842,19 +905,19 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.17", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", - "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.23.tgz", + "integrity": "sha512-9/4foRoUKp8s96tSkh8DlAAc5A0Ty8vLXld+l9gjKKY6ckwI8G15f0hskGmuLZu78ZlGa1vtsfOa+lnB4vG6Jg==", "dev": true, "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/@nodelib/fs.scandir": { @@ -927,43 +990,22 @@ "node": ">=12.0.0" } }, - "node_modules/@openpgp/jsdoc/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@openpgp/jsdoc/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@openpgp/noble-curves": { - "version": "1.2.1-0", - "resolved": "https://registry.npmjs.org/@openpgp/noble-curves/-/noble-curves-1.2.1-0.tgz", - "integrity": "sha512-RUJ3NIGJ04VbUHEOXYxXKKgD+u7D5fJYUox3Ewu1mPbgdjEUvS96nq6xZrCPCCyOTJlyh7jR1tcbOUzWJFiJbQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@openpgp/noble-curves/-/noble-curves-1.3.0.tgz", + "integrity": "sha512-6QjsDyzTc5AZMC3CDRcp2L/VuxIcfxFT4kCWAV/gk4OcjWtgh49S5M7pjkOzYzjhpapu5HYIWkuUdTxDC5WXEw==", "dev": true, "dependencies": { - "@openpgp/noble-hashes": "1.3.3-0" + "@openpgp/noble-hashes": "1.3.3" }, "funding": { "url": "https://paulmillr.com/funding/" } }, "node_modules/@openpgp/noble-hashes": { - "version": "1.3.3-0", - "resolved": "https://registry.npmjs.org/@openpgp/noble-hashes/-/noble-hashes-1.3.3-0.tgz", - "integrity": "sha512-2MOWNAzEm5fMu3u90HSLxddYU6Fr8P7/7knXrPHyS7DiJevOlDmPES/AZxcWQfhHrwdNLL0fRVdOHkftvIcXVQ==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@openpgp/noble-hashes/-/noble-hashes-1.3.3.tgz", + "integrity": "sha512-CPDNePrQTQrL5Fxd/K3B53Gty4xbNVxnMSUdDmYjW5tTpRqOlme0INYTnnQqoE/XUdIlq5fByOMDuDWR5JpXZw==", "dev": true, "dependencies": { "@types/bn.js": "^4.11.6", @@ -1012,6 +1054,16 @@ } } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@rollup/plugin-alias": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.1.0.tgz", @@ -1057,46 +1109,6 @@ } } }, - "node_modules/@rollup/plugin-commonjs/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@rollup/plugin-commonjs/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@rollup/plugin-commonjs/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@rollup/plugin-node-resolve": { "version": "15.2.3", "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz", @@ -1122,21 +1134,6 @@ } } }, - "node_modules/@rollup/plugin-node-resolve/node_modules/is-builtin-module": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", - "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", - "dev": true, - "dependencies": { - "builtin-modules": "^3.3.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@rollup/plugin-replace": { "version": "5.0.5", "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-5.0.5.tgz", @@ -1180,15 +1177,6 @@ } } }, - "node_modules/@rollup/plugin-terser/node_modules/serialize-javascript": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", - "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, "node_modules/@rollup/plugin-wasm": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/@rollup/plugin-wasm/-/plugin-wasm-6.2.2.tgz", @@ -1232,9 +1220,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.9.6.tgz", - "integrity": "sha512-MVNXSSYN6QXOulbHpLMKYi60ppyO13W9my1qogeiAqtjb2yR4LSmfU2+POvDkLzhjYLXz9Rf9+9a3zFHW1Lecg==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.12.0.tgz", + "integrity": "sha512-+ac02NL/2TCKRrJu2wffk1kZ+RyqxVUlbjSagNgPm94frxtr+XDL12E5Ll1enWskLrtrZ2r8L3wED1orIibV/w==", "cpu": [ "arm" ], @@ -1245,9 +1233,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.9.6.tgz", - "integrity": "sha512-T14aNLpqJ5wzKNf5jEDpv5zgyIqcpn1MlwCrUXLrwoADr2RkWA0vOWP4XxbO9aiO3dvMCQICZdKeDrFl7UMClw==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.12.0.tgz", + "integrity": "sha512-OBqcX2BMe6nvjQ0Nyp7cC90cnumt8PXmO7Dp3gfAju/6YwG0Tj74z1vKrfRz7qAv23nBcYM8BCbhrsWqO7PzQQ==", "cpu": [ "arm64" ], @@ -1258,9 +1246,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.9.6.tgz", - "integrity": "sha512-CqNNAyhRkTbo8VVZ5R85X73H3R5NX9ONnKbXuHisGWC0qRbTTxnF1U4V9NafzJbgGM0sHZpdO83pLPzq8uOZFw==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.12.0.tgz", + "integrity": "sha512-X64tZd8dRE/QTrBIEs63kaOBG0b5GVEd3ccoLtyf6IdXtHdh8h+I56C2yC3PtC9Ucnv0CpNFJLqKFVgCYe0lOQ==", "cpu": [ "arm64" ], @@ -1271,9 +1259,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.9.6.tgz", - "integrity": "sha512-zRDtdJuRvA1dc9Mp6BWYqAsU5oeLixdfUvkTHuiYOHwqYuQ4YgSmi6+/lPvSsqc/I0Omw3DdICx4Tfacdzmhog==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.12.0.tgz", + "integrity": "sha512-cc71KUZoVbUJmGP2cOuiZ9HSOP14AzBAThn3OU+9LcA1+IUqswJyR1cAJj3Mg55HbjZP6OLAIscbQsQLrpgTOg==", "cpu": [ "x64" ], @@ -1284,9 +1272,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.9.6.tgz", - "integrity": "sha512-oNk8YXDDnNyG4qlNb6is1ojTOGL/tRhbbKeE/YuccItzerEZT68Z9gHrY3ROh7axDc974+zYAPxK5SH0j/G+QQ==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.12.0.tgz", + "integrity": "sha512-a6w/Y3hyyO6GlpKL2xJ4IOh/7d+APaqLYdMf86xnczU3nurFTaVN9s9jOXQg97BE4nYm/7Ga51rjec5nfRdrvA==", "cpu": [ "arm" ], @@ -1297,9 +1285,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.9.6.tgz", - "integrity": "sha512-Z3O60yxPtuCYobrtzjo0wlmvDdx2qZfeAWTyfOjEDqd08kthDKexLpV97KfAeUXPosENKd8uyJMRDfFMxcYkDQ==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.12.0.tgz", + "integrity": "sha512-0fZBq27b+D7Ar5CQMofVN8sggOVhEtzFUwOwPppQt0k+VR+7UHMZZY4y+64WJ06XOhBTKXtQB/Sv0NwQMXyNAA==", "cpu": [ "arm64" ], @@ -1310,9 +1298,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.9.6.tgz", - "integrity": "sha512-gpiG0qQJNdYEVad+1iAsGAbgAnZ8j07FapmnIAQgODKcOTjLEWM9sRb+MbQyVsYCnA0Im6M6QIq6ax7liws6eQ==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.12.0.tgz", + "integrity": "sha512-eTvzUS3hhhlgeAv6bfigekzWZjaEX9xP9HhxB0Dvrdbkk5w/b+1Sxct2ZuDxNJKzsRStSq1EaEkVSEe7A7ipgQ==", "cpu": [ "arm64" ], @@ -1323,9 +1311,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.9.6.tgz", - "integrity": "sha512-+uCOcvVmFUYvVDr27aiyun9WgZk0tXe7ThuzoUTAukZJOwS5MrGbmSlNOhx1j80GdpqbOty05XqSl5w4dQvcOA==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.12.0.tgz", + "integrity": "sha512-ix+qAB9qmrCRiaO71VFfY8rkiAZJL8zQRXveS27HS+pKdjwUfEhqo2+YF2oI+H/22Xsiski+qqwIBxVewLK7sw==", "cpu": [ "riscv64" ], @@ -1336,9 +1324,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.9.6.tgz", - "integrity": "sha512-HUNqM32dGzfBKuaDUBqFB7tP6VMN74eLZ33Q9Y1TBqRDn+qDonkAUyKWwF9BR9unV7QUzffLnz9GrnKvMqC/fw==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.12.0.tgz", + "integrity": "sha512-TenQhZVOtw/3qKOPa7d+QgkeM6xY0LtwzR8OplmyL5LrgTWIXpTQg2Q2ycBf8jm+SFW2Wt/DTn1gf7nFp3ssVA==", "cpu": [ "x64" ], @@ -1349,9 +1337,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.9.6.tgz", - "integrity": "sha512-ch7M+9Tr5R4FK40FHQk8VnML0Szi2KRujUgHXd/HjuH9ifH72GUmw6lStZBo3c3GB82vHa0ZoUfjfcM7JiiMrQ==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.12.0.tgz", + "integrity": "sha512-LfFdRhNnW0zdMvdCb5FNuWlls2WbbSridJvxOvYWgSBOYZtgBfW9UGNJG//rwMqTX1xQE9BAodvMH9tAusKDUw==", "cpu": [ "x64" ], @@ -1362,9 +1350,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.9.6.tgz", - "integrity": "sha512-VD6qnR99dhmTQ1mJhIzXsRcTBvTjbfbGGwKAHcu+52cVl15AC/kplkhxzW/uT0Xl62Y/meBKDZvoJSJN+vTeGA==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.12.0.tgz", + "integrity": "sha512-JPDxovheWNp6d7AHCgsUlkuCKvtu3RB55iNEkaQcf0ttsDU/JZF+iQnYcQJSk/7PtT4mjjVG8N1kpwnI9SLYaw==", "cpu": [ "arm64" ], @@ -1375,9 +1363,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.9.6.tgz", - "integrity": "sha512-J9AFDq/xiRI58eR2NIDfyVmTYGyIZmRcvcAoJ48oDld/NTR8wyiPUu2X/v1navJ+N/FGg68LEbX3Ejd6l8B7MQ==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.12.0.tgz", + "integrity": "sha512-fjtuvMWRGJn1oZacG8IPnzIV6GF2/XG+h71FKn76OYFqySXInJtseAqdprVTDTyqPxQOG9Exak5/E9Z3+EJ8ZA==", "cpu": [ "ia32" ], @@ -1388,9 +1376,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.9.6.tgz", - "integrity": "sha512-jqzNLhNDvIZOrt69Ce4UjGRpXJBzhUBzawMwnaDAwyHriki3XollsewxWzOzz+4yOFDkuJHtTsZFwMxhYJWmLQ==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.12.0.tgz", + "integrity": "sha512-ZYmr5mS2wd4Dew/JjT0Fqi2NPB/ZhZ2VvPp7SmvPZb4Y1CG/LRcS6tcRo2cYU7zLK5A7cdbhWnnWmUjoI4qapg==", "cpu": [ "x64" ], @@ -1401,18 +1389,18 @@ ] }, "node_modules/@sinonjs/commons": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", - "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", "dev": true, "dependencies": { "type-detect": "4.0.8" } }, "node_modules/@sinonjs/fake-timers": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.2.0.tgz", - "integrity": "sha512-OPwQlEdg40HAj5KNF8WW6q2KG4Z+cBCZb3m4ninfTZKaBmbIJodviQsDBoYMPHkOyJJMHnOJo5j2+LKDOhOACg==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", "dev": true, "dependencies": { "@sinonjs/commons": "^3.0.0" @@ -1469,9 +1457,9 @@ "dev": true }, "node_modules/@tsconfig/node16": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", "dev": true }, "node_modules/@types/bn.js": { @@ -1484,9 +1472,9 @@ } }, "node_modules/@types/chai": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.5.tgz", - "integrity": "sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==", + "version": "4.3.12", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.12.tgz", + "integrity": "sha512-zNKDHG/1yxm8Il6uCCVsm+dRdEsJlFoDu73X17y09bId6UwoYww+vFBsAcRzl8knM1sab3Dp1VRikFQwDOtDDw==", "dev": true }, "node_modules/@types/cookie": { @@ -1496,9 +1484,9 @@ "dev": true }, "node_modules/@types/cors": { - "version": "2.8.13", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz", - "integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==", + "version": "2.8.17", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", + "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", "dev": true, "dependencies": { "@types/node": "*" @@ -1523,9 +1511,9 @@ "dev": true }, "node_modules/@types/linkify-it": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz", - "integrity": "sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.5.tgz", + "integrity": "sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==", "dev": true }, "node_modules/@types/markdown-it": { @@ -1539,21 +1527,24 @@ } }, "node_modules/@types/mdurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz", - "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.5.tgz", + "integrity": "sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==", "dev": true }, "node_modules/@types/node": { - "version": "13.13.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.2.tgz", - "integrity": "sha512-LB2R1Oyhpg8gu4SON/mfforE525+Hi/M1ineICEDftqNVTyFg1aRIeGuTvXAoWHc4nbrFncWtJgMmoyRvuGh7A==", - "dev": true + "version": "20.11.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.21.tgz", + "integrity": "sha512-/ySDLGscFPNasfqStUuWWPfL78jompfIoVzLJPVVAHBh6rpG68+pI2Gk+fNLeI8/f1yPYL4s46EleVIc20F1Ow==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } }, "node_modules/@types/normalize-package-data": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.3.tgz", - "integrity": "sha512-ehPtgRgaULsFG8x0NeYJvmyH1hmlfsNLujHe9dQEia/7MAJYdzMSi19JtchUHjmBA6XC/75dK55mzZH+RyieSg==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", "dev": true }, "node_modules/@types/resolve": { @@ -1562,6 +1553,12 @@ "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", "dev": true }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -1576,9 +1573,9 @@ } }, "node_modules/acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -1597,24 +1594,24 @@ } }, "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", "dev": true, "engines": { "node": ">=0.4.0" } }, "node_modules/agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "dev": true, "dependencies": { - "es6-promisify": "^5.0.0" + "debug": "4" }, "engines": { - "node": ">= 4.0.0" + "node": ">= 6.0.0" } }, "node_modules/ajv": { @@ -1666,18 +1663,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/ansi-styles/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -1703,30 +1688,48 @@ "integrity": "sha512-rsiD3lX+0L0CsiZARp3bf9EGxprtuWAT7PpiJd+Fk53URV0/USOQkBIP1dLTV8t6aui0ECbymQ9W9YCcTd6XgA==", "dev": true }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, "node_modules/aria-query": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", - "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", "dev": true, "peer": true, "dependencies": { - "@babel/runtime": "^7.10.2", - "@babel/runtime-corejs3": "^7.10.2" + "dequal": "^2.0.3" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" }, "engines": { - "node": ">=6.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/array-includes": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", - "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", + "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "get-intrinsic": "^1.1.3", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", "is-string": "^1.0.7" }, "engines": { @@ -1736,15 +1739,53 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array.prototype.flat": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", - "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", + "node_modules/array.prototype.filter": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array.prototype.filter/-/array.prototype.filter-1.0.3.tgz", + "integrity": "sha512-VizNcj/RGJiUyQBgzwxzE5oHdeuXY5hSbbmKMlphj1cy1Vl7Pn2asCGbSrru6hSQjmCzqTBPVWAF/whmEOVHbw==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.4.tgz", + "integrity": "sha512-hzvSHUshSpCflDR1QMUBLHGHP1VIEBegT4pix9H/Z92Xw3ySoy6c2qh7lJWTJnRJ8JCZ9bJNCgTyYaJGcJu6xQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", "es-shim-unscopables": "^1.0.0" }, "engines": { @@ -1755,14 +1796,14 @@ } }, "node_modules/array.prototype.flatmap": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", - "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", "es-shim-unscopables": "^1.0.0" }, "engines": { @@ -1772,6 +1813,42 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.3.tgz", + "integrity": "sha512-/DdH4TiTmOKzyQbp/eadcCVexiCb36xJg7HshYOYJnNZFDj33GEv0P7GxsynpShhq4OLYJzbGcBDkLsDt7MnNg==", + "dev": true, + "peer": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.1.0", + "es-shim-unscopables": "^1.0.2" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", @@ -1782,9 +1859,9 @@ } }, "node_modules/ast-types-flow": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", - "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==", + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", "dev": true, "peer": true }, @@ -1797,10 +1874,35 @@ "lodash": "^4.17.14" } }, + "node_modules/asynciterator.prototype": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz", + "integrity": "sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==", + "dev": true, + "peer": true, + "dependencies": { + "has-symbols": "^1.0.3" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/axe-core": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.4.3.tgz", - "integrity": "sha512-32+ub6kkdhhWick/UjvEwRchgoetXqTK14INLqbGm5U2TzBkBNF3nQtLYm8ovxSkQWArjEQvftCKryjZaATu3w==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.0.tgz", + "integrity": "sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==", "dev": true, "peer": true, "engines": { @@ -1808,16 +1910,19 @@ } }, "node_modules/axobject-query": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", - "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", + "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", "dev": true, - "peer": true + "peer": true, + "dependencies": { + "dequal": "^2.0.3" + } }, "node_modules/balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, "node_modules/base64id": { @@ -1844,7 +1949,7 @@ "node_modules/benchmark": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/benchmark/-/benchmark-2.1.4.tgz", - "integrity": "sha1-CfPeMckWQl1JjMLuVloOvzwqVik=", + "integrity": "sha512-l9MlfN4M1K/H2fbhfMy3B7vJd6AGKJVQn2h6Sg/Yx+KckoUA7ewS5Vv6TjSq18ooE1kS9hhAlQRH3AkXIh/aOQ==", "dev": true, "dependencies": { "lodash": "^4.17.4", @@ -1867,60 +1972,54 @@ "dev": true }, "node_modules/bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true }, "node_modules/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", "dev": true, "dependencies": { "bytes": "3.1.2", - "content-type": "~1.0.4", + "content-type": "~1.0.5", "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.8.1", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.9.7", - "raw-body": "2.4.3", - "type-is": "~1.6.18" + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" }, "engines": { - "node": ">= 0.8" + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/body-parser/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" + "ms": "2.0.0" } }, - "node_modules/body-parser/node_modules/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==", - "dev": true, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true }, "node_modules/brace-expansion": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", - "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "dependencies": { "balanced-match": "^1.0.0", @@ -1955,62 +2054,31 @@ } }, "node_modules/browserstack-local": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/browserstack-local/-/browserstack-local-1.4.8.tgz", - "integrity": "sha512-s+mc3gTOJwELdLWi4qFVKtGwMbb5JWsR+JxKlMaJkRJxoZ0gg3WREgPxAN0bm6iU5+S4Bi0sz0oxBRZT8BiNsQ==", + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/browserstack-local/-/browserstack-local-1.5.5.tgz", + "integrity": "sha512-jKne7yosrMcptj3hqxp36TP9k0ZW2sCqhyurX24rUL4G3eT7OLgv+CSQN8iq5dtkv5IK+g+v8fWvsiC/S9KxMg==", "dev": true, "dependencies": { - "https-proxy-agent": "^4.0.0", + "agent-base": "^6.0.2", + "https-proxy-agent": "^5.0.1", "is-running": "^2.1.0", "ps-tree": "=1.2.0", "temp-fs": "^0.9.9" } }, - "node_modules/browserstack-local/node_modules/agent-base": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", - "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==", - "dev": true, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/browserstack-local/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, "node_modules/browserstack-local/node_modules/https-proxy-agent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", - "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "dev": true, "dependencies": { - "agent-base": "5", + "agent-base": "6", "debug": "4" }, "engines": { - "node": ">= 6.0.0" + "node": ">= 6" } }, - "node_modules/browserstack-local/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -2064,203 +2132,20 @@ "node": ">=12" } }, - "node_modules/c8/node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/c8/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/c8/node_modules/foreground-child": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", - "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/c8/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/c8/node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/c8/node_modules/istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", - "dev": true, - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/c8/node_modules/istanbul-reports": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", - "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", - "dev": true, - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/c8/node_modules/make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "dev": true, - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/c8/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/c8/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/c8/node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/c8/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/c8/node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/c8/node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/c8/node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "engines": { - "node": ">=12" - } - }, "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2275,6 +2160,18 @@ "node": ">=6" } }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/catharsis": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", @@ -2288,18 +2185,18 @@ } }, "node_modules/chai": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", - "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", + "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", "dev": true, "dependencies": { "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^4.1.2", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", "pathval": "^1.1.1", - "type-detect": "^4.0.5" + "type-detect": "^4.0.8" }, "engines": { "node": ">=4" @@ -2334,25 +2231,22 @@ } }, "node_modules/check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", "dev": true, + "dependencies": { + "get-func-name": "^2.0.2" + }, "engines": { "node": "*" } }, "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -2365,14 +2259,29 @@ "engines": { "node": ">= 8.10.0" }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, "optionalDependencies": { "fsevents": "~2.3.2" } }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/ci-info": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", - "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", "dev": true, "funding": [ { @@ -2396,13 +2305,39 @@ "node": ">=4" } }, - "node_modules/color-convert": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", - "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", + "node_modules/clean-regexp/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, "dependencies": { - "color-name": "^1.1.1" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, "node_modules/color-name": { @@ -2414,7 +2349,7 @@ "node_modules/commander": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", - "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", + "integrity": "sha512-+pJLBFVk+9ZZdlAOB5WuIElVPPth47hILFkmGym57aq8kwxsowvByvB0DHs1vQAhyMZzdcpTtF0VDKGkSDR4ZQ==", "dev": true, "dependencies": { "graceful-readlink": ">= 1.0.0" @@ -2426,13 +2361,13 @@ "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", "dev": true }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, "node_modules/confusing-browser-globals": { @@ -2456,15 +2391,36 @@ "node": ">= 0.10.0" } }, + "node_modules/connect/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/connect/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, "node_modules/content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "dev": true, "engines": { "node": ">= 0.6" } }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, "node_modules/cookie": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", @@ -2474,18 +2430,6 @@ "node": ">= 0.6" } }, - "node_modules/core-js-pure": { - "version": "3.25.5", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.25.5.tgz", - "integrity": "sha512-oml3M22pHM+igfWHDfdLVq2ShWmjM2V4L+dQEBs0DWVIqEm9WHCwGAlZ6BmyBQGy5sFrJmcx+856D9lVKyGWYg==", - "dev": true, - "hasInstallScript": true, - "peer": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, "node_modules/cors": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", @@ -2502,7 +2446,7 @@ "node_modules/corser": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", - "integrity": "sha1-jtolLsqrWEDc2XXOuQ2TcMgZ/4c=", + "integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==", "dev": true, "engines": { "node": ">= 0.4.0" @@ -2528,25 +2472,10 @@ "node": ">= 8" } }, - "node_modules/cross-spawn/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/custom-event": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", - "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=", + "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==", "dev": true }, "node_modules/damerau-levenshtein": { @@ -2557,21 +2486,41 @@ "peer": true }, "node_modules/date-format": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.3.tgz", - "integrity": "sha512-7P3FyqDcfeznLZp2b+OMitV9Sz2lUnsT87WaTat9nVwqsBkTzPG3lPLNwW3en6F4pHUiWzr6vb8CLhjdK9bcxQ==", + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", + "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", "dev": true, "engines": { "node": ">=4.0" } }, "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "dependencies": { - "ms": "2.0.0" + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/deep-eql": { @@ -2601,12 +2550,30 @@ "node": ">=0.10.0" } }, - "node_modules/define-properties": { + "node_modules/define-data-property": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" }, @@ -2618,45 +2585,65 @@ } }, "node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "dev": true, "engines": { - "node": ">= 0.6" + "node": ">= 0.8" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" } }, "node_modules/di": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", - "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", + "integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==", "dev": true }, "node_modules/diff": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", - "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true, "engines": { "node": ">=0.3.1" } }, "node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, "dependencies": { "esutils": "^2.0.2" }, "engines": { - "node": ">=0.10.0" + "node": ">=6.0.0" } }, "node_modules/dom-serialize": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", - "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", + "integrity": "sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ==", "dev": true, "dependencies": { "custom-event": "~1.0.0", @@ -2671,6 +2658,12 @@ "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", "dev": true }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, "node_modules/eckey-utils": { "version": "0.7.14", "resolved": "https://registry.npmjs.org/eckey-utils/-/eckey-utils-0.7.14.tgz", @@ -2680,22 +2673,28 @@ "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true }, "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "dev": true, "engines": { "node": ">= 0.8" } }, "node_modules/engine.io": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.4.2.tgz", - "integrity": "sha512-FKn/3oMiJjrOEOeUub2WCox6JhxBXq/Zn3fZOMCBxKnNYtsdKjxhl7yR3fZhM9PV+rdE75SU5SYMc+2PGzo+Tg==", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.4.tgz", + "integrity": "sha512-KdVSDKhVKyOi+r5uEabrDLZw2qXStVvCsEB/LN3mw4WFi6Gx50jTyuxYVCwAAC0U46FdnzP/ScKRBTXb/NiEOg==", "dev": true, "dependencies": { "@types/cookie": "^0.4.1", @@ -2706,49 +2705,26 @@ "cookie": "~0.4.1", "cors": "~2.8.5", "debug": "~4.3.1", - "engine.io-parser": "~5.0.3", + "engine.io-parser": "~5.2.1", "ws": "~8.11.0" }, "engines": { - "node": ">=10.0.0" + "node": ">=10.2.0" } }, "node_modules/engine.io-parser": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.6.tgz", - "integrity": "sha512-tjuoZDMAdEhVnSFleYPCtdL2GXwVTGtNjoeJd9IhIG3C1xs9uwxqRNEu5WpnDZCaozwVlK/nuQhpodhXSIMaxw==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.2.tgz", + "integrity": "sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==", "dev": true, "engines": { "node": ">=10.0.0" } }, - "node_modules/engine.io/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/engine.io/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/ent": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", + "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==", "dev": true }, "node_modules/entities": { @@ -2761,44 +2737,61 @@ } }, "node_modules/error-ex": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", - "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, "dependencies": { "is-arrayish": "^0.2.1" } }, "node_modules/es-abstract": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.4.tgz", - "integrity": "sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==", + "version": "1.22.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.4.tgz", + "integrity": "sha512-vZYJlk2u6qHYxBOTjAeg7qUxHdNfih64Uu2J8QqWgXZ2cri0ZpJAkzDUK/q593+mvKwlxyaxr6F1Q+3LKoQRgg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.6", + "call-bind": "^1.0.7", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.2", "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.3", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.1", "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", + "hasown": "^2.0.1", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", "is-callable": "^1.2.7", "is-negative-zero": "^2.0.2", "is-regex": "^1.1.4", "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", "is-weakref": "^1.0.2", - "object-inspect": "^1.12.2", + "object-inspect": "^1.13.1", "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.4.3", - "safe-regex-test": "^1.0.0", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", - "unbox-primitive": "^1.0.2" + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.0", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.8", + "string.prototype.trimend": "^1.0.7", + "string.prototype.trimstart": "^1.0.7", + "typed-array-buffer": "^1.0.1", + "typed-array-byte-length": "^1.0.0", + "typed-array-byte-offset": "^1.0.0", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" @@ -2807,13 +2800,81 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-shim-unscopables": { + "node_modules/es-array-method-boxes-properly": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", - "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", + "dev": true + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", "dev": true, "dependencies": { - "has": "^1.0.3" + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.0.17", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.17.tgz", + "integrity": "sha512-lh7BsUqelv4KUbR5a/ZTaGGIMLCjPGPqJ6q+Oq24YP0RdyptX1uzm4vvaqzk7Zx3bpl/76YLTTDj9L7uYQ92oQ==", + "dev": true, + "peer": true, + "dependencies": { + "asynciterator.prototype": "^1.0.0", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.4", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.2", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "iterator.prototype": "^1.1.2", + "safe-array-concat": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" } }, "node_modules/es-to-primitive": { @@ -2842,7 +2903,7 @@ "node_modules/es6-promisify": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", "dev": true, "dependencies": { "es6-promise": "^4.0.3" @@ -2887,9 +2948,9 @@ } }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "dev": true, "engines": { "node": ">=6" @@ -2898,31 +2959,32 @@ "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "dev": true }, "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true, "engines": { - "node": ">=0.8.0" + "node": ">=8" } }, "node_modules/eslint": { - "version": "8.51.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.51.0.tgz", - "integrity": "sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.51.0", - "@humanwhocodes/config-array": "^0.11.11", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -3004,24 +3066,15 @@ "eslint-plugin-import": "^2.25.2" } }, - "node_modules/eslint-config-airbnb-base/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/eslint-import-resolver-node": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz", - "integrity": "sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==", + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "dev": true, "dependencies": { "debug": "^3.2.7", - "is-core-module": "^2.11.0", - "resolve": "^1.22.1" + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" } }, "node_modules/eslint-import-resolver-node/node_modules/debug": { @@ -3033,16 +3086,10 @@ "ms": "^2.1.1" } }, - "node_modules/eslint-import-resolver-node/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, "node_modules/eslint-module-utils": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", - "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", + "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", "dev": true, "dependencies": { "debug": "^3.2.7" @@ -3065,16 +3112,10 @@ "ms": "^2.1.1" } }, - "node_modules/eslint-module-utils/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, "node_modules/eslint-plugin-chai-friendly": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-chai-friendly/-/eslint-plugin-chai-friendly-0.7.2.tgz", - "integrity": "sha512-LOIfGx5sZZ5FwM1shr2GlYAWV9Omdi+1/3byuVagvQNoGUuU0iHhp7AfjA1uR+4dJ4Isfb4+FwBJgQajIw9iAg==", + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-chai-friendly/-/eslint-plugin-chai-friendly-0.7.4.tgz", + "integrity": "sha512-PGPjJ8diYgX1mjLxGJqRop2rrGwZRKImoEOwUOgoIhg0p80MkTaqvmFLe5TF7/iagZHggasvIfQlUyHIhK/PYg==", "dev": true, "engines": { "node": ">=0.10.0" @@ -3084,26 +3125,28 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.27.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz", - "integrity": "sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==", + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", "dev": true, "dependencies": { - "array-includes": "^3.1.6", - "array.prototype.flat": "^1.3.1", - "array.prototype.flatmap": "^1.3.1", + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", "debug": "^3.2.7", "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.7", - "eslint-module-utils": "^2.7.4", - "has": "^1.0.3", - "is-core-module": "^2.11.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", - "object.values": "^1.1.6", - "resolve": "^1.22.1", - "semver": "^6.3.0", - "tsconfig-paths": "^3.14.1" + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" }, "engines": { "node": ">=4" @@ -3121,41 +3164,41 @@ "ms": "^2.1.1" } }, - "node_modules/eslint-plugin-import/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/eslint-plugin-import/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, - "bin": { - "semver": "bin/semver.js" + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" } }, "node_modules/eslint-plugin-jsx-a11y": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.1.tgz", - "integrity": "sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.8.0.tgz", + "integrity": "sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==", "dev": true, "peer": true, "dependencies": { - "@babel/runtime": "^7.18.9", - "aria-query": "^4.2.2", - "array-includes": "^3.1.5", - "ast-types-flow": "^0.0.7", - "axe-core": "^4.4.3", - "axobject-query": "^2.2.0", + "@babel/runtime": "^7.23.2", + "aria-query": "^5.3.0", + "array-includes": "^3.1.7", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "=4.7.0", + "axobject-query": "^3.2.1", "damerau-levenshtein": "^1.0.8", "emoji-regex": "^9.2.2", - "has": "^1.0.3", - "jsx-ast-utils": "^3.3.2", - "language-tags": "^1.0.5", + "es-iterator-helpers": "^1.0.15", + "hasown": "^2.0.0", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", "minimatch": "^3.1.2", - "semver": "^6.3.0" + "object.entries": "^1.1.7", + "object.fromentries": "^2.0.7" }, "engines": { "node": ">=4.0" @@ -3164,44 +3207,29 @@ "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" } }, - "node_modules/eslint-plugin-jsx-a11y/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "peer": true - }, - "node_modules/eslint-plugin-jsx-a11y/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "peer": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/eslint-plugin-react": { - "version": "7.31.10", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.31.10.tgz", - "integrity": "sha512-e4N/nc6AAlg4UKW/mXeYWd3R++qUano5/o+t+wnWxIf+bLsOaH3a4q74kX3nDjYym3VBN4HyO9nEn1GcAqgQOA==", + "version": "7.33.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz", + "integrity": "sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==", "dev": true, "peer": true, "dependencies": { - "array-includes": "^3.1.5", - "array.prototype.flatmap": "^1.3.0", + "array-includes": "^3.1.6", + "array.prototype.flatmap": "^1.3.1", + "array.prototype.tosorted": "^1.1.1", "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.0.12", "estraverse": "^5.3.0", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", - "object.entries": "^1.1.5", - "object.fromentries": "^2.0.5", - "object.hasown": "^1.1.1", - "object.values": "^1.1.5", + "object.entries": "^1.1.6", + "object.fromentries": "^2.0.6", + "object.hasown": "^1.1.2", + "object.values": "^1.1.6", "prop-types": "^15.8.1", - "resolve": "^2.0.0-next.3", - "semver": "^6.3.0", - "string.prototype.matchall": "^4.0.7" + "resolve": "^2.0.0-next.4", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.8" }, "engines": { "node": ">=4" @@ -3223,14 +3251,27 @@ "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" } }, - "node_modules/eslint-plugin-react/node_modules/resolve": { - "version": "2.0.0-next.4", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz", - "integrity": "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==", + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "peer": true, "dependencies": { - "is-core-module": "^2.9.0", + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "dev": true, + "peer": true, + "dependencies": { + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -3241,16 +3282,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-plugin-react/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "peer": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/eslint-plugin-unicorn": { "version": "48.0.1", "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-48.0.1.tgz", @@ -3283,37 +3314,10 @@ "eslint": ">=8.44.0" } }, - "node_modules/eslint-plugin-unicorn/node_modules/is-builtin-module": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", - "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", - "dev": true, - "dependencies": { - "builtin-modules": "^3.3.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint-plugin-unicorn/node_modules/jsesc": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", - "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/eslint-plugin-unicorn/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -3353,41 +3357,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/eslint/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/eslint/node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/eslint/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -3400,51 +3369,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/eslint/node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/eslint/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/espree": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", @@ -3502,9 +3426,9 @@ "dev": true }, "node_modules/esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, "engines": { "node": ">=0.10.0" @@ -3513,7 +3437,7 @@ "node_modules/event-stream": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", - "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", + "integrity": "sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==", "dev": true, "dependencies": { "duplexer": "~0.1.1", @@ -3526,9 +3450,9 @@ } }, "node_modules/eventemitter3": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.0.tgz", - "integrity": "sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", "dev": true }, "node_modules/extend": { @@ -3556,9 +3480,9 @@ "dev": true }, "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, "dependencies": { "reusify": "^1.0.4" @@ -3594,18 +3518,6 @@ "node": ">=8" } }, - "node_modules/fill-range/node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, "node_modules/finalhandler": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", @@ -3624,6 +3536,33 @@ "node": ">= 0.8" } }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/finalhandler/node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -3650,12 +3589,13 @@ } }, "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, "dependencies": { - "flatted": "^3.1.0", + "flatted": "^3.2.9", + "keyv": "^4.5.3", "rimraf": "^3.0.2" }, "engines": { @@ -3663,9 +3603,9 @@ } }, "node_modules/flatted": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", - "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, "node_modules/follow-redirects": { @@ -3688,36 +3628,52 @@ } } }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/from": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", - "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", + "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==", "dev": true }, "node_modules/fs-extra": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", - "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "dev": true, "dependencies": { "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" }, "engines": { - "node": ">=12" + "node": ">=6 <7 || >=8" } }, - "node_modules/fs-extra/node_modules/graceful-fs": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", - "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", - "dev": true - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, "node_modules/fsevents": { @@ -3735,21 +3691,24 @@ } }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" }, "engines": { "node": ">= 0.4" @@ -3786,27 +3745,33 @@ } }, "node_modules/get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" }, "engines": { "node": ">= 0.4" @@ -3828,50 +3793,109 @@ } }, "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "minimatch": "^5.0.1", + "once": "^1.3.0" }, "engines": { - "node": "*" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "dependencies": { - "is-glob": "^4.0.1" + "is-glob": "^4.0.3" }, "engines": { - "node": ">= 6" + "node": ">=10.13.0" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true, - "engines": { - "node": ">=0.4.0" - } + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true }, "node_modules/graceful-readlink": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", + "integrity": "sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w==", "dev": true }, "node_modules/graphemer": { @@ -3880,18 +3904,6 @@ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/has-bigints": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", @@ -3902,21 +3914,33 @@ } }, "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, "dependencies": { - "get-intrinsic": "^1.1.1" + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3935,12 +3959,12 @@ } }, "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, "dependencies": { - "has-symbols": "^1.0.2" + "has-symbols": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -3949,6 +3973,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hasown": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", + "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -3983,26 +4019,29 @@ "dev": true }, "node_modules/http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dev": true, "dependencies": { - "depd": "~1.1.2", + "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", + "statuses": "2.0.1", "toidentifier": "1.0.1" }, "engines": { - "node": ">= 0.6" + "node": ">= 0.8" } }, - "node_modules/http-errors/node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "node_modules/http-errors/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } }, "node_modules/http-proxy": { "version": "1.18.1", @@ -4045,18 +4084,6 @@ "node": ">=12" } }, - "node_modules/http-server/node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/https-proxy-agent": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", @@ -4070,6 +4097,18 @@ "node": ">= 4.5.0" } }, + "node_modules/https-proxy-agent/node_modules/agent-base": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "dev": true, + "dependencies": { + "es6-promisify": "^5.0.0" + }, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/https-proxy-agent/node_modules/debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", @@ -4079,16 +4118,22 @@ "ms": "^2.1.1" } }, - "node_modules/https-proxy-agent/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } }, "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, "engines": { "node": ">= 4" @@ -4113,7 +4158,7 @@ "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, "engines": { "node": ">=0.8.19" @@ -4131,7 +4176,7 @@ "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, "dependencies": { "once": "^1.3.0", @@ -4139,31 +4184,63 @@ } }, "node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, "node_modules/internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", "dev": true, "dependencies": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", + "es-errors": "^1.3.0", + "hasown": "^2.0.0", "side-channel": "^1.0.4" }, "engines": { "node": ">= 0.4" } }, + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, + "node_modules/is-async-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "dev": true, + "peer": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", @@ -4204,6 +4281,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, + "dependencies": { + "builtin-modules": "^3.3.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -4229,12 +4321,12 @@ } }, "node_modules/is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dev": true, "dependencies": { - "has": "^1.0.3" + "hasown": "^2.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4273,12 +4365,50 @@ "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, "engines": { "node": ">=0.10.0" } }, + "node_modules/is-finalizationregistry": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", + "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "dev": true, + "peer": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "peer": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -4291,16 +4421,26 @@ "node": ">=0.10.0" } }, + "node_modules/is-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", + "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", + "dev": true, + "peer": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", "dev": true }, "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "dev": true, "engines": { "node": ">= 0.4" @@ -4379,16 +4519,29 @@ "node_modules/is-running": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-running/-/is-running-2.1.0.tgz", - "integrity": "sha1-MKc/9cw4VOT8JUkICen1q/jeCeA=", + "integrity": "sha512-mjJd3PujZMl7j+D395WTIO5tU5RIDBfVSRtRR4VOJou3H66E38UjbjvDGh3slJzPuolsb+yQFqwHNNdyp5jg3w==", "dev": true }, + "node_modules/is-set": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", + "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", + "dev": true, + "peer": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2" + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4424,6 +4577,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", @@ -4436,6 +4604,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-weakmap": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", + "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==", + "dev": true, + "peer": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-weakref": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", @@ -4448,6 +4626,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-weakset": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", + "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==", + "dev": true, + "peer": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", @@ -4461,15 +4653,15 @@ } }, "node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", "dev": true }, "node_modules/isbinaryfile": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.8.tgz", - "integrity": "sha512-53h6XFniq77YdW+spoRrebh0mnmTxRPTlcuIArO57lmMdq4uBKFKaeTjnb92oYWrSn/LVL+LT+Hap2tFQj8V+w==", + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", + "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", "dev": true, "engines": { "node": ">= 8.0.0" @@ -4481,15 +4673,95 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/iterator.prototype": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", + "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", + "dev": true, + "peer": true, + "dependencies": { + "define-properties": "^1.2.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "reflect.getprototypeof": "^1.0.4", + "set-function-name": "^2.0.1" + } + }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/js2xmlparser": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", @@ -4499,6 +4771,24 @@ "xmlcreate": "^2.0.4" } }, + "node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -4514,7 +4804,7 @@ "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, "node_modules/json5": { @@ -4530,41 +4820,40 @@ } }, "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "node_modules/jsx-ast-utils": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz", - "integrity": "sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==", + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", "dev": true, "peer": true, "dependencies": { - "array-includes": "^3.1.5", - "object.assign": "^4.1.3" + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" }, "engines": { "node": ">=4.0" } }, "node_modules/just-extend": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", - "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", + "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", "dev": true }, "node_modules/karma": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.1.tgz", - "integrity": "sha512-Cj57NKOskK7wtFWSlMvZf459iX+kpYIPXmkNUzP2WAFcA7nhr/ALn5R7sw3w+1udFDcpMx/tuB8d5amgm3ijaA==", + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.3.tgz", + "integrity": "sha512-LuucC/RE92tJ8mlCwqEoRWXP38UMAqpnq98vktmS9SznSoUPPUJQbc91dHcxcunROvfQjdORVA/YFviH+Xci9Q==", "dev": true, "dependencies": { "@colors/colors": "1.5.0", @@ -4586,7 +4875,7 @@ "qjobs": "^1.2.0", "range-parser": "^1.2.1", "rimraf": "^3.0.2", - "socket.io": "^4.4.1", + "socket.io": "^4.7.2", "source-map": "^0.6.1", "tmp": "^0.2.1", "ua-parser-js": "^0.7.30", @@ -4614,14 +4903,26 @@ } }, "node_modules/karma-chrome-launcher": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.1.1.tgz", - "integrity": "sha512-hsIglcq1vtboGPAN+DGCISCFOxW+ZVnIqhDQcCMqqCp+4dmJ0Qpq5QAjkbA0X2L9Mi6OBkHi2Srrbmm7pUKkzQ==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.2.0.tgz", + "integrity": "sha512-rE9RkUPI7I9mAxByQWkGJFXfFD6lE4gC5nPuZdobf/QdTEJI6EU4yIay/cfU/xV4ZxlM5JiTv7zWYgA64NpS5Q==", "dev": true, "dependencies": { "which": "^1.2.1" } }, + "node_modules/karma-chrome-launcher/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, "node_modules/karma-firefox-launcher": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-2.1.2.tgz", @@ -4632,21 +4933,6 @@ "which": "^2.0.1" } }, - "node_modules/karma-firefox-launcher/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/karma-mocha": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/karma-mocha/-/karma-mocha-2.0.1.tgz", @@ -4659,7 +4945,7 @@ "node_modules/karma-mocha-reporter": { "version": "2.2.5", "resolved": "https://registry.npmjs.org/karma-mocha-reporter/-/karma-mocha-reporter-2.2.5.tgz", - "integrity": "sha1-FRIAlejtgZGG5HoLAS8810GJVWA=", + "integrity": "sha512-Hr6nhkIp0GIJJrvzY8JFeHpQZNseuIakGac4bpw8K1+5F0tLb6l7uvXRa8mt2Z+NVwYgCct4QAfp2R2QP6o00w==", "dev": true, "dependencies": { "chalk": "^2.1.0", @@ -4705,10 +4991,43 @@ "node": ">=4" } }, + "node_modules/karma-mocha-reporter/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/karma-mocha-reporter/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/karma-mocha-reporter/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/karma-mocha-reporter/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/karma-mocha-reporter/node_modules/strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", "dev": true, "dependencies": { "ansi-regex": "^3.0.0" @@ -4730,13 +5049,13 @@ } }, "node_modules/karma-webkit-launcher": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/karma-webkit-launcher/-/karma-webkit-launcher-2.1.0.tgz", - "integrity": "sha512-S5eqhH0DIcuJFi27nC6eBxZ3MTrPnYybPthDU2Q8dfG0yFrXx8FqNDKSbRZsFFvAKJ55QVtYH1bbArd3ddI5Sg==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/karma-webkit-launcher/-/karma-webkit-launcher-2.4.0.tgz", + "integrity": "sha512-k6fmeEwRt5PiPwb/B8stLNbtqcCqBcdMVUsep58da2uS0pEYr4X/RgP1/ThJK12Q6uispGgWVtDtp6O0hDOF+Q==", "dev": true, "dependencies": { "is-ci": "^3.0.1", - "uuid": "^9.0.0" + "uuid": "^9.0.1" }, "peerDependenciesMeta": { "playwright": { @@ -4744,15 +5063,6 @@ } } }, - "node_modules/karma-webkit-launcher/node_modules/uuid": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", - "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", - "dev": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/karma/node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -4764,77 +5074,48 @@ "wrap-ansi": "^7.0.0" } }, - "node_modules/karma/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/karma/node_modules/graceful-fs": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", - "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", - "dev": true - }, - "node_modules/karma/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/karma/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "node_modules/karma/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/karma/node_modules/tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dev": true, - "dependencies": { - "rimraf": "^3.0.0" - }, - "engines": { - "node": ">=8.17.0" - } - }, - "node_modules/karma/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" + "node": "*" }, "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/karma/node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "node_modules/karma/node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", "dev": true, + "bin": { + "mime": "cli.js" + }, "engines": { - "node": ">=10" + "node": ">=4.0.0" + } + }, + "node_modules/karma/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" } }, "node_modules/karma/node_modules/yargs": { @@ -4864,6 +5145,15 @@ "node": ">=10" } }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/klaw": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", @@ -4881,13 +5171,16 @@ "peer": true }, "node_modules/language-tags": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", - "integrity": "sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", "dev": true, "peer": true, "dependencies": { - "language-subtag-registry": "~0.3.2" + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" } }, "node_modules/levn": { @@ -4989,6 +5282,39 @@ "node": ">=4" } }, + "node_modules/log-symbols/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/log-symbols/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/log-symbols/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/log-symbols/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/log-symbols/node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -5002,44 +5328,21 @@ } }, "node_modules/log4js": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.4.1.tgz", - "integrity": "sha512-iUiYnXqAmNKiIZ1XSAitQ4TmNs8CdZYTAWINARF3LjnsLN8tY5m0vRwd6uuWj/yNY0YHxeZodnbmxKFUOM2rMg==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz", + "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==", "dev": true, "dependencies": { - "date-format": "^4.0.3", - "debug": "^4.3.3", - "flatted": "^3.2.4", + "date-format": "^4.0.14", + "debug": "^4.3.4", + "flatted": "^3.2.7", "rfdc": "^1.3.0", - "streamroller": "^3.0.2" + "streamroller": "^3.1.5" }, "engines": { "node": ">=8.0" } }, - "node_modules/log4js/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/log4js/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -5054,12 +5357,12 @@ } }, "node_modules/loupe": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", - "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", "dev": true, "dependencies": { - "get-func-name": "^2.0.0" + "get-func-name": "^2.0.1" } }, "node_modules/lru-cache": { @@ -5074,16 +5377,10 @@ "node": ">=10" } }, - "node_modules/lru-cache/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/magic-string": { - "version": "0.30.6", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.6.tgz", - "integrity": "sha512-n62qCLbPjNjyo+owKtveQxZFZTBm+Ms6YoGD23Wew6Vw337PElFNifQpknPruVRQV57kVShPnLGo9vWxVhpPvA==", + "version": "0.30.7", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.7.tgz", + "integrity": "sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==", "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" @@ -5092,11 +5389,35 @@ "node": ">=12" } }, - "node_modules/magic-string/node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } }, "node_modules/make-error": { "version": "1.3.6", @@ -5107,7 +5428,7 @@ "node_modules/map-stream": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", - "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=", + "integrity": "sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==", "dev": true }, "node_modules/markdown-it": { @@ -5136,12 +5457,6 @@ "markdown-it": "*" } }, - "node_modules/markdown-it/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, "node_modules/marked": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", @@ -5163,40 +5478,40 @@ "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "dev": true, "bin": { "mime": "cli.js" }, "engines": { - "node": ">=4.0.0" + "node": ">=4" } }, "node_modules/mime-db": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { - "version": "2.1.34", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", - "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dev": true, "dependencies": { - "mime-db": "1.51.0" + "mime-db": "1.52.0" }, "engines": { "node": ">= 0.6" @@ -5232,22 +5547,31 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, "bin": { "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/mocha": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", - "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.3.0.tgz", + "integrity": "sha512-uF2XJs+7xSLsrmIvn37i/wnc91nw7XjOQB8ccyx5aEgdnohr7n+rEiZP23WkCYHjilR6+EboEnbq/ZQDz4LSbg==", "dev": true, "dependencies": { "ansi-colors": "4.1.1", @@ -5257,13 +5581,12 @@ "diff": "5.0.0", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", - "glob": "7.2.0", + "glob": "8.1.0", "he": "1.2.0", "js-yaml": "4.1.0", "log-symbols": "4.1.0", "minimatch": "5.0.1", "ms": "2.1.3", - "nanoid": "3.3.3", "serialize-javascript": "6.0.0", "strip-json-comments": "3.1.1", "supports-color": "8.1.1", @@ -5278,17 +5601,43 @@ }, "engines": { "node": ">= 14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" } }, - "node_modules/mocha/node_modules/argparse": { + "node_modules/mocha/node_modules/brace-expansion": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/mocha/node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } }, "node_modules/mocha/node_modules/cliui": { "version": "7.0.4", @@ -5301,44 +5650,6 @@ "wrap-ansi": "^7.0.0" } }, - "node_modules/mocha/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/mocha/node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/mocha/node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/mocha/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, "node_modules/mocha/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -5351,66 +5662,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mocha/node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "node_modules/mocha/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "is-glob": "^4.0.1" }, "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/mocha/node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/mocha/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/mocha/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/mocha/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "node": ">= 6" } }, "node_modules/mocha/node_modules/log-symbols": { @@ -5441,15 +5702,6 @@ "node": ">=10" } }, - "node_modules/mocha/node_modules/minimatch/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, "node_modules/mocha/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -5465,20 +5717,6 @@ "randombytes": "^2.1.0" } }, - "node_modules/mocha/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/mocha/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -5494,32 +5732,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/mocha/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/mocha/node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/mocha/node_modules/yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", @@ -5548,27 +5760,15 @@ } }, "node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node_modules/nanoid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", - "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", - "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, "node_modules/negotiator": { @@ -5581,25 +5781,25 @@ } }, "node_modules/nise": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.4.tgz", - "integrity": "sha512-8+Ib8rRJ4L0o3kfmyVCL7gzrohyDe0cMFTBa2d364yIrEGMEoetznKJx899YxjybU6bL9SQkYPSBBs1gyYs8Xg==", + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.9.tgz", + "integrity": "sha512-qOnoujW4SV6e40dYxJOb3uvuoPHtmLzIk4TFo+j0jPJoC+5Z9xja5qH5JZobEPsa8+YYphMrOSwnrshEhG2qww==", "dev": true, "dependencies": { - "@sinonjs/commons": "^2.0.0", - "@sinonjs/fake-timers": "^10.0.2", - "@sinonjs/text-encoding": "^0.7.1", - "just-extend": "^4.0.2", - "path-to-regexp": "^1.7.0" + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/text-encoding": "^0.7.2", + "just-extend": "^6.2.0", + "path-to-regexp": "^6.2.1" } }, - "node_modules/nise/node_modules/@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "node_modules/nise/node_modules/@sinonjs/fake-timers": { + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", + "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", "dev": true, "dependencies": { - "type-detect": "4.0.8" + "@sinonjs/commons": "^3.0.0" } }, "node_modules/normalize-package-data": { @@ -5614,6 +5814,15 @@ "validate-npm-package-license": "^3.0.1" } }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -5626,16 +5835,16 @@ "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5651,13 +5860,13 @@ } }, "node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", "has-symbols": "^1.0.3", "object-keys": "^1.1.1" }, @@ -5669,29 +5878,28 @@ } }, "node_modules/object.entries": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz", - "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz", + "integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" }, "engines": { "node": ">= 0.4" } }, "node_modules/object.fromentries": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.5.tgz", - "integrity": "sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", + "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" }, "engines": { "node": ">= 0.4" @@ -5700,29 +5908,42 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/object.groupby": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.2.tgz", + "integrity": "sha512-bzBq58S+x+uo0VjurFT0UktpKHOZmv4/xePiOA1nbB9pMqpGK7rUPNgf+1YC+7mE+0HzhTMqNUuCqvKhj6FnBw==", + "dev": true, + "dependencies": { + "array.prototype.filter": "^1.0.3", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.0.0" + } + }, "node_modules/object.hasown": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.1.tgz", - "integrity": "sha512-LYLe4tivNQzq4JdaWW6WO3HMZZJWzkkH8fnI6EebWl0VZth2wL2Lovm74ep2/gZzlaTdV62JZHEqHQ2yVn8Q/A==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.3.tgz", + "integrity": "sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==", "dev": true, "peer": true, "dependencies": { - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object.values": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", - "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", + "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" }, "engines": { "node": ">= 0.4" @@ -5732,9 +5953,9 @@ } }, "node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dev": true, "dependencies": { "ee-first": "1.1.1" @@ -5746,16 +5967,16 @@ "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, "dependencies": { "wrappy": "1" } }, "node_modules/opener": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.1.tgz", - "integrity": "sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", "dev": true, "bin": { "opener": "bin/opener-bin.js" @@ -5868,7 +6089,7 @@ "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, "engines": { "node": ">=0.10.0" @@ -5889,15 +6110,37 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, - "node_modules/path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", "dev": true, "dependencies": { - "isarray": "0.0.1" + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", + "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/path-to-regexp": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", + "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==", + "dev": true + }, "node_modules/pathval": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", @@ -5910,7 +6153,7 @@ "node_modules/pause-stream": { "version": "0.0.11", "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", - "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", + "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==", "dev": true, "dependencies": { "through": "~2.3" @@ -5935,31 +6178,47 @@ "dev": true }, "node_modules/playwright": { - "version": "1.30.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.30.0.tgz", - "integrity": "sha512-ENbW5o75HYB3YhnMTKJLTErIBExrSlX2ZZ1C/FzmHjUYIfxj/UnI+DWpQr992m+OQVSg0rCExAOlRwB+x+yyIg==", + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.42.0.tgz", + "integrity": "sha512-Ko7YRUgj5xBHbntrgt4EIw/nE//XBHOKVKnBjO1KuZkmkhlbgyggTe5s9hjqQ1LpN+Xg+kHsQyt5Pa0Bw5XpvQ==", "dev": true, - "hasInstallScript": true, "dependencies": { - "playwright-core": "1.30.0" + "playwright-core": "1.42.0" }, "bin": { "playwright": "cli.js" }, "engines": { - "node": ">=14" + "node": ">=16" + }, + "optionalDependencies": { + "fsevents": "2.3.2" } }, "node_modules/playwright-core": { - "version": "1.30.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.30.0.tgz", - "integrity": "sha512-7AnRmTCf+GVYhHbLJsGUtskWTE33SwMZkybJ0v6rqR1boxq2x36U7p1vDRV7HO2IwTZgmycracLxPEJI49wu4g==", + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.42.0.tgz", + "integrity": "sha512-0HD9y8qEVlcbsAjdpBaFjmaTHf+1FeIddy8VJLeiqwhcNqGCBe4Wp2e8knpqiYbzxtxarxiXyNDw2cG8sCaNMQ==", "dev": true, "bin": { - "playwright": "cli.js" + "playwright-core": "cli.js" }, "engines": { - "node": ">=14" + "node": ">=16" + } + }, + "node_modules/playwright/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, "node_modules/pluralize": { @@ -5972,14 +6231,14 @@ } }, "node_modules/portfinder": { - "version": "1.0.28", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", - "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", + "version": "1.0.32", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz", + "integrity": "sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==", "dev": true, "dependencies": { - "async": "^2.6.2", - "debug": "^3.1.1", - "mkdirp": "^0.5.5" + "async": "^2.6.4", + "debug": "^3.2.7", + "mkdirp": "^0.5.6" }, "engines": { "node": ">= 0.12.0" @@ -5994,11 +6253,26 @@ "ms": "^2.1.1" } }, - "node_modules/portfinder/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "node_modules/portfinder/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } }, "node_modules/prelude-ls": { "version": "1.2.1", @@ -6037,9 +6311,9 @@ } }, "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "engines": { "node": ">=6" @@ -6048,7 +6322,7 @@ "node_modules/q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", "dev": true, "engines": { "node": ">=0.6.0", @@ -6118,13 +6392,13 @@ } }, "node_modules/raw-body": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", - "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "dev": true, "dependencies": { "bytes": "3.1.2", - "http-errors": "1.8.1", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" }, @@ -6132,18 +6406,6 @@ "node": ">= 0.8" } }, - "node_modules/raw-body/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -6265,10 +6527,32 @@ "node": ">=8.10.0" } }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.5.tgz", + "integrity": "sha512-62wgfC8dJWrmxv44CA36pLDnP6KKl3Vhxb7PL+8+qrrFMMoJij4vgiMP8zV4O8+CBMXY1mHxI5fITGHXFHVmQQ==", + "dev": true, + "peer": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.0.0", + "get-intrinsic": "^1.2.3", + "globalthis": "^1.0.3", + "which-builtin-type": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", "dev": true, "peer": true }, @@ -6282,14 +6566,15 @@ } }, "node_modules/regexp.prototype.flags": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", - "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" }, "engines": { "node": ">= 0.4" @@ -6322,7 +6607,7 @@ "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, "engines": { "node": ">=0.10.0" @@ -6331,25 +6616,25 @@ "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", "dev": true }, "node_modules/requizzle": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz", - "integrity": "sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ==", + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.4.tgz", + "integrity": "sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==", "dev": true, "dependencies": { - "lodash": "^4.17.14" + "lodash": "^4.17.21" } }, "node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, "dependencies": { - "is-core-module": "^2.9.0", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -6389,9 +6674,9 @@ } }, "node_modules/rfdc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", - "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.1.tgz", + "integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==", "dev": true }, "node_modules/rimraf": { @@ -6409,10 +6694,30 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/rollup": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.9.6.tgz", - "integrity": "sha512-05lzkCS2uASX0CiLFybYfVkwNbKZG5NFQ6Go0VWyogFTXXbR039UVsegViTntkk4OglHBdF54ccApXRRuXRbsg==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.12.0.tgz", + "integrity": "sha512-wz66wn4t1OHIJw3+XU7mJJQV/2NAfw5OAk6G6Hoo3zcvz/XOfQ52Vgi+AN4Uxoxi0KBBwk2g8zPrTDA4btSB/Q==", "dev": true, "dependencies": { "@types/estree": "1.0.5" @@ -6425,19 +6730,19 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.9.6", - "@rollup/rollup-android-arm64": "4.9.6", - "@rollup/rollup-darwin-arm64": "4.9.6", - "@rollup/rollup-darwin-x64": "4.9.6", - "@rollup/rollup-linux-arm-gnueabihf": "4.9.6", - "@rollup/rollup-linux-arm64-gnu": "4.9.6", - "@rollup/rollup-linux-arm64-musl": "4.9.6", - "@rollup/rollup-linux-riscv64-gnu": "4.9.6", - "@rollup/rollup-linux-x64-gnu": "4.9.6", - "@rollup/rollup-linux-x64-musl": "4.9.6", - "@rollup/rollup-win32-arm64-msvc": "4.9.6", - "@rollup/rollup-win32-ia32-msvc": "4.9.6", - "@rollup/rollup-win32-x64-msvc": "4.9.6", + "@rollup/rollup-android-arm-eabi": "4.12.0", + "@rollup/rollup-android-arm64": "4.12.0", + "@rollup/rollup-darwin-arm64": "4.12.0", + "@rollup/rollup-darwin-x64": "4.12.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.12.0", + "@rollup/rollup-linux-arm64-gnu": "4.12.0", + "@rollup/rollup-linux-arm64-musl": "4.12.0", + "@rollup/rollup-linux-riscv64-gnu": "4.12.0", + "@rollup/rollup-linux-x64-gnu": "4.12.0", + "@rollup/rollup-linux-x64-musl": "4.12.0", + "@rollup/rollup-win32-arm64-msvc": "4.12.0", + "@rollup/rollup-win32-ia32-msvc": "4.12.0", + "@rollup/rollup-win32-x64-msvc": "4.12.0", "fsevents": "~2.3.2" } }, @@ -6464,6 +6769,24 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/safe-array-concat": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.0.tgz", + "integrity": "sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "get-intrinsic": "^1.2.2", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -6471,15 +6794,18 @@ "dev": true }, "node_modules/safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", "is-regex": "^1.1.4" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -6493,16 +6819,57 @@ "node_modules/secure-compare": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", - "integrity": "sha1-8aAymzCLIh+uN7mXTz1XjQypmeM=", + "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==", "dev": true }, "node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { - "semver": "bin/semver" + "semver": "bin/semver.js" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", + "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.2", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/setprototypeof": { @@ -6533,33 +6900,38 @@ } }, "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.5.tgz", + "integrity": "sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, "node_modules/sinon": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.1.0.tgz", - "integrity": "sha512-cS5FgpDdE9/zx7no8bxROHymSlPLZzq0ChbbLk1DrxBfc+eTeBK3y8nIL+nu/0QeYydhhbLIr7ecHJpywjQaoQ==", + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.2.0.tgz", + "integrity": "sha512-nPS85arNqwBXaIsFCkolHjGIkFo+Oxu9vbgmBJizLAhqe6P2o3Qmj3KCUoRkfhHtvgDhZdWD3risLHAUJ8npjw==", + "deprecated": "16.1.1", "dev": true, "dependencies": { "@sinonjs/commons": "^3.0.0", - "@sinonjs/fake-timers": "^10.2.0", + "@sinonjs/fake-timers": "^10.3.0", "@sinonjs/samsam": "^8.0.0", "diff": "^5.1.0", "nise": "^5.1.4", @@ -6570,6 +6942,15 @@ "url": "https://opencollective.com/sinon" } }, + "node_modules/sinon/node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/slash": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", @@ -6589,28 +6970,30 @@ "dev": true }, "node_modules/socket.io": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.6.0.tgz", - "integrity": "sha512-b65bp6INPk/BMMrIgVvX12x3Q+NqlGqSlTuvKQWt0BUJ3Hyy3JangBl7fEoWZTXbOKlCqNPbQ6MbWgok/km28w==", + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.4.tgz", + "integrity": "sha512-DcotgfP1Zg9iP/dH9zvAQcWrE0TtbMVwXmlV4T4mqsvY+gw+LqUGPfx2AoVyRk0FLME+GQhufDMyacFmw7ksqw==", "dev": true, "dependencies": { "accepts": "~1.3.4", "base64id": "~2.0.0", + "cors": "~2.8.5", "debug": "~4.3.2", - "engine.io": "~6.4.0", + "engine.io": "~6.5.2", "socket.io-adapter": "~2.5.2", - "socket.io-parser": "~4.2.1" + "socket.io-parser": "~4.2.4" }, "engines": { - "node": ">=10.0.0" + "node": ">=10.2.0" } }, "node_modules/socket.io-adapter": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz", - "integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.4.tgz", + "integrity": "sha512-wDNHGXGewWAjQPt3pyeYBtpWSq9cLE5UW1ZUPL/2eGK9jtse/FpXib7epSTsz0Q0m+6sg6Y4KtcFTlah1bdOVg==", "dev": true, "dependencies": { + "debug": "~4.3.4", "ws": "~8.11.0" } }, @@ -6627,52 +7010,6 @@ "node": ">=10.0.0" } }, - "node_modules/socket.io-parser/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/socket.io-parser/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/socket.io/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/socket.io/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -6693,30 +7030,41 @@ } }, "node_modules/spdx-correct": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", - "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", "dev": true, "dependencies": { - "spdx-license-ids": "^1.0.2" + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" } }, - "node_modules/spdx-expression-parse": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", - "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", "dev": true }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, "node_modules/spdx-license-ids": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", - "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz", + "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==", "dev": true }, "node_modules/split": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", - "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", + "integrity": "sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==", "dev": true, "dependencies": { "through": "2" @@ -6728,7 +7076,7 @@ "node_modules/statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", "dev": true, "engines": { "node": ">= 0.6" @@ -6737,92 +7085,128 @@ "node_modules/stream-combiner": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", - "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", + "integrity": "sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==", "dev": true, "dependencies": { "duplexer": "~0.1.1" } }, "node_modules/streamroller": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.0.2.tgz", - "integrity": "sha512-ur6y5S5dopOaRXBuRIZ1u6GC5bcEXHRZKgfBjfCglMhmIf+roVCECjvkEYzNQOXIN2/JPnkMPW/8B3CZoKaEPA==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz", + "integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==", "dev": true, "dependencies": { - "date-format": "^4.0.3", - "debug": "^4.1.1", - "fs-extra": "^10.0.0" + "date-format": "^4.0.14", + "debug": "^4.3.4", + "fs-extra": "^8.1.0" }, "engines": { "node": ">=8.0" } }, - "node_modules/streamroller/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "dependencies": { - "ms": "2.1.2" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">=8" } }, - "node_modules/streamroller/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/string-width/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "node_modules/string.prototype.matchall": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz", - "integrity": "sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg==", + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz", + "integrity": "sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==", "dev": true, "peer": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", - "get-intrinsic": "^1.1.1", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "regexp.prototype.flags": "^1.4.1", + "internal-slot": "^1.0.5", + "regexp.prototype.flags": "^1.5.0", + "set-function-name": "^2.0.0", "side-channel": "^1.0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/string.prototype.trimend": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", - "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", + "node_modules/string.prototype.trim": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", + "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", + "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimstart": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", - "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", + "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6840,6 +7224,19 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -6885,15 +7282,6 @@ "node": ">=8" } }, - "node_modules/supports-color/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -6915,7 +7303,7 @@ "node_modules/temp-fs": { "version": "0.9.9", "resolved": "https://registry.npmjs.org/temp-fs/-/temp-fs-0.9.9.tgz", - "integrity": "sha1-gHFzBDeHByDpQxUy/igUNk+IA9c=", + "integrity": "sha512-WfecDCR1xC9b0nsrzSaxPf3ZuWeWLUWblW4vlDQAa1biQaKHiImHnJfeQocQe/hXKMcolRzgkcVX/7kK4zoWbw==", "dev": true, "dependencies": { "rimraf": "~2.5.2" @@ -6924,10 +7312,30 @@ "node": ">=0.8.0" } }, + "node_modules/temp-fs/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/temp-fs/node_modules/rimraf": { "version": "2.5.4", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz", - "integrity": "sha1-loAAk8vxoMhr2VtGJUZ1NcKd+gQ=", + "integrity": "sha512-Lw7SHMjssciQb/rRz7JyPIy9+bbUshEucPoLRvWqy09vC5zQixl8Uet+Zl+SROBB/JMWHJRdCk1qdxNWHNMvlQ==", "dev": true, "dependencies": { "glob": "^7.0.5" @@ -6937,9 +7345,9 @@ } }, "node_modules/terser": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.27.0.tgz", - "integrity": "sha512-bi1HRwVRskAjheeYl291n3JC4GgO/Ty4z1nVs5AAsmonJulGxpSektecnNedrwK9C7vpvVtcX3cw00VSLt7U2A==", + "version": "5.28.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.28.1.tgz", + "integrity": "sha512-wM+bZp54v/E9eRRGXb5ZFDvinrJIOaTapx3WUokyVGZu5ucVCK55zEgGd5Dl2fSr3jUo5sDiERErUWLY6QPFyA==", "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -6960,18 +7368,168 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true }, + "node_modules/tmp": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.2.tgz", + "integrity": "sha512-ETcvHhaIc9J2MDEAH6N67j9bvBvu/3Gb764qaGhwtFvjtvhegqoqSpofgeyq1Sc24mW5pdyUDs9HP5j3ehkxRw==", + "dev": true, + "dependencies": { + "rimraf": "^5.0.5" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/tmp/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/tmp/node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/tmp/node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/tmp/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/tmp/node_modules/rimraf": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", + "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", + "dev": true, + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/tmp/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -6982,9 +7540,9 @@ } }, "node_modules/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", @@ -7034,21 +7592,21 @@ } }, "node_modules/tsconfig-paths": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", - "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", "dev": true, "dependencies": { "@types/json5": "^0.0.29", - "json5": "^1.0.1", + "json5": "^1.0.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } }, "node_modules/tsx": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.0.tgz", - "integrity": "sha512-I+t79RYPlEYlHn9a+KzwrvEwhJg35h/1zHsLC2JXvhC2mdynMv6Zxzvhv5EMV6VF5qJlLlkSnMVvdZV3PSIGcg==", + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.1.tgz", + "integrity": "sha512-8d6VuibXHtlN5E3zFkgY8u4DX7Y3Z27zvvPKVmLon/D4AjuKzarkUBTLDBgj9iTQ0hg5xM7c/mYiRVM+HETf0g==", "dev": true, "dependencies": { "esbuild": "~0.19.10", @@ -7110,6 +7668,79 @@ "node": ">= 0.6" } }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.5.tgz", + "integrity": "sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/typescript": { "version": "5.3.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", @@ -7124,9 +7755,9 @@ } }, "node_modules/ua-parser-js": { - "version": "0.7.33", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.33.tgz", - "integrity": "sha512-s8ax/CeZdK9R/56Sui0WM6y9OFREJarMRHqLB2EwkovemBxNQ+Bqu8GAsUnVcXKgphb++ghr/B2BZx4mahujPw==", + "version": "0.7.37", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.37.tgz", + "integrity": "sha512-xV8kqRKM+jhMvcHWUKthV9fNebIzrNy//2O9ZwWcfiBFR5f25XVZPLlEajk/sf3Ra15V92isyQqnIEXRDaZWEA==", "dev": true, "funding": [ { @@ -7136,6 +7767,10 @@ { "type": "paypal", "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" } ], "engines": { @@ -7169,6 +7804,12 @@ "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", "dev": true }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "node_modules/union": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", @@ -7182,18 +7823,18 @@ } }, "node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true, "engines": { - "node": ">= 10.0.0" + "node": ">= 4.0.0" } }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true, "engines": { "node": ">= 0.8" @@ -7217,12 +7858,25 @@ "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "dev": true, "engines": { "node": ">= 0.4.0" } }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", @@ -7243,20 +7897,14 @@ "node": ">=10.12.0" } }, - "node_modules/v8-to-istanbul/node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, "node_modules/validate-npm-package-license": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", - "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, "dependencies": { - "spdx-correct": "~1.0.0", - "spdx-expression-parse": "~1.0.0" + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" } }, "node_modules/vary": { @@ -7271,16 +7919,16 @@ "node_modules/void-elements": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", - "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", + "integrity": "sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/web-streams-polyfill": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.0.tgz", - "integrity": "sha512-EqPmREeOzttaLRm5HS7io98goBgZ7IVz79aDvqjD0kYXLtFZTc0T/U6wHTPKyIjb+MdN7DFIIX6hgdBEpWmfPA==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", "dev": true, "engines": { "node": ">= 8" @@ -7311,15 +7959,18 @@ } }, "node_modules/which": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", - "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "dependencies": { "isexe": "^2.0.0" }, "bin": { - "which": "bin/which" + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, "node_modules/which-boxed-primitive": { @@ -7338,16 +7989,113 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/which-builtin-type": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz", + "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==", + "dev": true, + "peer": true, + "dependencies": { + "function.prototype.name": "^1.1.5", + "has-tostringtag": "^1.0.0", + "is-async-function": "^2.0.0", + "is-date-object": "^1.0.5", + "is-finalizationregistry": "^1.0.2", + "is-generator-function": "^1.0.10", + "is-regex": "^1.1.4", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", + "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", + "dev": true, + "peer": true, + "dependencies": { + "is-map": "^2.0.1", + "is-set": "^2.0.1", + "is-weakmap": "^2.0.1", + "is-weakset": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.14.tgz", + "integrity": "sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.6", + "call-bind": "^1.0.5", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/workerpool": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", "dev": true }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, "node_modules/ws": { @@ -7377,6 +8125,48 @@ "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", "dev": true }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/yargs-unparser": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", @@ -7392,30 +8182,6 @@ "node": ">=10" } }, - "node_modules/yargs-unparser/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yargs-unparser/node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", @@ -7475,6 +8241,33 @@ "supports-color": "^5.3.0" } }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -7523,6 +8316,33 @@ "supports-color": "^5.3.0" } }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -7535,30 +8355,19 @@ } }, "@babel/parser": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz", - "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==", + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz", + "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==", "dev": true }, "@babel/runtime": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.4.tgz", - "integrity": "sha512-EXpLCrk55f+cYqmHsSR+yD/0gAIMxxA9QK9lnQWzhMCvt+YmoBN7Zx94s++Kv0+unHk39vxNO8t+CMA2WSS3wA==", + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz", + "integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==", "dev": true, "peer": true, "requires": { - "regenerator-runtime": "^0.13.4" - } - }, - "@babel/runtime-corejs3": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.19.4.tgz", - "integrity": "sha512-HzjQ8+dzdx7dmZy4DQ8KV8aHi/74AjEbBGTFutBmg/pd3dY5/q1sfuOGPTFGEytlQhWoeVXqcK5BwMgIkRkNDQ==", - "dev": true, - "peer": true, - "requires": { - "core-js-pure": "^3.25.1", - "regenerator-runtime": "^0.13.4" + "regenerator-runtime": "^0.14.0" } }, "@bcoe/v8-coverage": { @@ -7765,15 +8574,15 @@ } }, "@eslint-community/regexpp": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.9.1.tgz", - "integrity": "sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", "dev": true }, "@eslint/eslintrc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", - "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "requires": { "ajv": "^6.12.4", @@ -7785,81 +8594,23 @@ "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "globals": { - "version": "13.23.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", - "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } } }, "@eslint/js": { - "version": "8.51.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.51.0.tgz", - "integrity": "sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true }, "@humanwhocodes/config-array": { - "version": "0.11.11", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", - "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, "requires": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", "minimatch": "^3.0.5" - }, - "dependencies": { - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } } }, "@humanwhocodes/module-importer": { @@ -7869,11 +8620,70 @@ "dev": true }, "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", "dev": true }, + "@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "requires": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true + }, + "ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true + }, + "string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + } + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + }, + "wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "requires": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + } + } + } + }, "@istanbuljs/schema": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", @@ -7881,9 +8691,9 @@ "dev": true }, "@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.4.tgz", + "integrity": "sha512-Oud2QPM5dHviZNn4y/WhhYKSXksv+1xLEIsNrAbGcFzUN3ubqWRFT5gwPchNc5NuzILOU4tPBDTZ4VwhL8Y7cw==", "dev": true, "requires": { "@jridgewell/set-array": "^1.0.1", @@ -7892,9 +8702,9 @@ } }, "@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true }, "@jridgewell/set-array": { @@ -7914,19 +8724,19 @@ } }, "@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", "dev": true }, "@jridgewell/trace-mapping": { - "version": "0.3.17", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", - "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.23.tgz", + "integrity": "sha512-9/4foRoUKp8s96tSkh8DlAAc5A0Ty8vLXld+l9gjKKY6ckwI8G15f0hskGmuLZu78ZlGa1vtsfOa+lnB4vG6Jg==", "dev": true, "requires": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "@nodelib/fs.scandir": { @@ -7982,35 +8792,21 @@ "strip-json-comments": "^3.1.0", "taffydb": "2.6.2", "underscore": "~1.13.2" - }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - } } }, "@openpgp/noble-curves": { - "version": "1.2.1-0", - "resolved": "https://registry.npmjs.org/@openpgp/noble-curves/-/noble-curves-1.2.1-0.tgz", - "integrity": "sha512-RUJ3NIGJ04VbUHEOXYxXKKgD+u7D5fJYUox3Ewu1mPbgdjEUvS96nq6xZrCPCCyOTJlyh7jR1tcbOUzWJFiJbQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@openpgp/noble-curves/-/noble-curves-1.3.0.tgz", + "integrity": "sha512-6QjsDyzTc5AZMC3CDRcp2L/VuxIcfxFT4kCWAV/gk4OcjWtgh49S5M7pjkOzYzjhpapu5HYIWkuUdTxDC5WXEw==", "dev": true, "requires": { - "@openpgp/noble-hashes": "1.3.3-0" + "@openpgp/noble-hashes": "1.3.3" } }, "@openpgp/noble-hashes": { - "version": "1.3.3-0", - "resolved": "https://registry.npmjs.org/@openpgp/noble-hashes/-/noble-hashes-1.3.3-0.tgz", - "integrity": "sha512-2MOWNAzEm5fMu3u90HSLxddYU6Fr8P7/7knXrPHyS7DiJevOlDmPES/AZxcWQfhHrwdNLL0fRVdOHkftvIcXVQ==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@openpgp/noble-hashes/-/noble-hashes-1.3.3.tgz", + "integrity": "sha512-CPDNePrQTQrL5Fxd/K3B53Gty4xbNVxnMSUdDmYjW5tTpRqOlme0INYTnnQqoE/XUdIlq5fByOMDuDWR5JpXZw==", "dev": true, "requires": { "@types/bn.js": "^4.11.6", @@ -8039,6 +8835,13 @@ "dev": true, "requires": {} }, + "@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true + }, "@rollup/plugin-alias": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.1.0.tgz", @@ -8060,39 +8863,6 @@ "glob": "^8.0.3", "is-reference": "1.2.1", "magic-string": "^0.30.3" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - } - }, - "minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } } }, "@rollup/plugin-node-resolve": { @@ -8107,17 +8877,6 @@ "is-builtin-module": "^3.2.1", "is-module": "^1.0.0", "resolve": "^1.22.1" - }, - "dependencies": { - "is-builtin-module": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", - "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", - "dev": true, - "requires": { - "builtin-modules": "^3.3.0" - } - } } }, "@rollup/plugin-replace": { @@ -8139,17 +8898,6 @@ "serialize-javascript": "^6.0.1", "smob": "^1.0.0", "terser": "^5.17.4" - }, - "dependencies": { - "serialize-javascript": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", - "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - } } }, "@rollup/plugin-wasm": { @@ -8173,109 +8921,109 @@ } }, "@rollup/rollup-android-arm-eabi": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.9.6.tgz", - "integrity": "sha512-MVNXSSYN6QXOulbHpLMKYi60ppyO13W9my1qogeiAqtjb2yR4LSmfU2+POvDkLzhjYLXz9Rf9+9a3zFHW1Lecg==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.12.0.tgz", + "integrity": "sha512-+ac02NL/2TCKRrJu2wffk1kZ+RyqxVUlbjSagNgPm94frxtr+XDL12E5Ll1enWskLrtrZ2r8L3wED1orIibV/w==", "dev": true, "optional": true }, "@rollup/rollup-android-arm64": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.9.6.tgz", - "integrity": "sha512-T14aNLpqJ5wzKNf5jEDpv5zgyIqcpn1MlwCrUXLrwoADr2RkWA0vOWP4XxbO9aiO3dvMCQICZdKeDrFl7UMClw==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.12.0.tgz", + "integrity": "sha512-OBqcX2BMe6nvjQ0Nyp7cC90cnumt8PXmO7Dp3gfAju/6YwG0Tj74z1vKrfRz7qAv23nBcYM8BCbhrsWqO7PzQQ==", "dev": true, "optional": true }, "@rollup/rollup-darwin-arm64": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.9.6.tgz", - "integrity": "sha512-CqNNAyhRkTbo8VVZ5R85X73H3R5NX9ONnKbXuHisGWC0qRbTTxnF1U4V9NafzJbgGM0sHZpdO83pLPzq8uOZFw==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.12.0.tgz", + "integrity": "sha512-X64tZd8dRE/QTrBIEs63kaOBG0b5GVEd3ccoLtyf6IdXtHdh8h+I56C2yC3PtC9Ucnv0CpNFJLqKFVgCYe0lOQ==", "dev": true, "optional": true }, "@rollup/rollup-darwin-x64": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.9.6.tgz", - "integrity": "sha512-zRDtdJuRvA1dc9Mp6BWYqAsU5oeLixdfUvkTHuiYOHwqYuQ4YgSmi6+/lPvSsqc/I0Omw3DdICx4Tfacdzmhog==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.12.0.tgz", + "integrity": "sha512-cc71KUZoVbUJmGP2cOuiZ9HSOP14AzBAThn3OU+9LcA1+IUqswJyR1cAJj3Mg55HbjZP6OLAIscbQsQLrpgTOg==", "dev": true, "optional": true }, "@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.9.6.tgz", - "integrity": "sha512-oNk8YXDDnNyG4qlNb6is1ojTOGL/tRhbbKeE/YuccItzerEZT68Z9gHrY3ROh7axDc974+zYAPxK5SH0j/G+QQ==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.12.0.tgz", + "integrity": "sha512-a6w/Y3hyyO6GlpKL2xJ4IOh/7d+APaqLYdMf86xnczU3nurFTaVN9s9jOXQg97BE4nYm/7Ga51rjec5nfRdrvA==", "dev": true, "optional": true }, "@rollup/rollup-linux-arm64-gnu": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.9.6.tgz", - "integrity": "sha512-Z3O60yxPtuCYobrtzjo0wlmvDdx2qZfeAWTyfOjEDqd08kthDKexLpV97KfAeUXPosENKd8uyJMRDfFMxcYkDQ==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.12.0.tgz", + "integrity": "sha512-0fZBq27b+D7Ar5CQMofVN8sggOVhEtzFUwOwPppQt0k+VR+7UHMZZY4y+64WJ06XOhBTKXtQB/Sv0NwQMXyNAA==", "dev": true, "optional": true }, "@rollup/rollup-linux-arm64-musl": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.9.6.tgz", - "integrity": "sha512-gpiG0qQJNdYEVad+1iAsGAbgAnZ8j07FapmnIAQgODKcOTjLEWM9sRb+MbQyVsYCnA0Im6M6QIq6ax7liws6eQ==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.12.0.tgz", + "integrity": "sha512-eTvzUS3hhhlgeAv6bfigekzWZjaEX9xP9HhxB0Dvrdbkk5w/b+1Sxct2ZuDxNJKzsRStSq1EaEkVSEe7A7ipgQ==", "dev": true, "optional": true }, "@rollup/rollup-linux-riscv64-gnu": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.9.6.tgz", - "integrity": "sha512-+uCOcvVmFUYvVDr27aiyun9WgZk0tXe7ThuzoUTAukZJOwS5MrGbmSlNOhx1j80GdpqbOty05XqSl5w4dQvcOA==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.12.0.tgz", + "integrity": "sha512-ix+qAB9qmrCRiaO71VFfY8rkiAZJL8zQRXveS27HS+pKdjwUfEhqo2+YF2oI+H/22Xsiski+qqwIBxVewLK7sw==", "dev": true, "optional": true }, "@rollup/rollup-linux-x64-gnu": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.9.6.tgz", - "integrity": "sha512-HUNqM32dGzfBKuaDUBqFB7tP6VMN74eLZ33Q9Y1TBqRDn+qDonkAUyKWwF9BR9unV7QUzffLnz9GrnKvMqC/fw==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.12.0.tgz", + "integrity": "sha512-TenQhZVOtw/3qKOPa7d+QgkeM6xY0LtwzR8OplmyL5LrgTWIXpTQg2Q2ycBf8jm+SFW2Wt/DTn1gf7nFp3ssVA==", "dev": true, "optional": true }, "@rollup/rollup-linux-x64-musl": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.9.6.tgz", - "integrity": "sha512-ch7M+9Tr5R4FK40FHQk8VnML0Szi2KRujUgHXd/HjuH9ifH72GUmw6lStZBo3c3GB82vHa0ZoUfjfcM7JiiMrQ==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.12.0.tgz", + "integrity": "sha512-LfFdRhNnW0zdMvdCb5FNuWlls2WbbSridJvxOvYWgSBOYZtgBfW9UGNJG//rwMqTX1xQE9BAodvMH9tAusKDUw==", "dev": true, "optional": true }, "@rollup/rollup-win32-arm64-msvc": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.9.6.tgz", - "integrity": "sha512-VD6qnR99dhmTQ1mJhIzXsRcTBvTjbfbGGwKAHcu+52cVl15AC/kplkhxzW/uT0Xl62Y/meBKDZvoJSJN+vTeGA==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.12.0.tgz", + "integrity": "sha512-JPDxovheWNp6d7AHCgsUlkuCKvtu3RB55iNEkaQcf0ttsDU/JZF+iQnYcQJSk/7PtT4mjjVG8N1kpwnI9SLYaw==", "dev": true, "optional": true }, "@rollup/rollup-win32-ia32-msvc": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.9.6.tgz", - "integrity": "sha512-J9AFDq/xiRI58eR2NIDfyVmTYGyIZmRcvcAoJ48oDld/NTR8wyiPUu2X/v1navJ+N/FGg68LEbX3Ejd6l8B7MQ==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.12.0.tgz", + "integrity": "sha512-fjtuvMWRGJn1oZacG8IPnzIV6GF2/XG+h71FKn76OYFqySXInJtseAqdprVTDTyqPxQOG9Exak5/E9Z3+EJ8ZA==", "dev": true, "optional": true }, "@rollup/rollup-win32-x64-msvc": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.9.6.tgz", - "integrity": "sha512-jqzNLhNDvIZOrt69Ce4UjGRpXJBzhUBzawMwnaDAwyHriki3XollsewxWzOzz+4yOFDkuJHtTsZFwMxhYJWmLQ==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.12.0.tgz", + "integrity": "sha512-ZYmr5mS2wd4Dew/JjT0Fqi2NPB/ZhZ2VvPp7SmvPZb4Y1CG/LRcS6tcRo2cYU7zLK5A7cdbhWnnWmUjoI4qapg==", "dev": true, "optional": true }, "@sinonjs/commons": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", - "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", "dev": true, "requires": { "type-detect": "4.0.8" } }, "@sinonjs/fake-timers": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.2.0.tgz", - "integrity": "sha512-OPwQlEdg40HAj5KNF8WW6q2KG4Z+cBCZb3m4ninfTZKaBmbIJodviQsDBoYMPHkOyJJMHnOJo5j2+LKDOhOACg==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", "dev": true, "requires": { "@sinonjs/commons": "^3.0.0" @@ -8334,9 +9082,9 @@ "dev": true }, "@tsconfig/node16": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", "dev": true }, "@types/bn.js": { @@ -8349,9 +9097,9 @@ } }, "@types/chai": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.5.tgz", - "integrity": "sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==", + "version": "4.3.12", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.12.tgz", + "integrity": "sha512-zNKDHG/1yxm8Il6uCCVsm+dRdEsJlFoDu73X17y09bId6UwoYww+vFBsAcRzl8knM1sab3Dp1VRikFQwDOtDDw==", "dev": true }, "@types/cookie": { @@ -8361,9 +9109,9 @@ "dev": true }, "@types/cors": { - "version": "2.8.13", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz", - "integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==", + "version": "2.8.17", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", + "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", "dev": true, "requires": { "@types/node": "*" @@ -8388,9 +9136,9 @@ "dev": true }, "@types/linkify-it": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz", - "integrity": "sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.5.tgz", + "integrity": "sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==", "dev": true }, "@types/markdown-it": { @@ -8404,21 +9152,24 @@ } }, "@types/mdurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz", - "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.5.tgz", + "integrity": "sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==", "dev": true }, "@types/node": { - "version": "13.13.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.2.tgz", - "integrity": "sha512-LB2R1Oyhpg8gu4SON/mfforE525+Hi/M1ineICEDftqNVTyFg1aRIeGuTvXAoWHc4nbrFncWtJgMmoyRvuGh7A==", - "dev": true + "version": "20.11.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.21.tgz", + "integrity": "sha512-/ySDLGscFPNasfqStUuWWPfL78jompfIoVzLJPVVAHBh6rpG68+pI2Gk+fNLeI8/f1yPYL4s46EleVIc20F1Ow==", + "dev": true, + "requires": { + "undici-types": "~5.26.4" + } }, "@types/normalize-package-data": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.3.tgz", - "integrity": "sha512-ehPtgRgaULsFG8x0NeYJvmyH1hmlfsNLujHe9dQEia/7MAJYdzMSi19JtchUHjmBA6XC/75dK55mzZH+RyieSg==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", "dev": true }, "@types/resolve": { @@ -8427,6 +9178,12 @@ "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", "dev": true }, + "@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, "accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -8438,9 +9195,9 @@ } }, "acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true }, "acorn-jsx": { @@ -8451,18 +9208,18 @@ "requires": {} }, "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", "dev": true }, "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "dev": true, "requires": { - "es6-promisify": "^5.0.0" + "debug": "4" } }, "ajv": { @@ -8496,17 +9253,6 @@ "dev": true, "requires": { "color-convert": "^2.0.1" - }, - "dependencies": { - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - } } }, "anymatch": { @@ -8531,54 +9277,125 @@ "integrity": "sha512-rsiD3lX+0L0CsiZARp3bf9EGxprtuWAT7PpiJd+Fk53URV0/USOQkBIP1dLTV8t6aui0ECbymQ9W9YCcTd6XgA==", "dev": true }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, "aria-query": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", - "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", "dev": true, "peer": true, "requires": { - "@babel/runtime": "^7.10.2", - "@babel/runtime-corejs3": "^7.10.2" + "dequal": "^2.0.3" + } + }, + "array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dev": true, + "requires": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" } }, "array-includes": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", - "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", + "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "get-intrinsic": "^1.1.3", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", "is-string": "^1.0.7" } }, - "array.prototype.flat": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", - "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", + "array.prototype.filter": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array.prototype.filter/-/array.prototype.filter-1.0.3.tgz", + "integrity": "sha512-VizNcj/RGJiUyQBgzwxzE5oHdeuXY5hSbbmKMlphj1cy1Vl7Pn2asCGbSrru6hSQjmCzqTBPVWAF/whmEOVHbw==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.7" + } + }, + "array.prototype.findlastindex": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.4.tgz", + "integrity": "sha512-hzvSHUshSpCflDR1QMUBLHGHP1VIEBegT4pix9H/Z92Xw3ySoy6c2qh7lJWTJnRJ8JCZ9bJNCgTyYaJGcJu6xQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + } + }, + "array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", "es-shim-unscopables": "^1.0.0" } }, "array.prototype.flatmap": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", - "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", "es-shim-unscopables": "^1.0.0" } }, + "array.prototype.tosorted": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.3.tgz", + "integrity": "sha512-/DdH4TiTmOKzyQbp/eadcCVexiCb36xJg7HshYOYJnNZFDj33GEv0P7GxsynpShhq4OLYJzbGcBDkLsDt7MnNg==", + "dev": true, + "peer": true, + "requires": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.1.0", + "es-shim-unscopables": "^1.0.2" + } + }, + "arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dev": true, + "requires": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + } + }, "assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", @@ -8586,9 +9403,9 @@ "dev": true }, "ast-types-flow": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", - "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==", + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", "dev": true, "peer": true }, @@ -8601,24 +9418,46 @@ "lodash": "^4.17.14" } }, + "asynciterator.prototype": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz", + "integrity": "sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==", + "dev": true, + "peer": true, + "requires": { + "has-symbols": "^1.0.3" + } + }, + "available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "requires": { + "possible-typed-array-names": "^1.0.0" + } + }, "axe-core": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.4.3.tgz", - "integrity": "sha512-32+ub6kkdhhWick/UjvEwRchgoetXqTK14INLqbGm5U2TzBkBNF3nQtLYm8ovxSkQWArjEQvftCKryjZaATu3w==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.0.tgz", + "integrity": "sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==", "dev": true, "peer": true }, "axobject-query": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", - "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", + "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", "dev": true, - "peer": true + "peer": true, + "requires": { + "dequal": "^2.0.3" + } }, "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, "base64id": { @@ -8639,7 +9478,7 @@ "benchmark": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/benchmark/-/benchmark-2.1.4.tgz", - "integrity": "sha1-CfPeMckWQl1JjMLuVloOvzwqVik=", + "integrity": "sha512-l9MlfN4M1K/H2fbhfMy3B7vJd6AGKJVQn2h6Sg/Yx+KckoUA7ewS5Vv6TjSq18ooE1kS9hhAlQRH3AkXIh/aOQ==", "dev": true, "requires": { "lodash": "^4.17.4", @@ -8659,50 +9498,52 @@ "dev": true }, "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true }, "body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", "dev": true, "requires": { "bytes": "3.1.2", - "content-type": "~1.0.4", + "content-type": "~1.0.5", "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.8.1", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.9.7", - "raw-body": "2.4.3", - "type-is": "~1.6.18" + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" }, "dependencies": { - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { - "safer-buffer": ">= 2.1.2 < 3" + "ms": "2.0.0" } }, - "qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==", + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true } } }, "brace-expansion": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", - "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { "balanced-match": "^1.0.0", @@ -8734,47 +9575,27 @@ } }, "browserstack-local": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/browserstack-local/-/browserstack-local-1.4.8.tgz", - "integrity": "sha512-s+mc3gTOJwELdLWi4qFVKtGwMbb5JWsR+JxKlMaJkRJxoZ0gg3WREgPxAN0bm6iU5+S4Bi0sz0oxBRZT8BiNsQ==", + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/browserstack-local/-/browserstack-local-1.5.5.tgz", + "integrity": "sha512-jKne7yosrMcptj3hqxp36TP9k0ZW2sCqhyurX24rUL4G3eT7OLgv+CSQN8iq5dtkv5IK+g+v8fWvsiC/S9KxMg==", "dev": true, "requires": { - "https-proxy-agent": "^4.0.0", + "agent-base": "^6.0.2", + "https-proxy-agent": "^5.0.1", "is-running": "^2.1.0", "ps-tree": "=1.2.0", "temp-fs": "^0.9.9" }, "dependencies": { - "agent-base": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", - "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==", - "dev": true - }, - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, "https-proxy-agent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", - "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "dev": true, "requires": { - "agent-base": "5", + "agent-base": "6", "debug": "4" } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true } } }, @@ -8814,156 +9635,19 @@ "v8-to-istanbul": "^9.0.0", "yargs": "^17.7.2", "yargs-parser": "^21.1.1" - }, - "dependencies": { - "cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "foreground-child": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", - "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.0", - "signal-exit": "^3.0.2" - } - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "dev": true - }, - "istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - } - }, - "istanbul-reports": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", - "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", - "dev": true, - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "dev": true, - "requires": { - "semver": "^7.5.3" - } - }, - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "requires": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "requires": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - } - }, - "yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true - } } }, "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dev": true, "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" } }, "callsites": { @@ -8972,6 +9656,12 @@ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + }, "catharsis": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", @@ -8982,18 +9672,18 @@ } }, "chai": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", - "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", + "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", "dev": true, "requires": { "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^4.1.2", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", "pathval": "^1.1.1", - "type-detect": "^4.0.5" + "type-detect": "^4.0.8" } }, "chai-as-promised": { @@ -9016,15 +9706,18 @@ } }, "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", - "dev": true + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "requires": { + "get-func-name": "^2.0.2" + } }, "chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, "requires": { "anymatch": "~3.1.2", @@ -9035,12 +9728,23 @@ "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } } }, "ci-info": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", - "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", "dev": true }, "clean-regexp": { @@ -9050,15 +9754,34 @@ "dev": true, "requires": { "escape-string-regexp": "^1.0.5" + }, + "dependencies": { + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + } + } + }, + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" } }, "color-convert": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", - "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "color-name": "^1.1.1" + "color-name": "~1.1.4" } }, "color-name": { @@ -9070,7 +9793,7 @@ "commander": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", - "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", + "integrity": "sha512-+pJLBFVk+9ZZdlAOB5WuIElVPPth47hILFkmGym57aq8kwxsowvByvB0DHs1vQAhyMZzdcpTtF0VDKGkSDR4ZQ==", "dev": true, "requires": { "graceful-readlink": ">= 1.0.0" @@ -9079,13 +9802,13 @@ "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", "dev": true }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, "confusing-browser-globals": { @@ -9104,12 +9827,35 @@ "finalhandler": "1.1.2", "parseurl": "~1.3.3", "utils-merge": "1.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + } } }, "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true + }, + "convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, "cookie": { @@ -9118,13 +9864,6 @@ "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", "dev": true }, - "core-js-pure": { - "version": "3.25.5", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.25.5.tgz", - "integrity": "sha512-oml3M22pHM+igfWHDfdLVq2ShWmjM2V4L+dQEBs0DWVIqEm9WHCwGAlZ6BmyBQGy5sFrJmcx+856D9lVKyGWYg==", - "dev": true, - "peer": true - }, "cors": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", @@ -9138,7 +9877,7 @@ "corser": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", - "integrity": "sha1-jtolLsqrWEDc2XXOuQ2TcMgZ/4c=", + "integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==", "dev": true }, "create-require": { @@ -9156,23 +9895,12 @@ "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" - }, - "dependencies": { - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } } }, "custom-event": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", - "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=", + "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==", "dev": true }, "damerau-levenshtein": { @@ -9183,20 +9911,26 @@ "peer": true }, "date-format": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.3.tgz", - "integrity": "sha512-7P3FyqDcfeznLZp2b+OMitV9Sz2lUnsT87WaTat9nVwqsBkTzPG3lPLNwW3en6F4pHUiWzr6vb8CLhjdK9bcxQ==", + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", + "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", "dev": true }, "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "2.1.2" } }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + }, "deep-eql": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", @@ -9218,38 +9952,63 @@ "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true }, - "define-properties": { + "define-data-property": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + } + }, + "define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "requires": { + "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } }, "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true + }, + "dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "peer": true + }, + "destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "dev": true }, "di": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", - "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", + "integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==", "dev": true }, "diff": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", - "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true }, "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, "requires": { "esutils": "^2.0.2" @@ -9258,7 +10017,7 @@ "dom-serialize": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", - "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", + "integrity": "sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ==", "dev": true, "requires": { "custom-event": "~1.0.0", @@ -9273,6 +10032,12 @@ "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", "dev": true }, + "eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, "eckey-utils": { "version": "0.7.14", "resolved": "https://registry.npmjs.org/eckey-utils/-/eckey-utils-0.7.14.tgz", @@ -9282,19 +10047,25 @@ "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true + }, + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true }, "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "dev": true }, "engine.io": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.4.2.tgz", - "integrity": "sha512-FKn/3oMiJjrOEOeUub2WCox6JhxBXq/Zn3fZOMCBxKnNYtsdKjxhl7yR3fZhM9PV+rdE75SU5SYMc+2PGzo+Tg==", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.4.tgz", + "integrity": "sha512-KdVSDKhVKyOi+r5uEabrDLZw2qXStVvCsEB/LN3mw4WFi6Gx50jTyuxYVCwAAC0U46FdnzP/ScKRBTXb/NiEOg==", "dev": true, "requires": { "@types/cookie": "^0.4.1", @@ -9305,37 +10076,20 @@ "cookie": "~0.4.1", "cors": "~2.8.5", "debug": "~4.3.1", - "engine.io-parser": "~5.0.3", + "engine.io-parser": "~5.2.1", "ws": "~8.11.0" - }, - "dependencies": { - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } } }, "engine.io-parser": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.6.tgz", - "integrity": "sha512-tjuoZDMAdEhVnSFleYPCtdL2GXwVTGtNjoeJd9IhIG3C1xs9uwxqRNEu5WpnDZCaozwVlK/nuQhpodhXSIMaxw==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.2.tgz", + "integrity": "sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==", "dev": true }, "ent": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", + "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==", "dev": true }, "entities": { @@ -9345,53 +10099,126 @@ "dev": true }, "error-ex": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", - "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, "requires": { "is-arrayish": "^0.2.1" } }, "es-abstract": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.4.tgz", - "integrity": "sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==", + "version": "1.22.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.4.tgz", + "integrity": "sha512-vZYJlk2u6qHYxBOTjAeg7qUxHdNfih64Uu2J8QqWgXZ2cri0ZpJAkzDUK/q593+mvKwlxyaxr6F1Q+3LKoQRgg==", "dev": true, "requires": { - "call-bind": "^1.0.2", + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.6", + "call-bind": "^1.0.7", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.2", "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.3", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.1", "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", + "hasown": "^2.0.1", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", "is-callable": "^1.2.7", "is-negative-zero": "^2.0.2", "is-regex": "^1.1.4", "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", "is-weakref": "^1.0.2", - "object-inspect": "^1.12.2", + "object-inspect": "^1.13.1", "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.4.3", - "safe-regex-test": "^1.0.0", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", - "unbox-primitive": "^1.0.2" + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.0", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.8", + "string.prototype.trimend": "^1.0.7", + "string.prototype.trimstart": "^1.0.7", + "typed-array-buffer": "^1.0.1", + "typed-array-byte-length": "^1.0.0", + "typed-array-byte-offset": "^1.0.0", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.14" + } + }, + "es-array-method-boxes-properly": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", + "dev": true + }, + "es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.2.4" + } + }, + "es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true + }, + "es-iterator-helpers": { + "version": "1.0.17", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.17.tgz", + "integrity": "sha512-lh7BsUqelv4KUbR5a/ZTaGGIMLCjPGPqJ6q+Oq24YP0RdyptX1uzm4vvaqzk7Zx3bpl/76YLTTDj9L7uYQ92oQ==", + "dev": true, + "peer": true, + "requires": { + "asynciterator.prototype": "^1.0.0", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.4", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.2", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "iterator.prototype": "^1.1.2", + "safe-array-concat": "^1.1.0" + } + }, + "es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" } }, "es-shim-unscopables": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", - "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", "dev": true, "requires": { - "has": "^1.0.3" + "hasown": "^2.0.0" } }, "es-to-primitive": { @@ -9414,7 +10241,7 @@ "es6-promisify": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", "dev": true, "requires": { "es6-promise": "^4.0.3" @@ -9452,36 +10279,37 @@ } }, "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "dev": true }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "dev": true }, "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true }, "eslint": { - "version": "8.51.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.51.0.tgz", - "integrity": "sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.51.0", - "@humanwhocodes/config-array": "^0.11.11", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -9514,68 +10342,11 @@ "text-table": "^0.2.0" }, "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true - }, - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true } } }, @@ -9600,25 +10371,17 @@ "object.assign": "^4.1.2", "object.entries": "^1.1.5", "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } } }, "eslint-import-resolver-node": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz", - "integrity": "sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==", + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "dev": true, "requires": { "debug": "^3.2.7", - "is-core-module": "^2.11.0", - "resolve": "^1.22.1" + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" }, "dependencies": { "debug": { @@ -9629,19 +10392,13 @@ "requires": { "ms": "^2.1.1" } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true } } }, "eslint-module-utils": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", - "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", + "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", "dev": true, "requires": { "debug": "^3.2.7" @@ -9655,43 +10412,39 @@ "requires": { "ms": "^2.1.1" } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true } } }, "eslint-plugin-chai-friendly": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-chai-friendly/-/eslint-plugin-chai-friendly-0.7.2.tgz", - "integrity": "sha512-LOIfGx5sZZ5FwM1shr2GlYAWV9Omdi+1/3byuVagvQNoGUuU0iHhp7AfjA1uR+4dJ4Isfb4+FwBJgQajIw9iAg==", + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-chai-friendly/-/eslint-plugin-chai-friendly-0.7.4.tgz", + "integrity": "sha512-PGPjJ8diYgX1mjLxGJqRop2rrGwZRKImoEOwUOgoIhg0p80MkTaqvmFLe5TF7/iagZHggasvIfQlUyHIhK/PYg==", "dev": true, "requires": {} }, "eslint-plugin-import": { - "version": "2.27.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz", - "integrity": "sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==", + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", "dev": true, "requires": { - "array-includes": "^3.1.6", - "array.prototype.flat": "^1.3.1", - "array.prototype.flatmap": "^1.3.1", + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", "debug": "^3.2.7", "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.7", - "eslint-module-utils": "^2.7.4", - "has": "^1.0.3", - "is-core-module": "^2.11.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", - "object.values": "^1.1.6", - "resolve": "^1.22.1", - "semver": "^6.3.0", - "tsconfig-paths": "^3.14.1" + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" }, "dependencies": { "debug": { @@ -9703,99 +10456,88 @@ "ms": "^2.1.1" } }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } } } }, "eslint-plugin-jsx-a11y": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.1.tgz", - "integrity": "sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.8.0.tgz", + "integrity": "sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==", "dev": true, "peer": true, "requires": { - "@babel/runtime": "^7.18.9", - "aria-query": "^4.2.2", - "array-includes": "^3.1.5", - "ast-types-flow": "^0.0.7", - "axe-core": "^4.4.3", - "axobject-query": "^2.2.0", + "@babel/runtime": "^7.23.2", + "aria-query": "^5.3.0", + "array-includes": "^3.1.7", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "=4.7.0", + "axobject-query": "^3.2.1", "damerau-levenshtein": "^1.0.8", "emoji-regex": "^9.2.2", - "has": "^1.0.3", - "jsx-ast-utils": "^3.3.2", - "language-tags": "^1.0.5", + "es-iterator-helpers": "^1.0.15", + "hasown": "^2.0.0", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", "minimatch": "^3.1.2", - "semver": "^6.3.0" - }, - "dependencies": { - "emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "peer": true - }, - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "peer": true - } + "object.entries": "^1.1.7", + "object.fromentries": "^2.0.7" } }, "eslint-plugin-react": { - "version": "7.31.10", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.31.10.tgz", - "integrity": "sha512-e4N/nc6AAlg4UKW/mXeYWd3R++qUano5/o+t+wnWxIf+bLsOaH3a4q74kX3nDjYym3VBN4HyO9nEn1GcAqgQOA==", + "version": "7.33.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz", + "integrity": "sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==", "dev": true, "peer": true, "requires": { - "array-includes": "^3.1.5", - "array.prototype.flatmap": "^1.3.0", + "array-includes": "^3.1.6", + "array.prototype.flatmap": "^1.3.1", + "array.prototype.tosorted": "^1.1.1", "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.0.12", "estraverse": "^5.3.0", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", - "object.entries": "^1.1.5", - "object.fromentries": "^2.0.5", - "object.hasown": "^1.1.1", - "object.values": "^1.1.5", + "object.entries": "^1.1.6", + "object.fromentries": "^2.0.6", + "object.hasown": "^1.1.2", + "object.values": "^1.1.6", "prop-types": "^15.8.1", - "resolve": "^2.0.0-next.3", - "semver": "^6.3.0", - "string.prototype.matchall": "^4.0.7" + "resolve": "^2.0.0-next.4", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.8" }, "dependencies": { - "resolve": { - "version": "2.0.0-next.4", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz", - "integrity": "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==", + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "peer": true, "requires": { - "is-core-module": "^2.9.0", + "esutils": "^2.0.2" + } + }, + "resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "dev": true, + "peer": true, + "requires": { + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" } - }, - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "peer": true } } }, @@ -9830,25 +10572,10 @@ "strip-indent": "^3.0.0" }, "dependencies": { - "is-builtin-module": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", - "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", - "dev": true, - "requires": { - "builtin-modules": "^3.3.0" - } - }, - "jsesc": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", - "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", - "dev": true - }, "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -9914,15 +10641,15 @@ "dev": true }, "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, "event-stream": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", - "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", + "integrity": "sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==", "dev": true, "requires": { "duplexer": "~0.1.1", @@ -9935,9 +10662,9 @@ } }, "eventemitter3": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.0.tgz", - "integrity": "sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", "dev": true }, "extend": { @@ -9965,9 +10692,9 @@ "dev": true }, "fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, "requires": { "reusify": "^1.0.4" @@ -9995,17 +10722,6 @@ "dev": true, "requires": { "to-regex-range": "^5.0.1" - }, - "dependencies": { - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } } }, "finalhandler": { @@ -10021,6 +10737,32 @@ "parseurl": "~1.3.3", "statuses": "~1.5.0", "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + } } }, "find-up": { @@ -10040,19 +10782,20 @@ "dev": true }, "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, "requires": { - "flatted": "^3.1.0", + "flatted": "^3.2.9", + "keyv": "^4.5.3", "rimraf": "^3.0.2" } }, "flatted": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", - "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, "follow-redirects": { @@ -10061,35 +10804,46 @@ "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", "dev": true }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "requires": { + "is-callable": "^1.1.3" + } + }, + "foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + } + }, "from": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", - "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", + "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==", "dev": true }, "fs-extra": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", - "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "dev": true, "requires": { "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "dependencies": { - "graceful-fs": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", - "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", - "dev": true - } + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" } }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, "fsevents": { @@ -10100,21 +10854,21 @@ "optional": true }, "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true }, "function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" } }, "functions-have-names": { @@ -10136,24 +10890,27 @@ "dev": true }, "get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dev": true, "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" } }, "get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" } }, "get-tsconfig": { @@ -10166,38 +10923,84 @@ } }, "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } } }, "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "requires": { - "is-glob": "^4.0.1" + "is-glob": "^4.0.3" + } + }, + "globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3" + } + }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.3" } }, "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, "graceful-readlink": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", + "integrity": "sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w==", "dev": true }, "graphemer": { @@ -10206,15 +11009,6 @@ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, "has-bigints": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", @@ -10222,20 +11016,26 @@ "dev": true }, "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, "requires": { - "get-intrinsic": "^1.1.1" + "es-define-property": "^1.0.0" } }, + "has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true + }, "has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", @@ -10243,12 +11043,21 @@ "dev": true }, "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, "requires": { - "has-symbols": "^1.0.2" + "has-symbols": "^1.0.3" + } + }, + "hasown": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", + "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", + "dev": true, + "requires": { + "function-bind": "^1.1.2" } }, "he": { @@ -10279,22 +11088,22 @@ "dev": true }, "http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dev": true, "requires": { - "depd": "~1.1.2", + "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", + "statuses": "2.0.1", "toidentifier": "1.0.1" }, "dependencies": { - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "dev": true } } @@ -10329,14 +11138,6 @@ "secure-compare": "3.0.1", "union": "~0.5.0", "url-join": "^4.0.1" - }, - "dependencies": { - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true - } } }, "https-proxy-agent": { @@ -10349,6 +11150,15 @@ "debug": "^3.1.0" }, "dependencies": { + "agent-base": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "dev": true, + "requires": { + "es6-promisify": "^5.0.0" + } + }, "debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", @@ -10357,19 +11167,22 @@ "requires": { "ms": "^2.1.1" } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true } } }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, "ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true }, "import-fresh": { @@ -10385,7 +11198,7 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true }, "indent-string": { @@ -10397,7 +11210,7 @@ "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, "requires": { "once": "^1.3.0", @@ -10405,28 +11218,48 @@ } }, "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", "dev": true, "requires": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", + "es-errors": "^1.3.0", + "hasown": "^2.0.0", "side-channel": "^1.0.4" } }, + "is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + } + }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, + "is-async-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "dev": true, + "peer": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, "is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", @@ -10455,6 +11288,15 @@ "has-tostringtag": "^1.0.0" } }, + "is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, + "requires": { + "builtin-modules": "^3.3.0" + } + }, "is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -10471,12 +11313,12 @@ } }, "is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dev": true, "requires": { - "has": "^1.0.3" + "hasown": "^2.0.0" } }, "is-date-object": { @@ -10497,9 +11339,35 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true }, + "is-finalizationregistry": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", + "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "dev": true, + "peer": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "peer": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -10509,16 +11377,23 @@ "is-extglob": "^2.1.1" } }, + "is-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", + "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", + "dev": true, + "peer": true + }, "is-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", "dev": true }, "is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "dev": true }, "is-number": { @@ -10570,16 +11445,23 @@ "is-running": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-running/-/is-running-2.1.0.tgz", - "integrity": "sha1-MKc/9cw4VOT8JUkICen1q/jeCeA=", + "integrity": "sha512-mjJd3PujZMl7j+D395WTIO5tU5RIDBfVSRtRR4VOJou3H66E38UjbjvDGh3slJzPuolsb+yQFqwHNNdyp5jg3w==", "dev": true }, + "is-set": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", + "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", + "dev": true, + "peer": true + }, "is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", "dev": true, "requires": { - "call-bind": "^1.0.2" + "call-bind": "^1.0.7" } }, "is-string": { @@ -10600,12 +11482,28 @@ "has-symbols": "^1.0.2" } }, + "is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, + "requires": { + "which-typed-array": "^1.1.14" + } + }, "is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true }, + "is-weakmap": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", + "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==", + "dev": true, + "peer": true + }, "is-weakref": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", @@ -10615,6 +11513,17 @@ "call-bind": "^1.0.2" } }, + "is-weakset": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", + "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==", + "dev": true, + "peer": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + } + }, "is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", @@ -10625,29 +11534,89 @@ } }, "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", "dev": true }, "isbinaryfile": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.8.tgz", - "integrity": "sha512-53h6XFniq77YdW+spoRrebh0mnmTxRPTlcuIArO57lmMdq4uBKFKaeTjnb92oYWrSn/LVL+LT+Hap2tFQj8V+w==", + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", + "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", "dev": true }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, + "istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true + }, + "istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + } + }, + "istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "iterator.prototype": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", + "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", + "dev": true, + "peer": true, + "requires": { + "define-properties": "^1.2.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "reflect.getprototypeof": "^1.0.4", + "set-function-name": "^2.0.1" + } + }, + "jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "requires": { + "@isaacs/cliui": "^8.0.2", + "@pkgjs/parseargs": "^0.11.0" + } + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, "js2xmlparser": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", @@ -10657,6 +11626,18 @@ "xmlcreate": "^2.0.4" } }, + "jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true + }, + "json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, "json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -10672,7 +11653,7 @@ "json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, "json5": { @@ -10685,36 +11666,37 @@ } }, "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" + "graceful-fs": "^4.1.6" } }, "jsx-ast-utils": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz", - "integrity": "sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==", + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", "dev": true, "peer": true, "requires": { - "array-includes": "^3.1.5", - "object.assign": "^4.1.3" + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" } }, "just-extend": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", - "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", + "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", "dev": true }, "karma": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.1.tgz", - "integrity": "sha512-Cj57NKOskK7wtFWSlMvZf459iX+kpYIPXmkNUzP2WAFcA7nhr/ALn5R7sw3w+1udFDcpMx/tuB8d5amgm3ijaA==", + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.3.tgz", + "integrity": "sha512-LuucC/RE92tJ8mlCwqEoRWXP38UMAqpnq98vktmS9SznSoUPPUJQbc91dHcxcunROvfQjdORVA/YFviH+Xci9Q==", "dev": true, "requires": { "@colors/colors": "1.5.0", @@ -10736,7 +11718,7 @@ "qjobs": "^1.2.0", "range-parser": "^1.2.1", "rimraf": "^3.0.2", - "socket.io": "^4.4.1", + "socket.io": "^4.7.2", "source-map": "^0.6.1", "tmp": "^0.2.1", "ua-parser-js": "^0.7.30", @@ -10754,61 +11736,35 @@ "wrap-ansi": "^7.0.0" } }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "graceful-fs": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", - "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, - "tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dev": true, - "requires": { - "rimraf": "^3.0.0" - } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", "dev": true }, + "mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "requires": { + "minimist": "^1.2.6" + } + }, "yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", @@ -10844,12 +11800,23 @@ } }, "karma-chrome-launcher": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.1.1.tgz", - "integrity": "sha512-hsIglcq1vtboGPAN+DGCISCFOxW+ZVnIqhDQcCMqqCp+4dmJ0Qpq5QAjkbA0X2L9Mi6OBkHi2Srrbmm7pUKkzQ==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.2.0.tgz", + "integrity": "sha512-rE9RkUPI7I9mAxByQWkGJFXfFD6lE4gC5nPuZdobf/QdTEJI6EU4yIay/cfU/xV4ZxlM5JiTv7zWYgA64NpS5Q==", "dev": true, "requires": { "which": "^1.2.1" + }, + "dependencies": { + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } } }, "karma-firefox-launcher": { @@ -10860,17 +11827,6 @@ "requires": { "is-wsl": "^2.2.0", "which": "^2.0.1" - }, - "dependencies": { - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } } }, "karma-mocha": { @@ -10885,7 +11841,7 @@ "karma-mocha-reporter": { "version": "2.2.5", "resolved": "https://registry.npmjs.org/karma-mocha-reporter/-/karma-mocha-reporter-2.2.5.tgz", - "integrity": "sha1-FRIAlejtgZGG5HoLAS8810GJVWA=", + "integrity": "sha512-Hr6nhkIp0GIJJrvzY8JFeHpQZNseuIakGac4bpw8K1+5F0tLb6l7uvXRa8mt2Z+NVwYgCct4QAfp2R2QP6o00w==", "dev": true, "requires": { "chalk": "^2.1.0", @@ -10919,10 +11875,37 @@ "supports-color": "^5.3.0" } }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", "dev": true, "requires": { "ansi-regex": "^3.0.0" @@ -10940,21 +11923,22 @@ } }, "karma-webkit-launcher": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/karma-webkit-launcher/-/karma-webkit-launcher-2.1.0.tgz", - "integrity": "sha512-S5eqhH0DIcuJFi27nC6eBxZ3MTrPnYybPthDU2Q8dfG0yFrXx8FqNDKSbRZsFFvAKJ55QVtYH1bbArd3ddI5Sg==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/karma-webkit-launcher/-/karma-webkit-launcher-2.4.0.tgz", + "integrity": "sha512-k6fmeEwRt5PiPwb/B8stLNbtqcCqBcdMVUsep58da2uS0pEYr4X/RgP1/ThJK12Q6uispGgWVtDtp6O0hDOF+Q==", "dev": true, "requires": { "is-ci": "^3.0.1", - "uuid": "^9.0.0" - }, - "dependencies": { - "uuid": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", - "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", - "dev": true - } + "uuid": "^9.0.1" + } + }, + "keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "requires": { + "json-buffer": "3.0.1" } }, "klaw": { @@ -10974,13 +11958,13 @@ "peer": true }, "language-tags": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", - "integrity": "sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", "dev": true, "peer": true, "requires": { - "language-subtag-registry": "~0.3.2" + "language-subtag-registry": "^0.3.20" } }, "levn": { @@ -11064,6 +12048,33 @@ "supports-color": "^5.3.0" } }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -11076,33 +12087,16 @@ } }, "log4js": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.4.1.tgz", - "integrity": "sha512-iUiYnXqAmNKiIZ1XSAitQ4TmNs8CdZYTAWINARF3LjnsLN8tY5m0vRwd6uuWj/yNY0YHxeZodnbmxKFUOM2rMg==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz", + "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==", "dev": true, "requires": { - "date-format": "^4.0.3", - "debug": "^4.3.3", - "flatted": "^3.2.4", + "date-format": "^4.0.14", + "debug": "^4.3.4", + "flatted": "^3.2.7", "rfdc": "^1.3.0", - "streamroller": "^3.0.2" - }, - "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } + "streamroller": "^3.1.5" } }, "loose-envify": { @@ -11116,12 +12110,12 @@ } }, "loupe": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", - "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", "dev": true, "requires": { - "get-func-name": "^2.0.0" + "get-func-name": "^2.0.1" } }, "lru-cache": { @@ -11131,30 +12125,34 @@ "dev": true, "requires": { "yallist": "^4.0.0" - }, - "dependencies": { - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } } }, "magic-string": { - "version": "0.30.6", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.6.tgz", - "integrity": "sha512-n62qCLbPjNjyo+owKtveQxZFZTBm+Ms6YoGD23Wew6Vw337PElFNifQpknPruVRQV57kVShPnLGo9vWxVhpPvA==", + "version": "0.30.7", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.7.tgz", + "integrity": "sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==", "dev": true, "requires": { "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, + "make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "requires": { + "semver": "^7.5.3" }, "dependencies": { - "@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true + "semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } } } }, @@ -11167,7 +12165,7 @@ "map-stream": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", - "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=", + "integrity": "sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==", "dev": true }, "markdown-it": { @@ -11181,14 +12179,6 @@ "linkify-it": "^3.0.1", "mdurl": "^1.0.1", "uc.micro": "^1.0.5" - }, - "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - } } }, "markdown-it-anchor": { @@ -11213,28 +12203,28 @@ "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "dev": true }, "mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "dev": true }, "mime-db": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "dev": true }, "mime-types": { - "version": "2.1.34", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", - "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dev": true, "requires": { - "mime-db": "1.51.0" + "mime-db": "1.52.0" } }, "min-indent": { @@ -11258,19 +12248,22 @@ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true }, + "minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true + }, "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true }, "mocha": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", - "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.3.0.tgz", + "integrity": "sha512-uF2XJs+7xSLsrmIvn37i/wnc91nw7XjOQB8ccyx5aEgdnohr7n+rEiZP23WkCYHjilR6+EboEnbq/ZQDz4LSbg==", "dev": true, "requires": { "ansi-colors": "4.1.1", @@ -11280,13 +12273,12 @@ "diff": "5.0.0", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", - "glob": "7.2.0", + "glob": "8.1.0", "he": "1.2.0", "js-yaml": "4.1.0", "log-symbols": "4.1.0", "minimatch": "5.0.1", "ms": "2.1.3", - "nanoid": "3.3.3", "serialize-javascript": "6.0.0", "strip-json-comments": "3.1.1", "supports-color": "8.1.1", @@ -11296,11 +12288,30 @@ "yargs-unparser": "2.0.0" }, "dependencies": { - "argparse": { + "brace-expansion": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } }, "cliui": { "version": "7.0.4", @@ -11313,85 +12324,19 @@ "wrap-ansi": "^7.0.0" } }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, - "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "dependencies": { - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" + "is-glob": "^4.0.1" } }, "log-symbols": { @@ -11411,17 +12356,6 @@ "dev": true, "requires": { "brace-expansion": "^2.0.1" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - } } }, "ms": { @@ -11439,17 +12373,6 @@ "randombytes": "^2.1.0" } }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, "supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -11459,23 +12382,6 @@ "has-flag": "^4.0.0" } }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, "yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", @@ -11500,21 +12406,15 @@ } }, "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "nanoid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", - "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, "negotiator": { @@ -11524,25 +12424,25 @@ "dev": true }, "nise": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.4.tgz", - "integrity": "sha512-8+Ib8rRJ4L0o3kfmyVCL7gzrohyDe0cMFTBa2d364yIrEGMEoetznKJx899YxjybU6bL9SQkYPSBBs1gyYs8Xg==", + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.9.tgz", + "integrity": "sha512-qOnoujW4SV6e40dYxJOb3uvuoPHtmLzIk4TFo+j0jPJoC+5Z9xja5qH5JZobEPsa8+YYphMrOSwnrshEhG2qww==", "dev": true, "requires": { - "@sinonjs/commons": "^2.0.0", - "@sinonjs/fake-timers": "^10.0.2", - "@sinonjs/text-encoding": "^0.7.1", - "just-extend": "^4.0.2", - "path-to-regexp": "^1.7.0" + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/text-encoding": "^0.7.2", + "just-extend": "^6.2.0", + "path-to-regexp": "^6.2.1" }, "dependencies": { - "@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "@sinonjs/fake-timers": { + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", + "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", "dev": true, "requires": { - "type-detect": "4.0.8" + "@sinonjs/commons": "^3.0.0" } } } @@ -11557,6 +12457,14 @@ "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true + } } }, "normalize-path": { @@ -11568,13 +12476,13 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true }, "object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "dev": true }, "object-keys": { @@ -11584,66 +12492,78 @@ "dev": true }, "object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", "has-symbols": "^1.0.3", "object-keys": "^1.1.1" } }, "object.entries": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz", - "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz", + "integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" } }, "object.fromentries": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.5.tgz", - "integrity": "sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", + "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", "dev": true, - "peer": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + } + }, + "object.groupby": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.2.tgz", + "integrity": "sha512-bzBq58S+x+uo0VjurFT0UktpKHOZmv4/xePiOA1nbB9pMqpGK7rUPNgf+1YC+7mE+0HzhTMqNUuCqvKhj6FnBw==", + "dev": true, + "requires": { + "array.prototype.filter": "^1.0.3", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.0.0" } }, "object.hasown": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.1.tgz", - "integrity": "sha512-LYLe4tivNQzq4JdaWW6WO3HMZZJWzkkH8fnI6EebWl0VZth2wL2Lovm74ep2/gZzlaTdV62JZHEqHQ2yVn8Q/A==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.3.tgz", + "integrity": "sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==", "dev": true, "peer": true, "requires": { - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" } }, "object.values": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", - "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", + "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" } }, "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dev": true, "requires": { "ee-first": "1.1.1" @@ -11652,16 +12572,16 @@ "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, "requires": { "wrappy": "1" } }, "opener": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.1.tgz", - "integrity": "sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", "dev": true }, "optionator": { @@ -11738,7 +12658,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true }, "path-key": { @@ -11753,15 +12673,30 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, - "path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", "dev": true, "requires": { - "isarray": "0.0.1" + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", + "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "dev": true + } } }, + "path-to-regexp": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", + "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==", + "dev": true + }, "pathval": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", @@ -11771,7 +12706,7 @@ "pause-stream": { "version": "0.0.11", "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", - "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", + "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==", "dev": true, "requires": { "through": "~2.3" @@ -11790,18 +12725,28 @@ "dev": true }, "playwright": { - "version": "1.30.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.30.0.tgz", - "integrity": "sha512-ENbW5o75HYB3YhnMTKJLTErIBExrSlX2ZZ1C/FzmHjUYIfxj/UnI+DWpQr992m+OQVSg0rCExAOlRwB+x+yyIg==", + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.42.0.tgz", + "integrity": "sha512-Ko7YRUgj5xBHbntrgt4EIw/nE//XBHOKVKnBjO1KuZkmkhlbgyggTe5s9hjqQ1LpN+Xg+kHsQyt5Pa0Bw5XpvQ==", "dev": true, "requires": { - "playwright-core": "1.30.0" + "fsevents": "2.3.2", + "playwright-core": "1.42.0" + }, + "dependencies": { + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + } } }, "playwright-core": { - "version": "1.30.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.30.0.tgz", - "integrity": "sha512-7AnRmTCf+GVYhHbLJsGUtskWTE33SwMZkybJ0v6rqR1boxq2x36U7p1vDRV7HO2IwTZgmycracLxPEJI49wu4g==", + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.42.0.tgz", + "integrity": "sha512-0HD9y8qEVlcbsAjdpBaFjmaTHf+1FeIddy8VJLeiqwhcNqGCBe4Wp2e8knpqiYbzxtxarxiXyNDw2cG8sCaNMQ==", "dev": true }, "pluralize": { @@ -11811,14 +12756,14 @@ "dev": true }, "portfinder": { - "version": "1.0.28", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", - "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", + "version": "1.0.32", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz", + "integrity": "sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==", "dev": true, "requires": { - "async": "^2.6.2", - "debug": "^3.1.1", - "mkdirp": "^0.5.5" + "async": "^2.6.4", + "debug": "^3.2.7", + "mkdirp": "^0.5.6" }, "dependencies": { "debug": { @@ -11830,14 +12775,23 @@ "ms": "^2.1.1" } }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "requires": { + "minimist": "^1.2.6" + } } } }, + "possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true + }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -11866,15 +12820,15 @@ } }, "punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true }, "q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", "dev": true }, "qjobs": { @@ -11914,26 +12868,15 @@ "dev": true }, "raw-body": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", - "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "dev": true, "requires": { "bytes": "3.1.2", - "http-errors": "1.8.1", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" - }, - "dependencies": { - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - } } }, "react-is": { @@ -12028,10 +12971,26 @@ "picomatch": "^2.2.1" } }, + "reflect.getprototypeof": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.5.tgz", + "integrity": "sha512-62wgfC8dJWrmxv44CA36pLDnP6KKl3Vhxb7PL+8+qrrFMMoJij4vgiMP8zV4O8+CBMXY1mHxI5fITGHXFHVmQQ==", + "dev": true, + "peer": true, + "requires": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.0.0", + "get-intrinsic": "^1.2.3", + "globalthis": "^1.0.3", + "which-builtin-type": "^1.1.3" + } + }, "regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", "dev": true, "peer": true }, @@ -12042,14 +13001,15 @@ "dev": true }, "regexp.prototype.flags": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", - "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" } }, "regjsparser": { @@ -12072,31 +13032,31 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true }, "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", "dev": true }, "requizzle": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz", - "integrity": "sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ==", + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.4.tgz", + "integrity": "sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==", "dev": true, "requires": { - "lodash": "^4.17.14" + "lodash": "^4.17.21" } }, "resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, "requires": { - "is-core-module": "^2.9.0", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" } @@ -12120,9 +13080,9 @@ "dev": true }, "rfdc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", - "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.1.tgz", + "integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==", "dev": true }, "rimraf": { @@ -12132,27 +13092,43 @@ "dev": true, "requires": { "glob": "^7.1.3" + }, + "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } } }, "rollup": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.9.6.tgz", - "integrity": "sha512-05lzkCS2uASX0CiLFybYfVkwNbKZG5NFQ6Go0VWyogFTXXbR039UVsegViTntkk4OglHBdF54ccApXRRuXRbsg==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.12.0.tgz", + "integrity": "sha512-wz66wn4t1OHIJw3+XU7mJJQV/2NAfw5OAk6G6Hoo3zcvz/XOfQ52Vgi+AN4Uxoxi0KBBwk2g8zPrTDA4btSB/Q==", "dev": true, "requires": { - "@rollup/rollup-android-arm-eabi": "4.9.6", - "@rollup/rollup-android-arm64": "4.9.6", - "@rollup/rollup-darwin-arm64": "4.9.6", - "@rollup/rollup-darwin-x64": "4.9.6", - "@rollup/rollup-linux-arm-gnueabihf": "4.9.6", - "@rollup/rollup-linux-arm64-gnu": "4.9.6", - "@rollup/rollup-linux-arm64-musl": "4.9.6", - "@rollup/rollup-linux-riscv64-gnu": "4.9.6", - "@rollup/rollup-linux-x64-gnu": "4.9.6", - "@rollup/rollup-linux-x64-musl": "4.9.6", - "@rollup/rollup-win32-arm64-msvc": "4.9.6", - "@rollup/rollup-win32-ia32-msvc": "4.9.6", - "@rollup/rollup-win32-x64-msvc": "4.9.6", + "@rollup/rollup-android-arm-eabi": "4.12.0", + "@rollup/rollup-android-arm64": "4.12.0", + "@rollup/rollup-darwin-arm64": "4.12.0", + "@rollup/rollup-darwin-x64": "4.12.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.12.0", + "@rollup/rollup-linux-arm64-gnu": "4.12.0", + "@rollup/rollup-linux-arm64-musl": "4.12.0", + "@rollup/rollup-linux-riscv64-gnu": "4.12.0", + "@rollup/rollup-linux-x64-gnu": "4.12.0", + "@rollup/rollup-linux-x64-musl": "4.12.0", + "@rollup/rollup-win32-arm64-msvc": "4.12.0", + "@rollup/rollup-win32-ia32-msvc": "4.12.0", + "@rollup/rollup-win32-x64-msvc": "4.12.0", "@types/estree": "1.0.5", "fsevents": "~2.3.2" } @@ -12166,6 +13142,18 @@ "queue-microtask": "^1.2.2" } }, + "safe-array-concat": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.0.tgz", + "integrity": "sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg==", + "dev": true, + "requires": { + "call-bind": "^1.0.5", + "get-intrinsic": "^1.2.2", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + } + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -12173,13 +13161,13 @@ "dev": true }, "safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", "is-regex": "^1.1.4" } }, @@ -12192,15 +13180,50 @@ "secure-compare": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", - "integrity": "sha1-8aAymzCLIh+uN7mXTz1XjQypmeM=", + "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==", "dev": true }, "semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true }, + "serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "set-function-length": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", + "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", + "dev": true, + "requires": { + "define-data-property": "^1.1.2", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.1" + } + }, + "set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "requires": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + } + }, "setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -12223,34 +13246,43 @@ "dev": true }, "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.5.tgz", + "integrity": "sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==", "dev": true, "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" } }, "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, "sinon": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.1.0.tgz", - "integrity": "sha512-cS5FgpDdE9/zx7no8bxROHymSlPLZzq0ChbbLk1DrxBfc+eTeBK3y8nIL+nu/0QeYydhhbLIr7ecHJpywjQaoQ==", + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.2.0.tgz", + "integrity": "sha512-nPS85arNqwBXaIsFCkolHjGIkFo+Oxu9vbgmBJizLAhqe6P2o3Qmj3KCUoRkfhHtvgDhZdWD3risLHAUJ8npjw==", "dev": true, "requires": { "@sinonjs/commons": "^3.0.0", - "@sinonjs/fake-timers": "^10.2.0", + "@sinonjs/fake-timers": "^10.3.0", "@sinonjs/samsam": "^8.0.0", "diff": "^5.1.0", "nise": "^5.1.4", "supports-color": "^7.2.0" + }, + "dependencies": { + "diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "dev": true + } } }, "slash": { @@ -12266,42 +13298,27 @@ "dev": true }, "socket.io": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.6.0.tgz", - "integrity": "sha512-b65bp6INPk/BMMrIgVvX12x3Q+NqlGqSlTuvKQWt0BUJ3Hyy3JangBl7fEoWZTXbOKlCqNPbQ6MbWgok/km28w==", + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.4.tgz", + "integrity": "sha512-DcotgfP1Zg9iP/dH9zvAQcWrE0TtbMVwXmlV4T4mqsvY+gw+LqUGPfx2AoVyRk0FLME+GQhufDMyacFmw7ksqw==", "dev": true, "requires": { "accepts": "~1.3.4", "base64id": "~2.0.0", + "cors": "~2.8.5", "debug": "~4.3.2", - "engine.io": "~6.4.0", + "engine.io": "~6.5.2", "socket.io-adapter": "~2.5.2", - "socket.io-parser": "~4.2.1" - }, - "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } + "socket.io-parser": "~4.2.4" } }, "socket.io-adapter": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz", - "integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.4.tgz", + "integrity": "sha512-wDNHGXGewWAjQPt3pyeYBtpWSq9cLE5UW1ZUPL/2eGK9jtse/FpXib7epSTsz0Q0m+6sg6Y4KtcFTlah1bdOVg==", "dev": true, "requires": { + "debug": "~4.3.4", "ws": "~8.11.0" } }, @@ -12313,23 +13330,6 @@ "requires": { "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.1" - }, - "dependencies": { - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } } }, "source-map": { @@ -12349,30 +13349,41 @@ } }, "spdx-correct": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", - "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", "dev": true, "requires": { - "spdx-license-ids": "^1.0.2" + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" } }, - "spdx-expression-parse": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", - "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", + "spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", "dev": true }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, "spdx-license-ids": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", - "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz", + "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==", "dev": true }, "split": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", - "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", + "integrity": "sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==", "dev": true, "requires": { "through": "2" @@ -12381,83 +13392,116 @@ "statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", "dev": true }, "stream-combiner": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", - "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", + "integrity": "sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==", "dev": true, "requires": { "duplexer": "~0.1.1" } }, "streamroller": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.0.2.tgz", - "integrity": "sha512-ur6y5S5dopOaRXBuRIZ1u6GC5bcEXHRZKgfBjfCglMhmIf+roVCECjvkEYzNQOXIN2/JPnkMPW/8B3CZoKaEPA==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz", + "integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==", "dev": true, "requires": { - "date-format": "^4.0.3", - "debug": "^4.1.1", - "fs-extra": "^10.0.0" + "date-format": "^4.0.14", + "debug": "^4.3.4", + "fs-extra": "^8.1.0" + } + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + } + } + }, + "string-width-cjs": { + "version": "npm:string-width@4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true } } }, "string.prototype.matchall": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz", - "integrity": "sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg==", + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz", + "integrity": "sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==", "dev": true, "peer": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", - "get-intrinsic": "^1.1.1", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "regexp.prototype.flags": "^1.4.1", + "internal-slot": "^1.0.5", + "regexp.prototype.flags": "^1.5.0", + "set-function-name": "^2.0.0", "side-channel": "^1.0.4" } }, - "string.prototype.trimend": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", - "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", + "string.prototype.trim": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", + "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + } + }, + "string.prototype.trimend": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", + "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" } }, "string.prototype.trimstart": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", - "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", + "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" } }, "strip-ansi": { @@ -12469,6 +13513,15 @@ "ansi-regex": "^5.0.1" } }, + "strip-ansi-cjs": { + "version": "npm:strip-ansi@6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -12497,14 +13550,6 @@ "dev": true, "requires": { "has-flag": "^4.0.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - } } }, "supports-preserve-symlinks-flag": { @@ -12522,16 +13567,30 @@ "temp-fs": { "version": "0.9.9", "resolved": "https://registry.npmjs.org/temp-fs/-/temp-fs-0.9.9.tgz", - "integrity": "sha1-gHFzBDeHByDpQxUy/igUNk+IA9c=", + "integrity": "sha512-WfecDCR1xC9b0nsrzSaxPf3ZuWeWLUWblW4vlDQAa1biQaKHiImHnJfeQocQe/hXKMcolRzgkcVX/7kK4zoWbw==", "dev": true, "requires": { "rimraf": "~2.5.2" }, "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, "rimraf": { "version": "2.5.4", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz", - "integrity": "sha1-loAAk8vxoMhr2VtGJUZ1NcKd+gQ=", + "integrity": "sha512-Lw7SHMjssciQb/rRz7JyPIy9+bbUshEucPoLRvWqy09vC5zQixl8Uet+Zl+SROBB/JMWHJRdCk1qdxNWHNMvlQ==", "dev": true, "requires": { "glob": "^7.0.5" @@ -12540,9 +13599,9 @@ } }, "terser": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.27.0.tgz", - "integrity": "sha512-bi1HRwVRskAjheeYl291n3JC4GgO/Ty4z1nVs5AAsmonJulGxpSektecnNedrwK9C7vpvVtcX3cw00VSLt7U2A==", + "version": "5.28.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.28.1.tgz", + "integrity": "sha512-wM+bZp54v/E9eRRGXb5ZFDvinrJIOaTapx3WUokyVGZu5ucVCK55zEgGd5Dl2fSr3jUo5sDiERErUWLY6QPFyA==", "dev": true, "requires": { "@jridgewell/source-map": "^0.3.3", @@ -12559,18 +13618,121 @@ } } }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true }, + "tmp": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.2.tgz", + "integrity": "sha512-ETcvHhaIc9J2MDEAH6N67j9bvBvu/3Gb764qaGhwtFvjtvhegqoqSpofgeyq1Sc24mW5pdyUDs9HP5j3ehkxRw==", + "dev": true, + "requires": { + "rimraf": "^5.0.5" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + } + }, + "glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "requires": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + } + }, + "minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "rimraf": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", + "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", + "dev": true, + "requires": { + "glob": "^10.3.7" + } + }, + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true + } + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, "toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -12578,9 +13740,9 @@ "dev": true }, "ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, "requires": { "@cspotcode/source-map-support": "^0.8.0", @@ -12607,21 +13769,21 @@ } }, "tsconfig-paths": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", - "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", "dev": true, "requires": { "@types/json5": "^0.0.29", - "json5": "^1.0.1", + "json5": "^1.0.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } }, "tsx": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.0.tgz", - "integrity": "sha512-I+t79RYPlEYlHn9a+KzwrvEwhJg35h/1zHsLC2JXvhC2mdynMv6Zxzvhv5EMV6VF5qJlLlkSnMVvdZV3PSIGcg==", + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.1.tgz", + "integrity": "sha512-8d6VuibXHtlN5E3zFkgY8u4DX7Y3Z27zvvPKVmLon/D4AjuKzarkUBTLDBgj9iTQ0hg5xM7c/mYiRVM+HETf0g==", "dev": true, "requires": { "esbuild": "~0.19.10", @@ -12660,6 +13822,58 @@ "mime-types": "~2.1.24" } }, + "typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + } + }, + "typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + } + }, + "typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + } + }, + "typed-array-length": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.5.tgz", + "integrity": "sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + } + }, "typescript": { "version": "5.3.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", @@ -12667,9 +13881,9 @@ "dev": true }, "ua-parser-js": { - "version": "0.7.33", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.33.tgz", - "integrity": "sha512-s8ax/CeZdK9R/56Sui0WM6y9OFREJarMRHqLB2EwkovemBxNQ+Bqu8GAsUnVcXKgphb++ghr/B2BZx4mahujPw==", + "version": "0.7.37", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.37.tgz", + "integrity": "sha512-xV8kqRKM+jhMvcHWUKthV9fNebIzrNy//2O9ZwWcfiBFR5f25XVZPLlEajk/sf3Ra15V92isyQqnIEXRDaZWEA==", "dev": true }, "uc.micro": { @@ -12696,6 +13910,12 @@ "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", "dev": true }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "union": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", @@ -12706,15 +13926,15 @@ } }, "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true }, "uri-js": { @@ -12735,7 +13955,13 @@ "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true + }, + "uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", "dev": true }, "v8-compile-cache-lib": { @@ -12753,24 +13979,16 @@ "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", "convert-source-map": "^2.0.0" - }, - "dependencies": { - "convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - } } }, "validate-npm-package-license": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", - "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, "requires": { - "spdx-correct": "~1.0.0", - "spdx-expression-parse": "~1.0.0" + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" } }, "vary": { @@ -12782,13 +14000,13 @@ "void-elements": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", - "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", + "integrity": "sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==", "dev": true }, "web-streams-polyfill": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.0.tgz", - "integrity": "sha512-EqPmREeOzttaLRm5HS7io98goBgZ7IVz79aDvqjD0kYXLtFZTc0T/U6wHTPKyIjb+MdN7DFIIX6hgdBEpWmfPA==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", "dev": true }, "whatwg-encoding": { @@ -12812,9 +14030,9 @@ } }, "which": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", - "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" @@ -12833,16 +14051,85 @@ "is-symbol": "^1.0.3" } }, + "which-builtin-type": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz", + "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==", + "dev": true, + "peer": true, + "requires": { + "function.prototype.name": "^1.1.5", + "has-tostringtag": "^1.0.0", + "is-async-function": "^2.0.0", + "is-date-object": "^1.0.5", + "is-finalizationregistry": "^1.0.2", + "is-generator-function": "^1.0.10", + "is-regex": "^1.1.4", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.9" + } + }, + "which-collection": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", + "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", + "dev": true, + "peer": true, + "requires": { + "is-map": "^2.0.1", + "is-set": "^2.0.1", + "is-weakmap": "^2.0.1", + "is-weakset": "^2.0.1" + } + }, + "which-typed-array": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.14.tgz", + "integrity": "sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.6", + "call-bind": "^1.0.5", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.1" + } + }, "workerpool": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", "dev": true }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrap-ansi-cjs": { + "version": "npm:wrap-ansi@7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, "ws": { @@ -12858,6 +14145,39 @@ "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", "dev": true }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true + }, "yargs-unparser": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", @@ -12868,20 +14188,6 @@ "decamelize": "^4.0.0", "flat": "^5.0.2", "is-plain-obj": "^2.1.0" - }, - "dependencies": { - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - }, - "decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true - } } }, "yn": { diff --git a/package.json b/package.json index f1ae1e42..b1744c4d 100644 --- a/package.json +++ b/package.json @@ -64,8 +64,8 @@ "devDependencies": { "@openpgp/asmcrypto.js": "^3.1.0", "@openpgp/jsdoc": "^3.6.11", - "@openpgp/noble-curves": "^1.2.1-0", - "@openpgp/noble-hashes": "^1.3.3-0", + "@openpgp/noble-curves": "^1.3.0", + "@openpgp/noble-hashes": "^1.3.3", "@openpgp/seek-bzip": "^1.0.5-git", "@openpgp/tweetnacl": "^1.0.4-1", "@openpgp/web-stream-tools": "~0.1.1", @@ -75,36 +75,36 @@ "@rollup/plugin-replace": "^5.0.5", "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-wasm": "^6.2.2", - "@types/chai": "^4.2.14", + "@types/chai": "^4.3.12", "argon2id": "^1.0.1", "benchmark": "^2.1.4", "c8": "^8.0.1", - "chai": "^4.3.7", + "chai": "^4.4.1", "chai-as-promised": "^7.1.1", "eckey-utils": "^0.7.14", - "eslint": "^8.34.0", + "eslint": "^8.57.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-base": "^15.0.0", - "eslint-plugin-chai-friendly": "^0.7.2", - "eslint-plugin-import": "^2.27.5", + "eslint-plugin-chai-friendly": "^0.7.4", + "eslint-plugin-import": "^2.29.1", "eslint-plugin-unicorn": "^48.0.1", "fflate": "^0.7.4", "http-server": "^14.1.1", - "karma": "^6.4.0", + "karma": "^6.4.3", "karma-browserstack-launcher": "^1.6.0", - "karma-chrome-launcher": "^3.1.1", + "karma-chrome-launcher": "^3.2.0", "karma-firefox-launcher": "^2.1.2", "karma-mocha": "^2.0.1", "karma-mocha-reporter": "^2.2.5", - "karma-webkit-launcher": "^2.1.0", - "mocha": "^10.2.0", - "playwright": "^1.30.0", - "rollup": "^4.9.5", - "sinon": "^15.1.0", - "ts-node": "^10.9.1", - "tsx": "^4.7.0", + "karma-webkit-launcher": "^2.4.0", + "mocha": "^10.3.0", + "playwright": "^1.42.0", + "rollup": "^4.12.0", + "sinon": "^15.2.0", + "ts-node": "^10.9.2", + "tsx": "^4.7.1", "typescript": "^5.3.3", - "web-streams-polyfill": "^3.2.0" + "web-streams-polyfill": "^3.3.3" }, "repository": { "type": "git", From f5cebfe6fdbbcbf072805b3a1aef61314ff4dd96 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Wed, 28 Feb 2024 12:58:43 +0100 Subject: [PATCH 110/201] CI: update Playwright browser installation --- .github/workflows/tests.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index cd4ce7ab..539020d7 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -93,11 +93,11 @@ jobs: - name: Install browsers if: steps.cache-playwright-browsers.outputs.cache-hit != 'true' run: | - npx playwright install-deps chrome - npx playwright install-deps firefox + npx playwright install --with-deps chromium + npx playwright install --with-deps firefox - name: Install WebKit # caching not possible, external shared libraries required - run: npx playwright install-deps webkit + run: npx playwright install --with-deps webkit - name: Run browser tests run: npm run test-browser From df59dec319add7ede0b3dafaed070d9d7d4648c2 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Wed, 28 Feb 2024 13:21:05 +0100 Subject: [PATCH 111/201] Update README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a06ff88f..c70e6822 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ library to convert back and forth between them. * If the user's browser supports [native WebCrypto](https://caniuse.com/#feat=cryptography) via the `window.crypto.subtle` API, this will be used. Under Node.js the native [crypto module](https://nodejs.org/api/crypto.html#crypto_crypto) is used. * The library implements authenticated encryption (AEAD) as per the ["crypto refresh" draft standard](https://datatracker.ietf.org/doc/draft-ietf-openpgp-crypto-refresh) using AES-OCB, EAX, or GCM. This makes symmetric encryption faster on platforms with native implementations. However, since the specification is very recent and other OpenPGP implementations are in the process of adopting it, the feature is currently behind a flag. **Note: activating this setting can break compatibility with other OpenPGP implementations which have yet to implement the feature.** You can enable it by setting `openpgp.config.aeadProtect = true`. -Note that this setting has a different effect from the one in OpenPGP.js v5, which implemented support for a provisional version of AEAD from [RFC4880bis](https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-10), which was modified in a later draft of the crypto refresh. +Note that this setting has a different effect from the one in OpenPGP.js v6, which implemented support for a provisional version of AEAD from [RFC4880bis](https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-10), which was modified in a later draft of the crypto refresh. You can change the AEAD mode by setting one of the following options: @@ -182,7 +182,7 @@ If you notice missing or incorrect type definitions, feel free to open a PR. ### Examples -Here are some examples of how to use OpenPGP.js v5. For more elaborate examples and working code, please check out the [public API unit tests](https://github.com/openpgpjs/openpgpjs/blob/main/test/general/openpgp.js). If you're upgrading from v4 it might help to check out the [changelog](https://github.com/openpgpjs/openpgpjs/wiki/V5-Changelog) and [documentation](https://github.com/openpgpjs/openpgpjs#documentation). +Here are some examples of how to use OpenPGP.js v6. For more elaborate examples and working code, please check out the [public API unit tests](https://github.com/openpgpjs/openpgpjs/blob/main/test/general/openpgp.js). If you're upgrading from v4 it might help to check out the [changelog](https://github.com/openpgpjs/openpgpjs/wiki/v6-Changelog) and [documentation](https://github.com/openpgpjs/openpgpjs#documentation). #### Encrypt and decrypt *Uint8Array* data with a password From 147d043a32e27ddfec82f5efffb790ac7803c34f Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Wed, 28 Feb 2024 13:17:40 +0100 Subject: [PATCH 112/201] 6.0.0-alpha.1 --- docs/AEADEncryptedDataPacket.html | 16 +- docs/Argon2S2K.html | 18 +- docs/CleartextMessage.html | 14 +- docs/CompressedDataPacket.html | 82 +- docs/Key.html | 58 +- docs/LiteralDataPacket.html | 22 +- docs/MarkerPacket.html | 6 +- docs/Message.html | 42 +- docs/OnePassSignaturePacket.html | 24 +- docs/PacketList.html | 16 +- docs/PaddingPacket.html | 10 +- docs/PrivateKey.html | 22 +- docs/PublicKey.html | 10 +- docs/PublicKeyEncryptedSessionKeyPacket.html | 16 +- docs/PublicKeyPacket.html | 48 +- docs/PublicSubkeyPacket.html | 48 +- docs/SecretKeyPacket.html | 74 +- docs/SecretSubkeyPacket.html | 74 +- docs/Signature.html | 10 +- docs/SignaturePacket.html | 26 +- ...EncryptedIntegrityProtectedDataPacket.html | 12 +- docs/SymEncryptedSessionKeyPacket.html | 18 +- docs/SymmetricallyEncryptedDataPacket.html | 12 +- docs/TrustPacket.html | 6 +- docs/UserAttributePacket.html | 10 +- docs/UserIDPacket.html | 12 +- docs/global.html | 965 +++++++++-- docs/index.html | 10 +- docs/module-config.html | 182 +-- docs/module-crypto.html | 6 +- docs/module-crypto_aes_kw.html | 107 +- docs/module-crypto_cipher.html | 1430 ----------------- docs/module-crypto_cmac.html | 8 +- docs/module-crypto_crypto.html | 32 +- docs/module-crypto_hash.html | 10 +- docs/module-crypto_hkdf.html | 4 +- docs/module-crypto_mode.html | 12 +- docs/module-crypto_mode_cfb.html | 6 +- docs/module-crypto_mode_eax.html | 10 +- docs/module-crypto_mode_gcm.html | 6 +- docs/module-crypto_mode_ocb.html | 10 +- docs/module-crypto_pkcs1.html | 12 +- docs/module-crypto_public_key.html | 12 +- docs/module-crypto_public_key_dsa.html | 12 +- docs/module-crypto_public_key_elgamal.html | 12 +- docs/module-crypto_public_key_elliptic.html | 4 +- ...dule-crypto_public_key_elliptic_curve.html | 14 +- ...odule-crypto_public_key_elliptic_ecdh.html | 62 +- ...dule-crypto_public_key_elliptic_ecdsa.html | 12 +- ...dule-crypto_public_key_elliptic_eddsa.html | 12 +- ...ypto_public_key_elliptic_eddsa_legacy.html | 10 +- docs/module-crypto_public_key_prime.html | 12 +- docs/module-crypto_public_key_rsa.html | 110 +- docs/module-crypto_random.html | 8 +- docs/module-crypto_signature.html | 10 +- docs/module-encoding_base64.html | 10 +- docs/module-enums.html | 878 +--------- docs/module-key_Subkey-Subkey.html | 42 +- docs/module-key_Subkey.html | 2 +- docs/module-key_User-User.html | 22 +- docs/module-key_User.html | 2 +- docs/module-key_helper.html | 24 +- docs/module-packet_packet.html | 12 +- docs/module-type_ecdh_symkey.html | 4 +- docs/module-type_kdf_params-KDFParams.html | 8 +- docs/module-type_keyid-KeyID.html | 16 +- docs/module-type_keyid.html | 2 +- docs/module-type_oid.html | 4 +- docs/module-type_s2k-GenericS2K.html | 18 +- docs/module-type_s2k.html | 4 +- docs/module-type_x25519x448_symkey.html | 4 +- docs/module-util.html | 4 +- package-lock.json | 4 +- package.json | 2 +- 74 files changed, 1644 insertions(+), 3224 deletions(-) delete mode 100644 docs/module-crypto_cipher.html diff --git a/docs/AEADEncryptedDataPacket.html b/docs/AEADEncryptedDataPacket.html index da6470c6..1ebb55a7 100644 --- a/docs/AEADEncryptedDataPacket.html +++ b/docs/AEADEncryptedDataPacket.html @@ -98,7 +98,7 @@ AEAD Protected Data Packet

Source:
@@ -200,7 +200,7 @@ AEAD Protected Data Packet

Source:
@@ -270,7 +270,7 @@ AEAD Protected Data Packet

Source:
@@ -475,7 +475,7 @@ AEAD Protected Data Packet

Source:
@@ -717,7 +717,7 @@ AEAD Protected Data Packet

Source:
@@ -888,7 +888,7 @@ AEAD Protected Data Packet

Source:
@@ -1007,7 +1007,7 @@ AEAD Protected Data Packet

Source:
@@ -1078,7 +1078,7 @@ AEAD Protected Data Packet


diff --git a/docs/Argon2S2K.html b/docs/Argon2S2K.html index 7cbeb4ff..2f363b7e 100644 --- a/docs/Argon2S2K.html +++ b/docs/Argon2S2K.html @@ -152,7 +152,7 @@
Source:
@@ -258,7 +258,7 @@
Source:
@@ -332,7 +332,7 @@
Source:
@@ -406,7 +406,7 @@
Source:
@@ -480,7 +480,7 @@
Source:
@@ -612,7 +612,7 @@ hashAlgorithm

Source:
@@ -791,7 +791,7 @@ hashAlgorithm

Source:
@@ -903,7 +903,7 @@ hashAlgorithm

Source:
@@ -971,7 +971,7 @@ hashAlgorithm


diff --git a/docs/CleartextMessage.html b/docs/CleartextMessage.html index 1d6fba9e..a7598850 100644 --- a/docs/CleartextMessage.html +++ b/docs/CleartextMessage.html @@ -168,7 +168,7 @@ See https://tools.ietf.o
Source:
@@ -346,7 +346,7 @@ See https://tools.ietf.o
Source:
@@ -461,7 +461,7 @@ See https://tools.ietf.o
Source:
@@ -573,7 +573,7 @@ See https://tools.ietf.o
Source:
@@ -974,7 +974,7 @@ See https://tools.ietf.o
Source:
@@ -1211,7 +1211,7 @@ See https://tools.ietf.o
Source:
@@ -1279,7 +1279,7 @@ See https://tools.ietf.o
diff --git a/docs/CompressedDataPacket.html b/docs/CompressedDataPacket.html index 2a8a0504..45d85ebb 100644 --- a/docs/CompressedDataPacket.html +++ b/docs/CompressedDataPacket.html @@ -160,7 +160,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

Source:
@@ -266,7 +266,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

Source:
@@ -343,71 +343,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

Source:
- - - - - - - - - - - - - - - - -

deflateLevel

- - - - -
-

zip/zlib compression level, between 1 and 9

-
- - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
@@ -481,7 +417,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

Source:
@@ -563,7 +499,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

Source:
@@ -715,7 +651,7 @@ read by read_packet

Source:
@@ -900,7 +836,7 @@ read by read_packet

Source:
@@ -990,7 +926,7 @@ read by read_packet

Source:
@@ -1061,7 +997,7 @@ read by read_packet


diff --git a/docs/Key.html b/docs/Key.html index 4eafe297..e306f07c 100644 --- a/docs/Key.html +++ b/docs/Key.html @@ -96,7 +96,7 @@ Can contain additional subkeys, signatures, user ids, user attributes.

Source:
@@ -333,7 +333,7 @@ if it is a valid revocation signature.

Source:
@@ -514,7 +514,7 @@ if it is a valid revocation signature.

Source:
@@ -626,7 +626,7 @@ if it is a valid revocation signature.

Source:
@@ -738,7 +738,7 @@ if it is a valid revocation signature.

Source:
@@ -1006,7 +1006,7 @@ if it is a valid revocation signature.

Source:
@@ -1225,7 +1225,7 @@ Returns Infinity if the key doesn't expire, or null if
Source:
@@ -1333,7 +1333,7 @@ Returns Infinity if the key doesn't expire, or null if
Source:
@@ -1445,7 +1445,7 @@ Returns Infinity if the key doesn't expire, or null if
Source:
@@ -1557,7 +1557,7 @@ Returns Infinity if the key doesn't expire, or null if
Source:
@@ -1735,7 +1735,7 @@ If no keyID is given, returns all keys, starting with the primary key.

Source:
@@ -1977,7 +1977,7 @@ algorithm preferences, and so on.

Source:
@@ -2220,7 +2220,7 @@ algorithm preferences, and so on.

Source:
@@ -2425,7 +2425,7 @@ algorithm preferences, and so on.

Source:
@@ -2717,7 +2717,7 @@ algorithm preferences, and so on.

Source:
@@ -2911,7 +2911,7 @@ If no keyID is given, returns all subkeys.

Source:
@@ -3023,7 +3023,7 @@ If no keyID is given, returns all subkeys.

Source:
@@ -3135,7 +3135,7 @@ If no keyID is given, returns all subkeys.

Source:
@@ -3412,7 +3412,7 @@ If no keyID is given, returns all subkeys.

Source:
@@ -3596,7 +3596,7 @@ If no keyID is given, returns all subkeys.

Source:
@@ -3811,7 +3811,7 @@ If no keyID is given, returns all subkeys.

Source:
@@ -4081,7 +4081,7 @@ If no keyID is given, returns all subkeys.

Source:
@@ -4193,7 +4193,7 @@ If no keyID is given, returns all subkeys.

Source:
@@ -4434,7 +4434,7 @@ a private key is returned.

Source:
@@ -4677,7 +4677,7 @@ a private key is returned.

Source:
@@ -4918,7 +4918,7 @@ and valid self signature. Throws if the primary key is invalid.

Source:
@@ -5201,7 +5201,7 @@ and valid self signature. Throws if the primary key is invalid.

Source:
@@ -5314,7 +5314,7 @@ Signature validity is null if the verification keys do not correspond to the cer
Source:
@@ -5382,7 +5382,7 @@ Signature validity is null if the verification keys do not correspond to the cer
diff --git a/docs/LiteralDataPacket.html b/docs/LiteralDataPacket.html index c3d734a8..1b5ec55a 100644 --- a/docs/LiteralDataPacket.html +++ b/docs/LiteralDataPacket.html @@ -147,7 +147,7 @@ further interpreted.

Source:
@@ -326,7 +326,7 @@ further interpreted.

Source:
@@ -441,7 +441,7 @@ further interpreted.

Source:
@@ -623,7 +623,7 @@ with normalized end of line to \n

Source:
@@ -790,7 +790,7 @@ with normalized end of line to \n

Source:
@@ -977,7 +977,7 @@ with normalized end of line to \n

Source:
@@ -1116,7 +1116,7 @@ with normalized end of line to \n

Source:
@@ -1302,7 +1302,7 @@ will be normalized to \r\n and by default text is converted to UTF8

Source:
@@ -1392,7 +1392,7 @@ will be normalized to \r\n and by default text is converted to UTF8

Source:
@@ -1507,7 +1507,7 @@ will be normalized to \r\n and by default text is converted to UTF8

Source:
@@ -1575,7 +1575,7 @@ will be normalized to \r\n and by default text is converted to UTF8


diff --git a/docs/MarkerPacket.html b/docs/MarkerPacket.html index d41e366f..bf14fa5d 100644 --- a/docs/MarkerPacket.html +++ b/docs/MarkerPacket.html @@ -106,7 +106,7 @@ software is necessary to process the message.

Source:
@@ -265,7 +265,7 @@ software is necessary to process the message.

Source:
@@ -333,7 +333,7 @@ software is necessary to process the message.


diff --git a/docs/Message.html b/docs/Message.html index 47b41564..146ae170 100644 --- a/docs/Message.html +++ b/docs/Message.html @@ -146,7 +146,7 @@ See https://tools.iet
Source:
@@ -661,7 +661,7 @@ See https://tools.iet
Source:
@@ -933,7 +933,7 @@ See https://tools.iet
Source:
@@ -1140,7 +1140,7 @@ See https://tools.iet
Source:
@@ -1291,7 +1291,7 @@ See https://tools.iet
Source:
@@ -1495,7 +1495,7 @@ See https://tools.iet
Source:
@@ -1800,7 +1800,7 @@ See https://tools.iet
Source:
@@ -2105,7 +2105,7 @@ See https://tools.iet
Source:
@@ -2545,7 +2545,7 @@ See https://tools.iet
Source:
@@ -2657,7 +2657,7 @@ See https://tools.iet
Source:
@@ -2769,7 +2769,7 @@ See https://tools.iet
Source:
@@ -2884,7 +2884,7 @@ See https://tools.iet
Source:
@@ -2999,7 +2999,7 @@ See https://tools.iet
Source:
@@ -3111,7 +3111,7 @@ See https://tools.iet
Source:
@@ -3515,7 +3515,7 @@ See https://tools.iet
Source:
@@ -3916,7 +3916,7 @@ See https://tools.iet
Source:
@@ -4028,7 +4028,7 @@ See https://tools.iet
Source:
@@ -4265,7 +4265,7 @@ See https://tools.iet
Source:
@@ -4531,7 +4531,7 @@ See https://tools.iet
Source:
@@ -4643,7 +4643,7 @@ See https://tools.iet
Source:
@@ -4711,7 +4711,7 @@ See https://tools.iet
diff --git a/docs/OnePassSignaturePacket.html b/docs/OnePassSignaturePacket.html index 0d385ee7..0f2bdf57 100644 --- a/docs/OnePassSignaturePacket.html +++ b/docs/OnePassSignaturePacket.html @@ -101,7 +101,7 @@ can compute the entire signed message in one pass.

Source:
@@ -199,7 +199,7 @@ that describes another signature to be applied to the same message data.

Source:
@@ -273,7 +273,7 @@ that describes another signature to be applied to the same message data.

Source:
@@ -344,7 +344,7 @@ that describes another signature to be applied to the same message data.

Source:
@@ -408,7 +408,7 @@ that describes another signature to be applied to the same message data.

Source:
@@ -482,7 +482,7 @@ that describes another signature to be applied to the same message data.

Source:
@@ -553,7 +553,7 @@ that describes another signature to be applied to the same message data.

Source:
@@ -629,7 +629,7 @@ Signature types are described in
Source:
@@ -693,7 +693,7 @@ Signature types are described in
Source:
@@ -824,7 +824,7 @@ Signature types are described in
Source:
@@ -936,7 +936,7 @@ Signature types are described in
Source:
@@ -1004,7 +1004,7 @@ Signature types are described in
diff --git a/docs/PacketList.html b/docs/PacketList.html index 26512388..dc87bd44 100644 --- a/docs/PacketList.html +++ b/docs/PacketList.html @@ -97,7 +97,7 @@ are stored as numerical indices.

Source:
@@ -345,7 +345,7 @@ Equivalent to calling read on an empty PacketList instance.

Source:
@@ -530,7 +530,7 @@ Equivalent to calling read on an empty PacketList instance.

Source:
@@ -687,7 +687,7 @@ Equivalent to calling read on an empty PacketList instance.

Source:
@@ -859,7 +859,7 @@ Equivalent to calling read on an empty PacketList instance.

Source:
@@ -1097,7 +1097,7 @@ Equivalent to calling read on an empty PacketList instance.

Source:
@@ -1200,7 +1200,7 @@ class instance.

Source:
@@ -1268,7 +1268,7 @@ class instance.


diff --git a/docs/PaddingPacket.html b/docs/PaddingPacket.html index f61bf58f..6f9faa6a 100644 --- a/docs/PaddingPacket.html +++ b/docs/PaddingPacket.html @@ -97,7 +97,7 @@ Padding Packet

Source:
@@ -256,7 +256,7 @@ Padding Packet

Source:
@@ -427,7 +427,7 @@ Padding Packet

Source:
@@ -517,7 +517,7 @@ Padding Packet

Source:
@@ -585,7 +585,7 @@ Padding Packet


diff --git a/docs/PrivateKey.html b/docs/PrivateKey.html index 492f3427..8cf63e1c 100644 --- a/docs/PrivateKey.html +++ b/docs/PrivateKey.html @@ -144,7 +144,7 @@
Source:
@@ -453,7 +453,7 @@ Note: Curve448 and Curve25519 are not widely supported yet.

Source:
@@ -622,7 +622,7 @@ Note: Curve448 and Curve25519 are not widely supported yet.

Source:
@@ -734,7 +734,7 @@ Note: Curve448 and Curve25519 are not widely supported yet.

Source:
@@ -979,7 +979,7 @@ This is useful to retrieve keys for session key decryption

Source:
@@ -1092,7 +1092,7 @@ A dummy key is considered encrypted.

Source:
@@ -1182,7 +1182,7 @@ A dummy key is considered encrypted.

Source:
@@ -1485,7 +1485,7 @@ A dummy key is considered encrypted.

Source:
@@ -1597,7 +1597,7 @@ A dummy key is considered encrypted.

Source:
@@ -1774,7 +1774,7 @@ If only gnu-dummy keys are found, we cannot properly validate so we throw an err
Source:
@@ -1849,7 +1849,7 @@ If only gnu-dummy keys are found, we cannot properly validate so we throw an err
diff --git a/docs/PublicKey.html b/docs/PublicKey.html index 0719a06c..99a3d8d4 100644 --- a/docs/PublicKey.html +++ b/docs/PublicKey.html @@ -144,7 +144,7 @@
Source:
@@ -315,7 +315,7 @@
Source:
@@ -427,7 +427,7 @@
Source:
@@ -535,7 +535,7 @@
Source:
@@ -603,7 +603,7 @@
diff --git a/docs/PublicKeyEncryptedSessionKeyPacket.html b/docs/PublicKeyEncryptedSessionKeyPacket.html index c9f05bd5..db373e3b 100644 --- a/docs/PublicKeyEncryptedSessionKeyPacket.html +++ b/docs/PublicKeyEncryptedSessionKeyPacket.html @@ -107,7 +107,7 @@ decrypt the message.

Source:
@@ -209,7 +209,7 @@ decrypt the message.

Source:
@@ -283,7 +283,7 @@ decrypt the message.

Source:
@@ -458,7 +458,7 @@ This is needed for constant-time processing. Expected object of the form: { sess
Source:
@@ -626,7 +626,7 @@ This is needed for constant-time processing. Expected object of the form: { sess
Source:
@@ -794,7 +794,7 @@ This is needed for constant-time processing. Expected object of the form: { sess
Source:
@@ -884,7 +884,7 @@ This is needed for constant-time processing. Expected object of the form: { sess
Source:
@@ -952,7 +952,7 @@ This is needed for constant-time processing. Expected object of the form: { sess
diff --git a/docs/PublicKeyPacket.html b/docs/PublicKeyPacket.html index 476c16f1..c0d1ed6f 100644 --- a/docs/PublicKeyPacket.html +++ b/docs/PublicKeyPacket.html @@ -195,7 +195,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -301,7 +301,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -375,7 +375,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -449,7 +449,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -523,7 +523,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -597,7 +597,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -671,7 +671,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -735,7 +735,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -816,7 +816,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -880,7 +880,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -1018,7 +1018,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -1130,7 +1130,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -1220,7 +1220,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -1310,7 +1310,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -1422,7 +1422,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -1530,7 +1530,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -1642,7 +1642,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -1754,7 +1754,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -1866,7 +1866,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -1978,7 +1978,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -2138,7 +2138,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -2250,7 +2250,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -2411,7 +2411,7 @@ key (sometimes called an OpenPGP certificate).

Source:
@@ -2457,7 +2457,7 @@ key (sometimes called an OpenPGP certificate).


diff --git a/docs/PublicSubkeyPacket.html b/docs/PublicSubkeyPacket.html index 2725ce91..1a11c8a2 100644 --- a/docs/PublicSubkeyPacket.html +++ b/docs/PublicSubkeyPacket.html @@ -193,7 +193,7 @@ services.

Source:
@@ -315,7 +315,7 @@ services.

Source:
@@ -394,7 +394,7 @@ services.

Source:
@@ -473,7 +473,7 @@ services.

Source:
@@ -552,7 +552,7 @@ services.

Source:
@@ -631,7 +631,7 @@ services.

Source:
@@ -710,7 +710,7 @@ services.

Source:
@@ -779,7 +779,7 @@ services.

Source:
@@ -865,7 +865,7 @@ services.

Source:
@@ -934,7 +934,7 @@ services.

Source:
@@ -1072,7 +1072,7 @@ services.

Source:
@@ -1189,7 +1189,7 @@ services.

Source:
@@ -1284,7 +1284,7 @@ services.

Source:
@@ -1379,7 +1379,7 @@ services.

Source:
@@ -1496,7 +1496,7 @@ services.

Source:
@@ -1609,7 +1609,7 @@ services.

Source:
@@ -1726,7 +1726,7 @@ services.

Source:
@@ -1843,7 +1843,7 @@ services.

Source:
@@ -1960,7 +1960,7 @@ services.

Source:
@@ -2077,7 +2077,7 @@ services.

Source:
@@ -2242,7 +2242,7 @@ services.

Source:
@@ -2359,7 +2359,7 @@ services.

Source:
@@ -2525,7 +2525,7 @@ services.

Source:
@@ -2571,7 +2571,7 @@ services.


diff --git a/docs/SecretKeyPacket.html b/docs/SecretKeyPacket.html index 59097cb0..d51ed4de 100644 --- a/docs/SecretKeyPacket.html +++ b/docs/SecretKeyPacket.html @@ -191,7 +191,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -308,7 +308,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -387,7 +387,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -466,7 +466,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -545,7 +545,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -624,7 +624,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -688,7 +688,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -767,7 +767,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -831,7 +831,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -905,7 +905,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -984,7 +984,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -1053,7 +1053,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -1134,7 +1134,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -1208,7 +1208,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -1282,7 +1282,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -1361,7 +1361,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -1430,7 +1430,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -1519,7 +1519,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -1614,7 +1614,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -1709,7 +1709,7 @@ includes the secret-key material after all the public-key fields.

Source:
@@ -1851,7 +1851,7 @@ otherwise calls to this function will throw an error.

Source:
@@ -2065,7 +2065,7 @@ This can be used to remove passphrase protection after calling decrypt().

Source:
@@ -2189,7 +2189,7 @@ This can be used to remove passphrase protection after calling decrypt().

Source:
@@ -2306,7 +2306,7 @@ This can be used to remove passphrase protection after calling decrypt().

Source:
@@ -2419,7 +2419,7 @@ This can be used to remove passphrase protection after calling decrypt().

Source:
@@ -2536,7 +2536,7 @@ This can be used to remove passphrase protection after calling decrypt().

Source:
@@ -2653,7 +2653,7 @@ This can be used to remove passphrase protection after calling decrypt().

Source:
@@ -2770,7 +2770,7 @@ This can be used to remove passphrase protection after calling decrypt().

Source:
@@ -2888,7 +2888,7 @@ Returns false for gnu-dummy keys and null for public keys.

Source:
@@ -2999,7 +2999,7 @@ Returns false for gnu-dummy keys and null for public keys.

Source:
@@ -3114,7 +3114,7 @@ Such keys are:

Source:
@@ -3266,7 +3266,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
Source:
@@ -3411,7 +3411,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
Source:
@@ -3501,7 +3501,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
Source:
@@ -3625,7 +3625,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
Source:
@@ -3791,7 +3791,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
Source:
@@ -3837,7 +3837,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
diff --git a/docs/SecretSubkeyPacket.html b/docs/SecretSubkeyPacket.html index 63f9b9b3..a3a608b0 100644 --- a/docs/SecretSubkeyPacket.html +++ b/docs/SecretSubkeyPacket.html @@ -190,7 +190,7 @@ Key packet and has exactly the same format.

Source:
@@ -312,7 +312,7 @@ Key packet and has exactly the same format.

Source:
@@ -391,7 +391,7 @@ Key packet and has exactly the same format.

Source:
@@ -470,7 +470,7 @@ Key packet and has exactly the same format.

Source:
@@ -549,7 +549,7 @@ Key packet and has exactly the same format.

Source:
@@ -628,7 +628,7 @@ Key packet and has exactly the same format.

Source:
@@ -697,7 +697,7 @@ Key packet and has exactly the same format.

Source:
@@ -776,7 +776,7 @@ Key packet and has exactly the same format.

Source:
@@ -845,7 +845,7 @@ Key packet and has exactly the same format.

Source:
@@ -924,7 +924,7 @@ Key packet and has exactly the same format.

Source:
@@ -1003,7 +1003,7 @@ Key packet and has exactly the same format.

Source:
@@ -1072,7 +1072,7 @@ Key packet and has exactly the same format.

Source:
@@ -1158,7 +1158,7 @@ Key packet and has exactly the same format.

Source:
@@ -1237,7 +1237,7 @@ Key packet and has exactly the same format.

Source:
@@ -1316,7 +1316,7 @@ Key packet and has exactly the same format.

Source:
@@ -1395,7 +1395,7 @@ Key packet and has exactly the same format.

Source:
@@ -1464,7 +1464,7 @@ Key packet and has exactly the same format.

Source:
@@ -1558,7 +1558,7 @@ Key packet and has exactly the same format.

Source:
@@ -1653,7 +1653,7 @@ Key packet and has exactly the same format.

Source:
@@ -1748,7 +1748,7 @@ Key packet and has exactly the same format.

Source:
@@ -1895,7 +1895,7 @@ otherwise calls to this function will throw an error.

Source:
@@ -2114,7 +2114,7 @@ This can be used to remove passphrase protection after calling decrypt().

Source:
@@ -2238,7 +2238,7 @@ This can be used to remove passphrase protection after calling decrypt().

Source:
@@ -2355,7 +2355,7 @@ This can be used to remove passphrase protection after calling decrypt().

Source:
@@ -2468,7 +2468,7 @@ This can be used to remove passphrase protection after calling decrypt().

Source:
@@ -2585,7 +2585,7 @@ This can be used to remove passphrase protection after calling decrypt().

Source:
@@ -2702,7 +2702,7 @@ This can be used to remove passphrase protection after calling decrypt().

Source:
@@ -2819,7 +2819,7 @@ This can be used to remove passphrase protection after calling decrypt().

Source:
@@ -2937,7 +2937,7 @@ Returns false for gnu-dummy keys and null for public keys.

Source:
@@ -3053,7 +3053,7 @@ Returns false for gnu-dummy keys and null for public keys.

Source:
@@ -3173,7 +3173,7 @@ Such keys are:

Source:
@@ -3330,7 +3330,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
Source:
@@ -3475,7 +3475,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
Source:
@@ -3570,7 +3570,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
Source:
@@ -3694,7 +3694,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
Source:
@@ -3860,7 +3860,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
Source:
@@ -3906,7 +3906,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
diff --git a/docs/Signature.html b/docs/Signature.html index 16b92a51..7431d944 100644 --- a/docs/Signature.html +++ b/docs/Signature.html @@ -144,7 +144,7 @@
Source:
@@ -322,7 +322,7 @@
Source:
@@ -434,7 +434,7 @@
Source:
@@ -546,7 +546,7 @@
Source:
@@ -614,7 +614,7 @@
diff --git a/docs/SignaturePacket.html b/docs/SignaturePacket.html index f1b23612..a8e1c2b2 100644 --- a/docs/SignaturePacket.html +++ b/docs/SignaturePacket.html @@ -99,7 +99,7 @@ block of text, and a signature that is a certification of a User ID.

Source:
@@ -201,7 +201,7 @@ block of text, and a signature that is a certification of a User ID.

Source:
@@ -271,7 +271,7 @@ block of text, and a signature that is a certification of a User ID.

Source:
@@ -341,7 +341,7 @@ block of text, and a signature that is a certification of a User ID.

Source:
@@ -423,7 +423,7 @@ block of text, and a signature that is a certification of a User ID.

Source:
@@ -599,7 +599,7 @@ block of text, and a signature that is a certification of a User ID.

Source:
@@ -760,7 +760,7 @@ block of text, and a signature that is a certification of a User ID.

Source:
@@ -1048,7 +1048,7 @@ block of text, and a signature that is a certification of a User ID.

Source:
@@ -1427,7 +1427,7 @@ block of text, and a signature that is a certification of a User ID.

Source:
@@ -1546,7 +1546,7 @@ block of text, and a signature that is a certification of a User ID.

Source:
@@ -1654,7 +1654,7 @@ block of text, and a signature that is a certification of a User ID.

Source:
@@ -1765,7 +1765,7 @@ block of text, and a signature that is a certification of a User ID.

Source:
@@ -1833,7 +1833,7 @@ block of text, and a signature that is a certification of a User ID.


diff --git a/docs/SymEncryptedIntegrityProtectedDataPacket.html b/docs/SymEncryptedIntegrityProtectedDataPacket.html index 04cfd19d..1824c4af 100644 --- a/docs/SymEncryptedIntegrityProtectedDataPacket.html +++ b/docs/SymEncryptedIntegrityProtectedDataPacket.html @@ -101,7 +101,7 @@ packet.

Source:
@@ -203,7 +203,7 @@ packet.

Source:
@@ -273,7 +273,7 @@ packet.

Source:
@@ -478,7 +478,7 @@ packet.

Source:
@@ -738,7 +738,7 @@ packet.

Source:
@@ -831,7 +831,7 @@ packet.


diff --git a/docs/SymEncryptedSessionKeyPacket.html b/docs/SymEncryptedSessionKeyPacket.html index a2b46c0d..64f22f5a 100644 --- a/docs/SymEncryptedSessionKeyPacket.html +++ b/docs/SymEncryptedSessionKeyPacket.html @@ -165,7 +165,7 @@ the Symmetric-Key Encrypted Session Key packet.

Source:
@@ -271,7 +271,7 @@ the Symmetric-Key Encrypted Session Key packet.

Source:
@@ -345,7 +345,7 @@ the Symmetric-Key Encrypted Session Key packet.

Source:
@@ -419,7 +419,7 @@ the Symmetric-Key Encrypted Session Key packet.

Source:
@@ -550,7 +550,7 @@ the Symmetric-Key Encrypted Session Key packet.

Source:
@@ -761,7 +761,7 @@ the Symmetric-Key Encrypted Session Key packet.

Source:
@@ -929,7 +929,7 @@ the Symmetric-Key Encrypted Session Key packet.

Source:
@@ -1019,7 +1019,7 @@ the Symmetric-Key Encrypted Session Key packet.

Source:
@@ -1087,7 +1087,7 @@ the Symmetric-Key Encrypted Session Key packet.


diff --git a/docs/SymmetricallyEncryptedDataPacket.html b/docs/SymmetricallyEncryptedDataPacket.html index c7c01bec..dc4f9d2c 100644 --- a/docs/SymmetricallyEncryptedDataPacket.html +++ b/docs/SymmetricallyEncryptedDataPacket.html @@ -101,7 +101,7 @@ that form whole OpenPGP messages).

Source:
@@ -197,7 +197,7 @@ that form whole OpenPGP messages).

Source:
@@ -271,7 +271,7 @@ that form whole OpenPGP messages).

Source:
@@ -477,7 +477,7 @@ See RFC 4880 9.2 f
Source:
@@ -720,7 +720,7 @@ See RFC 4880 9.2 f
Source:
@@ -795,7 +795,7 @@ See RFC 4880 9.2 f
diff --git a/docs/TrustPacket.html b/docs/TrustPacket.html index f9ce4086..07ec3afd 100644 --- a/docs/TrustPacket.html +++ b/docs/TrustPacket.html @@ -105,7 +105,7 @@ other than local keyring files.

Source:
@@ -216,7 +216,7 @@ Currently not implemented as we ignore trust packets

Source:
@@ -262,7 +262,7 @@ Currently not implemented as we ignore trust packets


diff --git a/docs/UserAttributePacket.html b/docs/UserAttributePacket.html index 1e485667..f5e8797f 100644 --- a/docs/UserAttributePacket.html +++ b/docs/UserAttributePacket.html @@ -107,7 +107,7 @@ an implementation may use any method desired.

Source:
@@ -266,7 +266,7 @@ an implementation may use any method desired.

Source:
@@ -427,7 +427,7 @@ an implementation may use any method desired.

Source:
@@ -517,7 +517,7 @@ an implementation may use any method desired.

Source:
@@ -585,7 +585,7 @@ an implementation may use any method desired.


diff --git a/docs/UserIDPacket.html b/docs/UserIDPacket.html index 78afa335..8bdb8988 100644 --- a/docs/UserIDPacket.html +++ b/docs/UserIDPacket.html @@ -100,7 +100,7 @@ specifies the length of the User ID.

Source:
@@ -207,7 +207,7 @@ John Doe john@example.com

Source:
@@ -338,7 +338,7 @@ John Doe john@example.com

Source:
@@ -495,7 +495,7 @@ John Doe john@example.com

Source:
@@ -585,7 +585,7 @@ John Doe john@example.com

Source:
@@ -653,7 +653,7 @@ John Doe john@example.com


diff --git a/docs/global.html b/docs/global.html index c2ff19a6..6514b8a2 100644 --- a/docs/global.html +++ b/docs/global.html @@ -100,97 +100,6 @@

Methods

- - - - - - -

aes()

- - - - - - -
-

Javascript AES implementation. -This is used as fallback if the native Crypto APIs are not available.

-
- - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - - - - - - @@ -443,7 +352,7 @@ This is used as fallback if the native Crypto APIs are not available.

Source:
@@ -656,7 +565,7 @@ This is used as fallback if the native Crypto APIs are not available.

Source:
@@ -795,7 +704,7 @@ This is used as fallback if the native Crypto APIs are not available.

Source:
@@ -1204,7 +1113,7 @@ This is used as fallback if the native Crypto APIs are not available.

Source:
@@ -1785,7 +1694,7 @@ One of decryptionKeys, sessionkeys or passwords<
Source:
@@ -2088,7 +1997,7 @@ This method does not change the original key.

Source:
@@ -2447,7 +2356,7 @@ One of decryptionKeys or passwords must be specified.<
Source:
@@ -2579,7 +2488,7 @@ Ultimately, the interface provides no advantages and it's only needed because of
Source:
@@ -3348,7 +3257,7 @@ must be specified. If signing keys are specified, those will be used to sign the
Source:
@@ -3636,7 +3545,7 @@ This method does not change the original key.

Source:
@@ -4256,7 +4165,7 @@ At least one of encryptionKeys or passwords must be sp
Source:
@@ -4472,7 +4381,7 @@ At least one of encryptionKeys or passwords must be sp
Source:
@@ -4822,7 +4731,7 @@ Note: Curve448 and Curve25519 (new format) are not widely supported yet.

Elliptic curve for ECC keys: -curve25519Legacy (default), p256, p384, p521, secp256k1, +curve25519Legacy (default), nistP256, nistP384, nistP521, secp256k1, brainpoolP256r1, brainpoolP384r1, or brainpoolP512r1

@@ -5073,7 +4982,7 @@ default to main key options, except for sign parameter that default
Source:
@@ -5423,7 +5332,7 @@ default to main key options, except for sign parameter that default
Source:
@@ -5481,6 +5390,591 @@ default to main key options, except for sign parameter that default +

getCipherBlockSize(algo)

+ + + + + + +
+

Get block size for given cipher algo

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +module:enums.symmetric + + + +

alrogithm identifier

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

getCipherKeySize(algo)

+ + + + + + +
+

Get key size for given cipher algo

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +module:enums.symmetric + + + +

alrogithm identifier

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

getCipherParams(algo)

+ + + + + + +
+

Get block and key size for given cipher algo

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +module:enums.symmetric + + + +

alrogithm identifier

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

getCompressionStreamInstantiators(compressionFormat) → {Object}

+ + + + + + +
+

Get Compression Stream API instatiators if the constructors are implemented. +NB: the return instatiator functions will throw when called if the provided compressionFormat is not supported +(supported formats cannot be determined in advance).

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
compressionFormat + + +'deflate-raw' +| + +'deflate' +| + +'gzip' +| + +string + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Object + + +
+
+ + + + + + + + + + + + +

newPacketFromTag(tag, allowedPackets) → {Object}

@@ -5607,7 +6101,7 @@ default to main key options, except for sign parameter that default
Source:
@@ -5751,7 +6245,7 @@ default to main key options, except for sign parameter that default
Source:
@@ -5941,7 +6435,7 @@ default to main key options, except for sign parameter that default
Source:
@@ -6028,7 +6522,7 @@ default to main key options, except for sign parameter that default -

(async) produceEncryptionKey(keyVersion, s2k, passphrase, cipherAlgo, aeadModeopt, serializedPacketTag)

+

(async) produceEncryptionKey(keyVersion, s2k, passphrase, cipherAlgo, aeadModeopt, serializedPacketTagopt, isLegacyAEADopt)

@@ -6246,6 +6740,8 @@ default to main key options, except for sign parameter that default + <optional>
+ @@ -6259,6 +6755,39 @@ default to main key options, except for sign parameter that default + + + + isLegacyAEAD + + + + + +Boolean + + + + + + + + + <optional>
+ + + + + + + + + + +

for AEAD-encrypted keys from RFC4880bis (v4 and v5 only)

+ + + @@ -6298,7 +6827,7 @@ default to main key options, except for sign parameter that default
Source:
@@ -6539,7 +7068,7 @@ default to main key options, except for sign parameter that default
Source:
@@ -6827,7 +7356,7 @@ default to main key options, except for sign parameter that default
Source:
@@ -7115,7 +7644,7 @@ default to main key options, except for sign parameter that default
Source:
@@ -7409,7 +7938,7 @@ default to main key options, except for sign parameter that default
Source:
@@ -7697,7 +8226,7 @@ default to main key options, except for sign parameter that default
Source:
@@ -7985,7 +8514,7 @@ default to main key options, except for sign parameter that default
Source:
@@ -8273,7 +8802,7 @@ default to main key options, except for sign parameter that default
Source:
@@ -8735,7 +9264,7 @@ to set the same date as the key creation time to ensure that old message signatu
Source:
@@ -9264,7 +9793,7 @@ If a revocation certificate is passed, the reasonForRevocation parameter will be
Source:
@@ -9479,7 +10008,7 @@ If a revocation certificate is passed, the reasonForRevocation parameter will be
Source:
@@ -10028,7 +10557,7 @@ If a revocation certificate is passed, the reasonForRevocation parameter will be
Source:
@@ -10190,7 +10719,7 @@ the encoded bytes

Source:
@@ -10652,7 +11181,7 @@ an attribute "data" containing a stream of bytes and "type"
Source:
@@ -10897,7 +11426,7 @@ The new key includes a revocation certificate that must be removed before return
Source:
@@ -10946,6 +11475,190 @@ The new key includes a revocation certificate that must be removed before return + + + + + +

zlib(compressionStreamInstantiator, ZlibStreamedConstructor) → {ReadableStream.<Uint8Array>}

+ + + + + + +
+

Zlib processor relying on Compression Stream API if available, or falling back to fflate otherwise.

+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
compressionStreamInstantiator + + +function + + + +
ZlibStreamedConstructor + + +FunctionConstructor + + + +

fflate constructor

+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+

compressed or decompressed data

+
+ + + +
+
+ Type +
+
+ +ReadableStream.<Uint8Array> + + +
+
+ + + + + + + + @@ -10961,7 +11674,7 @@ The new key includes a revocation certificate that must be removed before return
diff --git a/docs/index.html b/docs/index.html index 275ca440..e20f21ed 100644 --- a/docs/index.html +++ b/docs/index.html @@ -139,7 +139,7 @@ library to convert back and forth between them.

Algorithmically** -p256 +nistP256 ECDH ECDSA Yes* @@ -147,7 +147,7 @@ library to convert back and forth between them.

If native*** -p384 +nistP384 ECDH ECDSA Yes* @@ -155,7 +155,7 @@ library to convert back and forth between them.

If native*** -p521 +nistP521 ECDH ECDSA Yes* @@ -501,7 +501,7 @@ can .pipe() to a Writable stream, for example.

Generate new key pair

ECC keys (smaller and faster to generate):

-

Possible values for curve are: curve25519, ed25519, p256, p384, p521, +

Possible values for curve are: curve25519, ed25519, nistP256, nistP384, nistP521, brainpoolP256r1, brainpoolP384r1, brainpoolP512r1, and secp256k1. Note that both the curve25519 and ed25519 options generate a primary key for signing using Ed25519 and a subkey for encryption using Curve25519.

@@ -706,7 +706,7 @@ and a subkey for encryption using Curve25519.


diff --git a/docs/module-config.html b/docs/module-config.html index 315e5010..55a40273 100644 --- a/docs/module-config.html +++ b/docs/module-config.html @@ -89,7 +89,7 @@
Source:
@@ -247,7 +247,7 @@ as a global config setting, but can be used for specific function calls (e.g. de
Source:
@@ -365,7 +365,7 @@ Must be an integer value from 0 to 56.

Source:
@@ -489,7 +489,7 @@ Note: not all OpenPGP implementations are compatible with this option.
Source:
@@ -614,7 +614,7 @@ where key flags were ignored when selecting a key for encryption.

Source:
@@ -733,7 +733,7 @@ and have self-signature's creation date that does not match the primary key crea
Source:
@@ -854,7 +854,7 @@ This is an insecure setting:

Source:
@@ -979,7 +979,7 @@ and deferring checking their integrity until the decrypted stream has been read
Source:
@@ -1091,7 +1091,7 @@ and deferring checking their integrity until the decrypted stream has been read
Source:
@@ -1213,7 +1213,7 @@ See also constantTimePKCS1DecryptionSupportedSymmetricAlgorithms.Source:
@@ -1331,119 +1331,7 @@ However, the more algorithms are added, the slower the decryption procedure beco
Source:
- - - - - - - -
- - - - - - - - -

(static) deflateLevel

- - - - - - - - - - -
Properties:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
deflateLevel - - -Integer - - - -

Default zip/zlib compression level, between 1 and 9

- - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
@@ -1555,7 +1443,7 @@ However, the more algorithms are added, the slower the decryption procedure beco
Source:
@@ -1667,7 +1555,7 @@ However, the more algorithms are added, the slower the decryption procedure beco
Source:
@@ -1784,7 +1672,7 @@ validation error when the notation is marked as critical.

Source:
@@ -1900,7 +1788,7 @@ validation error when the notation is marked as critical.

Source:
@@ -2017,7 +1905,7 @@ The default is 2047 since due to a bug, previous versions of OpenPGP.js could ge
Source:
@@ -2134,7 +2022,7 @@ The default is 2047 since due to a bug, previous versions of OpenPGP.js could ge
Source:
@@ -2251,7 +2139,7 @@ Only has an effect when aeadProtect is set to true.

Source:
@@ -2363,7 +2251,7 @@ Only has an effect when aeadProtect is set to true.

Source:
@@ -2475,7 +2363,7 @@ Only has an effect when aeadProtect is set to true.

Source:
@@ -2587,7 +2475,7 @@ Only has an effect when aeadProtect is set to true.

Source:
@@ -2703,7 +2591,7 @@ Only has an effect when aeadProtect is set to true.

Source:
@@ -2819,7 +2707,7 @@ Only has an effect when aeadProtect is set to true.

Source:
@@ -2935,7 +2823,7 @@ Only has an effect when aeadProtect is set to true.

Source:
@@ -3051,7 +2939,7 @@ Only has an effect when aeadProtect is set to true.

Source:
@@ -3163,7 +3051,7 @@ Only has an effect when aeadProtect is set to true.

Source:
@@ -3378,7 +3266,7 @@ For more details on the choice of parameters, see https://tools.ietf.org/html/rf
Source:
@@ -3497,7 +3385,7 @@ Note: this is the exponent value, not the final number of iterations (refer to s
Source:
@@ -3619,7 +3507,7 @@ Note: Argon2 is the strongest option but not all OpenPGP implementations are com
Source:
@@ -3731,7 +3619,7 @@ Note: Argon2 is the strongest option but not all OpenPGP implementations are com
Source:
@@ -3843,7 +3731,7 @@ Note: Argon2 is the strongest option but not all OpenPGP implementations are com
Source:
@@ -3960,7 +3848,7 @@ When false, certain standard curves will not be supported (depending on the plat
Source:
@@ -4078,7 +3966,7 @@ Note: not all OpenPGP implementations are compatible with this option.
Source:
@@ -4190,7 +4078,7 @@ Note: not all OpenPGP implementations are compatible with this option.
Source:
@@ -4224,7 +4112,7 @@ Note: not all OpenPGP implementations are compatible with this option.
diff --git a/docs/module-crypto.html b/docs/module-crypto.html index 6360dce9..b6f6f44f 100644 --- a/docs/module-crypto.html +++ b/docs/module-crypto.html @@ -89,7 +89,7 @@
Source:
@@ -105,7 +105,7 @@
  • module:crypto/public_key
  • -
  • module:crypto/cipher
  • +
  • module:crypto/cipher
  • module:crypto/random
  • @@ -169,7 +169,7 @@
    diff --git a/docs/module-crypto_aes_kw.html b/docs/module-crypto_aes_kw.html index 2150278b..86b2ee47 100644 --- a/docs/module-crypto_aes_kw.html +++ b/docs/module-crypto_aes_kw.html @@ -89,7 +89,7 @@
    Source:
    @@ -153,7 +153,7 @@ -

    (static) unwrap(key, data) → {Uint8Array}

    +

    (static) unwrap(algo, key, wrappedData) → {Uint8Array}

    @@ -197,13 +197,19 @@ - key + algo -String +enums.symmetric.aes128 +| + +enums.symmetric.aes256 +| + +enums.symmetric.aes192 @@ -213,20 +219,43 @@ - +

    AES algo

    - data + key -String +Uint8Array + + + + + + + + + +

    wrapping key

    + + + + + + + wrappedData + + + + + +Uint8Array @@ -279,7 +308,7 @@
    Source:
    @@ -302,26 +331,15 @@ -
    Throws:
    - - - -
    - - -Error - - - -
    - - -
    Returns:
    +
    +

    unwrapped data

    +
    +
    @@ -348,7 +366,7 @@ -

    (static) wrap(key, data) → {Uint8Array}

    +

    (static) wrap(algo, key, dataToWrap) → {Uint8Array}

    @@ -390,6 +408,35 @@ + + + algo + + + + + +enums.symmetric.aes128 +| + +enums.symmetric.aes256 +| + +enums.symmetric.aes192 + + + + + + + + + +

    AES algo

    + + + + key @@ -408,14 +455,14 @@ - +

    wrapping key

    - data + dataToWrap @@ -474,7 +521,7 @@
    Source:
    @@ -502,6 +549,10 @@
    Returns:
    +
    +

    wrapped key

    +
    +
    @@ -538,7 +589,7 @@
    diff --git a/docs/module-crypto_cipher.html b/docs/module-crypto_cipher.html deleted file mode 100644 index 089085be..00000000 --- a/docs/module-crypto_cipher.html +++ /dev/null @@ -1,1430 +0,0 @@ - - - - - JSDoc: Module: crypto/cipher - - - - - - - - - - -
    - -

    Module: crypto/cipher

    - - - - - - -
    - -
    - - - - - -
    - -
    -
    - - -

    Symmetric cryptography functions

    - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - -

    Methods

    - - - - - - - -

    (static) aes128(key) → {Object}

    - - - - - - -
    -

    AES-128 encryption and decryption (ID 7)

    -
    - - - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    key - - -String - - - -

    128-bit key

    - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - -
    See:
    -
    - -
    - - - -
    - - - - - - - - - - - - - - - -
    Returns:
    - - - - -
    -
    - Type -
    -
    - -Object - - -
    -
    - - - - - - - - - - - - - -

    (static) aes192(key) → {Object}

    - - - - - - -
    -

    AES-128 Block Cipher (ID 8)

    -
    - - - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    key - - -String - - - -

    192-bit key

    - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - -
    See:
    -
    - -
    - - - -
    - - - - - - - - - - - - - - - -
    Returns:
    - - - - -
    -
    - Type -
    -
    - -Object - - -
    -
    - - - - - - - - - - - - - -

    (static) aes256(key) → {Object}

    - - - - - - -
    -

    AES-128 Block Cipher (ID 9)

    -
    - - - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    key - - -String - - - -

    256-bit key

    - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - -
    See:
    -
    - -
    - - - -
    - - - - - - - - - - - - - - - -
    Returns:
    - - - - -
    -
    - Type -
    -
    - -Object - - -
    -
    - - - - - - - - - - - - - -

    (static) blowfish(key) → {Object}

    - - - - - - -
    -

    Blowfish Block Cipher (ID 4)

    -
    - - - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    key - - -String - - - -

    128-bit key

    - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - -
    See:
    -
    - -
    - - - -
    - - - - - - - - - - - - - - - -
    Returns:
    - - - - -
    -
    - Type -
    -
    - -Object - - -
    -
    - - - - - - - - - - - - - -

    (static) cast5(key) → {Object}

    - - - - - - -
    -

    CAST-128 Block Cipher (ID 3)

    -
    - - - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    key - - -String - - - -

    128-bit key

    - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - -
    See:
    -
    - -
    - - - -
    - - - - - - - - - - - - - - - -
    Returns:
    - - - - -
    -
    - Type -
    -
    - -Object - - -
    -
    - - - - - - - - - - - - - -

    (static) idea()

    - - - - - - -
    -

    Not implemented

    -
    - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - - - - - - - - - - -
    Throws:
    - - - -
    - - -Error - - - -
    - - - - - - - - - - - - - - - - -

    (static) tripledes(key) → {Object}

    - - - - - - -
    -

    Triple DES Block Cipher (ID 2)

    -
    - - - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    key - - -String - - - -

    192-bit key

    - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - -
    See:
    -
    - -
    - - - -
    - - - - - - - - - - - - - - - -
    Returns:
    - - - - -
    -
    - Type -
    -
    - -Object - - -
    -
    - - - - - - - - - - - - - -

    (static) twofish(key) → {Object}

    - - - - - - -
    -

    Twofish Block Cipher (ID 10)

    -
    - - - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    key - - -String - - - -

    256-bit key

    - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - -
    See:
    -
    - -
    - - - -
    - - - - - - - - - - - - - - - -
    Returns:
    - - - - -
    -
    - Type -
    -
    - -Object - - -
    -
    - - - - - - - - - - - - - -
    - -
    - - - - -
    - - - -
    - - - - - - - \ No newline at end of file diff --git a/docs/module-crypto_cmac.html b/docs/module-crypto_cmac.html index 31aaadf1..51430d3e 100644 --- a/docs/module-crypto_cmac.html +++ b/docs/module-crypto_cmac.html @@ -90,7 +90,7 @@ native AES-CBC using either the WebCrypto API or Node.js' crypto API.

    Source:
    @@ -195,7 +195,7 @@ The OMAC authors indicate that they will promulgate this modification
    Source:
    @@ -352,7 +352,7 @@ simplify the implementation.

    Source:
    @@ -398,7 +398,7 @@ simplify the implementation.


    diff --git a/docs/module-crypto_crypto.html b/docs/module-crypto_crypto.html index a0105d17..a79a85c7 100644 --- a/docs/module-crypto_crypto.html +++ b/docs/module-crypto_crypto.html @@ -90,7 +90,7 @@ well as key generation and parameter handling for all public-key cryptosystems.<
    Source:
    @@ -296,7 +296,7 @@ well as key generation and parameter handling for all public-key cryptosystems.<
    Source:
    @@ -458,7 +458,7 @@ See RFC 4880 9.2 f
    Source:
    @@ -619,7 +619,7 @@ See RFC 4880 9.2 f
    Source:
    @@ -848,7 +848,7 @@ See RFC 4880 9.2 f
    Source:
    @@ -1030,7 +1030,7 @@ See RFC 4880 9.2 f
    Source:
    @@ -1170,7 +1170,7 @@ See RFC 4880 9.2 f
    Source:
    @@ -1354,7 +1354,7 @@ See RFC 4880 9.2 f
    Source:
    @@ -1561,7 +1561,7 @@ See RFC 4880 9.2 f
    Source:
    @@ -1745,7 +1745,7 @@ See RFC 4880 9.2 f
    Source:
    @@ -2075,7 +2075,7 @@ See RFC 4880 5.5.3Source:
    @@ -2358,7 +2358,7 @@ See RFC 4880 9.1 f
    Source:
    @@ -2542,7 +2542,7 @@ See RFC 4880 9.1 f
    Source:
    @@ -2749,7 +2749,7 @@ See RFC 4880 9.1 f
    Source:
    @@ -2910,7 +2910,7 @@ See RFC 4880 9.1 f
    Source:
    @@ -2985,7 +2985,7 @@ See RFC 4880 9.1 f
    diff --git a/docs/module-crypto_hash.html b/docs/module-crypto_hash.html index 1e4de57d..58d2f69e 100644 --- a/docs/module-crypto_hash.html +++ b/docs/module-crypto_hash.html @@ -89,7 +89,7 @@
    Source:
    @@ -191,7 +191,7 @@
    Source:
    @@ -352,7 +352,7 @@
    Source:
    @@ -513,7 +513,7 @@
    Source:
    @@ -581,7 +581,7 @@
    diff --git a/docs/module-crypto_hkdf.html b/docs/module-crypto_hkdf.html index 08e03208..1e3d190a 100644 --- a/docs/module-crypto_hkdf.html +++ b/docs/module-crypto_hkdf.html @@ -89,7 +89,7 @@
    Source:
    @@ -152,7 +152,7 @@
    diff --git a/docs/module-crypto_mode.html b/docs/module-crypto_mode.html index 766568b7..a5f99439 100644 --- a/docs/module-crypto_mode.html +++ b/docs/module-crypto_mode.html @@ -89,7 +89,7 @@
    Source:
    @@ -182,7 +182,7 @@
    Source:
    @@ -249,7 +249,7 @@
    Source:
    @@ -316,7 +316,7 @@
    Source:
    @@ -383,7 +383,7 @@
    Source:
    @@ -424,7 +424,7 @@
    diff --git a/docs/module-crypto_mode_cfb.html b/docs/module-crypto_mode_cfb.html index 2aa1d209..1b25c348 100644 --- a/docs/module-crypto_mode_cfb.html +++ b/docs/module-crypto_mode_cfb.html @@ -236,7 +236,7 @@
    Source:
    @@ -477,7 +477,7 @@
    Source:
    @@ -533,7 +533,7 @@
    diff --git a/docs/module-crypto_mode_eax.html b/docs/module-crypto_mode_eax.html index 76aa3551..50d97721 100644 --- a/docs/module-crypto_mode_eax.html +++ b/docs/module-crypto_mode_eax.html @@ -90,7 +90,7 @@ native AES-CTR using either the WebCrypto API or Node.js' crypto API.

    Source:
    @@ -296,7 +296,7 @@ native AES-CTR using either the WebCrypto API or Node.js' crypto API.

    Source:
    @@ -480,7 +480,7 @@ native AES-CTR using either the WebCrypto API or Node.js' crypto API.

    Source:
    @@ -665,7 +665,7 @@ native AES-CTR using either the WebCrypto API or Node.js' crypto API.

    Source:
    @@ -733,7 +733,7 @@ native AES-CTR using either the WebCrypto API or Node.js' crypto API.


    diff --git a/docs/module-crypto_mode_gcm.html b/docs/module-crypto_mode_gcm.html index c9911464..9264ae90 100644 --- a/docs/module-crypto_mode_gcm.html +++ b/docs/module-crypto_mode_gcm.html @@ -90,7 +90,7 @@ the WebCrypto api as well as node.js' crypto api.

    Source:
    @@ -273,7 +273,7 @@ the WebCrypto api as well as node.js' crypto api.

    Source:
    @@ -319,7 +319,7 @@ the WebCrypto api as well as node.js' crypto api.


    diff --git a/docs/module-crypto_mode_ocb.html b/docs/module-crypto_mode_ocb.html index 19dceb00..15b9f96e 100644 --- a/docs/module-crypto_mode_ocb.html +++ b/docs/module-crypto_mode_ocb.html @@ -89,7 +89,7 @@
    Source:
    @@ -295,7 +295,7 @@
    Source:
    @@ -502,7 +502,7 @@
    Source:
    @@ -686,7 +686,7 @@
    Source:
    @@ -732,7 +732,7 @@
    diff --git a/docs/module-crypto_pkcs1.html b/docs/module-crypto_pkcs1.html index 2a8616b5..77b6196d 100644 --- a/docs/module-crypto_pkcs1.html +++ b/docs/module-crypto_pkcs1.html @@ -89,7 +89,7 @@
    Source:
    @@ -197,7 +197,7 @@
    Source:
    @@ -358,7 +358,7 @@
    Source:
    @@ -578,7 +578,7 @@
    Source:
    @@ -792,7 +792,7 @@
    Source:
    @@ -867,7 +867,7 @@
    diff --git a/docs/module-crypto_public_key.html b/docs/module-crypto_public_key.html index c052971f..44230499 100644 --- a/docs/module-crypto_public_key.html +++ b/docs/module-crypto_public_key.html @@ -89,7 +89,7 @@
    Source:
    @@ -182,7 +182,7 @@
    Source:
    @@ -249,7 +249,7 @@
    Source:
    @@ -316,7 +316,7 @@
    Source:
    @@ -383,7 +383,7 @@
    Source:
    @@ -424,7 +424,7 @@
    diff --git a/docs/module-crypto_public_key_dsa.html b/docs/module-crypto_public_key_dsa.html index aa017bee..477c975d 100644 --- a/docs/module-crypto_public_key_dsa.html +++ b/docs/module-crypto_public_key_dsa.html @@ -89,7 +89,7 @@
    Source:
    @@ -188,7 +188,7 @@ Expect y == y'

    Source:
    @@ -434,7 +434,7 @@ Expect y == y'

    Source:
    @@ -683,7 +683,7 @@ Expect y == y'

    Source:
    @@ -1005,7 +1005,7 @@ Expect y == y'

    Source:
    @@ -1069,7 +1069,7 @@ Expect y == y'


    diff --git a/docs/module-crypto_public_key_elgamal.html b/docs/module-crypto_public_key_elgamal.html index a4e8c423..8bc4483c 100644 --- a/docs/module-crypto_public_key_elgamal.html +++ b/docs/module-crypto_public_key_elgamal.html @@ -89,7 +89,7 @@
    Source:
    @@ -188,7 +188,7 @@ Expect y == y'

    Source:
    @@ -412,7 +412,7 @@ Expect y == y'

    Source:
    @@ -672,7 +672,7 @@ Note that in OpenPGP, the message needs to be padded with PKCS#1 (same as RSA)Source:
    @@ -898,7 +898,7 @@ Note that in OpenPGP, the message needs to be padded with PKCS#1 (same as RSA)Source:
    @@ -966,7 +966,7 @@ Note that in OpenPGP, the message needs to be padded with PKCS#1 (same as RSA)
    diff --git a/docs/module-crypto_public_key_elliptic.html b/docs/module-crypto_public_key_elliptic.html index f116206b..bdbb779e 100644 --- a/docs/module-crypto_public_key_elliptic.html +++ b/docs/module-crypto_public_key_elliptic.html @@ -89,7 +89,7 @@
    Source:
    @@ -165,7 +165,7 @@
    diff --git a/docs/module-crypto_public_key_elliptic_curve.html b/docs/module-crypto_public_key_elliptic_curve.html index b925f144..9bb3ccd5 100644 --- a/docs/module-crypto_public_key_elliptic_curve.html +++ b/docs/module-crypto_public_key_elliptic_curve.html @@ -89,7 +89,7 @@
    Source:
    @@ -249,7 +249,7 @@
    Source:
    @@ -406,7 +406,7 @@
    Source:
    @@ -632,7 +632,7 @@
    Source:
    @@ -835,7 +835,7 @@
    Source:
    @@ -1066,7 +1066,7 @@ Not suitable for EdDSA (different secret key format)

    Source:
    @@ -1134,7 +1134,7 @@ Not suitable for EdDSA (different secret key format)


    diff --git a/docs/module-crypto_public_key_elliptic_ecdh.html b/docs/module-crypto_public_key_elliptic_ecdh.html index 8c83d512..585f2f1f 100644 --- a/docs/module-crypto_public_key_elliptic_ecdh.html +++ b/docs/module-crypto_public_key_elliptic_ecdh.html @@ -91,7 +91,7 @@
    Source:
    @@ -169,7 +169,7 @@
    Source:
    @@ -467,7 +467,7 @@
    Source:
    @@ -720,7 +720,7 @@
    Source:
    @@ -973,7 +973,7 @@
    Source:
    @@ -1176,7 +1176,7 @@
    Source:
    @@ -1337,7 +1337,7 @@
    Source:
    @@ -1540,7 +1540,7 @@
    Source:
    @@ -1747,7 +1747,7 @@
    Source:
    @@ -1977,7 +1977,7 @@
    Source:
    @@ -2157,7 +2157,7 @@
    Source:
    @@ -2360,7 +2360,7 @@
    Source:
    @@ -2540,7 +2540,7 @@
    Source:
    @@ -2766,7 +2766,7 @@
    Source:
    @@ -2946,7 +2946,7 @@
    Source:
    @@ -3077,7 +3077,7 @@
    Source:
    @@ -3155,7 +3155,7 @@
    Source:
    @@ -3453,7 +3453,7 @@
    Source:
    @@ -3706,7 +3706,7 @@
    Source:
    @@ -3959,7 +3959,7 @@
    Source:
    @@ -4162,7 +4162,7 @@
    Source:
    @@ -4323,7 +4323,7 @@
    Source:
    @@ -4526,7 +4526,7 @@
    Source:
    @@ -4733,7 +4733,7 @@
    Source:
    @@ -4963,7 +4963,7 @@
    Source:
    @@ -5143,7 +5143,7 @@
    Source:
    @@ -5346,7 +5346,7 @@
    Source:
    @@ -5526,7 +5526,7 @@
    Source:
    @@ -5752,7 +5752,7 @@
    Source:
    @@ -5932,7 +5932,7 @@
    Source:
    @@ -5996,7 +5996,7 @@
    diff --git a/docs/module-crypto_public_key_elliptic_ecdsa.html b/docs/module-crypto_public_key_elliptic_ecdsa.html index ff155f0b..ec2cb35c 100644 --- a/docs/module-crypto_public_key_elliptic_ecdsa.html +++ b/docs/module-crypto_public_key_elliptic_ecdsa.html @@ -89,7 +89,7 @@
    Source:
    @@ -364,7 +364,7 @@
    Source:
    @@ -571,7 +571,7 @@
    Source:
    @@ -847,7 +847,7 @@
    Source:
    @@ -956,7 +956,7 @@ To be used if no native implementation is available for the given curve/operatio
    Source:
    @@ -1002,7 +1002,7 @@ To be used if no native implementation is available for the given curve/operatio
    diff --git a/docs/module-crypto_public_key_elliptic_eddsa.html b/docs/module-crypto_public_key_elliptic_eddsa.html index 21bb2eb8..1f8c76be 100644 --- a/docs/module-crypto_public_key_elliptic_eddsa.html +++ b/docs/module-crypto_public_key_elliptic_eddsa.html @@ -89,7 +89,7 @@
    Source:
    @@ -249,7 +249,7 @@
    Source:
    @@ -521,7 +521,7 @@
    Source:
    @@ -751,7 +751,7 @@
    Source:
    @@ -1027,7 +1027,7 @@
    Source:
    @@ -1091,7 +1091,7 @@
    diff --git a/docs/module-crypto_public_key_elliptic_eddsa_legacy.html b/docs/module-crypto_public_key_elliptic_eddsa_legacy.html index b9a68f12..efeafadb 100644 --- a/docs/module-crypto_public_key_elliptic_eddsa_legacy.html +++ b/docs/module-crypto_public_key_elliptic_eddsa_legacy.html @@ -90,7 +90,7 @@ This key type has been deprecated by the crypto-refresh RFC.

    Source:
    @@ -365,7 +365,7 @@ This key type has been deprecated by the crypto-refresh RFC.

    Source:
    @@ -572,7 +572,7 @@ This key type has been deprecated by the crypto-refresh RFC.

    Source:
    @@ -848,7 +848,7 @@ This key type has been deprecated by the crypto-refresh RFC.

    Source:
    @@ -912,7 +912,7 @@ This key type has been deprecated by the crypto-refresh RFC.


    diff --git a/docs/module-crypto_public_key_prime.html b/docs/module-crypto_public_key_prime.html index f26a9c24..abbe4ce7 100644 --- a/docs/module-crypto_public_key_prime.html +++ b/docs/module-crypto_public_key_prime.html @@ -89,7 +89,7 @@
    Source:
    @@ -273,7 +273,7 @@ Fails if b^(n-1) mod n != 1.

    Source:
    @@ -476,7 +476,7 @@ Fails if b^(n-1) mod n != 1.

    Source:
    @@ -680,7 +680,7 @@ See HAC Remark 4.28.

    Source:
    @@ -883,7 +883,7 @@ See HAC Remark 4.28.

    Source:
    @@ -939,7 +939,7 @@ See HAC Remark 4.28.


    diff --git a/docs/module-crypto_public_key_rsa.html b/docs/module-crypto_public_key_rsa.html index 7cc1eccf..f2579994 100644 --- a/docs/module-crypto_public_key_rsa.html +++ b/docs/module-crypto_public_key_rsa.html @@ -89,7 +89,7 @@
    Source:
    @@ -411,7 +411,7 @@
    Source:
    @@ -647,7 +647,7 @@
    Source:
    @@ -833,7 +833,7 @@
    Source:
    @@ -1186,7 +1186,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

    Source:
    @@ -1462,7 +1462,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

    Source:
    @@ -1738,7 +1738,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

    Source:
    @@ -1786,6 +1786,96 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

    + + + + + + +

    (inner) jwkToPrivate()

    + + + + + + +
    +

    Convert JWK private key to OpenPGP private key params

    +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + @@ -2033,7 +2123,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

    Source:
    @@ -2218,7 +2308,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

    Source:
    @@ -2264,7 +2354,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q


    diff --git a/docs/module-crypto_random.html b/docs/module-crypto_random.html index fa8b2c6c..bce5b5f0 100644 --- a/docs/module-crypto_random.html +++ b/docs/module-crypto_random.html @@ -89,7 +89,7 @@
    Source:
    @@ -272,7 +272,7 @@
    Source:
    @@ -433,7 +433,7 @@
    Source:
    @@ -501,7 +501,7 @@
    diff --git a/docs/module-crypto_signature.html b/docs/module-crypto_signature.html index accef42e..9871733f 100644 --- a/docs/module-crypto_signature.html +++ b/docs/module-crypto_signature.html @@ -89,7 +89,7 @@
    Source:
    @@ -276,7 +276,7 @@ See RFC 4880 5.2.2.<
    Source:
    @@ -555,7 +555,7 @@ for public key and hash algorithms.

    Source:
    @@ -834,7 +834,7 @@ for public key and hash algorithms.

    Source:
    @@ -902,7 +902,7 @@ for public key and hash algorithms.


    diff --git a/docs/module-encoding_base64.html b/docs/module-encoding_base64.html index 11035aa0..50e2f9c1 100644 --- a/docs/module-encoding_base64.html +++ b/docs/module-encoding_base64.html @@ -168,7 +168,7 @@
    Source:
    @@ -332,7 +332,7 @@
    Source:
    @@ -499,7 +499,7 @@
    Source:
    @@ -686,7 +686,7 @@
    Source:
    @@ -754,7 +754,7 @@
    diff --git a/docs/module-enums.html b/docs/module-enums.html index af3da952..00325c0f 100644 --- a/docs/module-enums.html +++ b/docs/module-enums.html @@ -235,7 +235,7 @@
    Source:
    @@ -499,7 +499,7 @@
    Source:
    @@ -694,7 +694,7 @@
    Source:
    @@ -763,7 +763,7 @@ - p256 + nistP256 @@ -786,7 +786,7 @@ - "P-256" + p256 @@ -809,122 +809,7 @@ - secp256r1 - - - - - -String - - - - - - - - - - - - - - - - - prime256v1 - - - - - -String - - - - - - - - - - - - - - - - - "1.2.840.10045.3.1.7" - - - - - -String - - - - - - - - - - - - - - - - - 2a8648ce3d030107 - - - - - -String - - - - - - - - - - - - - - - - - 2A8648CE3D030107 - - - - - -String - - - - - - - - - - - - - - - - - p384 + nistP384 @@ -947,7 +832,7 @@ - "P-384" + p384 @@ -970,99 +855,7 @@ - secp384r1 - - - - - -String - - - - - - - - - - - - - - - - - "1.3.132.0.34" - - - - - -String - - - - - - - - - - - - - - - - - 2b81040022 - - - - - -String - - - - - - - - - - - - - - - - - 2B81040022 - - - - - -String - - - - - - - - - - - - - - - - - p521 + nistP521 @@ -1085,99 +878,7 @@ - "P-521" - - - - - -String - - - - - - - - - - - - - - - - - secp521r1 - - - - - -String - - - - - - - - - - - - - - - - - "1.3.132.0.35" - - - - - -String - - - - - - - - - - - - - - - - - 2b81040023 - - - - - -String - - - - - - - - - - - - - - - - - 2B81040023 + p521 @@ -1221,75 +922,6 @@ - - - "1.3.132.0.10" - - - - - -String - - - - - - - - - - - - - - - - - 2b8104000a - - - - - -String - - - - - - - - - - - - - - - - - 2B8104000A - - - - - -String - - - - - - - - - - - - - - ed25519Legacy @@ -1313,29 +945,6 @@ - - - ED25519 - - - - - -String - - - - - - - - - - - - - - ed25519 @@ -1354,98 +963,6 @@ - - - - - - - - Ed25519 - - - - - -String - - - - - - - - - - - - - - - - - "1.3.6.1.4.1.11591.15.1" - - - - - -String - - - - - - - - - - - - - - - - - 2b06010401da470f01 - - - - - -String - - - - - - - - - - - - - - - - - 2B06010401DA470F01 - - - - - -String - - - - - - - - - @@ -1474,52 +991,6 @@ - - - X25519 - - - - - -String - - - - - - - - - - - - - - - - - cv25519 - - - - - -String - - - - - - - - - - - - - - curve25519 @@ -1538,98 +1009,6 @@ - - - - - - - - Curve25519 - - - - - -String - - - - - - - - - - - - - - - - - "1.3.6.1.4.1.3029.1.5.1" - - - - - -String - - - - - - - - - - - - - - - - - 2b060104019755010501 - - - - - -String - - - - - - - - - - - - - - - - - 2B060104019755010501 - - - - - -String - - - - - - - - - @@ -1658,75 +1037,6 @@ - - - "1.3.36.3.3.2.8.1.1.7" - - - - - -String - - - - - - - - - - - - - - - - - 2b2403030208010107 - - - - - -String - - - - - - - - - - - - - - - - - 2B2403030208010107 - - - - - -String - - - - - - - - - - - - - - brainpoolP384r1 @@ -1750,75 +1060,6 @@ - - - "1.3.36.3.3.2.8.1.1.11" - - - - - -String - - - - - - - - - - - - - - - - - 2b240303020801010b - - - - - -String - - - - - - - - - - - - - - - - - 2B240303020801010B - - - - - -String - - - - - - - - - - - - - - brainpoolP512r1 @@ -1841,75 +1082,6 @@ - - - - "1.3.36.3.3.2.8.1.1.13" - - - - - -String - - - - - - - - - - - - - - - - - 2b240303020801010d - - - - - -String - - - - - - - - - - - - - - - - - 2B240303020801010D - - - - - -String - - - - - - - - - - - - - @@ -1947,7 +1119,7 @@
    Source:
    @@ -2151,7 +1323,7 @@ fingerprint format

    Source:
    @@ -2461,7 +1633,7 @@ fingerprint format

    Source:
    @@ -2727,7 +1899,7 @@ possession of more than one person.

    Source:
    @@ -2922,7 +2094,7 @@ possession of more than one person.

    Source:
    @@ -3462,7 +2634,7 @@ possession of more than one person.

    Source:
    @@ -3888,7 +3060,7 @@ possession of more than one person.

    Source:
    @@ -4106,7 +3278,7 @@ possession of more than one person.

    Source:
    @@ -4324,7 +3496,7 @@ possession of more than one person.

    Source:
    @@ -4841,7 +4013,7 @@ document) that cannot include a target subpacket.

    Source:
    @@ -5565,7 +4737,7 @@ document) that cannot include a target subpacket.

    Source:
    @@ -5852,7 +5024,7 @@ document) that cannot include a target subpacket.

    Source:
    @@ -6048,7 +5220,7 @@ document) that cannot include a target subpacket.

    Source:
    @@ -6202,7 +5374,7 @@ document) that cannot include a target subpacket.

    Source:
    @@ -6418,7 +5590,7 @@ document) that cannot include a target subpacket.

    Source:
    @@ -6515,7 +5687,7 @@ document) that cannot include a target subpacket.


    diff --git a/docs/module-key_Subkey-Subkey.html b/docs/module-key_Subkey-Subkey.html index 87f2ab7f..d8ef91cc 100644 --- a/docs/module-key_Subkey-Subkey.html +++ b/docs/module-key_Subkey-Subkey.html @@ -171,7 +171,7 @@
    Source:
    @@ -281,7 +281,7 @@
    Source:
    @@ -394,7 +394,7 @@
    Source:
    @@ -511,7 +511,7 @@
    Source:
    @@ -628,7 +628,7 @@
    Source:
    @@ -741,7 +741,7 @@
    Source:
    @@ -942,7 +942,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -1055,7 +1055,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -1172,7 +1172,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -1289,7 +1289,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -1406,7 +1406,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -1523,7 +1523,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -1640,7 +1640,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -1757,7 +1757,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -1873,7 +1873,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -2149,7 +2149,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -2487,7 +2487,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -2599,7 +2599,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -2832,7 +2832,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -3044,7 +3044,7 @@ and valid binding signature.

    Source:
    @@ -3137,7 +3137,7 @@ and valid binding signature.


    diff --git a/docs/module-key_Subkey.html b/docs/module-key_Subkey.html index 681d225d..da7d59b7 100644 --- a/docs/module-key_Subkey.html +++ b/docs/module-key_Subkey.html @@ -77,7 +77,7 @@
    diff --git a/docs/module-key_User-User.html b/docs/module-key_User-User.html index 8ef2f320..8e8ef785 100644 --- a/docs/module-key_User-User.html +++ b/docs/module-key_User-User.html @@ -171,7 +171,7 @@
    Source:
    @@ -404,7 +404,7 @@
    Source:
    @@ -516,7 +516,7 @@
    Source:
    @@ -789,7 +789,7 @@
    Source:
    @@ -1127,7 +1127,7 @@
    Source:
    @@ -1239,7 +1239,7 @@
    Source:
    @@ -1442,7 +1442,7 @@
    Source:
    @@ -1623,7 +1623,7 @@ and validity of self signature.

    Source:
    @@ -1887,7 +1887,7 @@ and validity of self signature.

    Source:
    @@ -2154,7 +2154,7 @@ Signature validity is null if the verification keys do not correspond to the cer
    Source:
    @@ -2234,7 +2234,7 @@ Signature validity is null if the verification keys do not correspond to the cer
    diff --git a/docs/module-key_User.html b/docs/module-key_User.html index 298131b9..8daa7956 100644 --- a/docs/module-key_User.html +++ b/docs/module-key_User.html @@ -77,7 +77,7 @@
    diff --git a/docs/module-key_helper.html b/docs/module-key_helper.html index 45f9f817..df586d3f 100644 --- a/docs/module-key_helper.html +++ b/docs/module-key_helper.html @@ -89,7 +89,7 @@
    Source:
    @@ -281,7 +281,7 @@
    Source:
    @@ -518,7 +518,7 @@
    Source:
    @@ -928,7 +928,7 @@
    Source:
    @@ -1116,7 +1116,7 @@ The expiration time of the signature is ignored.

    Source:
    @@ -1352,7 +1352,7 @@ The expiration time of the signature is ignored.

    Source:
    @@ -1624,7 +1624,7 @@ The expiration time of the signature is ignored.

    Source:
    @@ -1896,7 +1896,7 @@ The expiration time of the signature is ignored.

    Source:
    @@ -2200,7 +2200,7 @@ The expiration time of the signature is ignored.

    Source:
    @@ -2507,7 +2507,7 @@ The expiration time of the signature is ignored.

    Source:
    @@ -2806,7 +2806,7 @@ The expiration time of the signature is ignored.

    Source:
    @@ -2852,7 +2852,7 @@ The expiration time of the signature is ignored.


    diff --git a/docs/module-packet_packet.html b/docs/module-packet_packet.html index 9215d135..4ed6b6e4 100644 --- a/docs/module-packet_packet.html +++ b/docs/module-packet_packet.html @@ -89,7 +89,7 @@
    Source:
    @@ -275,7 +275,7 @@
    Source:
    @@ -436,7 +436,7 @@
    Source:
    @@ -621,7 +621,7 @@ string

    Source:
    @@ -783,7 +783,7 @@ string

    Source:
    @@ -851,7 +851,7 @@ string


    diff --git a/docs/module-type_ecdh_symkey.html b/docs/module-type_ecdh_symkey.html index 1849b1da..b6fe97e6 100644 --- a/docs/module-type_ecdh_symkey.html +++ b/docs/module-type_ecdh_symkey.html @@ -89,7 +89,7 @@
    Source:
    @@ -152,7 +152,7 @@
    diff --git a/docs/module-type_kdf_params-KDFParams.html b/docs/module-type_kdf_params-KDFParams.html index efa1ab8f..87d5ca38 100644 --- a/docs/module-type_kdf_params-KDFParams.html +++ b/docs/module-type_kdf_params-KDFParams.html @@ -163,7 +163,7 @@
    Source:
    @@ -322,7 +322,7 @@
    Source:
    @@ -434,7 +434,7 @@
    Source:
    @@ -502,7 +502,7 @@
    diff --git a/docs/module-type_keyid-KeyID.html b/docs/module-type_keyid-KeyID.html index bb3e2898..9cdefc53 100644 --- a/docs/module-type_keyid-KeyID.html +++ b/docs/module-type_keyid-KeyID.html @@ -101,7 +101,7 @@ formed.

    Source:
    @@ -295,7 +295,7 @@ formed.

    Source:
    @@ -385,7 +385,7 @@ formed.

    Source:
    @@ -497,7 +497,7 @@ formed.

    Source:
    @@ -658,7 +658,7 @@ formed.

    Source:
    @@ -748,7 +748,7 @@ formed.

    Source:
    @@ -860,7 +860,7 @@ formed.

    Source:
    @@ -928,7 +928,7 @@ formed.


    diff --git a/docs/module-type_keyid.html b/docs/module-type_keyid.html index 35a85bf5..9a78068b 100644 --- a/docs/module-type_keyid.html +++ b/docs/module-type_keyid.html @@ -77,7 +77,7 @@
    diff --git a/docs/module-type_oid.html b/docs/module-type_oid.html index 27a5dcd4..8d23ee8a 100644 --- a/docs/module-type_oid.html +++ b/docs/module-type_oid.html @@ -100,7 +100,7 @@ sequence of octets is the valid representation of a curve OID.

    Source:
    @@ -163,7 +163,7 @@ sequence of octets is the valid representation of a curve OID.


    diff --git a/docs/module-type_s2k-GenericS2K.html b/docs/module-type_s2k-GenericS2K.html index 07287091..18af6ab1 100644 --- a/docs/module-type_s2k-GenericS2K.html +++ b/docs/module-type_s2k-GenericS2K.html @@ -153,7 +153,7 @@
    Source:
    @@ -262,7 +262,7 @@
    Source:
    @@ -332,7 +332,7 @@
    Source:
    @@ -406,7 +406,7 @@
    Source:
    @@ -480,7 +480,7 @@
    Source:
    @@ -612,7 +612,7 @@ hashAlgorithm

    Source:
    @@ -774,7 +774,7 @@ hashAlgorithm hash length

    Source:
    @@ -886,7 +886,7 @@ hashAlgorithm hash length

    Source:
    @@ -954,7 +954,7 @@ hashAlgorithm hash length


    diff --git a/docs/module-type_s2k.html b/docs/module-type_s2k.html index 25caf336..afc40e6a 100644 --- a/docs/module-type_s2k.html +++ b/docs/module-type_s2k.html @@ -95,7 +95,7 @@ symmetrically encrypted messages.

    Source:
    @@ -165,7 +165,7 @@ symmetrically encrypted messages.


    diff --git a/docs/module-type_x25519x448_symkey.html b/docs/module-type_x25519x448_symkey.html index 4e92f253..cd9071b4 100644 --- a/docs/module-type_x25519x448_symkey.html +++ b/docs/module-type_x25519x448_symkey.html @@ -91,7 +91,7 @@ the former includes an algorithm byte preceeding the encrypted session key.

    <
    Source:
    @@ -154,7 +154,7 @@ the former includes an algorithm byte preceeding the encrypted session key.

    <
    diff --git a/docs/module-util.html b/docs/module-util.html index 977a0736..fa68cd6a 100644 --- a/docs/module-util.html +++ b/docs/module-util.html @@ -89,7 +89,7 @@
    Source:
    @@ -152,7 +152,7 @@
    diff --git a/package-lock.json b/package-lock.json index eca4d50a..73ddf44d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "openpgp", - "version": "6.0.0-alpha.0", + "version": "6.0.0-alpha.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "openpgp", - "version": "6.0.0-alpha.0", + "version": "6.0.0-alpha.1", "license": "LGPL-3.0+", "devDependencies": { "@openpgp/asmcrypto.js": "^3.1.0", diff --git a/package.json b/package.json index b1744c4d..3a52dff3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "openpgp", "description": "OpenPGP.js is a Javascript implementation of the OpenPGP protocol. This is defined in RFC 4880.", - "version": "6.0.0-alpha.0", + "version": "6.0.0-alpha.1", "license": "LGPL-3.0+", "homepage": "https://openpgpjs.org/", "engines": { From aba61efa702eef0c6800bec5eccdea2c67d13035 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Thu, 21 Mar 2024 14:09:23 +0100 Subject: [PATCH 113/201] CI: update interop test suite: fix sop-openpgpjs, include crypto-refresh tests, and compare with gopenpgp v3 sop-openpgpjs did not correctly apply the `OPENPGPJS_PATH` env variable; as a result, it did not actually test the code from either the PR and base branch, but always from the hardcoded version bundled with it. --- .github/test-suite/config.json.template | 3 ++- .github/test-suite/prepare_config.sh | 2 +- .github/workflows/sop-test-suite.yml | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/test-suite/config.json.template b/.github/test-suite/config.json.template index 7dd7e3fb..7a3b33c5 100644 --- a/.github/test-suite/config.json.template +++ b/.github/test-suite/config.json.template @@ -21,7 +21,8 @@ "path": "__GPGME_SOP__" }, { - "path": "__GOSOP__" + "id": "gosop-v2", + "path": "__GOSOP_V2__" }, { "path": "__RNP_SOP__" diff --git a/.github/test-suite/prepare_config.sh b/.github/test-suite/prepare_config.sh index debe9add..0bf112c1 100755 --- a/.github/test-suite/prepare_config.sh +++ b/.github/test-suite/prepare_config.sh @@ -7,7 +7,7 @@ cat $CONFIG_TEMPLATE \ | sed "s@__OPENPGPJS_MAIN__@${OPENPGPJS_MAIN}@g" \ | sed "s@__SQOP__@${SQOP}@g" \ | sed "s@__GPGME_SOP__@${GPGME_SOP}@g" \ - | sed "s@__GOSOP__@${GOSOP}@g" \ + | sed "s@__GOSOP_V2__@${GOSOP_DIR_V2}/gosop@g" \ | sed "s@__SOP_OPENPGPJS__@${SOP_OPENPGPJS}@g" \ | sed "s@__RNP_SOP__@${RNP_SOP}@g" \ > $CONFIG_OUTPUT \ No newline at end of file diff --git a/.github/workflows/sop-test-suite.yml b/.github/workflows/sop-test-suite.yml index bd336dbf..458a7046 100644 --- a/.github/workflows/sop-test-suite.yml +++ b/.github/workflows/sop-test-suite.yml @@ -10,7 +10,7 @@ jobs: name: Run interoperability test suite runs-on: ubuntu-latest container: - image: ghcr.io/protonmail/openpgp-interop-test-docker:v1.1.1 + image: ghcr.io/protonmail/openpgp-interop-test-docker:v1.1.6 credentials: username: ${{ github.actor }} password: ${{ secrets.github_token }} @@ -79,7 +79,7 @@ jobs: with: name: test-suite-results.json - name: Compare with baseline - uses: ProtonMail/openpgp-interop-test-analyzer@v1 + uses: ProtonMail/openpgp-interop-test-analyzer@v2 with: results: ${{ steps.download-test-results.outputs.download-path }}/test-suite-results.json output: baseline-comparison.json From cb97c8fcb9152a04f350e26c6dfe9aeb40130415 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Fri, 22 Mar 2024 11:44:51 +0100 Subject: [PATCH 114/201] CI: fix sop test result comparison --- .github/workflows/sop-test-suite.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sop-test-suite.yml b/.github/workflows/sop-test-suite.yml index 458a7046..c390e4c8 100644 --- a/.github/workflows/sop-test-suite.yml +++ b/.github/workflows/sop-test-suite.yml @@ -84,4 +84,4 @@ jobs: results: ${{ steps.download-test-results.outputs.download-path }}/test-suite-results.json output: baseline-comparison.json baseline: sop-openpgpjs-main - target: sop-openpgpjs-main + target: sop-openpgpjs-branch From b41298a3f6a3ebf91e3ce0ba0b5b653dc3144770 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Fri, 22 Mar 2024 16:07:49 +0100 Subject: [PATCH 115/201] Add back armor checksum to detached signatures for GPG compatibility GPG v2 fails to parse detached signatures without the checksum --- src/encoding/armor.js | 80 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/src/encoding/armor.js b/src/encoding/armor.js index 8686d131..3820364d 100644 --- a/src/encoding/armor.js +++ b/src/encoding/armor.js @@ -107,6 +107,78 @@ function addheader(customComment, config) { return result; } +/** + * Calculates a checksum over the given data and returns it base64 encoded + * @param {String | ReadableStream} data - Data to create a CRC-24 checksum for + * @returns {String | ReadableStream} Base64 encoded checksum. + * @private + */ +function getCheckSum(data) { + const crc = createcrc24(data); + return base64.encode(crc); +} + +// https://create.stephan-brumme.com/crc32/#slicing-by-8-overview + +const crc_table = [ + new Array(0xFF), + new Array(0xFF), + new Array(0xFF), + new Array(0xFF) +]; + +for (let i = 0; i <= 0xFF; i++) { + let crc = i << 16; + for (let j = 0; j < 8; j++) { + crc = (crc << 1) ^ ((crc & 0x800000) !== 0 ? 0x864CFB : 0); + } + crc_table[0][i] = + ((crc & 0xFF0000) >> 16) | + (crc & 0x00FF00) | + ((crc & 0x0000FF) << 16); +} +for (let i = 0; i <= 0xFF; i++) { + crc_table[1][i] = (crc_table[0][i] >> 8) ^ crc_table[0][crc_table[0][i] & 0xFF]; +} +for (let i = 0; i <= 0xFF; i++) { + crc_table[2][i] = (crc_table[1][i] >> 8) ^ crc_table[0][crc_table[1][i] & 0xFF]; +} +for (let i = 0; i <= 0xFF; i++) { + crc_table[3][i] = (crc_table[2][i] >> 8) ^ crc_table[0][crc_table[2][i] & 0xFF]; +} + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView#Endianness +const isLittleEndian = (function() { + const buffer = new ArrayBuffer(2); + new DataView(buffer).setInt16(0, 0xFF, true /* littleEndian */); + // Int16Array uses the platform's endianness. + return new Int16Array(buffer)[0] === 0xFF; +}()); + +/** + * Internal function to calculate a CRC-24 checksum over a given string (data) + * @param {String | ReadableStream} input - Data to create a CRC-24 checksum for + * @returns {Uint8Array | ReadableStream} The CRC-24 checksum. + * @private + */ +function createcrc24(input) { + let crc = 0xCE04B7; + return stream.transform(input, value => { + const len32 = isLittleEndian ? Math.floor(value.length / 4) : 0; + const arr32 = new Uint32Array(value.buffer, value.byteOffset, len32); + for (let i = 0; i < len32; i++) { + crc ^= arr32[i]; + crc = + crc_table[0][(crc >> 24) & 0xFF] ^ + crc_table[1][(crc >> 16) & 0xFF] ^ + crc_table[2][(crc >> 8) & 0xFF] ^ + crc_table[3][(crc >> 0) & 0xFF]; + } + for (let i = len32 * 4; i < value.length; i++) { + crc = (crc >> 8) ^ crc_table[0][(crc & 0xFF) ^ value[i]]; + } + }, () => new Uint8Array([crc, crc >> 8, crc >> 16])); +} /** * Verify armored headers. crypto-refresh-06, section 6.2: @@ -314,12 +386,18 @@ export function armor(messageType, body, partIndex, partTotal, customComment, co result.push(base64.encode(body)); result.push('-----END PGP PRIVATE KEY BLOCK-----\n'); break; - case enums.armor.signature: + case enums.armor.signature: { + const bodyClone = stream.passiveClone(body); result.push('-----BEGIN PGP SIGNATURE-----\n'); result.push(addheader(customComment, config)); result.push(base64.encode(body)); + // GPG v2 fails to parse signatures without checksums + result.push('=', getCheckSum(bodyClone)); result.push('-----END PGP SIGNATURE-----\n'); break; + } + default: + throw new Error('Unknown armor type'); } return util.concat(result); From 2574795d37a1745250bac43fa62aed91dd2c1f8d Mon Sep 17 00:00:00 2001 From: larabr Date: Fri, 22 Mar 2024 17:10:27 +0100 Subject: [PATCH 116/201] Fix wrong serialization of PKESK v6 for x25519/x448 (#1734) The cleartext session key symmetric algorithm was accidentally included in the packet. As a result, the generated messages may fail to parse and/or decrypt in other implementations. The messages would still decrypt successfully in OpenPGP.js, due to an overly permissive parsing procedure, which simply discarded the unused additional byte. We know also throw on unexpected cleartext symmetric algo in PKESK v6. --- src/crypto/crypto.js | 4 +- .../public_key_encrypted_session_key.js | 17 +++-- test/general/packet.js | 74 ++++++++++++++----- 3 files changed, 68 insertions(+), 27 deletions(-) diff --git a/src/crypto/crypto.js b/src/crypto/crypto.js index 04e2fe39..683f3e57 100644 --- a/src/crypto/crypto.js +++ b/src/crypto/crypto.js @@ -39,7 +39,7 @@ import ECDHXSymmetricKey from '../type/ecdh_x_symkey'; * Encrypts data using specified algorithm and public key parameters. * See {@link https://tools.ietf.org/html/rfc4880#section-9.1|RFC 4880 9.1} for public key algorithms. * @param {module:enums.publicKey} keyAlgo - Public key algorithm - * @param {module:enums.symmetric} symmetricAlgo - Cipher algorithm + * @param {module:enums.symmetric|null} symmetricAlgo - Cipher algorithm (v3 only) * @param {Object} publicParams - Algorithm-specific public key parameters * @param {Uint8Array} data - Session key data to be encrypted * @param {Uint8Array} fingerprint - Recipient fingerprint @@ -66,7 +66,7 @@ export async function publicKeyEncrypt(keyAlgo, symmetricAlgo, publicParams, dat } case enums.publicKey.x25519: case enums.publicKey.x448: { - if (!util.isAES(symmetricAlgo)) { + if (symmetricAlgo && !util.isAES(symmetricAlgo)) { // see https://gitlab.com/openpgp-wg/rfc4880bis/-/merge_requests/276 throw new Error('X25519 and X448 keys can only encrypt AES session keys'); } diff --git a/src/packet/public_key_encrypted_session_key.js b/src/packet/public_key_encrypted_session_key.js index 1f6c1d04..23a10563 100644 --- a/src/packet/public_key_encrypted_session_key.js +++ b/src/packet/public_key_encrypted_session_key.js @@ -128,9 +128,12 @@ class PublicKeyEncryptedSessionKeyPacket { } this.publicKeyAlgorithm = bytes[offset++]; this.encrypted = crypto.parseEncSessionKeyParams(this.publicKeyAlgorithm, bytes.subarray(offset)); - if (this.version === 3 && ( - this.publicKeyAlgorithm === enums.publicKey.x25519 || this.publicKeyAlgorithm === enums.publicKey.x448)) { - this.sessionKeyAlgorithm = enums.write(enums.symmetric, this.encrypted.C.algorithm); + if (this.publicKeyAlgorithm === enums.publicKey.x25519 || this.publicKeyAlgorithm === enums.publicKey.x448) { + if (this.version === 3) { + this.sessionKeyAlgorithm = enums.write(enums.symmetric, this.encrypted.C.algorithm); + } else if (this.encrypted.C.algorithm !== null) { + throw new Error('Unexpected cleartext symmetric algorithm'); + } } } @@ -174,9 +177,12 @@ class PublicKeyEncryptedSessionKeyPacket { */ async encrypt(key) { const algo = enums.write(enums.publicKey, this.publicKeyAlgorithm); - const encoded = encodeSessionKey(this.version, algo, this.sessionKeyAlgorithm, this.sessionKey); + // No symmetric encryption algorithm identifier is passed to the public-key algorithm for a + // v6 PKESK packet, as it is included in the v2 SEIPD packet. + const sessionKeyAlgorithm = this.version === 3 ? this.sessionKeyAlgorithm : null; + const encoded = encodeSessionKey(this.version, algo, sessionKeyAlgorithm, this.sessionKey); this.encrypted = await crypto.publicKeyEncrypt( - algo, this.sessionKeyAlgorithm, key.publicParams, encoded, key.getFingerprintBytes()); + algo, sessionKeyAlgorithm, key.publicParams, encoded, key.getFingerprintBytes()); } /** @@ -275,6 +281,7 @@ function decodeSessionKey(version, keyAlgo, decryptedData, randomSessionKey) { case enums.publicKey.x25519: case enums.publicKey.x448: return { + sessionKeyAlgorithm: null, sessionKey: decryptedData }; default: diff --git a/test/general/packet.js b/test/general/packet.js index 0cf26d7b..b40e2ba5 100644 --- a/test/general/packet.js +++ b/test/general/packet.js @@ -8,6 +8,8 @@ chaiUse(chaiAsPromised); import openpgp from '../initOpenpgp.js'; import crypto from '../../src/crypto'; import util from '../../src/util.js'; +import * as packet from '../../src/packet'; + import * as input from './testInputs.js'; @@ -469,32 +471,64 @@ export default () => describe('Packet', function() { }); }); - it('Public key encrypted symmetric key packet', function() { - const rsa = openpgp.enums.publicKey.rsaEncryptSign; - const keySize = 1024; + describe('Public key encrypted symmetric key packet - roundtrip', () => { + const testData = [{ + algoLabel: 'RSA', + publicKeyAlgorithm: openpgp.enums.publicKey.rsaEncryptSign, + paramsPromise: crypto.generateParams(openpgp.enums.publicKey.rsaEncryptSign, 1024, 65537) + }, + { + algoLabel: 'ECDH NIST P-256', + publicKeyAlgorithm: openpgp.enums.publicKey.ecdh, + paramsPromise: crypto.generateParams(openpgp.enums.publicKey.ecdh, null, openpgp.enums.curve.nistP256) + }, + { + algoLabel: 'ECDH x25519Legacy', + publicKeyAlgorithm: openpgp.enums.publicKey.ecdh, + paramsPromise: crypto.generateParams(openpgp.enums.publicKey.ecdh, null, openpgp.enums.curve.curve25519Legacy) + }, + { + algoLabel: 'x25519', + publicKeyAlgorithm: openpgp.enums.publicKey.x25519, + paramsPromise: crypto.generateParams(openpgp.enums.publicKey.x25519) + }]; - return crypto.generateParams(rsa, keySize, 65537).then(function({ publicParams, privateParams }) { - const enc = new openpgp.PublicKeyEncryptedSessionKeyPacket(); - enc.version = 3; - const msg = new openpgp.PacketList(); - const msg2 = new openpgp.PacketList(); + function testRoundtrip({ v6 }) { + testData.forEach(({ algoLabel, publicKeyAlgorithm, paramsPromise }) => { + it(`${algoLabel} (PKESK ${v6 ? 'v6' : 'v3'})`, async () => { + const { publicParams, privateParams } = await paramsPromise; + // cannot use the `openpgp` exported values, since the different context gives issues when internally + // evaluating the `OID` instanceof of `publicParams.oid`, as part of `pkesk.encrypt` and `decrypt` + const pkesk = new packet.PublicKeyEncryptedSessionKeyPacket(); + pkesk.version = v6 ? 6 : 3; + const msg = new packet.PacketList(); + const msg2 = new packet.PacketList(); - enc.sessionKey = new Uint8Array([1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2]); - enc.publicKeyAlgorithm = openpgp.enums.publicKey.rsaEncryptSign; - enc.sessionKeyAlgorithm = openpgp.enums.symmetric.aes256; - enc.publicKeyID.bytes = '12345678'; - return enc.encrypt({ publicParams, getFingerprintBytes() {} }).then(async () => { + const privateKey = { + algorithm: publicKeyAlgorithm, + publicParams, + privateParams, + getFingerprintBytes: () => new Uint8Array(64) + }; + pkesk.sessionKey = new Uint8Array([1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2]); + pkesk.publicKeyAlgorithm = publicKeyAlgorithm; + pkesk.sessionKeyAlgorithm = openpgp.enums.symmetric.aes256; + pkesk.publicKeyID.bytes = '12345678'; + await pkesk.encrypt({ publicParams: privateKey.publicParams, getFingerprintBytes: privateKey.getFingerprintBytes }); - msg.push(enc); - await msg2.read(msg.write(), allAllowedPackets); + msg.push(pkesk); + const allAllowedPackets = util.constructAllowedPackets([...Object.values(packet).filter(packetClass => !!packetClass.tag)]); + await msg2.read(msg.write(), allAllowedPackets); - const privateKey = { algorithm: openpgp.enums.publicKey.rsaEncryptSign, publicParams, privateParams, getFingerprintBytes() {} }; - return msg2[0].decrypt(privateKey).then(() => { - expect(stringify(msg2[0].sessionKey)).to.equal(stringify(enc.sessionKey)); - expect(msg2[0].sessionKeyAlgorithm).to.equal(enc.sessionKeyAlgorithm); + await msg2[0].decrypt(privateKey); + expect(msg2[0].sessionKey).to.deep.equal(pkesk.sessionKey); + expect(msg2[0].sessionKeyAlgorithm).to.equal(v6 ? null : pkesk.sessionKeyAlgorithm); }); }); - }); + } + + testRoundtrip({ v6: false }); + testRoundtrip({ v6: true }); }); it('Secret key packet (reading, unencrypted)', async function() { From 6ebd179ed58c698d94599af48836825f0f7c902e Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Fri, 22 Mar 2024 16:58:33 +0100 Subject: [PATCH 117/201] Fix encrypting to a key with no declared features --- src/key/helper.js | 2 +- test/general/openpgp.js | 63 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/src/key/helper.js b/src/key/helper.js index d440cab2..9ca90bf4 100644 --- a/src/key/helper.js +++ b/src/key/helper.js @@ -171,7 +171,7 @@ export async function getPreferredCompressionAlgo(keys = [], date = new Date(), export async function getPreferredCipherSuite(keys = [], date = new Date(), userIDs = [], config = defaultConfig) { const selfSigs = await Promise.all(keys.map((key, i) => key.getPrimarySelfSignature(date, userIDs[i], config))); const withAEAD = keys.length ? - selfSigs.every(selfSig => selfSig.features[0] & enums.features.seipdv2) : + selfSigs.every(selfSig => selfSig.features && (selfSig.features[0] & enums.features.seipdv2)) : config.aeadProtect; if (withAEAD) { diff --git a/test/general/openpgp.js b/test/general/openpgp.js index 49cc76b1..ad5275b8 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -868,6 +868,56 @@ MbVkSnU2Z+vhSmYubDCldNOSVwE= =bTUQ -----END PGP PRIVATE KEY BLOCK-----`; +const rsaKeyWithNoFeaturesFromRNP = `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xcLYBGX9lyEBCADMOR1JW9yPhMxeMmrUWf2MqKtX9WHvS+EFkPaVwWmYIM/bjcrngPgKEG5wTND9 +S1QJ/Op9mzN36kwAzX0bLx2R+HlyvNQOzOA05uY3uhbZePvkE2o76z9//w07DEYtMG8aLvLdpVLW +U7YwMMdlI8zSwi2Q5/QAUOfCJCylxndj/U7AF+9sqrSoSJmwtzu+AS3pnHDgqcHpum7KTL7sOgwa +8713qGb05YgXCtUkh2hT0t7Kz5OsQrM01yJJlVkgxw6BZXiRCLSCGCepZiUvtWO53cwZ2GgIZZKx +piAEo8AjMHGUxyiMBR5DvzDLADVexLf/DB5BTz9KywRu2zTGUtYlABEBAAEAB/4ifoUlVmhHL4GL +aY2kx3xtjTG/vhkoH5Nm6sjTm6MXyHcDWQxMFPsQTB0zR65HEjmkJD2BML09RGxI+GxosokWljcB +O8a/pzg5h0ScZgik++vj5qmbbE1B89UKw7R4voUNkZ+A84Mt417S/fI38ZePg6/JmXwbr46tuol2 +CLMyxpFVNvGgqj7/U3co/BygukHMqfpC/K4QTVWUFCLkzgpAzk+LekSLWNrVD2soVQGmUn68OOLY +Dnwxe7mP/4GAmmnAH4nfg9Uf+z1tHVoaL7sUHKFXXBIjopcimWBjLIzWm0ZvKzmvmOE49Fswuoyt +Q2oLWYCXd/lrDr4u/VN+/uKhBADTpPm6+eNJ9CDOsIHTlNWrKD6/iubsLXWju5uyOW8rWDkE5m8+ +Ik+l4Eq8b0iAHGSS/6QayeRupeUCCkHnmA956qAFvHzkeE2S5YUg/mtnV+qPZrHG4UfD3KU0gv/Y +3x3HcqOYU7Ph6kq4mcF7UO83+8E8gJWyJwWwqpKXrgDZtQQA9wX5T11+bOwWh37SDWd20mqxTwZM +pSuClCUwVs8Z2p/Fo+Kq/+uoNRQW38O1J2QM37fMaKOePeYN15cIM3ilZQ0mU3UwvKC1B3zxd0f9 +28cZ4fxlGDE3qzZygbB/BxiXnlcPezO2r03X9PJnjCP2y5Wi+PMR5ciFY1w5qaI9ELEEAL6Wvdl4 +zSwkT4qxM7rWzrpVPisdHRiwFT6E+vTmNpA+qXvwlbLEXrYmFVY7CphWjyJQEvqxaa0MtdJniwef +cZtSi2CirquB0R3RJtloMZkbobRJFV43URIc9qUhSgarZ+Pco80mG06hjY2pxFot49oJZp2FNm5d +wPOB/kCvczK3QRHNGkJlcm5hZGV0dGUgPGJAZXhhbXBsZS5vcmc+wsCNBBMBCAA3FiEEKUdMEpbT +txHSmeOgwAeWcPHMimkFAmX9lyEFCQPCZwACGwMECwkIBwUVCAkKCwUWAgMBAAAKCRDAB5Zw8cyK +aUZHB/9j2vE9niEiQS9tNczxrXFde2Kg8U+PzoSU83QvkkWM2D4FBukCZDHj7cppIzYcDcH0Gaox +Y2eUgJx/q/Nq8svsk2Z4X3dGsEut+EqQpsjWny4kUHKUBemSh3JGJoH5ongxXXNwNTe31zNa1CRA +nmc5KXnOmD2FX17ax5Xu2SaJ11eiKcmKXMtZBVzzLL41LwUd2RPizIw1TT2zckHIstwaLdO4y5If +ZEnTiiBqrex8HYf/Vta8GF8uvJVQvn+Du5m/FmdeSFxTBeDvf1Sj6k8XBS9QQHbjpH/K4ePz9Twh +ayLuvrvWmyN5edo6Xf1LRh/R6dskKbUOreAfS8pTWWp0x8LYBGX9lyEBCAC43ooLMCLT0QYslVWZ +suDNNrQ0LYY24i3vRfnHFM9rRUthWrcIKzpKFvq9jntETYWkNM7LIJ2YhHueVMuLyaF2Evrkn89q +dCbA+ICS4uJ5RlhXv5ZfQT+H9fQL/JBTk9vQpBoZHr8foPc2YNonOuZjmeLSa1ZcR6BumUQqTjuk +CEgWxebnRUz6aL6+Mdl/emU7+G6IINC15q3RWUIlkmx5gQwsmIaztxVF9LniRIkB+Fjwf7U7AqfL +Y87/F1LHqeaIzc6oZNfIIXX57A4im3lqJQAQq1n/omyYHwWO+lWqbCwCj8ri4OXcgGZOdkbMOHff +hGsxKy8YK7qyvBxYiINPABEBAAEAB/sFu2CsWCG8T47Rcw/kZBd0RW3w8DhpGzoxYQoNkiecO9nK +evWR20VDZtL/bZuE0qKCJOEEi05XnEP49Mga3XWUI6KD1DCqLE/HS+0woLhE6lly3w3ahjtiC841 +UO9op/z4yx3ECaADawo/NWGONdVO4UaXH5zd35qp0za52RMgUtPqwJBZ9cKfXkFmfu9QDpiW1J4N +8S76Hgol4ThESRTm80d82L2UMVbFgXZOgpMgq+A1NXSbloSJ3ZMI2hR21PbQt/uAdwCP/E+EQOe+ +s6HN/9+0XjzsE0wcu7DJa/3QTWGTnn5Jg/SufHnABWTqYymfDH74TTPlkkWNJB65Cz0BBADUMLdg +jfDgmlw2CtKHuMYvMDe//a+KgrV2Q89QRnQk8agwXkiY/NxtRehOj35yzzUs/AdEfmVT6jaC/dQD +tEqeY1B9LI4nL4ZiE+qLnSKVPeeWtOVNUsNJUFRX6oSvChTlWj90UWvYtQUUS0zAQrI+tcJsypTE +fiSBG8DOzefi1wQA3wnGkyIidc7N8u/NdCvBO2jUOU4Q6A1E1k2eVfcjK05gHEtChUgf03v80iFG +42VIGa00rxfv9RdWAJzWy+/qqjPAUGtlrbM0VljZsvLnsZLU4cTaC2A+3Lm00UgkHAGzw4IBe9vB +4IAHYpRnZEwIveyDwVLpioEP5wShHYVXTEkEAILWuum7EgK70yYoC4HUvmUufpj7aTfpC4vYqi+4 +Xw0n8PLPPRZ3AjJE2O41kicip/Y30B3HVIxwbwYMBIjqRTpTyYer6jkRHc17xau8vzyWKLETC+7A +WPrljucvjEJXpkrDYlV5fmpsMvqVHJiSQrJDMFX1SHF8UUnqelGg6Fv8QLvCwHwEGAEIACYWIQQp +R0wSltO3EdKZ46DAB5Zw8cyKaQUCZf2XIgUJA8JnAAIbDAAKCRDAB5Zw8cyKaY7PB/9qOmlz84mu +wNrHo00TdXefBykwoJxtDLjNzQE/8HGnzuFWJgHvRDD8FLaaevRwD1AGf6B3YySxBwICoRqbsYGr +wg9ng3wIUBPeAeS61e/ATkFEqknQnj2rIscaztxz56b1Sy6YEjW6dD7QngoinDViAmNT/zY2diK8 +85iB+47tNXrUOHD1FKs8XKr05FwWWjFmmqGSxC+LSdNeuDtP1UKZaoYROyZ+R3zKdguNOhtDHX6o +me8oJym/ILMHRGIc4JvY9+2wE5U1FBYTsze3WnVH5dP5mfA2Uk83TR5KewKANsb4kl/OEPlADWdR +8wENR68u88WrKOGN359vq/DKwd3A +=c2mQ +-----END PGP PRIVATE KEY BLOCK-----`; + function withCompression(tests) { const compressionTypes = Object.values(openpgp.enums.compression); @@ -2204,6 +2254,19 @@ k0mXubZvyl4GBg== expect(seipd.version).to.equal(2); expect(seipd.aeadAlgorithm).to.equal(openpgp.enums.aead.ocb); }); + + it('should support encrypting to a key without features (missing SEIPDv1 feature)', async function () { + const key = await openpgp.readKey({ armoredKey: rsaKeyWithNoFeaturesFromRNP }); + const encrypted = await openpgp.encrypt({ + message: await openpgp.createMessage({ text: 'test' }), + encryptionKeys: key + }); + const decrypted = await openpgp.decrypt({ + message: await openpgp.readMessage({ armoredMessage: encrypted }), + decryptionKeys: key + }); + expect(decrypted.data).to.equal('test'); + }); }); describe('encryptSessionKey - unit tests', function() { From aa222fecb2433e36f9bcee3e236da8e6fa02114f Mon Sep 17 00:00:00 2001 From: larabr Date: Thu, 28 Mar 2024 14:24:23 +0100 Subject: [PATCH 118/201] Drop `config.revocationsExpire`, always honour revocation expiration instead (#1736) Unclear motivation for adding the original config option; if an expiration is there, it should be honoured. Breaking change: the option used to default to `false`, and ignore revocation expirations. We now honour those expirations, namely match the behaviour resulting from setting the option to `true`. --- openpgp.d.ts | 1 - src/config/config.js | 5 ----- src/key/helper.js | 2 +- test/general/key.js | 3 ++- 4 files changed, 3 insertions(+), 8 deletions(-) diff --git a/openpgp.d.ts b/openpgp.d.ts index 871a707d..10c8d710 100644 --- a/openpgp.d.ts +++ b/openpgp.d.ts @@ -328,7 +328,6 @@ interface Config { allowUnauthenticatedStream: boolean; minRSABits: number; passwordCollisionCheck: boolean; - revocationsExpire: boolean; ignoreUnsupportedPackets: boolean; ignoreMalformedPackets: boolean; versionString: string; diff --git a/src/config/config.js b/src/config/config.js index b006a3f4..d5c9c14c 100644 --- a/src/config/config.js +++ b/src/config/config.js @@ -155,11 +155,6 @@ export default { * @property {Boolean} passwordCollisionCheck */ passwordCollisionCheck: false, - /** - * @memberof module:config - * @property {Boolean} revocationsExpire If true, expired revocation signatures are ignored - */ - revocationsExpire: false, /** * Allow decryption using RSA keys without `encrypt` flag. * This setting is potentially insecure, but it is needed to get around an old openpgpjs bug diff --git a/src/key/helper.js b/src/key/helper.js index 9ca90bf4..d479b081 100644 --- a/src/key/helper.js +++ b/src/key/helper.js @@ -282,7 +282,7 @@ export async function isDataRevoked(primaryKey, signatureType, dataToVerify, rev !signature || revocationSignature.issuerKeyID.equals(signature.issuerKeyID) ) { await revocationSignature.verify( - key, signatureType, dataToVerify, config.revocationsExpire ? date : null, false, config + key, signatureType, dataToVerify, date, false, config ); // TODO get an identifier of the revoked object instead diff --git a/test/general/key.js b/test/general/key.js index 5e20a31e..1060ac87 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -4275,7 +4275,8 @@ VYGdb3eNlV8CfoEC const key = await openpgp.readKey({ armoredKey: pub_revoked_subkeys }); key.revocationSignatures = []; key.users[0].revocationSignatures = []; - return openpgp.encrypt({ encryptionKeys: [key], message: await openpgp.createMessage({ text: 'random data' }), date: new Date(1386842743000) }).then(() => { + const subkeyRevocationTime = key.subkeys[0].revocationSignatures[0].created; + return openpgp.encrypt({ encryptionKeys: [key], message: await openpgp.createMessage({ text: 'random data' }), date: subkeyRevocationTime }).then(() => { throw new Error('encryptSessionKey should not encrypt with revoked public key'); }).catch(error => { expect(error.message).to.equal('Error encrypting message: Could not find valid encryption key packet in key ' + key.getKeyID().toHex() + ': Subkey is revoked'); From c68bd960cea7557907891578f7a1b44cdc5f1147 Mon Sep 17 00:00:00 2001 From: larabr Date: Tue, 2 Apr 2024 17:37:57 +0200 Subject: [PATCH 119/201] Randomise v4 and v5 signatures via custom notation, add `config.nonDeterministicSignaturesViaNotation` to disable feature (#1737) EdDSA is known to be vulnerable to fault attacks which can lead to secret key extraction if two signatures over the same data can be collected. Randomly occurring bitflips in specific parts of the computation might in principle result in vulnerable faulty signatures being generated. To protect signatures generated using v4 and v5 keys from this possibility, we randomise each signature by adding a custom notation with a random value, functioning as a salt. For simplicity, we add the salt to all algos, not just EdDSA, as it may also serve as protection in case of weaknesses in the hash algo, potentially hindering e.g. some chosen-prefix attacks. v6 signatures do not need to rely on this, as they are non-deterministic by design. While this notation solution is interoperable, it will reveal that the signature has been generated using OpenPGP.js, which may not be desirable in some cases. For this reason, the option `config.nonDeterministicSignaturesViaNotation` (defaulting to true) has been added to turn off the feature. --- src/config/config.js | 8 +++++ src/key/helper.js | 4 +-- src/packet/signature.js | 43 +++++++++++++++++----- test/general/packet.js | 2 +- test/general/signature.js | 67 ++++++++++++++++++++++++++++++++++- test/security/subkey_trust.js | 2 +- 6 files changed, 112 insertions(+), 14 deletions(-) diff --git a/src/config/config.js b/src/config/config.js index d5c9c14c..866a0c34 100644 --- a/src/config/config.js +++ b/src/config/config.js @@ -250,6 +250,14 @@ export default { * @property {Array} knownNotations */ knownNotations: [], + /** + * If true, a salt notation is used to randomize signatures generated by v4 and v5 keys (v6 signatures are always non-deterministic, by design). + * This protects EdDSA signatures from potentially leaking the secret key in case of faults (i.e. bitflips) which, in principle, could occur + * during the signing computation. It is added to signatures of any algo for simplicity, and as it may also serve as protection in case of + * weaknesses in the hash algo, potentially hindering e.g. some chosen-prefix attacks. + * NOTE: the notation is interoperable, but will reveal that the signature has been generated using OpenPGP.js, which may not be desirable in some cases. + */ + nonDeterministicSignaturesViaNotation: true, /** * Whether to use the the noble-curves library for curves (other than Curve25519) that are not supported by the available native crypto API. * When false, certain standard curves will not be supported (depending on the platform). diff --git a/src/key/helper.js b/src/key/helper.js index d479b081..9425ebf8 100644 --- a/src/key/helper.js +++ b/src/key/helper.js @@ -218,8 +218,8 @@ export async function createSignaturePacket(dataToSign, privateKey, signingKeyPa Object.assign(signaturePacket, signatureProperties); signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm; signaturePacket.hashAlgorithm = await getPreferredHashAlgo(privateKey, signingKeyPacket, date, userID, config); - signaturePacket.rawNotations = notations; - await signaturePacket.sign(signingKeyPacket, dataToSign, date, detached); + signaturePacket.rawNotations = [...notations]; + await signaturePacket.sign(signingKeyPacket, dataToSign, date, detached, config); return signaturePacket; } diff --git a/src/packet/signature.js b/src/packet/signature.js index b650ca99..43fc2002 100644 --- a/src/packet/signature.js +++ b/src/packet/signature.js @@ -26,6 +26,14 @@ import defaultConfig from '../config'; // Symbol to store cryptographic validity of the signature, to avoid recomputing multiple times on verification. const verified = Symbol('verified'); +// A salt notation is used to randomize signatures. +// This is to protect EdDSA signatures in particular, which are known to be vulnerable to fault attacks +// leading to secret key extraction if two signatures over the same data can be collected (see https://github.com/jedisct1/libsodium/issues/170). +// For simplicity, we add the salt to all algos, as it may also serve as protection in case of weaknesses in the hash algo, potentially hindering e.g. +// some chosen-prefix attacks. +// v6 signatures do not need to rely on this notation, as they already include a separate, built-in salt. +const SALT_NOTATION_NAME = 'salt@notations.openpgpjs.org'; + // GPG puts the Issuer and Signature subpackets in the unhashed area. // Tampering with those invalidates the signature, so we still trust them and parse them. // All other unhashed subpackets are ignored. @@ -195,7 +203,7 @@ class SignaturePacket { * @throws {Error} if signing failed * @async */ - async sign(key, data, date = new Date(), detached = false) { + async sign(key, data, date = new Date(), detached = false, config) { this.version = key.version; this.created = util.normalizeDate(date); @@ -205,6 +213,31 @@ class SignaturePacket { const arr = [new Uint8Array([this.version, this.signatureType, this.publicKeyAlgorithm, this.hashAlgorithm])]; + // add randomness to the signature + if (this.version === 6) { + const saltLength = saltLengthForHash(this.hashAlgorithm); + if (this.salt === null) { + this.salt = crypto.random.getRandomBytes(saltLength); + } else if (saltLength !== this.salt.length) { + throw new Error('Provided salt does not have the required length'); + } + } else if (config.nonDeterministicSignaturesViaNotation) { + const saltNotations = this.rawNotations.filter(({ name }) => (name === SALT_NOTATION_NAME)); + // since re-signing the same object is not supported, it's not expected to have multiple salt notations, + // but we guard against it as a sanity check + if (saltNotations.length === 0) { + const saltValue = crypto.random.getRandomBytes(saltLengthForHash(this.hashAlgorithm)); + this.rawNotations.push({ + name: SALT_NOTATION_NAME, + value: saltValue, + humanReadable: false, + critical: false + }); + } else { + throw new Error('Unexpected existing salt notation'); + } + } + // Add hashed subpackets arr.push(this.writeHashedSubPackets()); @@ -215,14 +248,6 @@ class SignaturePacket { this.signatureData = util.concat(arr); - if (this.version === 6) { - const saltLength = saltLengthForHash(this.hashAlgorithm); - if (this.salt === null) { - this.salt = crypto.random.getRandomBytes(saltLength); - } else if (saltLength !== this.salt.length) { - throw new Error('Provided salt does not have the required length'); - } - } const toHash = this.toHash(this.signatureType, data, detached); const hash = await this.hash(this.signatureType, data, toHash, detached); diff --git a/test/general/packet.js b/test/general/packet.js index b40e2ba5..ad34ca31 100644 --- a/test/general/packet.js +++ b/test/general/packet.js @@ -1432,7 +1432,7 @@ V+HOQJQxXJkVRYa3QrFUehiMzTeqqMdgC6ZqJy7+ signature.publicKeyAlgorithm = openpgp.enums.publicKey.rsaSign; signature.signatureType = openpgp.enums.signature.text; - return signature.sign(key, literal).then(async () => { + return signature.sign(key, literal, undefined, undefined, openpgp.config).then(async () => { signed.push(literal); signed.push(signature); diff --git a/test/general/signature.js b/test/general/signature.js index 86b01476..20bd0c30 100644 --- a/test/general/signature.js +++ b/test/general/signature.js @@ -1409,7 +1409,7 @@ DAAKCRDyMVUMT0fjjlnQAQDFHUs6TIcxrNTtEZFjUFm1M0PJ1Dng/cDW4xN80fsn }); expect(await sig.verified).to.be.true; const { packets: [{ rawNotations: notations }] } = await sig.signature; - expect(notations).to.have.length(2); + expect(notations).to.have.length(3); expect(notations[0].name).to.equal('test@example.com'); expect(notations[0].value).to.deep.equal(new Uint8Array([116, 101, 115, 116])); expect(notations[0].humanReadable).to.be.true; @@ -1418,6 +1418,71 @@ DAAKCRDyMVUMT0fjjlnQAQDFHUs6TIcxrNTtEZFjUFm1M0PJ1Dng/cDW4xN80fsn expect(notations[1].value).to.deep.equal(new Uint8Array([0, 1, 2, 3])); expect(notations[1].humanReadable).to.be.false; expect(notations[1].critical).to.be.false; + expect(notations[2].name).to.equal('salt@notations.openpgpjs.org'); + expect(notations[2].humanReadable).to.be.false; + expect(notations[2].critical).to.be.false; + }); + + it('v4 signatures are randomized via salt notation (`config.nonDeterministicSignaturesViaNotation`)', async function() { + const v4SigningKey = await openpgp.readKey({ + armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xVgEX8+jfBYJKwYBBAHaRw8BAQdA9GbdDjprR0sWf0R5a5IpulUauc0FsmzJ +mOYCfoowt8EAAP9UwaqC0LWWQ5RlX7mps3728vFa/If1KBVwAjk7Uqhi2BKL +zQ90ZXN0MiA8YkBhLmNvbT7CjAQQFgoAHQUCX8+jfAQLCQcIAxUICgQWAgEA +AhkBAhsDAh4BACEJEG464aV2od77FiEEIcg441MtKnyJnPDRbjrhpXah3vuR +gQD+Il6Gw2oIok4/ANyDDLBYZtKqRrMv4NcfF9DHYuAFcP4BAPhFOffyP3qU +AEZb7QPrWdLfhn8/FeSFZxJvnmupQ9sDx10EX8+jfBIKKwYBBAGXVQEFAQEH +QOSzo9cX1U2esGFClprOt0QWXNJ97228R5tKFxo6/0NoAwEIBwAA/0n4sq2i +N6/jE+6rVO4o/7LW0xahxpV1tTA6qv1Op9TwFIDCeAQYFggACQUCX8+jfAIb +DAAhCRBuOuGldqHe+xYhBCHIOONTLSp8iZzw0W464aV2od773XcA/jlmX8/c +1/zIotEkyMZB4mI+GAg3FQ6bIACFBH1sz0MzAP9Snri0P4FRZ8D5THRCJoUm +GBgpBmrf6IVv484jBswGDA== +=8rBO +-----END PGP PRIVATE KEY BLOCK-----` + }); + + const date = new Date('Tue, 25 Dec 2023 00:00:00 GMT'); + const text = 'test'; + const armoredRandomSignature1 = await openpgp.sign({ + message: await openpgp.createMessage({ text }), + signingKeys: v4SigningKey, + date, + detached: true + }); + const armoredRandomSignature2 = await openpgp.sign({ + message: await openpgp.createMessage({ text }), + signingKeys: v4SigningKey, + date, + detached: true + }); + const randomSignature1 = await openpgp.readSignature({ armoredSignature: armoredRandomSignature1 }); + const randomSignature2 = await openpgp.readSignature({ armoredSignature: armoredRandomSignature2 }); + expect(randomSignature1.packets[0].signedHashValue).to.not.deep.equal(randomSignature2.packets[0].signedHashValue); + + // ensure the signatures are verifiable, as a sanity check + const verification1 = await openpgp.verify({ message: await openpgp.createMessage({ text }), signature: randomSignature1, verificationKeys: v4SigningKey, expectSigned: true }); + expect(verification1.data).to.equal(text); + + const armoredDeterministicSignature1 = await openpgp.sign({ + message: await openpgp.createMessage({ text }), + signingKeys: v4SigningKey, + date, + detached: true, + config: { nonDeterministicSignaturesViaNotation: false } + }); + const armoredDeterministicSignature2 = await openpgp.sign({ + message: await openpgp.createMessage({ text }), + signingKeys: v4SigningKey, + date, + detached: true, + config: { nonDeterministicSignaturesViaNotation: false } + }); + const deterministicSignature1 = await openpgp.readSignature({ armoredSignature: armoredDeterministicSignature1 }); + const deterministicSignature2 = await openpgp.readSignature({ armoredSignature: armoredDeterministicSignature2 }); + expect(deterministicSignature1.packets[0].signedHashValue).to.deep.equal(deterministicSignature2.packets[0].signedHashValue); + const verification2 = await openpgp.verify({ message: await openpgp.createMessage({ text }), signature: deterministicSignature1, verificationKeys: v4SigningKey, expectSigned: true }); + expect(verification2.data).to.equal(text); }); it('Verify v6 cleartext signed message with openpgp.verify', async function() { diff --git a/test/security/subkey_trust.js b/test/security/subkey_trust.js index e8aee45b..5d7f5fbe 100644 --- a/test/security/subkey_trust.js +++ b/test/security/subkey_trust.js @@ -50,7 +50,7 @@ export default () => it('Does not trust subkeys without Primary Key Binding Sign fakeBindingSignature.publicKeyAlgorithm = attackerPrivKey.keyPacket.algorithm; fakeBindingSignature.hashAlgorithm = enums.hash.sha256; fakeBindingSignature.keyFlags = [enums.keyFlags.signData]; - await fakeBindingSignature.sign(attackerPrivKey.keyPacket, dataToSign); + await fakeBindingSignature.sign(attackerPrivKey.keyPacket, dataToSign, undefined, undefined, openpgp.config); const newList = new PacketList(); newList.push( pktPubAttacker[0], // attacker private key From e9e843280b6d3b9a6b9d1e9909f829dfdfea5853 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Fri, 5 Apr 2024 17:11:33 +0200 Subject: [PATCH 120/201] CI: update to sop-openpgp-v2 to test different v6 profiles The implemented profiles do not work on v5, hence for now they need to be manually disabled in the config of 'sop-openpgpjs-main'. --- .github/test-suite/config.json.template | 3 ++- .github/test-suite/prepare_config.sh | 2 +- .github/workflows/sop-test-suite.yml | 6 +++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/test-suite/config.json.template b/.github/test-suite/config.json.template index 7a3b33c5..168cccf1 100644 --- a/.github/test-suite/config.json.template +++ b/.github/test-suite/config.json.template @@ -11,7 +11,8 @@ "id": "sop-openpgpjs-main", "path": "__SOP_OPENPGPJS__", "env": { - "OPENPGPJS_PATH": "__OPENPGPJS_MAIN__" + "OPENPGPJS_PATH": "__OPENPGPJS_MAIN__", + "DISABLE_PROFILES": "true" } }, { diff --git a/.github/test-suite/prepare_config.sh b/.github/test-suite/prepare_config.sh index 0bf112c1..f7ff0b51 100755 --- a/.github/test-suite/prepare_config.sh +++ b/.github/test-suite/prepare_config.sh @@ -8,6 +8,6 @@ cat $CONFIG_TEMPLATE \ | sed "s@__SQOP__@${SQOP}@g" \ | sed "s@__GPGME_SOP__@${GPGME_SOP}@g" \ | sed "s@__GOSOP_V2__@${GOSOP_DIR_V2}/gosop@g" \ - | sed "s@__SOP_OPENPGPJS__@${SOP_OPENPGPJS}@g" \ + | sed "s@__SOP_OPENPGPJS__@${SOP_OPENPGPJS_V2}@g" \ | sed "s@__RNP_SOP__@${RNP_SOP}@g" \ > $CONFIG_OUTPUT \ No newline at end of file diff --git a/.github/workflows/sop-test-suite.yml b/.github/workflows/sop-test-suite.yml index c390e4c8..5d8b1bcb 100644 --- a/.github/workflows/sop-test-suite.yml +++ b/.github/workflows/sop-test-suite.yml @@ -10,7 +10,7 @@ jobs: name: Run interoperability test suite runs-on: ubuntu-latest container: - image: ghcr.io/protonmail/openpgp-interop-test-docker:v1.1.6 + image: ghcr.io/protonmail/openpgp-interop-test-docker:v1.1.7 credentials: username: ${{ github.actor }} password: ${{ secrets.github_token }} @@ -25,7 +25,7 @@ jobs: - name: Install openpgpjs-branch run: cd openpgpjs-branch && npm install - name: Print openpgpjs-branch version - run: $SOP_OPENPGPJS version --extended + run: $SOP_OPENPGPJS_V2 version --extended env: OPENPGPJS_PATH: ${{ github.workspace }}/openpgpjs-branch # check out main branch @@ -37,7 +37,7 @@ jobs: - name: Install openpgpjs-main run: cd openpgpjs-main && npm install - name: Print openpgpjs-main version - run: $SOP_OPENPGPJS version --extended + run: $SOP_OPENPGPJS_V2 version --extended env: OPENPGPJS_PATH: ${{ github.workspace }}/openpgpjs-main # Run test suite From 90c8fbbf002bae206f66f2b47984b0907395f835 Mon Sep 17 00:00:00 2001 From: larabr Date: Tue, 9 Apr 2024 17:12:44 +0200 Subject: [PATCH 121/201] Add back armor checksum for non-v6 artifacts (#1741) We need to include the checksum to work around a GnuPG bug where data fails to be decoded if the base64 ends with no padding chars (=) (see https://dev.gnupg.org/T7071). Pure v6 artifacts are unaffected and won't include the checksum, as mandated by the spec. Breaking change: `openpgp.armor` takes an additional `emitChecksum` argument (defaults to false). NB: some types of data must not include the checksum, but compliance is left as responsibility of the caller: this function does not carry out any checks. Refer to the crypto-refresh RFC for more details. --------- Co-authored-by: Daniel Huigens --- openpgp.d.ts | 2 +- src/cleartext.js | 10 ++++++---- src/encoding/armor.js | 24 ++++++++++++++++-------- src/key/key.js | 4 +++- src/key/private_key.js | 4 +++- src/key/public_key.js | 4 +++- src/message.js | 8 +++++++- src/signature.js | 4 +++- test/general/armor.js | 34 ++++++++++++++++++++++++++++++++++ test/general/key.js | 2 +- 10 files changed, 77 insertions(+), 19 deletions(-) diff --git a/openpgp.d.ts b/openpgp.d.ts index 10c8d710..8801d0e3 100644 --- a/openpgp.d.ts +++ b/openpgp.d.ts @@ -735,7 +735,7 @@ export interface VerifyMessageResult = MaybeStream} ASCII armor. */ armor(config = defaultConfig) { - // emit header if one of the signatures has a version not 6 - const emitHeader = this.signature.packets.some(packet => packet.version !== 6); - const hash = emitHeader ? + // emit header and checksum if one of the signatures has a version not 6 + const emitHeaderAndChecksum = this.signature.packets.some(packet => packet.version !== 6); + const hash = emitHeaderAndChecksum ? Array.from(new Set(this.signature.packets.map( packet => enums.read(enums.hash, packet.hashAlgorithm).toUpperCase() ))).join() : @@ -124,7 +124,9 @@ export class CleartextMessage { text: this.text, data: this.signature.packets.write() }; - return armor(enums.armor.signed, body, undefined, undefined, undefined, config); + + // An ASCII-armored sequence of Signature packets that only includes v6 Signature packets MUST NOT contain a CRC24 footer. + return armor(enums.armor.signed, body, undefined, undefined, undefined, emitHeaderAndChecksum, config); } } diff --git a/src/encoding/armor.js b/src/encoding/armor.js index 3820364d..5404d8f6 100644 --- a/src/encoding/armor.js +++ b/src/encoding/armor.js @@ -334,10 +334,13 @@ export function unarmor(input) { * @param {Integer} [partIndex] * @param {Integer} [partTotal] * @param {String} [customComment] - Additional comment to add to the armored string + * @param {Boolean} [emitChecksum] - Whether to compute and include the CRC checksum + * (NB: some types of data must not include it, but compliance is left as responsibility of the caller: this function does not carry out any checks) + * @param {Object} [config] - Full configuration, defaults to openpgp.config * @returns {String | ReadableStream} Armored text. * @static */ -export function armor(messageType, body, partIndex, partTotal, customComment, config = defaultConfig) { +export function armor(messageType, body, partIndex, partTotal, customComment, emitChecksum = false, config = defaultConfig) { let text; let hash; if (messageType === enums.armor.signed) { @@ -345,18 +348,24 @@ export function armor(messageType, body, partIndex, partTotal, customComment, co hash = body.hash; body = body.data; } + // unless explicitly forbidden by the spec, we need to include the checksum to work around a GnuPG bug + // where data fails to be decoded if the base64 ends with no padding chars (=) (see https://dev.gnupg.org/T7071) + const maybeBodyClone = emitChecksum && stream.passiveClone(body); + const result = []; switch (messageType) { case enums.armor.multipartSection: result.push('-----BEGIN PGP MESSAGE, PART ' + partIndex + '/' + partTotal + '-----\n'); result.push(addheader(customComment, config)); result.push(base64.encode(body)); + maybeBodyClone && result.push('=', getCheckSum(maybeBodyClone)); result.push('-----END PGP MESSAGE, PART ' + partIndex + '/' + partTotal + '-----\n'); break; case enums.armor.multipartLast: result.push('-----BEGIN PGP MESSAGE, PART ' + partIndex + '-----\n'); result.push(addheader(customComment, config)); result.push(base64.encode(body)); + maybeBodyClone && result.push('=', getCheckSum(maybeBodyClone)); result.push('-----END PGP MESSAGE, PART ' + partIndex + '-----\n'); break; case enums.armor.signed: @@ -366,38 +375,37 @@ export function armor(messageType, body, partIndex, partTotal, customComment, co result.push('\n-----BEGIN PGP SIGNATURE-----\n'); result.push(addheader(customComment, config)); result.push(base64.encode(body)); + maybeBodyClone && result.push('=', getCheckSum(maybeBodyClone)); result.push('-----END PGP SIGNATURE-----\n'); break; case enums.armor.message: result.push('-----BEGIN PGP MESSAGE-----\n'); result.push(addheader(customComment, config)); result.push(base64.encode(body)); + maybeBodyClone && result.push('=', getCheckSum(maybeBodyClone)); result.push('-----END PGP MESSAGE-----\n'); break; case enums.armor.publicKey: result.push('-----BEGIN PGP PUBLIC KEY BLOCK-----\n'); result.push(addheader(customComment, config)); result.push(base64.encode(body)); + maybeBodyClone && result.push('=', getCheckSum(maybeBodyClone)); result.push('-----END PGP PUBLIC KEY BLOCK-----\n'); break; case enums.armor.privateKey: result.push('-----BEGIN PGP PRIVATE KEY BLOCK-----\n'); result.push(addheader(customComment, config)); result.push(base64.encode(body)); + maybeBodyClone && result.push('=', getCheckSum(maybeBodyClone)); result.push('-----END PGP PRIVATE KEY BLOCK-----\n'); break; - case enums.armor.signature: { - const bodyClone = stream.passiveClone(body); + case enums.armor.signature: result.push('-----BEGIN PGP SIGNATURE-----\n'); result.push(addheader(customComment, config)); result.push(base64.encode(body)); - // GPG v2 fails to parse signatures without checksums - result.push('=', getCheckSum(bodyClone)); + maybeBodyClone && result.push('=', getCheckSum(maybeBodyClone)); result.push('-----END PGP SIGNATURE-----\n'); break; - } - default: - throw new Error('Unknown armor type'); } return util.concat(result); diff --git a/src/key/key.js b/src/key/key.js index 3c7475ad..3964c5eb 100644 --- a/src/key/key.js +++ b/src/key/key.js @@ -612,7 +612,9 @@ class Key { const revocationSignature = await helper.getLatestValidSignature(this.revocationSignatures, this.keyPacket, enums.signature.keyRevocation, dataToVerify, date, config); const packetlist = new PacketList(); packetlist.push(revocationSignature); - return armor(enums.armor.publicKey, packetlist.write(), null, null, 'This is a revocation certificate'); + // An ASCII-armored Transferable Public Key packet sequence of a v6 key MUST NOT contain a CRC24 footer. + const emitChecksum = this.keyPacket.version !== 6; + return armor(enums.armor.publicKey, packetlist.write(), null, null, 'This is a revocation certificate', emitChecksum); } /** diff --git a/src/key/private_key.js b/src/key/private_key.js index 3c6fe474..904c09a0 100644 --- a/src/key/private_key.js +++ b/src/key/private_key.js @@ -64,7 +64,9 @@ class PrivateKey extends PublicKey { * @returns {ReadableStream} ASCII armor. */ armor(config = defaultConfig) { - return armor(enums.armor.privateKey, this.toPacketList().write(), undefined, undefined, undefined, config); + // An ASCII-armored Transferable Public Key packet sequence of a v6 key MUST NOT contain a CRC24 footer. + const emitChecksum = this.keyPacket.version !== 6; + return armor(enums.armor.privateKey, this.toPacketList().write(), undefined, undefined, undefined, emitChecksum, config); } /** diff --git a/src/key/public_key.js b/src/key/public_key.js index 66eac924..7996a32c 100644 --- a/src/key/public_key.js +++ b/src/key/public_key.js @@ -61,7 +61,9 @@ class PublicKey extends Key { * @returns {ReadableStream} ASCII armor. */ armor(config = defaultConfig) { - return armor(enums.armor.publicKey, this.toPacketList().write(), undefined, undefined, undefined, config); + // An ASCII-armored Transferable Public Key packet sequence of a v6 key MUST NOT contain a CRC24 footer. + const emitChecksum = this.keyPacket.version !== 6; + return armor(enums.armor.publicKey, this.toPacketList().write(), undefined, undefined, undefined, emitChecksum, config); } } diff --git a/src/message.js b/src/message.js index 159c003e..113d5623 100644 --- a/src/message.js +++ b/src/message.js @@ -680,7 +680,13 @@ export class Message { * @returns {ReadableStream} ASCII armor. */ armor(config = defaultConfig) { - return armor(enums.armor.message, this.write(), null, null, null, config); + const trailingPacket = this.packets[this.packets.length - 1]; + // An ASCII-armored Encrypted Message packet sequence that ends in an v2 SEIPD packet MUST NOT contain a CRC24 footer. + // An ASCII-armored sequence of Signature packets that only includes v6 Signature packets MUST NOT contain a CRC24 footer. + const emitChecksum = trailingPacket.constructor.tag === SymEncryptedIntegrityProtectedDataPacket.tag ? + trailingPacket.version !== 2 : + this.packets.some(packet => packet.constructor.tag === SignaturePacket.tag && packet.version !== 6); + return armor(enums.armor.message, this.write(), null, null, null, emitChecksum, config); } } diff --git a/src/signature.js b/src/signature.js index ae9e5623..f3e14e85 100644 --- a/src/signature.js +++ b/src/signature.js @@ -49,7 +49,9 @@ export class Signature { * @returns {ReadableStream} ASCII armor. */ armor(config = defaultConfig) { - return armor(enums.armor.signature, this.write(), undefined, undefined, undefined, config); + // An ASCII-armored sequence of Signature packets that only includes v6 Signature packets MUST NOT contain a CRC24 footer. + const emitChecksum = this.packets.some(packet => packet.constructor.tag === SignaturePacket.tag && packet.version !== 6); + return armor(enums.armor.signature, this.write(), undefined, undefined, undefined, emitChecksum, config); } /** diff --git a/test/general/armor.js b/test/general/armor.js index 62773792..01df7c05 100644 --- a/test/general/armor.js +++ b/test/general/armor.js @@ -255,6 +255,40 @@ export default () => describe('ASCII armor', function() { expect(msg.text).to.equal('\r\nsign this'); }); + it('Selectively output CRC checksum', async function () { + const includesArmorChecksum = armoredData => { + const lines = armoredData.split('\n'); + const lastDataLine = lines[lines.length - 3]; + return (lastDataLine[0] === '=' && lastDataLine.length === 5); + }; + + // unless explicitly forbidden by the spec, we include the checksum to work around a GnuPG bug (https://dev.gnupg.org/T7071) + const { privateKey: v4Key } = await openpgp.generateKey({ userIDs: { email: 'v4@armor.test' }, format: 'object' }); + expect(includesArmorChecksum(v4Key.armor())).to.be.true; + const { privateKey: v6Key } = await openpgp.generateKey({ userIDs: { email: 'v6@armor.test' }, config: { v6Keys: true, aeadProtect: true }, format: 'object' }); + expect(includesArmorChecksum(v6Key.armor())).to.be.false; + + const messageWithSEIPDv1 = await openpgp.encrypt({ message: await openpgp.createMessage({ text: 'test' }), encryptionKeys: v4Key }); + expect(includesArmorChecksum(messageWithSEIPDv1)).to.be.true; + const messageWithSEIPDv2 = await openpgp.encrypt({ message: await openpgp.createMessage({ text: 'test' }), encryptionKeys: v6Key }); + expect(includesArmorChecksum(messageWithSEIPDv2)).to.be.false; + + const signatureV4V6 = await openpgp.sign({ message: await openpgp.createMessage({ text: 'test' }), signingKeys: [v4Key, v6Key] }); + expect(includesArmorChecksum(signatureV4V6)).to.be.true; + const signatureV6 = await openpgp.sign({ message: await openpgp.createMessage({ text: 'test' }), signingKeys: v6Key }); + expect(includesArmorChecksum(signatureV6)).to.be.false; + + const detachedSignatureV4V6 = await openpgp.sign({ message: await openpgp.createMessage({ text: 'test' }), signingKeys: [v4Key, v6Key], detached: true }); + expect(includesArmorChecksum(detachedSignatureV4V6)).to.be.true; + const detachedSignatureV6 = await openpgp.sign({ message: await openpgp.createMessage({ text: 'test' }), signingKeys: v6Key, detached: true }); + expect(includesArmorChecksum(detachedSignatureV6)).to.be.false; + + const cleartextSignatureV4V6 = await openpgp.sign({ message: await openpgp.createCleartextMessage({ text: 'test' }), signingKeys: [v4Key, v6Key] }); + expect(includesArmorChecksum(cleartextSignatureV4V6)).to.be.true; + const cleartextSignatureV6 = await openpgp.sign({ message: await openpgp.createCleartextMessage({ text: 'test' }), signingKeys: v6Key }); + expect(includesArmorChecksum(cleartextSignatureV6)).to.be.false; + }); + it('Do not add extraneous blank line when base64 ends on line break', async function () { const pubKey = `-----BEGIN PGP PUBLIC KEY BLOCK----- diff --git a/test/general/key.js b/test/general/key.js index 1060ac87..570671fd 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -4024,7 +4024,7 @@ CNa5yq6lyexhsn2Vs8DsX+SOSUyNJiy5FyIJ const input = await openpgp.unarmor(revocation_certificate_arm4); const packetlist = await openpgp.PacketList.fromBinary(input.data, util.constructAllowedPackets([openpgp.SignaturePacket]), openpgp.config); - const armored = openpgp.armor(openpgp.enums.armor.publicKey, packetlist.write()); + const armored = openpgp.armor(openpgp.enums.armor.publicKey, packetlist.write(), undefined, undefined, undefined, true); expect(revocationCertificate.replace(/^Comment: .*$\n/mg, '')).to.equal(armored.replace(/^Comment: .*$\n/mg, '')); }); From a05c23b507463866153cbd39a93f978453eea932 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Tue, 9 Apr 2024 18:40:51 +0200 Subject: [PATCH 122/201] `Key.getRevocationCertificate()`: apply `config` settings when armoring The `config` input was not passed down to the armor function due to an oversight. --- src/key/key.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/key/key.js b/src/key/key.js index 3964c5eb..d0aaa6b9 100644 --- a/src/key/key.js +++ b/src/key/key.js @@ -614,7 +614,7 @@ class Key { packetlist.push(revocationSignature); // An ASCII-armored Transferable Public Key packet sequence of a v6 key MUST NOT contain a CRC24 footer. const emitChecksum = this.keyPacket.version !== 6; - return armor(enums.armor.publicKey, packetlist.write(), null, null, 'This is a revocation certificate', emitChecksum); + return armor(enums.armor.publicKey, packetlist.write(), null, null, 'This is a revocation certificate', emitChecksum, config); } /** From 9a53ac15df2244619fb2360a14d04270f49a3fa1 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Tue, 9 Apr 2024 18:57:53 +0200 Subject: [PATCH 123/201] Tests: bump Sinon to v17 --- package-lock.json | 55 +++++++++++++++-------------------------------- package.json | 2 +- 2 files changed, 18 insertions(+), 39 deletions(-) diff --git a/package-lock.json b/package-lock.json index 73ddf44d..534e2a6f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -47,7 +47,7 @@ "mocha": "^10.3.0", "playwright": "^1.42.0", "rollup": "^4.12.0", - "sinon": "^15.2.0", + "sinon": "^17.0.1", "ts-node": "^10.9.2", "tsx": "^4.7.1", "typescript": "^5.3.3", @@ -1398,9 +1398,9 @@ } }, "node_modules/@sinonjs/fake-timers": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", + "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", "dev": true, "dependencies": { "@sinonjs/commons": "^3.0.0" @@ -5793,15 +5793,6 @@ "path-to-regexp": "^6.2.1" } }, - "node_modules/nise/node_modules/@sinonjs/fake-timers": { - "version": "11.2.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", - "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^3.0.0" - } - }, "node_modules/normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -6924,17 +6915,16 @@ "dev": true }, "node_modules/sinon": { - "version": "15.2.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.2.0.tgz", - "integrity": "sha512-nPS85arNqwBXaIsFCkolHjGIkFo+Oxu9vbgmBJizLAhqe6P2o3Qmj3KCUoRkfhHtvgDhZdWD3risLHAUJ8npjw==", - "deprecated": "16.1.1", + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.1.tgz", + "integrity": "sha512-wmwE19Lie0MLT+ZYNpDymasPHUKTaZHUH/pKEubRXIzySv9Atnlw+BUMGCzWgV7b7wO+Hw6f1TEOr0IUnmU8/g==", "dev": true, "dependencies": { "@sinonjs/commons": "^3.0.0", - "@sinonjs/fake-timers": "^10.3.0", + "@sinonjs/fake-timers": "^11.2.2", "@sinonjs/samsam": "^8.0.0", "diff": "^5.1.0", - "nise": "^5.1.4", + "nise": "^5.1.5", "supports-color": "^7.2.0" }, "funding": { @@ -9021,9 +9011,9 @@ } }, "@sinonjs/fake-timers": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", + "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", "dev": true, "requires": { "@sinonjs/commons": "^3.0.0" @@ -12434,17 +12424,6 @@ "@sinonjs/text-encoding": "^0.7.2", "just-extend": "^6.2.0", "path-to-regexp": "^6.2.1" - }, - "dependencies": { - "@sinonjs/fake-timers": { - "version": "11.2.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", - "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", - "dev": true, - "requires": { - "@sinonjs/commons": "^3.0.0" - } - } } }, "normalize-package-data": { @@ -13264,16 +13243,16 @@ "dev": true }, "sinon": { - "version": "15.2.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.2.0.tgz", - "integrity": "sha512-nPS85arNqwBXaIsFCkolHjGIkFo+Oxu9vbgmBJizLAhqe6P2o3Qmj3KCUoRkfhHtvgDhZdWD3risLHAUJ8npjw==", + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.1.tgz", + "integrity": "sha512-wmwE19Lie0MLT+ZYNpDymasPHUKTaZHUH/pKEubRXIzySv9Atnlw+BUMGCzWgV7b7wO+Hw6f1TEOr0IUnmU8/g==", "dev": true, "requires": { "@sinonjs/commons": "^3.0.0", - "@sinonjs/fake-timers": "^10.3.0", + "@sinonjs/fake-timers": "^11.2.2", "@sinonjs/samsam": "^8.0.0", "diff": "^5.1.0", - "nise": "^5.1.4", + "nise": "^5.1.5", "supports-color": "^7.2.0" }, "dependencies": { diff --git a/package.json b/package.json index 3a52dff3..669dc61e 100644 --- a/package.json +++ b/package.json @@ -100,7 +100,7 @@ "mocha": "^10.3.0", "playwright": "^1.42.0", "rollup": "^4.12.0", - "sinon": "^15.2.0", + "sinon": "^17.0.1", "ts-node": "^10.9.2", "tsx": "^4.7.1", "typescript": "^5.3.3", From 231fbbe8cadfca6e9fc54b9842320f671e0d5d3a Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Tue, 9 Apr 2024 19:07:58 +0200 Subject: [PATCH 124/201] Run npm update --- package-lock.json | 2269 +++++++++++++++++++-------------------------- package.json | 14 +- 2 files changed, 955 insertions(+), 1328 deletions(-) diff --git a/package-lock.json b/package-lock.json index 534e2a6f..cea84044 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,7 @@ "@rollup/plugin-replace": "^5.0.5", "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-wasm": "^6.2.2", - "@types/chai": "^4.3.12", + "@types/chai": "^4.3.14", "argon2id": "^1.0.1", "benchmark": "^2.1.4", "c8": "^8.0.1", @@ -40,17 +40,17 @@ "karma": "^6.4.3", "karma-browserstack-launcher": "^1.6.0", "karma-chrome-launcher": "^3.2.0", - "karma-firefox-launcher": "^2.1.2", + "karma-firefox-launcher": "^2.1.3", "karma-mocha": "^2.0.1", "karma-mocha-reporter": "^2.2.5", "karma-webkit-launcher": "^2.4.0", - "mocha": "^10.3.0", - "playwright": "^1.42.0", - "rollup": "^4.12.0", + "mocha": "^10.4.0", + "playwright": "^1.43.0", + "rollup": "^4.14.1", "sinon": "^17.0.1", "ts-node": "^10.9.2", - "tsx": "^4.7.1", - "typescript": "^5.3.3", + "tsx": "^4.7.2", + "typescript": "^5.4.4", "web-streams-polyfill": "^3.3.3" }, "engines": { @@ -67,89 +67,18 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", + "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", "dev": true, "dependencies": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" + "@babel/highlight": "^7.24.2", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/code-frame/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/code-frame/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/code-frame/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/helper-validator-identifier": { "version": "7.22.20", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", @@ -160,14 +89,15 @@ } }, "node_modules/@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", + "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.22.20", "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" @@ -245,9 +175,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz", - "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==", + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz", + "integrity": "sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -257,9 +187,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz", - "integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==", + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.4.tgz", + "integrity": "sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==", "dev": true, "peer": true, "dependencies": { @@ -758,101 +688,11 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", - "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", "dev": true }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", @@ -863,14 +703,14 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.4.tgz", - "integrity": "sha512-Oud2QPM5dHviZNn4y/WhhYKSXksv+1xLEIsNrAbGcFzUN3ubqWRFT5gwPchNc5NuzILOU4tPBDTZ4VwhL8Y7cw==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, "dependencies": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" @@ -886,22 +726,22 @@ } }, "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/source-map": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", - "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", "dev": true, "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" } }, "node_modules/@jridgewell/sourcemap-codec": { @@ -911,9 +751,9 @@ "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.23", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.23.tgz", - "integrity": "sha512-9/4foRoUKp8s96tSkh8DlAAc5A0Ty8vLXld+l9gjKKY6ckwI8G15f0hskGmuLZu78ZlGa1vtsfOa+lnB4vG6Jg==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -1054,16 +894,6 @@ } } }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "optional": true, - "engines": { - "node": ">=14" - } - }, "node_modules/@rollup/plugin-alias": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.1.0.tgz", @@ -1220,9 +1050,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.12.0.tgz", - "integrity": "sha512-+ac02NL/2TCKRrJu2wffk1kZ+RyqxVUlbjSagNgPm94frxtr+XDL12E5Ll1enWskLrtrZ2r8L3wED1orIibV/w==", + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.14.1.tgz", + "integrity": "sha512-fH8/o8nSUek8ceQnT7K4EQbSiV7jgkHq81m9lWZFIXjJ7lJzpWXbQFpT/Zh6OZYnpFykvzC3fbEvEAFZu03dPA==", "cpu": [ "arm" ], @@ -1233,9 +1063,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.12.0.tgz", - "integrity": "sha512-OBqcX2BMe6nvjQ0Nyp7cC90cnumt8PXmO7Dp3gfAju/6YwG0Tj74z1vKrfRz7qAv23nBcYM8BCbhrsWqO7PzQQ==", + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.14.1.tgz", + "integrity": "sha512-Y/9OHLjzkunF+KGEoJr3heiD5X9OLa8sbT1lm0NYeKyaM3oMhhQFvPB0bNZYJwlq93j8Z6wSxh9+cyKQaxS7PQ==", "cpu": [ "arm64" ], @@ -1246,9 +1076,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.12.0.tgz", - "integrity": "sha512-X64tZd8dRE/QTrBIEs63kaOBG0b5GVEd3ccoLtyf6IdXtHdh8h+I56C2yC3PtC9Ucnv0CpNFJLqKFVgCYe0lOQ==", + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.14.1.tgz", + "integrity": "sha512-+kecg3FY84WadgcuSVm6llrABOdQAEbNdnpi5X3UwWiFVhZIZvKgGrF7kmLguvxHNQy+UuRV66cLVl3S+Rkt+Q==", "cpu": [ "arm64" ], @@ -1259,9 +1089,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.12.0.tgz", - "integrity": "sha512-cc71KUZoVbUJmGP2cOuiZ9HSOP14AzBAThn3OU+9LcA1+IUqswJyR1cAJj3Mg55HbjZP6OLAIscbQsQLrpgTOg==", + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.14.1.tgz", + "integrity": "sha512-2pYRzEjVqq2TB/UNv47BV/8vQiXkFGVmPFwJb+1E0IFFZbIX8/jo1olxqqMbo6xCXf8kabANhp5bzCij2tFLUA==", "cpu": [ "x64" ], @@ -1272,9 +1102,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.12.0.tgz", - "integrity": "sha512-a6w/Y3hyyO6GlpKL2xJ4IOh/7d+APaqLYdMf86xnczU3nurFTaVN9s9jOXQg97BE4nYm/7Ga51rjec5nfRdrvA==", + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.14.1.tgz", + "integrity": "sha512-mS6wQ6Do6/wmrF9aTFVpIJ3/IDXhg1EZcQFYHZLHqw6AzMBjTHWnCG35HxSqUNphh0EHqSM6wRTT8HsL1C0x5g==", "cpu": [ "arm" ], @@ -1285,9 +1115,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.12.0.tgz", - "integrity": "sha512-0fZBq27b+D7Ar5CQMofVN8sggOVhEtzFUwOwPppQt0k+VR+7UHMZZY4y+64WJ06XOhBTKXtQB/Sv0NwQMXyNAA==", + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.14.1.tgz", + "integrity": "sha512-p9rGKYkHdFMzhckOTFubfxgyIO1vw//7IIjBBRVzyZebWlzRLeNhqxuSaZ7kCEKVkm/kuC9fVRW9HkC/zNRG2w==", "cpu": [ "arm64" ], @@ -1298,9 +1128,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.12.0.tgz", - "integrity": "sha512-eTvzUS3hhhlgeAv6bfigekzWZjaEX9xP9HhxB0Dvrdbkk5w/b+1Sxct2ZuDxNJKzsRStSq1EaEkVSEe7A7ipgQ==", + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.14.1.tgz", + "integrity": "sha512-nDY6Yz5xS/Y4M2i9JLQd3Rofh5OR8Bn8qe3Mv/qCVpHFlwtZSBYSPaU4mrGazWkXrdQ98GB//H0BirGR/SKFSw==", "cpu": [ "arm64" ], @@ -1310,10 +1140,23 @@ "linux" ] }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.14.1.tgz", + "integrity": "sha512-im7HE4VBL+aDswvcmfx88Mp1soqL9OBsdDBU8NqDEYtkri0qV0THhQsvZtZeNNlLeCUQ16PZyv7cqutjDF35qw==", + "cpu": [ + "ppc64le" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.12.0.tgz", - "integrity": "sha512-ix+qAB9qmrCRiaO71VFfY8rkiAZJL8zQRXveS27HS+pKdjwUfEhqo2+YF2oI+H/22Xsiski+qqwIBxVewLK7sw==", + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.14.1.tgz", + "integrity": "sha512-RWdiHuAxWmzPJgaHJdpvUUlDz8sdQz4P2uv367T2JocdDa98iRw2UjIJ4QxSyt077mXZT2X6pKfT2iYtVEvOFw==", "cpu": [ "riscv64" ], @@ -1323,10 +1166,23 @@ "linux" ] }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.14.1.tgz", + "integrity": "sha512-VMgaGQ5zRX6ZqV/fas65/sUGc9cPmsntq2FiGmayW9KMNfWVG/j0BAqImvU4KTeOOgYSf1F+k6at1UfNONuNjA==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.12.0.tgz", - "integrity": "sha512-TenQhZVOtw/3qKOPa7d+QgkeM6xY0LtwzR8OplmyL5LrgTWIXpTQg2Q2ycBf8jm+SFW2Wt/DTn1gf7nFp3ssVA==", + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.14.1.tgz", + "integrity": "sha512-9Q7DGjZN+hTdJomaQ3Iub4m6VPu1r94bmK2z3UeWP3dGUecRC54tmVu9vKHTm1bOt3ASoYtEz6JSRLFzrysKlA==", "cpu": [ "x64" ], @@ -1337,9 +1193,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.12.0.tgz", - "integrity": "sha512-LfFdRhNnW0zdMvdCb5FNuWlls2WbbSridJvxOvYWgSBOYZtgBfW9UGNJG//rwMqTX1xQE9BAodvMH9tAusKDUw==", + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.14.1.tgz", + "integrity": "sha512-JNEG/Ti55413SsreTguSx0LOVKX902OfXIKVg+TCXO6Gjans/k9O6ww9q3oLGjNDaTLxM+IHFMeXy/0RXL5R/g==", "cpu": [ "x64" ], @@ -1350,9 +1206,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.12.0.tgz", - "integrity": "sha512-JPDxovheWNp6d7AHCgsUlkuCKvtu3RB55iNEkaQcf0ttsDU/JZF+iQnYcQJSk/7PtT4mjjVG8N1kpwnI9SLYaw==", + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.14.1.tgz", + "integrity": "sha512-ryS22I9y0mumlLNwDFYZRDFLwWh3aKaC72CWjFcFvxK0U6v/mOkM5Up1bTbCRAhv3kEIwW2ajROegCIQViUCeA==", "cpu": [ "arm64" ], @@ -1363,9 +1219,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.12.0.tgz", - "integrity": "sha512-fjtuvMWRGJn1oZacG8IPnzIV6GF2/XG+h71FKn76OYFqySXInJtseAqdprVTDTyqPxQOG9Exak5/E9Z3+EJ8ZA==", + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.14.1.tgz", + "integrity": "sha512-TdloItiGk+T0mTxKx7Hp279xy30LspMso+GzQvV2maYePMAWdmrzqSNZhUpPj3CGw12aGj57I026PgLCTu8CGg==", "cpu": [ "ia32" ], @@ -1376,9 +1232,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.12.0.tgz", - "integrity": "sha512-ZYmr5mS2wd4Dew/JjT0Fqi2NPB/ZhZ2VvPp7SmvPZb4Y1CG/LRcS6tcRo2cYU7zLK5A7cdbhWnnWmUjoI4qapg==", + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.14.1.tgz", + "integrity": "sha512-wQGI+LY/Py20zdUPq+XCem7JcPOyzIJBm3dli+56DJsQOHbnXZFEwgmnC6el1TPAfC8lBT3m+z69RmLykNUbew==", "cpu": [ "x64" ], @@ -1439,9 +1295,9 @@ "dev": true }, "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", "dev": true }, "node_modules/@tsconfig/node12": { @@ -1472,9 +1328,9 @@ } }, "node_modules/@types/chai": { - "version": "4.3.12", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.12.tgz", - "integrity": "sha512-zNKDHG/1yxm8Il6uCCVsm+dRdEsJlFoDu73X17y09bId6UwoYww+vFBsAcRzl8knM1sab3Dp1VRikFQwDOtDDw==", + "version": "4.3.14", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.14.tgz", + "integrity": "sha512-Wj71sXE4Q4AkGdG9Tvq1u/fquNz9EdG4LIJMwVVII7ashjD/8cf8fyIfJAjRr6YcsXnSE8cOGQPq1gqeR8z+3w==", "dev": true }, "node_modules/@types/cookie": { @@ -1533,9 +1389,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.11.21", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.21.tgz", - "integrity": "sha512-/ySDLGscFPNasfqStUuWWPfL78jompfIoVzLJPVVAHBh6rpG68+pI2Gk+fNLeI8/f1yPYL4s46EleVIc20F1Ow==", + "version": "20.12.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.6.tgz", + "integrity": "sha512-3KurE8taB8GCvZBPngVbp0lk5CKi8M9f9k1rsADh0Evdz5SzJ+Q+Hx9uHoFGsLnLnd1xmkDQr2hVhlA0Mn0lKQ==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -1721,15 +1577,16 @@ } }, "node_modules/array-includes": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", - "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", "is-string": "^1.0.7" }, "engines": { @@ -1739,17 +1596,19 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array.prototype.filter": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array.prototype.filter/-/array.prototype.filter-1.0.3.tgz", - "integrity": "sha512-VizNcj/RGJiUyQBgzwxzE5oHdeuXY5hSbbmKMlphj1cy1Vl7Pn2asCGbSrru6hSQjmCzqTBPVWAF/whmEOVHbw==", + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", "dev": true, + "peer": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-array-method-boxes-properly": "^1.0.0", - "is-string": "^1.0.7" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -1759,15 +1618,16 @@ } }, "node_modules/array.prototype.findlastindex": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.4.tgz", - "integrity": "sha512-hzvSHUshSpCflDR1QMUBLHGHP1VIEBegT4pix9H/Z92Xw3ySoy6c2qh7lJWTJnRJ8JCZ9bJNCgTyYaJGcJu6xQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.5", + "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", + "es-abstract": "^1.23.2", "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", "es-shim-unscopables": "^1.0.2" }, "engines": { @@ -1813,6 +1673,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/array.prototype.toreversed": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz", + "integrity": "sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==", + "dev": true, + "peer": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + } + }, "node_modules/array.prototype.tosorted": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.3.tgz", @@ -1874,16 +1747,6 @@ "lodash": "^4.17.14" } }, - "node_modules/asynciterator.prototype": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz", - "integrity": "sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==", - "dev": true, - "peer": true, - "dependencies": { - "has-symbols": "^1.0.3" - } - }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", @@ -1957,12 +1820,15 @@ } }, "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/bluebird": { @@ -2485,6 +2351,57 @@ "dev": true, "peer": true }, + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/date-format": { "version": "4.0.14", "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", @@ -2658,12 +2575,6 @@ "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", "dev": true }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true - }, "node_modules/eckey-utils": { "version": "0.7.14", "resolved": "https://registry.npmjs.org/eckey-utils/-/eckey-utils-0.7.14.tgz", @@ -2680,7 +2591,8 @@ "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true + "dev": true, + "peer": true }, "node_modules/encodeurl": { "version": "1.0.2", @@ -2746,18 +2658,22 @@ } }, "node_modules/es-abstract": { - "version": "1.22.4", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.4.tgz", - "integrity": "sha512-vZYJlk2u6qHYxBOTjAeg7qUxHdNfih64Uu2J8QqWgXZ2cri0ZpJAkzDUK/q593+mvKwlxyaxr6F1Q+3LKoQRgg==", + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", "dev": true, "dependencies": { "array-buffer-byte-length": "^1.0.1", "arraybuffer.prototype.slice": "^1.0.3", - "available-typed-arrays": "^1.0.6", + "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", "es-define-property": "^1.0.0", "es-errors": "^1.3.0", - "es-set-tostringtag": "^2.0.2", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", "es-to-primitive": "^1.2.1", "function.prototype.name": "^1.1.6", "get-intrinsic": "^1.2.4", @@ -2765,15 +2681,16 @@ "globalthis": "^1.0.3", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.1", + "has-proto": "^1.0.3", "has-symbols": "^1.0.3", - "hasown": "^2.0.1", + "hasown": "^2.0.2", "internal-slot": "^1.0.7", "is-array-buffer": "^3.0.4", "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", + "is-shared-array-buffer": "^1.0.3", "is-string": "^1.0.7", "is-typed-array": "^1.1.13", "is-weakref": "^1.0.2", @@ -2781,17 +2698,17 @@ "object-keys": "^1.1.1", "object.assign": "^4.1.5", "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.0", + "safe-array-concat": "^1.1.2", "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.8", - "string.prototype.trimend": "^1.0.7", - "string.prototype.trimstart": "^1.0.7", - "typed-array-buffer": "^1.0.1", - "typed-array-byte-length": "^1.0.0", - "typed-array-byte-offset": "^1.0.0", - "typed-array-length": "^1.0.4", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.14" + "which-typed-array": "^1.1.15" }, "engines": { "node": ">= 0.4" @@ -2800,12 +2717,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-array-method-boxes-properly": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", - "dev": true - }, "node_modules/es-define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", @@ -2828,27 +2739,38 @@ } }, "node_modules/es-iterator-helpers": { - "version": "1.0.17", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.17.tgz", - "integrity": "sha512-lh7BsUqelv4KUbR5a/ZTaGGIMLCjPGPqJ6q+Oq24YP0RdyptX1uzm4vvaqzk7Zx3bpl/76YLTTDj9L7uYQ92oQ==", + "version": "1.0.18", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.18.tgz", + "integrity": "sha512-scxAJaewsahbqTYrGKJihhViaM6DDZDDoucfvzNbK0pOren1g/daDQ3IAhzn+1G14rBG7w+i5N+qul60++zlKA==", "dev": true, "peer": true, "dependencies": { - "asynciterator.prototype": "^1.0.0", "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.22.4", + "es-abstract": "^1.23.0", "es-errors": "^1.3.0", - "es-set-tostringtag": "^2.0.2", + "es-set-tostringtag": "^2.0.3", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "globalthis": "^1.0.3", "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.1", + "has-proto": "^1.0.3", "has-symbols": "^1.0.3", "internal-slot": "^1.0.7", "iterator.prototype": "^1.1.2", - "safe-array-concat": "^1.1.0" + "safe-array-concat": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" }, "engines": { "node": ">= 0.4" @@ -3208,28 +3130,30 @@ } }, "node_modules/eslint-plugin-react": { - "version": "7.33.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz", - "integrity": "sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==", + "version": "7.34.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.1.tgz", + "integrity": "sha512-N97CxlouPT1AHt8Jn0mhhN2RrADlUAsk1/atcT2KyA/l9Q/E6ll7OIGwNumFmWfZ9skV3XXccYS19h80rHtgkw==", "dev": true, "peer": true, "dependencies": { - "array-includes": "^3.1.6", - "array.prototype.flatmap": "^1.3.1", - "array.prototype.tosorted": "^1.1.1", + "array-includes": "^3.1.7", + "array.prototype.findlast": "^1.2.4", + "array.prototype.flatmap": "^1.3.2", + "array.prototype.toreversed": "^1.1.2", + "array.prototype.tosorted": "^1.1.3", "doctrine": "^2.1.0", - "es-iterator-helpers": "^1.0.12", + "es-iterator-helpers": "^1.0.17", "estraverse": "^5.3.0", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", - "object.entries": "^1.1.6", - "object.fromentries": "^2.0.6", - "object.hasown": "^1.1.2", - "object.values": "^1.1.6", + "object.entries": "^1.1.7", + "object.fromentries": "^2.0.7", + "object.hasown": "^1.1.3", + "object.values": "^1.1.7", "prop-types": "^15.8.1", - "resolve": "^2.0.0-next.4", + "resolve": "^2.0.0-next.5", "semver": "^6.3.1", - "string.prototype.matchall": "^4.0.8" + "string.prototype.matchall": "^4.0.10" }, "engines": { "node": ">=4" @@ -3609,9 +3533,9 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", - "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "dev": true, "funding": [ { @@ -3781,9 +3705,9 @@ } }, "node_modules/get-tsconfig": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.2.tgz", - "integrity": "sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==", + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz", + "integrity": "sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==", "dev": true, "dependencies": { "resolve-pkg-maps": "^1.0.0" @@ -3974,9 +3898,9 @@ } }, "node_modules/hasown": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", - "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, "dependencies": { "function-bind": "^1.1.2" @@ -4332,6 +4256,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dev": true, + "dependencies": { + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-date-object": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", @@ -4422,11 +4361,14 @@ } }, "node_modules/is-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", - "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", "dev": true, "peer": true, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -4523,11 +4465,14 @@ "dev": true }, "node_modules/is-set": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", - "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", "dev": true, "peer": true, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -4605,11 +4550,14 @@ } }, "node_modules/is-weakmap": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", - "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", "dev": true, "peer": true, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -4627,14 +4575,17 @@ } }, "node_modules/is-weakset": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", - "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", + "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", "dev": true, "peer": true, "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4726,24 +4677,6 @@ "set-function-name": "^2.0.1" } }, - "node_modules/jackspeak": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", - "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", - "dev": true, - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -4924,13 +4857,28 @@ } }, "node_modules/karma-firefox-launcher": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-2.1.2.tgz", - "integrity": "sha512-VV9xDQU1QIboTrjtGVD4NCfzIH7n01ZXqy/qpBhnOeGVOkG5JYPEm8kuSd7psHE6WouZaQ9Ool92g8LFweSNMA==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-2.1.3.tgz", + "integrity": "sha512-LMM2bseebLbYjODBOVt7TCPP9OI2vZIXCavIXhkO9m+10Uj5l7u/SKoeRmYx8FYHTVGZSpk6peX+3BMHC1WwNw==", "dev": true, "dependencies": { "is-wsl": "^2.2.0", - "which": "^2.0.1" + "which": "^3.0.0" + } + }, + "node_modules/karma-firefox-launcher/node_modules/which": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", + "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/karma-mocha": { @@ -5378,9 +5326,9 @@ } }, "node_modules/magic-string": { - "version": "0.30.7", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.7.tgz", - "integrity": "sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==", + "version": "0.30.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.9.tgz", + "integrity": "sha512-S1+hd+dIrC8EZqKyT9DstTH/0Z+f76kmmvZnkfQVmOpDEF9iVgdYif3Q/pIWHmCoo59bQVGW0kVL3e2nl+9+Sw==", "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" @@ -5547,15 +5495,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", - "dev": true, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, "node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -5569,9 +5508,9 @@ } }, "node_modules/mocha": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.3.0.tgz", - "integrity": "sha512-uF2XJs+7xSLsrmIvn37i/wnc91nw7XjOQB8ccyx5aEgdnohr7n+rEiZP23WkCYHjilR6+EboEnbq/ZQDz4LSbg==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.4.0.tgz", + "integrity": "sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA==", "dev": true, "dependencies": { "ansi-colors": "4.1.1", @@ -5869,28 +5808,29 @@ } }, "node_modules/object.entries": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz", - "integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", + "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/object.fromentries": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", - "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -5900,41 +5840,46 @@ } }, "node_modules/object.groupby": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.2.tgz", - "integrity": "sha512-bzBq58S+x+uo0VjurFT0UktpKHOZmv4/xePiOA1nbB9pMqpGK7rUPNgf+1YC+7mE+0HzhTMqNUuCqvKhj6FnBw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", "dev": true, "dependencies": { - "array.prototype.filter": "^1.0.3", - "call-bind": "^1.0.5", + "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.0.0" + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/object.hasown": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.3.tgz", - "integrity": "sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.4.tgz", + "integrity": "sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==", "dev": true, "peer": true, "dependencies": { - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object.values": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", - "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -6101,35 +6046,10 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, - "node_modules/path-scurry": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", - "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", - "dev": true, - "dependencies": { - "lru-cache": "^9.1.1 || ^10.0.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", - "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", - "dev": true, - "engines": { - "node": "14 || >=16.14" - } - }, "node_modules/path-to-regexp": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", - "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", + "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", "dev": true }, "node_modules/pathval": { @@ -6150,6 +6070,12 @@ "through": "~2.3" } }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -6169,12 +6095,12 @@ "dev": true }, "node_modules/playwright": { - "version": "1.42.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.42.0.tgz", - "integrity": "sha512-Ko7YRUgj5xBHbntrgt4EIw/nE//XBHOKVKnBjO1KuZkmkhlbgyggTe5s9hjqQ1LpN+Xg+kHsQyt5Pa0Bw5XpvQ==", + "version": "1.43.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.43.0.tgz", + "integrity": "sha512-SiOKHbVjTSf6wHuGCbqrEyzlm6qvXcv7mENP+OZon1I07brfZLGdfWV0l/efAzVx7TF3Z45ov1gPEkku9q25YQ==", "dev": true, "dependencies": { - "playwright-core": "1.42.0" + "playwright-core": "1.43.0" }, "bin": { "playwright": "cli.js" @@ -6187,9 +6113,9 @@ } }, "node_modules/playwright-core": { - "version": "1.42.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.42.0.tgz", - "integrity": "sha512-0HD9y8qEVlcbsAjdpBaFjmaTHf+1FeIddy8VJLeiqwhcNqGCBe4Wp2e8knpqiYbzxtxarxiXyNDw2cG8sCaNMQ==", + "version": "1.43.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.43.0.tgz", + "integrity": "sha512-iWFjyBUH97+pUFiyTqSLd8cDMMOS0r2ZYz2qEsPjH8/bX++sbIJT35MSwKnp1r/OQBAqC5XO99xFbJ9XClhf4w==", "dev": true, "bin": { "playwright-core": "cli.js" @@ -6519,17 +6445,17 @@ } }, "node_modules/reflect.getprototypeof": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.5.tgz", - "integrity": "sha512-62wgfC8dJWrmxv44CA36pLDnP6KKl3Vhxb7PL+8+qrrFMMoJij4vgiMP8zV4O8+CBMXY1mHxI5fITGHXFHVmQQ==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", + "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", "dev": true, "peer": true, "dependencies": { - "call-bind": "^1.0.5", + "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.0.0", - "get-intrinsic": "^1.2.3", + "es-abstract": "^1.23.1", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", "globalthis": "^1.0.3", "which-builtin-type": "^1.1.3" }, @@ -6706,9 +6632,9 @@ } }, "node_modules/rollup": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.12.0.tgz", - "integrity": "sha512-wz66wn4t1OHIJw3+XU7mJJQV/2NAfw5OAk6G6Hoo3zcvz/XOfQ52Vgi+AN4Uxoxi0KBBwk2g8zPrTDA4btSB/Q==", + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.14.1.tgz", + "integrity": "sha512-4LnHSdd3QK2pa1J6dFbfm1HN0D7vSK/ZuZTsdyUAlA6Rr1yTouUTL13HaDOGJVgby461AhrNGBS7sCGXXtT+SA==", "dev": true, "dependencies": { "@types/estree": "1.0.5" @@ -6721,19 +6647,21 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.12.0", - "@rollup/rollup-android-arm64": "4.12.0", - "@rollup/rollup-darwin-arm64": "4.12.0", - "@rollup/rollup-darwin-x64": "4.12.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.12.0", - "@rollup/rollup-linux-arm64-gnu": "4.12.0", - "@rollup/rollup-linux-arm64-musl": "4.12.0", - "@rollup/rollup-linux-riscv64-gnu": "4.12.0", - "@rollup/rollup-linux-x64-gnu": "4.12.0", - "@rollup/rollup-linux-x64-musl": "4.12.0", - "@rollup/rollup-win32-arm64-msvc": "4.12.0", - "@rollup/rollup-win32-ia32-msvc": "4.12.0", - "@rollup/rollup-win32-x64-msvc": "4.12.0", + "@rollup/rollup-android-arm-eabi": "4.14.1", + "@rollup/rollup-android-arm64": "4.14.1", + "@rollup/rollup-darwin-arm64": "4.14.1", + "@rollup/rollup-darwin-x64": "4.14.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.14.1", + "@rollup/rollup-linux-arm64-gnu": "4.14.1", + "@rollup/rollup-linux-arm64-musl": "4.14.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.14.1", + "@rollup/rollup-linux-riscv64-gnu": "4.14.1", + "@rollup/rollup-linux-s390x-gnu": "4.14.1", + "@rollup/rollup-linux-x64-gnu": "4.14.1", + "@rollup/rollup-linux-x64-musl": "4.14.1", + "@rollup/rollup-win32-arm64-msvc": "4.14.1", + "@rollup/rollup-win32-ia32-msvc": "4.14.1", + "@rollup/rollup-win32-x64-msvc": "4.14.1", "fsevents": "~2.3.2" } }, @@ -6761,13 +6689,13 @@ } }, "node_modules/safe-array-concat": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.0.tgz", - "integrity": "sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", "dev": true, "dependencies": { - "call-bind": "^1.0.5", - "get-intrinsic": "^1.2.2", + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", "has-symbols": "^1.0.3", "isarray": "^2.0.5" }, @@ -6832,17 +6760,17 @@ } }, "node_modules/set-function-length": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", - "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dev": true, "dependencies": { - "define-data-property": "^1.1.2", + "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.3", + "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.1" + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -6891,12 +6819,12 @@ } }, "node_modules/side-channel": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.5.tgz", - "integrity": "sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "dev": true, "dependencies": { - "call-bind": "^1.0.6", + "call-bind": "^1.0.7", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.4", "object-inspect": "^1.13.1" @@ -6954,15 +6882,15 @@ } }, "node_modules/smob": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/smob/-/smob-1.4.1.tgz", - "integrity": "sha512-9LK+E7Hv5R9u4g4C3p+jjLstaLe11MDsL21UpYaCNmapvMkYhqCV4A/f/3gyH8QjMyh6l68q9xC85vihY9ahMQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz", + "integrity": "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==", "dev": true }, "node_modules/socket.io": { - "version": "4.7.4", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.4.tgz", - "integrity": "sha512-DcotgfP1Zg9iP/dH9zvAQcWrE0TtbMVwXmlV4T4mqsvY+gw+LqUGPfx2AoVyRk0FLME+GQhufDMyacFmw7ksqw==", + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz", + "integrity": "sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==", "dev": true, "dependencies": { "accepts": "~1.3.4", @@ -7109,27 +7037,6 @@ "node": ">=8" } }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, "node_modules/string-width/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -7137,35 +7044,42 @@ "dev": true }, "node_modules/string.prototype.matchall": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz", - "integrity": "sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==", + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", + "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", "dev": true, "peer": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", "has-symbols": "^1.0.3", - "internal-slot": "^1.0.5", - "regexp.prototype.flags": "^1.5.0", - "set-function-name": "^2.0.0", - "side-channel": "^1.0.4" + "internal-slot": "^1.0.7", + "regexp.prototype.flags": "^1.5.2", + "set-function-name": "^2.0.2", + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trim": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", - "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -7175,28 +7089,31 @@ } }, "node_modules/string.prototype.trimend": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", - "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimstart": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", - "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -7214,19 +7131,6 @@ "node": ">=8" } }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -7335,9 +7239,9 @@ } }, "node_modules/terser": { - "version": "5.28.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.28.1.tgz", - "integrity": "sha512-wM+bZp54v/E9eRRGXb5ZFDvinrJIOaTapx3WUokyVGZu5ucVCK55zEgGd5Dl2fSr3jUo5sDiERErUWLY6QPFyA==", + "version": "5.30.3", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.30.3.tgz", + "integrity": "sha512-STdUgOUx8rLbMGO9IOwHLpCqolkDITFFQSMYYwKE1N2lY6MVSaeoi10z/EhWxRc6ybqoVmKSkhKYH/XUpl7vSA==", "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -7405,107 +7309,12 @@ "dev": true }, "node_modules/tmp": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.2.tgz", - "integrity": "sha512-ETcvHhaIc9J2MDEAH6N67j9bvBvu/3Gb764qaGhwtFvjtvhegqoqSpofgeyq1Sc24mW5pdyUDs9HP5j3ehkxRw==", - "dev": true, - "dependencies": { - "rimraf": "^5.0.5" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/tmp/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/tmp/node_modules/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/tmp/node_modules/glob": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", - "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", - "dev": true, - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/tmp/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/tmp/node_modules/rimraf": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", - "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", - "dev": true, - "dependencies": { - "glob": "^10.3.7" - }, - "bin": { - "rimraf": "dist/esm/bin.mjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/tmp/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", "dev": true, "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=14.14" } }, "node_modules/to-regex-range": { @@ -7594,9 +7403,9 @@ } }, "node_modules/tsx": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.1.tgz", - "integrity": "sha512-8d6VuibXHtlN5E3zFkgY8u4DX7Y3Z27zvvPKVmLon/D4AjuKzarkUBTLDBgj9iTQ0hg5xM7c/mYiRVM+HETf0g==", + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.2.tgz", + "integrity": "sha512-BCNd4kz6fz12fyrgCTEdZHGJ9fWTGeUzXmQysh0RVocDY3h4frk05ZNCXSy4kIenF7y/QnrdiVpTsyNRn6vlAw==", "dev": true, "dependencies": { "esbuild": "~0.19.10", @@ -7712,9 +7521,9 @@ } }, "node_modules/typed-array-length": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.5.tgz", - "integrity": "sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", "dev": true, "dependencies": { "call-bind": "^1.0.7", @@ -7732,9 +7541,9 @@ } }, "node_modules/typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.4.tgz", + "integrity": "sha512-dGE2Vv8cpVvw28v8HCPqyb08EzbBURxDpuhJvTrusShUfGnhHBafDsLdS1EhhxyL6BJQE+2cT3dDPAv+MQ6oLw==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -8007,32 +7816,35 @@ } }, "node_modules/which-collection": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", - "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", "dev": true, "peer": true, "dependencies": { - "is-map": "^2.0.1", - "is-set": "^2.0.1", - "is-weakmap": "^2.0.1", - "is-weakset": "^2.0.1" + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/which-typed-array": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.14.tgz", - "integrity": "sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", "dev": true, "dependencies": { - "available-typed-arrays": "^1.0.6", - "call-bind": "^1.0.5", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-tostringtag": "^1.0.1" + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -8064,24 +7876,6 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -8202,71 +7996,13 @@ "dev": true }, "@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", + "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", "dev": true, "requires": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "@babel/highlight": "^7.24.2", + "picocolors": "^1.0.0" } }, "@babel/helper-validator-identifier": { @@ -8276,14 +8012,15 @@ "dev": true }, "@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", + "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.22.20", "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "dependencies": { "ansi-styles": { @@ -8345,15 +8082,15 @@ } }, "@babel/parser": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz", - "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==", + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz", + "integrity": "sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==", "dev": true }, "@babel/runtime": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz", - "integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==", + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.4.tgz", + "integrity": "sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==", "dev": true, "peer": true, "requires": { @@ -8610,70 +8347,11 @@ "dev": true }, "@humanwhocodes/object-schema": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", - "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", "dev": true }, - "@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "requires": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true - }, - "ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true - }, - "string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "requires": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - } - }, - "strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "requires": { - "ansi-regex": "^6.0.1" - } - }, - "wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "requires": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - } - } - } - }, "@istanbuljs/schema": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", @@ -8681,14 +8359,14 @@ "dev": true }, "@jridgewell/gen-mapping": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.4.tgz", - "integrity": "sha512-Oud2QPM5dHviZNn4y/WhhYKSXksv+1xLEIsNrAbGcFzUN3ubqWRFT5gwPchNc5NuzILOU4tPBDTZ4VwhL8Y7cw==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, "requires": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" } }, "@jridgewell/resolve-uri": { @@ -8698,19 +8376,19 @@ "dev": true }, "@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true }, "@jridgewell/source-map": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", - "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", "dev": true, "requires": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" } }, "@jridgewell/sourcemap-codec": { @@ -8720,9 +8398,9 @@ "dev": true }, "@jridgewell/trace-mapping": { - "version": "0.3.23", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.23.tgz", - "integrity": "sha512-9/4foRoUKp8s96tSkh8DlAAc5A0Ty8vLXld+l9gjKKY6ckwI8G15f0hskGmuLZu78ZlGa1vtsfOa+lnB4vG6Jg==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, "requires": { "@jridgewell/resolve-uri": "^3.1.0", @@ -8825,13 +8503,6 @@ "dev": true, "requires": {} }, - "@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "optional": true - }, "@rollup/plugin-alias": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.1.0.tgz", @@ -8911,93 +8582,107 @@ } }, "@rollup/rollup-android-arm-eabi": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.12.0.tgz", - "integrity": "sha512-+ac02NL/2TCKRrJu2wffk1kZ+RyqxVUlbjSagNgPm94frxtr+XDL12E5Ll1enWskLrtrZ2r8L3wED1orIibV/w==", + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.14.1.tgz", + "integrity": "sha512-fH8/o8nSUek8ceQnT7K4EQbSiV7jgkHq81m9lWZFIXjJ7lJzpWXbQFpT/Zh6OZYnpFykvzC3fbEvEAFZu03dPA==", "dev": true, "optional": true }, "@rollup/rollup-android-arm64": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.12.0.tgz", - "integrity": "sha512-OBqcX2BMe6nvjQ0Nyp7cC90cnumt8PXmO7Dp3gfAju/6YwG0Tj74z1vKrfRz7qAv23nBcYM8BCbhrsWqO7PzQQ==", + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.14.1.tgz", + "integrity": "sha512-Y/9OHLjzkunF+KGEoJr3heiD5X9OLa8sbT1lm0NYeKyaM3oMhhQFvPB0bNZYJwlq93j8Z6wSxh9+cyKQaxS7PQ==", "dev": true, "optional": true }, "@rollup/rollup-darwin-arm64": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.12.0.tgz", - "integrity": "sha512-X64tZd8dRE/QTrBIEs63kaOBG0b5GVEd3ccoLtyf6IdXtHdh8h+I56C2yC3PtC9Ucnv0CpNFJLqKFVgCYe0lOQ==", + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.14.1.tgz", + "integrity": "sha512-+kecg3FY84WadgcuSVm6llrABOdQAEbNdnpi5X3UwWiFVhZIZvKgGrF7kmLguvxHNQy+UuRV66cLVl3S+Rkt+Q==", "dev": true, "optional": true }, "@rollup/rollup-darwin-x64": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.12.0.tgz", - "integrity": "sha512-cc71KUZoVbUJmGP2cOuiZ9HSOP14AzBAThn3OU+9LcA1+IUqswJyR1cAJj3Mg55HbjZP6OLAIscbQsQLrpgTOg==", + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.14.1.tgz", + "integrity": "sha512-2pYRzEjVqq2TB/UNv47BV/8vQiXkFGVmPFwJb+1E0IFFZbIX8/jo1olxqqMbo6xCXf8kabANhp5bzCij2tFLUA==", "dev": true, "optional": true }, "@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.12.0.tgz", - "integrity": "sha512-a6w/Y3hyyO6GlpKL2xJ4IOh/7d+APaqLYdMf86xnczU3nurFTaVN9s9jOXQg97BE4nYm/7Ga51rjec5nfRdrvA==", + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.14.1.tgz", + "integrity": "sha512-mS6wQ6Do6/wmrF9aTFVpIJ3/IDXhg1EZcQFYHZLHqw6AzMBjTHWnCG35HxSqUNphh0EHqSM6wRTT8HsL1C0x5g==", "dev": true, "optional": true }, "@rollup/rollup-linux-arm64-gnu": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.12.0.tgz", - "integrity": "sha512-0fZBq27b+D7Ar5CQMofVN8sggOVhEtzFUwOwPppQt0k+VR+7UHMZZY4y+64WJ06XOhBTKXtQB/Sv0NwQMXyNAA==", + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.14.1.tgz", + "integrity": "sha512-p9rGKYkHdFMzhckOTFubfxgyIO1vw//7IIjBBRVzyZebWlzRLeNhqxuSaZ7kCEKVkm/kuC9fVRW9HkC/zNRG2w==", "dev": true, "optional": true }, "@rollup/rollup-linux-arm64-musl": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.12.0.tgz", - "integrity": "sha512-eTvzUS3hhhlgeAv6bfigekzWZjaEX9xP9HhxB0Dvrdbkk5w/b+1Sxct2ZuDxNJKzsRStSq1EaEkVSEe7A7ipgQ==", + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.14.1.tgz", + "integrity": "sha512-nDY6Yz5xS/Y4M2i9JLQd3Rofh5OR8Bn8qe3Mv/qCVpHFlwtZSBYSPaU4mrGazWkXrdQ98GB//H0BirGR/SKFSw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.14.1.tgz", + "integrity": "sha512-im7HE4VBL+aDswvcmfx88Mp1soqL9OBsdDBU8NqDEYtkri0qV0THhQsvZtZeNNlLeCUQ16PZyv7cqutjDF35qw==", "dev": true, "optional": true }, "@rollup/rollup-linux-riscv64-gnu": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.12.0.tgz", - "integrity": "sha512-ix+qAB9qmrCRiaO71VFfY8rkiAZJL8zQRXveS27HS+pKdjwUfEhqo2+YF2oI+H/22Xsiski+qqwIBxVewLK7sw==", + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.14.1.tgz", + "integrity": "sha512-RWdiHuAxWmzPJgaHJdpvUUlDz8sdQz4P2uv367T2JocdDa98iRw2UjIJ4QxSyt077mXZT2X6pKfT2iYtVEvOFw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-s390x-gnu": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.14.1.tgz", + "integrity": "sha512-VMgaGQ5zRX6ZqV/fas65/sUGc9cPmsntq2FiGmayW9KMNfWVG/j0BAqImvU4KTeOOgYSf1F+k6at1UfNONuNjA==", "dev": true, "optional": true }, "@rollup/rollup-linux-x64-gnu": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.12.0.tgz", - "integrity": "sha512-TenQhZVOtw/3qKOPa7d+QgkeM6xY0LtwzR8OplmyL5LrgTWIXpTQg2Q2ycBf8jm+SFW2Wt/DTn1gf7nFp3ssVA==", + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.14.1.tgz", + "integrity": "sha512-9Q7DGjZN+hTdJomaQ3Iub4m6VPu1r94bmK2z3UeWP3dGUecRC54tmVu9vKHTm1bOt3ASoYtEz6JSRLFzrysKlA==", "dev": true, "optional": true }, "@rollup/rollup-linux-x64-musl": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.12.0.tgz", - "integrity": "sha512-LfFdRhNnW0zdMvdCb5FNuWlls2WbbSridJvxOvYWgSBOYZtgBfW9UGNJG//rwMqTX1xQE9BAodvMH9tAusKDUw==", + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.14.1.tgz", + "integrity": "sha512-JNEG/Ti55413SsreTguSx0LOVKX902OfXIKVg+TCXO6Gjans/k9O6ww9q3oLGjNDaTLxM+IHFMeXy/0RXL5R/g==", "dev": true, "optional": true }, "@rollup/rollup-win32-arm64-msvc": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.12.0.tgz", - "integrity": "sha512-JPDxovheWNp6d7AHCgsUlkuCKvtu3RB55iNEkaQcf0ttsDU/JZF+iQnYcQJSk/7PtT4mjjVG8N1kpwnI9SLYaw==", + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.14.1.tgz", + "integrity": "sha512-ryS22I9y0mumlLNwDFYZRDFLwWh3aKaC72CWjFcFvxK0U6v/mOkM5Up1bTbCRAhv3kEIwW2ajROegCIQViUCeA==", "dev": true, "optional": true }, "@rollup/rollup-win32-ia32-msvc": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.12.0.tgz", - "integrity": "sha512-fjtuvMWRGJn1oZacG8IPnzIV6GF2/XG+h71FKn76OYFqySXInJtseAqdprVTDTyqPxQOG9Exak5/E9Z3+EJ8ZA==", + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.14.1.tgz", + "integrity": "sha512-TdloItiGk+T0mTxKx7Hp279xy30LspMso+GzQvV2maYePMAWdmrzqSNZhUpPj3CGw12aGj57I026PgLCTu8CGg==", "dev": true, "optional": true }, "@rollup/rollup-win32-x64-msvc": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.12.0.tgz", - "integrity": "sha512-ZYmr5mS2wd4Dew/JjT0Fqi2NPB/ZhZ2VvPp7SmvPZb4Y1CG/LRcS6tcRo2cYU7zLK5A7cdbhWnnWmUjoI4qapg==", + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.14.1.tgz", + "integrity": "sha512-wQGI+LY/Py20zdUPq+XCem7JcPOyzIJBm3dli+56DJsQOHbnXZFEwgmnC6el1TPAfC8lBT3m+z69RmLykNUbew==", "dev": true, "optional": true }, @@ -9054,9 +8739,9 @@ "dev": true }, "@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", "dev": true }, "@tsconfig/node12": { @@ -9087,9 +8772,9 @@ } }, "@types/chai": { - "version": "4.3.12", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.12.tgz", - "integrity": "sha512-zNKDHG/1yxm8Il6uCCVsm+dRdEsJlFoDu73X17y09bId6UwoYww+vFBsAcRzl8knM1sab3Dp1VRikFQwDOtDDw==", + "version": "4.3.14", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.14.tgz", + "integrity": "sha512-Wj71sXE4Q4AkGdG9Tvq1u/fquNz9EdG4LIJMwVVII7ashjD/8cf8fyIfJAjRr6YcsXnSE8cOGQPq1gqeR8z+3w==", "dev": true }, "@types/cookie": { @@ -9148,9 +8833,9 @@ "dev": true }, "@types/node": { - "version": "20.11.21", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.21.tgz", - "integrity": "sha512-/ySDLGscFPNasfqStUuWWPfL78jompfIoVzLJPVVAHBh6rpG68+pI2Gk+fNLeI8/f1yPYL4s46EleVIc20F1Ow==", + "version": "20.12.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.6.tgz", + "integrity": "sha512-3KurE8taB8GCvZBPngVbp0lk5CKi8M9f9k1rsADh0Evdz5SzJ+Q+Hx9uHoFGsLnLnd1xmkDQr2hVhlA0Mn0lKQ==", "dev": true, "requires": { "undici-types": "~5.26.4" @@ -9294,41 +8979,45 @@ } }, "array-includes": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", - "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", "is-string": "^1.0.7" } }, - "array.prototype.filter": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array.prototype.filter/-/array.prototype.filter-1.0.3.tgz", - "integrity": "sha512-VizNcj/RGJiUyQBgzwxzE5oHdeuXY5hSbbmKMlphj1cy1Vl7Pn2asCGbSrru6hSQjmCzqTBPVWAF/whmEOVHbw==", + "array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", "dev": true, + "peer": true, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-array-method-boxes-properly": "^1.0.0", - "is-string": "^1.0.7" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" } }, "array.prototype.findlastindex": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.4.tgz", - "integrity": "sha512-hzvSHUshSpCflDR1QMUBLHGHP1VIEBegT4pix9H/Z92Xw3ySoy6c2qh7lJWTJnRJ8JCZ9bJNCgTyYaJGcJu6xQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", "dev": true, "requires": { - "call-bind": "^1.0.5", + "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", + "es-abstract": "^1.23.2", "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", "es-shim-unscopables": "^1.0.2" } }, @@ -9356,6 +9045,19 @@ "es-shim-unscopables": "^1.0.0" } }, + "array.prototype.toreversed": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz", + "integrity": "sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==", + "dev": true, + "peer": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + } + }, "array.prototype.tosorted": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.3.tgz", @@ -9408,16 +9110,6 @@ "lodash": "^4.17.14" } }, - "asynciterator.prototype": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz", - "integrity": "sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==", - "dev": true, - "peer": true, - "requires": { - "has-symbols": "^1.0.3" - } - }, "available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", @@ -9476,9 +9168,9 @@ } }, "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true }, "bluebird": { @@ -9900,6 +9592,39 @@ "dev": true, "peer": true }, + "data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dev": true, + "requires": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + } + }, + "data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + } + }, + "data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dev": true, + "requires": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + } + }, "date-format": { "version": "4.0.14", "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", @@ -10022,12 +9747,6 @@ "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", "dev": true }, - "eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true - }, "eckey-utils": { "version": "0.7.14", "resolved": "https://registry.npmjs.org/eckey-utils/-/eckey-utils-0.7.14.tgz", @@ -10044,7 +9763,8 @@ "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true + "dev": true, + "peer": true }, "encodeurl": { "version": "1.0.2", @@ -10098,18 +9818,22 @@ } }, "es-abstract": { - "version": "1.22.4", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.4.tgz", - "integrity": "sha512-vZYJlk2u6qHYxBOTjAeg7qUxHdNfih64Uu2J8QqWgXZ2cri0ZpJAkzDUK/q593+mvKwlxyaxr6F1Q+3LKoQRgg==", + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", "dev": true, "requires": { "array-buffer-byte-length": "^1.0.1", "arraybuffer.prototype.slice": "^1.0.3", - "available-typed-arrays": "^1.0.6", + "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", "es-define-property": "^1.0.0", "es-errors": "^1.3.0", - "es-set-tostringtag": "^2.0.2", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", "es-to-primitive": "^1.2.1", "function.prototype.name": "^1.1.6", "get-intrinsic": "^1.2.4", @@ -10117,15 +9841,16 @@ "globalthis": "^1.0.3", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.1", + "has-proto": "^1.0.3", "has-symbols": "^1.0.3", - "hasown": "^2.0.1", + "hasown": "^2.0.2", "internal-slot": "^1.0.7", "is-array-buffer": "^3.0.4", "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", + "is-shared-array-buffer": "^1.0.3", "is-string": "^1.0.7", "is-typed-array": "^1.1.13", "is-weakref": "^1.0.2", @@ -10133,25 +9858,19 @@ "object-keys": "^1.1.1", "object.assign": "^4.1.5", "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.0", + "safe-array-concat": "^1.1.2", "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.8", - "string.prototype.trimend": "^1.0.7", - "string.prototype.trimstart": "^1.0.7", - "typed-array-buffer": "^1.0.1", - "typed-array-byte-length": "^1.0.0", - "typed-array-byte-offset": "^1.0.0", - "typed-array-length": "^1.0.4", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.14" + "which-typed-array": "^1.1.15" } }, - "es-array-method-boxes-properly": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", - "dev": true - }, "es-define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", @@ -10168,27 +9887,35 @@ "dev": true }, "es-iterator-helpers": { - "version": "1.0.17", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.17.tgz", - "integrity": "sha512-lh7BsUqelv4KUbR5a/ZTaGGIMLCjPGPqJ6q+Oq24YP0RdyptX1uzm4vvaqzk7Zx3bpl/76YLTTDj9L7uYQ92oQ==", + "version": "1.0.18", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.18.tgz", + "integrity": "sha512-scxAJaewsahbqTYrGKJihhViaM6DDZDDoucfvzNbK0pOren1g/daDQ3IAhzn+1G14rBG7w+i5N+qul60++zlKA==", "dev": true, "peer": true, "requires": { - "asynciterator.prototype": "^1.0.0", "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.22.4", + "es-abstract": "^1.23.0", "es-errors": "^1.3.0", - "es-set-tostringtag": "^2.0.2", + "es-set-tostringtag": "^2.0.3", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "globalthis": "^1.0.3", "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.1", + "has-proto": "^1.0.3", "has-symbols": "^1.0.3", "internal-slot": "^1.0.7", "iterator.prototype": "^1.1.2", - "safe-array-concat": "^1.1.0" + "safe-array-concat": "^1.1.2" + } + }, + "es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "requires": { + "es-errors": "^1.3.0" } }, "es-set-tostringtag": { @@ -10483,28 +10210,30 @@ } }, "eslint-plugin-react": { - "version": "7.33.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz", - "integrity": "sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==", + "version": "7.34.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.1.tgz", + "integrity": "sha512-N97CxlouPT1AHt8Jn0mhhN2RrADlUAsk1/atcT2KyA/l9Q/E6ll7OIGwNumFmWfZ9skV3XXccYS19h80rHtgkw==", "dev": true, "peer": true, "requires": { - "array-includes": "^3.1.6", - "array.prototype.flatmap": "^1.3.1", - "array.prototype.tosorted": "^1.1.1", + "array-includes": "^3.1.7", + "array.prototype.findlast": "^1.2.4", + "array.prototype.flatmap": "^1.3.2", + "array.prototype.toreversed": "^1.1.2", + "array.prototype.tosorted": "^1.1.3", "doctrine": "^2.1.0", - "es-iterator-helpers": "^1.0.12", + "es-iterator-helpers": "^1.0.17", "estraverse": "^5.3.0", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", - "object.entries": "^1.1.6", - "object.fromentries": "^2.0.6", - "object.hasown": "^1.1.2", - "object.values": "^1.1.6", + "object.entries": "^1.1.7", + "object.fromentries": "^2.0.7", + "object.hasown": "^1.1.3", + "object.values": "^1.1.7", "prop-types": "^15.8.1", - "resolve": "^2.0.0-next.4", + "resolve": "^2.0.0-next.5", "semver": "^6.3.1", - "string.prototype.matchall": "^4.0.8" + "string.prototype.matchall": "^4.0.10" }, "dependencies": { "doctrine": { @@ -10789,9 +10518,9 @@ "dev": true }, "follow-redirects": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", - "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "dev": true }, "for-each": { @@ -10904,9 +10633,9 @@ } }, "get-tsconfig": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.2.tgz", - "integrity": "sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==", + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz", + "integrity": "sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==", "dev": true, "requires": { "resolve-pkg-maps": "^1.0.0" @@ -11042,9 +10771,9 @@ } }, "hasown": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", - "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, "requires": { "function-bind": "^1.1.2" @@ -11311,6 +11040,15 @@ "hasown": "^2.0.0" } }, + "is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dev": true, + "requires": { + "is-typed-array": "^1.1.13" + } + }, "is-date-object": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", @@ -11368,9 +11106,9 @@ } }, "is-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", - "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", "dev": true, "peer": true }, @@ -11439,9 +11177,9 @@ "dev": true }, "is-set": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", - "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", "dev": true, "peer": true }, @@ -11488,9 +11226,9 @@ "dev": true }, "is-weakmap": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", - "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", "dev": true, "peer": true }, @@ -11504,14 +11242,14 @@ } }, "is-weakset": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", - "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", + "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", "dev": true, "peer": true, "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4" } }, "is-wsl": { @@ -11582,16 +11320,6 @@ "set-function-name": "^2.0.1" } }, - "jackspeak": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", - "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", - "dev": true, - "requires": { - "@isaacs/cliui": "^8.0.2", - "@pkgjs/parseargs": "^0.11.0" - } - }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -11810,13 +11538,24 @@ } }, "karma-firefox-launcher": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-2.1.2.tgz", - "integrity": "sha512-VV9xDQU1QIboTrjtGVD4NCfzIH7n01ZXqy/qpBhnOeGVOkG5JYPEm8kuSd7psHE6WouZaQ9Ool92g8LFweSNMA==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-2.1.3.tgz", + "integrity": "sha512-LMM2bseebLbYjODBOVt7TCPP9OI2vZIXCavIXhkO9m+10Uj5l7u/SKoeRmYx8FYHTVGZSpk6peX+3BMHC1WwNw==", "dev": true, "requires": { "is-wsl": "^2.2.0", - "which": "^2.0.1" + "which": "^3.0.0" + }, + "dependencies": { + "which": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", + "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } } }, "karma-mocha": { @@ -12118,9 +11857,9 @@ } }, "magic-string": { - "version": "0.30.7", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.7.tgz", - "integrity": "sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==", + "version": "0.30.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.9.tgz", + "integrity": "sha512-S1+hd+dIrC8EZqKyT9DstTH/0Z+f76kmmvZnkfQVmOpDEF9iVgdYif3Q/pIWHmCoo59bQVGW0kVL3e2nl+9+Sw==", "dev": true, "requires": { "@jridgewell/sourcemap-codec": "^1.4.15" @@ -12238,12 +11977,6 @@ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true }, - "minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", - "dev": true - }, "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -12251,9 +11984,9 @@ "dev": true }, "mocha": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.3.0.tgz", - "integrity": "sha512-uF2XJs+7xSLsrmIvn37i/wnc91nw7XjOQB8ccyx5aEgdnohr7n+rEiZP23WkCYHjilR6+EboEnbq/ZQDz4LSbg==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.4.0.tgz", + "integrity": "sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA==", "dev": true, "requires": { "ansi-colors": "4.1.1", @@ -12483,60 +12216,60 @@ } }, "object.entries": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz", - "integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", + "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" } }, "object.fromentries": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", - "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" } }, "object.groupby": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.2.tgz", - "integrity": "sha512-bzBq58S+x+uo0VjurFT0UktpKHOZmv4/xePiOA1nbB9pMqpGK7rUPNgf+1YC+7mE+0HzhTMqNUuCqvKhj6FnBw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", "dev": true, "requires": { - "array.prototype.filter": "^1.0.3", - "call-bind": "^1.0.5", + "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.0.0" + "es-abstract": "^1.23.2" } }, "object.hasown": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.3.tgz", - "integrity": "sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.4.tgz", + "integrity": "sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==", "dev": true, "peer": true, "requires": { - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" } }, "object.values": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", - "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" } }, "on-finished": { @@ -12652,28 +12385,10 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, - "path-scurry": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", - "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", - "dev": true, - "requires": { - "lru-cache": "^9.1.1 || ^10.0.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", - "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", - "dev": true - } - } - }, "path-to-regexp": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", - "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", + "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", "dev": true }, "pathval": { @@ -12691,6 +12406,12 @@ "through": "~2.3" } }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, "picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -12704,13 +12425,13 @@ "dev": true }, "playwright": { - "version": "1.42.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.42.0.tgz", - "integrity": "sha512-Ko7YRUgj5xBHbntrgt4EIw/nE//XBHOKVKnBjO1KuZkmkhlbgyggTe5s9hjqQ1LpN+Xg+kHsQyt5Pa0Bw5XpvQ==", + "version": "1.43.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.43.0.tgz", + "integrity": "sha512-SiOKHbVjTSf6wHuGCbqrEyzlm6qvXcv7mENP+OZon1I07brfZLGdfWV0l/efAzVx7TF3Z45ov1gPEkku9q25YQ==", "dev": true, "requires": { "fsevents": "2.3.2", - "playwright-core": "1.42.0" + "playwright-core": "1.43.0" }, "dependencies": { "fsevents": { @@ -12723,9 +12444,9 @@ } }, "playwright-core": { - "version": "1.42.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.42.0.tgz", - "integrity": "sha512-0HD9y8qEVlcbsAjdpBaFjmaTHf+1FeIddy8VJLeiqwhcNqGCBe4Wp2e8knpqiYbzxtxarxiXyNDw2cG8sCaNMQ==", + "version": "1.43.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.43.0.tgz", + "integrity": "sha512-iWFjyBUH97+pUFiyTqSLd8cDMMOS0r2ZYz2qEsPjH8/bX++sbIJT35MSwKnp1r/OQBAqC5XO99xFbJ9XClhf4w==", "dev": true }, "pluralize": { @@ -12951,17 +12672,17 @@ } }, "reflect.getprototypeof": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.5.tgz", - "integrity": "sha512-62wgfC8dJWrmxv44CA36pLDnP6KKl3Vhxb7PL+8+qrrFMMoJij4vgiMP8zV4O8+CBMXY1mHxI5fITGHXFHVmQQ==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", + "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", "dev": true, "peer": true, "requires": { - "call-bind": "^1.0.5", + "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.0.0", - "get-intrinsic": "^1.2.3", + "es-abstract": "^1.23.1", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", "globalthis": "^1.0.3", "which-builtin-type": "^1.1.3" } @@ -13090,24 +12811,26 @@ } }, "rollup": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.12.0.tgz", - "integrity": "sha512-wz66wn4t1OHIJw3+XU7mJJQV/2NAfw5OAk6G6Hoo3zcvz/XOfQ52Vgi+AN4Uxoxi0KBBwk2g8zPrTDA4btSB/Q==", + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.14.1.tgz", + "integrity": "sha512-4LnHSdd3QK2pa1J6dFbfm1HN0D7vSK/ZuZTsdyUAlA6Rr1yTouUTL13HaDOGJVgby461AhrNGBS7sCGXXtT+SA==", "dev": true, "requires": { - "@rollup/rollup-android-arm-eabi": "4.12.0", - "@rollup/rollup-android-arm64": "4.12.0", - "@rollup/rollup-darwin-arm64": "4.12.0", - "@rollup/rollup-darwin-x64": "4.12.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.12.0", - "@rollup/rollup-linux-arm64-gnu": "4.12.0", - "@rollup/rollup-linux-arm64-musl": "4.12.0", - "@rollup/rollup-linux-riscv64-gnu": "4.12.0", - "@rollup/rollup-linux-x64-gnu": "4.12.0", - "@rollup/rollup-linux-x64-musl": "4.12.0", - "@rollup/rollup-win32-arm64-msvc": "4.12.0", - "@rollup/rollup-win32-ia32-msvc": "4.12.0", - "@rollup/rollup-win32-x64-msvc": "4.12.0", + "@rollup/rollup-android-arm-eabi": "4.14.1", + "@rollup/rollup-android-arm64": "4.14.1", + "@rollup/rollup-darwin-arm64": "4.14.1", + "@rollup/rollup-darwin-x64": "4.14.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.14.1", + "@rollup/rollup-linux-arm64-gnu": "4.14.1", + "@rollup/rollup-linux-arm64-musl": "4.14.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.14.1", + "@rollup/rollup-linux-riscv64-gnu": "4.14.1", + "@rollup/rollup-linux-s390x-gnu": "4.14.1", + "@rollup/rollup-linux-x64-gnu": "4.14.1", + "@rollup/rollup-linux-x64-musl": "4.14.1", + "@rollup/rollup-win32-arm64-msvc": "4.14.1", + "@rollup/rollup-win32-ia32-msvc": "4.14.1", + "@rollup/rollup-win32-x64-msvc": "4.14.1", "@types/estree": "1.0.5", "fsevents": "~2.3.2" } @@ -13122,13 +12845,13 @@ } }, "safe-array-concat": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.0.tgz", - "integrity": "sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", "dev": true, "requires": { - "call-bind": "^1.0.5", - "get-intrinsic": "^1.2.2", + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", "has-symbols": "^1.0.3", "isarray": "^2.0.5" } @@ -13178,17 +12901,17 @@ } }, "set-function-length": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", - "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dev": true, "requires": { - "define-data-property": "^1.1.2", + "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.3", + "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.1" + "has-property-descriptors": "^1.0.2" } }, "set-function-name": { @@ -13225,12 +12948,12 @@ "dev": true }, "side-channel": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.5.tgz", - "integrity": "sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "dev": true, "requires": { - "call-bind": "^1.0.6", + "call-bind": "^1.0.7", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.4", "object-inspect": "^1.13.1" @@ -13271,15 +12994,15 @@ "dev": true }, "smob": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/smob/-/smob-1.4.1.tgz", - "integrity": "sha512-9LK+E7Hv5R9u4g4C3p+jjLstaLe11MDsL21UpYaCNmapvMkYhqCV4A/f/3gyH8QjMyh6l68q9xC85vihY9ahMQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz", + "integrity": "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==", "dev": true }, "socket.io": { - "version": "4.7.4", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.4.tgz", - "integrity": "sha512-DcotgfP1Zg9iP/dH9zvAQcWrE0TtbMVwXmlV4T4mqsvY+gw+LqUGPfx2AoVyRk0FLME+GQhufDMyacFmw7ksqw==", + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz", + "integrity": "sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==", "dev": true, "requires": { "accepts": "~1.3.4", @@ -13413,74 +13136,59 @@ } } }, - "string-width-cjs": { - "version": "npm:string-width@4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - } - } - }, "string.prototype.matchall": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz", - "integrity": "sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==", + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", + "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", "dev": true, "peer": true, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", "has-symbols": "^1.0.3", - "internal-slot": "^1.0.5", - "regexp.prototype.flags": "^1.5.0", - "set-function-name": "^2.0.0", - "side-channel": "^1.0.4" + "internal-slot": "^1.0.7", + "regexp.prototype.flags": "^1.5.2", + "set-function-name": "^2.0.2", + "side-channel": "^1.0.6" } }, "string.prototype.trim": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", - "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" } }, "string.prototype.trimend": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", - "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" } }, "string.prototype.trimstart": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", - "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" } }, "strip-ansi": { @@ -13492,15 +13200,6 @@ "ansi-regex": "^5.0.1" } }, - "strip-ansi-cjs": { - "version": "npm:strip-ansi@6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -13578,9 +13277,9 @@ } }, "terser": { - "version": "5.28.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.28.1.tgz", - "integrity": "sha512-wM+bZp54v/E9eRRGXb5ZFDvinrJIOaTapx3WUokyVGZu5ucVCK55zEgGd5Dl2fSr3jUo5sDiERErUWLY6QPFyA==", + "version": "5.30.3", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.30.3.tgz", + "integrity": "sha512-STdUgOUx8rLbMGO9IOwHLpCqolkDITFFQSMYYwKE1N2lY6MVSaeoi10z/EhWxRc6ybqoVmKSkhKYH/XUpl7vSA==", "dev": true, "requires": { "@jridgewell/source-map": "^0.3.3", @@ -13637,71 +13336,10 @@ "dev": true }, "tmp": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.2.tgz", - "integrity": "sha512-ETcvHhaIc9J2MDEAH6N67j9bvBvu/3Gb764qaGhwtFvjtvhegqoqSpofgeyq1Sc24mW5pdyUDs9HP5j3ehkxRw==", - "dev": true, - "requires": { - "rimraf": "^5.0.5" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - } - }, - "glob": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", - "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", - "dev": true, - "requires": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" - } - }, - "minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - }, - "rimraf": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", - "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", - "dev": true, - "requires": { - "glob": "^10.3.7" - } - }, - "signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true - } - } + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "dev": true }, "to-regex-range": { "version": "5.0.1", @@ -13760,9 +13398,9 @@ } }, "tsx": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.1.tgz", - "integrity": "sha512-8d6VuibXHtlN5E3zFkgY8u4DX7Y3Z27zvvPKVmLon/D4AjuKzarkUBTLDBgj9iTQ0hg5xM7c/mYiRVM+HETf0g==", + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.2.tgz", + "integrity": "sha512-BCNd4kz6fz12fyrgCTEdZHGJ9fWTGeUzXmQysh0RVocDY3h4frk05ZNCXSy4kIenF7y/QnrdiVpTsyNRn6vlAw==", "dev": true, "requires": { "esbuild": "~0.19.10", @@ -13840,9 +13478,9 @@ } }, "typed-array-length": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.5.tgz", - "integrity": "sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", "dev": true, "requires": { "call-bind": "^1.0.7", @@ -13854,9 +13492,9 @@ } }, "typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.4.tgz", + "integrity": "sha512-dGE2Vv8cpVvw28v8HCPqyb08EzbBURxDpuhJvTrusShUfGnhHBafDsLdS1EhhxyL6BJQE+2cT3dDPAv+MQ6oLw==", "dev": true }, "ua-parser-js": { @@ -14052,29 +13690,29 @@ } }, "which-collection": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", - "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", "dev": true, "peer": true, "requires": { - "is-map": "^2.0.1", - "is-set": "^2.0.1", - "is-weakmap": "^2.0.1", - "is-weakset": "^2.0.1" + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" } }, "which-typed-array": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.14.tgz", - "integrity": "sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", "dev": true, "requires": { - "available-typed-arrays": "^1.0.6", - "call-bind": "^1.0.5", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-tostringtag": "^1.0.1" + "has-tostringtag": "^1.0.2" } }, "workerpool": { @@ -14094,17 +13732,6 @@ "strip-ansi": "^6.0.0" } }, - "wrap-ansi-cjs": { - "version": "npm:wrap-ansi@7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/package.json b/package.json index 669dc61e..206d6639 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "@rollup/plugin-replace": "^5.0.5", "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-wasm": "^6.2.2", - "@types/chai": "^4.3.12", + "@types/chai": "^4.3.14", "argon2id": "^1.0.1", "benchmark": "^2.1.4", "c8": "^8.0.1", @@ -93,17 +93,17 @@ "karma": "^6.4.3", "karma-browserstack-launcher": "^1.6.0", "karma-chrome-launcher": "^3.2.0", - "karma-firefox-launcher": "^2.1.2", + "karma-firefox-launcher": "^2.1.3", "karma-mocha": "^2.0.1", "karma-mocha-reporter": "^2.2.5", "karma-webkit-launcher": "^2.4.0", - "mocha": "^10.3.0", - "playwright": "^1.42.0", - "rollup": "^4.12.0", + "mocha": "^10.4.0", + "playwright": "^1.43.0", + "rollup": "^4.14.1", "sinon": "^17.0.1", "ts-node": "^10.9.2", - "tsx": "^4.7.1", - "typescript": "^5.3.3", + "tsx": "^4.7.2", + "typescript": "^5.4.4", "web-streams-polyfill": "^3.3.3" }, "repository": { From 5464caa6f7f8ce7144cf45855f8f5637c2ec4e26 Mon Sep 17 00:00:00 2001 From: larabr Date: Fri, 12 Apr 2024 13:47:52 +0200 Subject: [PATCH 125/201] Fix email address validity check to still allow unicode values, and further relax constraints (#1739) We relaxed constraints in a previous commit, but excluded unicode chars, which are however allowed in v5. We now drop almost all email address constraints, by primarily rejecting control and spaces char classes. Library users are strongly encouraged to implement additional checks as needed, based on their supported email address format. NB: the validity checks in question affect the userID inputs accepted by e.g. `generateKey` and `reformatKey`, not the values parsed from existing entities, e.g. using `readKey` (where almost no validation is performed). --- src/util.js | 13 ++++++++----- test/general/util.js | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/util.js b/src/util.js index 47363c97..45db97e8 100644 --- a/src/util.js +++ b/src/util.js @@ -465,16 +465,19 @@ const util = { }, /** - * Test email format based on W3C HTML5 specification. - * This check is not exaustive, and does not match RFC 5322 exactly - * (see https://html.spec.whatwg.org/multipage/input.html#email-state-(type=email)), - * but is commonly used for email address validation. + * Test email format to ensure basic compliance: + * - must include a single @ + * - no control or space unicode chars allowed + * - no backslash and square brackets (as the latter can mess with the userID parsing) + * - cannot end with a punctuation char + * These checks are not meant to be exhaustive; applications are strongly encouraged to implement stricter validation, + * e.g. based on the W3C HTML spec (https://html.spec.whatwg.org/multipage/input.html#email-state-(type=email)). */ isEmailAddress: function(data) { if (!util.isString(data)) { return false; } - const re = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/; + const re = /^[^\p{C}\p{Z}@<>\\]+@[^\p{C}\p{Z}@<>\\]+[^\p{C}\p{Z}\p{P}]$/u; return re.test(data); }, diff --git a/test/general/util.js b/test/general/util.js index c17b88c8..5ba9b290 100644 --- a/test/general/util.js +++ b/test/general/util.js @@ -120,6 +120,10 @@ export default () => describe('Util unit tests', function() { const data = 'test@localhost'; expect(util.isEmailAddress(data)).to.be.true; }); + it('should return true for valid email address (unicode chars)', function() { + const data = '🙂@localhost'; + expect(util.isEmailAddress(data)).to.be.true; + }); it('should return false for invalid email address (full userID)', function() { const data = 'Test User '; expect(util.isEmailAddress(data)).to.be.false; @@ -128,6 +132,18 @@ export default () => describe('Util unit tests', function() { const data = 'testexamplecom'; expect(util.isEmailAddress(data)).to.be.false; }); + it('should return false for invalid email address (invisible unicode control char)', function() { + const data = 'test\u{feff}ctrl@email.it'; + expect(util.isEmailAddress(data)).to.be.false; + }); + it('should return false for invalid email address (trailing punctuation)', function() { + const data = 'test@localhost.'; + expect(util.isEmailAddress(data)).to.be.false; + }); + it('should return false for invalid email address (including whitespace)', function() { + const data = 'test space@email.it'; + expect(util.isEmailAddress(data)).to.be.false; + }); it('should return false for empty string', function() { const data = ''; expect(util.isEmailAddress(data)).to.be.false; From 2bf7c92469e4ed405a6b64af8d7072ca8019a187 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Fri, 12 Apr 2024 14:28:06 +0200 Subject: [PATCH 126/201] 6.0.0-beta.0 --- docs/AEADEncryptedDataPacket.html | 14 +- docs/Argon2S2K.html | 16 +- docs/CleartextMessage.html | 12 +- docs/CompressedDataPacket.html | 16 +- docs/Key.html | 56 +++--- docs/LiteralDataPacket.html | 20 +- docs/MarkerPacket.html | 4 +- docs/Message.html | 40 ++-- docs/OnePassSignaturePacket.html | 22 +-- docs/PacketList.html | 14 +- docs/PaddingPacket.html | 8 +- docs/PrivateKey.html | 20 +- docs/PublicKey.html | 8 +- docs/PublicKeyEncryptedSessionKeyPacket.html | 14 +- docs/PublicKeyPacket.html | 46 ++--- docs/PublicSubkeyPacket.html | 46 ++--- docs/SecretKeyPacket.html | 72 +++---- docs/SecretSubkeyPacket.html | 72 +++---- docs/Signature.html | 8 +- docs/SignaturePacket.html | 24 +-- ...EncryptedIntegrityProtectedDataPacket.html | 10 +- docs/SymEncryptedSessionKeyPacket.html | 16 +- docs/SymmetricallyEncryptedDataPacket.html | 10 +- docs/TrustPacket.html | 4 +- docs/UserAttributePacket.html | 8 +- docs/UserIDPacket.html | 10 +- docs/global.html | 143 ++++++++++---- docs/index.html | 4 +- docs/module-config.html | 178 ++++-------------- docs/module-crypto.html | 2 +- docs/module-crypto_aes_kw.html | 6 +- docs/module-crypto_cmac.html | 6 +- docs/module-crypto_crypto.html | 35 ++-- docs/module-crypto_hash.html | 8 +- docs/module-crypto_hkdf.html | 2 +- docs/module-crypto_mode.html | 10 +- docs/module-crypto_mode_cfb.html | 4 +- docs/module-crypto_mode_eax.html | 8 +- docs/module-crypto_mode_gcm.html | 4 +- docs/module-crypto_mode_ocb.html | 8 +- docs/module-crypto_pkcs1.html | 10 +- docs/module-crypto_public_key.html | 10 +- docs/module-crypto_public_key_dsa.html | 10 +- docs/module-crypto_public_key_elgamal.html | 10 +- docs/module-crypto_public_key_elliptic.html | 2 +- ...dule-crypto_public_key_elliptic_curve.html | 12 +- ...odule-crypto_public_key_elliptic_ecdh.html | 60 +++--- ...dule-crypto_public_key_elliptic_ecdsa.html | 10 +- ...dule-crypto_public_key_elliptic_eddsa.html | 10 +- ...ypto_public_key_elliptic_eddsa_legacy.html | 8 +- docs/module-crypto_public_key_prime.html | 10 +- docs/module-crypto_public_key_rsa.html | 20 +- docs/module-crypto_random.html | 6 +- docs/module-crypto_signature.html | 8 +- docs/module-encoding_base64.html | 8 +- docs/module-enums.html | 36 ++-- docs/module-key_Subkey-Subkey.html | 40 ++-- docs/module-key_User-User.html | 20 +- docs/module-key_helper.html | 22 +-- docs/module-packet_packet.html | 10 +- docs/module-type_ecdh_symkey.html | 2 +- docs/module-type_kdf_params-KDFParams.html | 6 +- docs/module-type_keyid-KeyID.html | 14 +- docs/module-type_oid.html | 2 +- docs/module-type_s2k-GenericS2K.html | 16 +- docs/module-type_s2k.html | 2 +- docs/module-type_x25519x448_symkey.html | 2 +- docs/module-util.html | 2 +- package-lock.json | 4 +- package.json | 2 +- 70 files changed, 670 insertions(+), 712 deletions(-) diff --git a/docs/AEADEncryptedDataPacket.html b/docs/AEADEncryptedDataPacket.html index 1ebb55a7..f692a3c7 100644 --- a/docs/AEADEncryptedDataPacket.html +++ b/docs/AEADEncryptedDataPacket.html @@ -98,7 +98,7 @@ AEAD Protected Data Packet

    Source:
    @@ -200,7 +200,7 @@ AEAD Protected Data Packet

    Source:
    @@ -270,7 +270,7 @@ AEAD Protected Data Packet

    Source:
    @@ -475,7 +475,7 @@ AEAD Protected Data Packet

    Source:
    @@ -717,7 +717,7 @@ AEAD Protected Data Packet

    Source:
    @@ -888,7 +888,7 @@ AEAD Protected Data Packet

    Source:
    @@ -1007,7 +1007,7 @@ AEAD Protected Data Packet

    Source:
    diff --git a/docs/Argon2S2K.html b/docs/Argon2S2K.html index 2f363b7e..1b5abb82 100644 --- a/docs/Argon2S2K.html +++ b/docs/Argon2S2K.html @@ -152,7 +152,7 @@
    Source:
    @@ -258,7 +258,7 @@
    Source:
    @@ -332,7 +332,7 @@
    Source:
    @@ -406,7 +406,7 @@
    Source:
    @@ -480,7 +480,7 @@
    Source:
    @@ -612,7 +612,7 @@ hashAlgorithm

    Source:
    @@ -791,7 +791,7 @@ hashAlgorithm

    Source:
    @@ -903,7 +903,7 @@ hashAlgorithm

    Source:
    diff --git a/docs/CleartextMessage.html b/docs/CleartextMessage.html index a7598850..f97d89f9 100644 --- a/docs/CleartextMessage.html +++ b/docs/CleartextMessage.html @@ -168,7 +168,7 @@ See https://tools.ietf.o
    Source:
    @@ -346,7 +346,7 @@ See https://tools.ietf.o
    Source:
    @@ -461,7 +461,7 @@ See https://tools.ietf.o
    Source:
    @@ -573,7 +573,7 @@ See https://tools.ietf.o
    Source:
    @@ -974,7 +974,7 @@ See https://tools.ietf.o
    Source:
    @@ -1211,7 +1211,7 @@ See https://tools.ietf.o
    Source:
    diff --git a/docs/CompressedDataPacket.html b/docs/CompressedDataPacket.html index 45d85ebb..2fdb293d 100644 --- a/docs/CompressedDataPacket.html +++ b/docs/CompressedDataPacket.html @@ -160,7 +160,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

    Source:
    @@ -266,7 +266,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

    Source:
    @@ -343,7 +343,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

    Source:
    @@ -417,7 +417,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

    Source:
    @@ -499,7 +499,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

    Source:
    @@ -651,7 +651,7 @@ read by read_packet

    Source:
    @@ -836,7 +836,7 @@ read by read_packet

    Source:
    @@ -926,7 +926,7 @@ read by read_packet

    Source:
    diff --git a/docs/Key.html b/docs/Key.html index e306f07c..317b2770 100644 --- a/docs/Key.html +++ b/docs/Key.html @@ -96,7 +96,7 @@ Can contain additional subkeys, signatures, user ids, user attributes.

    Source:
    @@ -333,7 +333,7 @@ if it is a valid revocation signature.

    Source:
    @@ -514,7 +514,7 @@ if it is a valid revocation signature.

    Source:
    @@ -626,7 +626,7 @@ if it is a valid revocation signature.

    Source:
    @@ -738,7 +738,7 @@ if it is a valid revocation signature.

    Source:
    @@ -1006,7 +1006,7 @@ if it is a valid revocation signature.

    Source:
    @@ -1225,7 +1225,7 @@ Returns Infinity if the key doesn't expire, or null if
    Source:
    @@ -1333,7 +1333,7 @@ Returns Infinity if the key doesn't expire, or null if
    Source:
    @@ -1445,7 +1445,7 @@ Returns Infinity if the key doesn't expire, or null if
    Source:
    @@ -1557,7 +1557,7 @@ Returns Infinity if the key doesn't expire, or null if
    Source:
    @@ -1735,7 +1735,7 @@ If no keyID is given, returns all keys, starting with the primary key.

    Source:
    @@ -1977,7 +1977,7 @@ algorithm preferences, and so on.

    Source:
    @@ -2220,7 +2220,7 @@ algorithm preferences, and so on.

    Source:
    @@ -2425,7 +2425,7 @@ algorithm preferences, and so on.

    Source:
    @@ -2717,7 +2717,7 @@ algorithm preferences, and so on.

    Source:
    @@ -2911,7 +2911,7 @@ If no keyID is given, returns all subkeys.

    Source:
    @@ -3023,7 +3023,7 @@ If no keyID is given, returns all subkeys.

    Source:
    @@ -3135,7 +3135,7 @@ If no keyID is given, returns all subkeys.

    Source:
    @@ -3412,7 +3412,7 @@ If no keyID is given, returns all subkeys.

    Source:
    @@ -3596,7 +3596,7 @@ If no keyID is given, returns all subkeys.

    Source:
    @@ -3811,7 +3811,7 @@ If no keyID is given, returns all subkeys.

    Source:
    @@ -4081,7 +4081,7 @@ If no keyID is given, returns all subkeys.

    Source:
    @@ -4193,7 +4193,7 @@ If no keyID is given, returns all subkeys.

    Source:
    @@ -4434,7 +4434,7 @@ a private key is returned.

    Source:
    @@ -4677,7 +4677,7 @@ a private key is returned.

    Source:
    @@ -4918,7 +4918,7 @@ and valid self signature. Throws if the primary key is invalid.

    Source:
    @@ -5201,7 +5201,7 @@ and valid self signature. Throws if the primary key is invalid.

    Source:
    @@ -5314,7 +5314,7 @@ Signature validity is null if the verification keys do not correspond to the cer
    Source:
    diff --git a/docs/LiteralDataPacket.html b/docs/LiteralDataPacket.html index 1b5ec55a..479deced 100644 --- a/docs/LiteralDataPacket.html +++ b/docs/LiteralDataPacket.html @@ -147,7 +147,7 @@ further interpreted.

    Source:
    @@ -326,7 +326,7 @@ further interpreted.

    Source:
    @@ -441,7 +441,7 @@ further interpreted.

    Source:
    @@ -623,7 +623,7 @@ with normalized end of line to \n

    Source:
    @@ -790,7 +790,7 @@ with normalized end of line to \n

    Source:
    @@ -977,7 +977,7 @@ with normalized end of line to \n

    Source:
    @@ -1116,7 +1116,7 @@ with normalized end of line to \n

    Source:
    @@ -1302,7 +1302,7 @@ will be normalized to \r\n and by default text is converted to UTF8

    Source:
    @@ -1392,7 +1392,7 @@ will be normalized to \r\n and by default text is converted to UTF8

    Source:
    @@ -1507,7 +1507,7 @@ will be normalized to \r\n and by default text is converted to UTF8

    Source:
    diff --git a/docs/MarkerPacket.html b/docs/MarkerPacket.html index bf14fa5d..0a691c46 100644 --- a/docs/MarkerPacket.html +++ b/docs/MarkerPacket.html @@ -106,7 +106,7 @@ software is necessary to process the message.

    Source:
    @@ -265,7 +265,7 @@ software is necessary to process the message.

    Source:
    diff --git a/docs/Message.html b/docs/Message.html index 146ae170..8fed6b4b 100644 --- a/docs/Message.html +++ b/docs/Message.html @@ -146,7 +146,7 @@ See https://tools.iet
    Source:
    @@ -661,7 +661,7 @@ See https://tools.iet
    Source:
    @@ -933,7 +933,7 @@ See https://tools.iet
    Source:
    @@ -1140,7 +1140,7 @@ See https://tools.iet
    Source:
    @@ -1291,7 +1291,7 @@ See https://tools.iet
    Source:
    @@ -1495,7 +1495,7 @@ See https://tools.iet
    Source:
    @@ -1800,7 +1800,7 @@ See https://tools.iet
    Source:
    @@ -2105,7 +2105,7 @@ See https://tools.iet
    Source:
    @@ -2545,7 +2545,7 @@ See https://tools.iet
    Source:
    @@ -2657,7 +2657,7 @@ See https://tools.iet
    Source:
    @@ -2769,7 +2769,7 @@ See https://tools.iet
    Source:
    @@ -2884,7 +2884,7 @@ See https://tools.iet
    Source:
    @@ -2999,7 +2999,7 @@ See https://tools.iet
    Source:
    @@ -3111,7 +3111,7 @@ See https://tools.iet
    Source:
    @@ -3515,7 +3515,7 @@ See https://tools.iet
    Source:
    @@ -3916,7 +3916,7 @@ See https://tools.iet
    Source:
    @@ -4028,7 +4028,7 @@ See https://tools.iet
    Source:
    @@ -4265,7 +4265,7 @@ See https://tools.iet
    Source:
    @@ -4531,7 +4531,7 @@ See https://tools.iet
    Source:
    @@ -4643,7 +4643,7 @@ See https://tools.iet
    Source:
    diff --git a/docs/OnePassSignaturePacket.html b/docs/OnePassSignaturePacket.html index 0f2bdf57..dca8a390 100644 --- a/docs/OnePassSignaturePacket.html +++ b/docs/OnePassSignaturePacket.html @@ -101,7 +101,7 @@ can compute the entire signed message in one pass.

    Source:
    @@ -199,7 +199,7 @@ that describes another signature to be applied to the same message data.

    Source:
    @@ -273,7 +273,7 @@ that describes another signature to be applied to the same message data.

    Source:
    @@ -344,7 +344,7 @@ that describes another signature to be applied to the same message data.

    Source:
    @@ -408,7 +408,7 @@ that describes another signature to be applied to the same message data.

    Source:
    @@ -482,7 +482,7 @@ that describes another signature to be applied to the same message data.

    Source:
    @@ -553,7 +553,7 @@ that describes another signature to be applied to the same message data.

    Source:
    @@ -629,7 +629,7 @@ Signature types are described in
    Source:
    @@ -693,7 +693,7 @@ Signature types are described in
    Source:
    @@ -824,7 +824,7 @@ Signature types are described in
    Source:
    @@ -936,7 +936,7 @@ Signature types are described in
    Source:
    diff --git a/docs/PacketList.html b/docs/PacketList.html index dc87bd44..517d93ce 100644 --- a/docs/PacketList.html +++ b/docs/PacketList.html @@ -97,7 +97,7 @@ are stored as numerical indices.

    Source:
    @@ -345,7 +345,7 @@ Equivalent to calling read on an empty PacketList instance.

    Source:
    @@ -530,7 +530,7 @@ Equivalent to calling read on an empty PacketList instance.

    Source:
    @@ -687,7 +687,7 @@ Equivalent to calling read on an empty PacketList instance.

    Source:
    @@ -859,7 +859,7 @@ Equivalent to calling read on an empty PacketList instance.

    Source:
    @@ -1097,7 +1097,7 @@ Equivalent to calling read on an empty PacketList instance.

    Source:
    @@ -1200,7 +1200,7 @@ class instance.

    Source:
    diff --git a/docs/PaddingPacket.html b/docs/PaddingPacket.html index 6f9faa6a..7fc377e0 100644 --- a/docs/PaddingPacket.html +++ b/docs/PaddingPacket.html @@ -97,7 +97,7 @@ Padding Packet

    Source:
    @@ -256,7 +256,7 @@ Padding Packet

    Source:
    @@ -427,7 +427,7 @@ Padding Packet

    Source:
    @@ -517,7 +517,7 @@ Padding Packet

    Source:
    diff --git a/docs/PrivateKey.html b/docs/PrivateKey.html index 8cf63e1c..b9009da2 100644 --- a/docs/PrivateKey.html +++ b/docs/PrivateKey.html @@ -144,7 +144,7 @@
    Source:
    @@ -453,7 +453,7 @@ Note: Curve448 and Curve25519 are not widely supported yet.

    Source:
    @@ -622,7 +622,7 @@ Note: Curve448 and Curve25519 are not widely supported yet.

    Source:
    @@ -734,7 +734,7 @@ Note: Curve448 and Curve25519 are not widely supported yet.

    Source:
    @@ -979,7 +979,7 @@ This is useful to retrieve keys for session key decryption

    Source:
    @@ -1092,7 +1092,7 @@ A dummy key is considered encrypted.

    Source:
    @@ -1182,7 +1182,7 @@ A dummy key is considered encrypted.

    Source:
    @@ -1485,7 +1485,7 @@ A dummy key is considered encrypted.

    Source:
    @@ -1597,7 +1597,7 @@ A dummy key is considered encrypted.

    Source:
    @@ -1774,7 +1774,7 @@ If only gnu-dummy keys are found, we cannot properly validate so we throw an err
    Source:
    diff --git a/docs/PublicKey.html b/docs/PublicKey.html index 99a3d8d4..2fcd3fa4 100644 --- a/docs/PublicKey.html +++ b/docs/PublicKey.html @@ -144,7 +144,7 @@
    Source:
    @@ -315,7 +315,7 @@
    Source:
    @@ -427,7 +427,7 @@
    Source:
    @@ -535,7 +535,7 @@
    Source:
    diff --git a/docs/PublicKeyEncryptedSessionKeyPacket.html b/docs/PublicKeyEncryptedSessionKeyPacket.html index db373e3b..68277ee5 100644 --- a/docs/PublicKeyEncryptedSessionKeyPacket.html +++ b/docs/PublicKeyEncryptedSessionKeyPacket.html @@ -107,7 +107,7 @@ decrypt the message.

    Source:
    @@ -209,7 +209,7 @@ decrypt the message.

    Source:
    @@ -283,7 +283,7 @@ decrypt the message.

    Source:
    @@ -458,7 +458,7 @@ This is needed for constant-time processing. Expected object of the form: { sess
    Source:
    @@ -626,7 +626,7 @@ This is needed for constant-time processing. Expected object of the form: { sess
    Source:
    @@ -794,7 +794,7 @@ This is needed for constant-time processing. Expected object of the form: { sess
    Source:
    @@ -884,7 +884,7 @@ This is needed for constant-time processing. Expected object of the form: { sess
    Source:
    diff --git a/docs/PublicKeyPacket.html b/docs/PublicKeyPacket.html index c0d1ed6f..8911f59c 100644 --- a/docs/PublicKeyPacket.html +++ b/docs/PublicKeyPacket.html @@ -195,7 +195,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -301,7 +301,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -375,7 +375,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -449,7 +449,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -523,7 +523,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -597,7 +597,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -671,7 +671,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -735,7 +735,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -816,7 +816,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -880,7 +880,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -1018,7 +1018,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -1130,7 +1130,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -1220,7 +1220,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -1310,7 +1310,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -1422,7 +1422,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -1530,7 +1530,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -1642,7 +1642,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -1754,7 +1754,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -1866,7 +1866,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -1978,7 +1978,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -2138,7 +2138,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -2250,7 +2250,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -2411,7 +2411,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    diff --git a/docs/PublicSubkeyPacket.html b/docs/PublicSubkeyPacket.html index 1a11c8a2..bae6870f 100644 --- a/docs/PublicSubkeyPacket.html +++ b/docs/PublicSubkeyPacket.html @@ -193,7 +193,7 @@ services.

    Source:
    @@ -315,7 +315,7 @@ services.

    Source:
    @@ -394,7 +394,7 @@ services.

    Source:
    @@ -473,7 +473,7 @@ services.

    Source:
    @@ -552,7 +552,7 @@ services.

    Source:
    @@ -631,7 +631,7 @@ services.

    Source:
    @@ -710,7 +710,7 @@ services.

    Source:
    @@ -779,7 +779,7 @@ services.

    Source:
    @@ -865,7 +865,7 @@ services.

    Source:
    @@ -934,7 +934,7 @@ services.

    Source:
    @@ -1072,7 +1072,7 @@ services.

    Source:
    @@ -1189,7 +1189,7 @@ services.

    Source:
    @@ -1284,7 +1284,7 @@ services.

    Source:
    @@ -1379,7 +1379,7 @@ services.

    Source:
    @@ -1496,7 +1496,7 @@ services.

    Source:
    @@ -1609,7 +1609,7 @@ services.

    Source:
    @@ -1726,7 +1726,7 @@ services.

    Source:
    @@ -1843,7 +1843,7 @@ services.

    Source:
    @@ -1960,7 +1960,7 @@ services.

    Source:
    @@ -2077,7 +2077,7 @@ services.

    Source:
    @@ -2242,7 +2242,7 @@ services.

    Source:
    @@ -2359,7 +2359,7 @@ services.

    Source:
    @@ -2525,7 +2525,7 @@ services.

    Source:
    diff --git a/docs/SecretKeyPacket.html b/docs/SecretKeyPacket.html index d51ed4de..c656a40a 100644 --- a/docs/SecretKeyPacket.html +++ b/docs/SecretKeyPacket.html @@ -191,7 +191,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -308,7 +308,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -387,7 +387,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -466,7 +466,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -545,7 +545,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -624,7 +624,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -688,7 +688,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -767,7 +767,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -831,7 +831,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -905,7 +905,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -984,7 +984,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -1053,7 +1053,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -1134,7 +1134,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -1208,7 +1208,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -1282,7 +1282,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -1361,7 +1361,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -1430,7 +1430,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -1519,7 +1519,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -1614,7 +1614,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -1709,7 +1709,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -1851,7 +1851,7 @@ otherwise calls to this function will throw an error.

    Source:
    @@ -2065,7 +2065,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2189,7 +2189,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2306,7 +2306,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2419,7 +2419,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2536,7 +2536,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2653,7 +2653,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2770,7 +2770,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2888,7 +2888,7 @@ Returns false for gnu-dummy keys and null for public keys.

    Source:
    @@ -2999,7 +2999,7 @@ Returns false for gnu-dummy keys and null for public keys.

    Source:
    @@ -3114,7 +3114,7 @@ Such keys are:

    Source:
    @@ -3266,7 +3266,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
    Source:
    @@ -3411,7 +3411,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
    Source:
    @@ -3501,7 +3501,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
    Source:
    @@ -3625,7 +3625,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
    Source:
    @@ -3791,7 +3791,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
    Source:
    diff --git a/docs/SecretSubkeyPacket.html b/docs/SecretSubkeyPacket.html index a3a608b0..dcd51ea2 100644 --- a/docs/SecretSubkeyPacket.html +++ b/docs/SecretSubkeyPacket.html @@ -190,7 +190,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -312,7 +312,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -391,7 +391,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -470,7 +470,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -549,7 +549,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -628,7 +628,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -697,7 +697,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -776,7 +776,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -845,7 +845,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -924,7 +924,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -1003,7 +1003,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -1072,7 +1072,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -1158,7 +1158,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -1237,7 +1237,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -1316,7 +1316,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -1395,7 +1395,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -1464,7 +1464,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -1558,7 +1558,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -1653,7 +1653,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -1748,7 +1748,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -1895,7 +1895,7 @@ otherwise calls to this function will throw an error.

    Source:
    @@ -2114,7 +2114,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2238,7 +2238,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2355,7 +2355,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2468,7 +2468,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2585,7 +2585,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2702,7 +2702,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2819,7 +2819,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2937,7 +2937,7 @@ Returns false for gnu-dummy keys and null for public keys.

    Source:
    @@ -3053,7 +3053,7 @@ Returns false for gnu-dummy keys and null for public keys.

    Source:
    @@ -3173,7 +3173,7 @@ Such keys are:

    Source:
    @@ -3330,7 +3330,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
    Source:
    @@ -3475,7 +3475,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
    Source:
    @@ -3570,7 +3570,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
    Source:
    @@ -3694,7 +3694,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
    Source:
    @@ -3860,7 +3860,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
    Source:
    diff --git a/docs/Signature.html b/docs/Signature.html index 7431d944..4cda6dc7 100644 --- a/docs/Signature.html +++ b/docs/Signature.html @@ -144,7 +144,7 @@
    Source:
    @@ -322,7 +322,7 @@
    Source:
    @@ -434,7 +434,7 @@
    Source:
    @@ -546,7 +546,7 @@
    Source:
    diff --git a/docs/SignaturePacket.html b/docs/SignaturePacket.html index a8e1c2b2..1fb31bff 100644 --- a/docs/SignaturePacket.html +++ b/docs/SignaturePacket.html @@ -99,7 +99,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    @@ -201,7 +201,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    @@ -271,7 +271,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    @@ -341,7 +341,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    @@ -423,7 +423,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    @@ -599,7 +599,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    @@ -760,7 +760,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    @@ -1048,7 +1048,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    @@ -1427,7 +1427,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    @@ -1546,7 +1546,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    @@ -1654,7 +1654,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    @@ -1765,7 +1765,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    diff --git a/docs/SymEncryptedIntegrityProtectedDataPacket.html b/docs/SymEncryptedIntegrityProtectedDataPacket.html index 1824c4af..ba8e6fec 100644 --- a/docs/SymEncryptedIntegrityProtectedDataPacket.html +++ b/docs/SymEncryptedIntegrityProtectedDataPacket.html @@ -101,7 +101,7 @@ packet.

    Source:
    @@ -203,7 +203,7 @@ packet.

    Source:
    @@ -273,7 +273,7 @@ packet.

    Source:
    @@ -478,7 +478,7 @@ packet.

    Source:
    @@ -738,7 +738,7 @@ packet.

    Source:
    diff --git a/docs/SymEncryptedSessionKeyPacket.html b/docs/SymEncryptedSessionKeyPacket.html index 64f22f5a..3c43dac9 100644 --- a/docs/SymEncryptedSessionKeyPacket.html +++ b/docs/SymEncryptedSessionKeyPacket.html @@ -165,7 +165,7 @@ the Symmetric-Key Encrypted Session Key packet.

    Source:
    @@ -271,7 +271,7 @@ the Symmetric-Key Encrypted Session Key packet.

    Source:
    @@ -345,7 +345,7 @@ the Symmetric-Key Encrypted Session Key packet.

    Source:
    @@ -419,7 +419,7 @@ the Symmetric-Key Encrypted Session Key packet.

    Source:
    @@ -550,7 +550,7 @@ the Symmetric-Key Encrypted Session Key packet.

    Source:
    @@ -761,7 +761,7 @@ the Symmetric-Key Encrypted Session Key packet.

    Source:
    @@ -929,7 +929,7 @@ the Symmetric-Key Encrypted Session Key packet.

    Source:
    @@ -1019,7 +1019,7 @@ the Symmetric-Key Encrypted Session Key packet.

    Source:
    diff --git a/docs/SymmetricallyEncryptedDataPacket.html b/docs/SymmetricallyEncryptedDataPacket.html index dc4f9d2c..fac92832 100644 --- a/docs/SymmetricallyEncryptedDataPacket.html +++ b/docs/SymmetricallyEncryptedDataPacket.html @@ -101,7 +101,7 @@ that form whole OpenPGP messages).

    Source:
    @@ -197,7 +197,7 @@ that form whole OpenPGP messages).

    Source:
    @@ -271,7 +271,7 @@ that form whole OpenPGP messages).

    Source:
    @@ -477,7 +477,7 @@ See RFC 4880 9.2 f
    Source:
    @@ -720,7 +720,7 @@ See RFC 4880 9.2 f
    Source:
    diff --git a/docs/TrustPacket.html b/docs/TrustPacket.html index 07ec3afd..593d3545 100644 --- a/docs/TrustPacket.html +++ b/docs/TrustPacket.html @@ -105,7 +105,7 @@ other than local keyring files.

    Source:
    @@ -216,7 +216,7 @@ Currently not implemented as we ignore trust packets

    Source:
    diff --git a/docs/UserAttributePacket.html b/docs/UserAttributePacket.html index f5e8797f..3c70f4d8 100644 --- a/docs/UserAttributePacket.html +++ b/docs/UserAttributePacket.html @@ -107,7 +107,7 @@ an implementation may use any method desired.

    Source:
    @@ -266,7 +266,7 @@ an implementation may use any method desired.

    Source:
    @@ -427,7 +427,7 @@ an implementation may use any method desired.

    Source:
    @@ -517,7 +517,7 @@ an implementation may use any method desired.

    Source:
    diff --git a/docs/UserIDPacket.html b/docs/UserIDPacket.html index 8bdb8988..52303c5d 100644 --- a/docs/UserIDPacket.html +++ b/docs/UserIDPacket.html @@ -100,7 +100,7 @@ specifies the length of the User ID.

    Source:
    @@ -207,7 +207,7 @@ John Doe john@example.com

    Source:
    @@ -338,7 +338,7 @@ John Doe john@example.com

    Source:
    @@ -495,7 +495,7 @@ John Doe john@example.com

    Source:
    @@ -585,7 +585,7 @@ John Doe john@example.com

    Source:
    diff --git a/docs/global.html b/docs/global.html index 6514b8a2..8412e089 100644 --- a/docs/global.html +++ b/docs/global.html @@ -106,7 +106,7 @@ -

    armor(messageType, body, partIndexopt, partTotalopt, customCommentopt) → {String|ReadableStream.<String>}

    +

    armor(messageType, body, partIndexopt, partTotalopt, customCommentopt, emitChecksumopt, configopt) → {String|ReadableStream.<String>}

    @@ -313,6 +313,73 @@ + + + + emitChecksum + + + + + +Boolean + + + + + + + + + <optional>
    + + + + + + + + + + +

    Whether to compute and include the CRC checksum +(NB: some types of data must not include it, but compliance is left as responsibility of the caller: this function does not carry out any checks)

    + + + + + + + config + + + + + +Object + + + + + + + + + <optional>
    + + + + + + + + + + +

    Full configuration, defaults to openpgp.config

    + + + @@ -352,7 +419,7 @@
    Source:
    @@ -565,7 +632,7 @@
    Source:
    @@ -704,7 +771,7 @@
    Source:
    @@ -1113,7 +1180,7 @@
    Source:
    @@ -1694,7 +1761,7 @@ One of decryptionKeys, sessionkeys or passwords<
    Source:
    @@ -1997,7 +2064,7 @@ This method does not change the original key.

    Source:
    @@ -2356,7 +2423,7 @@ One of decryptionKeys or passwords must be specified.<
    Source:
    @@ -2488,7 +2555,7 @@ Ultimately, the interface provides no advantages and it's only needed because of
    Source:
    @@ -3257,7 +3324,7 @@ must be specified. If signing keys are specified, those will be used to sign the
    Source:
    @@ -3545,7 +3612,7 @@ This method does not change the original key.

    Source:
    @@ -4165,7 +4232,7 @@ At least one of encryptionKeys or passwords must be sp
    Source:
    @@ -4381,7 +4448,7 @@ At least one of encryptionKeys or passwords must be sp
    Source:
    @@ -4982,7 +5049,7 @@ default to main key options, except for sign parameter that default
    Source:
    @@ -5332,7 +5399,7 @@ default to main key options, except for sign parameter that default
    Source:
    @@ -5493,7 +5560,7 @@ default to main key options, except for sign parameter that default
    Source:
    @@ -5632,7 +5699,7 @@ default to main key options, except for sign parameter that default
    Source:
    @@ -5771,7 +5838,7 @@ default to main key options, except for sign parameter that default
    Source:
    @@ -5921,7 +5988,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -6101,7 +6168,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -6245,7 +6312,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -6435,7 +6502,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -6827,7 +6894,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -7068,7 +7135,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -7356,7 +7423,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -7644,7 +7711,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -7938,7 +8005,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -8226,7 +8293,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -8514,7 +8581,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -8802,7 +8869,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -9264,7 +9331,7 @@ to set the same date as the key creation time to ensure that old message signatu
    Source:
    @@ -9793,7 +9860,7 @@ If a revocation certificate is passed, the reasonForRevocation parameter will be
    Source:
    @@ -10008,7 +10075,7 @@ If a revocation certificate is passed, the reasonForRevocation parameter will be
    Source:
    @@ -10557,7 +10624,7 @@ If a revocation certificate is passed, the reasonForRevocation parameter will be
    Source:
    @@ -10719,7 +10786,7 @@ the encoded bytes

    Source:
    @@ -11181,7 +11248,7 @@ an attribute "data" containing a stream of bytes and "type"
    Source:
    @@ -11426,7 +11493,7 @@ The new key includes a revocation certificate that must be removed before return
    Source:
    @@ -11606,7 +11673,7 @@ The new key includes a revocation certificate that must be removed before return
    Source:
    diff --git a/docs/index.html b/docs/index.html index e20f21ed..81ce2ee0 100644 --- a/docs/index.html +++ b/docs/index.html @@ -205,7 +205,7 @@ library to convert back and forth between them.

  • The library implements authenticated encryption (AEAD) as per the "crypto refresh" draft standard using AES-OCB, EAX, or GCM. This makes symmetric encryption faster on platforms with native implementations. However, since the specification is very recent and other OpenPGP implementations are in the process of adopting it, the feature is currently behind a flag. Note: activating this setting can break compatibility with other OpenPGP implementations which have yet to implement the feature. You can enable it by setting openpgp.config.aeadProtect = true. -Note that this setting has a different effect from the one in OpenPGP.js v5, which implemented support for a provisional version of AEAD from RFC4880bis, which was modified in a later draft of the crypto refresh.

    +Note that this setting has a different effect from the one in OpenPGP.js v6, which implemented support for a provisional version of AEAD from RFC4880bis, which was modified in a later draft of the crypto refresh.

    You can change the AEAD mode by setting one of the following options:

    openpgp.config.preferredAEADAlgorithm = openpgp.enums.aead.ocb; // Default (widest ecosystem support), non-native
     openpgp.config.preferredAEADAlgorithm = openpgp.enums.aead.gcm; // Native in WebCrypto and Node.js
    @@ -265,7 +265,7 @@ import * as openpgp from './openpgp.min.mjs';
     

    If you notice missing or incorrect type definitions, feel free to open a PR.

    Examples

    -

    Here are some examples of how to use OpenPGP.js v5. For more elaborate examples and working code, please check out the public API unit tests. If you're upgrading from v4 it might help to check out the changelog and documentation.

    +

    Here are some examples of how to use OpenPGP.js v6. For more elaborate examples and working code, please check out the public API unit tests. If you're upgrading from v4 it might help to check out the changelog and documentation.

    Encrypt and decrypt Uint8Array data with a password

    Encryption will use the algorithm specified in config.preferredSymmetricAlgorithm (defaults to aes256), and decryption will use the algorithm used for encryption.

    (async () => {
    diff --git a/docs/module-config.html b/docs/module-config.html
    index 55a40273..cd13962b 100644
    --- a/docs/module-config.html
    +++ b/docs/module-config.html
    @@ -89,7 +89,7 @@
         
         
    Source:
    @@ -247,7 +247,7 @@ as a global config setting, but can be used for specific function calls (e.g. de
    Source:
    @@ -365,7 +365,7 @@ Must be an integer value from 0 to 56.

    Source:
    @@ -489,7 +489,7 @@ Note: not all OpenPGP implementations are compatible with this option.
  • Source:
    @@ -614,7 +614,7 @@ where key flags were ignored when selecting a key for encryption.

    Source:
    @@ -733,7 +733,7 @@ and have self-signature's creation date that does not match the primary key crea
    Source:
    @@ -854,7 +854,7 @@ This is an insecure setting:

    Source:
    @@ -979,7 +979,7 @@ and deferring checking their integrity until the decrypted stream has been read
    Source:
    @@ -1091,7 +1091,7 @@ and deferring checking their integrity until the decrypted stream has been read
    Source:
    @@ -1213,7 +1213,7 @@ See also constantTimePKCS1DecryptionSupportedSymmetricAlgorithms.Source:
    @@ -1331,7 +1331,7 @@ However, the more algorithms are added, the slower the decryption procedure beco
    Source:
    @@ -1443,7 +1443,7 @@ However, the more algorithms are added, the slower the decryption procedure beco
    Source:
    @@ -1555,7 +1555,7 @@ However, the more algorithms are added, the slower the decryption procedure beco
    Source:
    @@ -1672,7 +1672,7 @@ validation error when the notation is marked as critical.

    Source:
    @@ -1788,7 +1788,7 @@ validation error when the notation is marked as critical.

    Source:
    @@ -1905,7 +1905,7 @@ The default is 2047 since due to a bug, previous versions of OpenPGP.js could ge
    Source:
    @@ -2022,7 +2022,7 @@ The default is 2047 since due to a bug, previous versions of OpenPGP.js could ge
    Source:
    @@ -2139,7 +2139,7 @@ Only has an effect when aeadProtect is set to true.

    Source:
    @@ -2251,7 +2251,7 @@ Only has an effect when aeadProtect is set to true.

    Source:
    @@ -2363,7 +2363,7 @@ Only has an effect when aeadProtect is set to true.

    Source:
    @@ -2475,7 +2475,7 @@ Only has an effect when aeadProtect is set to true.

    Source:
    @@ -2591,7 +2591,7 @@ Only has an effect when aeadProtect is set to true.

    Source:
    @@ -2707,7 +2707,7 @@ Only has an effect when aeadProtect is set to true.

    Source:
    @@ -2823,7 +2823,7 @@ Only has an effect when aeadProtect is set to true.

    Source:
    @@ -2939,119 +2939,7 @@ Only has an effect when aeadProtect is set to true.

    Source:
    - - - - - - - -
    - - - - - - - - -

    (static) revocationsExpire

    - - - - - - - - - - -
    Properties:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    revocationsExpire - - -Boolean - - - -

    If true, expired revocation signatures are ignored

    - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    @@ -3266,7 +3154,7 @@ For more details on the choice of parameters, see https://tools.ietf.org/html/rf
    Source:
    @@ -3385,7 +3273,7 @@ Note: this is the exponent value, not the final number of iterations (refer to s
    Source:
    @@ -3507,7 +3395,7 @@ Note: Argon2 is the strongest option but not all OpenPGP implementations are com
    Source:
    @@ -3619,7 +3507,7 @@ Note: Argon2 is the strongest option but not all OpenPGP implementations are com
    Source:
    @@ -3731,7 +3619,7 @@ Note: Argon2 is the strongest option but not all OpenPGP implementations are com
    Source:
    @@ -3848,7 +3736,7 @@ When false, certain standard curves will not be supported (depending on the plat
    Source:
    @@ -3966,7 +3854,7 @@ Note: not all OpenPGP implementations are compatible with this option.
    Source:
    @@ -4078,7 +3966,7 @@ Note: not all OpenPGP implementations are compatible with this option.
    Source:
    diff --git a/docs/module-crypto.html b/docs/module-crypto.html index b6f6f44f..229882e0 100644 --- a/docs/module-crypto.html +++ b/docs/module-crypto.html @@ -89,7 +89,7 @@
    Source:
    diff --git a/docs/module-crypto_aes_kw.html b/docs/module-crypto_aes_kw.html index 86b2ee47..8f31411f 100644 --- a/docs/module-crypto_aes_kw.html +++ b/docs/module-crypto_aes_kw.html @@ -89,7 +89,7 @@
    Source:
    @@ -308,7 +308,7 @@
    Source:
    @@ -521,7 +521,7 @@
    Source:
    diff --git a/docs/module-crypto_cmac.html b/docs/module-crypto_cmac.html index 51430d3e..7a695b0f 100644 --- a/docs/module-crypto_cmac.html +++ b/docs/module-crypto_cmac.html @@ -90,7 +90,7 @@ native AES-CBC using either the WebCrypto API or Node.js' crypto API.

    Source:
    @@ -195,7 +195,7 @@ The OMAC authors indicate that they will promulgate this modification
    Source:
    @@ -352,7 +352,7 @@ simplify the implementation.

    Source:
    diff --git a/docs/module-crypto_crypto.html b/docs/module-crypto_crypto.html index a79a85c7..57b6174f 100644 --- a/docs/module-crypto_crypto.html +++ b/docs/module-crypto_crypto.html @@ -90,7 +90,7 @@ well as key generation and parameter handling for all public-key cryptosystems.<
    Source:
    @@ -296,7 +296,7 @@ well as key generation and parameter handling for all public-key cryptosystems.<
    Source:
    @@ -458,7 +458,7 @@ See RFC 4880 9.2 f
    Source:
    @@ -619,7 +619,7 @@ See RFC 4880 9.2 f
    Source:
    @@ -848,7 +848,7 @@ See RFC 4880 9.2 f
    Source:
    @@ -1030,7 +1030,7 @@ See RFC 4880 9.2 f
    Source:
    @@ -1170,7 +1170,7 @@ See RFC 4880 9.2 f
    Source:
    @@ -1354,7 +1354,7 @@ See RFC 4880 9.2 f
    Source:
    @@ -1561,7 +1561,7 @@ See RFC 4880 9.2 f
    Source:
    @@ -1745,7 +1745,7 @@ See RFC 4880 9.2 f
    Source:
    @@ -2075,7 +2075,7 @@ See RFC 4880 5.5.3Source:
    @@ -2237,6 +2237,9 @@ See RFC 4880 9.1 f module:enums.symmetric +| + +null @@ -2246,7 +2249,7 @@ See RFC 4880 9.1 f -

    Cipher algorithm

    +

    Cipher algorithm (v3 only)

    @@ -2358,7 +2361,7 @@ See RFC 4880 9.1 f
    Source:
    @@ -2542,7 +2545,7 @@ See RFC 4880 9.1 f
    Source:
    @@ -2749,7 +2752,7 @@ See RFC 4880 9.1 f
    Source:
    @@ -2910,7 +2913,7 @@ See RFC 4880 9.1 f
    Source:
    diff --git a/docs/module-crypto_hash.html b/docs/module-crypto_hash.html index 58d2f69e..c0d81139 100644 --- a/docs/module-crypto_hash.html +++ b/docs/module-crypto_hash.html @@ -89,7 +89,7 @@
    Source:
    @@ -191,7 +191,7 @@
    Source:
    @@ -352,7 +352,7 @@
    Source:
    @@ -513,7 +513,7 @@
    Source:
    diff --git a/docs/module-crypto_hkdf.html b/docs/module-crypto_hkdf.html index 1e3d190a..8387f295 100644 --- a/docs/module-crypto_hkdf.html +++ b/docs/module-crypto_hkdf.html @@ -89,7 +89,7 @@
    Source:
    diff --git a/docs/module-crypto_mode.html b/docs/module-crypto_mode.html index a5f99439..90e5ba3a 100644 --- a/docs/module-crypto_mode.html +++ b/docs/module-crypto_mode.html @@ -89,7 +89,7 @@
    Source:
    @@ -182,7 +182,7 @@
    Source:
    @@ -249,7 +249,7 @@
    Source:
    @@ -316,7 +316,7 @@
    Source:
    @@ -383,7 +383,7 @@
    Source:
    diff --git a/docs/module-crypto_mode_cfb.html b/docs/module-crypto_mode_cfb.html index 1b25c348..2f0bd879 100644 --- a/docs/module-crypto_mode_cfb.html +++ b/docs/module-crypto_mode_cfb.html @@ -236,7 +236,7 @@
    Source:
    @@ -477,7 +477,7 @@
    Source:
    diff --git a/docs/module-crypto_mode_eax.html b/docs/module-crypto_mode_eax.html index 50d97721..60df2b29 100644 --- a/docs/module-crypto_mode_eax.html +++ b/docs/module-crypto_mode_eax.html @@ -90,7 +90,7 @@ native AES-CTR using either the WebCrypto API or Node.js' crypto API.

    Source:
    @@ -296,7 +296,7 @@ native AES-CTR using either the WebCrypto API or Node.js' crypto API.

    Source:
    @@ -480,7 +480,7 @@ native AES-CTR using either the WebCrypto API or Node.js' crypto API.

    Source:
    @@ -665,7 +665,7 @@ native AES-CTR using either the WebCrypto API or Node.js' crypto API.

    Source:
    diff --git a/docs/module-crypto_mode_gcm.html b/docs/module-crypto_mode_gcm.html index 9264ae90..1055359c 100644 --- a/docs/module-crypto_mode_gcm.html +++ b/docs/module-crypto_mode_gcm.html @@ -90,7 +90,7 @@ the WebCrypto api as well as node.js' crypto api.

    Source:
    @@ -273,7 +273,7 @@ the WebCrypto api as well as node.js' crypto api.

    Source:
    diff --git a/docs/module-crypto_mode_ocb.html b/docs/module-crypto_mode_ocb.html index 15b9f96e..87135068 100644 --- a/docs/module-crypto_mode_ocb.html +++ b/docs/module-crypto_mode_ocb.html @@ -89,7 +89,7 @@
    Source:
    @@ -295,7 +295,7 @@
    Source:
    @@ -502,7 +502,7 @@
    Source:
    @@ -686,7 +686,7 @@
    Source:
    diff --git a/docs/module-crypto_pkcs1.html b/docs/module-crypto_pkcs1.html index 77b6196d..d29920d6 100644 --- a/docs/module-crypto_pkcs1.html +++ b/docs/module-crypto_pkcs1.html @@ -89,7 +89,7 @@
    Source:
    @@ -197,7 +197,7 @@
    Source:
    @@ -358,7 +358,7 @@
    Source:
    @@ -578,7 +578,7 @@
    Source:
    @@ -792,7 +792,7 @@
    Source:
    diff --git a/docs/module-crypto_public_key.html b/docs/module-crypto_public_key.html index 44230499..59732ccb 100644 --- a/docs/module-crypto_public_key.html +++ b/docs/module-crypto_public_key.html @@ -89,7 +89,7 @@
    Source:
    @@ -182,7 +182,7 @@
    Source:
    @@ -249,7 +249,7 @@
    Source:
    @@ -316,7 +316,7 @@
    Source:
    @@ -383,7 +383,7 @@
    Source:
    diff --git a/docs/module-crypto_public_key_dsa.html b/docs/module-crypto_public_key_dsa.html index 477c975d..7a9b4f05 100644 --- a/docs/module-crypto_public_key_dsa.html +++ b/docs/module-crypto_public_key_dsa.html @@ -89,7 +89,7 @@
    Source:
    @@ -188,7 +188,7 @@ Expect y == y'

    Source:
    @@ -434,7 +434,7 @@ Expect y == y'

    Source:
    @@ -683,7 +683,7 @@ Expect y == y'

    Source:
    @@ -1005,7 +1005,7 @@ Expect y == y'

    Source:
    diff --git a/docs/module-crypto_public_key_elgamal.html b/docs/module-crypto_public_key_elgamal.html index 8bc4483c..477b656f 100644 --- a/docs/module-crypto_public_key_elgamal.html +++ b/docs/module-crypto_public_key_elgamal.html @@ -89,7 +89,7 @@
    Source:
    @@ -188,7 +188,7 @@ Expect y == y'

    Source:
    @@ -412,7 +412,7 @@ Expect y == y'

    Source:
    @@ -672,7 +672,7 @@ Note that in OpenPGP, the message needs to be padded with PKCS#1 (same as RSA)Source:
    @@ -898,7 +898,7 @@ Note that in OpenPGP, the message needs to be padded with PKCS#1 (same as RSA)Source:
    diff --git a/docs/module-crypto_public_key_elliptic.html b/docs/module-crypto_public_key_elliptic.html index bdbb779e..2ca35aaa 100644 --- a/docs/module-crypto_public_key_elliptic.html +++ b/docs/module-crypto_public_key_elliptic.html @@ -89,7 +89,7 @@
    Source:
    diff --git a/docs/module-crypto_public_key_elliptic_curve.html b/docs/module-crypto_public_key_elliptic_curve.html index 9bb3ccd5..b1e52b8f 100644 --- a/docs/module-crypto_public_key_elliptic_curve.html +++ b/docs/module-crypto_public_key_elliptic_curve.html @@ -89,7 +89,7 @@
    Source:
    @@ -249,7 +249,7 @@
    Source:
    @@ -406,7 +406,7 @@
    Source:
    @@ -632,7 +632,7 @@
    Source:
    @@ -835,7 +835,7 @@
    Source:
    @@ -1066,7 +1066,7 @@ Not suitable for EdDSA (different secret key format)

    Source:
    diff --git a/docs/module-crypto_public_key_elliptic_ecdh.html b/docs/module-crypto_public_key_elliptic_ecdh.html index 585f2f1f..5a5591ca 100644 --- a/docs/module-crypto_public_key_elliptic_ecdh.html +++ b/docs/module-crypto_public_key_elliptic_ecdh.html @@ -91,7 +91,7 @@
    Source:
    @@ -169,7 +169,7 @@
    Source:
    @@ -467,7 +467,7 @@
    Source:
    @@ -720,7 +720,7 @@
    Source:
    @@ -973,7 +973,7 @@
    Source:
    @@ -1176,7 +1176,7 @@
    Source:
    @@ -1337,7 +1337,7 @@
    Source:
    @@ -1540,7 +1540,7 @@
    Source:
    @@ -1747,7 +1747,7 @@
    Source:
    @@ -1977,7 +1977,7 @@
    Source:
    @@ -2157,7 +2157,7 @@
    Source:
    @@ -2360,7 +2360,7 @@
    Source:
    @@ -2540,7 +2540,7 @@
    Source:
    @@ -2766,7 +2766,7 @@
    Source:
    @@ -2946,7 +2946,7 @@
    Source:
    @@ -3077,7 +3077,7 @@
    Source:
    @@ -3155,7 +3155,7 @@
    Source:
    @@ -3453,7 +3453,7 @@
    Source:
    @@ -3706,7 +3706,7 @@
    Source:
    @@ -3959,7 +3959,7 @@
    Source:
    @@ -4162,7 +4162,7 @@
    Source:
    @@ -4323,7 +4323,7 @@
    Source:
    @@ -4526,7 +4526,7 @@
    Source:
    @@ -4733,7 +4733,7 @@
    Source:
    @@ -4963,7 +4963,7 @@
    Source:
    @@ -5143,7 +5143,7 @@
    Source:
    @@ -5346,7 +5346,7 @@
    Source:
    @@ -5526,7 +5526,7 @@
    Source:
    @@ -5752,7 +5752,7 @@
    Source:
    @@ -5932,7 +5932,7 @@
    Source:
    diff --git a/docs/module-crypto_public_key_elliptic_ecdsa.html b/docs/module-crypto_public_key_elliptic_ecdsa.html index ec2cb35c..e8fff15a 100644 --- a/docs/module-crypto_public_key_elliptic_ecdsa.html +++ b/docs/module-crypto_public_key_elliptic_ecdsa.html @@ -89,7 +89,7 @@
    Source:
    @@ -364,7 +364,7 @@
    Source:
    @@ -571,7 +571,7 @@
    Source:
    @@ -847,7 +847,7 @@
    Source:
    @@ -956,7 +956,7 @@ To be used if no native implementation is available for the given curve/operatio
    Source:
    diff --git a/docs/module-crypto_public_key_elliptic_eddsa.html b/docs/module-crypto_public_key_elliptic_eddsa.html index 1f8c76be..a57204fa 100644 --- a/docs/module-crypto_public_key_elliptic_eddsa.html +++ b/docs/module-crypto_public_key_elliptic_eddsa.html @@ -89,7 +89,7 @@
    Source:
    @@ -249,7 +249,7 @@
    Source:
    @@ -521,7 +521,7 @@
    Source:
    @@ -751,7 +751,7 @@
    Source:
    @@ -1027,7 +1027,7 @@
    Source:
    diff --git a/docs/module-crypto_public_key_elliptic_eddsa_legacy.html b/docs/module-crypto_public_key_elliptic_eddsa_legacy.html index efeafadb..24ddbc71 100644 --- a/docs/module-crypto_public_key_elliptic_eddsa_legacy.html +++ b/docs/module-crypto_public_key_elliptic_eddsa_legacy.html @@ -90,7 +90,7 @@ This key type has been deprecated by the crypto-refresh RFC.

    Source:
    @@ -365,7 +365,7 @@ This key type has been deprecated by the crypto-refresh RFC.

    Source:
    @@ -572,7 +572,7 @@ This key type has been deprecated by the crypto-refresh RFC.

    Source:
    @@ -848,7 +848,7 @@ This key type has been deprecated by the crypto-refresh RFC.

    Source:
    diff --git a/docs/module-crypto_public_key_prime.html b/docs/module-crypto_public_key_prime.html index abbe4ce7..e33cc57e 100644 --- a/docs/module-crypto_public_key_prime.html +++ b/docs/module-crypto_public_key_prime.html @@ -89,7 +89,7 @@
    Source:
    @@ -273,7 +273,7 @@ Fails if b^(n-1) mod n != 1.

    Source:
    @@ -476,7 +476,7 @@ Fails if b^(n-1) mod n != 1.

    Source:
    @@ -680,7 +680,7 @@ See HAC Remark 4.28.

    Source:
    @@ -883,7 +883,7 @@ See HAC Remark 4.28.

    Source:
    diff --git a/docs/module-crypto_public_key_rsa.html b/docs/module-crypto_public_key_rsa.html index f2579994..449d2273 100644 --- a/docs/module-crypto_public_key_rsa.html +++ b/docs/module-crypto_public_key_rsa.html @@ -89,7 +89,7 @@
    Source:
    @@ -411,7 +411,7 @@
    Source:
    @@ -647,7 +647,7 @@
    Source:
    @@ -833,7 +833,7 @@
    Source:
    @@ -1186,7 +1186,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

    Source:
    @@ -1462,7 +1462,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

    Source:
    @@ -1738,7 +1738,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

    Source:
    @@ -1846,7 +1846,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

    Source:
    @@ -2123,7 +2123,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

    Source:
    @@ -2308,7 +2308,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

    Source:
    diff --git a/docs/module-crypto_random.html b/docs/module-crypto_random.html index bce5b5f0..bfa1068f 100644 --- a/docs/module-crypto_random.html +++ b/docs/module-crypto_random.html @@ -89,7 +89,7 @@
    Source:
    @@ -272,7 +272,7 @@
    Source:
    @@ -433,7 +433,7 @@
    Source:
    diff --git a/docs/module-crypto_signature.html b/docs/module-crypto_signature.html index 9871733f..9b6b6f5a 100644 --- a/docs/module-crypto_signature.html +++ b/docs/module-crypto_signature.html @@ -89,7 +89,7 @@
    Source:
    @@ -276,7 +276,7 @@ See RFC 4880 5.2.2.<
    Source:
    @@ -555,7 +555,7 @@ for public key and hash algorithms.

    Source:
    @@ -834,7 +834,7 @@ for public key and hash algorithms.

    Source:
    diff --git a/docs/module-encoding_base64.html b/docs/module-encoding_base64.html index 50e2f9c1..b9553f11 100644 --- a/docs/module-encoding_base64.html +++ b/docs/module-encoding_base64.html @@ -168,7 +168,7 @@
    Source:
    @@ -332,7 +332,7 @@
    Source:
    @@ -499,7 +499,7 @@
    Source:
    @@ -686,7 +686,7 @@
    Source:
    diff --git a/docs/module-enums.html b/docs/module-enums.html index 00325c0f..eba0d320 100644 --- a/docs/module-enums.html +++ b/docs/module-enums.html @@ -235,7 +235,7 @@
    Source:
    @@ -499,7 +499,7 @@
    Source:
    @@ -694,7 +694,7 @@
    Source:
    @@ -1119,7 +1119,7 @@
    Source:
    @@ -1323,7 +1323,7 @@ fingerprint format

    Source:
    @@ -1633,7 +1633,7 @@ fingerprint format

    Source:
    @@ -1899,7 +1899,7 @@ possession of more than one person.

    Source:
    @@ -2094,7 +2094,7 @@ possession of more than one person.

    Source:
    @@ -2634,7 +2634,7 @@ possession of more than one person.

    Source:
    @@ -3060,7 +3060,7 @@ possession of more than one person.

    Source:
    @@ -3278,7 +3278,7 @@ possession of more than one person.

    Source:
    @@ -3496,7 +3496,7 @@ possession of more than one person.

    Source:
    @@ -4013,7 +4013,7 @@ document) that cannot include a target subpacket.

    Source:
    @@ -4737,7 +4737,7 @@ document) that cannot include a target subpacket.

    Source:
    @@ -5024,7 +5024,7 @@ document) that cannot include a target subpacket.

    Source:
    @@ -5220,7 +5220,7 @@ document) that cannot include a target subpacket.

    Source:
    @@ -5374,7 +5374,7 @@ document) that cannot include a target subpacket.

    Source:
    @@ -5590,7 +5590,7 @@ document) that cannot include a target subpacket.

    Source:
    diff --git a/docs/module-key_Subkey-Subkey.html b/docs/module-key_Subkey-Subkey.html index d8ef91cc..e7288557 100644 --- a/docs/module-key_Subkey-Subkey.html +++ b/docs/module-key_Subkey-Subkey.html @@ -171,7 +171,7 @@
    Source:
    @@ -281,7 +281,7 @@
    Source:
    @@ -394,7 +394,7 @@
    Source:
    @@ -511,7 +511,7 @@
    Source:
    @@ -628,7 +628,7 @@
    Source:
    @@ -741,7 +741,7 @@
    Source:
    @@ -942,7 +942,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -1055,7 +1055,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -1172,7 +1172,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -1289,7 +1289,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -1406,7 +1406,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -1523,7 +1523,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -1640,7 +1640,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -1757,7 +1757,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -1873,7 +1873,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -2149,7 +2149,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -2487,7 +2487,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -2599,7 +2599,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -2832,7 +2832,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -3044,7 +3044,7 @@ and valid binding signature.

    Source:
    diff --git a/docs/module-key_User-User.html b/docs/module-key_User-User.html index 8e8ef785..85992b4a 100644 --- a/docs/module-key_User-User.html +++ b/docs/module-key_User-User.html @@ -171,7 +171,7 @@
    Source:
    @@ -404,7 +404,7 @@
    Source:
    @@ -516,7 +516,7 @@
    Source:
    @@ -789,7 +789,7 @@
    Source:
    @@ -1127,7 +1127,7 @@
    Source:
    @@ -1239,7 +1239,7 @@
    Source:
    @@ -1442,7 +1442,7 @@
    Source:
    @@ -1623,7 +1623,7 @@ and validity of self signature.

    Source:
    @@ -1887,7 +1887,7 @@ and validity of self signature.

    Source:
    @@ -2154,7 +2154,7 @@ Signature validity is null if the verification keys do not correspond to the cer
    Source:
    diff --git a/docs/module-key_helper.html b/docs/module-key_helper.html index df586d3f..adae72ab 100644 --- a/docs/module-key_helper.html +++ b/docs/module-key_helper.html @@ -89,7 +89,7 @@
    Source:
    @@ -281,7 +281,7 @@
    Source:
    @@ -518,7 +518,7 @@
    Source:
    @@ -928,7 +928,7 @@
    Source:
    @@ -1116,7 +1116,7 @@ The expiration time of the signature is ignored.

    Source:
    @@ -1352,7 +1352,7 @@ The expiration time of the signature is ignored.

    Source:
    @@ -1624,7 +1624,7 @@ The expiration time of the signature is ignored.

    Source:
    @@ -1896,7 +1896,7 @@ The expiration time of the signature is ignored.

    Source:
    @@ -2200,7 +2200,7 @@ The expiration time of the signature is ignored.

    Source:
    @@ -2507,7 +2507,7 @@ The expiration time of the signature is ignored.

    Source:
    @@ -2806,7 +2806,7 @@ The expiration time of the signature is ignored.

    Source:
    diff --git a/docs/module-packet_packet.html b/docs/module-packet_packet.html index 4ed6b6e4..b7537336 100644 --- a/docs/module-packet_packet.html +++ b/docs/module-packet_packet.html @@ -89,7 +89,7 @@
    Source:
    @@ -275,7 +275,7 @@
    Source:
    @@ -436,7 +436,7 @@
    Source:
    @@ -621,7 +621,7 @@ string

    Source:
    @@ -783,7 +783,7 @@ string

    Source:
    diff --git a/docs/module-type_ecdh_symkey.html b/docs/module-type_ecdh_symkey.html index b6fe97e6..dac888c9 100644 --- a/docs/module-type_ecdh_symkey.html +++ b/docs/module-type_ecdh_symkey.html @@ -89,7 +89,7 @@
    Source:
    diff --git a/docs/module-type_kdf_params-KDFParams.html b/docs/module-type_kdf_params-KDFParams.html index 87d5ca38..24b9917a 100644 --- a/docs/module-type_kdf_params-KDFParams.html +++ b/docs/module-type_kdf_params-KDFParams.html @@ -163,7 +163,7 @@
    Source:
    @@ -322,7 +322,7 @@
    Source:
    @@ -434,7 +434,7 @@
    Source:
    diff --git a/docs/module-type_keyid-KeyID.html b/docs/module-type_keyid-KeyID.html index 9cdefc53..852cc2bb 100644 --- a/docs/module-type_keyid-KeyID.html +++ b/docs/module-type_keyid-KeyID.html @@ -101,7 +101,7 @@ formed.

    Source:
    @@ -295,7 +295,7 @@ formed.

    Source:
    @@ -385,7 +385,7 @@ formed.

    Source:
    @@ -497,7 +497,7 @@ formed.

    Source:
    @@ -658,7 +658,7 @@ formed.

    Source:
    @@ -748,7 +748,7 @@ formed.

    Source:
    @@ -860,7 +860,7 @@ formed.

    Source:
    diff --git a/docs/module-type_oid.html b/docs/module-type_oid.html index 8d23ee8a..3d481267 100644 --- a/docs/module-type_oid.html +++ b/docs/module-type_oid.html @@ -100,7 +100,7 @@ sequence of octets is the valid representation of a curve OID.

    Source:
    diff --git a/docs/module-type_s2k-GenericS2K.html b/docs/module-type_s2k-GenericS2K.html index 18af6ab1..ad84a251 100644 --- a/docs/module-type_s2k-GenericS2K.html +++ b/docs/module-type_s2k-GenericS2K.html @@ -153,7 +153,7 @@
    Source:
    @@ -262,7 +262,7 @@
    Source:
    @@ -332,7 +332,7 @@
    Source:
    @@ -406,7 +406,7 @@
    Source:
    @@ -480,7 +480,7 @@
    Source:
    @@ -612,7 +612,7 @@ hashAlgorithm

    Source:
    @@ -774,7 +774,7 @@ hashAlgorithm hash length

    Source:
    @@ -886,7 +886,7 @@ hashAlgorithm hash length

    Source:
    diff --git a/docs/module-type_s2k.html b/docs/module-type_s2k.html index afc40e6a..b785e0a2 100644 --- a/docs/module-type_s2k.html +++ b/docs/module-type_s2k.html @@ -95,7 +95,7 @@ symmetrically encrypted messages.

    Source:
    diff --git a/docs/module-type_x25519x448_symkey.html b/docs/module-type_x25519x448_symkey.html index cd9071b4..c583c525 100644 --- a/docs/module-type_x25519x448_symkey.html +++ b/docs/module-type_x25519x448_symkey.html @@ -91,7 +91,7 @@ the former includes an algorithm byte preceeding the encrypted session key.

    <
    Source:
    diff --git a/docs/module-util.html b/docs/module-util.html index fa68cd6a..1059ab7f 100644 --- a/docs/module-util.html +++ b/docs/module-util.html @@ -89,7 +89,7 @@
    Source:
    diff --git a/package-lock.json b/package-lock.json index cea84044..af51d0d7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "openpgp", - "version": "6.0.0-alpha.1", + "version": "6.0.0-beta.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "openpgp", - "version": "6.0.0-alpha.1", + "version": "6.0.0-beta.0", "license": "LGPL-3.0+", "devDependencies": { "@openpgp/asmcrypto.js": "^3.1.0", diff --git a/package.json b/package.json index 206d6639..a84c243b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "openpgp", "description": "OpenPGP.js is a Javascript implementation of the OpenPGP protocol. This is defined in RFC 4880.", - "version": "6.0.0-alpha.1", + "version": "6.0.0-beta.0", "license": "LGPL-3.0+", "homepage": "https://openpgpjs.org/", "engines": { From f3f1ab931b24a39ae5738b595b25d10744912b85 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Fri, 19 Apr 2024 16:25:48 +0200 Subject: [PATCH 127/201] Tests: update SEIPD version check to no longer depend on `config.aeadProtect` The logic was updated in github.com/openpgpjs/openpgpjs/pull/1678 . The tests worked anyway thanks to the config option matching the (monkey patched) keys' feature flags, which are the deciding factor for whether to use AEAD. --- test/general/openpgp.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/test/general/openpgp.js b/test/general/openpgp.js index ad5275b8..070af1b6 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -2213,7 +2213,7 @@ VFBLG8uc9IiaKann/DYBAJcZNZHRSfpDoV2pUA5EAEi2MdjxkRysFQnYPRAu ).to.be.rejectedWith(/Primary key is expired/); }); - it('uses AEAD when the encryption key prefs support it (SEIPv2', async function() { + it('uses AEAD when the encryption key prefs support it (SEIPDv2', async function() { const v4PrivateKeyWithOCBPref = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- xUsGY4d/4xsAAAAg+U2nu0jWCmHlZ3BqZYfQMxmZu52JGggkLq2EVD34laMAGXKB @@ -2859,7 +2859,8 @@ XfA3pqV4mTzF }; return openpgp.encrypt(encOpt).then(async function (encrypted) { decOpt.message = await openpgp.readMessage({ armoredMessage: encrypted }); - expect(decOpt.message.packets.findPacket(openpgp.enums.packet.symEncryptedIntegrityProtectedData).version === 2).to.equal(openpgp.config.aeadProtect); + const supportsSEIPDv2 = !!(publicKey.users[0].selfCertifications[0].features?.[0] & openpgp.enums.features.seipdv2); + expect(decOpt.message.packets.findPacket(openpgp.enums.packet.symEncryptedIntegrityProtectedData).version).to.equal(supportsSEIPDv2 ? 2 : 1); return openpgp.decrypt(decOpt); }).then(async function (decrypted) { expect(decrypted.data).to.equal(plaintext); @@ -2883,7 +2884,8 @@ XfA3pqV4mTzF }; return openpgp.encrypt(encOpt).then(async function (encrypted) { decOpt.message = await openpgp.readMessage({ armoredMessage: encrypted }); - expect(decOpt.message.packets.findPacket(openpgp.enums.packet.symEncryptedIntegrityProtectedData).version === 2).to.equal(openpgp.config.aeadProtect); + const supportsSEIPDv2 = !!(publicKey.users[0].selfCertifications[0].features?.[0] & openpgp.enums.features.seipdv2); + expect(decOpt.message.packets.findPacket(openpgp.enums.packet.symEncryptedIntegrityProtectedData).version).to.equal(supportsSEIPDv2 ? 2 : 1); return openpgp.decrypt(decOpt); }).then(async function (decrypted) { expect(decrypted.data).to.equal(plaintext); @@ -2906,7 +2908,7 @@ XfA3pqV4mTzF }; return openpgp.encrypt(encOpt).then(async function (encrypted) { decOpt.message = await openpgp.readMessage({ armoredMessage: encrypted }); - expect(decOpt.message.packets.findPacket(openpgp.enums.packet.symEncryptedIntegrityProtectedData).version === 2).to.equal(false); + expect(decOpt.message.packets.findPacket(openpgp.enums.packet.symEncryptedIntegrityProtectedData).version).to.equal(1); return openpgp.decrypt(decOpt); }).then(async function (decrypted) { expect(decrypted.data).to.equal(plaintext); @@ -2923,6 +2925,7 @@ XfA3pqV4mTzF }; return openpgp.generateKey(genOpt).then(async function(newKey) { + const supportsSEIPDv2 = openpgp.config.aeadProtect; const newPublicKey = await openpgp.readKey({ armoredKey: newKey.publicKey }); const newPrivateKey = await openpgp.readKey({ armoredKey: newKey.privateKey }); @@ -2937,7 +2940,7 @@ XfA3pqV4mTzF }; return openpgp.encrypt(encOpt).then(async function (encrypted) { decOpt.message = await openpgp.readMessage({ armoredMessage: encrypted }); - expect(decOpt.message.packets.findPacket(openpgp.enums.packet.symEncryptedIntegrityProtectedData).version === 2).to.equal(openpgp.config.aeadProtect); + expect(decOpt.message.packets.findPacket(openpgp.enums.packet.symEncryptedIntegrityProtectedData).version).to.equal(supportsSEIPDv2 ? 2 : 1); return openpgp.decrypt(decOpt); }).then(async function (decrypted) { expect(decrypted.data).to.equal(plaintext); @@ -2953,6 +2956,7 @@ XfA3pqV4mTzF const newKey = await openpgp.generateKey({ userIDs: [{ name: 'Test User', email: 'text@example.com' }] }); + const supportsSEIPDv2 = openpgp.config.aeadProtect; const newPublicKey = await openpgp.readKey({ armoredKey: newKey.publicKey }); const newPrivateKey = await openpgp.readKey({ armoredKey: newKey.privateKey }); @@ -2966,7 +2970,7 @@ XfA3pqV4mTzF detached: true }); const message = await openpgp.readMessage({ armoredMessage: encrypted }); - expect(message.packets.findPacket(openpgp.enums.packet.symEncryptedIntegrityProtectedData).version === 2).to.equal(openpgp.config.aeadProtect); + expect(message.packets.findPacket(openpgp.enums.packet.symEncryptedIntegrityProtectedData).version).to.equal(supportsSEIPDv2 ? 2 : 1); const decrypted = await openpgp.decrypt({ message, signature: await openpgp.readSignature({ armoredSignature: signed }), From 7e2ea3f871f5d58338497bbc1f0353ced8acecf2 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Fri, 19 Apr 2024 16:31:16 +0200 Subject: [PATCH 128/201] CI: update cache actions to Node 20 --- .github/workflows/tests.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 539020d7..609c3087 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -15,7 +15,7 @@ jobs: - uses: actions/setup-node@v4 - name: Check for cached folders id: cache-full - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | dist @@ -44,7 +44,7 @@ jobs: node-version: ${{ matrix.node-version }} - run: npm ci --ignore-scripts # for mocha - name: Retrieve cached folders - uses: actions/cache/restore@v3 + uses: actions/cache/restore@v4 id: cache-full with: # test/lib is not needed, but the path must be specified fully for a cache-hit @@ -65,7 +65,7 @@ jobs: - uses: actions/setup-node@v4 - name: Retrieve cached built folders - uses: actions/cache/restore@v3 + uses: actions/cache/restore@v4 id: cache-full with: path: | @@ -86,7 +86,7 @@ jobs: echo "version=$PLAYWRIGHT_VERSION" >> $GITHUB_OUTPUT - name: Check for cached browsers id: cache-playwright-browsers - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ~/.cache/ms-playwright key: playwright-browsers-${{ steps.playwright-version.outputs.version }} @@ -123,7 +123,7 @@ jobs: run: npm ci --ignore-scripts - name: Retrieve cached dist folder - uses: actions/cache/restore@v3 + uses: actions/cache/restore@v4 id: cache-full with: path: | @@ -158,7 +158,7 @@ jobs: - uses: actions/setup-node@v4 - run: npm ci --ignore-scripts # TS - name: Retrieve cached folders - uses: actions/cache/restore@v3 + uses: actions/cache/restore@v4 id: cache-full with: path: | @@ -177,7 +177,7 @@ jobs: - uses: actions/setup-node@v4 - run: npm ci --ignore-scripts # linter - name: Retrieve cached folders - uses: actions/cache/restore@v3 + uses: actions/cache/restore@v4 id: cache-full with: path: | From d1a24d175838dbfe2b3c4443cab0ee7145fd75ec Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Thu, 2 May 2024 19:09:23 +0200 Subject: [PATCH 129/201] Drop support for platforms without native BigInt (e.g. Safari <14) Remove BN.js fallback, and only keep native BigInteger interface (for algorithmic constant-time functions). Also, add support for TS modules, to move some over from the forked noble repos. --- package-lock.json | 50 +++ package.json | 2 + rollup.config.js | 5 + src/biginteger.js | 20 - src/biginteger.ts | 498 ++++++++++++++++++++++++ src/crypto/public_key/dsa.js | 7 +- src/crypto/public_key/elgamal.js | 8 +- src/crypto/public_key/elliptic/ecdsa.js | 5 +- src/crypto/public_key/prime.js | 9 +- src/crypto/public_key/rsa.js | 15 +- src/crypto/random.js | 3 +- src/util.js | 3 - test/crypto/validate.js | 4 +- tsconfig.json | 2 +- 14 files changed, 565 insertions(+), 66 deletions(-) delete mode 100644 src/biginteger.js create mode 100644 src/biginteger.ts diff --git a/package-lock.json b/package-lock.json index af51d0d7..e9b5d90d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-replace": "^5.0.5", "@rollup/plugin-terser": "^0.4.4", + "@rollup/plugin-typescript": "^11.1.6", "@rollup/plugin-wasm": "^6.2.2", "@types/chai": "^4.3.14", "argon2id": "^1.0.1", @@ -49,6 +50,7 @@ "rollup": "^4.14.1", "sinon": "^17.0.1", "ts-node": "^10.9.2", + "tslib": "^2.6.2", "tsx": "^4.7.2", "typescript": "^5.4.4", "web-streams-polyfill": "^3.3.3" @@ -1007,6 +1009,32 @@ } } }, + "node_modules/@rollup/plugin-typescript": { + "version": "11.1.6", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.6.tgz", + "integrity": "sha512-R92yOmIACgYdJ7dJ97p4K69I8gg6IEHt8M7dUBxN3W6nrO8uUxX5ixl0yU/N3aZTi8WhPuICvOHXQvF6FaykAA==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^5.1.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.14.0||^3.0.0||^4.0.0", + "tslib": "*", + "typescript": ">=3.7.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + }, + "tslib": { + "optional": true + } + } + }, "node_modules/@rollup/plugin-wasm": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/@rollup/plugin-wasm/-/plugin-wasm-6.2.2.tgz", @@ -7402,6 +7430,12 @@ "strip-bom": "^3.0.0" } }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + }, "node_modules/tsx": { "version": "4.7.2", "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.2.tgz", @@ -8561,6 +8595,16 @@ "terser": "^5.17.4" } }, + "@rollup/plugin-typescript": { + "version": "11.1.6", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.6.tgz", + "integrity": "sha512-R92yOmIACgYdJ7dJ97p4K69I8gg6IEHt8M7dUBxN3W6nrO8uUxX5ixl0yU/N3aZTi8WhPuICvOHXQvF6FaykAA==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^5.1.0", + "resolve": "^1.22.1" + } + }, "@rollup/plugin-wasm": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/@rollup/plugin-wasm/-/plugin-wasm-6.2.2.tgz", @@ -13397,6 +13441,12 @@ "strip-bom": "^3.0.0" } }, + "tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + }, "tsx": { "version": "4.7.2", "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.2.tgz", diff --git a/package.json b/package.json index a84c243b..5ecc8bd0 100644 --- a/package.json +++ b/package.json @@ -74,6 +74,7 @@ "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-replace": "^5.0.5", "@rollup/plugin-terser": "^0.4.4", + "@rollup/plugin-typescript": "^11.1.6", "@rollup/plugin-wasm": "^6.2.2", "@types/chai": "^4.3.14", "argon2id": "^1.0.1", @@ -102,6 +103,7 @@ "rollup": "^4.14.1", "sinon": "^17.0.1", "ts-node": "^10.9.2", + "tslib": "^2.6.2", "tsx": "^4.7.2", "typescript": "^5.4.4", "web-streams-polyfill": "^3.3.3" diff --git a/rollup.config.js b/rollup.config.js index c29e0e51..8cdc1458 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -9,6 +9,7 @@ import commonjs from '@rollup/plugin-commonjs'; import replace from '@rollup/plugin-replace'; import terser from '@rollup/plugin-terser'; import { wasm } from '@rollup/plugin-wasm'; +import typescript from '@rollup/plugin-typescript'; // ESlint does not support JSON module imports yet, see https://github.com/eslint/eslint/discussions/15305 // import pkg from './package.json' assert { type: 'json' }; @@ -63,6 +64,7 @@ export default Object.assign([ resolve({ browser: true }), + typescript(), commonjs({ ignore: nodeBuiltinModules.concat(nodeDependencies) }), @@ -85,6 +87,7 @@ export default Object.assign([ ].map(options => ({ ...options, inlineDynamicImports: true })), plugins: [ resolve(), + typescript(), commonjs(), replace({ 'OpenPGP.js VERSION': `OpenPGP.js ${pkg.version}` @@ -104,6 +107,7 @@ export default Object.assign([ resolve({ browser: true }), + typescript(), commonjs({ ignore: nodeBuiltinModules.concat(nodeDependencies) }), @@ -130,6 +134,7 @@ export default Object.assign([ resolve({ browser: true }), + typescript(), commonjs({ ignore: nodeBuiltinModules.concat(nodeDependencies), requireReturnsDefault: 'preferred' diff --git a/src/biginteger.js b/src/biginteger.js deleted file mode 100644 index bd114984..00000000 --- a/src/biginteger.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * We don't use the BigIntegerInterface wrapper from noble-hashes because: - * - importing the instance results in it being shared with noble-hashes, which separately calls `setImplementation()` - * on load, causing it to throw due to duplicate initialization. - * - even duplicating the interface code here to keep a separate instance requires handing a race-conditions the first time - * `getBigInteger` is called, when the code needs to check if the implementation is set, and initialize it if not. - * Ultimately, the interface provides no advantages and it's only needed because of TS. - */ -const detectBigInt = () => typeof BigInt !== 'undefined'; -export async function getBigInteger() { - if (detectBigInt()) { - // NativeBigInteger is small, so it's imported in isolation (it could also be imported at the top level) - const { default: NativeBigInteger } = await import('@openpgp/noble-hashes/esm/biginteger/native.interface'); - return NativeBigInteger; - } else { - // FallbackBigInteger relies on large BN.js lib, which is also used by noble-hashes and noble-curves - const { default: FallbackBigInteger } = await import('@openpgp/noble-hashes/esm/biginteger/bn.interface'); - return FallbackBigInteger; - } -} diff --git a/src/biginteger.ts b/src/biginteger.ts new file mode 100644 index 00000000..c99e5fcd --- /dev/null +++ b/src/biginteger.ts @@ -0,0 +1,498 @@ +/** + * @fileoverview + * BigInteger implementation of basic operations + * that wraps the native BigInt library. + * Operations are not constant time, + * but we try and limit timing leakage where we can + */ +export default class BigInteger { + private value: bigint; + /** + * Get a BigInteger (input must be big endian for strings and arrays) + * @param {Number|String|Uint8Array} n - Value to convert + * @throws {Error} on null or undefined input + */ + constructor(n: Uint8Array | string | number | bigint) { + if (n === undefined) { + throw new Error('Invalid BigInteger input'); + } + + if (n instanceof Uint8Array) { + const bytes = n; + const hexAlphabet = '0123456789ABCDEF'; + let s = ''; + bytes.forEach((v) => { + s += hexAlphabet[v >> 4] + hexAlphabet[v & 15]; + }); + this.value = BigInt('0x0' + s); + } else { + this.value = BigInt(n); + } + } + + clone() { + return new BigInteger(this.value); + } + + /** + * BigInteger increment in place + */ + iinc() { + this.value++; + return this; + } + + /** + * BigInteger increment + * @returns {BigInteger} this + 1. + */ + inc() { + return this.clone().iinc(); + } + + /** + * BigInteger decrement in place + */ + idec() { + this.value--; + return this; + } + + /** + * BigInteger decrement + * @returns {BigInteger} this - 1. + */ + dec() { + return this.clone().idec(); + } + + /** + * BigInteger addition in place + * @param {BigInteger} x - Value to add + */ + iadd(x: BigInteger) { + this.value += x.value; + return this; + } + + /** + * BigInteger addition + * @param {BigInteger} x - Value to add + * @returns {BigInteger} this + x. + */ + add(x: BigInteger) { + return this.clone().iadd(x); + } + + /** + * BigInteger subtraction in place + * @param {BigInteger} x - Value to subtract + */ + isub(x: BigInteger) { + this.value -= x.value; + return this; + } + + /** + * BigInteger subtraction + * @param {BigInteger} x - Value to subtract + * @returns {BigInteger} this - x. + */ + sub(x: BigInteger) { + return this.clone().isub(x); + } + + /** + * BigInteger multiplication in place + * @param {BigInteger} x - Value to multiply + */ + imul(x: BigInteger) { + this.value *= x.value; + return this; + } + + /** + * BigInteger multiplication + * @param {BigInteger} x - Value to multiply + * @returns {BigInteger} this * x. + */ + mul(x: BigInteger) { + return this.clone().imul(x); + } + + /** + * Compute value modulo m, in place + * @param {BigInteger} m - Modulo + */ + imod(m: BigInteger) { + this.value %= m.value; + if (this.isNegative()) { + this.iadd(m); + } + return this; + } + + /** + * Compute value modulo m + * @param {BigInteger} m - Modulo + * @returns {BigInteger} this mod m. + */ + mod(m: BigInteger) { + return this.clone().imod(m); + } + + /** + * Compute modular exponentiation using square and multiply + * @param {BigInteger} e - Exponent + * @param {BigInteger} n - Modulo + * @returns {BigInteger} this ** e mod n. + */ + modExp(e: BigInteger, n: BigInteger) { + if (n.isZero()) throw Error('Modulo cannot be zero'); + if (n.isOne()) return new BigInteger(0); + if (e.isNegative()) throw Error('Unsopported negative exponent'); + + let exp = e.value; + let x = this.value; + + x %= n.value; + let r = BigInt(1); + while (exp > BigInt(0)) { + const lsb = exp & BigInt(1); + exp >>= BigInt(1); // e / 2 + // Always compute multiplication step, to reduce timing leakage + const rx = (r * x) % n.value; + // Update r only if lsb is 1 (odd exponent) + r = lsb ? rx : r; + x = (x * x) % n.value; // Square + } + return new BigInteger(r); + } + + /** + * Compute the inverse of this value modulo n + * Note: this and and n must be relatively prime + * @param {BigInteger} n - Modulo + * @returns {BigInteger} x such that this*x = 1 mod n + * @throws {Error} if the inverse does not exist + */ + modInv(n: BigInteger) { + const { gcd, x } = this._egcd(n); + if (!gcd.isOne()) { + throw new Error('Inverse does not exist'); + } + return x.add(n).mod(n); + } + + /** + * BigInteger division, in place + * @param {BigInteger} n - Value to divide + */ + idiv(n: BigInteger) { + this.value /= n.value; + return this; + } + + /** + * BigInteger division + * @param {BigInteger} n - Value to divide + * @returns {BigInteger} this divded by n. + */ + div(n: BigInteger) { + return this.clone().idiv(n); + } + + /** + * Extended Eucleadian algorithm (http://anh.cs.luc.edu/331/notes/xgcd.pdf) + * Given a = this and b, compute (x, y) such that ax + by = gdc(a, b). + * Negative numbers are also supported. + * @param {BigInteger} b - Second operand + * @returns {{ gcd, x, y: BigInteger }} + */ + private _egcd(bInput: BigInteger) { + let x = BigInt(0); + let y = BigInt(1); + let xPrev = BigInt(1); + let yPrev = BigInt(0); + + // Deal with negative numbers: run algo over absolute values, + // and "move" the sign to the returned x and/or y. + // See https://math.stackexchange.com/questions/37806/extended-euclidean-algorithm-with-negative-numbers + let a = this.abs().value; + let b = bInput.abs().value; + const aNegated = this.isNegative(); + const bNegated = bInput.isNegative(); + + while (b !== BigInt(0)) { + const q = a / b; + let tmp = x; + x = xPrev - q * x; + xPrev = tmp; + + tmp = y; + y = yPrev - q * y; + yPrev = tmp; + + tmp = b; + b = a % b; + a = tmp; + } + + return { + x: new BigInteger(aNegated? -xPrev : xPrev), + y: new BigInteger(bNegated ? -yPrev : yPrev), + gcd: new BigInteger(a), + }; + } + + /** + * Compute greatest common divisor between this and n + * @param {BigInteger} b - Operand + * @returns {BigInteger} gcd + */ + gcd(bInput: BigInteger) { + let a = this.value; + let b = bInput.value; + while (b !== BigInt(0)) { + const tmp = b; + b = a % b; + a = tmp; + } + return new BigInteger(a); + } + + /** + * Shift this to the left by x, in place + * @param {BigInteger} x - Shift value + */ + ileftShift(x: BigInteger) { + this.value <<= x.value; + return this; + } + + /** + * Shift this to the left by x + * @param {BigInteger} x - Shift value + * @returns {BigInteger} this << x. + */ + leftShift(x: BigInteger) { + return this.clone().ileftShift(x); + } + + /** + * Shift this to the right by x, in place + * @param {BigInteger} x - Shift value + */ + irightShift(x: BigInteger) { + this.value >>= x.value; + return this; + } + + /** + * Shift this to the right by x + * @param {BigInteger} x - Shift value + * @returns {BigInteger} this >> x. + */ + rightShift(x: BigInteger) { + return this.clone().irightShift(x); + } + + ixor(x: BigInteger) { + this.value ^= x.value; + return this; + } + + xor(x: BigInteger) { + return this.clone().ixor(x); + } + + ibitwiseAnd(x: BigInteger) { + this.value &= x.value; + return this; + } + + bitwiseAnd(x: BigInteger) { + return this.clone().ibitwiseAnd(x); + } + + ibitwiseOr(x: BigInteger) { + this.value |= x.value; + return this; + } + + /** + * Whether this value is equal to x + * @param {BigInteger} x + * @returns {Boolean} + */ + equal(x: BigInteger) { + return this.value === x.value; + } + + /** + * Whether this value is less than x + * @param {BigInteger} x + * @returns {Boolean} + */ + lt(x: BigInteger) { + return this.value < x.value; + } + + /** + * Whether this value is less than or equal to x + * @param {BigInteger} x + * @returns {Boolean} + */ + lte(x: BigInteger) { + return this.value <= x.value; + } + + /** + * Whether this value is greater than x + * @param {BigInteger} x + * @returns {Boolean} + */ + gt(x: BigInteger) { + return this.value > x.value; + } + + /** + * Whether this value is greater than or equal to x + * @param {BigInteger} x + * @returns {Boolean} + */ + gte(x: BigInteger) { + return this.value >= x.value; + } + + isZero() { + return this.value === BigInt(0); + } + + isOne() { + return this.value === BigInt(1); + } + + isNegative() { + return this.value < BigInt(0); + } + + isEven() { + return !(this.value & BigInt(1)); + } + + abs() { + const res = this.clone(); + if (this.isNegative()) { + res.value = -res.value; + } + return res; + } + + negate() { + const res = this.clone(); + res.value = -res.value; + return res; + } + + /** + * Get this value as a string + * @returns {String} this value. + */ + toString() { + return this.value.toString(); + } + + /** + * Get this value as an exact Number (max 53 bits) + * Fails if this value is too large + * @returns {Number} + */ + toNumber() { + const number = Number(this.value); + if (number > Number.MAX_SAFE_INTEGER) { + // We throw and error to conform with the bn.js implementation + throw new Error('Number can only safely store up to 53 bits'); + } + return number; + } + + /** + * Get value of i-th bit + * @param {Number} i - Bit index + * @returns {Number} Bit value. + */ + getBit(i: number) { + const bit = (this.value >> BigInt(i)) & BigInt(1); + return bit === BigInt(0) ? 0 : 1; + } + + /** + * Compute bit length + * @returns {Number} Bit length. + */ + bitLength() { + const zero = new BigInteger(0); + const one = new BigInteger(1); + const negOne = new BigInteger(-1); + + // -1n >> -1n is -1n + // 1n >> 1n is 0n + const target = this.isNegative() ? negOne : zero; + let bitlen = 1; + const tmp = this.clone(); + while (!tmp.irightShift(one).equal(target)) { + bitlen++; + } + return bitlen; + } + + /** + * Compute byte length + * @returns {Number} Byte length. + */ + byteLength() { + const zero = new BigInteger(0); + const negOne = new BigInteger(-1); + + const target = this.isNegative() ? negOne : zero; + const eight = new BigInteger(8); + let len = 1; + const tmp = this.clone(); + while (!tmp.irightShift(eight).equal(target)) { + len++; + } + return len; + } + + /** + * Get Uint8Array representation of this number + * @param {String} endian - Endianess of output array (defaults to 'be') + * @param {Number} length - Of output array + * @returns {Uint8Array} + */ + toUint8Array(endian = 'be', length: number) { + // we get and parse the hex string (https://coolaj86.com/articles/convert-js-bigints-to-typedarrays/) + // this is faster than shift+mod iterations + let hex = this.value.toString(16); + if (hex.length % 2 === 1) { + hex = '0' + hex; + } + + const rawLength = hex.length / 2; + const bytes = new Uint8Array(length || rawLength); + // parse hex + const offset = length ? length - rawLength : 0; + let i = 0; + while (i < rawLength) { + bytes[i + offset] = parseInt(hex.slice(2 * i, 2 * i + 2), 16); + i++; + } + + if (endian !== 'be') { + bytes.reverse(); + } + + return bytes; + } +} diff --git a/src/crypto/public_key/dsa.js b/src/crypto/public_key/dsa.js index d3fb6e8c..80da4328 100644 --- a/src/crypto/public_key/dsa.js +++ b/src/crypto/public_key/dsa.js @@ -22,6 +22,7 @@ import { getRandomBigInteger } from '../random'; import util from '../../util'; import { isProbablePrime } from './prime'; +import BigInteger from '../../biginteger'; /* TODO regarding the hash function, read: @@ -41,8 +42,6 @@ import { isProbablePrime } from './prime'; * @async */ export async function sign(hashAlgo, hashed, g, p, q, x) { - const BigInteger = await util.getBigInteger(); - const one = new BigInteger(1); p = new BigInteger(p); q = new BigInteger(q); @@ -101,8 +100,6 @@ export async function sign(hashAlgo, hashed, g, p, q, x) { * @async */ export async function verify(hashAlgo, r, s, hashed, g, p, q, y) { - const BigInteger = await util.getBigInteger(); - const zero = new BigInteger(0); r = new BigInteger(r); s = new BigInteger(s); @@ -145,8 +142,6 @@ export async function verify(hashAlgo, r, s, hashed, g, p, q, y) { * @async */ export async function validateParams(p, q, g, y, x) { - const BigInteger = await util.getBigInteger(); - p = new BigInteger(p); q = new BigInteger(q); g = new BigInteger(g); diff --git a/src/crypto/public_key/elgamal.js b/src/crypto/public_key/elgamal.js index 2dc2c2fd..a64b9681 100644 --- a/src/crypto/public_key/elgamal.js +++ b/src/crypto/public_key/elgamal.js @@ -21,7 +21,7 @@ */ import { getRandomBigInteger } from '../random'; import { emeEncode, emeDecode } from '../pkcs1'; -import util from '../../util'; +import BigInteger from '../../biginteger'; /** * ElGamal Encryption function @@ -34,8 +34,6 @@ import util from '../../util'; * @async */ export async function encrypt(data, p, g, y) { - const BigInteger = await util.getBigInteger(); - p = new BigInteger(p); g = new BigInteger(g); y = new BigInteger(y); @@ -65,8 +63,6 @@ export async function encrypt(data, p, g, y) { * @async */ export async function decrypt(c1, c2, p, x, randomPayload) { - const BigInteger = await util.getBigInteger(); - c1 = new BigInteger(c1); c2 = new BigInteger(c2); p = new BigInteger(p); @@ -86,8 +82,6 @@ export async function decrypt(c1, c2, p, x, randomPayload) { * @async */ export async function validateParams(p, g, y, x) { - const BigInteger = await util.getBigInteger(); - p = new BigInteger(p); g = new BigInteger(g); y = new BigInteger(y); diff --git a/src/crypto/public_key/elliptic/ecdsa.js b/src/crypto/public_key/elliptic/ecdsa.js index 35d3c080..9f6f6446 100644 --- a/src/crypto/public_key/elliptic/ecdsa.js +++ b/src/crypto/public_key/elliptic/ecdsa.js @@ -25,6 +25,7 @@ import util from '../../../util'; import { getRandomBytes } from '../../random'; import hash from '../../hash'; import { CurveWithOID, webCurves, privateToJWK, rawPublicToJWK, validateStandardParams, nodeCurves } from './oid_curves'; +import BigInteger from '../../../biginteger'; const webCrypto = util.getWebCrypto(); const nodeCrypto = util.getNodeCrypto(); @@ -72,8 +73,8 @@ export async function sign(oid, hashAlgo, message, publicKey, privateKey, hashed // lowS: non-canonical sig: https://stackoverflow.com/questions/74338846/ecdsa-signature-verification-mismatch const signature = nobleCurve.sign(hashed, privateKey, { lowS: false }); return { - r: signature.r.toUint8Array('be', curve.payloadSize), - s: signature.s.toUint8Array('be', curve.payloadSize) + r: new BigInteger(signature.r).toUint8Array('be', curve.payloadSize), + s: new BigInteger(signature.s).toUint8Array('be', curve.payloadSize) }; } diff --git a/src/crypto/public_key/prime.js b/src/crypto/public_key/prime.js index 8045f638..7664a42c 100644 --- a/src/crypto/public_key/prime.js +++ b/src/crypto/public_key/prime.js @@ -19,6 +19,7 @@ * @fileoverview Algorithms for probabilistic random prime generation * @module crypto/public_key/prime */ +import BigInteger from '../../biginteger'; import util from '../../util'; import { getRandomBigInteger } from '../random'; @@ -31,8 +32,6 @@ import { getRandomBigInteger } from '../random'; * @async */ export async function randomProbablePrime(bits, e, k) { - const BigInteger = await util.getBigInteger(); - const one = new BigInteger(1); const min = one.leftShift(new BigInteger(bits - 1)); const thirty = new BigInteger(30); @@ -93,15 +92,11 @@ export async function isProbablePrime(n, e, k) { * @returns {boolean} */ export async function fermat(n, b) { - const BigInteger = await util.getBigInteger(); - b = b || new BigInteger(2); return b.modExp(n.dec(), n).isOne(); } export async function divisionTest(n) { - const BigInteger = await util.getBigInteger(); - return smallPrimes.every(m => { return n.mod(new BigInteger(m)) !== 0; }); @@ -230,8 +225,6 @@ const smallPrimes = [ * @async */ export async function millerRabin(n, k, rand) { - const BigInteger = await util.getBigInteger(); - const len = n.bitLength(); if (!k) { diff --git a/src/crypto/public_key/rsa.js b/src/crypto/public_key/rsa.js index 3b6b6ccb..862d34b5 100644 --- a/src/crypto/public_key/rsa.js +++ b/src/crypto/public_key/rsa.js @@ -25,6 +25,7 @@ import util from '../../util'; import { uint8ArrayToB64, b64ToUint8Array } from '../../encoding/base64'; import { emsaEncode, emeEncode, emeDecode } from '../pkcs1'; import enums from '../../enums'; +import BigInteger from '../../biginteger'; const webCrypto = util.getWebCrypto(); const nodeCrypto = util.getNodeCrypto(); @@ -141,8 +142,6 @@ export async function decrypt(data, n, e, d, p, q, u, randomPayload) { * @async */ export async function generate(bits, e) { - const BigInteger = await util.getBigInteger(); - e = new BigInteger(e); // Native RSA keygen using Web Crypto @@ -223,8 +222,6 @@ export async function generate(bits, e) { * @async */ export async function validateParams(n, e, d, p, q, u) { - const BigInteger = await util.getBigInteger(); - n = new BigInteger(n); p = new BigInteger(p); q = new BigInteger(q); @@ -263,8 +260,6 @@ export async function validateParams(n, e, d, p, q, u) { } async function bnSign(hashAlgo, n, d, hashed) { - const BigInteger = await util.getBigInteger(); - n = new BigInteger(n); const m = new BigInteger(await emsaEncode(hashAlgo, hashed, n.byteLength())); d = new BigInteger(d); @@ -301,8 +296,6 @@ async function nodeSign(hashAlgo, data, n, e, d, p, q, u) { } async function bnVerify(hashAlgo, s, n, e, hashed) { - const BigInteger = await util.getBigInteger(); - n = new BigInteger(n); s = new BigInteger(s); e = new BigInteger(e); @@ -346,8 +339,6 @@ async function nodeEncrypt(data, n, e) { } async function bnEncrypt(data, n, e) { - const BigInteger = await util.getBigInteger(); - n = new BigInteger(n); data = new BigInteger(emeEncode(data, n.byteLength())); e = new BigInteger(e); @@ -369,8 +360,6 @@ async function nodeDecrypt(data, n, e, d, p, q, u) { } async function bnDecrypt(data, n, e, d, p, q, u, randomPayload) { - const BigInteger = await util.getBigInteger(); - data = new BigInteger(data); n = new BigInteger(n); e = new BigInteger(e); @@ -412,8 +401,6 @@ async function bnDecrypt(data, n, e, d, p, q, u, randomPayload) { * @param {Uint8Array} u */ async function privateToJWK(n, e, d, p, q, u) { - const BigInteger = await util.getBigInteger(); - const pNum = new BigInteger(p); const qNum = new BigInteger(q); const dNum = new BigInteger(d); diff --git a/src/crypto/random.js b/src/crypto/random.js index 4936c97e..4b038587 100644 --- a/src/crypto/random.js +++ b/src/crypto/random.js @@ -21,6 +21,7 @@ * @fileoverview Provides tools for retrieving secure randomness from browsers or Node.js * @module crypto/random */ +import BigInteger from '../biginteger'; import util from '../util'; const nodeCrypto = util.getNodeCrypto(); @@ -51,8 +52,6 @@ export function getRandomBytes(length) { * @async */ export async function getRandomBigInteger(min, max) { - const BigInteger = await util.getBigInteger(); - if (max.lt(min)) { throw new Error('Illegal parameter value: max <= min'); } diff --git a/src/util.js b/src/util.js index 45db97e8..d4635cad 100644 --- a/src/util.js +++ b/src/util.js @@ -26,7 +26,6 @@ import * as stream from '@openpgp/web-stream-tools'; import { createRequire } from 'module'; // Must be stripped in browser built import enums from './enums'; import defaultConfig from './config'; -import { getBigInteger } from './biginteger'; const debugMode = (() => { try { @@ -50,8 +49,6 @@ const util = { isStream: stream.isStream, - getBigInteger, - /** * Load noble-curves lib on demand and return the requested curve function * @param {enums.publicKey} publicKeyAlgo diff --git a/test/crypto/validate.js b/test/crypto/validate.js index e76e4947..7f5e32bf 100644 --- a/test/crypto/validate.js +++ b/test/crypto/validate.js @@ -3,7 +3,7 @@ import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/new chaiUse(chaiAsPromised); import openpgp from '../initOpenpgp.js'; -import util from '../../src/util.js'; +import BigInteger from '../../src/biginteger.js'; const armoredDSAKey = `-----BEGIN PGP PRIVATE KEY BLOCK----- @@ -387,8 +387,6 @@ export default () => { }); it('detect g with small order', async function() { - const BigInteger = await util.getBigInteger(); - const keyPacket = await cloneKeyPacket(egKey); const { p, g } = keyPacket.publicParams; diff --git a/tsconfig.json b/tsconfig.json index a41b561b..6471d348 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,7 +3,7 @@ "strict": true, "target": "es2021", "module": "esnext", - "moduleResolution": "node", + "moduleResolution": "Bundler", "allowJs": true, "paths": { "openpgp": [ "." ] From ec52bdea83b7cd3d3c97722520cd1a7c37c5742b Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Thu, 2 May 2024 19:03:50 +0200 Subject: [PATCH 130/201] Point to official noble-hashes and noble-curve libs --- .eslintrc.cjs | 2 +- package-lock.json | 120 ++++++------------ package.json | 4 +- rollup.config.js | 4 +- src/crypto/hash/noble_hashes.js | 10 +- .../public_key/elliptic/noble_curves.js | 10 +- 6 files changed, 57 insertions(+), 93 deletions(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index ac607366..819f1f06 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -102,7 +102,7 @@ module.exports = { 'import/no-unassigned-import': 'error', 'import/no-unresolved': ['error', { // esm exports not supported: https://github.com/import-js/eslint-plugin-import/issues/1810 - ignore: ['openpgp', '@openpgp/noble-hashes', '@openpgp/web-stream-tools', '@openpgp/asmcrypto.js'] + ignore: ['openpgp', '@noble/hashes', '@openpgp/web-stream-tools', '@openpgp/asmcrypto.js'] }], 'import/prefer-default-export': 'off', diff --git a/package-lock.json b/package-lock.json index e9b5d90d..e6377dfb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,10 +9,10 @@ "version": "6.0.0-beta.0", "license": "LGPL-3.0+", "devDependencies": { + "@noble/curves": "^1.3.0", + "@noble/hashes": "^1.3.3", "@openpgp/asmcrypto.js": "^3.1.0", "@openpgp/jsdoc": "^3.6.11", - "@openpgp/noble-curves": "^1.3.0", - "@openpgp/noble-hashes": "^1.3.3", "@openpgp/seek-bzip": "^1.0.5-git", "@openpgp/tweetnacl": "^1.0.4-1", "@openpgp/web-stream-tools": "~0.1.1", @@ -762,6 +762,30 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@noble/curves": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.0.tgz", + "integrity": "sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==", + "dev": true, + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -832,34 +856,6 @@ "node": ">=12.0.0" } }, - "node_modules/@openpgp/noble-curves": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@openpgp/noble-curves/-/noble-curves-1.3.0.tgz", - "integrity": "sha512-6QjsDyzTc5AZMC3CDRcp2L/VuxIcfxFT4kCWAV/gk4OcjWtgh49S5M7pjkOzYzjhpapu5HYIWkuUdTxDC5WXEw==", - "dev": true, - "dependencies": { - "@openpgp/noble-hashes": "1.3.3" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@openpgp/noble-hashes": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@openpgp/noble-hashes/-/noble-hashes-1.3.3.tgz", - "integrity": "sha512-CPDNePrQTQrL5Fxd/K3B53Gty4xbNVxnMSUdDmYjW5tTpRqOlme0INYTnnQqoE/XUdIlq5fByOMDuDWR5JpXZw==", - "dev": true, - "dependencies": { - "@types/bn.js": "^4.11.6", - "bn.js": "^4.11.8" - }, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@openpgp/seek-bzip": { "version": "1.0.5-git", "resolved": "https://registry.npmjs.org/@openpgp/seek-bzip/-/seek-bzip-1.0.5-git.tgz", @@ -1346,15 +1342,6 @@ "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", "dev": true }, - "node_modules/@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/chai": { "version": "4.3.14", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.14.tgz", @@ -1865,12 +1852,6 @@ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", "dev": true }, - "node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, "node_modules/body-parser": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", @@ -8441,6 +8422,21 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "@noble/curves": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.0.tgz", + "integrity": "sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==", + "dev": true, + "requires": { + "@noble/hashes": "1.4.0" + } + }, + "@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -8496,25 +8492,6 @@ "underscore": "~1.13.2" } }, - "@openpgp/noble-curves": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@openpgp/noble-curves/-/noble-curves-1.3.0.tgz", - "integrity": "sha512-6QjsDyzTc5AZMC3CDRcp2L/VuxIcfxFT4kCWAV/gk4OcjWtgh49S5M7pjkOzYzjhpapu5HYIWkuUdTxDC5WXEw==", - "dev": true, - "requires": { - "@openpgp/noble-hashes": "1.3.3" - } - }, - "@openpgp/noble-hashes": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@openpgp/noble-hashes/-/noble-hashes-1.3.3.tgz", - "integrity": "sha512-CPDNePrQTQrL5Fxd/K3B53Gty4xbNVxnMSUdDmYjW5tTpRqOlme0INYTnnQqoE/XUdIlq5fByOMDuDWR5JpXZw==", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.6", - "bn.js": "^4.11.8" - } - }, "@openpgp/seek-bzip": { "version": "1.0.5-git", "resolved": "https://registry.npmjs.org/@openpgp/seek-bzip/-/seek-bzip-1.0.5-git.tgz", @@ -8806,15 +8783,6 @@ "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", "dev": true }, - "@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, "@types/chai": { "version": "4.3.14", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.14.tgz", @@ -9223,12 +9191,6 @@ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", "dev": true }, - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, "body-parser": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", diff --git a/package.json b/package.json index 5ecc8bd0..007a9db9 100644 --- a/package.json +++ b/package.json @@ -62,10 +62,10 @@ "postversion": "git push && git push --tags && npm publish" }, "devDependencies": { + "@noble/curves": "^1.3.0", + "@noble/hashes": "^1.3.3", "@openpgp/asmcrypto.js": "^3.1.0", "@openpgp/jsdoc": "^3.6.11", - "@openpgp/noble-curves": "^1.3.0", - "@openpgp/noble-hashes": "^1.3.3", "@openpgp/seek-bzip": "^1.0.5-git", "@openpgp/tweetnacl": "^1.0.4-1", "@openpgp/web-stream-tools": "~0.1.1", diff --git a/rollup.config.js b/rollup.config.js index 8cdc1458..870c0c26 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -86,7 +86,9 @@ export default Object.assign([ { file: 'dist/node/openpgp.min.mjs', format: 'es', banner, intro, plugins: [terser(terserOptions)], sourcemap: true } ].map(options => ({ ...options, inlineDynamicImports: true })), plugins: [ - resolve(), + resolve({ + exportConditions: ['node'] // needed for resolution of noble-curves import of '@noble/crypto' in Node 16 and 18 + }), typescript(), commonjs(), replace({ diff --git a/src/crypto/hash/noble_hashes.js b/src/crypto/hash/noble_hashes.js index 0d589a78..0d0ce7b4 100644 --- a/src/crypto/hash/noble_hashes.js +++ b/src/crypto/hash/noble_hashes.js @@ -4,11 +4,11 @@ * which share a lot of code anyway. */ -import { sha1 } from '@openpgp/noble-hashes/sha1'; -import { sha224, sha256 } from '@openpgp/noble-hashes/sha256'; -import { sha384, sha512 } from '@openpgp/noble-hashes/sha512'; -import { sha3_256, sha3_512 } from '@openpgp/noble-hashes/sha3'; -import { ripemd160 } from '@openpgp/noble-hashes/ripemd160'; +import { sha1 } from '@noble/hashes/sha1'; +import { sha224, sha256 } from '@noble/hashes/sha256'; +import { sha384, sha512 } from '@noble/hashes/sha512'; +import { sha3_256, sha3_512 } from '@noble/hashes/sha3'; +import { ripemd160 } from '@noble/hashes/ripemd160'; export const nobleHashes = new Map(Object.entries({ sha1, diff --git a/src/crypto/public_key/elliptic/noble_curves.js b/src/crypto/public_key/elliptic/noble_curves.js index 4e7703d5..fce717dd 100644 --- a/src/crypto/public_key/elliptic/noble_curves.js +++ b/src/crypto/public_key/elliptic/noble_curves.js @@ -4,14 +4,14 @@ * which share a lot of code anyway. */ -import { p256 as nistP256 } from '@openpgp/noble-curves/p256'; -import { p384 as nistP384 } from '@openpgp/noble-curves/p384'; -import { p521 as nistP521 } from '@openpgp/noble-curves/p521'; import { brainpoolP256r1 } from '@openpgp/noble-curves/brainpoolP256r1'; import { brainpoolP384r1 } from '@openpgp/noble-curves/brainpoolP384r1'; import { brainpoolP512r1 } from '@openpgp/noble-curves/brainpoolP512r1'; -import { x448, ed448 } from '@openpgp/noble-curves/ed448'; -import { secp256k1 } from '@openpgp/noble-curves/secp256k1'; +import { p256 as nistP256 } from '@noble/curves/p256'; +import { p384 as nistP384 } from '@noble/curves/p384'; +import { p521 as nistP521 } from '@noble/curves/p521'; +import { x448, ed448 } from '@noble/curves/ed448'; +import { secp256k1 } from '@noble/curves/secp256k1'; export const nobleCurves = new Map(Object.entries({ nistP256, From 5bfff907b444f5ca886e403b24b3bbaac1ac6926 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Thu, 2 May 2024 19:12:31 +0200 Subject: [PATCH 131/201] Move Brainpool curves implementation from noble-curves fork The main repo doesn't implement them --- .../elliptic/brainpool/brainpoolP256r1.ts | 23 +++++ .../elliptic/brainpool/brainpoolP384r1.ts | 23 +++++ .../elliptic/brainpool/brainpoolP512r1.ts | 23 +++++ .../public_key/elliptic/noble_curves.js | 6 +- test/crypto/brainpool_rfc7027.js | 83 +++++++++++++++++++ test/crypto/index.js | 2 + 6 files changed, 157 insertions(+), 3 deletions(-) create mode 100644 src/crypto/public_key/elliptic/brainpool/brainpoolP256r1.ts create mode 100644 src/crypto/public_key/elliptic/brainpool/brainpoolP384r1.ts create mode 100644 src/crypto/public_key/elliptic/brainpool/brainpoolP512r1.ts create mode 100644 test/crypto/brainpool_rfc7027.js diff --git a/src/crypto/public_key/elliptic/brainpool/brainpoolP256r1.ts b/src/crypto/public_key/elliptic/brainpool/brainpoolP256r1.ts new file mode 100644 index 00000000..c5ae5395 --- /dev/null +++ b/src/crypto/public_key/elliptic/brainpool/brainpoolP256r1.ts @@ -0,0 +1,23 @@ +import { createCurve } from '@noble/curves/_shortw_utils'; +import { sha256 } from '@noble/hashes/sha256'; +import { Field } from '@noble/curves/abstract/modular'; + +// brainpoolP256r1: https://datatracker.ietf.org/doc/html/rfc5639#section-3.4 + +const Fp = Field(BigInt('0xa9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d1f6e5377')); +const CURVE_A = Fp.create(BigInt('0x7d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6ce94a4b44f330b5d9')); +const CURVE_B = BigInt('0x26dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7e1ce6bccdc18ff8c07b6'); + +// prettier-ignore +export const brainpoolP256r1 = createCurve({ + a: CURVE_A, // Equation params: a, b + b: CURVE_B, + Fp, + // Curve order (q), total count of valid points in the field + n: BigInt('0xa9fb57dba1eea9bc3e660a909d838d718c397aa3b561a6f7901e0e82974856a7'), + // Base (generator) point (x, y) + Gx: BigInt('0x8bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27e1e3bd23c23a4453bd9ace3262'), + Gy: BigInt('0x547ef835c3dac4fd97f8461a14611dc9c27745132ded8e545c1d54c72f046997'), + h: BigInt(1), + lowS: false, +} as const, sha256); diff --git a/src/crypto/public_key/elliptic/brainpool/brainpoolP384r1.ts b/src/crypto/public_key/elliptic/brainpool/brainpoolP384r1.ts new file mode 100644 index 00000000..82f177df --- /dev/null +++ b/src/crypto/public_key/elliptic/brainpool/brainpoolP384r1.ts @@ -0,0 +1,23 @@ +import { createCurve } from '@noble/curves/_shortw_utils'; +import { sha384 } from '@noble/hashes/sha512'; +import { Field } from '@noble/curves/abstract/modular'; + +// brainpoolP384 r1: https://datatracker.ietf.org/doc/html/rfc5639#section-3.6 + +const Fp = Field(BigInt('0x8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b412b1da197fb71123acd3a729901d1a71874700133107ec53')); +const CURVE_A = Fp.create(BigInt('0x7bc382c63d8c150c3c72080ace05afa0c2bea28e4fb22787139165efba91f90f8aa5814a503ad4eb04a8c7dd22ce2826')); +const CURVE_B = BigInt('0x04a8c7dd22ce28268b39b55416f0447c2fb77de107dcd2a62e880ea53eeb62d57cb4390295dbc9943ab78696fa504c11'); + +// prettier-ignore +export const brainpoolP384r1 = createCurve({ + a: CURVE_A, // Equation params: a, b + b: CURVE_B, + Fp, + // Curve order (q), total count of valid points in the field + n: BigInt('0x8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b31f166e6cac0425a7cf3ab6af6b7fc3103b883202e9046565'), + // Base (generator) point (x, y) + Gx: BigInt('0x1d1c64f068cf45ffa2a63a81b7c13f6b8847a3e77ef14fe3db7fcafe0cbd10e8e826e03436d646aaef87b2e247d4af1e'), + Gy: BigInt('0x8abe1d7520f9c2a45cb1eb8e95cfd55262b70b29feec5864e19c054ff99129280e4646217791811142820341263c5315'), + h: BigInt(1), + lowS: false, +} as const, sha384); diff --git a/src/crypto/public_key/elliptic/brainpool/brainpoolP512r1.ts b/src/crypto/public_key/elliptic/brainpool/brainpoolP512r1.ts new file mode 100644 index 00000000..37ed3b3d --- /dev/null +++ b/src/crypto/public_key/elliptic/brainpool/brainpoolP512r1.ts @@ -0,0 +1,23 @@ +import { createCurve } from '@noble/curves/_shortw_utils'; +import { sha512 } from '@noble/hashes/sha512'; +import { Field } from '@noble/curves/abstract/modular'; + +// brainpoolP512r1: https://datatracker.ietf.org/doc/html/rfc5639#section-3.7 + +const Fp = Field(BigInt('0xaadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca703308717d4d9b009bc66842aecda12ae6a380e62881ff2f2d82c68528aa6056583a48f3')); +const CURVE_A = Fp.create(BigInt('0x7830a3318b603b89e2327145ac234cc594cbdd8d3df91610a83441caea9863bc2ded5d5aa8253aa10a2ef1c98b9ac8b57f1117a72bf2c7b9e7c1ac4d77fc94ca')); +const CURVE_B = BigInt('0x3df91610a83441caea9863bc2ded5d5aa8253aa10a2ef1c98b9ac8b57f1117a72bf2c7b9e7c1ac4d77fc94cadc083e67984050b75ebae5dd2809bd638016f723'); + +// prettier-ignore +export const brainpoolP512r1 = createCurve({ + a: CURVE_A, // Equation params: a, b + b: CURVE_B, + Fp, + // Curve order (q), total count of valid points in the field + n: BigInt('0xaadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca70330870553e5c414ca92619418661197fac10471db1d381085ddaddb58796829ca90069'), + // Base (generator) point (x, y) + Gx: BigInt('0x81aee4bdd82ed9645a21322e9c4c6a9385ed9f70b5d916c1b43b62eef4d0098eff3b1f78e2d0d48d50d1687b93b97d5f7c6d5047406a5e688b352209bcb9f822'), + Gy: BigInt('0x7dde385d566332ecc0eabfa9cf7822fdf209f70024a57b1aa000c55b881f8111b2dcde494a5f485e5bca4bd88a2763aed1ca2b2fa8f0540678cd1e0f3ad80892'), + h: BigInt(1), + lowS: false, +} as const, sha512); diff --git a/src/crypto/public_key/elliptic/noble_curves.js b/src/crypto/public_key/elliptic/noble_curves.js index fce717dd..49af7169 100644 --- a/src/crypto/public_key/elliptic/noble_curves.js +++ b/src/crypto/public_key/elliptic/noble_curves.js @@ -4,12 +4,12 @@ * which share a lot of code anyway. */ -import { brainpoolP256r1 } from '@openpgp/noble-curves/brainpoolP256r1'; -import { brainpoolP384r1 } from '@openpgp/noble-curves/brainpoolP384r1'; -import { brainpoolP512r1 } from '@openpgp/noble-curves/brainpoolP512r1'; import { p256 as nistP256 } from '@noble/curves/p256'; import { p384 as nistP384 } from '@noble/curves/p384'; import { p521 as nistP521 } from '@noble/curves/p521'; +import { brainpoolP256r1 } from './brainpool/brainpoolP256r1'; +import { brainpoolP384r1 } from './brainpool/brainpoolP384r1'; +import { brainpoolP512r1 } from './brainpool/brainpoolP512r1'; import { x448, ed448 } from '@noble/curves/ed448'; import { secp256k1 } from '@noble/curves/secp256k1'; diff --git a/test/crypto/brainpool_rfc7027.js b/test/crypto/brainpool_rfc7027.js new file mode 100644 index 00000000..b28ff9cb --- /dev/null +++ b/test/crypto/brainpool_rfc7027.js @@ -0,0 +1,83 @@ +import { expect } from 'chai'; + +import { brainpoolP256r1 } from '../../src/crypto/public_key/elliptic/brainpool/brainpoolP256r1'; +import { brainpoolP384r1 } from '../../src/crypto/public_key/elliptic/brainpool/brainpoolP384r1'; +import { brainpoolP512r1 } from '../../src/crypto/public_key/elliptic/brainpool/brainpoolP512r1'; +import util from '../../src/util'; + +const rfc7027 = [ + { + 'curve': 'brainpoolP256r1', + 'dA': '81DB1EE100150FF2EA338D708271BE38300CB54241D79950F77B063039804F1D', + 'QAx': '44106E913F92BC02A1705D9953A8414DB95E1AAA49E81D9E85F929A8E3100BE5', + 'QAy': '8AB4846F11CACCB73CE49CBDD120F5A900A69FD32C272223F789EF10EB089BDC', + 'dB': '55E40BC41E37E3E2AD25C3C6654511FFA8474A91A0032087593852D3E7D76BD3', + 'QBx': '8D2D688C6CF93E1160AD04CC4429117DC2C41825E1E9FCA0ADDD34E6F1B39F7B', + 'QBy': '990C57520812BE512641E47034832106BC7D3E8DD0E4C7F1136D7006547CEC6A', + 'Zx': '89AFC39D41D3B327814B80940B042590F96556EC91E6AE7939BCE31F3A18BF2B', + 'Zy': '49C27868F4ECA2179BFD7D59B1E3BF34C1DBDE61AE12931648F43E59632504DE' + }, + { + 'curve': 'brainpoolP384r1', + 'dA': '1E20F5E048A5886F1F157C74E91BDE2B98C8B52D58E5003D57053FC4B0BD65D6F15EB5D1EE1610DF870795143627D042', + 'QAx': '68B665DD91C195800650CDD363C625F4E742E8134667B767B1B476793588F885AB698C852D4A6E77A252D6380FCAF068', + 'QAy': '55BC91A39C9EC01DEE36017B7D673A931236D2F1F5C83942D049E3FA20607493E0D038FF2FD30C2AB67D15C85F7FAA59', + 'dB': '032640BC6003C59260F7250C3DB58CE647F98E1260ACCE4ACDA3DD869F74E01F8BA5E0324309DB6A9831497ABAC96670', + 'QBx': '4D44326F269A597A5B58BBA565DA5556ED7FD9A8A9EB76C25F46DB69D19DC8CE6AD18E404B15738B2086DF37E71D1EB4', + 'QBy': '62D692136DE56CBE93BF5FA3188EF58BC8A3A0EC6C1E151A21038A42E9185329B5B275903D192F8D4E1F32FE9CC78C48', + 'Zx': '0BD9D3A7EA0B3D519D09D8E48D0785FB744A6B355E6304BC51C229FBBCE239BBADF6403715C35D4FB2A5444F575D4F42', + 'Zy': '0DF213417EBE4D8E40A5F76F66C56470C489A3478D146DECF6DF0D94BAE9E598157290F8756066975F1DB34B2324B7BD' + }, + { + 'curve': 'brainpoolP512r1', + 'dA': '16302FF0DBBB5A8D733DAB7141C1B45ACBC8715939677F6A56850A38BD87BD59B09E80279609FF333EB9D4C061231FB26F92EEB04982A5F1D1764CAD57665422', + 'QAx': '0A420517E406AAC0ACDCE90FCD71487718D3B953EFD7FBEC5F7F27E28C6149999397E91E029E06457DB2D3E640668B392C2A7E737A7F0BF04436D11640FD09FD', + 'QAy': '72E6882E8DB28AAD36237CD25D580DB23783961C8DC52DFA2EC138AD472A0FCEF3887CF62B623B2A87DE5C588301EA3E5FC269B373B60724F5E82A6AD147FDE7', + 'dB': '230E18E1BCC88A362FA54E4EA3902009292F7F8033624FD471B5D8ACE49D12CFABBC19963DAB8E2F1EBA00BFFB29E4D72D13F2224562F405CB80503666B25429', + 'QBx': '9D45F66DE5D67E2E6DB6E93A59CE0BB48106097FF78A081DE781CDB31FCE8CCBAAEA8DD4320C4119F1E9CD437A2EAB3731FA9668AB268D871DEDA55A5473199F', + 'QBy': '2FDC313095BCDD5FB3A91636F07A959C8E86B5636A1E930E8396049CB481961D365CC11453A06C719835475B12CB52FC3C383BCE35E27EF194512B71876285FA', + 'Zx': 'A7927098655F1F9976FA50A9D566865DC530331846381C87256BAF3226244B76D36403C024D7BBF0AA0803EAFF405D3D24F11A9B5C0BEF679FE1454B21C4CD1F', + 'Zy': '7DB71C3DEF63212841C463E881BDCF055523BD368240E6C3143BD8DEF8B3B3223B95E0F53082FF5E412F4222537A43DF1C6D25729DDB51620A832BE6A26680A2' + } +]; + +const hexToBigint = hex => BigInt(`0x${hex}`); + +// prettier-ignore +const BRAINPOOL = { + brainpoolP256r1, + brainpoolP384r1, + brainpoolP512r1 +}; + +export default () => describe('Brainpool curves (RFC7027)', () => { + it('Field orders', () => { + const vectors = { + brainpoolP256r1: BigInt('0xa9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d1f6e5377'), + brainpoolP384r1: BigInt('0x8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b412b1da197fb71123acd3a729901d1a71874700133107ec53'), + brainpoolP512r1: BigInt('0xaadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca703308717d4d9b009bc66842aecda12ae6a380e62881ff2f2d82c68528aa6056583a48f3') + }; + for (const n of Object.keys(vectors)) { expect(BRAINPOOL[n].CURVE.Fp.ORDER).to.deep.equal(vectors[n]); } + }); + + for (const v of rfc7027) { + it(v.curve, () => { + const curve = BRAINPOOL[v.curve]; + const secKeyA = util.hexToUint8Array(v.dA); + const pubKeyA = curve.getPublicKey(secKeyA); + const pubPointA = curve.ProjectivePoint.fromHex(pubKeyA); + expect(pubPointA.x).to.equal(hexToBigint(v.QAx)); + expect(pubPointA.y).to.equal(hexToBigint(v.QAy)); + const secKeyB = hexToBigint(v.dB); + const pubKeyB = curve.getPublicKey(secKeyB); + const pubPointB = curve.ProjectivePoint.fromHex(pubKeyB); + expect(pubPointB.x).to.equal(hexToBigint(v.QBx)); + expect(pubPointB.y).to.equal(hexToBigint(v.QBy)); + const shared = curve.getSharedSecret(secKeyA, pubKeyB); + const sharedPoint = curve.ProjectivePoint.fromHex(shared); + expect(sharedPoint.x).to.equal(hexToBigint(v.Zx)); + expect(sharedPoint.y).to.equal(hexToBigint(v.Zy)); + expect(shared).to.deep.equal(curve.getSharedSecret(secKeyB, pubKeyA)); + }); + } +}); diff --git a/test/crypto/index.js b/test/crypto/index.js index 205b9866..86f45445 100644 --- a/test/crypto/index.js +++ b/test/crypto/index.js @@ -2,6 +2,7 @@ import testCipher from './cipher'; import testHash from './hash'; import testCrypto from './crypto'; import testElliptic from './elliptic'; +import testBrainpoolRFC7027 from './brainpool_rfc7027'; import testECDH from './ecdh'; import testPKCS5 from './pkcs5'; import testAESKW from './aes_kw'; @@ -17,6 +18,7 @@ export default () => describe('Crypto', function () { testHash(); testCrypto(); testElliptic(); + testBrainpoolRFC7027(); testECDH(); testPKCS5(); testAESKW(); From 2985b0f4707fb96662587f1514848bc06fa46c77 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Fri, 3 May 2024 16:02:25 +0200 Subject: [PATCH 132/201] Lint: add support for TS files, fix errors --- .eslintrc.cjs | 36 +- openpgp.d.ts | 121 ++-- package-lock.json | 685 ++++++++++++++++++ package.json | 2 + src/biginteger.ts | 7 +- .../elliptic/brainpool/brainpoolP256r1.ts | 3 +- .../elliptic/brainpool/brainpoolP384r1.ts | 3 +- .../elliptic/brainpool/brainpoolP512r1.ts | 3 +- src/crypto/public_key/elliptic/ecdsa.js | 1 + .../public_key/elliptic/noble_curves.js | 4 +- src/crypto/public_key/prime.js | 1 - src/crypto/public_key/rsa.js | 2 +- src/key/key.js | 1 + src/openpgp.js | 4 +- src/packet/padding.js | 2 +- src/packet/public_subkey.js | 2 +- .../sym_encrypted_integrity_protected_data.js | 2 +- test/crypto/validate.js | 2 +- test/general/brainpool.js | 7 +- test/general/packet.js | 5 +- test/general/streaming.js | 2 +- test/general/util.js | 2 +- 22 files changed, 801 insertions(+), 96 deletions(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 819f1f06..58a62f87 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -1,8 +1,15 @@ module.exports = { - 'extends': 'airbnb-base', + 'extends': [ + 'airbnb-base', + 'airbnb-typescript/base' + ], + + 'parser': '@typescript-eslint/parser', + 'parserOptions': { 'ecmaVersion': 11, - 'sourceType': 'module' + 'sourceType': 'module', + 'project': 'tsconfig.json' }, 'env': { @@ -12,6 +19,7 @@ module.exports = { }, 'plugins': [ + '@typescript-eslint', 'chai-friendly', 'import', 'unicorn' @@ -43,11 +51,11 @@ module.exports = { 'arrow-body-style': 'off', 'arrow-parens': ['error','as-needed'], 'class-methods-use-this': 'off', - 'comma-dangle': ['error', 'never'], - 'comma-spacing': 'off', + '@typescript-eslint/comma-dangle': ['error', 'never'], + '@typescript-eslint/comma-spacing': 'off', 'consistent-return': 'off', 'default-case': 'off', - 'default-param-last': 'off', + '@typescript-eslint/default-param-last': 'off', 'eol-last': ['error', 'always'], 'function-call-argument-newline': 'off', 'func-names': ['error', 'never'], @@ -68,7 +76,7 @@ module.exports = { 'no-plusplus': 'off', 'no-restricted-syntax': ['error', 'ForInStatement', 'LabeledStatement', 'WithStatement'], 'object-curly-newline': 'off', - 'no-shadow': 'off', // TODO get rid of this + '@typescript-eslint/no-shadow': 'off', // TODO get rid of this 'object-property-newline': [ 'error', { @@ -89,10 +97,12 @@ module.exports = { 'prefer-template': 'off', 'quote-props': 'off', 'quotes': ['error', 'single', { 'avoidEscape': true }], - 'space-before-function-paren': ['error', { 'anonymous': 'ignore', 'named': 'never', 'asyncArrow': 'always' }], + '@typescript-eslint/space-before-function-paren': ['error', { 'anonymous': 'ignore', 'named': 'never', 'asyncArrow': 'always' }], 'spaced-comment': 'off', - 'indent': ['error', 2, { 'SwitchCase': 1 }], - 'no-unused-vars': 'error', + 'indent': 'off', + '@typescript-eslint/indent': ['error', 2, { 'SwitchCase': 1 }], + 'no-unused-vars': 'off', + '@typescript-eslint/no-unused-vars': 'error', // eslint-plugin-import rules: 'import/named': 'error', @@ -107,17 +117,19 @@ module.exports = { 'import/prefer-default-export': 'off', // Custom silencers: - 'camelcase': 'off', // used in tests, need to fix separately 'no-multi-assign': 'off', 'no-underscore-dangle': 'off', 'no-await-in-loop': 'off', + 'camelcase': 'off', // snake_case used in tests, need to fix separately + '@typescript-eslint/naming-convention': 'off', // supersedes 'camelcase' rule + '@typescript-eslint/lines-between-class-members': 'off', // Custom errors: - 'no-use-before-define': [2, { 'functions': false, 'classes': true, 'variables': false }], + '@typescript-eslint/no-use-before-define': ['error', { 'functions': false, 'classes': true, 'variables': false, 'allowNamedExports': true }], 'no-constant-condition': [2, { 'checkLoops': false }], 'new-cap': [2, { 'properties': false, 'capIsNewExceptionPattern': 'EAX|OCB|GCM|CMAC|CBC|OMAC|CTR', 'newIsCapExceptionPattern': 'type|hash*' }], 'max-lines': [2, { 'max': 620, 'skipBlankLines': true, 'skipComments': true }], - 'no-unused-expressions': 0, + '@typescript-eslint/no-unused-expressions': 0, 'chai-friendly/no-unused-expressions': [2, { 'allowShortCircuit': true }], 'unicorn/switch-case-braces': ['error', 'avoid'], diff --git a/openpgp.d.ts b/openpgp.d.ts index 8801d0e3..795f3869 100644 --- a/openpgp.d.ts +++ b/openpgp.d.ts @@ -1,3 +1,5 @@ +/* eslint-disable max-lines, @typescript-eslint/indent */ + /** * Type definitions for OpenPGP.js http://openpgpjs.org/ * @@ -64,8 +66,8 @@ export abstract class Key { // NB: the order of the `update` declarations matters, since PublicKey includes PrivateKey public update(sourceKey: PrivateKey, date?: Date, config?: Config): Promise; public update(sourceKey: PublicKey, date?: Date, config?: Config): Promise; - public signPrimaryUser(privateKeys: PrivateKey[], date?: Date, userID?: UserID, config?: Config): Promise - public signAllUsers(privateKeys: PrivateKey[], date?: Date, config?: Config): Promise + public signPrimaryUser(privateKeys: PrivateKey[], date?: Date, userID?: UserID, config?: Config): Promise; + public signAllUsers(privateKeys: PrivateKey[], date?: Date, config?: Config): Promise; public verifyPrimaryKey(date?: Date, userID?: UserID, config?: Config): Promise; // throws on error public verifyPrimaryUser(publicKeys: PublicKey[], date?: Date, userIDs?: UserID, config?: Config): Promise<{ keyID: KeyID, valid: boolean | null }[]>; public verifyAllUsers(publicKeys?: PublicKey[], date?: Date, config?: Config): Promise<{ userID: string, keyID: KeyID, valid: boolean | null }[]>; @@ -92,7 +94,7 @@ export class PrivateKey extends PublicKey { public revoke(reason?: ReasonForRevocation, date?: Date, config?: Config): Promise; public isDecrypted(): boolean; public addSubkey(options: SubkeyOptions): Promise; - public getDecryptionKeys(keyID?: KeyID, date?: Date | null, userID?: UserID, config?: Config): Promise + public getDecryptionKeys(keyID?: KeyID, date?: Date | null, userID?: UserID, config?: Config): Promise; public update(sourceKey: PublicKey, date?: Date, config?: Config): Promise; } @@ -108,9 +110,9 @@ export class Subkey { public getCreationTime(): Date; public getAlgorithmInfo(): AlgorithmInfo; public getKeyID(): KeyID; - public getExpirationTime(date?: Date, config?: Config): Promise + public getExpirationTime(date?: Date, config?: Config): Promise; public isRevoked(signature: SignaturePacket, key: AnyKeyPacket, date?: Date, config?: Config): Promise; - public update(subKey: Subkey, date?: Date, config?: Config): Promise + public update(subKey: Subkey, date?: Date, config?: Config): Promise; public revoke(primaryKey: SecretKeyPacket, reasonForRevocation?: ReasonForRevocation, date?: Date, config?: Config): Promise; } @@ -200,25 +202,25 @@ export function createMessage>(options: { text: T, export function createMessage>(options: { binary: T, filename?: string, date?: Date, format?: enums.literalFormatNames }): Promise>; export function encrypt>(options: EncryptOptions & { message: Message, format?: 'armored' }): Promise< - T extends WebStream ? WebStream : - T extends NodeWebStream ? NodeWebStream : + T extends WebStream ? WebStream : + T extends NodeWebStream ? NodeWebStream : string >; export function encrypt>(options: EncryptOptions & { message: Message, format: 'binary' }): Promise< - T extends WebStream ? WebStream : - T extends NodeWebStream ? NodeWebStream : + T extends WebStream ? WebStream : + T extends NodeWebStream ? NodeWebStream : Uint8Array >; export function encrypt>(options: EncryptOptions & { message: Message, format: 'object' }): Promise>; export function sign>(options: SignOptions & { message: Message, format?: 'armored' }): Promise< - T extends WebStream ? WebStream : - T extends NodeWebStream ? NodeWebStream : + T extends WebStream ? WebStream : + T extends NodeWebStream ? NodeWebStream : string >; export function sign>(options: SignOptions & { message: Message, format: 'binary' }): Promise< - T extends WebStream ? WebStream : - T extends NodeWebStream ? NodeWebStream : + T extends WebStream ? WebStream : + T extends NodeWebStream ? NodeWebStream : Uint8Array >; export function sign>(options: SignOptions & { message: Message, format: 'object' }): Promise>; @@ -227,26 +229,26 @@ export function sign(options: SignOptions & { message: CleartextMessage, format: export function decrypt>(options: DecryptOptions & { message: Message, format: 'binary' }): Promise ? WebStream : - T extends NodeWebStream ? NodeWebStream : + T extends WebStream ? WebStream : + T extends NodeWebStream ? NodeWebStream : Uint8Array }>; export function decrypt>(options: DecryptOptions & { message: Message }): Promise ? WebStream : - T extends NodeWebStream ? NodeWebStream : + T extends WebStream ? WebStream : + T extends NodeWebStream ? NodeWebStream : string }>; export function verify(options: VerifyOptions & { message: CleartextMessage, format?: 'utf8' }): Promise>; export function verify>(options: VerifyOptions & { message: Message, format: 'binary' }): Promise ? WebStream : - T extends NodeWebStream ? NodeWebStream : + T extends WebStream ? WebStream : + T extends NodeWebStream ? NodeWebStream : Uint8Array >>; export function verify>(options: VerifyOptions & { message: Message }): Promise ? WebStream : - T extends NodeWebStream ? NodeWebStream : + T extends WebStream ? WebStream : + T extends NodeWebStream ? NodeWebStream : string >>; @@ -273,7 +275,7 @@ export class Message> { /** Encrypt the message @param encryptionKeys array of public keys, used to encrypt the message */ - public encrypt(encryptionKeys?: PublicKey[], passwords?: string[], sessionKeys?: SessionKey[], wildcard?: boolean, encryptionKeyIDs?: KeyID[], date?: Date, userIDs?: UserID[], config?: Config): Promise>>; + public encrypt(encryptionKeys?: PublicKey[], passwords?: string[], sessionKeys?: SessionKey[], wildcard?: boolean, encryptionKeyIDs?: KeyID[], date?: Date, userIDs?: UserID[], config?: Config): Promise>>; /** Returns the key IDs of the keys to which the session key is encrypted */ @@ -351,7 +353,7 @@ interface Config { rejectPublicKeyAlgorithms: Set; rejectCurves: Set; } -export var config: Config; +export const config: Config; // PartialConfig has the same properties as Config, but declared as optional. // This interface is relevant for top-level functions, which accept a subset of configuration options @@ -432,7 +434,7 @@ export class AEADEncryptedDataPacket extends BasePacket { static readonly tag: enums.packet.aeadEncryptedData; private decrypt(sessionKeyAlgorithm: enums.symmetric, sessionKey: Uint8Array, config?: Config): void; private encrypt(sessionKeyAlgorithm: enums.symmetric, sessionKey: Uint8Array, config?: Config): void; - private crypt(fn: Function, sessionKey: Uint8Array, data: MaybeStream): MaybeStream + private crypt(fn: Function, sessionKey: Uint8Array, data: MaybeStream): MaybeStream; } export class PublicKeyEncryptedSessionKeyPacket extends BasePacket { @@ -678,7 +680,7 @@ export interface EncryptSessionKeyOptions extends SessionKey { config?: PartialConfig } -interface SerializedKeyPair { +interface SerializedKeyPair { privateKey: T; publicKey: T; } @@ -745,44 +747,44 @@ export function unarmor(input: string, config?: Config): Promise<{ text: string, /* ############## v5 ENUMS #################### */ export namespace enums { - function read(type: typeof armor, e: armor): armorNames; - function read(type: typeof compression, e: compression): compressionNames; - function read(type: typeof hash, e: hash): hashNames; - function read(type: typeof packet, e: packet): packetNames; - function read(type: typeof publicKey, e: publicKey): publicKeyNames; - function read(type: typeof symmetric, e: symmetric): symmetricNames; - function read(type: typeof keyStatus, e: keyStatus): keyStatusNames; - function read(type: typeof keyFlags, e: keyFlags): keyFlagsNames; + export function read(type: typeof armor, e: armor): armorNames; + export function read(type: typeof compression, e: compression): compressionNames; + export function read(type: typeof hash, e: hash): hashNames; + export function read(type: typeof packet, e: packet): packetNames; + export function read(type: typeof publicKey, e: publicKey): publicKeyNames; + export function read(type: typeof symmetric, e: symmetric): symmetricNames; + export function read(type: typeof keyStatus, e: keyStatus): keyStatusNames; + export function read(type: typeof keyFlags, e: keyFlags): keyFlagsNames; export type armorNames = 'multipartSection' | 'multipartLast' | 'signed' | 'message' | 'publicKey' | 'privateKey'; - enum armor { + export enum armor { multipartSection = 0, multipartLast = 1, signed = 2, message = 3, publicKey = 4, privateKey = 5, - signature = 6, + signature = 6 } - enum reasonForRevocation { + export enum reasonForRevocation { noReason = 0, // No reason specified (key revocations or cert revocations) keySuperseded = 1, // Key is superseded (key revocations) keyCompromised = 2, // Key material has been compromised (key revocations) keyRetired = 3, // Key is retired and no longer used (key revocations) - userIDInvalid = 32, // User ID information is no longer valid (cert revocations) + userIDInvalid = 32 // User ID information is no longer valid (cert revocations) } export type compressionNames = 'uncompressed' | 'zip' | 'zlib' | 'bzip2'; - enum compression { + export enum compression { uncompressed = 0, zip = 1, zlib = 2, - bzip2 = 3, + bzip2 = 3 } export type hashNames = 'md5' | 'sha1' | 'ripemd' | 'sha256' | 'sha384' | 'sha512' | 'sha224' | 'sha3_256' | 'sha3_512'; - enum hash { + export enum hash { md5 = 1, sha1 = 2, ripemd = 3, @@ -794,10 +796,10 @@ export namespace enums { sha3_512 = 14 } - export type packetNames = 'publicKeyEncryptedSessionKey' | 'signature' | 'symEncryptedSessionKey' | 'onePassSignature' | 'secretKey' | 'publicKey' - | 'secretSubkey' | 'compressed' | 'symmetricallyEncrypted' | 'marker' | 'literal' | 'trust' | 'userID' | 'publicSubkey' | 'userAttribute' - | 'symEncryptedIntegrityProtected' | 'modificationDetectionCode' | 'AEADEncryptedDataPacket'; - enum packet { + export type packetNames = 'publicKeyEncryptedSessionKey' | 'signature' | 'symEncryptedSessionKey' | 'onePassSignature' | 'secretKey' | 'publicKey' | + 'secretSubkey' | 'compressed' | 'symmetricallyEncrypted' | 'marker' | 'literal' | 'trust' | 'userID' | 'publicSubkey' | 'userAttribute' | + 'symEncryptedIntegrityProtected' | 'modificationDetectionCode' | 'AEADEncryptedDataPacket'; + export enum packet { publicKeyEncryptedSessionKey = 1, signature = 2, symEncryptedSessionKey = 3, @@ -815,11 +817,11 @@ export namespace enums { userAttribute = 17, symEncryptedIntegrityProtectedData = 18, modificationDetectionCode = 19, - aeadEncryptedData = 20, + aeadEncryptedData = 20 } export type publicKeyNames = 'rsaEncryptSign' | 'rsaEncrypt' | 'rsaSign' | 'elgamal' | 'dsa' | 'ecdh' | 'ecdsa' | 'eddsaLegacy' | 'aedh' | 'aedsa' | 'ed25519' | 'x25519' | 'ed448' | 'x448'; - enum publicKey { + export enum publicKey { rsaEncryptSign = 1, rsaEncrypt = 2, rsaSign = 3, @@ -836,7 +838,7 @@ export namespace enums { ed448 = 28 } - enum curve { + export enum curve { /** @deprecated use `nistP256` instead */ p256 = 'nistP256', nistP256 = 'nistP256', @@ -859,7 +861,7 @@ export namespace enums { } export type symmetricNames = 'idea' | 'tripledes' | 'cast5' | 'blowfish' | 'aes128' | 'aes192' | 'aes256' | 'twofish'; - enum symmetric { + export enum symmetric { idea = 1, tripledes = 2, cast5 = 3, @@ -867,31 +869,30 @@ export namespace enums { aes128 = 7, aes192 = 8, aes256 = 9, - twofish = 10, + twofish = 10 } export type keyStatusNames = 'invalid' | 'expired' | 'revoked' | 'valid' | 'noSelfCert'; - enum keyStatus { + export enum keyStatus { invalid = 0, expired = 1, revoked = 2, valid = 3, - noSelfCert = 4, + noSelfCert = 4 } - export type keyFlagsNames = 'certifyKeys' | 'signData' | 'encryptCommunication' | 'encryptStorage' | 'splitPrivateKey' | 'authentication' - | 'sharedPrivateKey'; - enum keyFlags { + export type keyFlagsNames = 'certifyKeys' | 'signData' | 'encryptCommunication' | 'encryptStorage' | 'splitPrivateKey' | 'authentication' | 'sharedPrivateKey'; + export enum keyFlags { certifyKeys = 1, signData = 2, encryptCommunication = 4, encryptStorage = 8, splitPrivateKey = 16, authentication = 32, - sharedPrivateKey = 128, + sharedPrivateKey = 128 } - enum signature { + export enum signature { binary = 0, text = 1, standalone = 2, @@ -910,21 +911,21 @@ export namespace enums { } export type aeadNames = 'eax' | 'ocb' | 'gcm'; - enum aead { + export enum aead { eax = 1, ocb = 2, experimentalGCM = 100 // Private algorithm } - export type literalFormatNames = 'utf8' | 'binary' | 'text' | 'mime' - enum literal { + export type literalFormatNames = 'utf8' | 'binary' | 'text' | 'mime'; + export enum literal { binary = 98, text = 116, utf8 = 117, mime = 109 } - enum s2k { + export enum s2k { simple = 0, salted = 1, iterated = 3, diff --git a/package-lock.json b/package-lock.json index e6377dfb..b1ceb5e7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@rollup/plugin-wasm": "^6.2.2", "@types/chai": "^4.3.14", + "@typescript-eslint/parser": "^7.8.0", "argon2id": "^1.0.1", "benchmark": "^2.1.4", "c8": "^8.0.1", @@ -33,6 +34,7 @@ "eslint": "^8.57.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-base": "^15.0.0", + "eslint-config-airbnb-typescript": "^18.0.0", "eslint-plugin-chai-friendly": "^0.7.4", "eslint-plugin-import": "^2.29.1", "eslint-plugin-unicorn": "^48.0.1", @@ -1375,6 +1377,13 @@ "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", "dev": true }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "peer": true + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -1424,6 +1433,277 @@ "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", "dev": true }, + "node_modules/@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "dev": true, + "peer": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.8.0.tgz", + "integrity": "sha512-gFTT+ezJmkwutUPmB0skOj3GZJtlEGnlssems4AjkVweUPGj7jRwwqg0Hhg7++kPGJqKtTYx+R05Ftww372aIg==", + "dev": true, + "peer": true, + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.8.0", + "@typescript-eslint/type-utils": "7.8.0", + "@typescript-eslint/utils": "7.8.0", + "@typescript-eslint/visitor-keys": "7.8.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "peer": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.8.0.tgz", + "integrity": "sha512-KgKQly1pv0l4ltcftP59uQZCi4HUYswCLbTqVZEJu7uLX8CTLyswqMLqLN+2QFz4jCptqWVV4SB7vdxcH2+0kQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "7.8.0", + "@typescript-eslint/types": "7.8.0", + "@typescript-eslint/typescript-estree": "7.8.0", + "@typescript-eslint/visitor-keys": "7.8.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.8.0.tgz", + "integrity": "sha512-viEmZ1LmwsGcnr85gIq+FCYI7nO90DVbE37/ll51hjv9aG+YZMb4WDE2fyWpUR4O/UrhGRpYXK/XajcGTk2B8g==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.8.0", + "@typescript-eslint/visitor-keys": "7.8.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.8.0.tgz", + "integrity": "sha512-H70R3AefQDQpz9mGv13Uhi121FNMh+WEaRqcXTX09YEDky21km4dV1ZXJIp8QjXc4ZaVkXVdohvWDzbnbHDS+A==", + "dev": true, + "peer": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "7.8.0", + "@typescript-eslint/utils": "7.8.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.8.0.tgz", + "integrity": "sha512-wf0peJ+ZGlcH+2ZS23aJbOv+ztjeeP8uQ9GgwMJGVLx/Nj9CJt17GWgWWoSmoRVKAX2X+7fzEnAjxdvK2gqCLw==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.8.0.tgz", + "integrity": "sha512-5pfUCOwK5yjPaJQNy44prjCwtr981dO8Qo9J9PwYXZ0MosgAbfEMB008dJ5sNo3+/BN6ytBPuSvXUg9SAqB0dg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.8.0", + "@typescript-eslint/visitor-keys": "7.8.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.8.0.tgz", + "integrity": "sha512-L0yFqOCflVqXxiZyXrDr80lnahQfSOfc9ELAAZ75sqicqp2i36kEZZGuUymHNFoYOqxRT05up760b4iGsl02nQ==", + "dev": true, + "peer": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.15", + "@types/semver": "^7.5.8", + "@typescript-eslint/scope-manager": "7.8.0", + "@typescript-eslint/types": "7.8.0", + "@typescript-eslint/typescript-estree": "7.8.0", + "semver": "^7.6.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "peer": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.8.0.tgz", + "integrity": "sha512-q4/gibTNBQNA0lGyYQCmWRS5D15n8rXh4QjK3KV+MBPlTYHpfBUT3D3PaPR/HeNiI9W6R7FvlkcGhNyAoP+caA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.8.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@ungap/structured-clone": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", @@ -1611,6 +1891,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/array.prototype.findlast": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", @@ -2554,6 +2843,18 @@ "node": ">=0.3.1" } }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -2997,6 +3298,20 @@ "eslint-plugin-import": "^2.25.2" } }, + "node_modules/eslint-config-airbnb-typescript": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-18.0.0.tgz", + "integrity": "sha512-oc+Lxzgzsu8FQyFVa4QFaVKiitTYiiW3frB9KYW5OWdPrqFc7FzxgB20hP4cHMlr+MBzGcLl3jnCOVOydL9mIg==", + "dev": true, + "dependencies": { + "eslint-config-airbnb-base": "^15.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^7.0.0", + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" + } + }, "node_modules/eslint-import-resolver-node": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", @@ -3400,6 +3715,34 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -3807,6 +4150,35 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -5441,6 +5813,28 @@ "node": ">= 0.6" } }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -6061,6 +6455,15 @@ "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", "dev": true }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/pathval": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", @@ -7347,6 +7750,18 @@ "node": ">=0.6" } }, + "node_modules/ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "dev": true, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, "node_modules/ts-node": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", @@ -8816,6 +9231,13 @@ "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", "dev": true }, + "@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "peer": true + }, "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -8865,6 +9287,170 @@ "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", "dev": true }, + "@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "dev": true, + "peer": true + }, + "@typescript-eslint/eslint-plugin": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.8.0.tgz", + "integrity": "sha512-gFTT+ezJmkwutUPmB0skOj3GZJtlEGnlssems4AjkVweUPGj7jRwwqg0Hhg7++kPGJqKtTYx+R05Ftww372aIg==", + "dev": true, + "peer": true, + "requires": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.8.0", + "@typescript-eslint/type-utils": "7.8.0", + "@typescript-eslint/utils": "7.8.0", + "@typescript-eslint/visitor-keys": "7.8.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "dependencies": { + "semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "peer": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "@typescript-eslint/parser": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.8.0.tgz", + "integrity": "sha512-KgKQly1pv0l4ltcftP59uQZCi4HUYswCLbTqVZEJu7uLX8CTLyswqMLqLN+2QFz4jCptqWVV4SB7vdxcH2+0kQ==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "7.8.0", + "@typescript-eslint/types": "7.8.0", + "@typescript-eslint/typescript-estree": "7.8.0", + "@typescript-eslint/visitor-keys": "7.8.0", + "debug": "^4.3.4" + } + }, + "@typescript-eslint/scope-manager": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.8.0.tgz", + "integrity": "sha512-viEmZ1LmwsGcnr85gIq+FCYI7nO90DVbE37/ll51hjv9aG+YZMb4WDE2fyWpUR4O/UrhGRpYXK/XajcGTk2B8g==", + "dev": true, + "requires": { + "@typescript-eslint/types": "7.8.0", + "@typescript-eslint/visitor-keys": "7.8.0" + } + }, + "@typescript-eslint/type-utils": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.8.0.tgz", + "integrity": "sha512-H70R3AefQDQpz9mGv13Uhi121FNMh+WEaRqcXTX09YEDky21km4dV1ZXJIp8QjXc4ZaVkXVdohvWDzbnbHDS+A==", + "dev": true, + "peer": true, + "requires": { + "@typescript-eslint/typescript-estree": "7.8.0", + "@typescript-eslint/utils": "7.8.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + } + }, + "@typescript-eslint/types": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.8.0.tgz", + "integrity": "sha512-wf0peJ+ZGlcH+2ZS23aJbOv+ztjeeP8uQ9GgwMJGVLx/Nj9CJt17GWgWWoSmoRVKAX2X+7fzEnAjxdvK2gqCLw==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.8.0.tgz", + "integrity": "sha512-5pfUCOwK5yjPaJQNy44prjCwtr981dO8Qo9J9PwYXZ0MosgAbfEMB008dJ5sNo3+/BN6ytBPuSvXUg9SAqB0dg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "7.8.0", + "@typescript-eslint/visitor-keys": "7.8.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "@typescript-eslint/utils": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.8.0.tgz", + "integrity": "sha512-L0yFqOCflVqXxiZyXrDr80lnahQfSOfc9ELAAZ75sqicqp2i36kEZZGuUymHNFoYOqxRT05up760b4iGsl02nQ==", + "dev": true, + "peer": true, + "requires": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.15", + "@types/semver": "^7.5.8", + "@typescript-eslint/scope-manager": "7.8.0", + "@typescript-eslint/types": "7.8.0", + "@typescript-eslint/typescript-estree": "7.8.0", + "semver": "^7.6.0" + }, + "dependencies": { + "semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "peer": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "@typescript-eslint/visitor-keys": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.8.0.tgz", + "integrity": "sha512-q4/gibTNBQNA0lGyYQCmWRS5D15n8rXh4QjK3KV+MBPlTYHpfBUT3D3PaPR/HeNiI9W6R7FvlkcGhNyAoP+caA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "7.8.0", + "eslint-visitor-keys": "^3.4.3" + } + }, "@ungap/structured-clone": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", @@ -9004,6 +9590,12 @@ "is-string": "^1.0.7" } }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, "array.prototype.findlast": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", @@ -9726,6 +10318,15 @@ "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -10096,6 +10697,15 @@ "semver": "^6.3.0" } }, + "eslint-config-airbnb-typescript": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-18.0.0.tgz", + "integrity": "sha512-oc+Lxzgzsu8FQyFVa4QFaVKiitTYiiW3frB9KYW5OWdPrqFc7FzxgB20hP4cHMlr+MBzGcLl3jnCOVOydL9mIg==", + "dev": true, + "requires": { + "eslint-config-airbnb-base": "^15.0.0" + } + }, "eslint-import-resolver-node": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", @@ -10404,6 +11014,30 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -10707,6 +11341,28 @@ "define-properties": "^1.1.3" } }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "dependencies": { + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + } + } + }, "gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -11941,6 +12597,22 @@ "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "dev": true }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, "mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -12397,6 +13069,12 @@ "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", "dev": true }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, "pathval": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", @@ -13362,6 +14040,13 @@ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true }, + "ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "dev": true, + "requires": {} + }, "ts-node": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", diff --git a/package.json b/package.json index 007a9db9..38ee83db 100644 --- a/package.json +++ b/package.json @@ -77,6 +77,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@rollup/plugin-wasm": "^6.2.2", "@types/chai": "^4.3.14", + "@typescript-eslint/parser": "^7.8.0", "argon2id": "^1.0.1", "benchmark": "^2.1.4", "c8": "^8.0.1", @@ -86,6 +87,7 @@ "eslint": "^8.57.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-base": "^15.0.0", + "eslint-config-airbnb-typescript": "^18.0.0", "eslint-plugin-chai-friendly": "^0.7.4", "eslint-plugin-import": "^2.29.1", "eslint-plugin-unicorn": "^48.0.1", diff --git a/src/biginteger.ts b/src/biginteger.ts index c99e5fcd..6b9c0adc 100644 --- a/src/biginteger.ts +++ b/src/biginteger.ts @@ -7,6 +7,7 @@ */ export default class BigInteger { private value: bigint; + /** * Get a BigInteger (input must be big endian for strings and arrays) * @param {Number|String|Uint8Array} n - Value to convert @@ -21,7 +22,7 @@ export default class BigInteger { const bytes = n; const hexAlphabet = '0123456789ABCDEF'; let s = ''; - bytes.forEach((v) => { + bytes.forEach(v => { s += hexAlphabet[v >> 4] + hexAlphabet[v & 15]; }); this.value = BigInt('0x0' + s); @@ -239,9 +240,9 @@ export default class BigInteger { } return { - x: new BigInteger(aNegated? -xPrev : xPrev), + x: new BigInteger(aNegated ? -xPrev : xPrev), y: new BigInteger(bNegated ? -yPrev : yPrev), - gcd: new BigInteger(a), + gcd: new BigInteger(a) }; } diff --git a/src/crypto/public_key/elliptic/brainpool/brainpoolP256r1.ts b/src/crypto/public_key/elliptic/brainpool/brainpoolP256r1.ts index c5ae5395..1cbdf69a 100644 --- a/src/crypto/public_key/elliptic/brainpool/brainpoolP256r1.ts +++ b/src/crypto/public_key/elliptic/brainpool/brainpoolP256r1.ts @@ -4,6 +4,7 @@ import { Field } from '@noble/curves/abstract/modular'; // brainpoolP256r1: https://datatracker.ietf.org/doc/html/rfc5639#section-3.4 +// eslint-disable-next-line new-cap const Fp = Field(BigInt('0xa9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d1f6e5377')); const CURVE_A = Fp.create(BigInt('0x7d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6ce94a4b44f330b5d9')); const CURVE_B = BigInt('0x26dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7e1ce6bccdc18ff8c07b6'); @@ -19,5 +20,5 @@ export const brainpoolP256r1 = createCurve({ Gx: BigInt('0x8bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27e1e3bd23c23a4453bd9ace3262'), Gy: BigInt('0x547ef835c3dac4fd97f8461a14611dc9c27745132ded8e545c1d54c72f046997'), h: BigInt(1), - lowS: false, + lowS: false } as const, sha256); diff --git a/src/crypto/public_key/elliptic/brainpool/brainpoolP384r1.ts b/src/crypto/public_key/elliptic/brainpool/brainpoolP384r1.ts index 82f177df..e7cee9c3 100644 --- a/src/crypto/public_key/elliptic/brainpool/brainpoolP384r1.ts +++ b/src/crypto/public_key/elliptic/brainpool/brainpoolP384r1.ts @@ -4,6 +4,7 @@ import { Field } from '@noble/curves/abstract/modular'; // brainpoolP384 r1: https://datatracker.ietf.org/doc/html/rfc5639#section-3.6 +// eslint-disable-next-line new-cap const Fp = Field(BigInt('0x8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b412b1da197fb71123acd3a729901d1a71874700133107ec53')); const CURVE_A = Fp.create(BigInt('0x7bc382c63d8c150c3c72080ace05afa0c2bea28e4fb22787139165efba91f90f8aa5814a503ad4eb04a8c7dd22ce2826')); const CURVE_B = BigInt('0x04a8c7dd22ce28268b39b55416f0447c2fb77de107dcd2a62e880ea53eeb62d57cb4390295dbc9943ab78696fa504c11'); @@ -19,5 +20,5 @@ export const brainpoolP384r1 = createCurve({ Gx: BigInt('0x1d1c64f068cf45ffa2a63a81b7c13f6b8847a3e77ef14fe3db7fcafe0cbd10e8e826e03436d646aaef87b2e247d4af1e'), Gy: BigInt('0x8abe1d7520f9c2a45cb1eb8e95cfd55262b70b29feec5864e19c054ff99129280e4646217791811142820341263c5315'), h: BigInt(1), - lowS: false, + lowS: false } as const, sha384); diff --git a/src/crypto/public_key/elliptic/brainpool/brainpoolP512r1.ts b/src/crypto/public_key/elliptic/brainpool/brainpoolP512r1.ts index 37ed3b3d..86e2b86a 100644 --- a/src/crypto/public_key/elliptic/brainpool/brainpoolP512r1.ts +++ b/src/crypto/public_key/elliptic/brainpool/brainpoolP512r1.ts @@ -4,6 +4,7 @@ import { Field } from '@noble/curves/abstract/modular'; // brainpoolP512r1: https://datatracker.ietf.org/doc/html/rfc5639#section-3.7 +// eslint-disable-next-line new-cap const Fp = Field(BigInt('0xaadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca703308717d4d9b009bc66842aecda12ae6a380e62881ff2f2d82c68528aa6056583a48f3')); const CURVE_A = Fp.create(BigInt('0x7830a3318b603b89e2327145ac234cc594cbdd8d3df91610a83441caea9863bc2ded5d5aa8253aa10a2ef1c98b9ac8b57f1117a72bf2c7b9e7c1ac4d77fc94ca')); const CURVE_B = BigInt('0x3df91610a83441caea9863bc2ded5d5aa8253aa10a2ef1c98b9ac8b57f1117a72bf2c7b9e7c1ac4d77fc94cadc083e67984050b75ebae5dd2809bd638016f723'); @@ -19,5 +20,5 @@ export const brainpoolP512r1 = createCurve({ Gx: BigInt('0x81aee4bdd82ed9645a21322e9c4c6a9385ed9f70b5d916c1b43b62eef4d0098eff3b1f78e2d0d48d50d1687b93b97d5f7c6d5047406a5e688b352209bcb9f822'), Gy: BigInt('0x7dde385d566332ecc0eabfa9cf7822fdf209f70024a57b1aa000c55b881f8111b2dcde494a5f485e5bca4bd88a2763aed1ca2b2fa8f0540678cd1e0f3ad80892'), h: BigInt(1), - lowS: false, + lowS: false } as const, sha512); diff --git a/src/crypto/public_key/elliptic/ecdsa.js b/src/crypto/public_key/elliptic/ecdsa.js index 9f6f6446..b7db3a85 100644 --- a/src/crypto/public_key/elliptic/ecdsa.js +++ b/src/crypto/public_key/elliptic/ecdsa.js @@ -157,6 +157,7 @@ export async function validateParams(oid, Q, d) { const hashed = await hash.digest(hashAlgo, message); try { const signature = await sign(oid, hashAlgo, message, Q, d, hashed); + // eslint-disable-next-line @typescript-eslint/return-await return await verify(oid, hashAlgo, signature, message, Q, hashed); } catch (err) { return false; diff --git a/src/crypto/public_key/elliptic/noble_curves.js b/src/crypto/public_key/elliptic/noble_curves.js index 49af7169..acfac17e 100644 --- a/src/crypto/public_key/elliptic/noble_curves.js +++ b/src/crypto/public_key/elliptic/noble_curves.js @@ -7,11 +7,11 @@ import { p256 as nistP256 } from '@noble/curves/p256'; import { p384 as nistP384 } from '@noble/curves/p384'; import { p521 as nistP521 } from '@noble/curves/p521'; +import { x448, ed448 } from '@noble/curves/ed448'; +import { secp256k1 } from '@noble/curves/secp256k1'; import { brainpoolP256r1 } from './brainpool/brainpoolP256r1'; import { brainpoolP384r1 } from './brainpool/brainpoolP384r1'; import { brainpoolP512r1 } from './brainpool/brainpoolP512r1'; -import { x448, ed448 } from '@noble/curves/ed448'; -import { secp256k1 } from '@noble/curves/secp256k1'; export const nobleCurves = new Map(Object.entries({ nistP256, diff --git a/src/crypto/public_key/prime.js b/src/crypto/public_key/prime.js index 7664a42c..854f02ba 100644 --- a/src/crypto/public_key/prime.js +++ b/src/crypto/public_key/prime.js @@ -20,7 +20,6 @@ * @module crypto/public_key/prime */ import BigInteger from '../../biginteger'; -import util from '../../util'; import { getRandomBigInteger } from '../random'; /** diff --git a/src/crypto/public_key/rsa.js b/src/crypto/public_key/rsa.js index 862d34b5..e8c3adff 100644 --- a/src/crypto/public_key/rsa.js +++ b/src/crypto/public_key/rsa.js @@ -325,7 +325,7 @@ async function nodeVerify(hashAlgo, data, s, n, e) { verify.end(); try { - return await verify.verify(key, s); + return verify.verify(key, s); } catch (err) { return false; } diff --git a/src/key/key.js b/src/key/key.js index d0aaa6b9..8e608572 100644 --- a/src/key/key.js +++ b/src/key/key.js @@ -501,6 +501,7 @@ class Key { } } if (!users.length) { + // eslint-disable-next-line @typescript-eslint/no-throw-literal throw exception || new Error('Could not find primary user'); } await Promise.all(users.map(async function (a) { diff --git a/src/openpgp.js b/src/openpgp.js index c645eb93..edbdd8a1 100644 --- a/src/openpgp.js +++ b/src/openpgp.js @@ -301,7 +301,7 @@ export async function encrypt({ message, encryptionKeys, signingKeys, passwords, // serialize data const armor = format === 'armored'; const data = armor ? message.armor(config) : message.write(); - return convertStream(data); + return await convertStream(data); } catch (err) { throw util.wrapError('Error encrypting message', err); } @@ -438,7 +438,7 @@ export async function sign({ message, signingKeys, format = 'armored', detached ]); }); } - return convertStream(signature); + return await convertStream(signature); } catch (err) { throw util.wrapError('Error signing message', err); } diff --git a/src/packet/padding.js b/src/packet/padding.js index 567ef2e5..8baec745 100644 --- a/src/packet/padding.js +++ b/src/packet/padding.js @@ -37,7 +37,7 @@ class PaddingPacket { * Read a padding packet * @param {Uint8Array | ReadableStream} bytes */ - read(bytes) { // eslint-disable-line no-unused-vars + read(bytes) { // eslint-disable-line @typescript-eslint/no-unused-vars // Padding packets are ignored, so this function is never called. } diff --git a/src/packet/public_subkey.js b/src/packet/public_subkey.js index 731fc222..a0b664e8 100644 --- a/src/packet/public_subkey.js +++ b/src/packet/public_subkey.js @@ -35,7 +35,7 @@ class PublicSubkeyPacket extends PublicKeyPacket { * @param {Date} [date] - Creation date * @param {Object} [config] - Full configuration, defaults to openpgp.config */ - // eslint-disable-next-line no-useless-constructor + // eslint-disable-next-line @typescript-eslint/no-useless-constructor constructor(date, config) { super(date, config); } diff --git a/src/packet/sym_encrypted_integrity_protected_data.js b/src/packet/sym_encrypted_integrity_protected_data.js index 764c0f6a..4512aaa2 100644 --- a/src/packet/sym_encrypted_integrity_protected_data.js +++ b/src/packet/sym_encrypted_integrity_protected_data.js @@ -287,7 +287,7 @@ export async function runAEAD(packet, fn, key, data) { done = true; } cryptedBytes += chunk.length - tagLengthIfDecrypting; - // eslint-disable-next-line no-loop-func + // eslint-disable-next-line @typescript-eslint/no-loop-func latestPromise = latestPromise.then(() => cryptedPromise).then(async crypted => { await writer.ready; await writer.write(crypted); diff --git a/test/crypto/validate.js b/test/crypto/validate.js index 7f5e32bf..3731ea9e 100644 --- a/test/crypto/validate.js +++ b/test/crypto/validate.js @@ -3,7 +3,7 @@ import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/new chaiUse(chaiAsPromised); import openpgp from '../initOpenpgp.js'; -import BigInteger from '../../src/biginteger.js'; +import BigInteger from '../../src/biginteger.ts'; const armoredDSAKey = `-----BEGIN PGP PRIVATE KEY BLOCK----- diff --git a/test/general/brainpool.js b/test/general/brainpool.js index 1cd3f78f..c50987c0 100644 --- a/test/general/brainpool.js +++ b/test/general/brainpool.js @@ -318,14 +318,13 @@ function omnibus() { signingKeys: [hi] }); // Decrypting and verifying - return openpgp.decrypt({ + const output = await openpgp.decrypt({ message: await openpgp.readMessage({ armoredMessage: encrypted }), decryptionKeys: bye, verificationKeys: [pubHi] - }).then(async output => { - expect(output.data).to.equal(testData2); - await expect(output.signatures[0].verified).to.eventually.be.true; }); + expect(output.data).to.equal(testData2); + await expect(output.signatures[0].verified).to.eventually.be.true; } finally { openpgp.config.rejectCurves = rejectCurves; } diff --git a/test/general/packet.js b/test/general/packet.js index ad34ca31..78f5d621 100644 --- a/test/general/packet.js +++ b/test/general/packet.js @@ -191,14 +191,15 @@ export default () => describe('Packet', function() { cryptStub.onCall(0).callsFake(async function() { cryptCallsActive++; try { - return await crypt.apply(this, arguments); // eslint-disable-line no-invalid-this + // eslint-disable-next-line @typescript-eslint/return-await + return await crypt.apply(this, arguments); } finally { cryptCallsActive--; } }); cryptStub.onCall(1).callsFake(function() { expect(cryptCallsActive).to.equal(1); - return crypt.apply(this, arguments); // eslint-disable-line no-invalid-this + return crypt.apply(this, arguments); }); cryptStub.callThrough(); return cryptStub; diff --git a/test/general/streaming.js b/test/general/streaming.js index 85761f57..105722a2 100644 --- a/test/general/streaming.js +++ b/test/general/streaming.js @@ -254,7 +254,7 @@ function tests() { expect(stream.isStream(encrypted)).to.equal(expectedType); const message = await openpgp.readMessage({ binaryMessage: encrypted }); - setTimeout(dataArrived, 3000); // Do not wait until data arrived, but wait a bit to check that it doesn't arrive early. + setTimeout(() => dataArrived(), 3000); // Do not wait until data arrived, but wait a bit to check that it doesn't arrive early. const decrypted = await openpgp.decrypt({ passwords: ['test'], message, diff --git a/test/general/util.js b/test/general/util.js index 5ba9b290..5a7d87f4 100644 --- a/test/general/util.js +++ b/test/general/util.js @@ -38,7 +38,7 @@ export default () => describe('Util unit tests', function() { expect(util.isArray(data)).to.be.true; }); it('should return true for type Array', function() { - const data = Array(); // eslint-disable-line no-array-constructor + const data = Array(); // eslint-disable-line @typescript-eslint/no-array-constructor expect(util.isArray(data)).to.be.true; }); it('should return true for inherited type of Array', function() { From 90495522f7477f27c8001152eed7449dc337187c Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Mon, 6 May 2024 12:19:41 +0200 Subject: [PATCH 133/201] CI: update Browserstack legacy targets (drop Safari 13) --- package.json | 2 +- test/karma.conf.cjs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 38ee83db..2f5d1bac 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "prebrowsertest": "npm run build-test", "browsertest": "npm start -- -o test/unittests.html", "test-browser": "karma start test/karma.conf.cjs", - "test-browserstack": "karma start test/karma.conf.cjs --browsers bs_safari_latest,bs_ios_14,bs_safari_13_1", + "test-browserstack": "karma start test/karma.conf.cjs --browsers bs_safari_latest,bs_ios_14,bs_safari_14", "coverage": "c8 npm test", "lint": "eslint .", "docs": "jsdoc --configure .jsdocrc.cjs --destination docs --recurse README.md src && printf '%s' 'docs.openpgpjs.org' > docs/CNAME", diff --git a/test/karma.conf.cjs b/test/karma.conf.cjs index 25d5cf4f..30c7ba30 100644 --- a/test/karma.conf.cjs +++ b/test/karma.conf.cjs @@ -102,12 +102,12 @@ module.exports = function(config) { os: 'OS X', os_version: 'Ventura' }, - bs_safari_13_1: { // no BigInt support + bs_safari_14: { base: 'BrowserStack', browser: 'Safari', - browser_version: '13.1', + browser_version: '14', os: 'OS X', - os_version: 'Catalina' + os_version: 'Big Sur' }, bs_ios_14: { base: 'BrowserStack', From cf0285add5da4acbf11910d8028253fe6a345cf6 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Fri, 10 May 2024 13:06:09 +0200 Subject: [PATCH 134/201] Drop BigInteger class, use standalone helpers --- package-lock.json | 13 + package.json | 1 + rollup.config.js | 16 +- src/biginteger.ts | 499 ------------------- src/crypto/biginteger.ts | 216 ++++++++ src/crypto/pkcs1.js | 2 +- src/crypto/public_key/dsa.js | 109 ++-- src/crypto/public_key/elgamal.js | 71 +-- src/crypto/public_key/elliptic/ecdsa.js | 6 +- src/crypto/public_key/{prime.js => prime.ts} | 98 ++-- src/crypto/public_key/rsa.js | 147 +++--- src/crypto/random.js | 22 +- test/crypto/biginteger.js | 96 ++++ test/crypto/index.js | 2 + test/crypto/validate.js | 11 +- tsconfig.json | 2 +- 16 files changed, 572 insertions(+), 739 deletions(-) delete mode 100644 src/biginteger.ts create mode 100644 src/crypto/biginteger.ts rename src/crypto/public_key/{prime.js => prime.ts} (79%) create mode 100644 test/crypto/biginteger.js diff --git a/package-lock.json b/package-lock.json index b1ceb5e7..8d0c7a99 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,6 +27,7 @@ "@typescript-eslint/parser": "^7.8.0", "argon2id": "^1.0.1", "benchmark": "^2.1.4", + "bn.js": "^5.2.1", "c8": "^8.0.1", "chai": "^4.4.1", "chai-as-promised": "^7.1.1", @@ -2141,6 +2142,12 @@ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", "dev": true }, + "node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", + "dev": true + }, "node_modules/body-parser": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", @@ -9783,6 +9790,12 @@ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", "dev": true }, + "bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", + "dev": true + }, "body-parser": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", diff --git a/package.json b/package.json index 2f5d1bac..4d0968ba 100644 --- a/package.json +++ b/package.json @@ -80,6 +80,7 @@ "@typescript-eslint/parser": "^7.8.0", "argon2id": "^1.0.1", "benchmark": "^2.1.4", + "bn.js": "^5.2.1", "c8": "^8.0.1", "chai": "^4.4.1", "chai-as-promised": "^7.1.1", diff --git a/rollup.config.js b/rollup.config.js index 870c0c26..87050ee8 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -64,7 +64,9 @@ export default Object.assign([ resolve({ browser: true }), - typescript(), + typescript({ + compilerOptions: { outDir: './dist/tmp-ts' } // to avoid js files being overwritten + }), commonjs({ ignore: nodeBuiltinModules.concat(nodeDependencies) }), @@ -89,7 +91,9 @@ export default Object.assign([ resolve({ exportConditions: ['node'] // needed for resolution of noble-curves import of '@noble/crypto' in Node 16 and 18 }), - typescript(), + typescript({ + compilerOptions: { outDir: './dist/tmp-ts' } + }), commonjs(), replace({ 'OpenPGP.js VERSION': `OpenPGP.js ${pkg.version}` @@ -109,7 +113,9 @@ export default Object.assign([ resolve({ browser: true }), - typescript(), + typescript({ + compilerOptions: { outDir: './dist/lightweight/tmp-ts' } + }), commonjs({ ignore: nodeBuiltinModules.concat(nodeDependencies) }), @@ -136,7 +142,9 @@ export default Object.assign([ resolve({ browser: true }), - typescript(), + typescript({ + compilerOptions: { outDir: './test/lib/tmp-ts' } + }), commonjs({ ignore: nodeBuiltinModules.concat(nodeDependencies), requireReturnsDefault: 'preferred' diff --git a/src/biginteger.ts b/src/biginteger.ts deleted file mode 100644 index 6b9c0adc..00000000 --- a/src/biginteger.ts +++ /dev/null @@ -1,499 +0,0 @@ -/** - * @fileoverview - * BigInteger implementation of basic operations - * that wraps the native BigInt library. - * Operations are not constant time, - * but we try and limit timing leakage where we can - */ -export default class BigInteger { - private value: bigint; - - /** - * Get a BigInteger (input must be big endian for strings and arrays) - * @param {Number|String|Uint8Array} n - Value to convert - * @throws {Error} on null or undefined input - */ - constructor(n: Uint8Array | string | number | bigint) { - if (n === undefined) { - throw new Error('Invalid BigInteger input'); - } - - if (n instanceof Uint8Array) { - const bytes = n; - const hexAlphabet = '0123456789ABCDEF'; - let s = ''; - bytes.forEach(v => { - s += hexAlphabet[v >> 4] + hexAlphabet[v & 15]; - }); - this.value = BigInt('0x0' + s); - } else { - this.value = BigInt(n); - } - } - - clone() { - return new BigInteger(this.value); - } - - /** - * BigInteger increment in place - */ - iinc() { - this.value++; - return this; - } - - /** - * BigInteger increment - * @returns {BigInteger} this + 1. - */ - inc() { - return this.clone().iinc(); - } - - /** - * BigInteger decrement in place - */ - idec() { - this.value--; - return this; - } - - /** - * BigInteger decrement - * @returns {BigInteger} this - 1. - */ - dec() { - return this.clone().idec(); - } - - /** - * BigInteger addition in place - * @param {BigInteger} x - Value to add - */ - iadd(x: BigInteger) { - this.value += x.value; - return this; - } - - /** - * BigInteger addition - * @param {BigInteger} x - Value to add - * @returns {BigInteger} this + x. - */ - add(x: BigInteger) { - return this.clone().iadd(x); - } - - /** - * BigInteger subtraction in place - * @param {BigInteger} x - Value to subtract - */ - isub(x: BigInteger) { - this.value -= x.value; - return this; - } - - /** - * BigInteger subtraction - * @param {BigInteger} x - Value to subtract - * @returns {BigInteger} this - x. - */ - sub(x: BigInteger) { - return this.clone().isub(x); - } - - /** - * BigInteger multiplication in place - * @param {BigInteger} x - Value to multiply - */ - imul(x: BigInteger) { - this.value *= x.value; - return this; - } - - /** - * BigInteger multiplication - * @param {BigInteger} x - Value to multiply - * @returns {BigInteger} this * x. - */ - mul(x: BigInteger) { - return this.clone().imul(x); - } - - /** - * Compute value modulo m, in place - * @param {BigInteger} m - Modulo - */ - imod(m: BigInteger) { - this.value %= m.value; - if (this.isNegative()) { - this.iadd(m); - } - return this; - } - - /** - * Compute value modulo m - * @param {BigInteger} m - Modulo - * @returns {BigInteger} this mod m. - */ - mod(m: BigInteger) { - return this.clone().imod(m); - } - - /** - * Compute modular exponentiation using square and multiply - * @param {BigInteger} e - Exponent - * @param {BigInteger} n - Modulo - * @returns {BigInteger} this ** e mod n. - */ - modExp(e: BigInteger, n: BigInteger) { - if (n.isZero()) throw Error('Modulo cannot be zero'); - if (n.isOne()) return new BigInteger(0); - if (e.isNegative()) throw Error('Unsopported negative exponent'); - - let exp = e.value; - let x = this.value; - - x %= n.value; - let r = BigInt(1); - while (exp > BigInt(0)) { - const lsb = exp & BigInt(1); - exp >>= BigInt(1); // e / 2 - // Always compute multiplication step, to reduce timing leakage - const rx = (r * x) % n.value; - // Update r only if lsb is 1 (odd exponent) - r = lsb ? rx : r; - x = (x * x) % n.value; // Square - } - return new BigInteger(r); - } - - /** - * Compute the inverse of this value modulo n - * Note: this and and n must be relatively prime - * @param {BigInteger} n - Modulo - * @returns {BigInteger} x such that this*x = 1 mod n - * @throws {Error} if the inverse does not exist - */ - modInv(n: BigInteger) { - const { gcd, x } = this._egcd(n); - if (!gcd.isOne()) { - throw new Error('Inverse does not exist'); - } - return x.add(n).mod(n); - } - - /** - * BigInteger division, in place - * @param {BigInteger} n - Value to divide - */ - idiv(n: BigInteger) { - this.value /= n.value; - return this; - } - - /** - * BigInteger division - * @param {BigInteger} n - Value to divide - * @returns {BigInteger} this divded by n. - */ - div(n: BigInteger) { - return this.clone().idiv(n); - } - - /** - * Extended Eucleadian algorithm (http://anh.cs.luc.edu/331/notes/xgcd.pdf) - * Given a = this and b, compute (x, y) such that ax + by = gdc(a, b). - * Negative numbers are also supported. - * @param {BigInteger} b - Second operand - * @returns {{ gcd, x, y: BigInteger }} - */ - private _egcd(bInput: BigInteger) { - let x = BigInt(0); - let y = BigInt(1); - let xPrev = BigInt(1); - let yPrev = BigInt(0); - - // Deal with negative numbers: run algo over absolute values, - // and "move" the sign to the returned x and/or y. - // See https://math.stackexchange.com/questions/37806/extended-euclidean-algorithm-with-negative-numbers - let a = this.abs().value; - let b = bInput.abs().value; - const aNegated = this.isNegative(); - const bNegated = bInput.isNegative(); - - while (b !== BigInt(0)) { - const q = a / b; - let tmp = x; - x = xPrev - q * x; - xPrev = tmp; - - tmp = y; - y = yPrev - q * y; - yPrev = tmp; - - tmp = b; - b = a % b; - a = tmp; - } - - return { - x: new BigInteger(aNegated ? -xPrev : xPrev), - y: new BigInteger(bNegated ? -yPrev : yPrev), - gcd: new BigInteger(a) - }; - } - - /** - * Compute greatest common divisor between this and n - * @param {BigInteger} b - Operand - * @returns {BigInteger} gcd - */ - gcd(bInput: BigInteger) { - let a = this.value; - let b = bInput.value; - while (b !== BigInt(0)) { - const tmp = b; - b = a % b; - a = tmp; - } - return new BigInteger(a); - } - - /** - * Shift this to the left by x, in place - * @param {BigInteger} x - Shift value - */ - ileftShift(x: BigInteger) { - this.value <<= x.value; - return this; - } - - /** - * Shift this to the left by x - * @param {BigInteger} x - Shift value - * @returns {BigInteger} this << x. - */ - leftShift(x: BigInteger) { - return this.clone().ileftShift(x); - } - - /** - * Shift this to the right by x, in place - * @param {BigInteger} x - Shift value - */ - irightShift(x: BigInteger) { - this.value >>= x.value; - return this; - } - - /** - * Shift this to the right by x - * @param {BigInteger} x - Shift value - * @returns {BigInteger} this >> x. - */ - rightShift(x: BigInteger) { - return this.clone().irightShift(x); - } - - ixor(x: BigInteger) { - this.value ^= x.value; - return this; - } - - xor(x: BigInteger) { - return this.clone().ixor(x); - } - - ibitwiseAnd(x: BigInteger) { - this.value &= x.value; - return this; - } - - bitwiseAnd(x: BigInteger) { - return this.clone().ibitwiseAnd(x); - } - - ibitwiseOr(x: BigInteger) { - this.value |= x.value; - return this; - } - - /** - * Whether this value is equal to x - * @param {BigInteger} x - * @returns {Boolean} - */ - equal(x: BigInteger) { - return this.value === x.value; - } - - /** - * Whether this value is less than x - * @param {BigInteger} x - * @returns {Boolean} - */ - lt(x: BigInteger) { - return this.value < x.value; - } - - /** - * Whether this value is less than or equal to x - * @param {BigInteger} x - * @returns {Boolean} - */ - lte(x: BigInteger) { - return this.value <= x.value; - } - - /** - * Whether this value is greater than x - * @param {BigInteger} x - * @returns {Boolean} - */ - gt(x: BigInteger) { - return this.value > x.value; - } - - /** - * Whether this value is greater than or equal to x - * @param {BigInteger} x - * @returns {Boolean} - */ - gte(x: BigInteger) { - return this.value >= x.value; - } - - isZero() { - return this.value === BigInt(0); - } - - isOne() { - return this.value === BigInt(1); - } - - isNegative() { - return this.value < BigInt(0); - } - - isEven() { - return !(this.value & BigInt(1)); - } - - abs() { - const res = this.clone(); - if (this.isNegative()) { - res.value = -res.value; - } - return res; - } - - negate() { - const res = this.clone(); - res.value = -res.value; - return res; - } - - /** - * Get this value as a string - * @returns {String} this value. - */ - toString() { - return this.value.toString(); - } - - /** - * Get this value as an exact Number (max 53 bits) - * Fails if this value is too large - * @returns {Number} - */ - toNumber() { - const number = Number(this.value); - if (number > Number.MAX_SAFE_INTEGER) { - // We throw and error to conform with the bn.js implementation - throw new Error('Number can only safely store up to 53 bits'); - } - return number; - } - - /** - * Get value of i-th bit - * @param {Number} i - Bit index - * @returns {Number} Bit value. - */ - getBit(i: number) { - const bit = (this.value >> BigInt(i)) & BigInt(1); - return bit === BigInt(0) ? 0 : 1; - } - - /** - * Compute bit length - * @returns {Number} Bit length. - */ - bitLength() { - const zero = new BigInteger(0); - const one = new BigInteger(1); - const negOne = new BigInteger(-1); - - // -1n >> -1n is -1n - // 1n >> 1n is 0n - const target = this.isNegative() ? negOne : zero; - let bitlen = 1; - const tmp = this.clone(); - while (!tmp.irightShift(one).equal(target)) { - bitlen++; - } - return bitlen; - } - - /** - * Compute byte length - * @returns {Number} Byte length. - */ - byteLength() { - const zero = new BigInteger(0); - const negOne = new BigInteger(-1); - - const target = this.isNegative() ? negOne : zero; - const eight = new BigInteger(8); - let len = 1; - const tmp = this.clone(); - while (!tmp.irightShift(eight).equal(target)) { - len++; - } - return len; - } - - /** - * Get Uint8Array representation of this number - * @param {String} endian - Endianess of output array (defaults to 'be') - * @param {Number} length - Of output array - * @returns {Uint8Array} - */ - toUint8Array(endian = 'be', length: number) { - // we get and parse the hex string (https://coolaj86.com/articles/convert-js-bigints-to-typedarrays/) - // this is faster than shift+mod iterations - let hex = this.value.toString(16); - if (hex.length % 2 === 1) { - hex = '0' + hex; - } - - const rawLength = hex.length / 2; - const bytes = new Uint8Array(length || rawLength); - // parse hex - const offset = length ? length - rawLength : 0; - let i = 0; - while (i < rawLength) { - bytes[i + offset] = parseInt(hex.slice(2 * i, 2 * i + 2), 16); - i++; - } - - if (endian !== 'be') { - bytes.reverse(); - } - - return bytes; - } -} diff --git a/src/crypto/biginteger.ts b/src/crypto/biginteger.ts new file mode 100644 index 00000000..ba8c82c4 --- /dev/null +++ b/src/crypto/biginteger.ts @@ -0,0 +1,216 @@ +// Operations are not constant time, but we try and limit timing leakage where we can + +const _0n = BigInt(0); +const _1n = BigInt(1); + +export function uint8ArrayToBigInt(bytes: Uint8Array) { + const hexAlphabet = '0123456789ABCDEF'; + let s = ''; + bytes.forEach(v => { + s += hexAlphabet[v >> 4] + hexAlphabet[v & 15]; + }); + return BigInt('0x0' + s); +} + +export function mod(a: bigint, m: bigint) { + const reduced = a % m; + return reduced < _0n ? reduced + m : reduced; +} + +/** + * Compute modular exponentiation using square and multiply + * @param {BigInt} a - Base + * @param {BigInt} e - Exponent + * @param {BigInt} n - Modulo + * @returns {BigInt} b ** e mod n. + */ +export function modExp(b: bigint, e: bigint, n: bigint) { + if (n === _0n) throw Error('Modulo cannot be zero'); + if (n === _1n) return BigInt(0); + if (e < _0n) throw Error('Unsopported negative exponent'); + + let exp = e; + let x = b; + + x %= n; + let r = BigInt(1); + while (exp > _0n) { + const lsb = exp & _1n; + exp >>= _1n; // e / 2 + // Always compute multiplication step, to reduce timing leakage + const rx = (r * x) % n; + // Update r only if lsb is 1 (odd exponent) + r = lsb ? rx : r; + x = (x * x) % n; // Square + } + return r; +} + + +function abs(x: bigint) { + return x >= _0n ? x : -x; +} + +/** + * Extended Eucleadian algorithm (http://anh.cs.luc.edu/331/notes/xgcd.pdf) + * Given a and b, compute (x, y) such that ax + by = gdc(a, b). + * Negative numbers are also supported. + * @param {BigInt} a - First operand + * @param {BigInt} b - Second operand + * @returns {{ gcd, x, y: bigint }} + */ +function _egcd(aInput: bigint, bInput: bigint) { + let x = BigInt(0); + let y = BigInt(1); + let xPrev = BigInt(1); + let yPrev = BigInt(0); + + // Deal with negative numbers: run algo over absolute values, + // and "move" the sign to the returned x and/or y. + // See https://math.stackexchange.com/questions/37806/extended-euclidean-algorithm-with-negative-numbers + let a = abs(aInput); + let b = abs(bInput); + const aNegated = aInput < _0n; + const bNegated = bInput < _0n; + + while (b !== _0n) { + const q = a / b; + let tmp = x; + x = xPrev - q * x; + xPrev = tmp; + + tmp = y; + y = yPrev - q * y; + yPrev = tmp; + + tmp = b; + b = a % b; + a = tmp; + } + + return { + x: aNegated ? -xPrev : xPrev, + y: bNegated ? -yPrev : yPrev, + gcd: a + }; +} + +/** + * Compute the inverse of `a` modulo `n` + * Note: `a` and and `n` must be relatively prime + * @param {BigInt} a + * @param {BigInt} n - Modulo + * @returns {BigInt} x such that a*x = 1 mod n + * @throws {Error} if the inverse does not exist + */ +export function modInv(a: bigint, n: bigint) { + const { gcd, x } = _egcd(a, n); + if (gcd !== _1n) { + throw new Error('Inverse does not exist'); + } + return mod(x + n, n); +} + +/** + * Compute greatest common divisor between this and n + * @param {BigInt} aInput - Operand + * @param {BigInt} bInput - Operand + * @returns {BigInt} gcd + */ +export function gcd(aInput: bigint, bInput: bigint) { + let a = aInput; + let b = bInput; + while (b !== _0n) { + const tmp = b; + b = a % b; + a = tmp; + } + return a; +} + +/** + * Get this value as an exact Number (max 53 bits) + * Fails if this value is too large + * @returns {Number} + */ +export function bigIntToNumber(x: bigint) { + const number = Number(x); + if (number > Number.MAX_SAFE_INTEGER) { + // We throw and error to conform with the bn.js implementation + throw new Error('Number can only safely store up to 53 bits'); + } + return number; +} + +/** + * Get value of i-th bit + * @param {BigInt} x + * @param {Number} i - Bit index + * @returns {Number} Bit value. + */ +export function getBit(x:bigint, i: number) { + const bit = (x >> BigInt(i)) & _1n; + return bit === _0n ? 0 : 1; +} + +/** + * Compute bit length + */ +export function bitLength(x: bigint) { + // -1n >> -1n is -1n + // 1n >> 1n is 0n + const target = x < _0n ? BigInt(-1) : _0n; + let bitlen = 1; + let tmp = x; + // eslint-disable-next-line no-cond-assign + while ((tmp >>= _1n) !== target) { + bitlen++; + } + return bitlen; +} + +/** + * Compute byte length + */ +export function byteLength(x: bigint) { + const target = x < _0n ? BigInt(-1) : _0n; + const _8n = BigInt(8); + let len = 1; + let tmp = x; + // eslint-disable-next-line no-cond-assign + while ((tmp >>= _8n) !== target) { + len++; + } + return len; +} + +/** + * Get Uint8Array representation of this number + * @param {String} endian - Endianess of output array (defaults to 'be') + * @param {Number} length - Of output array + * @returns {Uint8Array} + */ +export function bigIntToUint8Array(x: bigint, endian = 'be', length: number) { + // we get and parse the hex string (https://coolaj86.com/articles/convert-js-bigints-to-typedarrays/) + // this is faster than shift+mod iterations + let hex = x.toString(16); + if (hex.length % 2 === 1) { + hex = '0' + hex; + } + + const rawLength = hex.length / 2; + const bytes = new Uint8Array(length || rawLength); + // parse hex + const offset = length ? length - rawLength : 0; + let i = 0; + while (i < rawLength) { + bytes[i + offset] = parseInt(hex.slice(2 * i, 2 * i + 2), 16); + i++; + } + + if (endian !== 'be') { + bytes.reverse(); + } + + return bytes; +} diff --git a/src/crypto/pkcs1.js b/src/crypto/pkcs1.js index 229081e8..d888017d 100644 --- a/src/crypto/pkcs1.js +++ b/src/crypto/pkcs1.js @@ -132,7 +132,7 @@ export function emeDecode(encoded, randomPayload) { * @param {Integer} emLen - Intended length in octets of the encoded message * @returns {Uint8Array} Encoded message. */ -export async function emsaEncode(algo, hashed, emLen) { +export function emsaEncode(algo, hashed, emLen) { let i; if (hashed.length !== hash.getHashByteLength(algo)) { throw new Error('Invalid hash length'); diff --git a/src/crypto/public_key/dsa.js b/src/crypto/public_key/dsa.js index 80da4328..c01e3185 100644 --- a/src/crypto/public_key/dsa.js +++ b/src/crypto/public_key/dsa.js @@ -22,7 +22,7 @@ import { getRandomBigInteger } from '../random'; import util from '../../util'; import { isProbablePrime } from './prime'; -import BigInteger from '../../biginteger'; +import { bigIntToUint8Array, bitLength, byteLength, mod, modExp, modInv, uint8ArrayToBigInt } from '../biginteger'; /* TODO regarding the hash function, read: @@ -30,6 +30,9 @@ import BigInteger from '../../biginteger'; https://tools.ietf.org/html/rfc4880#section-14 */ +const _0n = BigInt(0); +const _1n = BigInt(1); + /** * DSA Sign function * @param {Integer} hashAlgo @@ -42,24 +45,24 @@ import BigInteger from '../../biginteger'; * @async */ export async function sign(hashAlgo, hashed, g, p, q, x) { - const one = new BigInteger(1); - p = new BigInteger(p); - q = new BigInteger(q); - g = new BigInteger(g); - x = new BigInteger(x); + const _0n = BigInt(0); + p = uint8ArrayToBigInt(p); + q = uint8ArrayToBigInt(q); + g = uint8ArrayToBigInt(g); + x = uint8ArrayToBigInt(x); let k; let r; let s; let t; - g = g.mod(p); - x = x.mod(q); + g = mod(g, p); + x = mod(x, q); // If the output size of the chosen hash is larger than the number of // bits of q, the hash result is truncated to fit by taking the number // of leftmost bits equal to the number of bits of q. This (possibly // truncated) hash function result is treated as a number and used // directly in the DSA signature algorithm. - const h = new BigInteger(hashed.subarray(0, q.byteLength())).mod(q); + const h = mod(uint8ArrayToBigInt(hashed.subarray(0, byteLength(q))), q); // FIPS-186-4, section 4.6: // The values of r and s shall be checked to determine if r = 0 or s = 0. // If either r = 0 or s = 0, a new value of k shall be generated, and the @@ -67,22 +70,22 @@ export async function sign(hashAlgo, hashed, g, p, q, x) { // or s = 0 if signatures are generated properly. while (true) { // See Appendix B here: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf - k = await getRandomBigInteger(one, q); // returns in [1, q-1] - r = g.modExp(k, p).imod(q); // (g**k mod p) mod q - if (r.isZero()) { + k = getRandomBigInteger(_1n, q); // returns in [1, q-1] + r = mod(modExp(g, k, p), q); // (g**k mod p) mod q + if (r === _0n) { continue; } - const xr = x.mul(r).imod(q); - t = h.add(xr).imod(q); // H(m) + x*r mod q - s = k.modInv(q).imul(t).imod(q); // k**-1 * (H(m) + x*r) mod q - if (s.isZero()) { + const xr = mod(x * r, q); + t = mod(h + xr, q); // H(m) + x*r mod q + s = mod(modInv(k, q) * t, q); // k**-1 * (H(m) + x*r) mod q + if (s === _0n) { continue; } break; } return { - r: r.toUint8Array('be', q.byteLength()), - s: s.toUint8Array('be', q.byteLength()) + r: bigIntToUint8Array(r, 'be', byteLength(p)), + s: bigIntToUint8Array(s, 'be', byteLength(p)) }; } @@ -100,35 +103,34 @@ export async function sign(hashAlgo, hashed, g, p, q, x) { * @async */ export async function verify(hashAlgo, r, s, hashed, g, p, q, y) { - const zero = new BigInteger(0); - r = new BigInteger(r); - s = new BigInteger(s); + r = uint8ArrayToBigInt(r); + s = uint8ArrayToBigInt(s); - p = new BigInteger(p); - q = new BigInteger(q); - g = new BigInteger(g); - y = new BigInteger(y); + p = uint8ArrayToBigInt(p); + q = uint8ArrayToBigInt(q); + g = uint8ArrayToBigInt(g); + y = uint8ArrayToBigInt(y); - if (r.lte(zero) || r.gte(q) || - s.lte(zero) || s.gte(q)) { + if (r <= _0n || r >= q || + s <= _0n || s >= q) { util.printDebug('invalid DSA Signature'); return false; } - const h = new BigInteger(hashed.subarray(0, q.byteLength())).imod(q); - const w = s.modInv(q); // s**-1 mod q - if (w.isZero()) { + const h = mod(uint8ArrayToBigInt(hashed.subarray(0, byteLength(q))), q); + const w = modInv(s, q); // s**-1 mod q + if (w === _0n) { util.printDebug('invalid DSA Signature'); return false; } - g = g.mod(p); - y = y.mod(p); - const u1 = h.mul(w).imod(q); // H(m) * w mod q - const u2 = r.mul(w).imod(q); // r * w mod q - const t1 = g.modExp(u1, p); // g**u1 mod p - const t2 = y.modExp(u2, p); // y**u2 mod p - const v = t1.mul(t2).imod(p).imod(q); // (g**u1 * y**u2 mod p) mod q - return v.equal(r); + g = mod(g, p); + y = mod(y, p); + const u1 = mod(h * w, q); // H(m) * w mod q + const u2 = mod(r * w, q); // r * w mod q + const t1 = modExp(g, u1, p); // g**u1 mod p + const t2 = modExp(y, u2, p); // y**u2 mod p + const v = mod(mod(t1 * t2, p), q); // (g**u1 * y**u2 mod p) mod q + return v === r; } /** @@ -142,20 +144,19 @@ export async function verify(hashAlgo, r, s, hashed, g, p, q, y) { * @async */ export async function validateParams(p, q, g, y, x) { - p = new BigInteger(p); - q = new BigInteger(q); - g = new BigInteger(g); - y = new BigInteger(y); - const one = new BigInteger(1); + p = uint8ArrayToBigInt(p); + q = uint8ArrayToBigInt(q); + g = uint8ArrayToBigInt(g); + y = uint8ArrayToBigInt(y); // Check that 1 < g < p - if (g.lte(one) || g.gte(p)) { + if (g <= _1n || g >= p) { return false; } /** * Check that subgroup order q divides p-1 */ - if (!p.dec().mod(q).isZero()) { + if (mod(p - _1n, q) !== _0n) { return false; } @@ -163,16 +164,16 @@ export async function validateParams(p, q, g, y, x) { * g has order q * Check that g ** q = 1 mod p */ - if (!g.modExp(q, p).isOne()) { + if (modExp(g, q, p) !== _1n) { return false; } /** * Check q is large and probably prime (we mainly want to avoid small factors) */ - const qSize = new BigInteger(q.bitLength()); - const n150 = new BigInteger(150); - if (qSize.lt(n150) || !(await isProbablePrime(q, null, 32))) { + const qSize = BigInt(bitLength(q)); + const _150n = BigInt(150); + if (qSize < _150n || !isProbablePrime(q, null, 32)) { return false; } @@ -182,11 +183,11 @@ export async function validateParams(p, q, g, y, x) { * * Blinded exponentiation computes g**{rq + x} to compare to y */ - x = new BigInteger(x); - const two = new BigInteger(2); - const r = await getRandomBigInteger(two.leftShift(qSize.dec()), two.leftShift(qSize)); // draw r of same size as q - const rqx = q.mul(r).add(x); - if (!y.equal(g.modExp(rqx, p))) { + x = uint8ArrayToBigInt(x); + const _2n = BigInt(2); + const r = getRandomBigInteger(_2n << (qSize - _1n), _2n << qSize); // draw r of same size as q + const rqx = q * r + x; + if (y !== modExp(g, rqx, p)) { return false; } diff --git a/src/crypto/public_key/elgamal.js b/src/crypto/public_key/elgamal.js index a64b9681..6bd4641e 100644 --- a/src/crypto/public_key/elgamal.js +++ b/src/crypto/public_key/elgamal.js @@ -21,7 +21,9 @@ */ import { getRandomBigInteger } from '../random'; import { emeEncode, emeDecode } from '../pkcs1'; -import BigInteger from '../../biginteger'; +import { bigIntToUint8Array, bitLength, byteLength, mod, modExp, modInv, uint8ArrayToBigInt } from '../biginteger'; + +const _1n = BigInt(1); /** * ElGamal Encryption function @@ -34,19 +36,19 @@ import BigInteger from '../../biginteger'; * @async */ export async function encrypt(data, p, g, y) { - p = new BigInteger(p); - g = new BigInteger(g); - y = new BigInteger(y); + p = uint8ArrayToBigInt(p); + g = uint8ArrayToBigInt(g); + y = uint8ArrayToBigInt(y); - const padded = emeEncode(data, p.byteLength()); - const m = new BigInteger(padded); + const padded = emeEncode(data, byteLength(p)); + const m = uint8ArrayToBigInt(padded); // OpenPGP uses a "special" version of ElGamal where g is generator of the full group Z/pZ* // hence g has order p-1, and to avoid that k = 0 mod p-1, we need to pick k in [1, p-2] - const k = await getRandomBigInteger(new BigInteger(1), p.dec()); + const k = getRandomBigInteger(_1n, p - _1n); return { - c1: g.modExp(k, p).toUint8Array(), - c2: y.modExp(k, p).imul(m).imod(p).toUint8Array() + c1: bigIntToUint8Array(modExp(g, k, p)), + c2: bigIntToUint8Array(mod(modExp(y, k, p) * m, p)) }; } @@ -63,13 +65,13 @@ export async function encrypt(data, p, g, y) { * @async */ export async function decrypt(c1, c2, p, x, randomPayload) { - c1 = new BigInteger(c1); - c2 = new BigInteger(c2); - p = new BigInteger(p); - x = new BigInteger(x); + c1 = uint8ArrayToBigInt(c1); + c2 = uint8ArrayToBigInt(c2); + p = uint8ArrayToBigInt(p); + x = uint8ArrayToBigInt(x); - const padded = c1.modExp(x, p).modInv(p).imul(c2).imod(p); - return emeDecode(padded.toUint8Array('be', p.byteLength()), randomPayload); + const padded = mod(modInv(modExp(c1, x, p), p) * c2, p); + return emeDecode(bigIntToUint8Array(padded, 'be', byteLength(p)), randomPayload); } /** @@ -82,20 +84,19 @@ export async function decrypt(c1, c2, p, x, randomPayload) { * @async */ export async function validateParams(p, g, y, x) { - p = new BigInteger(p); - g = new BigInteger(g); - y = new BigInteger(y); + p = uint8ArrayToBigInt(p); + g = uint8ArrayToBigInt(g); + y = uint8ArrayToBigInt(y); - const one = new BigInteger(1); // Check that 1 < g < p - if (g.lte(one) || g.gte(p)) { + if (g <= _1n || g >= p) { return false; } // Expect p-1 to be large - const pSize = new BigInteger(p.bitLength()); - const n1023 = new BigInteger(1023); - if (pSize.lt(n1023)) { + const pSize = BigInt(bitLength(p)); + const _1023n = BigInt(1023); + if (pSize < _1023n) { return false; } @@ -103,7 +104,7 @@ export async function validateParams(p, g, y, x) { * g should have order p-1 * Check that g ** (p-1) = 1 mod p */ - if (!g.modExp(p.dec(), p).isOne()) { + if (modExp(g, p - _1n, p) !== _1n) { return false; } @@ -114,14 +115,15 @@ export async function validateParams(p, g, y, x) { * We just check g**i != 1 for all i up to a threshold */ let res = g; - const i = new BigInteger(1); - const threshold = new BigInteger(2).leftShift(new BigInteger(17)); // we want order > threshold - while (i.lt(threshold)) { - res = res.mul(g).imod(p); - if (res.isOne()) { + let i = BigInt(1); + const _2n = BigInt(2); + const threshold = _2n << BigInt(17); // we want order > threshold + while (i < threshold) { + res = mod(res * g, p); + if (res === _1n) { return false; } - i.iinc(); + i++; } /** @@ -130,11 +132,10 @@ export async function validateParams(p, g, y, x) { * * Blinded exponentiation computes g**{r(p-1) + x} to compare to y */ - x = new BigInteger(x); - const two = new BigInteger(2); - const r = await getRandomBigInteger(two.leftShift(pSize.dec()), two.leftShift(pSize)); // draw r of same size as p-1 - const rqx = p.dec().imul(r).iadd(x); - if (!y.equal(g.modExp(rqx, p))) { + x = uint8ArrayToBigInt(x); + const r = getRandomBigInteger(_2n << (pSize - _1n), _2n << pSize); // draw r of same size as p-1 + const rqx = (p - _1n) * r + x; + if (y !== modExp(g, rqx, p)) { return false; } diff --git a/src/crypto/public_key/elliptic/ecdsa.js b/src/crypto/public_key/elliptic/ecdsa.js index b7db3a85..76fe73d1 100644 --- a/src/crypto/public_key/elliptic/ecdsa.js +++ b/src/crypto/public_key/elliptic/ecdsa.js @@ -25,7 +25,7 @@ import util from '../../../util'; import { getRandomBytes } from '../../random'; import hash from '../../hash'; import { CurveWithOID, webCurves, privateToJWK, rawPublicToJWK, validateStandardParams, nodeCurves } from './oid_curves'; -import BigInteger from '../../../biginteger'; +import { bigIntToUint8Array } from '../../biginteger'; const webCrypto = util.getWebCrypto(); const nodeCrypto = util.getNodeCrypto(); @@ -73,8 +73,8 @@ export async function sign(oid, hashAlgo, message, publicKey, privateKey, hashed // lowS: non-canonical sig: https://stackoverflow.com/questions/74338846/ecdsa-signature-verification-mismatch const signature = nobleCurve.sign(hashed, privateKey, { lowS: false }); return { - r: new BigInteger(signature.r).toUint8Array('be', curve.payloadSize), - s: new BigInteger(signature.s).toUint8Array('be', curve.payloadSize) + r: bigIntToUint8Array(signature.r, 'be', curve.payloadSize), + s: bigIntToUint8Array(signature.s, 'be', curve.payloadSize) }; } diff --git a/src/crypto/public_key/prime.js b/src/crypto/public_key/prime.ts similarity index 79% rename from src/crypto/public_key/prime.js rename to src/crypto/public_key/prime.ts index 854f02ba..b892d666 100644 --- a/src/crypto/public_key/prime.js +++ b/src/crypto/public_key/prime.ts @@ -19,21 +19,20 @@ * @fileoverview Algorithms for probabilistic random prime generation * @module crypto/public_key/prime */ -import BigInteger from '../../biginteger'; +import { bigIntToNumber, bitLength, gcd, getBit, mod, modExp } from '../biginteger'; import { getRandomBigInteger } from '../random'; +const _1n = BigInt(1); + /** * Generate a probably prime random number - * @param {Integer} bits - Bit length of the prime - * @param {BigInteger} e - Optional RSA exponent to check against the prime - * @param {Integer} k - Optional number of iterations of Miller-Rabin test - * @returns BigInteger - * @async + * @param bits - Bit length of the prime + * @param e - Optional RSA exponent to check against the prime + * @param k - Optional number of iterations of Miller-Rabin test */ -export async function randomProbablePrime(bits, e, k) { - const one = new BigInteger(1); - const min = one.leftShift(new BigInteger(bits - 1)); - const thirty = new BigInteger(30); +export function randomProbablePrime(bits: number, e: bigint, k: number) { + const _30n = BigInt(30); + const min = _1n << BigInt(bits - 1); /* * We can avoid any multiples of 3 and 5 by looking at n mod 30 * n mod 30 = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 @@ -42,40 +41,38 @@ export async function randomProbablePrime(bits, e, k) { */ const adds = [1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2]; - const n = await getRandomBigInteger(min, min.leftShift(one)); - let i = n.mod(thirty).toNumber(); + let n = getRandomBigInteger(min, min << _1n); + let i = bigIntToNumber(mod(n, _30n)); do { - n.iadd(new BigInteger(adds[i])); + n += BigInt(adds[i]); i = (i + adds[i]) % adds.length; // If reached the maximum, go back to the minimum. - if (n.bitLength() > bits) { - n.imod(min.leftShift(one)).iadd(min); - i = n.mod(thirty).toNumber(); + if (bitLength(n) > bits) { + n = mod(n, min << _1n); n += min; + i = bigIntToNumber(mod(n, _30n)); } - } while (!await isProbablePrime(n, e, k)); + } while (!isProbablePrime(n, e, k)); return n; } /** * Probabilistic primality testing - * @param {BigInteger} n - Number to test - * @param {BigInteger} e - Optional RSA exponent to check against the prime - * @param {Integer} k - Optional number of iterations of Miller-Rabin test - * @returns {boolean} - * @async + * @param n - Number to test + * @param e - Optional RSA exponent to check against the prime + * @param k - Optional number of iterations of Miller-Rabin test */ -export async function isProbablePrime(n, e, k) { - if (e && !n.dec().gcd(e).isOne()) { +export function isProbablePrime(n: bigint, e: bigint, k: number) { + if (e && gcd(n - _1n, e) !== _1n) { return false; } - if (!await divisionTest(n)) { + if (!divisionTest(n)) { return false; } - if (!await fermat(n)) { + if (!fermat(n)) { return false; } - if (!await millerRabin(n, k)) { + if (!millerRabin(n, k)) { return false; } // TODO implement the Lucas test @@ -86,19 +83,16 @@ export async function isProbablePrime(n, e, k) { /** * Tests whether n is probably prime or not using Fermat's test with b = 2. * Fails if b^(n-1) mod n != 1. - * @param {BigInteger} n - Number to test - * @param {BigInteger} b - Optional Fermat test base - * @returns {boolean} + * @param n - Number to test + * @param b - Optional Fermat test base */ -export async function fermat(n, b) { - b = b || new BigInteger(2); - return b.modExp(n.dec(), n).isOne(); +export function fermat(n: bigint, b = BigInt(2)) { + return modExp(b, n - _1n, n) === _1n; } -export async function divisionTest(n) { - return smallPrimes.every(m => { - return n.mod(new BigInteger(m)) !== 0; - }); +export function divisionTest(n: bigint) { + const _0n = BigInt(0); + return smallPrimes.every(m => mod(n, m) !== _0n); } // https://github.com/gpg/libgcrypt/blob/master/cipher/primegen.c @@ -182,7 +176,7 @@ const smallPrimes = [ 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999 -]; +].map(n => BigInt(n)); // Miller-Rabin - Miller Rabin algorithm for primality test @@ -217,42 +211,42 @@ const smallPrimes = [ /** * Tests whether n is probably prime or not using the Miller-Rabin test. * See HAC Remark 4.28. - * @param {BigInteger} n - Number to test - * @param {Integer} k - Optional number of iterations of Miller-Rabin test - * @param {Function} rand - Optional function to generate potential witnesses + * @param n - Number to test + * @param k - Optional number of iterations of Miller-Rabin test + * @param rand - Optional function to generate potential witnesses * @returns {boolean} * @async */ -export async function millerRabin(n, k, rand) { - const len = n.bitLength(); +export function millerRabin(n: bigint, k: number, rand?: () => bigint) { + const len = bitLength(n); if (!k) { k = Math.max(1, (len / 48) | 0); } - const n1 = n.dec(); // n - 1 + const n1 = n - _1n; // n - 1 // Find d and s, (n - 1) = (2 ^ s) * d; let s = 0; - while (!n1.getBit(s)) { s++; } - const d = n.rightShift(new BigInteger(s)); + while (!getBit(n1, s)) { s++; } + const d = n >> BigInt(s); for (; k > 0; k--) { - const a = rand ? rand() : await getRandomBigInteger(new BigInteger(2), n1); + const a = rand ? rand() : getRandomBigInteger(BigInt(2), n1); - let x = a.modExp(d, n); - if (x.isOne() || x.equal(n1)) { + let x = modExp(a, d, n); + if (x === _1n || x === n1) { continue; } let i; for (i = 1; i < s; i++) { - x = x.mul(x).mod(n); + x = mod(x * x, n); - if (x.isOne()) { + if (x === _1n) { return false; } - if (x.equal(n1)) { + if (x === n1) { break; } } diff --git a/src/crypto/public_key/rsa.js b/src/crypto/public_key/rsa.js index e8c3adff..5c6027ca 100644 --- a/src/crypto/public_key/rsa.js +++ b/src/crypto/public_key/rsa.js @@ -25,10 +25,11 @@ import util from '../../util'; import { uint8ArrayToB64, b64ToUint8Array } from '../../encoding/base64'; import { emsaEncode, emeEncode, emeDecode } from '../pkcs1'; import enums from '../../enums'; -import BigInteger from '../../biginteger'; +import { bigIntToNumber, bigIntToUint8Array, bitLength, byteLength, mod, modExp, modInv, uint8ArrayToBigInt } from '../biginteger'; const webCrypto = util.getWebCrypto(); const nodeCrypto = util.getNodeCrypto(); +const _1n = BigInt(1); /** Create signature * @param {module:enums.hash} hashAlgo - Hash algorithm @@ -142,14 +143,14 @@ export async function decrypt(data, n, e, d, p, q, u, randomPayload) { * @async */ export async function generate(bits, e) { - e = new BigInteger(e); + e = BigInt(e); // Native RSA keygen using Web Crypto if (util.getWebCrypto()) { const keyGenOpt = { name: 'RSASSA-PKCS1-v1_5', modulusLength: bits, // the specified keysize in bits - publicExponent: e.toUint8Array(), // take three bytes (max 65537) for exponent + publicExponent: bigIntToUint8Array(e), // take three bytes (max 65537) for exponent hash: { name: 'SHA-1' // not required for actual RSA keys, but for crypto api 'sign' and 'verify' } @@ -164,7 +165,7 @@ export async function generate(bits, e) { } else if (util.getNodeCrypto()) { const opts = { modulusLength: bits, - publicExponent: e.toNumber(), + publicExponent: bigIntToNumber(e), publicKeyEncoding: { type: 'pkcs1', format: 'jwk' }, privateKeyEncoding: { type: 'pkcs1', format: 'jwk' } }; @@ -187,26 +188,26 @@ export async function generate(bits, e) { let q; let n; do { - q = await randomProbablePrime(bits - (bits >> 1), e, 40); - p = await randomProbablePrime(bits >> 1, e, 40); - n = p.mul(q); - } while (n.bitLength() !== bits); + q = randomProbablePrime(bits - (bits >> 1), e, 40); + p = randomProbablePrime(bits >> 1, e, 40); + n = p * q; + } while (bitLength(n) !== bits); - const phi = p.dec().imul(q.dec()); + const phi = (p - _1n) * (q - _1n); - if (q.lt(p)) { + if (q < p) { [p, q] = [q, p]; } return { - n: n.toUint8Array(), - e: e.toUint8Array(), - d: e.modInv(phi).toUint8Array(), - p: p.toUint8Array(), - q: q.toUint8Array(), + n: bigIntToUint8Array(n), + e: bigIntToUint8Array(e), + d: bigIntToUint8Array(modInv(e, phi)), + p: bigIntToUint8Array(p), + q: bigIntToUint8Array(q), // dp: d.mod(p.subn(1)), // dq: d.mod(q.subn(1)), - u: p.modInv(q).toUint8Array() + u: bigIntToUint8Array(modInv(p, q)) }; } @@ -222,24 +223,24 @@ export async function generate(bits, e) { * @async */ export async function validateParams(n, e, d, p, q, u) { - n = new BigInteger(n); - p = new BigInteger(p); - q = new BigInteger(q); + n = uint8ArrayToBigInt(n); + p = uint8ArrayToBigInt(p); + q = uint8ArrayToBigInt(q); // expect pq = n - if (!p.mul(q).equal(n)) { + if ((p * q) !== n) { return false; } - const two = new BigInteger(2); + const _2n = BigInt(2); // expect p*u = 1 mod q - u = new BigInteger(u); - if (!p.mul(u).mod(q).isOne()) { + u = uint8ArrayToBigInt(u); + if (mod(p * u, q) !== BigInt(1)) { return false; } - e = new BigInteger(e); - d = new BigInteger(d); + e = uint8ArrayToBigInt(e); + d = uint8ArrayToBigInt(d); /** * In RSA pkcs#1 the exponents (d, e) are inverses modulo lcm(p-1, q-1) * We check that [de = 1 mod (p-1)] and [de = 1 mod (q-1)] @@ -247,11 +248,11 @@ export async function validateParams(n, e, d, p, q, u) { * * We blind the multiplication with r, and check that rde = r mod lcm(p-1, q-1) */ - const nSizeOver3 = new BigInteger(Math.floor(n.bitLength() / 3)); - const r = await getRandomBigInteger(two, two.leftShift(nSizeOver3)); // r in [ 2, 2^{|n|/3} ) < p and q - const rde = r.mul(d).mul(e); + const nSizeOver3 = BigInt(Math.floor(bitLength(n) / 3)); + const r = getRandomBigInteger(_2n, _2n << nSizeOver3); // r in [ 2, 2^{|n|/3} ) < p and q + const rde = r * d * e; - const areInverses = rde.mod(p.dec()).equal(r) && rde.mod(q.dec()).equal(r); + const areInverses = mod(rde, p - _1n) === r && mod(rde, q - _1n) === r; if (!areInverses) { return false; } @@ -260,13 +261,13 @@ export async function validateParams(n, e, d, p, q, u) { } async function bnSign(hashAlgo, n, d, hashed) { - n = new BigInteger(n); - const m = new BigInteger(await emsaEncode(hashAlgo, hashed, n.byteLength())); - d = new BigInteger(d); - if (m.gte(n)) { + n = uint8ArrayToBigInt(n); + const m = uint8ArrayToBigInt(emsaEncode(hashAlgo, hashed, byteLength(n))); + d = uint8ArrayToBigInt(d); + if (m >= n) { throw new Error('Message size cannot exceed modulus size'); } - return m.modExp(d, n).toUint8Array('be', n.byteLength()); + return bigIntToUint8Array(modExp(m, d, n), 'be', byteLength(n)); } async function webSign(hashName, data, n, e, d, p, q, u) { @@ -296,14 +297,14 @@ async function nodeSign(hashAlgo, data, n, e, d, p, q, u) { } async function bnVerify(hashAlgo, s, n, e, hashed) { - n = new BigInteger(n); - s = new BigInteger(s); - e = new BigInteger(e); - if (s.gte(n)) { + n = uint8ArrayToBigInt(n); + s = uint8ArrayToBigInt(s); + e = uint8ArrayToBigInt(e); + if (s >= n) { throw new Error('Signature size cannot exceed modulus size'); } - const EM1 = s.modExp(e, n).toUint8Array('be', n.byteLength()); - const EM2 = await emsaEncode(hashAlgo, hashed, n.byteLength()); + const EM1 = bigIntToUint8Array(modExp(s, e, n), 'be', byteLength(n)); + const EM2 = emsaEncode(hashAlgo, hashed, byteLength(n)); return util.equalsUint8Array(EM1, EM2); } @@ -339,13 +340,13 @@ async function nodeEncrypt(data, n, e) { } async function bnEncrypt(data, n, e) { - n = new BigInteger(n); - data = new BigInteger(emeEncode(data, n.byteLength())); - e = new BigInteger(e); - if (data.gte(n)) { + n = uint8ArrayToBigInt(n); + data = uint8ArrayToBigInt(emeEncode(data, byteLength(n))); + e = uint8ArrayToBigInt(e); + if (data >= n) { throw new Error('Message size cannot exceed modulus size'); } - return data.modExp(e, n).toUint8Array('be', n.byteLength()); + return bigIntToUint8Array(modExp(data, e, n), 'be', byteLength(n)); } async function nodeDecrypt(data, n, e, d, p, q, u) { @@ -360,34 +361,32 @@ async function nodeDecrypt(data, n, e, d, p, q, u) { } async function bnDecrypt(data, n, e, d, p, q, u, randomPayload) { - data = new BigInteger(data); - n = new BigInteger(n); - e = new BigInteger(e); - d = new BigInteger(d); - p = new BigInteger(p); - q = new BigInteger(q); - u = new BigInteger(u); - if (data.gte(n)) { + data = uint8ArrayToBigInt(data); + n = uint8ArrayToBigInt(n); + e = uint8ArrayToBigInt(e); + d = uint8ArrayToBigInt(d); + p = uint8ArrayToBigInt(p); + q = uint8ArrayToBigInt(q); + u = uint8ArrayToBigInt(u); + if (data >= n) { throw new Error('Data too large.'); } - const dq = d.mod(q.dec()); // d mod (q-1) - const dp = d.mod(p.dec()); // d mod (p-1) + const dq = mod(d, q - _1n); // d mod (q-1) + const dp = mod(d, p - _1n); // d mod (p-1) - const unblinder = (await getRandomBigInteger(new BigInteger(2), n)).mod(n); - const blinder = unblinder.modInv(n).modExp(e, n); - data = data.mul(blinder).mod(n); + const unblinder = getRandomBigInteger(BigInt(2), n); + const blinder = modExp(modInv(unblinder, n), e, n); + data = mod(data * blinder, n); + const mp = modExp(data, dp, p); // data**{d mod (q-1)} mod p + const mq = modExp(data, dq, q); // data**{d mod (p-1)} mod q + const h = mod(u * (mq - mp), q); // u * (mq-mp) mod q (operands already < q) - const mp = data.modExp(dp, p); // data**{d mod (q-1)} mod p - const mq = data.modExp(dq, q); // data**{d mod (p-1)} mod q - const h = u.mul(mq.sub(mp)).mod(q); // u * (mq-mp) mod q (operands already < q) + let result = h * p + mp; // result < n due to relations above - let result = h.mul(p).add(mp); // result < n due to relations above + result = mod(result * unblinder, n); - result = result.mul(unblinder).mod(n); - - - return emeDecode(result.toUint8Array('be', n.byteLength()), randomPayload); + return emeDecode(bigIntToUint8Array(result, 'be', byteLength(n)), randomPayload); } /** Convert Openpgp private key params to jwk key according to @@ -401,14 +400,14 @@ async function bnDecrypt(data, n, e, d, p, q, u, randomPayload) { * @param {Uint8Array} u */ async function privateToJWK(n, e, d, p, q, u) { - const pNum = new BigInteger(p); - const qNum = new BigInteger(q); - const dNum = new BigInteger(d); + const pNum = uint8ArrayToBigInt(p); + const qNum = uint8ArrayToBigInt(q); + const dNum = uint8ArrayToBigInt(d); - let dq = dNum.mod(qNum.dec()); // d mod (q-1) - let dp = dNum.mod(pNum.dec()); // d mod (p-1) - dp = dp.toUint8Array(); - dq = dq.toUint8Array(); + let dq = mod(dNum, qNum - _1n); // d mod (q-1) + let dp = mod(dNum, pNum - _1n); // d mod (p-1) + dp = bigIntToUint8Array(dp); + dq = bigIntToUint8Array(dq); return { kty: 'RSA', n: uint8ArrayToB64(n, true), @@ -444,7 +443,7 @@ function publicToJWK(n, e) { function jwkToPrivate(jwk, e) { return { n: b64ToUint8Array(jwk.n), - e: e.toUint8Array(), + e: bigIntToUint8Array(e), d: b64ToUint8Array(jwk.d), // switch p and q p: b64ToUint8Array(jwk.q), diff --git a/src/crypto/random.js b/src/crypto/random.js index 4b038587..c7e53169 100644 --- a/src/crypto/random.js +++ b/src/crypto/random.js @@ -21,7 +21,7 @@ * @fileoverview Provides tools for retrieving secure randomness from browsers or Node.js * @module crypto/random */ -import BigInteger from '../biginteger'; +import { byteLength, mod, uint8ArrayToBigInt } from './biginteger'; import util from '../util'; const nodeCrypto = util.getNodeCrypto(); @@ -45,23 +45,23 @@ export function getRandomBytes(length) { } /** - * Create a secure random BigInteger that is greater than or equal to min and less than max. - * @param {module:BigInteger} min - Lower bound, included - * @param {module:BigInteger} max - Upper bound, excluded - * @returns {Promise} Random BigInteger. + * Create a secure random BigInt that is greater than or equal to min and less than max. + * @param {bigint} min - Lower bound, included + * @param {bigint} max - Upper bound, excluded + * @returns {bigint} Random BigInt. * @async */ -export async function getRandomBigInteger(min, max) { - if (max.lt(min)) { +export function getRandomBigInteger(min, max) { + if (max < min) { throw new Error('Illegal parameter value: max <= min'); } - const modulus = max.sub(min); - const bytes = modulus.byteLength(); + const modulus = max - min; + const bytes = byteLength(modulus); // Using a while loop is necessary to avoid bias introduced by the mod operation. // However, we request 64 extra random bits so that the bias is negligible. // Section B.1.1 here: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf - const r = new BigInteger(getRandomBytes(bytes + 8)); - return r.mod(modulus).add(min); + const r = uint8ArrayToBigInt(getRandomBytes(bytes + 8)); + return mod(r, modulus) + min; } diff --git a/test/crypto/biginteger.js b/test/crypto/biginteger.js new file mode 100644 index 00000000..aeabd943 --- /dev/null +++ b/test/crypto/biginteger.js @@ -0,0 +1,96 @@ +import { expect } from 'chai'; + +import BN from 'bn.js'; +import { bigIntToUint8Array, bitLength, byteLength, gcd, getBit, modExp, modInv } from '../../src/crypto/biginteger'; +import { getRandomBytes } from '../../src/crypto/random'; + +async function getRandomBN(min, max) { + if (max.cmp(min) <= 0) { + throw new Error('Illegal parameter value: max <= min'); + } + + const modulus = max.sub(min); + const bytes = modulus.byteLength(); + const r = new BN(getRandomBytes(bytes + 8)); + return r.mod(modulus).add(min); +} + + +export default () => describe('BigInt', () => { + it('bitLength is correct', function() { + const n = BigInt(127); + const expected = 7; + expect(bitLength(n)).to.equal(expected); + expect(bitLength(n + BigInt(1))).to.equal(expected + 1); + }); + + it('byteLength is correct', function() { + const n = BigInt(65535); + const expected = 2; + expect(byteLength(n)).to.equal(expected); + expect(byteLength(n + BigInt(1))).to.equal(expected + 1); + }); + + it('toUint8Array is correct', function() { + const nString = '417653931840771530406225971293556769925351769207235721650257629558293828796031115397206059067934284452829611906818956352854418342467914729341523414945427019410284762464062112274326172407819051167058569790660930309496043254270888417520676082271432948852231332576271876251597199882908964994070268531832274431027'; + const n = BigInt(nString); + const paddedSize = Number(byteLength(n)) + 1; + // big endian, unpadded + let expected = new BN(nString).toArrayLike(Uint8Array); + expect(bigIntToUint8Array(n)).to.deep.equal(expected); + // big endian, padded + expected = new BN(nString).toArrayLike(Uint8Array, 'be', paddedSize); + expect(bigIntToUint8Array(n, 'be', paddedSize)).to.deep.equal(expected); + // little endian, unpadded + expected = new BN(nString).toArrayLike(Uint8Array, 'le'); + expect(bigIntToUint8Array(n, 'le')).to.deep.equal(expected); + //little endian, padded + expected = new BN(nString).toArrayLike(Uint8Array, 'le', paddedSize); + expect(bigIntToUint8Array(n, 'le', paddedSize)).to.deep.equal(expected); + }); + + it('modExp is correct (large values)', function() { + const stringX = '417653931840771530406225971293556769925351769207235721650257629558293828796031115397206059067934284452829611906818956352854418342467914729341523414945427019410284762464062112274326172407819051167058569790660930309496043254270888417520676082271432948852231332576271876251597199882908964994070268531832274431027'; + const stringE = '21139356010872569239159922781526379521587348169074209285187910481667533072168468011617194695181255483288792585413365359733692097084373249198758148704369207793873998901870577262254971784191473102265830193058813215898765238784670469696574407580179153118937858890572095234316482449291777882525949871374961971753'; + const stringN = '129189808515414783602892982235788912674846062846614219472827821758734760420002631653235573915244294540972376140705505703576175711417114803419704967903726436285518767606681184247119430411311152556442947708732584954518890222684529678365388350886907287414896703685680210648760841628375425909680236584021041565183'; + const x = BigInt(stringX); + const e = BigInt(stringE); + const n = BigInt(stringN); + + const got = modExp(x, e, n); + const expected = new BN(stringX).toRed(BN.red(new BN(stringN))).redPow(new BN(stringE)); + // different formats, it's easier to compare strings + expect(got.toString(), expected.toString()); + }); + + it('gcd is correct', async function() { + const aBN = await getRandomBN(new BN(2), new BN(200)); + const bBN = await getRandomBN(new BN(2), new BN(200)); + if (aBN.isEven()) aBN.iaddn(1); + const a = BigInt(aBN.toString()); + const b = BigInt(bBN.toString()); + const expected = aBN.gcd(bBN); + expect(gcd(a, b).toString()).to.equal(expected.toString()); + }); + + it('modular inversion is correct', async function() { + const moduloBN = new BN(229); // this is a prime + const baseBN = await getRandomBN(new BN(2), moduloBN); + const a = BigInt(baseBN.toString()); + const n = BigInt(moduloBN.toString()); + const expected = baseBN.invm(moduloBN); + expect(modInv(a, n).toString()).to.equal(expected.toString()); + // test negative operand + const expectedNegated = baseBN.neg().invm(moduloBN); + expect(modInv(-a, n).toString()).to.equal(expectedNegated.toString()); + expect(() => modInv(a * n, n)).to.throw(/Inverse does not exist/); + }); + + it('getBit is correct', async function() { + const i = 5; + const nBN = await getRandomBN(new BN(2), new BN(200)); + const n = BigInt(nBN.toString()); + const expected = nBN.testn(5) ? 1 : 0; + expect(getBit(n, i)).to.equal(expected); + }); +}); diff --git a/test/crypto/index.js b/test/crypto/index.js index 86f45445..a4c73ae5 100644 --- a/test/crypto/index.js +++ b/test/crypto/index.js @@ -1,3 +1,4 @@ +import testBigInteger from './biginteger'; import testCipher from './cipher'; import testHash from './hash'; import testCrypto from './crypto'; @@ -14,6 +15,7 @@ import testRSA from './rsa'; import testValidate from './validate'; export default () => describe('Crypto', function () { + testBigInteger(); testCipher(); testHash(); testCrypto(); diff --git a/test/crypto/validate.js b/test/crypto/validate.js index 3731ea9e..8ed63089 100644 --- a/test/crypto/validate.js +++ b/test/crypto/validate.js @@ -3,7 +3,7 @@ import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/new chaiUse(chaiAsPromised); import openpgp from '../initOpenpgp.js'; -import BigInteger from '../../src/biginteger.ts'; +import { bigIntToUint8Array, modExp, uint8ArrayToBigInt } from '../../src/crypto/biginteger.ts'; const armoredDSAKey = `-----BEGIN PGP PRIVATE KEY BLOCK----- @@ -390,11 +390,12 @@ export default () => { const keyPacket = await cloneKeyPacket(egKey); const { p, g } = keyPacket.publicParams; - const pBN = new BigInteger(p); - const gBN = new BigInteger(g); + const _1n = BigInt(1); + const pBN = uint8ArrayToBigInt(p); + const gBN = uint8ArrayToBigInt(g); // g**(p-1)/2 has order 2 - const gOrd2 = gBN.modExp(pBN.dec().irightShift(new BigInteger(1)), pBN); - keyPacket.publicParams.g = gOrd2.toUint8Array(); + const gOrd2 = modExp(gBN, (pBN - _1n) >> _1n, pBN); + keyPacket.publicParams.g = bigIntToUint8Array(gOrd2); await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid'); }); }); diff --git a/tsconfig.json b/tsconfig.json index 6471d348..1b8fdcb0 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,6 +7,6 @@ "allowJs": true, "paths": { "openpgp": [ "." ] - }, + }, } } From ad7165dfd0816dc57a9bd9ad8c258efe13dd2334 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Tue, 14 May 2024 13:20:58 +0200 Subject: [PATCH 135/201] `readPrivateKeys`: support parsing key block with mix of private and public keys Previously, parsing a key block where a public key followed a private one would fail. --- src/key/factory.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/key/factory.js b/src/key/factory.js index 37ee2a77..36e39a46 100644 --- a/src/key/factory.js +++ b/src/key/factory.js @@ -456,14 +456,17 @@ export async function readPrivateKeys({ armoredKeys, binaryKeys, config }) { } const keys = []; const packetlist = await PacketList.fromBinary(input, allowedKeyPackets, config); - const keyIndex = packetlist.indexOfTag(enums.packet.secretKey); - if (keyIndex.length === 0) { - throw new Error('No secret key packet found'); - } + const keyIndex = packetlist.indexOfTag(enums.packet.publicKey, enums.packet.secretKey); for (let i = 0; i < keyIndex.length; i++) { + if (packetlist[keyIndex[i]].constructor.tag === enums.packet.publicKey) { + continue; + } const oneKeyList = packetlist.slice(keyIndex[i], keyIndex[i + 1]); const newKey = new PrivateKey(oneKeyList); keys.push(newKey); } + if (keys.length === 0) { + throw new Error('No secret key packet found'); + } return keys; } From 727c7cad37927ec308d2d50a7cf56b2c0d8a1d5b Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Mon, 13 May 2024 18:43:42 +0200 Subject: [PATCH 136/201] `read[Private]Key`: support parsing key blocks (return first parsable key) Previously, `readKey` and `readPrivateKey` would throw when given a block of keys as input. With this change, the first parsable key is returned by both functions: the behaviour is equivalent to calling `readKeys` (resp. `readPrivateKeys`) and taking the first array entry. --- src/key/factory.js | 17 +++++++++++-- test/general/openpgp.js | 56 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 2 deletions(-) diff --git a/src/key/factory.js b/src/key/factory.js index 36e39a46..ad542640 100644 --- a/src/key/factory.js +++ b/src/key/factory.js @@ -340,7 +340,12 @@ export async function readKey({ armoredKey, binaryKey, config, ...rest }) { input = binaryKey; } const packetlist = await PacketList.fromBinary(input, allowedKeyPackets, config); - return createKey(packetlist); + const keyIndex = packetlist.indexOfTag(enums.packet.publicKey, enums.packet.secretKey); + if (keyIndex.length === 0) { + throw new Error('No key packet found'); + } + const firstKeyPacketList = packetlist.slice(keyIndex[0], keyIndex[1]); + return createKey(firstKeyPacketList); } /** @@ -377,7 +382,15 @@ export async function readPrivateKey({ armoredKey, binaryKey, config, ...rest }) input = binaryKey; } const packetlist = await PacketList.fromBinary(input, allowedKeyPackets, config); - return new PrivateKey(packetlist); + const keyIndex = packetlist.indexOfTag(enums.packet.publicKey, enums.packet.secretKey); + for (let i = 0; i < keyIndex.length; i++) { + if (packetlist[keyIndex[i]].constructor.tag === enums.packet.publicKey) { + continue; + } + const firstPrivateKeyList = packetlist.slice(keyIndex[i], keyIndex[i + 1]); + return new PrivateKey(firstPrivateKeyList); + } + throw new Error('No secret key packet found'); } /** diff --git a/test/general/openpgp.js b/test/general/openpgp.js index 070af1b6..d6d1df92 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -990,6 +990,62 @@ export default () => describe('OpenPGP.js public api tests', function() { }); }); + it('readPrivateKey and readPrivateKeys should have consistent results', async function() { + const privateAndPublicKeyBlock = `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xVgEZkI3VBYJKwYBBAHaRw8BAQdA7nW1t5qRdtIYzEVEEhRSDgTgbk2JHofY +Ph8FuGsDqgwAAQDYVpZt1w6a+vxgb4M351aCpA2sCfx8kbFg23h8Irtm1xFY +zQ88dGVzdEB0ZXN0LmNvbT7CwBMEEBYKAIUFgmZCN1QDCwkHCZDuyoEpQ/KE +H0UUAAAAAAAcACBzYWx0QG5vdGF0aW9ucy5vcGVucGdwanMub3JnzKJ8mXOC +wnEp6lVJ/5+rRzR4UcwlL8EjhOS+rV0T8pAFFQgKDA4EFgACAQIZAQKbAwIe +ARYhBECs3D9sMFn6oOxAqu7KgSlD8oQfAAAPbwD+NjyEHt1CRI+0XmgHdiwZ +JN115IO+M37bOxgBnTbVoF0BAMGECXVQoSRVNy0TYf+AUUPQ6tSZ1zLXszwe +FK3w+CoGxjMEZkI3VBYJKwYBBAHaRw8BAQdA7nW1t5qRdtIYzEVEEhRSDgTg +bk2JHofYPh8FuGsDqgzNDzx0ZXN0QHRlc3QuY29tPsLAEwQQFgoAhQWCZkI3 +VAMLCQcJkO7KgSlD8oQfRRQAAAAAABwAIHNhbHRAbm90YXRpb25zLm9wZW5w +Z3Bqcy5vcmfMonyZc4LCcSnqVUn/n6tHNHhRzCUvwSOE5L6tXRPykAUVCAoM +DgQWAAIBAhkBApsDAh4BFiEEQKzcP2wwWfqg7ECq7sqBKUPyhB8AAA9vAP42 +PIQe3UJEj7ReaAd2LBkk3XXkg74zfts7GAGdNtWgXQEAwYQJdVChJFU3LRNh +/4BRQ9Dq1JnXMtezPB4UrfD4KgY= +-----END PGP PRIVATE KEY BLOCK-----`; + // readPrivateKey should read the first private key encountered in a key block + const key = await openpgp.readPrivateKey({ armoredKey: privateAndPublicKeyBlock }); + const privateKeys = await openpgp.readPrivateKeys({ armoredKeys: privateAndPublicKeyBlock }); + expect(privateKeys.length).to.equal(1); + expect(key.isPrivate()).to.be.true; + expect(privateKeys[0].isPrivate()).to.be.true; + expect(key.isDecrypted()).to.be.true; + expect(privateKeys[0].isDecrypted()).to.be.true; + expect(key.getKeyID().equals(privateKeys[0].getKeyID())).to.be.true; + }); + + it('readKey and readKeys should have consistent results', async function() { + const publicAndPrivateKeyBlock = `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xjMEZkI3VBYJKwYBBAHaRw8BAQdA7nW1t5qRdtIYzEVEEhRSDgTgbk2JHofY +Ph8FuGsDqgzNDzx0ZXN0QHRlc3QuY29tPsLAEwQQFgoAhQWCZkI3VAMLCQcJ +kO7KgSlD8oQfRRQAAAAAABwAIHNhbHRAbm90YXRpb25zLm9wZW5wZ3Bqcy5v +cmfMonyZc4LCcSnqVUn/n6tHNHhRzCUvwSOE5L6tXRPykAUVCAoMDgQWAAIB +AhkBApsDAh4BFiEEQKzcP2wwWfqg7ECq7sqBKUPyhB8AAA9vAP42PIQe3UJE +j7ReaAd2LBkk3XXkg74zfts7GAGdNtWgXQEAwYQJdVChJFU3LRNh/4BRQ9Dq +1JnXMtezPB4UrfD4KgbFWARmQjdUFgkrBgEEAdpHDwEBB0DudbW3mpF20hjM +RUQSFFIOBOBuTYkeh9g+HwW4awOqDAABANhWlm3XDpr6/GBvgzfnVoKkDawJ +/HyRsWDbeHwiu2bXEVjNDzx0ZXN0QHRlc3QuY29tPsLAEwQQFgoAhQWCZkI3 +VAMLCQcJkO7KgSlD8oQfRRQAAAAAABwAIHNhbHRAbm90YXRpb25zLm9wZW5w +Z3Bqcy5vcmfMonyZc4LCcSnqVUn/n6tHNHhRzCUvwSOE5L6tXRPykAUVCAoM +DgQWAAIBAhkBApsDAh4BFiEEQKzcP2wwWfqg7ECq7sqBKUPyhB8AAA9vAP42 +PIQe3UJEj7ReaAd2LBkk3XXkg74zfts7GAGdNtWgXQEAwYQJdVChJFU3LRNh +/4BRQ9Dq1JnXMtezPB4UrfD4KgY= +-----END PGP PRIVATE KEY BLOCK-----`; + // readKey should read the first key encountered in a key block + const key = await openpgp.readKey({ armoredKey: publicAndPrivateKeyBlock }); + const keys = await openpgp.readKeys({ armoredKeys: publicAndPrivateKeyBlock }); + expect(keys.length).to.equal(2); + expect(key.isPrivate()).to.be.false; + expect(keys[0].isPrivate()).to.be.false; + expect(keys[1].isPrivate()).to.be.true; + }); + it('readPrivateKey should throw on armored public key', async function() { await expect(openpgp.readPrivateKey({ armoredKey: pub_key })).to.be.rejectedWith(/Armored text not of type private key/); }); From 676c31b748a53343700de6d73dadf8d2a764d7b6 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Thu, 16 May 2024 17:21:36 +0200 Subject: [PATCH 137/201] CI: update SOP actions to Node 20 --- .github/workflows/sop-test-suite.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/sop-test-suite.yml b/.github/workflows/sop-test-suite.yml index 5d8b1bcb..193a91ac 100644 --- a/.github/workflows/sop-test-suite.yml +++ b/.github/workflows/sop-test-suite.yml @@ -56,12 +56,12 @@ jobs: RESULTS_HTML: .github/test-suite/test-suite-results.html # Upload results - name: Upload test results json artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: test-suite-results.json path: .github/test-suite/test-suite-results.json - name: Upload test results html artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: test-suite-results.html path: .github/test-suite/test-suite-results.html @@ -75,7 +75,7 @@ jobs: uses: actions/checkout@v4 - name: Download test results json artifact id: download-test-results - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: test-suite-results.json - name: Compare with baseline From 6a306a179794992d0bf0b319f3a8d6a8e6ca32f3 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Fri, 17 May 2024 13:00:37 +0200 Subject: [PATCH 138/201] Lint: add support for dep imports that use `exports` declarations --- .eslintrc.cjs | 11 ++++--- package-lock.json | 79 +++++++++++++++++++++++++++++++++++++++++++++++ package.json | 1 + 3 files changed, 87 insertions(+), 4 deletions(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 58a62f87..1be7c193 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -25,6 +25,12 @@ module.exports = { 'unicorn' ], + 'settings': { + 'import/resolver': { + 'typescript': {} + } + }, + 'globals': { // TODO are all these necessary? 'globalThis': true, 'console': true, @@ -110,10 +116,7 @@ module.exports = { 'import/first': 'off', 'import/no-extraneous-dependencies': ['error', { 'devDependencies': true, 'optionalDependencies': false, 'peerDependencies': false }], 'import/no-unassigned-import': 'error', - 'import/no-unresolved': ['error', { - // esm exports not supported: https://github.com/import-js/eslint-plugin-import/issues/1810 - ignore: ['openpgp', '@noble/hashes', '@openpgp/web-stream-tools', '@openpgp/asmcrypto.js'] - }], + 'import/no-unresolved': 'error', 'import/prefer-default-export': 'off', // Custom silencers: diff --git a/package-lock.json b/package-lock.json index 8d0c7a99..d6baabb7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,6 +36,7 @@ "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-airbnb-typescript": "^18.0.0", + "eslint-import-resolver-typescript": "^3.6.1", "eslint-plugin-chai-friendly": "^0.7.4", "eslint-plugin-import": "^2.29.1", "eslint-plugin-unicorn": "^48.0.1", @@ -2950,6 +2951,19 @@ "node": ">=10.0.0" } }, + "node_modules/enhanced-resolve": { + "version": "5.16.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.1.tgz", + "integrity": "sha512-4U5pNsuDl0EhuZpq46M5xPslstkviJuhrdobaRDBk2Jy2KO37FDAJl4lb2KlNabxT0m4MTK2UHNrsAcphE8nyw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/ent": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", @@ -3339,6 +3353,31 @@ "ms": "^2.1.1" } }, + "node_modules/eslint-import-resolver-typescript": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz", + "integrity": "sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "enhanced-resolve": "^5.12.0", + "eslint-module-utils": "^2.7.4", + "fast-glob": "^3.3.1", + "get-tsconfig": "^4.5.0", + "is-core-module": "^2.11.0", + "is-glob": "^4.0.3" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*" + } + }, "node_modules/eslint-module-utils": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", @@ -7613,6 +7652,15 @@ "integrity": "sha512-y3JaeRSplks6NYQuCOj3ZFMO3j60rTwbuKCvZxsAraGYH2epusatvZ0baZYA01WsGqJBq/Dl6vOrMUJqyMj8kA==", "dev": true }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/temp-fs": { "version": "0.9.9", "resolved": "https://registry.npmjs.org/temp-fs/-/temp-fs-0.9.9.tgz", @@ -10416,6 +10464,16 @@ "integrity": "sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==", "dev": true }, + "enhanced-resolve": { + "version": "5.16.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.1.tgz", + "integrity": "sha512-4U5pNsuDl0EhuZpq46M5xPslstkviJuhrdobaRDBk2Jy2KO37FDAJl4lb2KlNabxT0m4MTK2UHNrsAcphE8nyw==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, "ent": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", @@ -10741,6 +10799,21 @@ } } }, + "eslint-import-resolver-typescript": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz", + "integrity": "sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==", + "dev": true, + "requires": { + "debug": "^4.3.4", + "enhanced-resolve": "^5.12.0", + "eslint-module-utils": "^2.7.4", + "fast-glob": "^3.3.1", + "get-tsconfig": "^4.5.0", + "is-core-module": "^2.11.0", + "is-glob": "^4.0.3" + } + }, "eslint-module-utils": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", @@ -13939,6 +14012,12 @@ "integrity": "sha512-y3JaeRSplks6NYQuCOj3ZFMO3j60rTwbuKCvZxsAraGYH2epusatvZ0baZYA01WsGqJBq/Dl6vOrMUJqyMj8kA==", "dev": true }, + "tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true + }, "temp-fs": { "version": "0.9.9", "resolved": "https://registry.npmjs.org/temp-fs/-/temp-fs-0.9.9.tgz", diff --git a/package.json b/package.json index 4d0968ba..f3fd019d 100644 --- a/package.json +++ b/package.json @@ -89,6 +89,7 @@ "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-airbnb-typescript": "^18.0.0", + "eslint-import-resolver-typescript": "^3.6.1", "eslint-plugin-chai-friendly": "^0.7.4", "eslint-plugin-import": "^2.29.1", "eslint-plugin-unicorn": "^48.0.1", From 1d732c34fffc50cc6de9bc195f66aea2ae8a2ade Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Fri, 17 May 2024 13:04:47 +0200 Subject: [PATCH 139/201] Run npm update --- package-lock.json | 1985 +++++++++++++++++++++++++-------------------- package.json | 18 +- 2 files changed, 1109 insertions(+), 894 deletions(-) diff --git a/package-lock.json b/package-lock.json index d6baabb7..03aa3b3f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,8 +9,8 @@ "version": "6.0.0-beta.0", "license": "LGPL-3.0+", "devDependencies": { - "@noble/curves": "^1.3.0", - "@noble/hashes": "^1.3.3", + "@noble/curves": "^1.4.0", + "@noble/hashes": "^1.4.0", "@openpgp/asmcrypto.js": "^3.1.0", "@openpgp/jsdoc": "^3.6.11", "@openpgp/seek-bzip": "^1.0.5-git", @@ -23,14 +23,14 @@ "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-typescript": "^11.1.6", "@rollup/plugin-wasm": "^6.2.2", - "@types/chai": "^4.3.14", - "@typescript-eslint/parser": "^7.8.0", + "@types/chai": "^4.3.16", + "@typescript-eslint/parser": "^7.9.0", "argon2id": "^1.0.1", "benchmark": "^2.1.4", "bn.js": "^5.2.1", "c8": "^8.0.1", "chai": "^4.4.1", - "chai-as-promised": "^7.1.1", + "chai-as-promised": "^7.1.2", "eckey-utils": "^0.7.14", "eslint": "^8.57.0", "eslint-config-airbnb": "^19.0.4", @@ -50,28 +50,19 @@ "karma-mocha-reporter": "^2.2.5", "karma-webkit-launcher": "^2.4.0", "mocha": "^10.4.0", - "playwright": "^1.43.0", - "rollup": "^4.14.1", + "playwright": "^1.44.0", + "rollup": "^4.17.2", "sinon": "^17.0.1", "ts-node": "^10.9.2", "tslib": "^2.6.2", - "tsx": "^4.7.2", - "typescript": "^5.4.4", + "tsx": "^4.10.4", + "typescript": "^5.4.5", "web-streams-polyfill": "^3.3.3" }, "engines": { "node": ">= 16.5.0" } }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/@babel/code-frame": { "version": "7.24.2", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", @@ -86,21 +77,21 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.5.tgz", + "integrity": "sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", - "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.5.tgz", + "integrity": "sha512-8lLmua6AVh/8SLJRRVD6V8p73Hir9w5mJrhE+IPpILG31KKlI9iz5zmBYKcWPS59qSfgP9RaSBQSHHE81WKuEw==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-validator-identifier": "^7.24.5", "chalk": "^2.4.2", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" @@ -181,9 +172,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz", - "integrity": "sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.5.tgz", + "integrity": "sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -193,9 +184,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.4.tgz", - "integrity": "sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz", + "integrity": "sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==", "dev": true, "peer": true, "dependencies": { @@ -243,9 +234,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", - "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", + "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", "cpu": [ "ppc64" ], @@ -259,9 +250,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", - "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", "cpu": [ "arm" ], @@ -275,9 +266,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", - "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", "cpu": [ "arm64" ], @@ -291,9 +282,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", - "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", "cpu": [ "x64" ], @@ -307,9 +298,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", - "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", + "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", "cpu": [ "arm64" ], @@ -323,9 +314,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", - "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", + "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", "cpu": [ "x64" ], @@ -339,9 +330,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", - "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", "cpu": [ "arm64" ], @@ -355,9 +346,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", - "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", "cpu": [ "x64" ], @@ -371,9 +362,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", - "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", "cpu": [ "arm" ], @@ -387,9 +378,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", - "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", "cpu": [ "arm64" ], @@ -403,9 +394,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", - "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", "cpu": [ "ia32" ], @@ -419,9 +410,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", - "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", "cpu": [ "loong64" ], @@ -435,9 +426,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", - "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", "cpu": [ "mips64el" ], @@ -451,9 +442,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", - "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", "cpu": [ "ppc64" ], @@ -467,9 +458,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", - "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", "cpu": [ "riscv64" ], @@ -483,9 +474,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", - "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", "cpu": [ "s390x" ], @@ -499,9 +490,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", - "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", "cpu": [ "x64" ], @@ -515,9 +506,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", - "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", "cpu": [ "x64" ], @@ -531,9 +522,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", - "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", "cpu": [ "x64" ], @@ -547,9 +538,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", - "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", "cpu": [ "x64" ], @@ -563,9 +554,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", - "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", "cpu": [ "arm64" ], @@ -579,9 +570,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", - "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", "cpu": [ "ia32" ], @@ -595,9 +586,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", - "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", + "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", "cpu": [ "x64" ], @@ -657,6 +648,28 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/@eslint/js": { "version": "8.57.0", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", @@ -680,6 +693,28 @@ "node": ">=10.10.0" } }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -1078,9 +1113,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.14.1.tgz", - "integrity": "sha512-fH8/o8nSUek8ceQnT7K4EQbSiV7jgkHq81m9lWZFIXjJ7lJzpWXbQFpT/Zh6OZYnpFykvzC3fbEvEAFZu03dPA==", + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.17.2.tgz", + "integrity": "sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==", "cpu": [ "arm" ], @@ -1091,9 +1126,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.14.1.tgz", - "integrity": "sha512-Y/9OHLjzkunF+KGEoJr3heiD5X9OLa8sbT1lm0NYeKyaM3oMhhQFvPB0bNZYJwlq93j8Z6wSxh9+cyKQaxS7PQ==", + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.17.2.tgz", + "integrity": "sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw==", "cpu": [ "arm64" ], @@ -1104,9 +1139,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.14.1.tgz", - "integrity": "sha512-+kecg3FY84WadgcuSVm6llrABOdQAEbNdnpi5X3UwWiFVhZIZvKgGrF7kmLguvxHNQy+UuRV66cLVl3S+Rkt+Q==", + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.17.2.tgz", + "integrity": "sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==", "cpu": [ "arm64" ], @@ -1117,9 +1152,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.14.1.tgz", - "integrity": "sha512-2pYRzEjVqq2TB/UNv47BV/8vQiXkFGVmPFwJb+1E0IFFZbIX8/jo1olxqqMbo6xCXf8kabANhp5bzCij2tFLUA==", + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.17.2.tgz", + "integrity": "sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ==", "cpu": [ "x64" ], @@ -1130,9 +1165,22 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.14.1.tgz", - "integrity": "sha512-mS6wQ6Do6/wmrF9aTFVpIJ3/IDXhg1EZcQFYHZLHqw6AzMBjTHWnCG35HxSqUNphh0EHqSM6wRTT8HsL1C0x5g==", + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.17.2.tgz", + "integrity": "sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.17.2.tgz", + "integrity": "sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg==", "cpu": [ "arm" ], @@ -1143,9 +1191,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.14.1.tgz", - "integrity": "sha512-p9rGKYkHdFMzhckOTFubfxgyIO1vw//7IIjBBRVzyZebWlzRLeNhqxuSaZ7kCEKVkm/kuC9fVRW9HkC/zNRG2w==", + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.17.2.tgz", + "integrity": "sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==", "cpu": [ "arm64" ], @@ -1156,9 +1204,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.14.1.tgz", - "integrity": "sha512-nDY6Yz5xS/Y4M2i9JLQd3Rofh5OR8Bn8qe3Mv/qCVpHFlwtZSBYSPaU4mrGazWkXrdQ98GB//H0BirGR/SKFSw==", + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.17.2.tgz", + "integrity": "sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA==", "cpu": [ "arm64" ], @@ -1169,11 +1217,11 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.14.1.tgz", - "integrity": "sha512-im7HE4VBL+aDswvcmfx88Mp1soqL9OBsdDBU8NqDEYtkri0qV0THhQsvZtZeNNlLeCUQ16PZyv7cqutjDF35qw==", + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.17.2.tgz", + "integrity": "sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ==", "cpu": [ - "ppc64le" + "ppc64" ], "dev": true, "optional": true, @@ -1182,9 +1230,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.14.1.tgz", - "integrity": "sha512-RWdiHuAxWmzPJgaHJdpvUUlDz8sdQz4P2uv367T2JocdDa98iRw2UjIJ4QxSyt077mXZT2X6pKfT2iYtVEvOFw==", + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.17.2.tgz", + "integrity": "sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg==", "cpu": [ "riscv64" ], @@ -1195,9 +1243,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.14.1.tgz", - "integrity": "sha512-VMgaGQ5zRX6ZqV/fas65/sUGc9cPmsntq2FiGmayW9KMNfWVG/j0BAqImvU4KTeOOgYSf1F+k6at1UfNONuNjA==", + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.17.2.tgz", + "integrity": "sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g==", "cpu": [ "s390x" ], @@ -1208,9 +1256,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.14.1.tgz", - "integrity": "sha512-9Q7DGjZN+hTdJomaQ3Iub4m6VPu1r94bmK2z3UeWP3dGUecRC54tmVu9vKHTm1bOt3ASoYtEz6JSRLFzrysKlA==", + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz", + "integrity": "sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==", "cpu": [ "x64" ], @@ -1221,9 +1269,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.14.1.tgz", - "integrity": "sha512-JNEG/Ti55413SsreTguSx0LOVKX902OfXIKVg+TCXO6Gjans/k9O6ww9q3oLGjNDaTLxM+IHFMeXy/0RXL5R/g==", + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.17.2.tgz", + "integrity": "sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==", "cpu": [ "x64" ], @@ -1234,9 +1282,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.14.1.tgz", - "integrity": "sha512-ryS22I9y0mumlLNwDFYZRDFLwWh3aKaC72CWjFcFvxK0U6v/mOkM5Up1bTbCRAhv3kEIwW2ajROegCIQViUCeA==", + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.17.2.tgz", + "integrity": "sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA==", "cpu": [ "arm64" ], @@ -1247,9 +1295,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.14.1.tgz", - "integrity": "sha512-TdloItiGk+T0mTxKx7Hp279xy30LspMso+GzQvV2maYePMAWdmrzqSNZhUpPj3CGw12aGj57I026PgLCTu8CGg==", + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.17.2.tgz", + "integrity": "sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ==", "cpu": [ "ia32" ], @@ -1260,9 +1308,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.14.1.tgz", - "integrity": "sha512-wQGI+LY/Py20zdUPq+XCem7JcPOyzIJBm3dli+56DJsQOHbnXZFEwgmnC6el1TPAfC8lBT3m+z69RmLykNUbew==", + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.17.2.tgz", + "integrity": "sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==", "cpu": [ "x64" ], @@ -1317,9 +1365,9 @@ "dev": true }, "node_modules/@socket.io/component-emitter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", - "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", "dev": true }, "node_modules/@tsconfig/node10": { @@ -1347,9 +1395,9 @@ "dev": true }, "node_modules/@types/chai": { - "version": "4.3.14", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.14.tgz", - "integrity": "sha512-Wj71sXE4Q4AkGdG9Tvq1u/fquNz9EdG4LIJMwVVII7ashjD/8cf8fyIfJAjRr6YcsXnSE8cOGQPq1gqeR8z+3w==", + "version": "4.3.16", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.16.tgz", + "integrity": "sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ==", "dev": true }, "node_modules/@types/cookie": { @@ -1379,13 +1427,6 @@ "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", "dev": true }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, - "peer": true - }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -1393,9 +1434,9 @@ "dev": true }, "node_modules/@types/linkify-it": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.5.tgz", - "integrity": "sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", "dev": true }, "node_modules/@types/markdown-it": { @@ -1409,15 +1450,15 @@ } }, "node_modules/@types/mdurl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.5.tgz", - "integrity": "sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", "dev": true }, "node_modules/@types/node": { - "version": "20.12.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.6.tgz", - "integrity": "sha512-3KurE8taB8GCvZBPngVbp0lk5CKi8M9f9k1rsADh0Evdz5SzJ+Q+Hx9uHoFGsLnLnd1xmkDQr2hVhlA0Mn0lKQ==", + "version": "20.12.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz", + "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -1435,30 +1476,21 @@ "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", "dev": true }, - "node_modules/@types/semver": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", - "dev": true, - "peer": true - }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.8.0.tgz", - "integrity": "sha512-gFTT+ezJmkwutUPmB0skOj3GZJtlEGnlssems4AjkVweUPGj7jRwwqg0Hhg7++kPGJqKtTYx+R05Ftww372aIg==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.9.0.tgz", + "integrity": "sha512-6e+X0X3sFe/G/54aC3jt0txuMTURqLyekmEHViqyA2VnxhLMpvA6nqmcjIy+Cr9tLDHPssA74BP5Mx9HQIxBEA==", "dev": true, "peer": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.8.0", - "@typescript-eslint/type-utils": "7.8.0", - "@typescript-eslint/utils": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0", - "debug": "^4.3.4", + "@typescript-eslint/scope-manager": "7.9.0", + "@typescript-eslint/type-utils": "7.9.0", + "@typescript-eslint/utils": "7.9.0", + "@typescript-eslint/visitor-keys": "7.9.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", - "semver": "^7.6.0", "ts-api-utils": "^1.3.0" }, "engines": { @@ -1478,32 +1510,16 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "peer": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@typescript-eslint/parser": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.8.0.tgz", - "integrity": "sha512-KgKQly1pv0l4ltcftP59uQZCi4HUYswCLbTqVZEJu7uLX8CTLyswqMLqLN+2QFz4jCptqWVV4SB7vdxcH2+0kQ==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.9.0.tgz", + "integrity": "sha512-qHMJfkL5qvgQB2aLvhUSXxbK7OLnDkwPzFalg458pxQgfxKDfT1ZDbHQM/I6mDIf/svlMkj21kzKuQ2ixJlatQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.8.0", - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/typescript-estree": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0", + "@typescript-eslint/scope-manager": "7.9.0", + "@typescript-eslint/types": "7.9.0", + "@typescript-eslint/typescript-estree": "7.9.0", + "@typescript-eslint/visitor-keys": "7.9.0", "debug": "^4.3.4" }, "engines": { @@ -1523,13 +1539,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.8.0.tgz", - "integrity": "sha512-viEmZ1LmwsGcnr85gIq+FCYI7nO90DVbE37/ll51hjv9aG+YZMb4WDE2fyWpUR4O/UrhGRpYXK/XajcGTk2B8g==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.9.0.tgz", + "integrity": "sha512-ZwPK4DeCDxr3GJltRz5iZejPFAAr4Wk3+2WIBaj1L5PYK5RgxExu/Y68FFVclN0y6GGwH8q+KgKRCvaTmFBbgQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0" + "@typescript-eslint/types": "7.9.0", + "@typescript-eslint/visitor-keys": "7.9.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -1540,14 +1556,14 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.8.0.tgz", - "integrity": "sha512-H70R3AefQDQpz9mGv13Uhi121FNMh+WEaRqcXTX09YEDky21km4dV1ZXJIp8QjXc4ZaVkXVdohvWDzbnbHDS+A==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.9.0.tgz", + "integrity": "sha512-6Qy8dfut0PFrFRAZsGzuLoM4hre4gjzWJB6sUvdunCYZsYemTkzZNwF1rnGea326PHPT3zn5Lmg32M/xfJfByA==", "dev": true, "peer": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.8.0", - "@typescript-eslint/utils": "7.8.0", + "@typescript-eslint/typescript-estree": "7.9.0", + "@typescript-eslint/utils": "7.9.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -1568,9 +1584,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.8.0.tgz", - "integrity": "sha512-wf0peJ+ZGlcH+2ZS23aJbOv+ztjeeP8uQ9GgwMJGVLx/Nj9CJt17GWgWWoSmoRVKAX2X+7fzEnAjxdvK2gqCLw==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.9.0.tgz", + "integrity": "sha512-oZQD9HEWQanl9UfsbGVcZ2cGaR0YT5476xfWE0oE5kQa2sNK2frxOlkeacLOTh9po4AlUT5rtkGyYM5kew0z5w==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -1581,13 +1597,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.8.0.tgz", - "integrity": "sha512-5pfUCOwK5yjPaJQNy44prjCwtr981dO8Qo9J9PwYXZ0MosgAbfEMB008dJ5sNo3+/BN6ytBPuSvXUg9SAqB0dg==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.9.0.tgz", + "integrity": "sha512-zBCMCkrb2YjpKV3LA0ZJubtKCDxLttxfdGmwZvTqqWevUPN0FZvSI26FalGFFUZU/9YQK/A4xcQF9o/VVaCKAg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0", + "@typescript-eslint/types": "7.9.0", + "@typescript-eslint/visitor-keys": "7.9.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -1608,59 +1624,17 @@ } } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@typescript-eslint/utils": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.8.0.tgz", - "integrity": "sha512-L0yFqOCflVqXxiZyXrDr80lnahQfSOfc9ELAAZ75sqicqp2i36kEZZGuUymHNFoYOqxRT05up760b4iGsl02nQ==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.9.0.tgz", + "integrity": "sha512-5KVRQCzZajmT4Ep+NEgjXCvjuypVvYHUW7RHlXzNPuak2oWpVoD1jf5xCP0dPAuNIchjC7uQyvbdaSTFaLqSdA==", "dev": true, "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.15", - "@types/semver": "^7.5.8", - "@typescript-eslint/scope-manager": "7.8.0", - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/typescript-estree": "7.8.0", - "semver": "^7.6.0" + "@typescript-eslint/scope-manager": "7.9.0", + "@typescript-eslint/types": "7.9.0", + "@typescript-eslint/typescript-estree": "7.9.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -1673,29 +1647,13 @@ "eslint": "^8.56.0" } }, - "node_modules/@typescript-eslint/utils/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "peer": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.8.0.tgz", - "integrity": "sha512-q4/gibTNBQNA0lGyYQCmWRS5D15n8rXh4QjK3KV+MBPlTYHpfBUT3D3PaPR/HeNiI9W6R7FvlkcGhNyAoP+caA==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.9.0.tgz", + "integrity": "sha512-iESPx2TNLDNGQLyjKhUvIKprlP49XNEK+MvIf9nIO7ZZaZdbnfWKHnXAgufpxqfA0YryH8XToi4+CjBgVnFTSQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.8.0", + "@typescript-eslint/types": "7.9.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -2189,13 +2147,12 @@ "dev": true }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^1.0.0" } }, "node_modules/braces": { @@ -2375,15 +2332,15 @@ } }, "node_modules/chai-as-promised": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz", - "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.2.tgz", + "integrity": "sha512-aBDHZxRzYnUYuIAIPBH2s511DjlKPzXNlXSGFC8CwmroWQLfrW0LtE1nK3MAwwNhJPa9raEjNCmRoFpG0Hurdw==", "dev": true, "dependencies": { "check-error": "^1.0.2" }, "peerDependencies": { - "chai": ">= 2.1.2 < 5" + "chai": ">= 2.1.2 < 6" } }, "node_modules/chalk": { @@ -3070,15 +3027,15 @@ } }, "node_modules/es-iterator-helpers": { - "version": "1.0.18", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.18.tgz", - "integrity": "sha512-scxAJaewsahbqTYrGKJihhViaM6DDZDDoucfvzNbK0pOren1g/daDQ3IAhzn+1G14rBG7w+i5N+qul60++zlKA==", + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz", + "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==", "dev": true, "peer": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", + "es-abstract": "^1.23.3", "es-errors": "^1.3.0", "es-set-tostringtag": "^2.0.3", "function-bind": "^1.1.2", @@ -3163,9 +3120,9 @@ } }, "node_modules/esbuild": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", - "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", + "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", "dev": true, "hasInstallScript": true, "bin": { @@ -3175,29 +3132,29 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.19.12", - "@esbuild/android-arm": "0.19.12", - "@esbuild/android-arm64": "0.19.12", - "@esbuild/android-x64": "0.19.12", - "@esbuild/darwin-arm64": "0.19.12", - "@esbuild/darwin-x64": "0.19.12", - "@esbuild/freebsd-arm64": "0.19.12", - "@esbuild/freebsd-x64": "0.19.12", - "@esbuild/linux-arm": "0.19.12", - "@esbuild/linux-arm64": "0.19.12", - "@esbuild/linux-ia32": "0.19.12", - "@esbuild/linux-loong64": "0.19.12", - "@esbuild/linux-mips64el": "0.19.12", - "@esbuild/linux-ppc64": "0.19.12", - "@esbuild/linux-riscv64": "0.19.12", - "@esbuild/linux-s390x": "0.19.12", - "@esbuild/linux-x64": "0.19.12", - "@esbuild/netbsd-x64": "0.19.12", - "@esbuild/openbsd-x64": "0.19.12", - "@esbuild/sunos-x64": "0.19.12", - "@esbuild/win32-arm64": "0.19.12", - "@esbuild/win32-ia32": "0.19.12", - "@esbuild/win32-x64": "0.19.12" + "@esbuild/aix-ppc64": "0.20.2", + "@esbuild/android-arm": "0.20.2", + "@esbuild/android-arm64": "0.20.2", + "@esbuild/android-x64": "0.20.2", + "@esbuild/darwin-arm64": "0.20.2", + "@esbuild/darwin-x64": "0.20.2", + "@esbuild/freebsd-arm64": "0.20.2", + "@esbuild/freebsd-x64": "0.20.2", + "@esbuild/linux-arm": "0.20.2", + "@esbuild/linux-arm64": "0.20.2", + "@esbuild/linux-ia32": "0.20.2", + "@esbuild/linux-loong64": "0.20.2", + "@esbuild/linux-mips64el": "0.20.2", + "@esbuild/linux-ppc64": "0.20.2", + "@esbuild/linux-riscv64": "0.20.2", + "@esbuild/linux-s390x": "0.20.2", + "@esbuild/linux-x64": "0.20.2", + "@esbuild/netbsd-x64": "0.20.2", + "@esbuild/openbsd-x64": "0.20.2", + "@esbuild/sunos-x64": "0.20.2", + "@esbuild/win32-arm64": "0.20.2", + "@esbuild/win32-ia32": "0.20.2", + "@esbuild/win32-x64": "0.20.2" } }, "node_modules/escalade": { @@ -3319,6 +3276,15 @@ "eslint-plugin-import": "^2.25.2" } }, + "node_modules/eslint-config-airbnb-base/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/eslint-config-airbnb-typescript": { "version": "18.0.0", "resolved": "https://registry.npmjs.org/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-18.0.0.tgz", @@ -3447,6 +3413,16 @@ "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" } }, + "node_modules/eslint-plugin-import/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/eslint-plugin-import/node_modules/debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", @@ -3468,6 +3444,27 @@ "node": ">=0.10.0" } }, + "node_modules/eslint-plugin-import/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/eslint-plugin-jsx-a11y": { "version": "6.8.0", "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.8.0.tgz", @@ -3499,6 +3496,30 @@ "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" } }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/eslint-plugin-react": { "version": "7.34.1", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.1.tgz", @@ -3533,9 +3554,9 @@ } }, "node_modules/eslint-plugin-react-hooks": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", - "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", + "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", "dev": true, "peer": true, "engines": { @@ -3545,6 +3566,17 @@ "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" } }, + "node_modules/eslint-plugin-react/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/eslint-plugin-react/node_modules/doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", @@ -3558,6 +3590,19 @@ "node": ">=0.10.0" } }, + "node_modules/eslint-plugin-react/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/eslint-plugin-react/node_modules/resolve": { "version": "2.0.0-next.5", "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", @@ -3576,6 +3621,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "peer": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/eslint-plugin-unicorn": { "version": "48.0.1", "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-48.0.1.tgz", @@ -3608,21 +3663,6 @@ "eslint": ">=8.44.0" } }, - "node_modules/eslint-plugin-unicorn/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/eslint-scope": { "version": "7.2.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", @@ -3651,6 +3691,16 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/eslint/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -3663,6 +3713,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/espree": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", @@ -4103,9 +4165,9 @@ } }, "node_modules/get-tsconfig": { - "version": "4.7.3", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz", - "integrity": "sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==", + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.5.tgz", + "integrity": "sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==", "dev": true, "dependencies": { "resolve-pkg-maps": "^1.0.0" @@ -4145,15 +4207,6 @@ "node": ">=10.13.0" } }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, "node_modules/glob/node_modules/minimatch": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", @@ -4182,12 +4235,13 @@ } }, "node_modules/globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", "dev": true, "dependencies": { - "define-properties": "^1.1.3" + "define-properties": "^1.2.1", + "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -5438,6 +5492,16 @@ } } }, + "node_modules/karma/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/karma/node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -5481,6 +5545,18 @@ "node": ">=4.0.0" } }, + "node_modules/karma/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/karma/node_modules/mkdirp": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", @@ -5740,28 +5816,13 @@ "get-func-name": "^2.0.1" } }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/magic-string": { - "version": "0.30.9", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.9.tgz", - "integrity": "sha512-S1+hd+dIrC8EZqKyT9DstTH/0Z+f76kmmvZnkfQVmOpDEF9iVgdYif3Q/pIWHmCoo59bQVGW0kVL3e2nl+9+Sw==", + "version": "0.30.10", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", + "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" } }, "node_modules/make-dir": { @@ -5779,21 +5840,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/make-dir/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", @@ -5924,15 +5970,18 @@ } }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", "dev": true, "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" }, "engines": { - "node": "*" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/minimist": { @@ -5991,15 +6040,6 @@ "node": ">= 14.0.0" } }, - "node_modules/mocha/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, "node_modules/mocha/node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -6368,17 +6408,17 @@ } }, "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" }, "engines": { "node": ">= 0.8.0" @@ -6529,9 +6569,9 @@ } }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", "dev": true }, "node_modules/picomatch": { @@ -6553,12 +6593,12 @@ "dev": true }, "node_modules/playwright": { - "version": "1.43.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.43.0.tgz", - "integrity": "sha512-SiOKHbVjTSf6wHuGCbqrEyzlm6qvXcv7mENP+OZon1I07brfZLGdfWV0l/efAzVx7TF3Z45ov1gPEkku9q25YQ==", + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.44.0.tgz", + "integrity": "sha512-F9b3GUCLQ3Nffrfb6dunPOkE5Mh68tR7zN32L4jCk4FjQamgesGay7/dAAe1WaMEGV04DkdJfcJzjoCKygUaRQ==", "dev": true, "dependencies": { - "playwright-core": "1.43.0" + "playwright-core": "1.44.0" }, "bin": { "playwright": "cli.js" @@ -6571,9 +6611,9 @@ } }, "node_modules/playwright-core": { - "version": "1.43.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.43.0.tgz", - "integrity": "sha512-iWFjyBUH97+pUFiyTqSLd8cDMMOS0r2ZYz2qEsPjH8/bX++sbIJT35MSwKnp1r/OQBAqC5XO99xFbJ9XClhf4w==", + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.44.0.tgz", + "integrity": "sha512-ZTbkNpFfYcGWohvTTl+xewITm7EOuqIqex0c7dNZ+aXsbrLj0qI8XlGKfPpipjm0Wny/4Lt4CJsWJk1stVS5qQ==", "dev": true, "bin": { "playwright-core": "cli.js" @@ -7069,6 +7109,16 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/rimraf/node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -7089,10 +7139,22 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/rollup": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.14.1.tgz", - "integrity": "sha512-4LnHSdd3QK2pa1J6dFbfm1HN0D7vSK/ZuZTsdyUAlA6Rr1yTouUTL13HaDOGJVgby461AhrNGBS7sCGXXtT+SA==", + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.17.2.tgz", + "integrity": "sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==", "dev": true, "dependencies": { "@types/estree": "1.0.5" @@ -7105,21 +7167,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.14.1", - "@rollup/rollup-android-arm64": "4.14.1", - "@rollup/rollup-darwin-arm64": "4.14.1", - "@rollup/rollup-darwin-x64": "4.14.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.14.1", - "@rollup/rollup-linux-arm64-gnu": "4.14.1", - "@rollup/rollup-linux-arm64-musl": "4.14.1", - "@rollup/rollup-linux-powerpc64le-gnu": "4.14.1", - "@rollup/rollup-linux-riscv64-gnu": "4.14.1", - "@rollup/rollup-linux-s390x-gnu": "4.14.1", - "@rollup/rollup-linux-x64-gnu": "4.14.1", - "@rollup/rollup-linux-x64-musl": "4.14.1", - "@rollup/rollup-win32-arm64-msvc": "4.14.1", - "@rollup/rollup-win32-ia32-msvc": "4.14.1", - "@rollup/rollup-win32-x64-msvc": "4.14.1", + "@rollup/rollup-android-arm-eabi": "4.17.2", + "@rollup/rollup-android-arm64": "4.17.2", + "@rollup/rollup-darwin-arm64": "4.17.2", + "@rollup/rollup-darwin-x64": "4.17.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.17.2", + "@rollup/rollup-linux-arm-musleabihf": "4.17.2", + "@rollup/rollup-linux-arm64-gnu": "4.17.2", + "@rollup/rollup-linux-arm64-musl": "4.17.2", + "@rollup/rollup-linux-powerpc64le-gnu": "4.17.2", + "@rollup/rollup-linux-riscv64-gnu": "4.17.2", + "@rollup/rollup-linux-s390x-gnu": "4.17.2", + "@rollup/rollup-linux-x64-gnu": "4.17.2", + "@rollup/rollup-linux-x64-musl": "4.17.2", + "@rollup/rollup-win32-arm64-msvc": "4.17.2", + "@rollup/rollup-win32-ia32-msvc": "4.17.2", + "@rollup/rollup-win32-x64-msvc": "4.17.2", "fsevents": "~2.3.2" } }, @@ -7200,12 +7263,15 @@ "dev": true }, "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, "bin": { "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/serialize-javascript": { @@ -7673,6 +7739,16 @@ "node": ">=0.8.0" } }, + "node_modules/temp-fs/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/temp-fs/node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -7693,6 +7769,18 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/temp-fs/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/temp-fs/node_modules/rimraf": { "version": "2.5.4", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz", @@ -7706,9 +7794,9 @@ } }, "node_modules/terser": { - "version": "5.30.3", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.30.3.tgz", - "integrity": "sha512-STdUgOUx8rLbMGO9IOwHLpCqolkDITFFQSMYYwKE1N2lY6MVSaeoi10z/EhWxRc6ybqoVmKSkhKYH/XUpl7vSA==", + "version": "5.31.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.0.tgz", + "integrity": "sha512-Q1JFAoUKE5IMfI4Z/lkE/E6+SwgzO+x4tq4v1AyBLRj8VSYvRO6A/rQrPg1yud4g0En9EKI1TvFRF2tQFcoUkg==", "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -7743,6 +7831,16 @@ "node": ">=8" } }, + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/test-exclude/node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -7763,6 +7861,18 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/test-exclude/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -7888,13 +7998,13 @@ "dev": true }, "node_modules/tsx": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.2.tgz", - "integrity": "sha512-BCNd4kz6fz12fyrgCTEdZHGJ9fWTGeUzXmQysh0RVocDY3h4frk05ZNCXSy4kIenF7y/QnrdiVpTsyNRn6vlAw==", + "version": "4.10.4", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.10.4.tgz", + "integrity": "sha512-Gtg9qnZWNqC/OtcgiXfoAUdAKx3/cgKOYvEocAsv+m21MV/eKpV/WUjRXe6/sDCaGBl2/v8S6v29BpUnGMCX5A==", "dev": true, "dependencies": { - "esbuild": "~0.19.10", - "get-tsconfig": "^4.7.2" + "esbuild": "~0.20.2", + "get-tsconfig": "^4.7.5" }, "bin": { "tsx": "dist/cli.mjs" @@ -8026,9 +8136,9 @@ } }, "node_modules/typescript": { - "version": "5.4.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.4.tgz", - "integrity": "sha512-dGE2Vv8cpVvw28v8HCPqyb08EzbBURxDpuhJvTrusShUfGnhHBafDsLdS1EhhxyL6BJQE+2cT3dDPAv+MQ6oLw==", + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -8338,6 +8448,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/workerpool": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", @@ -8403,12 +8522,6 @@ "node": ">=10" } }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", @@ -8474,12 +8587,6 @@ } }, "dependencies": { - "@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true - }, "@babel/code-frame": { "version": "7.24.2", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", @@ -8491,18 +8598,18 @@ } }, "@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.5.tgz", + "integrity": "sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA==", "dev": true }, "@babel/highlight": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", - "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.5.tgz", + "integrity": "sha512-8lLmua6AVh/8SLJRRVD6V8p73Hir9w5mJrhE+IPpILG31KKlI9iz5zmBYKcWPS59qSfgP9RaSBQSHHE81WKuEw==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-validator-identifier": "^7.24.5", "chalk": "^2.4.2", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" @@ -8567,15 +8674,15 @@ } }, "@babel/parser": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz", - "integrity": "sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.5.tgz", + "integrity": "sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==", "dev": true }, "@babel/runtime": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.4.tgz", - "integrity": "sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz", + "integrity": "sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==", "dev": true, "peer": true, "requires": { @@ -8616,163 +8723,163 @@ } }, "@esbuild/aix-ppc64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", - "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", + "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", "dev": true, "optional": true }, "@esbuild/android-arm": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", - "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", "dev": true, "optional": true }, "@esbuild/android-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", - "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", "dev": true, "optional": true }, "@esbuild/android-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", - "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", "dev": true, "optional": true }, "@esbuild/darwin-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", - "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", + "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", "dev": true, "optional": true }, "@esbuild/darwin-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", - "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", + "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", "dev": true, "optional": true }, "@esbuild/freebsd-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", - "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", "dev": true, "optional": true }, "@esbuild/freebsd-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", - "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", "dev": true, "optional": true }, "@esbuild/linux-arm": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", - "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", "dev": true, "optional": true }, "@esbuild/linux-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", - "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", "dev": true, "optional": true }, "@esbuild/linux-ia32": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", - "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", "dev": true, "optional": true }, "@esbuild/linux-loong64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", - "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", "dev": true, "optional": true }, "@esbuild/linux-mips64el": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", - "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", "dev": true, "optional": true }, "@esbuild/linux-ppc64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", - "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", "dev": true, "optional": true }, "@esbuild/linux-riscv64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", - "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", "dev": true, "optional": true }, "@esbuild/linux-s390x": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", - "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", "dev": true, "optional": true }, "@esbuild/linux-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", - "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", "dev": true, "optional": true }, "@esbuild/netbsd-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", - "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", "dev": true, "optional": true }, "@esbuild/openbsd-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", - "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", "dev": true, "optional": true }, "@esbuild/sunos-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", - "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", "dev": true, "optional": true }, "@esbuild/win32-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", - "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", "dev": true, "optional": true }, "@esbuild/win32-ia32": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", - "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", "dev": true, "optional": true }, "@esbuild/win32-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", - "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", + "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", "dev": true, "optional": true }, @@ -8806,6 +8913,27 @@ "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } } }, "@eslint/js": { @@ -8823,6 +8951,27 @@ "@humanwhocodes/object-schema": "^2.0.2", "debug": "^4.3.1", "minimatch": "^3.0.5" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } } }, "@humanwhocodes/module-importer": { @@ -9073,107 +9222,114 @@ } }, "@rollup/rollup-android-arm-eabi": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.14.1.tgz", - "integrity": "sha512-fH8/o8nSUek8ceQnT7K4EQbSiV7jgkHq81m9lWZFIXjJ7lJzpWXbQFpT/Zh6OZYnpFykvzC3fbEvEAFZu03dPA==", + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.17.2.tgz", + "integrity": "sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==", "dev": true, "optional": true }, "@rollup/rollup-android-arm64": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.14.1.tgz", - "integrity": "sha512-Y/9OHLjzkunF+KGEoJr3heiD5X9OLa8sbT1lm0NYeKyaM3oMhhQFvPB0bNZYJwlq93j8Z6wSxh9+cyKQaxS7PQ==", + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.17.2.tgz", + "integrity": "sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw==", "dev": true, "optional": true }, "@rollup/rollup-darwin-arm64": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.14.1.tgz", - "integrity": "sha512-+kecg3FY84WadgcuSVm6llrABOdQAEbNdnpi5X3UwWiFVhZIZvKgGrF7kmLguvxHNQy+UuRV66cLVl3S+Rkt+Q==", + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.17.2.tgz", + "integrity": "sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==", "dev": true, "optional": true }, "@rollup/rollup-darwin-x64": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.14.1.tgz", - "integrity": "sha512-2pYRzEjVqq2TB/UNv47BV/8vQiXkFGVmPFwJb+1E0IFFZbIX8/jo1olxqqMbo6xCXf8kabANhp5bzCij2tFLUA==", + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.17.2.tgz", + "integrity": "sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ==", "dev": true, "optional": true }, "@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.14.1.tgz", - "integrity": "sha512-mS6wQ6Do6/wmrF9aTFVpIJ3/IDXhg1EZcQFYHZLHqw6AzMBjTHWnCG35HxSqUNphh0EHqSM6wRTT8HsL1C0x5g==", + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.17.2.tgz", + "integrity": "sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm-musleabihf": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.17.2.tgz", + "integrity": "sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg==", "dev": true, "optional": true }, "@rollup/rollup-linux-arm64-gnu": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.14.1.tgz", - "integrity": "sha512-p9rGKYkHdFMzhckOTFubfxgyIO1vw//7IIjBBRVzyZebWlzRLeNhqxuSaZ7kCEKVkm/kuC9fVRW9HkC/zNRG2w==", + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.17.2.tgz", + "integrity": "sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==", "dev": true, "optional": true }, "@rollup/rollup-linux-arm64-musl": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.14.1.tgz", - "integrity": "sha512-nDY6Yz5xS/Y4M2i9JLQd3Rofh5OR8Bn8qe3Mv/qCVpHFlwtZSBYSPaU4mrGazWkXrdQ98GB//H0BirGR/SKFSw==", + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.17.2.tgz", + "integrity": "sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA==", "dev": true, "optional": true }, "@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.14.1.tgz", - "integrity": "sha512-im7HE4VBL+aDswvcmfx88Mp1soqL9OBsdDBU8NqDEYtkri0qV0THhQsvZtZeNNlLeCUQ16PZyv7cqutjDF35qw==", + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.17.2.tgz", + "integrity": "sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ==", "dev": true, "optional": true }, "@rollup/rollup-linux-riscv64-gnu": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.14.1.tgz", - "integrity": "sha512-RWdiHuAxWmzPJgaHJdpvUUlDz8sdQz4P2uv367T2JocdDa98iRw2UjIJ4QxSyt077mXZT2X6pKfT2iYtVEvOFw==", + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.17.2.tgz", + "integrity": "sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg==", "dev": true, "optional": true }, "@rollup/rollup-linux-s390x-gnu": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.14.1.tgz", - "integrity": "sha512-VMgaGQ5zRX6ZqV/fas65/sUGc9cPmsntq2FiGmayW9KMNfWVG/j0BAqImvU4KTeOOgYSf1F+k6at1UfNONuNjA==", + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.17.2.tgz", + "integrity": "sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g==", "dev": true, "optional": true }, "@rollup/rollup-linux-x64-gnu": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.14.1.tgz", - "integrity": "sha512-9Q7DGjZN+hTdJomaQ3Iub4m6VPu1r94bmK2z3UeWP3dGUecRC54tmVu9vKHTm1bOt3ASoYtEz6JSRLFzrysKlA==", + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz", + "integrity": "sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==", "dev": true, "optional": true }, "@rollup/rollup-linux-x64-musl": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.14.1.tgz", - "integrity": "sha512-JNEG/Ti55413SsreTguSx0LOVKX902OfXIKVg+TCXO6Gjans/k9O6ww9q3oLGjNDaTLxM+IHFMeXy/0RXL5R/g==", + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.17.2.tgz", + "integrity": "sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==", "dev": true, "optional": true }, "@rollup/rollup-win32-arm64-msvc": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.14.1.tgz", - "integrity": "sha512-ryS22I9y0mumlLNwDFYZRDFLwWh3aKaC72CWjFcFvxK0U6v/mOkM5Up1bTbCRAhv3kEIwW2ajROegCIQViUCeA==", + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.17.2.tgz", + "integrity": "sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA==", "dev": true, "optional": true }, "@rollup/rollup-win32-ia32-msvc": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.14.1.tgz", - "integrity": "sha512-TdloItiGk+T0mTxKx7Hp279xy30LspMso+GzQvV2maYePMAWdmrzqSNZhUpPj3CGw12aGj57I026PgLCTu8CGg==", + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.17.2.tgz", + "integrity": "sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ==", "dev": true, "optional": true }, "@rollup/rollup-win32-x64-msvc": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.14.1.tgz", - "integrity": "sha512-wQGI+LY/Py20zdUPq+XCem7JcPOyzIJBm3dli+56DJsQOHbnXZFEwgmnC6el1TPAfC8lBT3m+z69RmLykNUbew==", + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.17.2.tgz", + "integrity": "sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==", "dev": true, "optional": true }, @@ -9224,9 +9380,9 @@ "dev": true }, "@socket.io/component-emitter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", - "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", "dev": true }, "@tsconfig/node10": { @@ -9254,9 +9410,9 @@ "dev": true }, "@types/chai": { - "version": "4.3.14", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.14.tgz", - "integrity": "sha512-Wj71sXE4Q4AkGdG9Tvq1u/fquNz9EdG4LIJMwVVII7ashjD/8cf8fyIfJAjRr6YcsXnSE8cOGQPq1gqeR8z+3w==", + "version": "4.3.16", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.16.tgz", + "integrity": "sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ==", "dev": true }, "@types/cookie": { @@ -9286,13 +9442,6 @@ "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", "dev": true }, - "@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, - "peer": true - }, "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -9300,9 +9449,9 @@ "dev": true }, "@types/linkify-it": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.5.tgz", - "integrity": "sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", "dev": true }, "@types/markdown-it": { @@ -9316,15 +9465,15 @@ } }, "@types/mdurl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.5.tgz", - "integrity": "sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", "dev": true }, "@types/node": { - "version": "20.12.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.6.tgz", - "integrity": "sha512-3KurE8taB8GCvZBPngVbp0lk5CKi8M9f9k1rsADh0Evdz5SzJ+Q+Hx9uHoFGsLnLnd1xmkDQr2hVhlA0Mn0lKQ==", + "version": "20.12.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz", + "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==", "dev": true, "requires": { "undici-types": "~5.26.4" @@ -9342,167 +9491,102 @@ "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", "dev": true }, - "@types/semver": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", - "dev": true, - "peer": true - }, "@typescript-eslint/eslint-plugin": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.8.0.tgz", - "integrity": "sha512-gFTT+ezJmkwutUPmB0skOj3GZJtlEGnlssems4AjkVweUPGj7jRwwqg0Hhg7++kPGJqKtTYx+R05Ftww372aIg==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.9.0.tgz", + "integrity": "sha512-6e+X0X3sFe/G/54aC3jt0txuMTURqLyekmEHViqyA2VnxhLMpvA6nqmcjIy+Cr9tLDHPssA74BP5Mx9HQIxBEA==", "dev": true, "peer": true, "requires": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.8.0", - "@typescript-eslint/type-utils": "7.8.0", - "@typescript-eslint/utils": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0", - "debug": "^4.3.4", + "@typescript-eslint/scope-manager": "7.9.0", + "@typescript-eslint/type-utils": "7.9.0", + "@typescript-eslint/utils": "7.9.0", + "@typescript-eslint/visitor-keys": "7.9.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", - "semver": "^7.6.0", "ts-api-utils": "^1.3.0" - }, - "dependencies": { - "semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "peer": true, - "requires": { - "lru-cache": "^6.0.0" - } - } } }, "@typescript-eslint/parser": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.8.0.tgz", - "integrity": "sha512-KgKQly1pv0l4ltcftP59uQZCi4HUYswCLbTqVZEJu7uLX8CTLyswqMLqLN+2QFz4jCptqWVV4SB7vdxcH2+0kQ==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.9.0.tgz", + "integrity": "sha512-qHMJfkL5qvgQB2aLvhUSXxbK7OLnDkwPzFalg458pxQgfxKDfT1ZDbHQM/I6mDIf/svlMkj21kzKuQ2ixJlatQ==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "7.8.0", - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/typescript-estree": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0", + "@typescript-eslint/scope-manager": "7.9.0", + "@typescript-eslint/types": "7.9.0", + "@typescript-eslint/typescript-estree": "7.9.0", + "@typescript-eslint/visitor-keys": "7.9.0", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.8.0.tgz", - "integrity": "sha512-viEmZ1LmwsGcnr85gIq+FCYI7nO90DVbE37/ll51hjv9aG+YZMb4WDE2fyWpUR4O/UrhGRpYXK/XajcGTk2B8g==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.9.0.tgz", + "integrity": "sha512-ZwPK4DeCDxr3GJltRz5iZejPFAAr4Wk3+2WIBaj1L5PYK5RgxExu/Y68FFVclN0y6GGwH8q+KgKRCvaTmFBbgQ==", "dev": true, "requires": { - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0" + "@typescript-eslint/types": "7.9.0", + "@typescript-eslint/visitor-keys": "7.9.0" } }, "@typescript-eslint/type-utils": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.8.0.tgz", - "integrity": "sha512-H70R3AefQDQpz9mGv13Uhi121FNMh+WEaRqcXTX09YEDky21km4dV1ZXJIp8QjXc4ZaVkXVdohvWDzbnbHDS+A==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.9.0.tgz", + "integrity": "sha512-6Qy8dfut0PFrFRAZsGzuLoM4hre4gjzWJB6sUvdunCYZsYemTkzZNwF1rnGea326PHPT3zn5Lmg32M/xfJfByA==", "dev": true, "peer": true, "requires": { - "@typescript-eslint/typescript-estree": "7.8.0", - "@typescript-eslint/utils": "7.8.0", + "@typescript-eslint/typescript-estree": "7.9.0", + "@typescript-eslint/utils": "7.9.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" } }, "@typescript-eslint/types": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.8.0.tgz", - "integrity": "sha512-wf0peJ+ZGlcH+2ZS23aJbOv+ztjeeP8uQ9GgwMJGVLx/Nj9CJt17GWgWWoSmoRVKAX2X+7fzEnAjxdvK2gqCLw==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.9.0.tgz", + "integrity": "sha512-oZQD9HEWQanl9UfsbGVcZ2cGaR0YT5476xfWE0oE5kQa2sNK2frxOlkeacLOTh9po4AlUT5rtkGyYM5kew0z5w==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.8.0.tgz", - "integrity": "sha512-5pfUCOwK5yjPaJQNy44prjCwtr981dO8Qo9J9PwYXZ0MosgAbfEMB008dJ5sNo3+/BN6ytBPuSvXUg9SAqB0dg==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.9.0.tgz", + "integrity": "sha512-zBCMCkrb2YjpKV3LA0ZJubtKCDxLttxfdGmwZvTqqWevUPN0FZvSI26FalGFFUZU/9YQK/A4xcQF9o/VVaCKAg==", "dev": true, "requires": { - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0", + "@typescript-eslint/types": "7.9.0", + "@typescript-eslint/visitor-keys": "7.9.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^1.3.0" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - }, - "semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } } }, "@typescript-eslint/utils": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.8.0.tgz", - "integrity": "sha512-L0yFqOCflVqXxiZyXrDr80lnahQfSOfc9ELAAZ75sqicqp2i36kEZZGuUymHNFoYOqxRT05up760b4iGsl02nQ==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.9.0.tgz", + "integrity": "sha512-5KVRQCzZajmT4Ep+NEgjXCvjuypVvYHUW7RHlXzNPuak2oWpVoD1jf5xCP0dPAuNIchjC7uQyvbdaSTFaLqSdA==", "dev": true, "peer": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.15", - "@types/semver": "^7.5.8", - "@typescript-eslint/scope-manager": "7.8.0", - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/typescript-estree": "7.8.0", - "semver": "^7.6.0" - }, - "dependencies": { - "semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "peer": true, - "requires": { - "lru-cache": "^6.0.0" - } - } + "@typescript-eslint/scope-manager": "7.9.0", + "@typescript-eslint/types": "7.9.0", + "@typescript-eslint/typescript-estree": "7.9.0" } }, "@typescript-eslint/visitor-keys": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.8.0.tgz", - "integrity": "sha512-q4/gibTNBQNA0lGyYQCmWRS5D15n8rXh4QjK3KV+MBPlTYHpfBUT3D3PaPR/HeNiI9W6R7FvlkcGhNyAoP+caA==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.9.0.tgz", + "integrity": "sha512-iESPx2TNLDNGQLyjKhUvIKprlP49XNEK+MvIf9nIO7ZZaZdbnfWKHnXAgufpxqfA0YryH8XToi4+CjBgVnFTSQ==", "dev": true, "requires": { - "@typescript-eslint/types": "7.8.0", + "@typescript-eslint/types": "7.9.0", "eslint-visitor-keys": "^3.4.3" } }, @@ -9882,13 +9966,12 @@ } }, "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^1.0.0" } }, "braces": { @@ -10028,9 +10111,9 @@ } }, "chai-as-promised": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz", - "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.2.tgz", + "integrity": "sha512-aBDHZxRzYnUYuIAIPBH2s511DjlKPzXNlXSGFC8CwmroWQLfrW0LtE1nK3MAwwNhJPa9raEjNCmRoFpG0Hurdw==", "dev": true, "requires": { "check-error": "^1.0.2" @@ -10565,15 +10648,15 @@ "dev": true }, "es-iterator-helpers": { - "version": "1.0.18", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.18.tgz", - "integrity": "sha512-scxAJaewsahbqTYrGKJihhViaM6DDZDDoucfvzNbK0pOren1g/daDQ3IAhzn+1G14rBG7w+i5N+qul60++zlKA==", + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz", + "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==", "dev": true, "peer": true, "requires": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", + "es-abstract": "^1.23.3", "es-errors": "^1.3.0", "es-set-tostringtag": "^2.0.3", "function-bind": "^1.1.2", @@ -10643,34 +10726,34 @@ } }, "esbuild": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", - "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", + "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", "dev": true, "requires": { - "@esbuild/aix-ppc64": "0.19.12", - "@esbuild/android-arm": "0.19.12", - "@esbuild/android-arm64": "0.19.12", - "@esbuild/android-x64": "0.19.12", - "@esbuild/darwin-arm64": "0.19.12", - "@esbuild/darwin-x64": "0.19.12", - "@esbuild/freebsd-arm64": "0.19.12", - "@esbuild/freebsd-x64": "0.19.12", - "@esbuild/linux-arm": "0.19.12", - "@esbuild/linux-arm64": "0.19.12", - "@esbuild/linux-ia32": "0.19.12", - "@esbuild/linux-loong64": "0.19.12", - "@esbuild/linux-mips64el": "0.19.12", - "@esbuild/linux-ppc64": "0.19.12", - "@esbuild/linux-riscv64": "0.19.12", - "@esbuild/linux-s390x": "0.19.12", - "@esbuild/linux-x64": "0.19.12", - "@esbuild/netbsd-x64": "0.19.12", - "@esbuild/openbsd-x64": "0.19.12", - "@esbuild/sunos-x64": "0.19.12", - "@esbuild/win32-arm64": "0.19.12", - "@esbuild/win32-ia32": "0.19.12", - "@esbuild/win32-x64": "0.19.12" + "@esbuild/aix-ppc64": "0.20.2", + "@esbuild/android-arm": "0.20.2", + "@esbuild/android-arm64": "0.20.2", + "@esbuild/android-x64": "0.20.2", + "@esbuild/darwin-arm64": "0.20.2", + "@esbuild/darwin-x64": "0.20.2", + "@esbuild/freebsd-arm64": "0.20.2", + "@esbuild/freebsd-x64": "0.20.2", + "@esbuild/linux-arm": "0.20.2", + "@esbuild/linux-arm64": "0.20.2", + "@esbuild/linux-ia32": "0.20.2", + "@esbuild/linux-loong64": "0.20.2", + "@esbuild/linux-mips64el": "0.20.2", + "@esbuild/linux-ppc64": "0.20.2", + "@esbuild/linux-riscv64": "0.20.2", + "@esbuild/linux-s390x": "0.20.2", + "@esbuild/linux-x64": "0.20.2", + "@esbuild/netbsd-x64": "0.20.2", + "@esbuild/openbsd-x64": "0.20.2", + "@esbuild/sunos-x64": "0.20.2", + "@esbuild/win32-arm64": "0.20.2", + "@esbuild/win32-ia32": "0.20.2", + "@esbuild/win32-x64": "0.20.2" } }, "escalade": { @@ -10737,11 +10820,30 @@ "text-table": "^0.2.0" }, "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } } } }, @@ -10766,6 +10868,14 @@ "object.assign": "^4.1.2", "object.entries": "^1.1.5", "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true + } } }, "eslint-config-airbnb-typescript": { @@ -10866,6 +10976,16 @@ "tsconfig-paths": "^3.15.0" }, "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", @@ -10883,6 +11003,21 @@ "requires": { "esutils": "^2.0.2" } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true } } }, @@ -10909,6 +11044,29 @@ "minimatch": "^3.1.2", "object.entries": "^1.1.7", "object.fromentries": "^2.0.7" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "peer": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "peer": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } } }, "eslint-plugin-react": { @@ -10938,6 +11096,17 @@ "string.prototype.matchall": "^4.0.10" }, "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "peer": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", @@ -10948,6 +11117,16 @@ "esutils": "^2.0.2" } }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "peer": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, "resolve": { "version": "2.0.0-next.5", "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", @@ -10959,13 +11138,20 @@ "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" } + }, + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "peer": true } } }, "eslint-plugin-react-hooks": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", - "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", + "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", "dev": true, "peer": true, "requires": {} @@ -10991,17 +11177,6 @@ "regjsparser": "^0.10.0", "semver": "^7.5.4", "strip-indent": "^3.0.0" - }, - "dependencies": { - "semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } } }, "eslint-scope": { @@ -11359,9 +11534,9 @@ } }, "get-tsconfig": { - "version": "4.7.3", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz", - "integrity": "sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==", + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.5.tgz", + "integrity": "sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==", "dev": true, "requires": { "resolve-pkg-maps": "^1.0.0" @@ -11380,15 +11555,6 @@ "once": "^1.3.0" }, "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, "minimatch": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", @@ -11419,12 +11585,13 @@ } }, "globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", "dev": true, "requires": { - "define-properties": "^1.1.3" + "define-properties": "^1.2.1", + "gopd": "^1.0.1" } }, "globby": { @@ -12191,6 +12358,16 @@ "yargs": "^16.1.1" }, "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -12222,6 +12399,15 @@ "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", "dev": true }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, "mkdirp": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", @@ -12595,19 +12781,10 @@ "get-func-name": "^2.0.1" } }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, "magic-string": { - "version": "0.30.9", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.9.tgz", - "integrity": "sha512-S1+hd+dIrC8EZqKyT9DstTH/0Z+f76kmmvZnkfQVmOpDEF9iVgdYif3Q/pIWHmCoo59bQVGW0kVL3e2nl+9+Sw==", + "version": "0.30.10", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", + "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", "dev": true, "requires": { "@jridgewell/sourcemap-codec": "^1.4.15" @@ -12620,17 +12797,6 @@ "dev": true, "requires": { "semver": "^7.5.3" - }, - "dependencies": { - "semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } } }, "make-error": { @@ -12727,12 +12893,12 @@ "dev": true }, "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", "dev": true, "requires": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" } }, "minimist": { @@ -12775,15 +12941,6 @@ "yargs-unparser": "2.0.0" }, "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, "chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -13061,17 +13218,17 @@ "dev": true }, "optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "requires": { - "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" } }, "p-limit": { @@ -13177,9 +13334,9 @@ } }, "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", "dev": true }, "picomatch": { @@ -13195,13 +13352,13 @@ "dev": true }, "playwright": { - "version": "1.43.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.43.0.tgz", - "integrity": "sha512-SiOKHbVjTSf6wHuGCbqrEyzlm6qvXcv7mENP+OZon1I07brfZLGdfWV0l/efAzVx7TF3Z45ov1gPEkku9q25YQ==", + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.44.0.tgz", + "integrity": "sha512-F9b3GUCLQ3Nffrfb6dunPOkE5Mh68tR7zN32L4jCk4FjQamgesGay7/dAAe1WaMEGV04DkdJfcJzjoCKygUaRQ==", "dev": true, "requires": { "fsevents": "2.3.2", - "playwright-core": "1.43.0" + "playwright-core": "1.44.0" }, "dependencies": { "fsevents": { @@ -13214,9 +13371,9 @@ } }, "playwright-core": { - "version": "1.43.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.43.0.tgz", - "integrity": "sha512-iWFjyBUH97+pUFiyTqSLd8cDMMOS0r2ZYz2qEsPjH8/bX++sbIJT35MSwKnp1r/OQBAqC5XO99xFbJ9XClhf4w==", + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.44.0.tgz", + "integrity": "sha512-ZTbkNpFfYcGWohvTTl+xewITm7EOuqIqex0c7dNZ+aXsbrLj0qI8XlGKfPpipjm0Wny/4Lt4CJsWJk1stVS5qQ==", "dev": true }, "pluralize": { @@ -13564,6 +13721,16 @@ "glob": "^7.1.3" }, "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -13577,30 +13744,40 @@ "once": "^1.3.0", "path-is-absolute": "^1.0.0" } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } } } }, "rollup": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.14.1.tgz", - "integrity": "sha512-4LnHSdd3QK2pa1J6dFbfm1HN0D7vSK/ZuZTsdyUAlA6Rr1yTouUTL13HaDOGJVgby461AhrNGBS7sCGXXtT+SA==", + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.17.2.tgz", + "integrity": "sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==", "dev": true, "requires": { - "@rollup/rollup-android-arm-eabi": "4.14.1", - "@rollup/rollup-android-arm64": "4.14.1", - "@rollup/rollup-darwin-arm64": "4.14.1", - "@rollup/rollup-darwin-x64": "4.14.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.14.1", - "@rollup/rollup-linux-arm64-gnu": "4.14.1", - "@rollup/rollup-linux-arm64-musl": "4.14.1", - "@rollup/rollup-linux-powerpc64le-gnu": "4.14.1", - "@rollup/rollup-linux-riscv64-gnu": "4.14.1", - "@rollup/rollup-linux-s390x-gnu": "4.14.1", - "@rollup/rollup-linux-x64-gnu": "4.14.1", - "@rollup/rollup-linux-x64-musl": "4.14.1", - "@rollup/rollup-win32-arm64-msvc": "4.14.1", - "@rollup/rollup-win32-ia32-msvc": "4.14.1", - "@rollup/rollup-win32-x64-msvc": "4.14.1", + "@rollup/rollup-android-arm-eabi": "4.17.2", + "@rollup/rollup-android-arm64": "4.17.2", + "@rollup/rollup-darwin-arm64": "4.17.2", + "@rollup/rollup-darwin-x64": "4.17.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.17.2", + "@rollup/rollup-linux-arm-musleabihf": "4.17.2", + "@rollup/rollup-linux-arm64-gnu": "4.17.2", + "@rollup/rollup-linux-arm64-musl": "4.17.2", + "@rollup/rollup-linux-powerpc64le-gnu": "4.17.2", + "@rollup/rollup-linux-riscv64-gnu": "4.17.2", + "@rollup/rollup-linux-s390x-gnu": "4.17.2", + "@rollup/rollup-linux-x64-gnu": "4.17.2", + "@rollup/rollup-linux-x64-musl": "4.17.2", + "@rollup/rollup-win32-arm64-msvc": "4.17.2", + "@rollup/rollup-win32-ia32-msvc": "4.17.2", + "@rollup/rollup-win32-x64-msvc": "4.17.2", "@types/estree": "1.0.5", "fsevents": "~2.3.2" } @@ -13656,9 +13833,9 @@ "dev": true }, "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true }, "serialize-javascript": { @@ -14027,6 +14204,16 @@ "rimraf": "~2.5.2" }, "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -14041,6 +14228,15 @@ "path-is-absolute": "^1.0.0" } }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, "rimraf": { "version": "2.5.4", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz", @@ -14053,9 +14249,9 @@ } }, "terser": { - "version": "5.30.3", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.30.3.tgz", - "integrity": "sha512-STdUgOUx8rLbMGO9IOwHLpCqolkDITFFQSMYYwKE1N2lY6MVSaeoi10z/EhWxRc6ybqoVmKSkhKYH/XUpl7vSA==", + "version": "5.31.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.0.tgz", + "integrity": "sha512-Q1JFAoUKE5IMfI4Z/lkE/E6+SwgzO+x4tq4v1AyBLRj8VSYvRO6A/rQrPg1yud4g0En9EKI1TvFRF2tQFcoUkg==", "dev": true, "requires": { "@jridgewell/source-map": "^0.3.3", @@ -14083,6 +14279,16 @@ "minimatch": "^3.0.4" }, "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -14096,6 +14302,15 @@ "once": "^1.3.0", "path-is-absolute": "^1.0.0" } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } } } }, @@ -14187,14 +14402,14 @@ "dev": true }, "tsx": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.2.tgz", - "integrity": "sha512-BCNd4kz6fz12fyrgCTEdZHGJ9fWTGeUzXmQysh0RVocDY3h4frk05ZNCXSy4kIenF7y/QnrdiVpTsyNRn6vlAw==", + "version": "4.10.4", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.10.4.tgz", + "integrity": "sha512-Gtg9qnZWNqC/OtcgiXfoAUdAKx3/cgKOYvEocAsv+m21MV/eKpV/WUjRXe6/sDCaGBl2/v8S6v29BpUnGMCX5A==", "dev": true, "requires": { - "esbuild": "~0.19.10", + "esbuild": "~0.20.2", "fsevents": "~2.3.3", - "get-tsconfig": "^4.7.2" + "get-tsconfig": "^4.7.5" } }, "type-check": { @@ -14281,9 +14496,9 @@ } }, "typescript": { - "version": "5.4.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.4.tgz", - "integrity": "sha512-dGE2Vv8cpVvw28v8HCPqyb08EzbBURxDpuhJvTrusShUfGnhHBafDsLdS1EhhxyL6BJQE+2cT3dDPAv+MQ6oLw==", + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", "dev": true }, "ua-parser-js": { @@ -14504,6 +14719,12 @@ "has-tostringtag": "^1.0.2" } }, + "word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true + }, "workerpool": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", @@ -14546,12 +14767,6 @@ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", diff --git a/package.json b/package.json index f3fd019d..6ec3487a 100644 --- a/package.json +++ b/package.json @@ -62,8 +62,8 @@ "postversion": "git push && git push --tags && npm publish" }, "devDependencies": { - "@noble/curves": "^1.3.0", - "@noble/hashes": "^1.3.3", + "@noble/curves": "^1.4.0", + "@noble/hashes": "^1.4.0", "@openpgp/asmcrypto.js": "^3.1.0", "@openpgp/jsdoc": "^3.6.11", "@openpgp/seek-bzip": "^1.0.5-git", @@ -76,14 +76,14 @@ "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-typescript": "^11.1.6", "@rollup/plugin-wasm": "^6.2.2", - "@types/chai": "^4.3.14", - "@typescript-eslint/parser": "^7.8.0", + "@types/chai": "^4.3.16", + "@typescript-eslint/parser": "^7.9.0", "argon2id": "^1.0.1", "benchmark": "^2.1.4", "bn.js": "^5.2.1", "c8": "^8.0.1", "chai": "^4.4.1", - "chai-as-promised": "^7.1.1", + "chai-as-promised": "^7.1.2", "eckey-utils": "^0.7.14", "eslint": "^8.57.0", "eslint-config-airbnb": "^19.0.4", @@ -103,13 +103,13 @@ "karma-mocha-reporter": "^2.2.5", "karma-webkit-launcher": "^2.4.0", "mocha": "^10.4.0", - "playwright": "^1.43.0", - "rollup": "^4.14.1", + "playwright": "^1.44.0", + "rollup": "^4.17.2", "sinon": "^17.0.1", "ts-node": "^10.9.2", "tslib": "^2.6.2", - "tsx": "^4.7.2", - "typescript": "^5.4.4", + "tsx": "^4.10.4", + "typescript": "^5.4.5", "web-streams-polyfill": "^3.3.3" }, "repository": { From d138b5290b1be04e0dbc095ee5a118103a0b9c73 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Fri, 17 May 2024 14:13:46 +0200 Subject: [PATCH 140/201] 6.0.0-beta.1 --- docs/AEADEncryptedDataPacket.html | 16 +- docs/Argon2S2K.html | 18 +- docs/CleartextMessage.html | 14 +- docs/CompressedDataPacket.html | 18 +- docs/Key.html | 58 +- docs/LiteralDataPacket.html | 22 +- docs/MarkerPacket.html | 6 +- docs/Message.html | 42 +- docs/OnePassSignaturePacket.html | 24 +- docs/PacketList.html | 16 +- docs/PaddingPacket.html | 10 +- docs/PrivateKey.html | 22 +- docs/PublicKey.html | 10 +- docs/PublicKeyEncryptedSessionKeyPacket.html | 16 +- docs/PublicKeyPacket.html | 48 +- docs/PublicSubkeyPacket.html | 48 +- docs/SecretKeyPacket.html | 74 +- docs/SecretSubkeyPacket.html | 74 +- docs/Signature.html | 10 +- docs/SignaturePacket.html | 26 +- ...EncryptedIntegrityProtectedDataPacket.html | 12 +- docs/SymEncryptedSessionKeyPacket.html | 18 +- docs/SymmetricallyEncryptedDataPacket.html | 12 +- docs/TrustPacket.html | 6 +- docs/UserAttributePacket.html | 10 +- docs/UserIDPacket.html | 12 +- docs/global.html | 171 +--- docs/index.html | 2 +- docs/module-config.html | 68 +- docs/module-crypto.html | 4 +- docs/module-crypto_aes_kw.html | 8 +- docs/module-crypto_cmac.html | 8 +- docs/module-crypto_crypto.html | 32 +- docs/module-crypto_hash.html | 10 +- docs/module-crypto_hkdf.html | 4 +- docs/module-crypto_mode.html | 12 +- docs/module-crypto_mode_cfb.html | 6 +- docs/module-crypto_mode_eax.html | 10 +- docs/module-crypto_mode_gcm.html | 6 +- docs/module-crypto_mode_ocb.html | 10 +- docs/module-crypto_pkcs1.html | 12 +- docs/module-crypto_public_key.html | 12 +- docs/module-crypto_public_key_dsa.html | 12 +- docs/module-crypto_public_key_elgamal.html | 12 +- docs/module-crypto_public_key_elliptic.html | 4 +- ...dule-crypto_public_key_elliptic_curve.html | 14 +- ...odule-crypto_public_key_elliptic_ecdh.html | 62 +- ...dule-crypto_public_key_elliptic_ecdsa.html | 12 +- ...dule-crypto_public_key_elliptic_eddsa.html | 12 +- ...ypto_public_key_elliptic_eddsa_legacy.html | 10 +- docs/module-crypto_public_key_prime.html | 954 ------------------ docs/module-crypto_public_key_rsa.html | 24 +- docs/module-crypto_random.html | 20 +- docs/module-crypto_signature.html | 10 +- docs/module-encoding_base64.html | 10 +- docs/module-enums.html | 38 +- docs/module-key_Subkey-Subkey.html | 42 +- docs/module-key_Subkey.html | 2 +- docs/module-key_User-User.html | 22 +- docs/module-key_User.html | 2 +- docs/module-key_helper.html | 24 +- docs/module-packet_packet.html | 12 +- docs/module-type_ecdh_symkey.html | 4 +- docs/module-type_kdf_params-KDFParams.html | 8 +- docs/module-type_keyid-KeyID.html | 16 +- docs/module-type_keyid.html | 2 +- docs/module-type_oid.html | 4 +- docs/module-type_s2k-GenericS2K.html | 18 +- docs/module-type_s2k.html | 4 +- docs/module-type_x25519x448_symkey.html | 4 +- docs/module-util.html | 4 +- package-lock.json | 4 +- package.json | 2 +- 73 files changed, 667 insertions(+), 1718 deletions(-) delete mode 100644 docs/module-crypto_public_key_prime.html diff --git a/docs/AEADEncryptedDataPacket.html b/docs/AEADEncryptedDataPacket.html index f692a3c7..8a6baa7a 100644 --- a/docs/AEADEncryptedDataPacket.html +++ b/docs/AEADEncryptedDataPacket.html @@ -98,7 +98,7 @@ AEAD Protected Data Packet

    Source:
    @@ -200,7 +200,7 @@ AEAD Protected Data Packet

    Source:
    @@ -270,7 +270,7 @@ AEAD Protected Data Packet

    Source:
    @@ -475,7 +475,7 @@ AEAD Protected Data Packet

    Source:
    @@ -717,7 +717,7 @@ AEAD Protected Data Packet

    Source:
    @@ -888,7 +888,7 @@ AEAD Protected Data Packet

    Source:
    @@ -1007,7 +1007,7 @@ AEAD Protected Data Packet

    Source:
    @@ -1078,7 +1078,7 @@ AEAD Protected Data Packet


    diff --git a/docs/Argon2S2K.html b/docs/Argon2S2K.html index 1b5abb82..75c3302a 100644 --- a/docs/Argon2S2K.html +++ b/docs/Argon2S2K.html @@ -152,7 +152,7 @@
    Source:
    @@ -258,7 +258,7 @@
    Source:
    @@ -332,7 +332,7 @@
    Source:
    @@ -406,7 +406,7 @@
    Source:
    @@ -480,7 +480,7 @@
    Source:
    @@ -612,7 +612,7 @@ hashAlgorithm

    Source:
    @@ -791,7 +791,7 @@ hashAlgorithm

    Source:
    @@ -903,7 +903,7 @@ hashAlgorithm

    Source:
    @@ -971,7 +971,7 @@ hashAlgorithm


    diff --git a/docs/CleartextMessage.html b/docs/CleartextMessage.html index f97d89f9..8ec800a1 100644 --- a/docs/CleartextMessage.html +++ b/docs/CleartextMessage.html @@ -168,7 +168,7 @@ See https://tools.ietf.o
    Source:
    @@ -346,7 +346,7 @@ See https://tools.ietf.o
    Source:
    @@ -461,7 +461,7 @@ See https://tools.ietf.o
    Source:
    @@ -573,7 +573,7 @@ See https://tools.ietf.o
    Source:
    @@ -974,7 +974,7 @@ See https://tools.ietf.o
    Source:
    @@ -1211,7 +1211,7 @@ See https://tools.ietf.o
    Source:
    @@ -1279,7 +1279,7 @@ See https://tools.ietf.o
    diff --git a/docs/CompressedDataPacket.html b/docs/CompressedDataPacket.html index 2fdb293d..2ed1a205 100644 --- a/docs/CompressedDataPacket.html +++ b/docs/CompressedDataPacket.html @@ -160,7 +160,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

    Source:
    @@ -266,7 +266,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

    Source:
    @@ -343,7 +343,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

    Source:
    @@ -417,7 +417,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

    Source:
    @@ -499,7 +499,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

    Source:
    @@ -651,7 +651,7 @@ read by read_packet

    Source:
    @@ -836,7 +836,7 @@ read by read_packet

    Source:
    @@ -926,7 +926,7 @@ read by read_packet

    Source:
    @@ -997,7 +997,7 @@ read by read_packet


    diff --git a/docs/Key.html b/docs/Key.html index 317b2770..318afac0 100644 --- a/docs/Key.html +++ b/docs/Key.html @@ -96,7 +96,7 @@ Can contain additional subkeys, signatures, user ids, user attributes.

    Source:
    @@ -333,7 +333,7 @@ if it is a valid revocation signature.

    Source:
    @@ -514,7 +514,7 @@ if it is a valid revocation signature.

    Source:
    @@ -626,7 +626,7 @@ if it is a valid revocation signature.

    Source:
    @@ -738,7 +738,7 @@ if it is a valid revocation signature.

    Source:
    @@ -1006,7 +1006,7 @@ if it is a valid revocation signature.

    Source:
    @@ -1225,7 +1225,7 @@ Returns Infinity if the key doesn't expire, or null if
    Source:
    @@ -1333,7 +1333,7 @@ Returns Infinity if the key doesn't expire, or null if
    Source:
    @@ -1445,7 +1445,7 @@ Returns Infinity if the key doesn't expire, or null if
    Source:
    @@ -1557,7 +1557,7 @@ Returns Infinity if the key doesn't expire, or null if
    Source:
    @@ -1735,7 +1735,7 @@ If no keyID is given, returns all keys, starting with the primary key.

    Source:
    @@ -1977,7 +1977,7 @@ algorithm preferences, and so on.

    Source:
    @@ -2220,7 +2220,7 @@ algorithm preferences, and so on.

    Source:
    @@ -2425,7 +2425,7 @@ algorithm preferences, and so on.

    Source:
    @@ -2717,7 +2717,7 @@ algorithm preferences, and so on.

    Source:
    @@ -2911,7 +2911,7 @@ If no keyID is given, returns all subkeys.

    Source:
    @@ -3023,7 +3023,7 @@ If no keyID is given, returns all subkeys.

    Source:
    @@ -3135,7 +3135,7 @@ If no keyID is given, returns all subkeys.

    Source:
    @@ -3412,7 +3412,7 @@ If no keyID is given, returns all subkeys.

    Source:
    @@ -3596,7 +3596,7 @@ If no keyID is given, returns all subkeys.

    Source:
    @@ -3811,7 +3811,7 @@ If no keyID is given, returns all subkeys.

    Source:
    @@ -4081,7 +4081,7 @@ If no keyID is given, returns all subkeys.

    Source:
    @@ -4193,7 +4193,7 @@ If no keyID is given, returns all subkeys.

    Source:
    @@ -4434,7 +4434,7 @@ a private key is returned.

    Source:
    @@ -4677,7 +4677,7 @@ a private key is returned.

    Source:
    @@ -4918,7 +4918,7 @@ and valid self signature. Throws if the primary key is invalid.

    Source:
    @@ -5201,7 +5201,7 @@ and valid self signature. Throws if the primary key is invalid.

    Source:
    @@ -5314,7 +5314,7 @@ Signature validity is null if the verification keys do not correspond to the cer
    Source:
    @@ -5382,7 +5382,7 @@ Signature validity is null if the verification keys do not correspond to the cer
    diff --git a/docs/LiteralDataPacket.html b/docs/LiteralDataPacket.html index 479deced..277ed5c7 100644 --- a/docs/LiteralDataPacket.html +++ b/docs/LiteralDataPacket.html @@ -147,7 +147,7 @@ further interpreted.

    Source:
    @@ -326,7 +326,7 @@ further interpreted.

    Source:
    @@ -441,7 +441,7 @@ further interpreted.

    Source:
    @@ -623,7 +623,7 @@ with normalized end of line to \n

    Source:
    @@ -790,7 +790,7 @@ with normalized end of line to \n

    Source:
    @@ -977,7 +977,7 @@ with normalized end of line to \n

    Source:
    @@ -1116,7 +1116,7 @@ with normalized end of line to \n

    Source:
    @@ -1302,7 +1302,7 @@ will be normalized to \r\n and by default text is converted to UTF8

    Source:
    @@ -1392,7 +1392,7 @@ will be normalized to \r\n and by default text is converted to UTF8

    Source:
    @@ -1507,7 +1507,7 @@ will be normalized to \r\n and by default text is converted to UTF8

    Source:
    @@ -1575,7 +1575,7 @@ will be normalized to \r\n and by default text is converted to UTF8


    diff --git a/docs/MarkerPacket.html b/docs/MarkerPacket.html index 0a691c46..0c12f8da 100644 --- a/docs/MarkerPacket.html +++ b/docs/MarkerPacket.html @@ -106,7 +106,7 @@ software is necessary to process the message.

    Source:
    @@ -265,7 +265,7 @@ software is necessary to process the message.

    Source:
    @@ -333,7 +333,7 @@ software is necessary to process the message.


    diff --git a/docs/Message.html b/docs/Message.html index 8fed6b4b..46a3bda5 100644 --- a/docs/Message.html +++ b/docs/Message.html @@ -146,7 +146,7 @@ See https://tools.iet
    Source:
    @@ -661,7 +661,7 @@ See https://tools.iet
    Source:
    @@ -933,7 +933,7 @@ See https://tools.iet
    Source:
    @@ -1140,7 +1140,7 @@ See https://tools.iet
    Source:
    @@ -1291,7 +1291,7 @@ See https://tools.iet
    Source:
    @@ -1495,7 +1495,7 @@ See https://tools.iet
    Source:
    @@ -1800,7 +1800,7 @@ See https://tools.iet
    Source:
    @@ -2105,7 +2105,7 @@ See https://tools.iet
    Source:
    @@ -2545,7 +2545,7 @@ See https://tools.iet
    Source:
    @@ -2657,7 +2657,7 @@ See https://tools.iet
    Source:
    @@ -2769,7 +2769,7 @@ See https://tools.iet
    Source:
    @@ -2884,7 +2884,7 @@ See https://tools.iet
    Source:
    @@ -2999,7 +2999,7 @@ See https://tools.iet
    Source:
    @@ -3111,7 +3111,7 @@ See https://tools.iet
    Source:
    @@ -3515,7 +3515,7 @@ See https://tools.iet
    Source:
    @@ -3916,7 +3916,7 @@ See https://tools.iet
    Source:
    @@ -4028,7 +4028,7 @@ See https://tools.iet
    Source:
    @@ -4265,7 +4265,7 @@ See https://tools.iet
    Source:
    @@ -4531,7 +4531,7 @@ See https://tools.iet
    Source:
    @@ -4643,7 +4643,7 @@ See https://tools.iet
    Source:
    @@ -4711,7 +4711,7 @@ See https://tools.iet
    diff --git a/docs/OnePassSignaturePacket.html b/docs/OnePassSignaturePacket.html index dca8a390..a496eef1 100644 --- a/docs/OnePassSignaturePacket.html +++ b/docs/OnePassSignaturePacket.html @@ -101,7 +101,7 @@ can compute the entire signed message in one pass.

    Source:
    @@ -199,7 +199,7 @@ that describes another signature to be applied to the same message data.

    Source:
    @@ -273,7 +273,7 @@ that describes another signature to be applied to the same message data.

    Source:
    @@ -344,7 +344,7 @@ that describes another signature to be applied to the same message data.

    Source:
    @@ -408,7 +408,7 @@ that describes another signature to be applied to the same message data.

    Source:
    @@ -482,7 +482,7 @@ that describes another signature to be applied to the same message data.

    Source:
    @@ -553,7 +553,7 @@ that describes another signature to be applied to the same message data.

    Source:
    @@ -629,7 +629,7 @@ Signature types are described in
    Source:
    @@ -693,7 +693,7 @@ Signature types are described in
    Source:
    @@ -824,7 +824,7 @@ Signature types are described in
    Source:
    @@ -936,7 +936,7 @@ Signature types are described in
    Source:
    @@ -1004,7 +1004,7 @@ Signature types are described in
    diff --git a/docs/PacketList.html b/docs/PacketList.html index 517d93ce..7be051f7 100644 --- a/docs/PacketList.html +++ b/docs/PacketList.html @@ -97,7 +97,7 @@ are stored as numerical indices.

    Source:
    @@ -345,7 +345,7 @@ Equivalent to calling read on an empty PacketList instance.

    Source:
    @@ -530,7 +530,7 @@ Equivalent to calling read on an empty PacketList instance.

    Source:
    @@ -687,7 +687,7 @@ Equivalent to calling read on an empty PacketList instance.

    Source:
    @@ -859,7 +859,7 @@ Equivalent to calling read on an empty PacketList instance.

    Source:
    @@ -1097,7 +1097,7 @@ Equivalent to calling read on an empty PacketList instance.

    Source:
    @@ -1200,7 +1200,7 @@ class instance.

    Source:
    @@ -1268,7 +1268,7 @@ class instance.


    diff --git a/docs/PaddingPacket.html b/docs/PaddingPacket.html index 7fc377e0..2a9d6ffe 100644 --- a/docs/PaddingPacket.html +++ b/docs/PaddingPacket.html @@ -97,7 +97,7 @@ Padding Packet

    Source:
    @@ -256,7 +256,7 @@ Padding Packet

    Source:
    @@ -427,7 +427,7 @@ Padding Packet

    Source:
    @@ -517,7 +517,7 @@ Padding Packet

    Source:
    @@ -585,7 +585,7 @@ Padding Packet


    diff --git a/docs/PrivateKey.html b/docs/PrivateKey.html index b9009da2..a24cfeb2 100644 --- a/docs/PrivateKey.html +++ b/docs/PrivateKey.html @@ -144,7 +144,7 @@
    Source:
    @@ -453,7 +453,7 @@ Note: Curve448 and Curve25519 are not widely supported yet.

    Source:
    @@ -622,7 +622,7 @@ Note: Curve448 and Curve25519 are not widely supported yet.

    Source:
    @@ -734,7 +734,7 @@ Note: Curve448 and Curve25519 are not widely supported yet.

    Source:
    @@ -979,7 +979,7 @@ This is useful to retrieve keys for session key decryption

    Source:
    @@ -1092,7 +1092,7 @@ A dummy key is considered encrypted.

    Source:
    @@ -1182,7 +1182,7 @@ A dummy key is considered encrypted.

    Source:
    @@ -1485,7 +1485,7 @@ A dummy key is considered encrypted.

    Source:
    @@ -1597,7 +1597,7 @@ A dummy key is considered encrypted.

    Source:
    @@ -1774,7 +1774,7 @@ If only gnu-dummy keys are found, we cannot properly validate so we throw an err
    Source:
    @@ -1849,7 +1849,7 @@ If only gnu-dummy keys are found, we cannot properly validate so we throw an err
    diff --git a/docs/PublicKey.html b/docs/PublicKey.html index 2fcd3fa4..0a180563 100644 --- a/docs/PublicKey.html +++ b/docs/PublicKey.html @@ -144,7 +144,7 @@
    Source:
    @@ -315,7 +315,7 @@
    Source:
    @@ -427,7 +427,7 @@
    Source:
    @@ -535,7 +535,7 @@
    Source:
    @@ -603,7 +603,7 @@
    diff --git a/docs/PublicKeyEncryptedSessionKeyPacket.html b/docs/PublicKeyEncryptedSessionKeyPacket.html index 68277ee5..6ea55a7a 100644 --- a/docs/PublicKeyEncryptedSessionKeyPacket.html +++ b/docs/PublicKeyEncryptedSessionKeyPacket.html @@ -107,7 +107,7 @@ decrypt the message.

    Source:
    @@ -209,7 +209,7 @@ decrypt the message.

    Source:
    @@ -283,7 +283,7 @@ decrypt the message.

    Source:
    @@ -458,7 +458,7 @@ This is needed for constant-time processing. Expected object of the form: { sess
    Source:
    @@ -626,7 +626,7 @@ This is needed for constant-time processing. Expected object of the form: { sess
    Source:
    @@ -794,7 +794,7 @@ This is needed for constant-time processing. Expected object of the form: { sess
    Source:
    @@ -884,7 +884,7 @@ This is needed for constant-time processing. Expected object of the form: { sess
    Source:
    @@ -952,7 +952,7 @@ This is needed for constant-time processing. Expected object of the form: { sess
    diff --git a/docs/PublicKeyPacket.html b/docs/PublicKeyPacket.html index 8911f59c..57e505d4 100644 --- a/docs/PublicKeyPacket.html +++ b/docs/PublicKeyPacket.html @@ -195,7 +195,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -301,7 +301,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -375,7 +375,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -449,7 +449,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -523,7 +523,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -597,7 +597,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -671,7 +671,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -735,7 +735,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -816,7 +816,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -880,7 +880,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -1018,7 +1018,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -1130,7 +1130,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -1220,7 +1220,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -1310,7 +1310,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -1422,7 +1422,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -1530,7 +1530,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -1642,7 +1642,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -1754,7 +1754,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -1866,7 +1866,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -1978,7 +1978,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -2138,7 +2138,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -2250,7 +2250,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -2411,7 +2411,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -2457,7 +2457,7 @@ key (sometimes called an OpenPGP certificate).


    diff --git a/docs/PublicSubkeyPacket.html b/docs/PublicSubkeyPacket.html index bae6870f..1b3a2f10 100644 --- a/docs/PublicSubkeyPacket.html +++ b/docs/PublicSubkeyPacket.html @@ -193,7 +193,7 @@ services.

    Source:
    @@ -315,7 +315,7 @@ services.

    Source:
    @@ -394,7 +394,7 @@ services.

    Source:
    @@ -473,7 +473,7 @@ services.

    Source:
    @@ -552,7 +552,7 @@ services.

    Source:
    @@ -631,7 +631,7 @@ services.

    Source:
    @@ -710,7 +710,7 @@ services.

    Source:
    @@ -779,7 +779,7 @@ services.

    Source:
    @@ -865,7 +865,7 @@ services.

    Source:
    @@ -934,7 +934,7 @@ services.

    Source:
    @@ -1072,7 +1072,7 @@ services.

    Source:
    @@ -1189,7 +1189,7 @@ services.

    Source:
    @@ -1284,7 +1284,7 @@ services.

    Source:
    @@ -1379,7 +1379,7 @@ services.

    Source:
    @@ -1496,7 +1496,7 @@ services.

    Source:
    @@ -1609,7 +1609,7 @@ services.

    Source:
    @@ -1726,7 +1726,7 @@ services.

    Source:
    @@ -1843,7 +1843,7 @@ services.

    Source:
    @@ -1960,7 +1960,7 @@ services.

    Source:
    @@ -2077,7 +2077,7 @@ services.

    Source:
    @@ -2242,7 +2242,7 @@ services.

    Source:
    @@ -2359,7 +2359,7 @@ services.

    Source:
    @@ -2525,7 +2525,7 @@ services.

    Source:
    @@ -2571,7 +2571,7 @@ services.


    diff --git a/docs/SecretKeyPacket.html b/docs/SecretKeyPacket.html index c656a40a..4eebe280 100644 --- a/docs/SecretKeyPacket.html +++ b/docs/SecretKeyPacket.html @@ -191,7 +191,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -308,7 +308,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -387,7 +387,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -466,7 +466,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -545,7 +545,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -624,7 +624,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -688,7 +688,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -767,7 +767,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -831,7 +831,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -905,7 +905,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -984,7 +984,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -1053,7 +1053,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -1134,7 +1134,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -1208,7 +1208,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -1282,7 +1282,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -1361,7 +1361,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -1430,7 +1430,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -1519,7 +1519,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -1614,7 +1614,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -1709,7 +1709,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -1851,7 +1851,7 @@ otherwise calls to this function will throw an error.

    Source:
    @@ -2065,7 +2065,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2189,7 +2189,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2306,7 +2306,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2419,7 +2419,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2536,7 +2536,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2653,7 +2653,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2770,7 +2770,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2888,7 +2888,7 @@ Returns false for gnu-dummy keys and null for public keys.

    Source:
    @@ -2999,7 +2999,7 @@ Returns false for gnu-dummy keys and null for public keys.

    Source:
    @@ -3114,7 +3114,7 @@ Such keys are:

    Source:
    @@ -3266,7 +3266,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
    Source:
    @@ -3411,7 +3411,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
    Source:
    @@ -3501,7 +3501,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
    Source:
    @@ -3625,7 +3625,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
    Source:
    @@ -3791,7 +3791,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
    Source:
    @@ -3837,7 +3837,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
    diff --git a/docs/SecretSubkeyPacket.html b/docs/SecretSubkeyPacket.html index dcd51ea2..ee0599fb 100644 --- a/docs/SecretSubkeyPacket.html +++ b/docs/SecretSubkeyPacket.html @@ -190,7 +190,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -312,7 +312,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -391,7 +391,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -470,7 +470,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -549,7 +549,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -628,7 +628,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -697,7 +697,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -776,7 +776,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -845,7 +845,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -924,7 +924,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -1003,7 +1003,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -1072,7 +1072,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -1158,7 +1158,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -1237,7 +1237,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -1316,7 +1316,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -1395,7 +1395,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -1464,7 +1464,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -1558,7 +1558,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -1653,7 +1653,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -1748,7 +1748,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -1895,7 +1895,7 @@ otherwise calls to this function will throw an error.

    Source:
    @@ -2114,7 +2114,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2238,7 +2238,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2355,7 +2355,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2468,7 +2468,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2585,7 +2585,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2702,7 +2702,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2819,7 +2819,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2937,7 +2937,7 @@ Returns false for gnu-dummy keys and null for public keys.

    Source:
    @@ -3053,7 +3053,7 @@ Returns false for gnu-dummy keys and null for public keys.

    Source:
    @@ -3173,7 +3173,7 @@ Such keys are:

    Source:
    @@ -3330,7 +3330,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
    Source:
    @@ -3475,7 +3475,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
    Source:
    @@ -3570,7 +3570,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
    Source:
    @@ -3694,7 +3694,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
    Source:
    @@ -3860,7 +3860,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
    Source:
    @@ -3906,7 +3906,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
    diff --git a/docs/Signature.html b/docs/Signature.html index 4cda6dc7..4582acd6 100644 --- a/docs/Signature.html +++ b/docs/Signature.html @@ -144,7 +144,7 @@
    Source:
    @@ -322,7 +322,7 @@
    Source:
    @@ -434,7 +434,7 @@
    Source:
    @@ -546,7 +546,7 @@
    Source:
    @@ -614,7 +614,7 @@
    diff --git a/docs/SignaturePacket.html b/docs/SignaturePacket.html index 1fb31bff..f66bdac0 100644 --- a/docs/SignaturePacket.html +++ b/docs/SignaturePacket.html @@ -99,7 +99,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    @@ -201,7 +201,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    @@ -271,7 +271,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    @@ -341,7 +341,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    @@ -423,7 +423,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    @@ -599,7 +599,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    @@ -760,7 +760,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    @@ -1048,7 +1048,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    @@ -1427,7 +1427,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    @@ -1546,7 +1546,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    @@ -1654,7 +1654,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    @@ -1765,7 +1765,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    @@ -1833,7 +1833,7 @@ block of text, and a signature that is a certification of a User ID.


    diff --git a/docs/SymEncryptedIntegrityProtectedDataPacket.html b/docs/SymEncryptedIntegrityProtectedDataPacket.html index ba8e6fec..25b1b415 100644 --- a/docs/SymEncryptedIntegrityProtectedDataPacket.html +++ b/docs/SymEncryptedIntegrityProtectedDataPacket.html @@ -101,7 +101,7 @@ packet.

    Source:
    @@ -203,7 +203,7 @@ packet.

    Source:
    @@ -273,7 +273,7 @@ packet.

    Source:
    @@ -478,7 +478,7 @@ packet.

    Source:
    @@ -738,7 +738,7 @@ packet.

    Source:
    @@ -831,7 +831,7 @@ packet.


    diff --git a/docs/SymEncryptedSessionKeyPacket.html b/docs/SymEncryptedSessionKeyPacket.html index 3c43dac9..144b2d9d 100644 --- a/docs/SymEncryptedSessionKeyPacket.html +++ b/docs/SymEncryptedSessionKeyPacket.html @@ -165,7 +165,7 @@ the Symmetric-Key Encrypted Session Key packet.

    Source:
    @@ -271,7 +271,7 @@ the Symmetric-Key Encrypted Session Key packet.

    Source:
    @@ -345,7 +345,7 @@ the Symmetric-Key Encrypted Session Key packet.

    Source:
    @@ -419,7 +419,7 @@ the Symmetric-Key Encrypted Session Key packet.

    Source:
    @@ -550,7 +550,7 @@ the Symmetric-Key Encrypted Session Key packet.

    Source:
    @@ -761,7 +761,7 @@ the Symmetric-Key Encrypted Session Key packet.

    Source:
    @@ -929,7 +929,7 @@ the Symmetric-Key Encrypted Session Key packet.

    Source:
    @@ -1019,7 +1019,7 @@ the Symmetric-Key Encrypted Session Key packet.

    Source:
    @@ -1087,7 +1087,7 @@ the Symmetric-Key Encrypted Session Key packet.


    diff --git a/docs/SymmetricallyEncryptedDataPacket.html b/docs/SymmetricallyEncryptedDataPacket.html index fac92832..27cc835c 100644 --- a/docs/SymmetricallyEncryptedDataPacket.html +++ b/docs/SymmetricallyEncryptedDataPacket.html @@ -101,7 +101,7 @@ that form whole OpenPGP messages).

    Source:
    @@ -197,7 +197,7 @@ that form whole OpenPGP messages).

    Source:
    @@ -271,7 +271,7 @@ that form whole OpenPGP messages).

    Source:
    @@ -477,7 +477,7 @@ See RFC 4880 9.2 f
    Source:
    @@ -720,7 +720,7 @@ See RFC 4880 9.2 f
    Source:
    @@ -795,7 +795,7 @@ See RFC 4880 9.2 f
    diff --git a/docs/TrustPacket.html b/docs/TrustPacket.html index 593d3545..5e0f1a24 100644 --- a/docs/TrustPacket.html +++ b/docs/TrustPacket.html @@ -105,7 +105,7 @@ other than local keyring files.

    Source:
    @@ -216,7 +216,7 @@ Currently not implemented as we ignore trust packets

    Source:
    @@ -262,7 +262,7 @@ Currently not implemented as we ignore trust packets


    diff --git a/docs/UserAttributePacket.html b/docs/UserAttributePacket.html index 3c70f4d8..1cbaf2c6 100644 --- a/docs/UserAttributePacket.html +++ b/docs/UserAttributePacket.html @@ -107,7 +107,7 @@ an implementation may use any method desired.

    Source:
    @@ -266,7 +266,7 @@ an implementation may use any method desired.

    Source:
    @@ -427,7 +427,7 @@ an implementation may use any method desired.

    Source:
    @@ -517,7 +517,7 @@ an implementation may use any method desired.

    Source:
    @@ -585,7 +585,7 @@ an implementation may use any method desired.


    diff --git a/docs/UserIDPacket.html b/docs/UserIDPacket.html index 52303c5d..35436bb1 100644 --- a/docs/UserIDPacket.html +++ b/docs/UserIDPacket.html @@ -100,7 +100,7 @@ specifies the length of the User ID.

    Source:
    @@ -207,7 +207,7 @@ John Doe john@example.com

    Source:
    @@ -338,7 +338,7 @@ John Doe john@example.com

    Source:
    @@ -495,7 +495,7 @@ John Doe john@example.com

    Source:
    @@ -585,7 +585,7 @@ John Doe john@example.com

    Source:
    @@ -653,7 +653,7 @@ John Doe john@example.com


    diff --git a/docs/global.html b/docs/global.html index 8412e089..5e078cd4 100644 --- a/docs/global.html +++ b/docs/global.html @@ -419,7 +419,7 @@
    Source:
    @@ -632,7 +632,7 @@
    Source:
    @@ -771,7 +771,7 @@
    Source:
    @@ -1180,7 +1180,7 @@
    Source:
    @@ -1761,7 +1761,7 @@ One of decryptionKeys, sessionkeys or passwords<
    Source:
    @@ -2064,7 +2064,7 @@ This method does not change the original key.

    Source:
    @@ -2423,7 +2423,7 @@ One of decryptionKeys or passwords must be specified.<
    Source:
    @@ -2488,103 +2488,6 @@ One of decryptionKeys or passwords must be specified.< - - - - - - -

    detectBigInt()

    - - - - - - -
    -

    We don't use the BigIntegerInterface wrapper from noble-hashes because:

    -
      -
    • importing the instance results in it being shared with noble-hashes, which separately calls setImplementation() -on load, causing it to throw due to duplicate initialization.
    • -
    • even duplicating the interface code here to keep a separate instance requires handing a race-conditions the first time -getBigInteger is called, when the code needs to check if the implementation is set, and initialize it if not. -Ultimately, the interface provides no advantages and it's only needed because of TS.
    • -
    -
    - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - @@ -3324,7 +3227,7 @@ must be specified. If signing keys are specified, those will be used to sign the
    Source:
    @@ -3612,7 +3515,7 @@ This method does not change the original key.

    Source:
    @@ -4232,7 +4135,7 @@ At least one of encryptionKeys or passwords must be sp
    Source:
    @@ -4448,7 +4351,7 @@ At least one of encryptionKeys or passwords must be sp
    Source:
    @@ -5049,7 +4952,7 @@ default to main key options, except for sign parameter that default
    Source:
    @@ -5399,7 +5302,7 @@ default to main key options, except for sign parameter that default
    Source:
    @@ -5560,7 +5463,7 @@ default to main key options, except for sign parameter that default
    Source:
    @@ -5699,7 +5602,7 @@ default to main key options, except for sign parameter that default
    Source:
    @@ -5838,7 +5741,7 @@ default to main key options, except for sign parameter that default
    Source:
    @@ -5988,7 +5891,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -6168,7 +6071,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -6312,7 +6215,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -6502,7 +6405,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -6894,7 +6797,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -7135,7 +7038,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -7423,7 +7326,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -7711,7 +7614,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -8005,7 +7908,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -8293,7 +8196,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -8581,7 +8484,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -8869,7 +8772,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -9331,7 +9234,7 @@ to set the same date as the key creation time to ensure that old message signatu
    Source:
    @@ -9860,7 +9763,7 @@ If a revocation certificate is passed, the reasonForRevocation parameter will be
    Source:
    @@ -10075,7 +9978,7 @@ If a revocation certificate is passed, the reasonForRevocation parameter will be
    Source:
    @@ -10624,7 +10527,7 @@ If a revocation certificate is passed, the reasonForRevocation parameter will be
    Source:
    @@ -10786,7 +10689,7 @@ the encoded bytes

    Source:
    @@ -11248,7 +11151,7 @@ an attribute "data" containing a stream of bytes and "type"
    Source:
    @@ -11493,7 +11396,7 @@ The new key includes a revocation certificate that must be removed before return
    Source:
    @@ -11673,7 +11576,7 @@ The new key includes a revocation certificate that must be removed before return
    Source:
    @@ -11741,7 +11644,7 @@ The new key includes a revocation certificate that must be removed before return
    diff --git a/docs/index.html b/docs/index.html index 81ce2ee0..6259911b 100644 --- a/docs/index.html +++ b/docs/index.html @@ -706,7 +706,7 @@ and a subkey for encryption using Curve25519.


    diff --git a/docs/module-config.html b/docs/module-config.html index cd13962b..ead6d452 100644 --- a/docs/module-config.html +++ b/docs/module-config.html @@ -89,7 +89,7 @@
    Source:
    @@ -247,7 +247,7 @@ as a global config setting, but can be used for specific function calls (e.g. de
    Source:
    @@ -365,7 +365,7 @@ Must be an integer value from 0 to 56.

    Source:
    @@ -489,7 +489,7 @@ Note: not all OpenPGP implementations are compatible with this option.
    Source:
    @@ -614,7 +614,7 @@ where key flags were ignored when selecting a key for encryption.

    Source:
    @@ -733,7 +733,7 @@ and have self-signature's creation date that does not match the primary key crea
    Source:
    @@ -854,7 +854,7 @@ This is an insecure setting:

    Source:
    @@ -979,7 +979,7 @@ and deferring checking their integrity until the decrypted stream has been read
    Source:
    @@ -1091,7 +1091,7 @@ and deferring checking their integrity until the decrypted stream has been read
    Source:
    @@ -1213,7 +1213,7 @@ See also constantTimePKCS1DecryptionSupportedSymmetricAlgorithms.Source:
    @@ -1331,7 +1331,7 @@ However, the more algorithms are added, the slower the decryption procedure beco
    Source:
    @@ -1443,7 +1443,7 @@ However, the more algorithms are added, the slower the decryption procedure beco
    Source:
    @@ -1555,7 +1555,7 @@ However, the more algorithms are added, the slower the decryption procedure beco
    Source:
    @@ -1672,7 +1672,7 @@ validation error when the notation is marked as critical.

    Source:
    @@ -1788,7 +1788,7 @@ validation error when the notation is marked as critical.

    Source:
    @@ -1905,7 +1905,7 @@ The default is 2047 since due to a bug, previous versions of OpenPGP.js could ge
    Source:
    @@ -2022,7 +2022,7 @@ The default is 2047 since due to a bug, previous versions of OpenPGP.js could ge
    Source:
    @@ -2139,7 +2139,7 @@ Only has an effect when aeadProtect is set to true.

    Source:
    @@ -2251,7 +2251,7 @@ Only has an effect when aeadProtect is set to true.

    Source:
    @@ -2363,7 +2363,7 @@ Only has an effect when aeadProtect is set to true.

    Source:
    @@ -2475,7 +2475,7 @@ Only has an effect when aeadProtect is set to true.

    Source:
    @@ -2591,7 +2591,7 @@ Only has an effect when aeadProtect is set to true.

    Source:
    @@ -2707,7 +2707,7 @@ Only has an effect when aeadProtect is set to true.

    Source:
    @@ -2823,7 +2823,7 @@ Only has an effect when aeadProtect is set to true.

    Source:
    @@ -2939,7 +2939,7 @@ Only has an effect when aeadProtect is set to true.

    Source:
    @@ -3154,7 +3154,7 @@ For more details on the choice of parameters, see https://tools.ietf.org/html/rf
    Source:
    @@ -3273,7 +3273,7 @@ Note: this is the exponent value, not the final number of iterations (refer to s
    Source:
    @@ -3395,7 +3395,7 @@ Note: Argon2 is the strongest option but not all OpenPGP implementations are com
    Source:
    @@ -3507,7 +3507,7 @@ Note: Argon2 is the strongest option but not all OpenPGP implementations are com
    Source:
    @@ -3619,7 +3619,7 @@ Note: Argon2 is the strongest option but not all OpenPGP implementations are com
    Source:
    @@ -3736,7 +3736,7 @@ When false, certain standard curves will not be supported (depending on the plat
    Source:
    @@ -3854,7 +3854,7 @@ Note: not all OpenPGP implementations are compatible with this option.
    Source:
    @@ -3966,7 +3966,7 @@ Note: not all OpenPGP implementations are compatible with this option.
    Source:
    @@ -4000,7 +4000,7 @@ Note: not all OpenPGP implementations are compatible with this option.
    diff --git a/docs/module-crypto.html b/docs/module-crypto.html index 229882e0..df3ddf0d 100644 --- a/docs/module-crypto.html +++ b/docs/module-crypto.html @@ -89,7 +89,7 @@
    Source:
    @@ -169,7 +169,7 @@
    diff --git a/docs/module-crypto_aes_kw.html b/docs/module-crypto_aes_kw.html index 8f31411f..9d025e00 100644 --- a/docs/module-crypto_aes_kw.html +++ b/docs/module-crypto_aes_kw.html @@ -89,7 +89,7 @@
    Source:
    @@ -308,7 +308,7 @@
    Source:
    @@ -521,7 +521,7 @@
    Source:
    @@ -589,7 +589,7 @@
    diff --git a/docs/module-crypto_cmac.html b/docs/module-crypto_cmac.html index 7a695b0f..609ac1c6 100644 --- a/docs/module-crypto_cmac.html +++ b/docs/module-crypto_cmac.html @@ -90,7 +90,7 @@ native AES-CBC using either the WebCrypto API or Node.js' crypto API.

    Source:
    @@ -195,7 +195,7 @@ The OMAC authors indicate that they will promulgate this modification
    Source:
    @@ -352,7 +352,7 @@ simplify the implementation.

    Source:
    @@ -398,7 +398,7 @@ simplify the implementation.


    diff --git a/docs/module-crypto_crypto.html b/docs/module-crypto_crypto.html index 57b6174f..3f48ad01 100644 --- a/docs/module-crypto_crypto.html +++ b/docs/module-crypto_crypto.html @@ -90,7 +90,7 @@ well as key generation and parameter handling for all public-key cryptosystems.<
    Source:
    @@ -296,7 +296,7 @@ well as key generation and parameter handling for all public-key cryptosystems.<
    Source:
    @@ -458,7 +458,7 @@ See RFC 4880 9.2 f
    Source:
    @@ -619,7 +619,7 @@ See RFC 4880 9.2 f
    Source:
    @@ -848,7 +848,7 @@ See RFC 4880 9.2 f
    Source:
    @@ -1030,7 +1030,7 @@ See RFC 4880 9.2 f
    Source:
    @@ -1170,7 +1170,7 @@ See RFC 4880 9.2 f
    Source:
    @@ -1354,7 +1354,7 @@ See RFC 4880 9.2 f
    Source:
    @@ -1561,7 +1561,7 @@ See RFC 4880 9.2 f
    Source:
    @@ -1745,7 +1745,7 @@ See RFC 4880 9.2 f
    Source:
    @@ -2075,7 +2075,7 @@ See RFC 4880 5.5.3Source:
    @@ -2361,7 +2361,7 @@ See RFC 4880 9.1 f
    Source:
    @@ -2545,7 +2545,7 @@ See RFC 4880 9.1 f
    Source:
    @@ -2752,7 +2752,7 @@ See RFC 4880 9.1 f
    Source:
    @@ -2913,7 +2913,7 @@ See RFC 4880 9.1 f
    Source:
    @@ -2988,7 +2988,7 @@ See RFC 4880 9.1 f
    diff --git a/docs/module-crypto_hash.html b/docs/module-crypto_hash.html index c0d81139..b255106d 100644 --- a/docs/module-crypto_hash.html +++ b/docs/module-crypto_hash.html @@ -89,7 +89,7 @@
    Source:
    @@ -191,7 +191,7 @@
    Source:
    @@ -352,7 +352,7 @@
    Source:
    @@ -513,7 +513,7 @@
    Source:
    @@ -581,7 +581,7 @@
    diff --git a/docs/module-crypto_hkdf.html b/docs/module-crypto_hkdf.html index 8387f295..53442804 100644 --- a/docs/module-crypto_hkdf.html +++ b/docs/module-crypto_hkdf.html @@ -89,7 +89,7 @@
    Source:
    @@ -152,7 +152,7 @@
    diff --git a/docs/module-crypto_mode.html b/docs/module-crypto_mode.html index 90e5ba3a..1b7a62a5 100644 --- a/docs/module-crypto_mode.html +++ b/docs/module-crypto_mode.html @@ -89,7 +89,7 @@
    Source:
    @@ -182,7 +182,7 @@
    Source:
    @@ -249,7 +249,7 @@
    Source:
    @@ -316,7 +316,7 @@
    Source:
    @@ -383,7 +383,7 @@
    Source:
    @@ -424,7 +424,7 @@
    diff --git a/docs/module-crypto_mode_cfb.html b/docs/module-crypto_mode_cfb.html index 2f0bd879..8cae2db7 100644 --- a/docs/module-crypto_mode_cfb.html +++ b/docs/module-crypto_mode_cfb.html @@ -236,7 +236,7 @@
    Source:
    @@ -477,7 +477,7 @@
    Source:
    @@ -533,7 +533,7 @@
    diff --git a/docs/module-crypto_mode_eax.html b/docs/module-crypto_mode_eax.html index 60df2b29..6a9a2ef4 100644 --- a/docs/module-crypto_mode_eax.html +++ b/docs/module-crypto_mode_eax.html @@ -90,7 +90,7 @@ native AES-CTR using either the WebCrypto API or Node.js' crypto API.

    Source:
    @@ -296,7 +296,7 @@ native AES-CTR using either the WebCrypto API or Node.js' crypto API.

    Source:
    @@ -480,7 +480,7 @@ native AES-CTR using either the WebCrypto API or Node.js' crypto API.

    Source:
    @@ -665,7 +665,7 @@ native AES-CTR using either the WebCrypto API or Node.js' crypto API.

    Source:
    @@ -733,7 +733,7 @@ native AES-CTR using either the WebCrypto API or Node.js' crypto API.


    diff --git a/docs/module-crypto_mode_gcm.html b/docs/module-crypto_mode_gcm.html index 1055359c..1746d55b 100644 --- a/docs/module-crypto_mode_gcm.html +++ b/docs/module-crypto_mode_gcm.html @@ -90,7 +90,7 @@ the WebCrypto api as well as node.js' crypto api.

    Source:
    @@ -273,7 +273,7 @@ the WebCrypto api as well as node.js' crypto api.

    Source:
    @@ -319,7 +319,7 @@ the WebCrypto api as well as node.js' crypto api.


    diff --git a/docs/module-crypto_mode_ocb.html b/docs/module-crypto_mode_ocb.html index 87135068..0cafab9f 100644 --- a/docs/module-crypto_mode_ocb.html +++ b/docs/module-crypto_mode_ocb.html @@ -89,7 +89,7 @@
    Source:
    @@ -295,7 +295,7 @@
    Source:
    @@ -502,7 +502,7 @@
    Source:
    @@ -686,7 +686,7 @@
    Source:
    @@ -732,7 +732,7 @@
    diff --git a/docs/module-crypto_pkcs1.html b/docs/module-crypto_pkcs1.html index d29920d6..4144f142 100644 --- a/docs/module-crypto_pkcs1.html +++ b/docs/module-crypto_pkcs1.html @@ -89,7 +89,7 @@
    Source:
    @@ -197,7 +197,7 @@
    Source:
    @@ -358,7 +358,7 @@
    Source:
    @@ -578,7 +578,7 @@
    Source:
    @@ -792,7 +792,7 @@
    Source:
    @@ -867,7 +867,7 @@
    diff --git a/docs/module-crypto_public_key.html b/docs/module-crypto_public_key.html index 59732ccb..111496b0 100644 --- a/docs/module-crypto_public_key.html +++ b/docs/module-crypto_public_key.html @@ -89,7 +89,7 @@
    Source:
    @@ -182,7 +182,7 @@
    Source:
    @@ -249,7 +249,7 @@
    Source:
    @@ -316,7 +316,7 @@
    Source:
    @@ -383,7 +383,7 @@
    Source:
    @@ -424,7 +424,7 @@
    diff --git a/docs/module-crypto_public_key_dsa.html b/docs/module-crypto_public_key_dsa.html index 7a9b4f05..6dc8058d 100644 --- a/docs/module-crypto_public_key_dsa.html +++ b/docs/module-crypto_public_key_dsa.html @@ -89,7 +89,7 @@
    Source:
    @@ -188,7 +188,7 @@ Expect y == y'

    Source:
    @@ -434,7 +434,7 @@ Expect y == y'

    Source:
    @@ -683,7 +683,7 @@ Expect y == y'

    Source:
    @@ -1005,7 +1005,7 @@ Expect y == y'

    Source:
    @@ -1069,7 +1069,7 @@ Expect y == y'


    diff --git a/docs/module-crypto_public_key_elgamal.html b/docs/module-crypto_public_key_elgamal.html index 477b656f..77f82b90 100644 --- a/docs/module-crypto_public_key_elgamal.html +++ b/docs/module-crypto_public_key_elgamal.html @@ -89,7 +89,7 @@
    Source:
    @@ -188,7 +188,7 @@ Expect y == y'

    Source:
    @@ -412,7 +412,7 @@ Expect y == y'

    Source:
    @@ -672,7 +672,7 @@ Note that in OpenPGP, the message needs to be padded with PKCS#1 (same as RSA)Source:
    @@ -898,7 +898,7 @@ Note that in OpenPGP, the message needs to be padded with PKCS#1 (same as RSA)Source:
    @@ -966,7 +966,7 @@ Note that in OpenPGP, the message needs to be padded with PKCS#1 (same as RSA)
    diff --git a/docs/module-crypto_public_key_elliptic.html b/docs/module-crypto_public_key_elliptic.html index 2ca35aaa..0d398def 100644 --- a/docs/module-crypto_public_key_elliptic.html +++ b/docs/module-crypto_public_key_elliptic.html @@ -89,7 +89,7 @@
    Source:
    @@ -165,7 +165,7 @@
    diff --git a/docs/module-crypto_public_key_elliptic_curve.html b/docs/module-crypto_public_key_elliptic_curve.html index b1e52b8f..b473c720 100644 --- a/docs/module-crypto_public_key_elliptic_curve.html +++ b/docs/module-crypto_public_key_elliptic_curve.html @@ -89,7 +89,7 @@
    Source:
    @@ -249,7 +249,7 @@
    Source:
    @@ -406,7 +406,7 @@
    Source:
    @@ -632,7 +632,7 @@
    Source:
    @@ -835,7 +835,7 @@
    Source:
    @@ -1066,7 +1066,7 @@ Not suitable for EdDSA (different secret key format)

    Source:
    @@ -1134,7 +1134,7 @@ Not suitable for EdDSA (different secret key format)


    diff --git a/docs/module-crypto_public_key_elliptic_ecdh.html b/docs/module-crypto_public_key_elliptic_ecdh.html index 5a5591ca..9ed650c6 100644 --- a/docs/module-crypto_public_key_elliptic_ecdh.html +++ b/docs/module-crypto_public_key_elliptic_ecdh.html @@ -91,7 +91,7 @@
    Source:
    @@ -169,7 +169,7 @@
    Source:
    @@ -467,7 +467,7 @@
    Source:
    @@ -720,7 +720,7 @@
    Source:
    @@ -973,7 +973,7 @@
    Source:
    @@ -1176,7 +1176,7 @@
    Source:
    @@ -1337,7 +1337,7 @@
    Source:
    @@ -1540,7 +1540,7 @@
    Source:
    @@ -1747,7 +1747,7 @@
    Source:
    @@ -1977,7 +1977,7 @@
    Source:
    @@ -2157,7 +2157,7 @@
    Source:
    @@ -2360,7 +2360,7 @@
    Source:
    @@ -2540,7 +2540,7 @@
    Source:
    @@ -2766,7 +2766,7 @@
    Source:
    @@ -2946,7 +2946,7 @@
    Source:
    @@ -3077,7 +3077,7 @@
    Source:
    @@ -3155,7 +3155,7 @@
    Source:
    @@ -3453,7 +3453,7 @@
    Source:
    @@ -3706,7 +3706,7 @@
    Source:
    @@ -3959,7 +3959,7 @@
    Source:
    @@ -4162,7 +4162,7 @@
    Source:
    @@ -4323,7 +4323,7 @@
    Source:
    @@ -4526,7 +4526,7 @@
    Source:
    @@ -4733,7 +4733,7 @@
    Source:
    @@ -4963,7 +4963,7 @@
    Source:
    @@ -5143,7 +5143,7 @@
    Source:
    @@ -5346,7 +5346,7 @@
    Source:
    @@ -5526,7 +5526,7 @@
    Source:
    @@ -5752,7 +5752,7 @@
    Source:
    @@ -5932,7 +5932,7 @@
    Source:
    @@ -5996,7 +5996,7 @@
    diff --git a/docs/module-crypto_public_key_elliptic_ecdsa.html b/docs/module-crypto_public_key_elliptic_ecdsa.html index e8fff15a..db7b2c8a 100644 --- a/docs/module-crypto_public_key_elliptic_ecdsa.html +++ b/docs/module-crypto_public_key_elliptic_ecdsa.html @@ -89,7 +89,7 @@
    Source:
    @@ -364,7 +364,7 @@
    Source:
    @@ -571,7 +571,7 @@
    Source:
    @@ -847,7 +847,7 @@
    Source:
    @@ -956,7 +956,7 @@ To be used if no native implementation is available for the given curve/operatio
    Source:
    @@ -1002,7 +1002,7 @@ To be used if no native implementation is available for the given curve/operatio
    diff --git a/docs/module-crypto_public_key_elliptic_eddsa.html b/docs/module-crypto_public_key_elliptic_eddsa.html index a57204fa..5bf9bccf 100644 --- a/docs/module-crypto_public_key_elliptic_eddsa.html +++ b/docs/module-crypto_public_key_elliptic_eddsa.html @@ -89,7 +89,7 @@
    Source:
    @@ -249,7 +249,7 @@
    Source:
    @@ -521,7 +521,7 @@
    Source:
    @@ -751,7 +751,7 @@
    Source:
    @@ -1027,7 +1027,7 @@
    Source:
    @@ -1091,7 +1091,7 @@
    diff --git a/docs/module-crypto_public_key_elliptic_eddsa_legacy.html b/docs/module-crypto_public_key_elliptic_eddsa_legacy.html index 24ddbc71..832516db 100644 --- a/docs/module-crypto_public_key_elliptic_eddsa_legacy.html +++ b/docs/module-crypto_public_key_elliptic_eddsa_legacy.html @@ -90,7 +90,7 @@ This key type has been deprecated by the crypto-refresh RFC.

    Source:
    @@ -365,7 +365,7 @@ This key type has been deprecated by the crypto-refresh RFC.

    Source:
    @@ -572,7 +572,7 @@ This key type has been deprecated by the crypto-refresh RFC.

    Source:
    @@ -848,7 +848,7 @@ This key type has been deprecated by the crypto-refresh RFC.

    Source:
    @@ -912,7 +912,7 @@ This key type has been deprecated by the crypto-refresh RFC.


    diff --git a/docs/module-crypto_public_key_prime.html b/docs/module-crypto_public_key_prime.html deleted file mode 100644 index e33cc57e..00000000 --- a/docs/module-crypto_public_key_prime.html +++ /dev/null @@ -1,954 +0,0 @@ - - - - - JSDoc: Module: crypto/public_key/prime - - - - - - - - - - -
    - -

    Module: crypto/public_key/prime

    - - - - - - -
    - -
    - - - - - -
    - -
    -
    - - -

    Algorithms for probabilistic random prime generation

    - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - -

    Methods

    - - - - - - - -

    (static) fermat(n, b) → {boolean}

    - - - - - - -
    -

    Tests whether n is probably prime or not using Fermat's test with b = 2. -Fails if b^(n-1) mod n != 1.

    -
    - - - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    n - - -BigInteger - - - -

    Number to test

    b - - -BigInteger - - - -

    Optional Fermat test base

    - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - - - - - - - - - - - - -
    Returns:
    - - - - -
    -
    - Type -
    -
    - -boolean - - -
    -
    - - - - - - - - - - - - - -

    (async, static) isProbablePrime(n, e, k) → {boolean}

    - - - - - - -
    -

    Probabilistic primality testing

    -
    - - - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    n - - -BigInteger - - - -

    Number to test

    e - - -BigInteger - - - -

    Optional RSA exponent to check against the prime

    k - - -Integer - - - -

    Optional number of iterations of Miller-Rabin test

    - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - - - - - - - - - - - - -
    Returns:
    - - - - -
    -
    - Type -
    -
    - -boolean - - -
    -
    - - - - - - - - - - - - - -

    (async, static) millerRabin(n, k, rand) → {boolean}

    - - - - - - -
    -

    Tests whether n is probably prime or not using the Miller-Rabin test. -See HAC Remark 4.28.

    -
    - - - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    n - - -BigInteger - - - -

    Number to test

    k - - -Integer - - - -

    Optional number of iterations of Miller-Rabin test

    rand - - -function - - - -

    Optional function to generate potential witnesses

    - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - - - - - - - - - - - - -
    Returns:
    - - - - -
    -
    - Type -
    -
    - -boolean - - -
    -
    - - - - - - - - - - - - - -

    (async, static) randomProbablePrime(bits, e, k)

    - - - - - - -
    -

    Generate a probably prime random number

    -
    - - - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    bits - - -Integer - - - -

    Bit length of the prime

    e - - -BigInteger - - - -

    Optional RSA exponent to check against the prime

    k - - -Integer - - - -

    Optional number of iterations of Miller-Rabin test

    - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - - - - - - - - - - - - -
    Returns:
    - - -
    -

    BigInteger

    -
    - - - - - - - - - - - - - - - -
    - -
    - - - - -
    - - - -
    - - - - - - - \ No newline at end of file diff --git a/docs/module-crypto_public_key_rsa.html b/docs/module-crypto_public_key_rsa.html index 449d2273..bcb3d1a4 100644 --- a/docs/module-crypto_public_key_rsa.html +++ b/docs/module-crypto_public_key_rsa.html @@ -89,7 +89,7 @@
    Source:
    @@ -411,7 +411,7 @@
    Source:
    @@ -647,7 +647,7 @@
    Source:
    @@ -833,7 +833,7 @@
    Source:
    @@ -843,7 +843,7 @@
    See:
    @@ -1186,7 +1186,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

    Source:
    @@ -1462,7 +1462,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

    Source:
    @@ -1738,7 +1738,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

    Source:
    @@ -1846,7 +1846,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

    Source:
    @@ -2123,7 +2123,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

    Source:
    @@ -2308,7 +2308,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

    Source:
    @@ -2354,7 +2354,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q


    diff --git a/docs/module-crypto_random.html b/docs/module-crypto_random.html index bfa1068f..5e4aade2 100644 --- a/docs/module-crypto_random.html +++ b/docs/module-crypto_random.html @@ -89,7 +89,7 @@
    Source:
    @@ -146,7 +146,7 @@ -

    (async, static) getRandomBigInteger(min, max) → {Promise.<module:BigInteger>}

    +

    (async, static) getRandomBigInteger(min, max) → {bigint}

    @@ -154,7 +154,7 @@
    -

    Create a secure random BigInteger that is greater than or equal to min and less than max.

    +

    Create a secure random BigInt that is greater than or equal to min and less than max.

    @@ -196,7 +196,7 @@ -module:BigInteger +bigint @@ -219,7 +219,7 @@ -module:BigInteger +bigint @@ -272,7 +272,7 @@
    Source:
    @@ -301,7 +301,7 @@
    -

    Random BigInteger.

    +

    Random BigInt.

    @@ -312,7 +312,7 @@
    -Promise.<module:BigInteger> +bigint
    @@ -433,7 +433,7 @@
    Source:
    @@ -501,7 +501,7 @@
    diff --git a/docs/module-crypto_signature.html b/docs/module-crypto_signature.html index 9b6b6f5a..d32f4ffa 100644 --- a/docs/module-crypto_signature.html +++ b/docs/module-crypto_signature.html @@ -89,7 +89,7 @@
    Source:
    @@ -276,7 +276,7 @@ See RFC 4880 5.2.2.<
    Source:
    @@ -555,7 +555,7 @@ for public key and hash algorithms.

    Source:
    @@ -834,7 +834,7 @@ for public key and hash algorithms.

    Source:
    @@ -902,7 +902,7 @@ for public key and hash algorithms.


    diff --git a/docs/module-encoding_base64.html b/docs/module-encoding_base64.html index b9553f11..6909128f 100644 --- a/docs/module-encoding_base64.html +++ b/docs/module-encoding_base64.html @@ -168,7 +168,7 @@
    Source:
    @@ -332,7 +332,7 @@
    Source:
    @@ -499,7 +499,7 @@
    Source:
    @@ -686,7 +686,7 @@
    Source:
    @@ -754,7 +754,7 @@
    diff --git a/docs/module-enums.html b/docs/module-enums.html index eba0d320..927be691 100644 --- a/docs/module-enums.html +++ b/docs/module-enums.html @@ -235,7 +235,7 @@
    Source:
    @@ -499,7 +499,7 @@
    Source:
    @@ -694,7 +694,7 @@
    Source:
    @@ -1119,7 +1119,7 @@
    Source:
    @@ -1323,7 +1323,7 @@ fingerprint format

    Source:
    @@ -1633,7 +1633,7 @@ fingerprint format

    Source:
    @@ -1899,7 +1899,7 @@ possession of more than one person.

    Source:
    @@ -2094,7 +2094,7 @@ possession of more than one person.

    Source:
    @@ -2634,7 +2634,7 @@ possession of more than one person.

    Source:
    @@ -3060,7 +3060,7 @@ possession of more than one person.

    Source:
    @@ -3278,7 +3278,7 @@ possession of more than one person.

    Source:
    @@ -3496,7 +3496,7 @@ possession of more than one person.

    Source:
    @@ -4013,7 +4013,7 @@ document) that cannot include a target subpacket.

    Source:
    @@ -4737,7 +4737,7 @@ document) that cannot include a target subpacket.

    Source:
    @@ -5024,7 +5024,7 @@ document) that cannot include a target subpacket.

    Source:
    @@ -5220,7 +5220,7 @@ document) that cannot include a target subpacket.

    Source:
    @@ -5374,7 +5374,7 @@ document) that cannot include a target subpacket.

    Source:
    @@ -5590,7 +5590,7 @@ document) that cannot include a target subpacket.

    Source:
    @@ -5687,7 +5687,7 @@ document) that cannot include a target subpacket.


    diff --git a/docs/module-key_Subkey-Subkey.html b/docs/module-key_Subkey-Subkey.html index e7288557..378ae6c5 100644 --- a/docs/module-key_Subkey-Subkey.html +++ b/docs/module-key_Subkey-Subkey.html @@ -171,7 +171,7 @@
    Source:
    @@ -281,7 +281,7 @@
    Source:
    @@ -394,7 +394,7 @@
    Source:
    @@ -511,7 +511,7 @@
    Source:
    @@ -628,7 +628,7 @@
    Source:
    @@ -741,7 +741,7 @@
    Source:
    @@ -942,7 +942,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -1055,7 +1055,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -1172,7 +1172,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -1289,7 +1289,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -1406,7 +1406,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -1523,7 +1523,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -1640,7 +1640,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -1757,7 +1757,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -1873,7 +1873,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -2149,7 +2149,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -2487,7 +2487,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -2599,7 +2599,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -2832,7 +2832,7 @@ Returns null if the subkey is invalid.

    Source:
    @@ -3044,7 +3044,7 @@ and valid binding signature.

    Source:
    @@ -3137,7 +3137,7 @@ and valid binding signature.


    diff --git a/docs/module-key_Subkey.html b/docs/module-key_Subkey.html index da7d59b7..e0d39f96 100644 --- a/docs/module-key_Subkey.html +++ b/docs/module-key_Subkey.html @@ -77,7 +77,7 @@
    diff --git a/docs/module-key_User-User.html b/docs/module-key_User-User.html index 85992b4a..21762695 100644 --- a/docs/module-key_User-User.html +++ b/docs/module-key_User-User.html @@ -171,7 +171,7 @@
    Source:
    @@ -404,7 +404,7 @@
    Source:
    @@ -516,7 +516,7 @@
    Source:
    @@ -789,7 +789,7 @@
    Source:
    @@ -1127,7 +1127,7 @@
    Source:
    @@ -1239,7 +1239,7 @@
    Source:
    @@ -1442,7 +1442,7 @@
    Source:
    @@ -1623,7 +1623,7 @@ and validity of self signature.

    Source:
    @@ -1887,7 +1887,7 @@ and validity of self signature.

    Source:
    @@ -2154,7 +2154,7 @@ Signature validity is null if the verification keys do not correspond to the cer
    Source:
    @@ -2234,7 +2234,7 @@ Signature validity is null if the verification keys do not correspond to the cer
    diff --git a/docs/module-key_User.html b/docs/module-key_User.html index 8daa7956..f915884a 100644 --- a/docs/module-key_User.html +++ b/docs/module-key_User.html @@ -77,7 +77,7 @@
    diff --git a/docs/module-key_helper.html b/docs/module-key_helper.html index adae72ab..9d9d5e74 100644 --- a/docs/module-key_helper.html +++ b/docs/module-key_helper.html @@ -89,7 +89,7 @@
    Source:
    @@ -281,7 +281,7 @@
    Source:
    @@ -518,7 +518,7 @@
    Source:
    @@ -928,7 +928,7 @@
    Source:
    @@ -1116,7 +1116,7 @@ The expiration time of the signature is ignored.

    Source:
    @@ -1352,7 +1352,7 @@ The expiration time of the signature is ignored.

    Source:
    @@ -1624,7 +1624,7 @@ The expiration time of the signature is ignored.

    Source:
    @@ -1896,7 +1896,7 @@ The expiration time of the signature is ignored.

    Source:
    @@ -2200,7 +2200,7 @@ The expiration time of the signature is ignored.

    Source:
    @@ -2507,7 +2507,7 @@ The expiration time of the signature is ignored.

    Source:
    @@ -2806,7 +2806,7 @@ The expiration time of the signature is ignored.

    Source:
    @@ -2852,7 +2852,7 @@ The expiration time of the signature is ignored.


    diff --git a/docs/module-packet_packet.html b/docs/module-packet_packet.html index b7537336..99303fe7 100644 --- a/docs/module-packet_packet.html +++ b/docs/module-packet_packet.html @@ -89,7 +89,7 @@
    Source:
    @@ -275,7 +275,7 @@
    Source:
    @@ -436,7 +436,7 @@
    Source:
    @@ -621,7 +621,7 @@ string

    Source:
    @@ -783,7 +783,7 @@ string

    Source:
    @@ -851,7 +851,7 @@ string


    diff --git a/docs/module-type_ecdh_symkey.html b/docs/module-type_ecdh_symkey.html index dac888c9..9c559b3f 100644 --- a/docs/module-type_ecdh_symkey.html +++ b/docs/module-type_ecdh_symkey.html @@ -89,7 +89,7 @@
    Source:
    @@ -152,7 +152,7 @@
    diff --git a/docs/module-type_kdf_params-KDFParams.html b/docs/module-type_kdf_params-KDFParams.html index 24b9917a..2c364142 100644 --- a/docs/module-type_kdf_params-KDFParams.html +++ b/docs/module-type_kdf_params-KDFParams.html @@ -163,7 +163,7 @@
    Source:
    @@ -322,7 +322,7 @@
    Source:
    @@ -434,7 +434,7 @@
    Source:
    @@ -502,7 +502,7 @@
    diff --git a/docs/module-type_keyid-KeyID.html b/docs/module-type_keyid-KeyID.html index 852cc2bb..fda5c8e1 100644 --- a/docs/module-type_keyid-KeyID.html +++ b/docs/module-type_keyid-KeyID.html @@ -101,7 +101,7 @@ formed.

    Source:
    @@ -295,7 +295,7 @@ formed.

    Source:
    @@ -385,7 +385,7 @@ formed.

    Source:
    @@ -497,7 +497,7 @@ formed.

    Source:
    @@ -658,7 +658,7 @@ formed.

    Source:
    @@ -748,7 +748,7 @@ formed.

    Source:
    @@ -860,7 +860,7 @@ formed.

    Source:
    @@ -928,7 +928,7 @@ formed.


    diff --git a/docs/module-type_keyid.html b/docs/module-type_keyid.html index 9a78068b..e953b456 100644 --- a/docs/module-type_keyid.html +++ b/docs/module-type_keyid.html @@ -77,7 +77,7 @@
    diff --git a/docs/module-type_oid.html b/docs/module-type_oid.html index 3d481267..bd4a59f0 100644 --- a/docs/module-type_oid.html +++ b/docs/module-type_oid.html @@ -100,7 +100,7 @@ sequence of octets is the valid representation of a curve OID.

    Source:
    @@ -163,7 +163,7 @@ sequence of octets is the valid representation of a curve OID.


    diff --git a/docs/module-type_s2k-GenericS2K.html b/docs/module-type_s2k-GenericS2K.html index ad84a251..ec13966a 100644 --- a/docs/module-type_s2k-GenericS2K.html +++ b/docs/module-type_s2k-GenericS2K.html @@ -153,7 +153,7 @@
    Source:
    @@ -262,7 +262,7 @@
    Source:
    @@ -332,7 +332,7 @@
    Source:
    @@ -406,7 +406,7 @@
    Source:
    @@ -480,7 +480,7 @@
    Source:
    @@ -612,7 +612,7 @@ hashAlgorithm

    Source:
    @@ -774,7 +774,7 @@ hashAlgorithm hash length

    Source:
    @@ -886,7 +886,7 @@ hashAlgorithm hash length

    Source:
    @@ -954,7 +954,7 @@ hashAlgorithm hash length


    diff --git a/docs/module-type_s2k.html b/docs/module-type_s2k.html index b785e0a2..202ddfa5 100644 --- a/docs/module-type_s2k.html +++ b/docs/module-type_s2k.html @@ -95,7 +95,7 @@ symmetrically encrypted messages.

    Source:
    @@ -165,7 +165,7 @@ symmetrically encrypted messages.


    diff --git a/docs/module-type_x25519x448_symkey.html b/docs/module-type_x25519x448_symkey.html index c583c525..305c14ab 100644 --- a/docs/module-type_x25519x448_symkey.html +++ b/docs/module-type_x25519x448_symkey.html @@ -91,7 +91,7 @@ the former includes an algorithm byte preceeding the encrypted session key.

    <
    Source:
    @@ -154,7 +154,7 @@ the former includes an algorithm byte preceeding the encrypted session key.

    <
    diff --git a/docs/module-util.html b/docs/module-util.html index 1059ab7f..68123fe2 100644 --- a/docs/module-util.html +++ b/docs/module-util.html @@ -89,7 +89,7 @@
    Source:
    @@ -152,7 +152,7 @@
    diff --git a/package-lock.json b/package-lock.json index 03aa3b3f..12a1367b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "openpgp", - "version": "6.0.0-beta.0", + "version": "6.0.0-beta.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "openpgp", - "version": "6.0.0-beta.0", + "version": "6.0.0-beta.1", "license": "LGPL-3.0+", "devDependencies": { "@noble/curves": "^1.4.0", diff --git a/package.json b/package.json index 6ec3487a..e9c7f688 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "openpgp", "description": "OpenPGP.js is a Javascript implementation of the OpenPGP protocol. This is defined in RFC 4880.", - "version": "6.0.0-beta.0", + "version": "6.0.0-beta.1", "license": "LGPL-3.0+", "homepage": "https://openpgpjs.org/", "engines": { From b1e27a1430fa666d9e749f7b5a141da024c15fc0 Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Mon, 17 Jun 2024 12:31:31 +0200 Subject: [PATCH 141/201] Delay checking unknown critical signature subpackets (#1766) Throw when verifying signatures with unknown critical subpackets, instead of when parsing them. --- src/packet/signature.js | 21 +++++++++++++-------- test/general/signature.js | 22 ++++++++++++++++++++++ 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/packet/signature.js b/src/packet/signature.js index 43fc2002..78a7963b 100644 --- a/src/packet/signature.js +++ b/src/packet/signature.js @@ -67,6 +67,7 @@ class SignaturePacket { this.signatureData = null; this.unhashedSubpackets = []; + this.unknownSubpackets = []; this.signedHashValue = null; this.salt = null; @@ -595,14 +596,13 @@ class SignaturePacket { this.preferredCipherSuites.push([bytes[i], bytes[i + 1]]); } break; - default: { - const err = new Error(`Unknown signature subpacket type ${type}`); - if (critical) { - throw err; - } else { - util.printDebug(err); - } - } + default: + this.unknownSubpackets.push({ + type, + critical, + body: bytes.subarray(mypos, bytes.length) + }); + break; } } @@ -801,6 +801,11 @@ class SignaturePacket { [enums.signature.binary, enums.signature.text].includes(this.signatureType)) { throw new Error('Insecure message hash algorithm: ' + enums.read(enums.hash, this.hashAlgorithm).toUpperCase()); } + this.unknownSubpackets.forEach(({ type, critical }) => { + if (critical) { + throw new Error(`Unknown critical signature subpacket type ${type}`); + } + }); this.rawNotations.forEach(({ name, critical }) => { if (critical && (config.knownNotations.indexOf(name) < 0)) { throw new Error(`Unknown critical notation: ${name}`); diff --git a/test/general/signature.js b/test/general/signature.js index 20bd0c30..8d0de696 100644 --- a/test/general/signature.js +++ b/test/general/signature.js @@ -2493,4 +2493,26 @@ JImeZLY02MctIpGZULbqgcUGK0P/yqrPL8Pe4lQM const verified = await openpgp.verify({ verificationKeys: key, message }); expect(await verified.signatures[0].verified).to.be.true; }); + + it('Should parse a signature with a critical unknown subpacket, but not verify it', async function() { + const key = await openpgp.readKey({ + armoredKey: `-----BEGIN PGP PUBLIC KEY BLOCK----- + +xjMEZmsxYRYJKwYBBAHaRw8BAQdAgPH3tbfVO4CNqRQevvYW6kYY0qpNQltw +CegLonECw/vNBFRlc3TCwBgEEBYKAIoFgmZrMWEDCwkHCZAFbxb2+9/G3UUU +AAAAAAAcACBzYWx0QG5vdGF0aW9ucy5vcGVucGdwanMub3Jn1Bg/fpBZjM6n +CMTgcCh7+NHCoTmgpPef1+7CO792jL4FFQgKDA4EFgACAQIZAQKbAwIeARYh +BL/u0Jl6QJQVEZ0grQVvFvb738bdBOMBAgMAAMAYAQD25k4by+9P5WuOvirp +MhKE441PBb1n3fhaVpLogoVgZwD/ST2+Y5G6NdJM+U45iwfZDfa3ix1/zUSf +DF+cVdXVOwrOOARmazFhEgorBgEEAZdVAQUBAQdAGVw9vpajNPafAzshTmok +O1ZCDuQN9KkV+qTxZ7JGoEIDAQgHwsADBBgWCgB1BYJmazFhCZAFbxb2+9/G +3UUUAAAAAAAcACBzYWx0QG5vdGF0aW9ucy5vcGVucGdwanMub3JnRIP2KWB1 +C8+8vpmscsPPBl+KYeNcCbCOJqo7G3A5ES0CmwwWIQS/7tCZekCUFRGdIK0F +bxb2+9/G3QTjAQIDAABj9wEA2E/C98UXszf4TWH7/xBGICoDDNxceMhSDvtt +nYhoNlUA/Ar+Ofx+vMf9oYcNjPEbYu/yu1AtKY44aZvDBLK2+OAI +=YrJy +-----END PGP PUBLIC KEY BLOCK-----` + }); + await expect(key.verifyPrimaryKey()).to.be.rejectedWith(/Unknown critical signature subpacket type 99/); + }); }); From 9f5ff66c3def6d54e69edf40c8b9c2ecb40447b8 Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Mon, 17 Jun 2024 16:52:28 +0200 Subject: [PATCH 142/201] Store unhashed subpackets in a more structured format (#1767) To match the new `unknownSubpackets` property. --- openpgp.d.ts | 9 ++++++++- src/packet/signature.js | 18 ++++++++++-------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/openpgp.d.ts b/openpgp.d.ts index 795f3869..405a99b3 100644 --- a/openpgp.d.ts +++ b/openpgp.d.ts @@ -497,7 +497,8 @@ export class SignaturePacket extends BasePacket { public hashAlgorithm: enums.hash | null; public publicKeyAlgorithm: enums.publicKey | null; public signatureData: null | Uint8Array; - public unhashedSubpackets: null | Uint8Array; + public unhashedSubpackets: RawSubpacket[]; + public unknownSubpackets: RawSubpacket[]; public signedHashValue: null | Uint8Array; public created: Date | null; public signatureExpirationTime: null | number; @@ -541,6 +542,12 @@ export class SignaturePacket extends BasePacket { public getExpirationTime(): Date | typeof Infinity; } +export interface RawSubpacket { + type: number; + critical: boolean; + body: Uint8Array; +} + export interface RawNotation { name: string; value: Uint8Array; diff --git a/src/packet/signature.js b/src/packet/signature.js index 78a7963b..a6bbc8d5 100644 --- a/src/packet/signature.js +++ b/src/packet/signature.js @@ -396,10 +396,8 @@ class SignaturePacket { * @returns {Uint8Array} Subpacket data. */ writeUnhashedSubPackets() { - const arr = []; - this.unhashedSubpackets.forEach(data => { - arr.push(writeSimpleLength(data.length)); - arr.push(data); + const arr = this.unhashedSubpackets.map(({ type, critical, body }) => { + return writeSubPacket(type, critical, body); }); const result = util.concat(arr); @@ -408,7 +406,7 @@ class SignaturePacket { return util.concat([length, result]); } - // V4 signature sub packets + // Signature subpackets readSubPacket(bytes, hashed = true) { let mypos = 0; @@ -416,15 +414,19 @@ class SignaturePacket { const critical = !!(bytes[mypos] & 0x80); const type = bytes[mypos] & 0x7F; + mypos++; + if (!hashed) { - this.unhashedSubpackets.push(bytes.subarray(mypos, bytes.length)); + this.unhashedSubpackets.push({ + type, + critical, + body: bytes.subarray(mypos, bytes.length) + }); if (!allowedUnhashedSubpackets.has(type)) { return; } } - mypos++; - // subpacket type switch (type) { case enums.signatureSubpacket.signatureCreationTime: From 08b71487c59715d1dd2cc337c34e709da1c27721 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Wed, 15 May 2024 19:26:18 +0200 Subject: [PATCH 143/201] Detect invalid PKESK public point encoding on decryption We got a report of a message including a PKESK packet where the ECDH x25519Legacy point was missing the leading byte (0x40). While decryption naturally would naturally fail afterwards, this change ensures we fail at a higher level, and do not blindly pass down invalid data to the low-level crypto functions. --- src/crypto/public_key/elliptic/ecdh.js | 3 +- src/crypto/public_key/elliptic/oid_curves.js | 44 +++++++++++++++----- test/crypto/ecdh.js | 32 +++++++++----- 3 files changed, 58 insertions(+), 21 deletions(-) diff --git a/src/crypto/public_key/elliptic/ecdh.js b/src/crypto/public_key/elliptic/ecdh.js index 8bd03f82..cf6cbbed 100644 --- a/src/crypto/public_key/elliptic/ecdh.js +++ b/src/crypto/public_key/elliptic/ecdh.js @@ -21,7 +21,7 @@ */ import nacl from '@openpgp/tweetnacl'; -import { CurveWithOID, jwkToRawPublic, rawPublicToJWK, privateToJWK, validateStandardParams } from './oid_curves'; +import { CurveWithOID, jwkToRawPublic, rawPublicToJWK, privateToJWK, validateStandardParams, checkPublicPointEnconding } from './oid_curves'; import * as aesKW from '../../aes_kw'; import { getRandomBytes } from '../../random'; import hash from '../../hash'; @@ -193,6 +193,7 @@ async function genPrivateEphemeralKey(curve, V, Q, d) { */ export async function decrypt(oid, kdfParams, V, C, Q, d, fingerprint) { const curve = new CurveWithOID(oid); + checkPublicPointEnconding(oid, V); const { sharedKey } = await genPrivateEphemeralKey(curve, V, Q, d); const param = buildEcdhParam(enums.publicKey.ecdh, oid, kdfParams, fingerprint); const { keySize } = getCipherParams(kdfParams.cipher); diff --git a/src/crypto/public_key/elliptic/oid_curves.js b/src/crypto/public_key/elliptic/oid_curves.js index 5aeddfb6..b7c151dd 100644 --- a/src/crypto/public_key/elliptic/oid_curves.js +++ b/src/crypto/public_key/elliptic/oid_curves.js @@ -57,7 +57,8 @@ const curves = { node: nodeCurves[enums.curve.nistP256], web: webCurves[enums.curve.nistP256], payloadSize: 32, - sharedSize: 256 + sharedSize: 256, + wireFormatLeadingByte: 0x04 }, [enums.curve.nistP384]: { oid: [0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22], @@ -67,7 +68,8 @@ const curves = { node: nodeCurves[enums.curve.nistP384], web: webCurves[enums.curve.nistP384], payloadSize: 48, - sharedSize: 384 + sharedSize: 384, + wireFormatLeadingByte: 0x04 }, [enums.curve.nistP521]: { oid: [0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x23], @@ -77,7 +79,8 @@ const curves = { node: nodeCurves[enums.curve.nistP521], web: webCurves[enums.curve.nistP521], payloadSize: 66, - sharedSize: 528 + sharedSize: 528, + wireFormatLeadingByte: 0x04 }, [enums.curve.secp256k1]: { oid: [0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x0A], @@ -85,14 +88,16 @@ const curves = { hash: enums.hash.sha256, cipher: enums.symmetric.aes128, node: nodeCurves[enums.curve.secp256k1], - payloadSize: 32 + payloadSize: 32, + wireFormatLeadingByte: 0x04 }, [enums.curve.ed25519Legacy]: { oid: [0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, 0x01, 0xDA, 0x47, 0x0F, 0x01], keyType: enums.publicKey.eddsaLegacy, hash: enums.hash.sha512, node: false, // nodeCurves.ed25519 TODO - payloadSize: 32 + payloadSize: 32, + wireFormatLeadingByte: 0x40 }, [enums.curve.curve25519Legacy]: { oid: [0x06, 0x0A, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01], @@ -100,7 +105,8 @@ const curves = { hash: enums.hash.sha256, cipher: enums.symmetric.aes128, node: false, // nodeCurves.curve25519 TODO - payloadSize: 32 + payloadSize: 32, + wireFormatLeadingByte: 0x40 }, [enums.curve.brainpoolP256r1]: { oid: [0x06, 0x09, 0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x07], @@ -108,7 +114,8 @@ const curves = { hash: enums.hash.sha256, cipher: enums.symmetric.aes128, node: nodeCurves[enums.curve.brainpoolP256r1], - payloadSize: 32 + payloadSize: 32, + wireFormatLeadingByte: 0x04 }, [enums.curve.brainpoolP384r1]: { oid: [0x06, 0x09, 0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0B], @@ -116,7 +123,8 @@ const curves = { hash: enums.hash.sha384, cipher: enums.symmetric.aes192, node: nodeCurves[enums.curve.brainpoolP384r1], - payloadSize: 48 + payloadSize: 48, + wireFormatLeadingByte: 0x04 }, [enums.curve.brainpoolP512r1]: { oid: [0x06, 0x09, 0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0D], @@ -124,7 +132,8 @@ const curves = { hash: enums.hash.sha512, cipher: enums.symmetric.aes256, node: nodeCurves[enums.curve.brainpoolP512r1], - payloadSize: 64 + payloadSize: 64, + wireFormatLeadingByte: 0x04 } }; @@ -268,8 +277,23 @@ async function validateStandardParams(algo, oid, Q, d) { return true; } +/** + * Check whether the public point has a valid encoding. + * NB: this function does not check e.g. whether the point belongs to the curve. + */ +function checkPublicPointEnconding(oid, V) { + const curveName = oid.getName(); + const { payloadSize, wireFormatLeadingByte } = curves[curveName]; + + const pointSize = (curveName === enums.curve.curve25519Legacy || curveName === enums.curve.ed25519Legacy) ? payloadSize : payloadSize * 2; + + if (V[0] !== wireFormatLeadingByte || V.length !== pointSize + 1) { + throw new Error('Invalid point encoding'); + } +} + export { - CurveWithOID, curves, webCurves, nodeCurves, generate, getPreferredHashAlgo, jwkToRawPublic, rawPublicToJWK, privateToJWK, validateStandardParams + CurveWithOID, curves, webCurves, nodeCurves, generate, getPreferredHashAlgo, jwkToRawPublic, rawPublicToJWK, privateToJWK, validateStandardParams, checkPublicPointEnconding }; ////////////////////////// diff --git a/test/crypto/ecdh.js b/test/crypto/ecdh.js index f4dede03..54408418 100644 --- a/test/crypto/ecdh.js +++ b/test/crypto/ecdh.js @@ -72,14 +72,6 @@ export default () => describe('ECDH key exchange @lightweight', function () { '', 2, 7, [], [], [], [], [] )).to.be.rejectedWith(Error, /Unknown curve/).notify(done); }); - it('Invalid ephemeral key', function (done) { - if (!openpgp.config.useEllipticFallback && !util.getNodeCrypto()) { - this.skip(); - } - expect(decrypt_message( - 'secp256k1', 2, 7, [], [], [], [], [] - )).to.be.rejectedWith(Error, /Private key is not valid for specified curve|second arg must be public key/).notify(done); - }); it('Invalid elliptic public key', function (done) { if (!openpgp.config.useEllipticFallback && !util.getNodeCrypto()) { this.skip(); @@ -145,8 +137,8 @@ export default () => describe('ECDH key exchange @lightweight', function () { const kdfParams = new KDFParams({ hash: curve.hash, cipher: curve.cipher }); const data = random.getRandomBytes(16); await expect( - ecdh.encrypt(oid, kdfParams, data, Q1.subarray(1), fingerprint1) - ).to.be.rejectedWith(/Public key is not valid for specified curve|Failed to translate Buffer to a EC_POINT|second arg must be public key/); + ecdh.encrypt(oid, kdfParams, data, Q1, fingerprint1) + ).to.be.rejectedWith(/Invalid point encoding/); }); it('Different keys', async function () { @@ -212,6 +204,26 @@ export default () => describe('ECDH key exchange @lightweight', function () { const { publicKey: V, wrappedKey: C } = await ecdh.encrypt(oid, kdfParams, data, Q, fingerprint1); expect(await ecdh.decrypt(oid, kdfParams, V, C, Q, d, fingerprint1)).to.deep.equal(data); }); + + it(`${curveName} - Detect invalid PKESK public point encoding on decryption`, async function () { + const curve = new elliptic_curves.CurveWithOID(curveName); + const oid = new OID(curve.oid); + const kdfParams = new KDFParams({ hash: curve.hash, cipher: curve.cipher }); + const data = random.getRandomBytes(16); + const Q = key_data[curveName].pub; + const d = key_data[curveName].priv; + const { publicKey: V, wrappedKey: C } = await ecdh.encrypt(oid, kdfParams, data, Q, fingerprint1); + + const publicPointWithoutPrefixByte = V.subarray(1); + const publicPointWithUnexpectedPrefixByte = new Uint8Array([0x1, ...publicPointWithoutPrefixByte]); + const publicPointWithUnexpectedSize = V.subarray(0, V.length - 1); + + const expectedError = /Invalid point encoding/; + await expect(ecdh.decrypt(oid, kdfParams, publicPointWithoutPrefixByte, C, Q, d, fingerprint1)).to.be.rejectedWith(expectedError); + await expect(ecdh.decrypt(oid, kdfParams, publicPointWithUnexpectedPrefixByte, C, Q, d, fingerprint1)).to.be.rejectedWith(expectedError); + await expect(ecdh.decrypt(oid, kdfParams, publicPointWithUnexpectedSize, C, Q, d, fingerprint1)).to.be.rejectedWith(expectedError); + + }); }); describe('Comparing decrypting with and without native crypto', () => { From f8d0e6052fedd0064010ebff2a437e198c381cc1 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Thu, 16 May 2024 10:01:07 +0200 Subject: [PATCH 144/201] Detect invalid ECDSA, EdDSA and ECDH public key point encodings on usage We now throw on unexpected leading byte. This change is primarily intended to help with debugging, in case of malformed params. In fact, in case of wrong point size, the operations would already fail anyway, just in lower-level functions. --- src/crypto/public_key/elliptic/ecdh.js | 2 + src/crypto/public_key/elliptic/ecdsa.js | 4 +- .../public_key/elliptic/eddsa_legacy.js | 3 ++ test/crypto/elliptic.js | 51 ++++++++++--------- 4 files changed, 35 insertions(+), 25 deletions(-) diff --git a/src/crypto/public_key/elliptic/ecdh.js b/src/crypto/public_key/elliptic/ecdh.js index cf6cbbed..dcb8d6f2 100644 --- a/src/crypto/public_key/elliptic/ecdh.js +++ b/src/crypto/public_key/elliptic/ecdh.js @@ -131,6 +131,7 @@ export async function encrypt(oid, kdfParams, data, Q, fingerprint) { const m = pkcs5.encode(data); const curve = new CurveWithOID(oid); + checkPublicPointEnconding(oid, Q); const { publicKey, sharedKey } = await genPublicEphemeralKey(curve, Q); const param = buildEcdhParam(enums.publicKey.ecdh, oid, kdfParams, fingerprint); const { keySize } = getCipherParams(kdfParams.cipher); @@ -193,6 +194,7 @@ async function genPrivateEphemeralKey(curve, V, Q, d) { */ export async function decrypt(oid, kdfParams, V, C, Q, d, fingerprint) { const curve = new CurveWithOID(oid); + checkPublicPointEnconding(oid, Q); checkPublicPointEnconding(oid, V); const { sharedKey } = await genPrivateEphemeralKey(curve, V, Q, d); const param = buildEcdhParam(enums.publicKey.ecdh, oid, kdfParams, fingerprint); diff --git a/src/crypto/public_key/elliptic/ecdsa.js b/src/crypto/public_key/elliptic/ecdsa.js index 76fe73d1..0527c13a 100644 --- a/src/crypto/public_key/elliptic/ecdsa.js +++ b/src/crypto/public_key/elliptic/ecdsa.js @@ -24,7 +24,7 @@ import enums from '../../../enums'; import util from '../../../util'; import { getRandomBytes } from '../../random'; import hash from '../../hash'; -import { CurveWithOID, webCurves, privateToJWK, rawPublicToJWK, validateStandardParams, nodeCurves } from './oid_curves'; +import { CurveWithOID, webCurves, privateToJWK, rawPublicToJWK, validateStandardParams, nodeCurves, checkPublicPointEnconding } from './oid_curves'; import { bigIntToUint8Array } from '../../biginteger'; const webCrypto = util.getWebCrypto(); @@ -46,6 +46,7 @@ const nodeCrypto = util.getNodeCrypto(); */ export async function sign(oid, hashAlgo, message, publicKey, privateKey, hashed) { const curve = new CurveWithOID(oid); + checkPublicPointEnconding(oid, publicKey); if (message && !util.isStream(message)) { const keyPair = { publicKey, privateKey }; switch (curve.type) { @@ -92,6 +93,7 @@ export async function sign(oid, hashAlgo, message, publicKey, privateKey, hashed */ export async function verify(oid, hashAlgo, signature, message, publicKey, hashed) { const curve = new CurveWithOID(oid); + checkPublicPointEnconding(oid, publicKey); // See https://github.com/openpgpjs/openpgpjs/pull/948. // NB: the impact was more likely limited to Brainpool curves, since thanks // to WebCrypto availability, NIST curve should not have been affected. diff --git a/src/crypto/public_key/elliptic/eddsa_legacy.js b/src/crypto/public_key/elliptic/eddsa_legacy.js index 966f8dbe..b24ab161 100644 --- a/src/crypto/public_key/elliptic/eddsa_legacy.js +++ b/src/crypto/public_key/elliptic/eddsa_legacy.js @@ -25,6 +25,7 @@ import nacl from '@openpgp/tweetnacl'; import util from '../../../util'; import enums from '../../../enums'; import hash from '../../hash'; +import { checkPublicPointEnconding } from './oid_curves'; /** * Sign a message using the provided legacy EdDSA key @@ -41,6 +42,7 @@ import hash from '../../hash'; * @async */ export async function sign(oid, hashAlgo, message, publicKey, privateKey, hashed) { + checkPublicPointEnconding(oid, publicKey); if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(enums.hash.sha256)) { // see https://tools.ietf.org/id/draft-ietf-openpgp-rfc4880bis-10.html#section-15-7.2 throw new Error('Hash algorithm too weak for EdDSA.'); @@ -67,6 +69,7 @@ export async function sign(oid, hashAlgo, message, publicKey, privateKey, hashed * @async */ export async function verify(oid, hashAlgo, { r, s }, m, publicKey, hashed) { + checkPublicPointEnconding(oid, publicKey); if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(enums.hash.sha256)) { throw new Error('Hash algorithm too weak for EdDSA.'); } diff --git a/test/crypto/elliptic.js b/test/crypto/elliptic.js index 3f0a6383..80059cea 100644 --- a/test/crypto/elliptic.js +++ b/test/crypto/elliptic.js @@ -10,6 +10,7 @@ import config from '../../src/config'; import util from '../../src/util.js'; import elliptic_data from './elliptic_data'; +import OID from '../../src/type/oid.js'; const key_data = elliptic_data.key_data; /* eslint-disable no-invalid-this */ @@ -80,22 +81,25 @@ export default () => describe('Elliptic Curve Cryptography @lightweight', functi }); })); }); - it('Signature verification', function (done) { - expect( - elliptic_curves.ecdsa.verify('nistP256', 8, signature_data.signature, signature_data.message, signature_data.pub, signature_data.hashed) - ).to.eventually.be.true.notify(done); + it('Signature verification', async function () { + const curve = new elliptic_curves.CurveWithOID('nistP256'); + await expect( + elliptic_curves.ecdsa.verify(new OID(curve.oid), 8, signature_data.signature, signature_data.message, signature_data.pub, signature_data.hashed) + ).to.eventually.be.true; }); - it('Invalid signature', function (done) { - expect( - elliptic_curves.ecdsa.verify('nistP256', 8, signature_data.signature, signature_data.message, key_data.nistP256.pub, signature_data.hashed) - ).to.eventually.be.false.notify(done); + it('Invalid signature', async function () { + const curve = new elliptic_curves.CurveWithOID('nistP256'); + await expect( + elliptic_curves.ecdsa.verify(new OID(curve.oid), 8, signature_data.signature, signature_data.message, key_data.nistP256.pub, signature_data.hashed) + ).to.eventually.be.false; }); - it('Signature generation', function () { - return elliptic_curves.ecdsa.sign('nistP256', 8, signature_data.message, key_data.nistP256.pub, key_data.nistP256.priv, signature_data.hashed).then(async signature => { - await expect( - elliptic_curves.ecdsa.verify('nistP256', 8, signature, signature_data.message, key_data.nistP256.pub, signature_data.hashed) - ).to.eventually.be.true; - }); + it('Signature generation', async function () { + const curve = new elliptic_curves.CurveWithOID('nistP256'); + const oid = new OID(curve.oid); + const signature = await elliptic_curves.ecdsa.sign(oid, 8, signature_data.message, key_data.nistP256.pub, key_data.nistP256.priv, signature_data.hashed); + await expect( + elliptic_curves.ecdsa.verify(oid, 8, signature, signature_data.message, key_data.nistP256.pub, signature_data.hashed) + ).to.eventually.be.true; }); }); describe('ECDSA signature', function () { @@ -137,13 +141,15 @@ export default () => describe('Elliptic Curve Cryptography @lightweight', functi enableNative(); }; - const verify_signature = async function (oid, hash, r, s, message, pub) { + const verify_signature = async function (curveName, hash, r, s, message, pub) { if (util.isString(message)) { message = util.stringToUint8Array(message); } else if (!util.isUint8Array(message)) { message = new Uint8Array(message); } const ecdsa = elliptic_curves.ecdsa; + const curve = new elliptic_curves.CurveWithOID(curveName); + const oid = new OID(curve.oid); return ecdsa.verify( oid, hash, { r: new Uint8Array(r), s: new Uint8Array(s) }, message, new Uint8Array(pub), await hashMod.digest(hash, message) ); @@ -191,15 +197,10 @@ export default () => describe('Elliptic Curve Cryptography @lightweight', functi } await expect(verify_signature( 'secp256k1', 8, [], [], [], [] - )).to.eventually.be.false; + )).to.be.rejectedWith(/Invalid point encoding/); await expect(verify_signature( 'secp256k1', 8, [], [], [], secp256k1_invalid_point_format - )).to.eventually.be.false; - }); - it('secp256k1 - Invalid point', async function () { - if (!config.useEllipticFallback && !util.getNodeCrypto()) { - this.skip(); // webcrypto does not implement secp256k1: JS fallback tested instead - } + )).to.be.rejectedWith(/Invalid point encoding/); await expect(verify_signature( 'secp256k1', 8, [], [], [], secp256k1_invalid_point )).to.eventually.be.false; @@ -241,6 +242,8 @@ export default () => describe('Elliptic Curve Cryptography @lightweight', functi }); const curves = ['secp256k1' , 'nistP256', 'nistP384', 'nistP521', 'brainpoolP256r1', 'brainpoolP384r1', 'brainpoolP512r1']; curves.forEach(curveName => it(`${curveName} - Sign and verify message`, async function () { + const curve = new elliptic_curves.CurveWithOID(curveName); + const oid = new OID(curve.oid); const { Q: keyPublic, secret: keyPrivate } = await elliptic_curves.generate(curveName); const message = new Uint8Array([ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, @@ -248,8 +251,8 @@ export default () => describe('Elliptic Curve Cryptography @lightweight', functi ]); const messageDigest = await hashMod.digest(openpgp.enums.hash.sha512, message); await testNativeAndFallback(async () => { - const signature = await elliptic_curves.ecdsa.sign(curveName, openpgp.enums.hash.sha512, message, keyPublic, keyPrivate, messageDigest); - await expect(elliptic_curves.ecdsa.verify(curveName, openpgp.enums.hash.sha512, signature, message, keyPublic, messageDigest)).to.eventually.be.true; + const signature = await elliptic_curves.ecdsa.sign(oid, openpgp.enums.hash.sha512, message, keyPublic, keyPrivate, messageDigest); + await expect(elliptic_curves.ecdsa.verify(oid, openpgp.enums.hash.sha512, signature, message, keyPublic, messageDigest)).to.eventually.be.true; }); })); }); From 52611e7f26e69db3676c44fde8bf6b2f212b9744 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Thu, 16 May 2024 10:15:57 +0200 Subject: [PATCH 145/201] Detect unexpected eddsaLegacy OID on parsing --- src/crypto/crypto.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/crypto/crypto.js b/src/crypto/crypto.js index 683f3e57..d0c0fa7a 100644 --- a/src/crypto/crypto.js +++ b/src/crypto/crypto.js @@ -171,6 +171,9 @@ export function parsePublicKeyParams(algo, bytes) { case enums.publicKey.eddsaLegacy: { const oid = new OID(); read += oid.read(bytes); checkSupportedCurve(oid); + if (oid.getName() !== enums.curve.ed25519Legacy) { + throw new Error('Unexpected OID for eddsaLegacy'); + } let Q = util.readMPI(bytes.subarray(read)); read += Q.length + 2; Q = util.leftPad(Q, 33); return { read: read, publicParams: { oid, Q } }; @@ -227,6 +230,9 @@ export function parsePrivateKeyParams(algo, bytes, publicParams) { } case enums.publicKey.eddsaLegacy: { const payloadSize = getCurvePayloadSize(algo, publicParams.oid); + if (publicParams.oid.getName() !== enums.curve.ed25519Legacy) { + throw new Error('Unexpected OID for eddsaLegacy'); + } let seed = util.readMPI(bytes.subarray(read)); read += seed.length + 2; seed = util.leftPad(seed, payloadSize); return { read, privateParams: { seed } }; From cf94380e260e6f1183d968e6c235ecbb83e52a88 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Thu, 16 May 2024 16:45:18 +0200 Subject: [PATCH 146/201] Read `wireFormatLeadingByte` value from curve object --- src/crypto/public_key/elliptic/ecdh.js | 4 ++-- src/crypto/public_key/elliptic/oid_curves.js | 15 ++++++++------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/crypto/public_key/elliptic/ecdh.js b/src/crypto/public_key/elliptic/ecdh.js index dcb8d6f2..e597b7cd 100644 --- a/src/crypto/public_key/elliptic/ecdh.js +++ b/src/crypto/public_key/elliptic/ecdh.js @@ -95,7 +95,7 @@ async function genPublicEphemeralKey(curve, Q) { const d = getRandomBytes(32); const { secretKey, sharedKey } = await genPrivateEphemeralKey(curve, Q, null, d); let { publicKey } = nacl.box.keyPair.fromSecretKey(secretKey); - publicKey = util.concatUint8Array([new Uint8Array([0x40]), publicKey]); + publicKey = util.concatUint8Array([new Uint8Array([curve.wireFormatLeadingByte]), publicKey]); return { publicKey, sharedKey }; // Note: sharedKey is little-endian here, unlike below } case 'web': @@ -327,7 +327,7 @@ async function webPublicEphemeralKey(curve, Q) { ); [s, p] = await Promise.all([s, p]); const sharedKey = new Uint8Array(s); - const publicKey = new Uint8Array(jwkToRawPublic(p)); + const publicKey = new Uint8Array(jwkToRawPublic(p, curve.wireFormatLeadingByte)); return { publicKey, sharedKey }; } diff --git a/src/crypto/public_key/elliptic/oid_curves.js b/src/crypto/public_key/elliptic/oid_curves.js index b7c151dd..b4526ee7 100644 --- a/src/crypto/public_key/elliptic/oid_curves.js +++ b/src/crypto/public_key/elliptic/oid_curves.js @@ -157,6 +157,7 @@ class CurveWithOID { this.web = params.web; this.payloadSize = params.payloadSize; this.sharedSize = params.sharedSize; + this.wireFormatLeadingByte = params.wireFormatLeadingByte; if (this.web && util.getWebCrypto()) { this.type = 'web'; } else if (this.node && util.getNodeCrypto()) { @@ -172,7 +173,7 @@ class CurveWithOID { switch (this.type) { case 'web': try { - return await webGenKeyPair(this.name); + return await webGenKeyPair(this.name, this.wireFormatLeadingByte); } catch (err) { util.printDebugError('Browser did not support generating ec key ' + err.message); return jsGenKeyPair(this.name); @@ -185,13 +186,13 @@ class CurveWithOID { privateKey[31] &= 248; const secretKey = privateKey.slice().reverse(); const { publicKey: rawPublicKey } = nacl.box.keyPair.fromSecretKey(secretKey); - const publicKey = util.concatUint8Array([new Uint8Array([0x40]), rawPublicKey]); + const publicKey = util.concatUint8Array([new Uint8Array([this.wireFormatLeadingByte]), rawPublicKey]); return { publicKey, privateKey }; } case 'ed25519Legacy': { const privateKey = getRandomBytes(32); const keyPair = nacl.sign.keyPair.fromSeed(privateKey); - const publicKey = util.concatUint8Array([new Uint8Array([0x40]), keyPair.publicKey]); + const publicKey = util.concatUint8Array([new Uint8Array([this.wireFormatLeadingByte]), keyPair.publicKey]); return { publicKey, privateKey }; } default: @@ -308,7 +309,7 @@ async function jsGenKeyPair(name) { return { publicKey, privateKey }; } -async function webGenKeyPair(name) { +async function webGenKeyPair(name, wireFormatLeadingByte) { // Note: keys generated with ECDSA and ECDH are structurally equivalent const webCryptoKey = await webCrypto.generateKey({ name: 'ECDSA', namedCurve: webCurves[name] }, true, ['sign', 'verify']); @@ -316,7 +317,7 @@ async function webGenKeyPair(name) { const publicKey = await webCrypto.exportKey('jwk', webCryptoKey.publicKey); return { - publicKey: jwkToRawPublic(publicKey), + publicKey: jwkToRawPublic(publicKey, wireFormatLeadingByte), privateKey: b64ToUint8Array(privateKey.d, true) }; } @@ -342,11 +343,11 @@ async function nodeGenKeyPair(name) { * * @returns {Uint8Array} Raw public key. */ -function jwkToRawPublic(jwk) { +function jwkToRawPublic(jwk, wireFormatLeadingByte) { const bufX = b64ToUint8Array(jwk.x); const bufY = b64ToUint8Array(jwk.y); const publicKey = new Uint8Array(bufX.length + bufY.length + 1); - publicKey[0] = 0x04; + publicKey[0] = wireFormatLeadingByte; publicKey.set(bufX, 1); publicKey.set(bufY, bufX.length + 1); return publicKey; From 12fb9163600245431f8857296a412d7521929fe4 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Thu, 16 May 2024 17:06:57 +0200 Subject: [PATCH 147/201] Pass curve object instead of oid to `checkPublicPointEnconding` --- src/crypto/public_key/elliptic/ecdh.js | 6 +++--- src/crypto/public_key/elliptic/ecdsa.js | 4 ++-- src/crypto/public_key/elliptic/eddsa_legacy.js | 8 +++++--- src/crypto/public_key/elliptic/oid_curves.js | 5 ++--- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/crypto/public_key/elliptic/ecdh.js b/src/crypto/public_key/elliptic/ecdh.js index e597b7cd..b57362a8 100644 --- a/src/crypto/public_key/elliptic/ecdh.js +++ b/src/crypto/public_key/elliptic/ecdh.js @@ -131,7 +131,7 @@ export async function encrypt(oid, kdfParams, data, Q, fingerprint) { const m = pkcs5.encode(data); const curve = new CurveWithOID(oid); - checkPublicPointEnconding(oid, Q); + checkPublicPointEnconding(curve, Q); const { publicKey, sharedKey } = await genPublicEphemeralKey(curve, Q); const param = buildEcdhParam(enums.publicKey.ecdh, oid, kdfParams, fingerprint); const { keySize } = getCipherParams(kdfParams.cipher); @@ -194,8 +194,8 @@ async function genPrivateEphemeralKey(curve, V, Q, d) { */ export async function decrypt(oid, kdfParams, V, C, Q, d, fingerprint) { const curve = new CurveWithOID(oid); - checkPublicPointEnconding(oid, Q); - checkPublicPointEnconding(oid, V); + checkPublicPointEnconding(curve, Q); + checkPublicPointEnconding(curve, V); const { sharedKey } = await genPrivateEphemeralKey(curve, V, Q, d); const param = buildEcdhParam(enums.publicKey.ecdh, oid, kdfParams, fingerprint); const { keySize } = getCipherParams(kdfParams.cipher); diff --git a/src/crypto/public_key/elliptic/ecdsa.js b/src/crypto/public_key/elliptic/ecdsa.js index 0527c13a..b0797963 100644 --- a/src/crypto/public_key/elliptic/ecdsa.js +++ b/src/crypto/public_key/elliptic/ecdsa.js @@ -46,7 +46,7 @@ const nodeCrypto = util.getNodeCrypto(); */ export async function sign(oid, hashAlgo, message, publicKey, privateKey, hashed) { const curve = new CurveWithOID(oid); - checkPublicPointEnconding(oid, publicKey); + checkPublicPointEnconding(curve, publicKey); if (message && !util.isStream(message)) { const keyPair = { publicKey, privateKey }; switch (curve.type) { @@ -93,7 +93,7 @@ export async function sign(oid, hashAlgo, message, publicKey, privateKey, hashed */ export async function verify(oid, hashAlgo, signature, message, publicKey, hashed) { const curve = new CurveWithOID(oid); - checkPublicPointEnconding(oid, publicKey); + checkPublicPointEnconding(curve, publicKey); // See https://github.com/openpgpjs/openpgpjs/pull/948. // NB: the impact was more likely limited to Brainpool curves, since thanks // to WebCrypto availability, NIST curve should not have been affected. diff --git a/src/crypto/public_key/elliptic/eddsa_legacy.js b/src/crypto/public_key/elliptic/eddsa_legacy.js index b24ab161..b564b176 100644 --- a/src/crypto/public_key/elliptic/eddsa_legacy.js +++ b/src/crypto/public_key/elliptic/eddsa_legacy.js @@ -25,7 +25,7 @@ import nacl from '@openpgp/tweetnacl'; import util from '../../../util'; import enums from '../../../enums'; import hash from '../../hash'; -import { checkPublicPointEnconding } from './oid_curves'; +import { CurveWithOID, checkPublicPointEnconding } from './oid_curves'; /** * Sign a message using the provided legacy EdDSA key @@ -42,7 +42,8 @@ import { checkPublicPointEnconding } from './oid_curves'; * @async */ export async function sign(oid, hashAlgo, message, publicKey, privateKey, hashed) { - checkPublicPointEnconding(oid, publicKey); + const curve = new CurveWithOID(oid); + checkPublicPointEnconding(curve, publicKey); if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(enums.hash.sha256)) { // see https://tools.ietf.org/id/draft-ietf-openpgp-rfc4880bis-10.html#section-15-7.2 throw new Error('Hash algorithm too weak for EdDSA.'); @@ -69,7 +70,8 @@ export async function sign(oid, hashAlgo, message, publicKey, privateKey, hashed * @async */ export async function verify(oid, hashAlgo, { r, s }, m, publicKey, hashed) { - checkPublicPointEnconding(oid, publicKey); + const curve = new CurveWithOID(oid); + checkPublicPointEnconding(curve, publicKey); if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(enums.hash.sha256)) { throw new Error('Hash algorithm too weak for EdDSA.'); } diff --git a/src/crypto/public_key/elliptic/oid_curves.js b/src/crypto/public_key/elliptic/oid_curves.js index b4526ee7..079c6f43 100644 --- a/src/crypto/public_key/elliptic/oid_curves.js +++ b/src/crypto/public_key/elliptic/oid_curves.js @@ -282,9 +282,8 @@ async function validateStandardParams(algo, oid, Q, d) { * Check whether the public point has a valid encoding. * NB: this function does not check e.g. whether the point belongs to the curve. */ -function checkPublicPointEnconding(oid, V) { - const curveName = oid.getName(); - const { payloadSize, wireFormatLeadingByte } = curves[curveName]; +function checkPublicPointEnconding(curve, V) { + const { payloadSize, wireFormatLeadingByte, name: curveName } = curve; const pointSize = (curveName === enums.curve.curve25519Legacy || curveName === enums.curve.ed25519Legacy) ? payloadSize : payloadSize * 2; From 7af16be62b2c11033badb7564ad7fde0cdb61b1e Mon Sep 17 00:00:00 2001 From: larabr Date: Tue, 25 Jun 2024 12:50:26 +0200 Subject: [PATCH 148/201] Use positive cert for self-signatures (#1769) To uniform behaviour with other openpgp libs. --- src/key/factory.js | 2 +- src/key/helper.js | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/key/factory.js b/src/key/factory.js index ad542640..e66eaa10 100644 --- a/src/key/factory.js +++ b/src/key/factory.js @@ -257,7 +257,7 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, conf key: secretKeyPacket }; const signatureProperties = secretKeyPacket.version !== 6 ? getKeySignatureProperties() : {}; - signatureProperties.signatureType = enums.signature.certGeneric; + signatureProperties.signatureType = enums.signature.certPositive; if (index === 0) { signatureProperties.isPrimaryUserID = true; } diff --git a/src/key/helper.js b/src/key/helper.js index 9425ebf8..2388a39a 100644 --- a/src/key/helper.js +++ b/src/key/helper.js @@ -35,6 +35,8 @@ export async function generateSecretKey(options, config) { * Returns the valid and non-expired signature that has the latest creation date, while ignoring signatures created in the future. * @param {Array} signatures - List of signatures * @param {PublicKeyPacket|PublicSubkeyPacket} publicKey - Public key packet to verify the signature + * @param {module:enums.signature} signatureType - Signature type to determine how to hash the data (NB: for userID signatures, + * `enums.signatures.certGeneric` should be given regardless of the actual trust level) * @param {Date} date - Use the given date instead of the current time * @param {Object} config - full configuration * @returns {Promise} The latest valid signature. From 8d11c5fd0fd0c2ec27efeeda15ce26e6d438faaa Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Wed, 26 Jun 2024 12:01:10 +0200 Subject: [PATCH 149/201] Drop support for Node 16 and 17 --- .github/workflows/tests.yml | 2 +- README.md | 4 ++-- package-lock.json | 46 ++++++++++++++++++------------------- package.json | 8 +++---- rollup.config.js | 2 +- 5 files changed, 31 insertions(+), 31 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 609c3087..fad99b2d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -31,7 +31,7 @@ jobs: strategy: fail-fast: false # if tests for one version fail, continue with the rest matrix: - node-version: [16.x, 18.x, '20.x'] + node-version: [18.x, 20.x] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ name: Node ${{ matrix.node-version }} diff --git a/README.md b/README.md index c70e6822..0ae026c8 100644 --- a/README.md +++ b/README.md @@ -33,9 +33,9 @@ OpenPGP.js [![BrowserStack Status](https://automate.browserstack.com/badge.svg?b ### Platform Support -* The `dist/openpgp.min.js` (or `.mjs`) bundle works with recent versions of Chrome, Firefox, Edge and Safari 13+. +* The `dist/openpgp.min.js` (or `.mjs`) bundle works with recent versions of Chrome, Firefox, Edge and Safari 14+. -* The `dist/node/openpgp.min.mjs` (or `.cjs`) bundle works in Node.js v16+: it is used by default when you `import ... from 'openpgp'` (resp. `require('openpgp')`). +* The `dist/node/openpgp.min.mjs` (or `.cjs`) bundle works in Node.js v18+: it is used by default when you `import ... from 'openpgp'` (resp. `require('openpgp')`). * Streaming support: the latest versions of Chrome, Firefox, Edge and Safari implement the [Streams specification](https://streams.spec.whatwg.org/), including `TransformStream`s. diff --git a/package-lock.json b/package-lock.json index c0236407..ca74ff82 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "@openpgp/jsdoc": "^3.6.11", "@openpgp/seek-bzip": "^1.0.5-git", "@openpgp/tweetnacl": "^1.0.4-1", - "@openpgp/web-stream-tools": "~0.1.2", + "@openpgp/web-stream-tools": "~0.1.3", "@rollup/plugin-alias": "^5.1.0", "@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-node-resolve": "^15.2.3", @@ -56,11 +56,11 @@ "ts-node": "^10.9.2", "tslib": "^2.6.2", "tsx": "^4.10.4", - "typescript": "^5.4.5", - "web-streams-polyfill": "^3.3.3" + "typescript": "^5.5.2", + "web-streams-polyfill": "^4.0.0" }, "engines": { - "node": ">= 16.5.0" + "node": ">= 18.0.0" } }, "node_modules/@babel/code-frame": { @@ -915,12 +915,12 @@ "dev": true }, "node_modules/@openpgp/web-stream-tools": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@openpgp/web-stream-tools/-/web-stream-tools-0.1.2.tgz", - "integrity": "sha512-uyTIFj6kjYMmeTv1bTIUcaTjC34ewpHny3XE+CvRCWGom642YCtIfd+6JFdemPgp18ZZc/u11D1SU16lpH3l0w==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@openpgp/web-stream-tools/-/web-stream-tools-0.1.3.tgz", + "integrity": "sha512-mT/ds43cH6c+AO5RFpxs+LkACr7KjC3/dZWHrP6KPrWJu4uJ/XJ+p7telaoYiqUfdjiiIvdNSOfhezW9fkmboQ==", "dev": true, "engines": { - "node": ">= 16.5.0" + "node": ">= 18.0.0" }, "peerDependencies": { "typescript": ">=4.2" @@ -8136,9 +8136,9 @@ } }, "node_modules/typescript": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", + "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -8320,9 +8320,9 @@ } }, "node_modules/web-streams-polyfill": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", - "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0.tgz", + "integrity": "sha512-0zJXHRAYEjM2tUfZ2DiSOHAa2aw1tisnnhU3ufD57R8iefL+DcdJyRBRyJpG+NUimDgbTI/lH+gAE1PAvV3Cgw==", "dev": true, "engines": { "node": ">= 8" @@ -9127,9 +9127,9 @@ "dev": true }, "@openpgp/web-stream-tools": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@openpgp/web-stream-tools/-/web-stream-tools-0.1.2.tgz", - "integrity": "sha512-uyTIFj6kjYMmeTv1bTIUcaTjC34ewpHny3XE+CvRCWGom642YCtIfd+6JFdemPgp18ZZc/u11D1SU16lpH3l0w==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@openpgp/web-stream-tools/-/web-stream-tools-0.1.3.tgz", + "integrity": "sha512-mT/ds43cH6c+AO5RFpxs+LkACr7KjC3/dZWHrP6KPrWJu4uJ/XJ+p7telaoYiqUfdjiiIvdNSOfhezW9fkmboQ==", "dev": true, "requires": {} }, @@ -14496,9 +14496,9 @@ } }, "typescript": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", + "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", "dev": true }, "ua-parser-js": { @@ -14625,9 +14625,9 @@ "dev": true }, "web-streams-polyfill": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", - "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0.tgz", + "integrity": "sha512-0zJXHRAYEjM2tUfZ2DiSOHAa2aw1tisnnhU3ufD57R8iefL+DcdJyRBRyJpG+NUimDgbTI/lH+gAE1PAvV3Cgw==", "dev": true }, "whatwg-encoding": { diff --git a/package.json b/package.json index f884af52..6a06fd28 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "license": "LGPL-3.0+", "homepage": "https://openpgpjs.org/", "engines": { - "node": ">= 16.5.0" + "node": ">= 18.0.0" }, "keywords": [ "crypto", @@ -68,7 +68,7 @@ "@openpgp/jsdoc": "^3.6.11", "@openpgp/seek-bzip": "^1.0.5-git", "@openpgp/tweetnacl": "^1.0.4-1", - "@openpgp/web-stream-tools": "~0.1.2", + "@openpgp/web-stream-tools": "~0.1.3", "@rollup/plugin-alias": "^5.1.0", "@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-node-resolve": "^15.2.3", @@ -109,8 +109,8 @@ "ts-node": "^10.9.2", "tslib": "^2.6.2", "tsx": "^4.10.4", - "typescript": "^5.4.5", - "web-streams-polyfill": "^3.3.3" + "typescript": "^5.5.2", + "web-streams-polyfill": "^4.0.0" }, "repository": { "type": "git", diff --git a/rollup.config.js b/rollup.config.js index 87050ee8..ca145fc9 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -89,7 +89,7 @@ export default Object.assign([ ].map(options => ({ ...options, inlineDynamicImports: true })), plugins: [ resolve({ - exportConditions: ['node'] // needed for resolution of noble-curves import of '@noble/crypto' in Node 16 and 18 + exportConditions: ['node'] // needed for resolution of noble-curves import of '@noble/crypto' in Node 18 }), typescript({ compilerOptions: { outDir: './dist/tmp-ts' } From 9efdaf14b1dd3523c4ba98c1601a6a8e9cf4f5fe Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Wed, 3 Jul 2024 22:00:29 +0200 Subject: [PATCH 150/201] Let hard revocations apply at any time (#1773) "Hard" revocations (i.e. key compromise, and unknown reasons) apply at any time, even before the revocation was created. Co-authored-by: larabr --- src/key/helper.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/key/helper.js b/src/key/helper.js index 2388a39a..16f47acd 100644 --- a/src/key/helper.js +++ b/src/key/helper.js @@ -283,8 +283,14 @@ export async function isDataRevoked(primaryKey, signatureType, dataToVerify, rev // `verifyAllCertifications`.) !signature || revocationSignature.issuerKeyID.equals(signature.issuerKeyID) ) { + const isHardRevocation = ![ + enums.reasonForRevocation.keyRetired, + enums.reasonForRevocation.keySuperseded, + enums.reasonForRevocation.userIDInvalid + ].includes(revocationSignature.reasonForRevocationFlag); + await revocationSignature.verify( - key, signatureType, dataToVerify, date, false, config + key, signatureType, dataToVerify, isHardRevocation ? null : date, false, config ); // TODO get an identifier of the revoked object instead From 5268c484e995abccb47675565484123caec03881 Mon Sep 17 00:00:00 2001 From: larabr Date: Thu, 4 Jul 2024 13:59:40 +0200 Subject: [PATCH 151/201] Disable support for parsing v5 entities by default (add `config.enableParsingV5Entities`) (#1774) Parsing of v5 keys, v5 signatures and AEAD-encrypted data packets now requires turning on the corresponding config flag. The affected entities are non-standard, and in the crypto-refresh RFC they have been superseded by v6 keys, v6 signatures and SEIPDv2 encrypted data, respectively. However, generation of v5 entities was supported behind config flag in OpenPGP.js v5, and some other libraries, hence parsing them might be necessary in some cases. --- src/config/config.js | 9 +++++++++ src/packet/aead_encrypted_data.js | 5 ++++- src/packet/public_key.js | 5 ++++- src/packet/secret_key.js | 2 +- src/packet/signature.js | 5 ++++- test/general/key.js | 29 ++++++++++++++--------------- test/general/packet.js | 14 +++++++------- test/general/signature.js | 7 ++++--- 8 files changed, 47 insertions(+), 29 deletions(-) diff --git a/src/config/config.js b/src/config/config.js index 866a0c34..5e4ae45e 100644 --- a/src/config/config.js +++ b/src/config/config.js @@ -81,6 +81,15 @@ export default { * @property {Boolean} v6Keys */ v6Keys: false, + /** + * Enable parsing v5 keys, v5 signatures and AEAD-encrypted data packets + * (which is different from the AEAD-encrypted SEIPDv2 packet). + * These are non-standard entities, which in the crypto-refresh have been superseded + * by v6 keys, v6 signatures and SEIPDv2 encrypted data, respectively. + * However, generation of v5 entities was supported behind config flag in OpenPGP.js v5, and some other libraries, + * hence parsing them might be necessary in some cases. + */ + enableParsingV5Entities: false, /** * S2K (String to Key) type, used for key derivation in the context of secret key encryption * and password-encrypted data. Weaker s2k options are not allowed. diff --git a/src/packet/aead_encrypted_data.js b/src/packet/aead_encrypted_data.js index 60bdc3a7..492fa8ef 100644 --- a/src/packet/aead_encrypted_data.js +++ b/src/packet/aead_encrypted_data.js @@ -68,7 +68,10 @@ class AEADEncryptedDataPacket { * @param {Uint8Array | ReadableStream} bytes * @throws {Error} on parsing failure */ - async read(bytes) { + async read(bytes, config = defaultConfig) { + if (!config.enableParsingV5Entities) { + throw new UnsupportedError('Support for parsing v5 entities is disabled; turn on `config.enableParsingV5Entities` if needed'); + } await stream.parse(bytes, async reader => { const version = await reader.readByte(); if (version !== VERSION) { // The only currently defined value is 1. diff --git a/src/packet/public_key.js b/src/packet/public_key.js index 17732e07..c3b13071 100644 --- a/src/packet/public_key.js +++ b/src/packet/public_key.js @@ -104,10 +104,13 @@ class PublicKeyPacket { * @returns {Object} This object with attributes set by the parser * @async */ - async read(bytes) { + async read(bytes, config = defaultConfig) { let pos = 0; // A one-octet version number (4, 5 or 6). this.version = bytes[pos++]; + if (this.version === 5 && !config.enableParsingV5Entities) { + throw new UnsupportedError('Support for parsing v5 entities is disabled; turn on `config.enableParsingV5Entities` if needed'); + } if (this.version === 4 || this.version === 5 || this.version === 6) { // - A four-octet number denoting the time that the key was created. diff --git a/src/packet/secret_key.js b/src/packet/secret_key.js index 2cdac5b6..2257a78b 100644 --- a/src/packet/secret_key.js +++ b/src/packet/secret_key.js @@ -102,7 +102,7 @@ class SecretKeyPacket extends PublicKeyPacket { */ async read(bytes, config = defaultConfig) { // - A Public-Key or Public-Subkey packet, as described above. - let i = await this.readPublicKey(bytes); + let i = await this.readPublicKey(bytes, config); const startOfSecretKeyData = i; // - One octet indicating string-to-key usage conventions. Zero diff --git a/src/packet/signature.js b/src/packet/signature.js index a6bbc8d5..87e0d304 100644 --- a/src/packet/signature.js +++ b/src/packet/signature.js @@ -117,9 +117,12 @@ class SignaturePacket { * @param {String} bytes - Payload of a tag 2 packet * @returns {SignaturePacket} Object representation. */ - read(bytes) { + read(bytes, config = defaultConfig) { let i = 0; this.version = bytes[i++]; + if (this.version === 5 && !config.enableParsingV5Entities) { + throw new UnsupportedError('Support for v5 entities is disabled; turn on `config.enableParsingV5Entities` if needed'); + } if (this.version !== 4 && this.version !== 5 && this.version !== 6) { throw new UnsupportedError(`Version ${this.version} of the signature packet is unsupported.`); diff --git a/test/general/key.js b/test/general/key.js index 570671fd..0ff089b1 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -2951,19 +2951,6 @@ function versionSpecificTests() { await expect(privateKey.verifyPrimaryKey()).to.be.fulfilled; }); }); - - - it('Parses V5 sample key', async function() { - // sec ed25519 2019-03-20 [SC] - // 19347BC9872464025F99DF3EC2E0000ED9884892E1F7B3EA4C94009159569B54 - // uid emma.goldman@example.net - // ssb cv25519 2019-03-20 [E] - // E4557C2B02FFBF4B04F87401EC336AF7133D0F85BE7FD09BAEFD9CAEB8C93965 - const key = await openpgp.readKey({ armoredKey: v5_sample_key }); - expect(await key.keyPacket.getFingerprint()).to.equal('19347bc9872464025f99df3ec2e0000ed9884892e1f7b3ea4c94009159569b54'); - expect(await key.subkeys[0].getFingerprint()).to.equal('e4557c2b02ffbf4b04f87401ec336af7133d0f85be7fd09baefd9caeb8c93965'); - await key.verifyPrimaryKey(); - }); } export default () => describe('Key', function() { @@ -3032,6 +3019,18 @@ export default () => describe('Key', function() { expect(key.write()).to.deep.equal(expectedSerializedKey.data); }); + it('Parses V5 sample key', async function() { + // sec ed25519 2019-03-20 [SC] + // 19347BC9872464025F99DF3EC2E0000ED9884892E1F7B3EA4C94009159569B54 + // uid emma.goldman@example.net + // ssb cv25519 2019-03-20 [E] + // E4557C2B02FFBF4B04F87401EC336AF7133D0F85BE7FD09BAEFD9CAEB8C93965 + const key = await openpgp.readKey({ armoredKey: v5_sample_key, config: { enableParsingV5Entities: true } }); + expect(await key.keyPacket.getFingerprint()).to.equal('19347bc9872464025f99df3ec2e0000ed9884892e1f7b3ea4c94009159569b54'); + expect(await key.subkeys[0].getFingerprint()).to.equal('e4557c2b02ffbf4b04f87401ec336af7133d0f85be7fd09baefd9caeb8c93965'); + await key.verifyPrimaryKey(); + }); + it('Parsing V5 public key packet', async function() { // Manually modified from https://gitlab.com/openpgp-wg/rfc4880bis/blob/00b2092/back.mkd#sample-eddsa-key const packetBytes = util.hexToUint8Array(` @@ -3065,7 +3064,7 @@ T/efFOC6BDkAAHcjAPwIPNHnR9bKmkVop6cE05dCIpZ/W8zXDGnjKYrrC4Hb =wpkQ -----END PGP PRIVATE KEY BLOCK-----`; const passphrase = 'password'; - const encryptedKey = await openpgp.readKey({ armoredKey }); + const encryptedKey = await openpgp.readKey({ armoredKey, config: { enableParsingV5Entities: true } }); const decryptedKey = await openpgp.decryptKey({ privateKey: encryptedKey, passphrase @@ -3485,7 +3484,7 @@ PzIEeL7UH3trraFmi+Gq8u4kAA== }); it('should pad an ECDSA P-521 key with shorter secret key', async function() { - const key = await openpgp.readKey({ armoredKey: shortP521Key }); + const key = await openpgp.readKey({ armoredKey: shortP521Key, config: { enableParsingV5Entities: true } }); // secret key should be padded expect(key.keyPacket.privateParams.d.length === 66); // sanity check diff --git a/test/general/packet.js b/test/general/packet.js index 78f5d621..5d7449b5 100644 --- a/test/general/packet.js +++ b/test/general/packet.js @@ -174,7 +174,7 @@ export default () => describe('Packet', function() { const msg2 = new openpgp.PacketList(); return enc.encrypt(algo, key, undefined, openpgp.config).then(async function() { - await msg2.read(msg.write(), allAllowedPackets); + await msg2.read(msg.write(), allAllowedPackets, { ...openpgp.config, enableParsingV5Entities: true }); return msg2[0].decrypt(algo, key); }).then(async function() { expect(await stream.readToEnd(msg2[0].packets[0].data)).to.deep.equal(literal.data); @@ -229,7 +229,7 @@ export default () => describe('Packet', function() { try { await enc.encrypt(algo, key, { ...openpgp.config, aeadChunkSizeByte: 0 }); - await msg2.read(msg.write(), allAllowedPackets); + await msg2.read(msg.write(), allAllowedPackets, { ...openpgp.config, enableParsingV5Entities: true }); await msg2[0].decrypt(algo, key); expect(await stream.readToEnd(msg2[0].packets[0].data)).to.deep.equal(literal.data); expect(encryptStub.callCount > 1).to.be.true; @@ -276,7 +276,7 @@ export default () => describe('Packet', function() { await enc.encrypt(algo, key, { ...openpgp.config, aeadChunkSizeByte: 14 }); const data = msg.write(); expect(await stream.readToEnd(stream.clone(data))).to.deep.equal(packetBytes); - await msg2.read(data, allAllowedPackets); + await msg2.read(data, allAllowedPackets, { ...openpgp.config, enableParsingV5Entities: true }); await msg2[0].decrypt(algo, key); expect(await stream.readToEnd(msg2[0].packets[0].data)).to.deep.equal(literal.data); } finally { @@ -706,7 +706,7 @@ export default () => describe('Packet', function() { await aeadEnc.encrypt(algo, key, undefined, openpgp.config); const msg2 = new openpgp.PacketList(); - await msg2.read(msg.write(), allAllowedPackets); + await msg2.read(msg.write(), allAllowedPackets, { ...openpgp.config, enableParsingV5Entities: true }); await msg2[0].decrypt(passphrase); const key2 = msg2[0].sessionKey; @@ -744,7 +744,7 @@ export default () => describe('Packet', function() { await aeadEnc.encrypt(algo, key, undefined, openpgp.config); const msg2 = new openpgp.PacketList(); - await msg2.read(msg.write(), allAllowedPackets); + await msg2.read(msg.write(), allAllowedPackets, { ...openpgp.config, enableParsingV5Entities: true }); await msg2[0].decrypt(passphrase); const key2 = msg2[0].sessionKey; @@ -820,7 +820,7 @@ export default () => describe('Packet', function() { expect(await stream.readToEnd(stream.clone(data))).to.deep.equal(packetBytes); const msg2 = new openpgp.PacketList(); - await msg2.read(data, allAllowedPackets); + await msg2.read(data, allAllowedPackets, { ...openpgp.config, enableParsingV5Entities: true }); await msg2[0].decrypt(passphrase); const key2 = msg2[0].sessionKey; @@ -899,7 +899,7 @@ export default () => describe('Packet', function() { expect(await stream.readToEnd(stream.clone(data))).to.deep.equal(packetBytes); const msg2 = new openpgp.PacketList(); - await msg2.read(data, allAllowedPackets); + await msg2.read(data, allAllowedPackets, { ...openpgp.config, enableParsingV5Entities: true }); await msg2[0].decrypt(passphrase); const key2 = msg2[0].sessionKey; diff --git a/test/general/signature.js b/test/general/signature.js index 8d0de696..648dd890 100644 --- a/test/general/signature.js +++ b/test/general/signature.js @@ -2417,7 +2417,7 @@ oaBUyhCKt8tz6Q== -----END PGP PRIVATE KEY BLOCK-----`; const key = await openpgp.readKey({ armoredKey }); const decrypted = await openpgp.decrypt({ - message: await openpgp.readMessage({ armoredMessage: encrypted }), + message: await openpgp.readMessage({ armoredMessage: encrypted, config: { enableParsingV5Entities: true } }), verificationKeys: key, decryptionKeys: key, config: { minRSABits: 1024 } @@ -2476,7 +2476,8 @@ EYaN9YdDOU2jF+HOaSNaJAsPF8J6BRgTCAAJBQJf0mstAhsMACMiIQUee6Tb AcvDfr9a0Cp4WAVzKDKLUzrRMgEAozi0VyjiBo1U2LcwTPJkA4PEQqQRVW1D KZTMSAH7JEo= =tqWy ------END PGP PRIVATE KEY BLOCK-----` +-----END PGP PRIVATE KEY BLOCK-----`, + config: { enableParsingV5Entities: true } }); const signed = `-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 @@ -2489,7 +2490,7 @@ A3X6psihFkcA+Nuog2qpAq20Zc2lzVjDZzQosb8MLvKMg3UFCX12Oc0BAJwd JImeZLY02MctIpGZULbqgcUGK0P/yqrPL8Pe4lQM =Pacb -----END PGP SIGNATURE-----`; - const message = await openpgp.readCleartextMessage({ cleartextMessage: signed }); + const message = await openpgp.readCleartextMessage({ cleartextMessage: signed, config: { enableParsingV5Entities: true } }); const verified = await openpgp.verify({ verificationKeys: key, message }); expect(await verified.signatures[0].verified).to.be.true; }); From f729d2bfa7d1e5c22acf7b2f6f3af0b248ca65a2 Mon Sep 17 00:00:00 2001 From: larabr Date: Thu, 4 Jul 2024 14:28:43 +0200 Subject: [PATCH 152/201] Fix ECDH fingerprint size of v6 keys (#1771) Fingerprint should not be truncated, unlike for v5 keys. --- src/crypto/public_key/elliptic/ecdh.js | 6 +-- .../public_key_encrypted_session_key.js | 6 ++- test/general/ecc_nist.js | 39 +++++++++++++++++++ 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/crypto/public_key/elliptic/ecdh.js b/src/crypto/public_key/elliptic/ecdh.js index b57362a8..9f5cd1f6 100644 --- a/src/crypto/public_key/elliptic/ecdh.js +++ b/src/crypto/public_key/elliptic/ecdh.js @@ -53,7 +53,7 @@ function buildEcdhParam(public_algo, oid, kdfParams, fingerprint) { new Uint8Array([public_algo]), kdfParams.write(), util.stringToUint8Array('Anonymous Sender '), - fingerprint.subarray(0, 20) + fingerprint ]); } @@ -123,7 +123,7 @@ async function genPublicEphemeralKey(curve, Q) { * @param {module:type/kdf_params} kdfParams - KDF params including cipher and algorithm to use * @param {Uint8Array} data - Unpadded session key data * @param {Uint8Array} Q - Recipient public key - * @param {Uint8Array} fingerprint - Recipient fingerprint + * @param {Uint8Array} fingerprint - Recipient fingerprint, already truncated depending on the key version * @returns {Promise<{publicKey: Uint8Array, wrappedKey: Uint8Array}>} * @async */ @@ -188,7 +188,7 @@ async function genPrivateEphemeralKey(curve, V, Q, d) { * @param {Uint8Array} C - Encrypted and wrapped value derived from session key * @param {Uint8Array} Q - Recipient public key * @param {Uint8Array} d - Recipient private key - * @param {Uint8Array} fingerprint - Recipient fingerprint + * @param {Uint8Array} fingerprint - Recipient fingerprint, already truncated depending on the key version * @returns {Promise} Value derived from session key. * @async */ diff --git a/src/packet/public_key_encrypted_session_key.js b/src/packet/public_key_encrypted_session_key.js index 23a10563..f0bdc402 100644 --- a/src/packet/public_key_encrypted_session_key.js +++ b/src/packet/public_key_encrypted_session_key.js @@ -180,9 +180,10 @@ class PublicKeyEncryptedSessionKeyPacket { // No symmetric encryption algorithm identifier is passed to the public-key algorithm for a // v6 PKESK packet, as it is included in the v2 SEIPD packet. const sessionKeyAlgorithm = this.version === 3 ? this.sessionKeyAlgorithm : null; + const fingerprint = key.version === 5 ? key.getFingerprintBytes().subarray(0, 20) : key.getFingerprintBytes(); const encoded = encodeSessionKey(this.version, algo, sessionKeyAlgorithm, this.sessionKey); this.encrypted = await crypto.publicKeyEncrypt( - algo, sessionKeyAlgorithm, key.publicParams, encoded, key.getFingerprintBytes()); + algo, sessionKeyAlgorithm, key.publicParams, encoded, fingerprint); } /** @@ -202,7 +203,8 @@ class PublicKeyEncryptedSessionKeyPacket { const randomPayload = randomSessionKey ? encodeSessionKey(this.version, this.publicKeyAlgorithm, randomSessionKey.sessionKeyAlgorithm, randomSessionKey.sessionKey) : null; - const decryptedData = await crypto.publicKeyDecrypt(this.publicKeyAlgorithm, key.publicParams, key.privateParams, this.encrypted, key.getFingerprintBytes(), randomPayload); + const fingerprint = key.version === 5 ? key.getFingerprintBytes().subarray(0, 20) : key.getFingerprintBytes(); + const decryptedData = await crypto.publicKeyDecrypt(this.publicKeyAlgorithm, key.publicParams, key.privateParams, this.encrypted, fingerprint, randomPayload); const { sessionKey, sessionKeyAlgorithm } = decodeSessionKey(this.version, this.publicKeyAlgorithm, decryptedData, randomSessionKey); diff --git a/test/general/ecc_nist.js b/test/general/ecc_nist.js index aecfe062..5e661248 100644 --- a/test/general/ecc_nist.js +++ b/test/general/ecc_nist.js @@ -75,5 +75,44 @@ export default () => describe('Elliptic Curve Cryptography for NIST P-256,P-384, expect(await result.signatures[0].verified).to.be.true; }); + it('should decrypt a message using the correct fingerprint size in the KDF (v6 key)', async function() { + // this test is to ensure the KDF function uses the correct fingerprint size (the fingerprint should not be truncated) + const key = await openpgp.readKey({ + armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xXkGZoVjGhMAAABMCCqGSM49AwEHAgMEUqR9vqdSZv8I+DGuSOYUSf4cNVlE +H16loiqRcAsDY9SHSTVHQkEWbc63HyEvV3jGSbSk2dNF64faN3nbhlZ0PgAB +APcoOjqcdJ9/LHRgxWvSbrKAmKNm0yJE9U9DY9hwshqhwqEGHxMIAAAAPgWC +ZoVjGgMLCQcFFQgKDA4EFgACAQKbAwIeASKhBk+e6Xq0rbnjKzVy/3Qitc2h +eW/w/IuxgPXjJW3nfTRxAAAAABQOEKxf0tyJS3Pbs1xApVxWKP4BAM8Bkygn +ddtiBifou11xgxOjT0y0CsbjIKyOnPTvIh/4AQCfyLJIAmQUN36mSInEepvy +NVk8jmweVYOCT8RluvFtG80OPHRlc3RAdGVzdC5pdD7CjwYTEwgAAAAsBYJm +hWMaAhkBIqEGT57perStueMrNXL/dCK1zaF5b/D8i7GA9eMlbed9NHEAAAAA +g9UQJqaRsvniF1WYuuRLpqMpOAEAvAhGhNpom/L2iIZLCpeyFCfGe5VDUBQB +1cjGpTbnrJoBAIjy1tgUH1gjixchymNf5LfUqwdXwEiLfv2f/Iq+KEX/x30G +ZoVjGhIAAABQCCqGSM49AwEHAgMESZrMsc0UrXB5/C8FHXAepykqAyueem7p +cjVvWFP9V59w/O/VXVyJBrZqleN0w/KexznRyzvQjH36HRlwVFwJ5QMBCAcA +AQDiiISRsjcPcaGXSAEYmvd80nH1oP8CJ/TQsi8od5nhqMKPBhgTCAAAACwF +gmaFYxoCmwwioQZPnul6tK254ys1cv90IrXNoXlv8PyLsYD14yVt5300cQAA +AAC2GhBn4S5eLyGPjccfUkFRKKWmAP4iHESir/KDsmsfhE5m/RwQcy7feCl7 +2bny7QRNGY8dFQD8CwmHJ0EvMDQcvVWPrj8WdgPblJEEgWd9AUItEFcDee0= +-----END PGP PRIVATE KEY BLOCK-----` + }); + const message = await openpgp.readMessage({ + armoredMessage: `-----BEGIN PGP MESSAGE----- + +wX4DYKEfntV7jkcSAgMEXplJPwjsvhh7xNeBeZtgepG1f0hUaW4eoeFCDpYH +IOr2RZFgRd6KbtmNsI1saqDwDg7EjFk+AWOe7av2xcFStTDfz+9mus03A6tk +7mPFWGsDUrxP2b+tyO6ofr9I4gyj5tI2X7R94AfRWgQxy+O2PvLSNAFXcx4o +SsrtSQmZUKpxuBROy+bZNheNgmN966vqnFBiM1vXikv5OVyprUV0EzzQ3Hnt +69s= +=0Agg +-----END PGP MESSAGE-----` + }); + const decrypted = await openpgp.decrypt({ message, decryptionKeys: key }); + expect(decrypted.data).to.equal('abc'); + }); + + // TODO find test vectors }); From 40b6427658faf9726f1922343e9096f6cb5fb4a5 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Thu, 4 Jul 2024 14:51:59 +0200 Subject: [PATCH 153/201] Tests: fix stream polyfilling in legacy browsers web-streams-polyfill v4 has a different entrypoint for the polyfills. --- test/unittests.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unittests.js b/test/unittests.js index de16574c..74ef06ad 100644 --- a/test/unittests.js +++ b/test/unittests.js @@ -30,7 +30,7 @@ globalThis.loadStreamsPolyfill = function() { // do not polyfill Node const detectNodeWebStreams = () => typeof globalThis.process === 'object' && typeof globalThis.process.versions === 'object' && globalThis.ReadableStream; - return detectNodeWebStreams() || import('web-streams-polyfill'); + return detectNodeWebStreams() || import('web-streams-polyfill/polyfill'); }; import runWorkerTests from './worker'; From 42938c871a271d1068cbebcb55a592bfc33b3ba4 Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Thu, 4 Jul 2024 19:41:39 +0200 Subject: [PATCH 154/201] Fix legacy AEAD secret key encryption of v5 keys (#1775) --- src/packet/secret_key.js | 2 +- test/general/key.js | 44 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/packet/secret_key.js b/src/packet/secret_key.js index 2257a78b..b93e9391 100644 --- a/src/packet/secret_key.js +++ b/src/packet/secret_key.js @@ -398,7 +398,7 @@ class SecretKeyPacket extends PublicKeyPacket { this.usedModernAEAD = !this.isLegacyAEAD; // legacy AEAD does not guarantee integrity of public key material const serializedPacketTag = writeTag(this.constructor.tag); - const key = await produceEncryptionKey(this.version, this.s2k, passphrase, this.symmetric, this.aead, serializedPacketTag); + const key = await produceEncryptionKey(this.version, this.s2k, passphrase, this.symmetric, this.aead, serializedPacketTag, this.isLegacyAEAD); const modeInstance = await mode(this.symmetric, key); this.iv = this.isLegacyAEAD ? crypto.random.getRandomBytes(blockSize) : crypto.random.getRandomBytes(mode.ivLength); diff --git a/test/general/key.js b/test/general/key.js index 0ff089b1..9aed9d57 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -3126,6 +3126,50 @@ Cg== expect(redecryptedKey.write()).to.deep.equal(decryptedKey.write()); }); + it('Parsing, decrypting, encrypting and serializing V5 key (AEAD-encrypted, deprecated/legacy format from RFC4880bis)', async function() { + // v5 key from OpenPGP.js v5, generated with config.aeadProtect flag (https://www.ietf.org/archive/id/draft-ietf-openpgp-rfc4880bis-10.html#section-5.5.3-3.5) + const armoredKey = `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xYwFZoaoyxYAAAAtCSsGAQQB2kcPAQEHQECiSN62X9PnTUoE9cx6aRxqh2aR +piHEjy2dtbhOsC7X/R0JAQMI3R4vBY0cUVnglteNXGCjgMgSTO3VeB70tgAA +ADIUlEIeqChwz1NRWl0WafC7vLrhIwgzW4dfRLqWU/tcDxhQji8oOdMihMVH +gOT1M/58zs0EVGVzdMKSBRAWCgBEBYJmhqjLBAsJBwgDFQgKBBYAAgECGQEC +mwMCHgcioQVBp/l8xtMGAhUT99DQhSQ8spB7ILxEALjWUfi5ODEQZgMiAQIA +ABJ7AQDbdXScaIjOUmKjsX1pTeDPfIPEWJSBY5n4e9tKMoFLuAD+ISyssmch +WjtxzfvElCc4/QL7P4yv7VBCHgVMfdBIggPHkQVmhqjLEgAAADIKKwYBBAGX +VQEFAQEHQL5K5HBcf0/GTcajPc3xeNNQQhJfT0TsmcorbEWV73FZAwEIB/0d +CQEDCJ2Wqcffz5cT4LmtIq4KlZUR8vlQrKcWF5MAAAAyiqtRwe6bSZ94e8Yt +1O6D4oH37UnCkKEuDQJb3G4SvHw4lJdlehfRFxndhHTuTVNQW9zCegUYFgoA +LAWCZoaoywKbDCKhBUGn+XzG0wYCFRP30NCFJDyykHsgvEQAuNZR+Lk4MRBm +AADOyAEA0VMzgtpSnXOfPNvVjOOW3yW/DnHSnOWjLmUujTLYXf0A/0nHjVMI +yrHaO8+1bQew7SIS9kYr1sh/z7LKooqYHBwH +=Woga +-----END PGP PRIVATE KEY BLOCK-----`; + const binaryKey = (await openpgp.unarmor(armoredKey)).data; + const passphrase = 'passphrase'; + const encryptedKey = await openpgp.readKey({ armoredKey, config: { enableParsingV5Entities: true } }); + expect(encryptedKey.keyPacket.isLegacyAEAD).to.be.true; + expect(encryptedKey.keyPacket.usedModernAEAD).to.be.false; // legacy AEAD does not guarantee integrity of public key material + expect(encryptedKey.write()).to.deep.equal(binaryKey); + + const decryptedKey = await openpgp.decryptKey({ + privateKey: encryptedKey, + passphrase + }); + const reecryptedKey = await openpgp.encryptKey({ + privateKey: decryptedKey, + passphrase, + config: { aeadProtect: true } + }); + expect(reecryptedKey.keyPacket.s2kUsage).to.equal(253); + expect(reecryptedKey.keyPacket.isLegacyAEAD).to.be.true; + const redecryptedKey = await openpgp.decryptKey({ + privateKey: reecryptedKey, + passphrase + }); + expect(redecryptedKey.write()).to.deep.equal(decryptedKey.write()); + }); + it('Parsing, decrypting, encrypting and serializing V4 key (AEAD-encrypted)', async function() { // key from gopenpgp const armoredKey = `-----BEGIN PGP PRIVATE KEY BLOCK----- From 00e147f5c158681ee1e9302580f8d1ef0051b173 Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Fri, 5 Jul 2024 13:50:11 +0200 Subject: [PATCH 155/201] Use preferred AEAD mode for secret key encryption (#1776) When config.aeadProtect is enabled, use config.preferredAEADAlgorithm to decide the AEAD mode when encrypting secret keys. --- src/packet/secret_key.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packet/secret_key.js b/src/packet/secret_key.js index b93e9391..737b2a82 100644 --- a/src/packet/secret_key.js +++ b/src/packet/secret_key.js @@ -392,7 +392,7 @@ class SecretKeyPacket extends PublicKeyPacket { if (config.aeadProtect) { this.s2kUsage = 253; - this.aead = enums.aead.eax; + this.aead = config.preferredAEADAlgorithm; const mode = crypto.getAEADMode(this.aead); this.isLegacyAEAD = this.version === 5; // v4 is always re-encrypted with standard format instead. this.usedModernAEAD = !this.isLegacyAEAD; // legacy AEAD does not guarantee integrity of public key material From 857b794e13cf3bf0c958d5617d68f97b9415596c Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Fri, 5 Jul 2024 13:52:45 +0200 Subject: [PATCH 156/201] Disallow using forbidden S2K modes (#1777) RFC9580 says that: Argon2 is only used with AEAD (S2K usage octet 253). An implementation MUST NOT create and MUST reject as malformed any secret key packet where the S2K usage octet is not AEAD (253) and the S2K specifier type is Argon2. Therefore, we disallow reading and writing Argon2 keys without AEAD. And: [The Simple and Salted S2K methods] are used only for reading in backwards compatibility mode. Since v6 keys don't need backwards compatibility, we also disallow reading Simple S2K there. We still allow reading Salted S2K since the spec says it may be used "when [the password] is high entropy". --- src/packet/secret_key.js | 6 ++++++ test/general/openpgp.js | 5 ++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/packet/secret_key.js b/src/packet/secret_key.js index 737b2a82..ddddae5f 100644 --- a/src/packet/secret_key.js +++ b/src/packet/secret_key.js @@ -568,6 +568,12 @@ class SecretKeyPacket extends PublicKeyPacket { * @returns encryption key */ async function produceEncryptionKey(keyVersion, s2k, passphrase, cipherAlgo, aeadMode, serializedPacketTag, isLegacyAEAD) { + if (s2k.type === 'argon2' && !aeadMode) { + throw new Error('Using Argon2 S2K without AEAD is not allowed'); + } + if (s2k.type === 'simple' && keyVersion === 6) { + throw new Error('Using Simple S2K with version 6 keys is not allowed'); + } const { keySize } = crypto.getCipherParams(cipherAlgo); const derivedKey = await s2k.produceKey(passphrase, keySize); if (!aeadMode || keyVersion === 5 || isLegacyAEAD) { diff --git a/test/general/openpgp.js b/test/general/openpgp.js index d6d1df92..e6f5bbca 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -1416,7 +1416,10 @@ VFBLG8uc9IiaKann/DYBAJcZNZHRSfpDoV2pUA5EAEi2MdjxkRysFQnYPRAu const locked = await openpgp.encryptKey({ privateKey: key, passphrase: passphrase, - config: { s2kType: openpgp.enums.s2k.argon2 } + config: { + s2kType: openpgp.enums.s2k.argon2, + aeadProtect: true + } }); expect(key.isDecrypted()).to.be.true; expect(locked.isDecrypted()).to.be.false; From b9c5c8df59069d006f775243a7c9b21996be32a9 Mon Sep 17 00:00:00 2001 From: larabr Date: Fri, 5 Jul 2024 14:38:16 +0200 Subject: [PATCH 157/201] Allow parsing legacy AEAD messages regardless of `config.enableParsingV5Entities` (#1779) As legacy AEAD messages have been in circulation for longer. --- src/config/config.js | 5 ++--- src/packet/aead_encrypted_data.js | 5 +---- test/general/packet.js | 14 +++++++------- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/config/config.js b/src/config/config.js index 5e4ae45e..4bdbe914 100644 --- a/src/config/config.js +++ b/src/config/config.js @@ -82,10 +82,9 @@ export default { */ v6Keys: false, /** - * Enable parsing v5 keys, v5 signatures and AEAD-encrypted data packets - * (which is different from the AEAD-encrypted SEIPDv2 packet). + * Enable parsing v5 keys and v5 signatures (which is different from the AEAD-encrypted SEIPDv2 packet). * These are non-standard entities, which in the crypto-refresh have been superseded - * by v6 keys, v6 signatures and SEIPDv2 encrypted data, respectively. + * by v6 keys and v6 signatures, respectively. * However, generation of v5 entities was supported behind config flag in OpenPGP.js v5, and some other libraries, * hence parsing them might be necessary in some cases. */ diff --git a/src/packet/aead_encrypted_data.js b/src/packet/aead_encrypted_data.js index 492fa8ef..60bdc3a7 100644 --- a/src/packet/aead_encrypted_data.js +++ b/src/packet/aead_encrypted_data.js @@ -68,10 +68,7 @@ class AEADEncryptedDataPacket { * @param {Uint8Array | ReadableStream} bytes * @throws {Error} on parsing failure */ - async read(bytes, config = defaultConfig) { - if (!config.enableParsingV5Entities) { - throw new UnsupportedError('Support for parsing v5 entities is disabled; turn on `config.enableParsingV5Entities` if needed'); - } + async read(bytes) { await stream.parse(bytes, async reader => { const version = await reader.readByte(); if (version !== VERSION) { // The only currently defined value is 1. diff --git a/test/general/packet.js b/test/general/packet.js index 5d7449b5..78f5d621 100644 --- a/test/general/packet.js +++ b/test/general/packet.js @@ -174,7 +174,7 @@ export default () => describe('Packet', function() { const msg2 = new openpgp.PacketList(); return enc.encrypt(algo, key, undefined, openpgp.config).then(async function() { - await msg2.read(msg.write(), allAllowedPackets, { ...openpgp.config, enableParsingV5Entities: true }); + await msg2.read(msg.write(), allAllowedPackets); return msg2[0].decrypt(algo, key); }).then(async function() { expect(await stream.readToEnd(msg2[0].packets[0].data)).to.deep.equal(literal.data); @@ -229,7 +229,7 @@ export default () => describe('Packet', function() { try { await enc.encrypt(algo, key, { ...openpgp.config, aeadChunkSizeByte: 0 }); - await msg2.read(msg.write(), allAllowedPackets, { ...openpgp.config, enableParsingV5Entities: true }); + await msg2.read(msg.write(), allAllowedPackets); await msg2[0].decrypt(algo, key); expect(await stream.readToEnd(msg2[0].packets[0].data)).to.deep.equal(literal.data); expect(encryptStub.callCount > 1).to.be.true; @@ -276,7 +276,7 @@ export default () => describe('Packet', function() { await enc.encrypt(algo, key, { ...openpgp.config, aeadChunkSizeByte: 14 }); const data = msg.write(); expect(await stream.readToEnd(stream.clone(data))).to.deep.equal(packetBytes); - await msg2.read(data, allAllowedPackets, { ...openpgp.config, enableParsingV5Entities: true }); + await msg2.read(data, allAllowedPackets); await msg2[0].decrypt(algo, key); expect(await stream.readToEnd(msg2[0].packets[0].data)).to.deep.equal(literal.data); } finally { @@ -706,7 +706,7 @@ export default () => describe('Packet', function() { await aeadEnc.encrypt(algo, key, undefined, openpgp.config); const msg2 = new openpgp.PacketList(); - await msg2.read(msg.write(), allAllowedPackets, { ...openpgp.config, enableParsingV5Entities: true }); + await msg2.read(msg.write(), allAllowedPackets); await msg2[0].decrypt(passphrase); const key2 = msg2[0].sessionKey; @@ -744,7 +744,7 @@ export default () => describe('Packet', function() { await aeadEnc.encrypt(algo, key, undefined, openpgp.config); const msg2 = new openpgp.PacketList(); - await msg2.read(msg.write(), allAllowedPackets, { ...openpgp.config, enableParsingV5Entities: true }); + await msg2.read(msg.write(), allAllowedPackets); await msg2[0].decrypt(passphrase); const key2 = msg2[0].sessionKey; @@ -820,7 +820,7 @@ export default () => describe('Packet', function() { expect(await stream.readToEnd(stream.clone(data))).to.deep.equal(packetBytes); const msg2 = new openpgp.PacketList(); - await msg2.read(data, allAllowedPackets, { ...openpgp.config, enableParsingV5Entities: true }); + await msg2.read(data, allAllowedPackets); await msg2[0].decrypt(passphrase); const key2 = msg2[0].sessionKey; @@ -899,7 +899,7 @@ export default () => describe('Packet', function() { expect(await stream.readToEnd(stream.clone(data))).to.deep.equal(packetBytes); const msg2 = new openpgp.PacketList(); - await msg2.read(data, allAllowedPackets, { ...openpgp.config, enableParsingV5Entities: true }); + await msg2.read(data, allAllowedPackets); await msg2[0].decrypt(passphrase); const key2 = msg2[0].sessionKey; From 35a1e1f23b9399caee168232ac1644bd335415d6 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Fri, 5 Jul 2024 15:10:29 +0200 Subject: [PATCH 158/201] Run npm audit --- package-lock.json | 74 +++++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/package-lock.json b/package-lock.json index ca74ff82..a21289d1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2156,12 +2156,12 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -2879,9 +2879,9 @@ } }, "node_modules/engine.io": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.4.tgz", - "integrity": "sha512-KdVSDKhVKyOi+r5uEabrDLZw2qXStVvCsEB/LN3mw4WFi6Gx50jTyuxYVCwAAC0U46FdnzP/ScKRBTXb/NiEOg==", + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.5.tgz", + "integrity": "sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==", "dev": true, "dependencies": { "@types/cookie": "^0.4.1", @@ -2893,7 +2893,7 @@ "cors": "~2.8.5", "debug": "~4.3.1", "engine.io-parser": "~5.2.1", - "ws": "~8.11.0" + "ws": "~8.17.1" }, "engines": { "node": ">=10.2.0" @@ -3891,9 +3891,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" @@ -7430,13 +7430,13 @@ } }, "node_modules/socket.io-adapter": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.4.tgz", - "integrity": "sha512-wDNHGXGewWAjQPt3pyeYBtpWSq9cLE5UW1ZUPL/2eGK9jtse/FpXib7epSTsz0Q0m+6sg6Y4KtcFTlah1bdOVg==", + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz", + "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", "dev": true, "dependencies": { "debug": "~4.3.4", - "ws": "~8.11.0" + "ws": "~8.17.1" } }, "node_modules/socket.io-parser": { @@ -8487,16 +8487,16 @@ "dev": true }, "node_modules/ws": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", - "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "dev": true, "engines": { "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { @@ -9975,12 +9975,12 @@ } }, "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "requires": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" } }, "browser-stdout": { @@ -10524,9 +10524,9 @@ "dev": true }, "engine.io": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.4.tgz", - "integrity": "sha512-KdVSDKhVKyOi+r5uEabrDLZw2qXStVvCsEB/LN3mw4WFi6Gx50jTyuxYVCwAAC0U46FdnzP/ScKRBTXb/NiEOg==", + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.5.tgz", + "integrity": "sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==", "dev": true, "requires": { "@types/cookie": "^0.4.1", @@ -10538,7 +10538,7 @@ "cors": "~2.8.5", "debug": "~4.3.1", "engine.io-parser": "~5.2.1", - "ws": "~8.11.0" + "ws": "~8.17.1" } }, "engine.io-parser": { @@ -11336,9 +11336,9 @@ } }, "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "requires": { "to-regex-range": "^5.0.1" @@ -13962,13 +13962,13 @@ } }, "socket.io-adapter": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.4.tgz", - "integrity": "sha512-wDNHGXGewWAjQPt3pyeYBtpWSq9cLE5UW1ZUPL/2eGK9jtse/FpXib7epSTsz0Q0m+6sg6Y4KtcFTlah1bdOVg==", + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz", + "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", "dev": true, "requires": { "debug": "~4.3.4", - "ws": "~8.11.0" + "ws": "~8.17.1" } }, "socket.io-parser": { @@ -14749,9 +14749,9 @@ "dev": true }, "ws": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", - "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "dev": true, "requires": {} }, From c0b35306cb4b4568ac493b7dba6113e1853e9fe2 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Fri, 5 Jul 2024 15:12:14 +0200 Subject: [PATCH 159/201] 6.0.0-beta.2 --- docs/AEADEncryptedDataPacket.html | 14 +-- docs/Argon2S2K.html | 16 +-- docs/CleartextMessage.html | 12 +- docs/CompressedDataPacket.html | 16 +-- docs/Key.html | 56 +++++----- docs/LiteralDataPacket.html | 20 ++-- docs/MarkerPacket.html | 4 +- docs/Message.html | 40 +++---- docs/OnePassSignaturePacket.html | 22 ++-- docs/PacketList.html | 14 +-- docs/PaddingPacket.html | 8 +- docs/PrivateKey.html | 20 ++-- docs/PublicKey.html | 8 +- docs/PublicKeyEncryptedSessionKeyPacket.html | 14 +-- docs/PublicKeyPacket.html | 46 ++++---- docs/PublicSubkeyPacket.html | 46 ++++---- docs/SecretKeyPacket.html | 72 ++++++------ docs/SecretSubkeyPacket.html | 72 ++++++------ docs/Signature.html | 8 +- docs/SignaturePacket.html | 24 ++-- ...EncryptedIntegrityProtectedDataPacket.html | 10 +- docs/SymEncryptedSessionKeyPacket.html | 16 +-- docs/SymmetricallyEncryptedDataPacket.html | 10 +- docs/TrustPacket.html | 4 +- docs/UserAttributePacket.html | 8 +- docs/UserIDPacket.html | 10 +- docs/global.html | 72 ++++++------ docs/index.html | 4 +- docs/module-config.html | 66 +++++------ docs/module-crypto.html | 2 +- docs/module-crypto_aes_kw.html | 6 +- docs/module-crypto_cmac.html | 6 +- docs/module-crypto_crypto.html | 30 ++--- docs/module-crypto_hash.html | 8 +- docs/module-crypto_hkdf.html | 2 +- docs/module-crypto_mode.html | 10 +- docs/module-crypto_mode_cfb.html | 4 +- docs/module-crypto_mode_eax.html | 8 +- docs/module-crypto_mode_gcm.html | 4 +- docs/module-crypto_mode_ocb.html | 8 +- docs/module-crypto_pkcs1.html | 10 +- docs/module-crypto_public_key.html | 10 +- docs/module-crypto_public_key_dsa.html | 10 +- docs/module-crypto_public_key_elgamal.html | 10 +- docs/module-crypto_public_key_elliptic.html | 2 +- ...dule-crypto_public_key_elliptic_curve.html | 103 +++++++++++++++++- ...odule-crypto_public_key_elliptic_ecdh.html | 68 ++++++------ ...dule-crypto_public_key_elliptic_ecdsa.html | 10 +- ...dule-crypto_public_key_elliptic_eddsa.html | 10 +- ...ypto_public_key_elliptic_eddsa_legacy.html | 8 +- docs/module-crypto_public_key_rsa.html | 20 ++-- docs/module-crypto_random.html | 6 +- docs/module-crypto_signature.html | 8 +- docs/module-encoding_base64.html | 8 +- docs/module-enums.html | 36 +++--- docs/module-key_Subkey-Subkey.html | 40 +++---- docs/module-key_User-User.html | 20 ++-- docs/module-key_helper.html | 48 ++++++-- docs/module-packet_packet.html | 10 +- docs/module-type_ecdh_symkey.html | 2 +- docs/module-type_kdf_params-KDFParams.html | 6 +- docs/module-type_keyid-KeyID.html | 14 +-- docs/module-type_oid.html | 2 +- docs/module-type_s2k-GenericS2K.html | 16 +-- docs/module-type_s2k.html | 2 +- docs/module-type_x25519x448_symkey.html | 2 +- docs/module-util.html | 2 +- package-lock.json | 4 +- package.json | 2 +- 69 files changed, 712 insertions(+), 597 deletions(-) diff --git a/docs/AEADEncryptedDataPacket.html b/docs/AEADEncryptedDataPacket.html index 8a6baa7a..7c3364c2 100644 --- a/docs/AEADEncryptedDataPacket.html +++ b/docs/AEADEncryptedDataPacket.html @@ -98,7 +98,7 @@ AEAD Protected Data Packet

    Source:
    @@ -200,7 +200,7 @@ AEAD Protected Data Packet

    Source:
    @@ -270,7 +270,7 @@ AEAD Protected Data Packet

    Source:
    @@ -475,7 +475,7 @@ AEAD Protected Data Packet

    Source:
    @@ -717,7 +717,7 @@ AEAD Protected Data Packet

    Source:
    @@ -888,7 +888,7 @@ AEAD Protected Data Packet

    Source:
    @@ -1007,7 +1007,7 @@ AEAD Protected Data Packet

    Source:
    diff --git a/docs/Argon2S2K.html b/docs/Argon2S2K.html index 75c3302a..80020ce8 100644 --- a/docs/Argon2S2K.html +++ b/docs/Argon2S2K.html @@ -152,7 +152,7 @@
    Source:
    @@ -258,7 +258,7 @@
    Source:
    @@ -332,7 +332,7 @@
    Source:
    @@ -406,7 +406,7 @@
    Source:
    @@ -480,7 +480,7 @@
    Source:
    @@ -612,7 +612,7 @@ hashAlgorithm

    Source:
    @@ -791,7 +791,7 @@ hashAlgorithm

    Source:
    @@ -903,7 +903,7 @@ hashAlgorithm

    Source:
    diff --git a/docs/CleartextMessage.html b/docs/CleartextMessage.html index 8ec800a1..64d9974f 100644 --- a/docs/CleartextMessage.html +++ b/docs/CleartextMessage.html @@ -168,7 +168,7 @@ See https://tools.ietf.o
    Source:
    @@ -346,7 +346,7 @@ See https://tools.ietf.o
    Source:
    @@ -461,7 +461,7 @@ See https://tools.ietf.o
    Source:
    @@ -573,7 +573,7 @@ See https://tools.ietf.o
    Source:
    @@ -974,7 +974,7 @@ See https://tools.ietf.o
    Source:
    @@ -1211,7 +1211,7 @@ See https://tools.ietf.o
    Source:
    diff --git a/docs/CompressedDataPacket.html b/docs/CompressedDataPacket.html index 2ed1a205..8485f380 100644 --- a/docs/CompressedDataPacket.html +++ b/docs/CompressedDataPacket.html @@ -160,7 +160,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

    Source:
    @@ -266,7 +266,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

    Source:
    @@ -343,7 +343,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

    Source:
    @@ -417,7 +417,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

    Source:
    @@ -499,7 +499,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

    Source:
    @@ -651,7 +651,7 @@ read by read_packet

    Source:
    @@ -836,7 +836,7 @@ read by read_packet

    Source:
    @@ -926,7 +926,7 @@ read by read_packet

    Source:
    diff --git a/docs/Key.html b/docs/Key.html index 318afac0..f8623449 100644 --- a/docs/Key.html +++ b/docs/Key.html @@ -96,7 +96,7 @@ Can contain additional subkeys, signatures, user ids, user attributes.

    Source:
    @@ -333,7 +333,7 @@ if it is a valid revocation signature.

    Source:
    @@ -514,7 +514,7 @@ if it is a valid revocation signature.

    Source:
    @@ -626,7 +626,7 @@ if it is a valid revocation signature.

    Source:
    @@ -738,7 +738,7 @@ if it is a valid revocation signature.

    Source:
    @@ -1006,7 +1006,7 @@ if it is a valid revocation signature.

    Source:
    @@ -1225,7 +1225,7 @@ Returns Infinity if the key doesn't expire, or null if
    Source:
    @@ -1333,7 +1333,7 @@ Returns Infinity if the key doesn't expire, or null if
    Source:
    @@ -1445,7 +1445,7 @@ Returns Infinity if the key doesn't expire, or null if
    Source:
    @@ -1557,7 +1557,7 @@ Returns Infinity if the key doesn't expire, or null if
    Source:
    @@ -1735,7 +1735,7 @@ If no keyID is given, returns all keys, starting with the primary key.

    Source:
    @@ -1977,7 +1977,7 @@ algorithm preferences, and so on.

    Source:
    @@ -2220,7 +2220,7 @@ algorithm preferences, and so on.

    Source:
    @@ -2425,7 +2425,7 @@ algorithm preferences, and so on.

    Source:
    @@ -2717,7 +2717,7 @@ algorithm preferences, and so on.

    Source:
    @@ -2911,7 +2911,7 @@ If no keyID is given, returns all subkeys.

    Source:
    @@ -3023,7 +3023,7 @@ If no keyID is given, returns all subkeys.

    Source:
    @@ -3135,7 +3135,7 @@ If no keyID is given, returns all subkeys.

    Source:
    @@ -3412,7 +3412,7 @@ If no keyID is given, returns all subkeys.

    Source:
    @@ -3596,7 +3596,7 @@ If no keyID is given, returns all subkeys.

    Source:
    @@ -3811,7 +3811,7 @@ If no keyID is given, returns all subkeys.

    Source:
    @@ -4081,7 +4081,7 @@ If no keyID is given, returns all subkeys.

    Source:
    @@ -4193,7 +4193,7 @@ If no keyID is given, returns all subkeys.

    Source:
    @@ -4434,7 +4434,7 @@ a private key is returned.

    Source:
    @@ -4677,7 +4677,7 @@ a private key is returned.

    Source:
    @@ -4918,7 +4918,7 @@ and valid self signature. Throws if the primary key is invalid.

    Source:
    @@ -5201,7 +5201,7 @@ and valid self signature. Throws if the primary key is invalid.

    Source:
    @@ -5314,7 +5314,7 @@ Signature validity is null if the verification keys do not correspond to the cer
    Source:
    diff --git a/docs/LiteralDataPacket.html b/docs/LiteralDataPacket.html index 277ed5c7..55048840 100644 --- a/docs/LiteralDataPacket.html +++ b/docs/LiteralDataPacket.html @@ -147,7 +147,7 @@ further interpreted.

    Source:
    @@ -326,7 +326,7 @@ further interpreted.

    Source:
    @@ -441,7 +441,7 @@ further interpreted.

    Source:
    @@ -623,7 +623,7 @@ with normalized end of line to \n

    Source:
    @@ -790,7 +790,7 @@ with normalized end of line to \n

    Source:
    @@ -977,7 +977,7 @@ with normalized end of line to \n

    Source:
    @@ -1116,7 +1116,7 @@ with normalized end of line to \n

    Source:
    @@ -1302,7 +1302,7 @@ will be normalized to \r\n and by default text is converted to UTF8

    Source:
    @@ -1392,7 +1392,7 @@ will be normalized to \r\n and by default text is converted to UTF8

    Source:
    @@ -1507,7 +1507,7 @@ will be normalized to \r\n and by default text is converted to UTF8

    Source:
    diff --git a/docs/MarkerPacket.html b/docs/MarkerPacket.html index 0c12f8da..2db07b12 100644 --- a/docs/MarkerPacket.html +++ b/docs/MarkerPacket.html @@ -106,7 +106,7 @@ software is necessary to process the message.

    Source:
    @@ -265,7 +265,7 @@ software is necessary to process the message.

    Source:
    diff --git a/docs/Message.html b/docs/Message.html index 46a3bda5..17b36998 100644 --- a/docs/Message.html +++ b/docs/Message.html @@ -146,7 +146,7 @@ See https://tools.iet
    Source:
    @@ -661,7 +661,7 @@ See https://tools.iet
    Source:
    @@ -933,7 +933,7 @@ See https://tools.iet
    Source:
    @@ -1140,7 +1140,7 @@ See https://tools.iet
    Source:
    @@ -1291,7 +1291,7 @@ See https://tools.iet
    Source:
    @@ -1495,7 +1495,7 @@ See https://tools.iet
    Source:
    @@ -1800,7 +1800,7 @@ See https://tools.iet
    Source:
    @@ -2105,7 +2105,7 @@ See https://tools.iet
    Source:
    @@ -2545,7 +2545,7 @@ See https://tools.iet
    Source:
    @@ -2657,7 +2657,7 @@ See https://tools.iet
    Source:
    @@ -2769,7 +2769,7 @@ See https://tools.iet
    Source:
    @@ -2884,7 +2884,7 @@ See https://tools.iet
    Source:
    @@ -2999,7 +2999,7 @@ See https://tools.iet
    Source:
    @@ -3111,7 +3111,7 @@ See https://tools.iet
    Source:
    @@ -3515,7 +3515,7 @@ See https://tools.iet
    Source:
    @@ -3916,7 +3916,7 @@ See https://tools.iet
    Source:
    @@ -4028,7 +4028,7 @@ See https://tools.iet
    Source:
    @@ -4265,7 +4265,7 @@ See https://tools.iet
    Source:
    @@ -4531,7 +4531,7 @@ See https://tools.iet
    Source:
    @@ -4643,7 +4643,7 @@ See https://tools.iet
    Source:
    diff --git a/docs/OnePassSignaturePacket.html b/docs/OnePassSignaturePacket.html index a496eef1..be20f102 100644 --- a/docs/OnePassSignaturePacket.html +++ b/docs/OnePassSignaturePacket.html @@ -101,7 +101,7 @@ can compute the entire signed message in one pass.

    Source:
    @@ -199,7 +199,7 @@ that describes another signature to be applied to the same message data.

    Source:
    @@ -273,7 +273,7 @@ that describes another signature to be applied to the same message data.

    Source:
    @@ -344,7 +344,7 @@ that describes another signature to be applied to the same message data.

    Source:
    @@ -408,7 +408,7 @@ that describes another signature to be applied to the same message data.

    Source:
    @@ -482,7 +482,7 @@ that describes another signature to be applied to the same message data.

    Source:
    @@ -553,7 +553,7 @@ that describes another signature to be applied to the same message data.

    Source:
    @@ -629,7 +629,7 @@ Signature types are described in
    Source:
    @@ -693,7 +693,7 @@ Signature types are described in
    Source:
    @@ -824,7 +824,7 @@ Signature types are described in
    Source:
    @@ -936,7 +936,7 @@ Signature types are described in
    Source:
    diff --git a/docs/PacketList.html b/docs/PacketList.html index 7be051f7..da633f5c 100644 --- a/docs/PacketList.html +++ b/docs/PacketList.html @@ -97,7 +97,7 @@ are stored as numerical indices.

    Source:
    @@ -345,7 +345,7 @@ Equivalent to calling read on an empty PacketList instance.

    Source:
    @@ -530,7 +530,7 @@ Equivalent to calling read on an empty PacketList instance.

    Source:
    @@ -687,7 +687,7 @@ Equivalent to calling read on an empty PacketList instance.

    Source:
    @@ -859,7 +859,7 @@ Equivalent to calling read on an empty PacketList instance.

    Source:
    @@ -1097,7 +1097,7 @@ Equivalent to calling read on an empty PacketList instance.

    Source:
    @@ -1200,7 +1200,7 @@ class instance.

    Source:
    diff --git a/docs/PaddingPacket.html b/docs/PaddingPacket.html index 2a9d6ffe..96cdc345 100644 --- a/docs/PaddingPacket.html +++ b/docs/PaddingPacket.html @@ -97,7 +97,7 @@ Padding Packet

    Source:
    @@ -256,7 +256,7 @@ Padding Packet

    Source:
    @@ -427,7 +427,7 @@ Padding Packet

    Source:
    @@ -517,7 +517,7 @@ Padding Packet

    Source:
    diff --git a/docs/PrivateKey.html b/docs/PrivateKey.html index a24cfeb2..389ec78f 100644 --- a/docs/PrivateKey.html +++ b/docs/PrivateKey.html @@ -144,7 +144,7 @@
    Source:
    @@ -453,7 +453,7 @@ Note: Curve448 and Curve25519 are not widely supported yet.

    Source:
    @@ -622,7 +622,7 @@ Note: Curve448 and Curve25519 are not widely supported yet.

    Source:
    @@ -734,7 +734,7 @@ Note: Curve448 and Curve25519 are not widely supported yet.

    Source:
    @@ -979,7 +979,7 @@ This is useful to retrieve keys for session key decryption

    Source:
    @@ -1092,7 +1092,7 @@ A dummy key is considered encrypted.

    Source:
    @@ -1182,7 +1182,7 @@ A dummy key is considered encrypted.

    Source:
    @@ -1485,7 +1485,7 @@ A dummy key is considered encrypted.

    Source:
    @@ -1597,7 +1597,7 @@ A dummy key is considered encrypted.

    Source:
    @@ -1774,7 +1774,7 @@ If only gnu-dummy keys are found, we cannot properly validate so we throw an err
    Source:
    diff --git a/docs/PublicKey.html b/docs/PublicKey.html index 0a180563..65b93cac 100644 --- a/docs/PublicKey.html +++ b/docs/PublicKey.html @@ -144,7 +144,7 @@
    Source:
    @@ -315,7 +315,7 @@
    Source:
    @@ -427,7 +427,7 @@
    Source:
    @@ -535,7 +535,7 @@
    Source:
    diff --git a/docs/PublicKeyEncryptedSessionKeyPacket.html b/docs/PublicKeyEncryptedSessionKeyPacket.html index 6ea55a7a..aefcc673 100644 --- a/docs/PublicKeyEncryptedSessionKeyPacket.html +++ b/docs/PublicKeyEncryptedSessionKeyPacket.html @@ -107,7 +107,7 @@ decrypt the message.

    Source:
    @@ -209,7 +209,7 @@ decrypt the message.

    Source:
    @@ -283,7 +283,7 @@ decrypt the message.

    Source:
    @@ -458,7 +458,7 @@ This is needed for constant-time processing. Expected object of the form: { sess
    Source:
    @@ -626,7 +626,7 @@ This is needed for constant-time processing. Expected object of the form: { sess
    Source:
    @@ -794,7 +794,7 @@ This is needed for constant-time processing. Expected object of the form: { sess
    Source:
    @@ -884,7 +884,7 @@ This is needed for constant-time processing. Expected object of the form: { sess
    Source:
    diff --git a/docs/PublicKeyPacket.html b/docs/PublicKeyPacket.html index 57e505d4..a762bc19 100644 --- a/docs/PublicKeyPacket.html +++ b/docs/PublicKeyPacket.html @@ -195,7 +195,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -301,7 +301,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -375,7 +375,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -449,7 +449,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -523,7 +523,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -597,7 +597,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -671,7 +671,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -735,7 +735,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -816,7 +816,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -880,7 +880,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -1018,7 +1018,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -1130,7 +1130,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -1220,7 +1220,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -1310,7 +1310,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -1422,7 +1422,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -1530,7 +1530,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -1642,7 +1642,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -1754,7 +1754,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -1866,7 +1866,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -1978,7 +1978,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -2138,7 +2138,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -2250,7 +2250,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    @@ -2411,7 +2411,7 @@ key (sometimes called an OpenPGP certificate).

    Source:
    diff --git a/docs/PublicSubkeyPacket.html b/docs/PublicSubkeyPacket.html index 1b3a2f10..8d4a64e2 100644 --- a/docs/PublicSubkeyPacket.html +++ b/docs/PublicSubkeyPacket.html @@ -193,7 +193,7 @@ services.

    Source:
    @@ -315,7 +315,7 @@ services.

    Source:
    @@ -394,7 +394,7 @@ services.

    Source:
    @@ -473,7 +473,7 @@ services.

    Source:
    @@ -552,7 +552,7 @@ services.

    Source:
    @@ -631,7 +631,7 @@ services.

    Source:
    @@ -710,7 +710,7 @@ services.

    Source:
    @@ -779,7 +779,7 @@ services.

    Source:
    @@ -865,7 +865,7 @@ services.

    Source:
    @@ -934,7 +934,7 @@ services.

    Source:
    @@ -1072,7 +1072,7 @@ services.

    Source:
    @@ -1189,7 +1189,7 @@ services.

    Source:
    @@ -1284,7 +1284,7 @@ services.

    Source:
    @@ -1379,7 +1379,7 @@ services.

    Source:
    @@ -1496,7 +1496,7 @@ services.

    Source:
    @@ -1609,7 +1609,7 @@ services.

    Source:
    @@ -1726,7 +1726,7 @@ services.

    Source:
    @@ -1843,7 +1843,7 @@ services.

    Source:
    @@ -1960,7 +1960,7 @@ services.

    Source:
    @@ -2077,7 +2077,7 @@ services.

    Source:
    @@ -2242,7 +2242,7 @@ services.

    Source:
    @@ -2359,7 +2359,7 @@ services.

    Source:
    @@ -2525,7 +2525,7 @@ services.

    Source:
    diff --git a/docs/SecretKeyPacket.html b/docs/SecretKeyPacket.html index 4eebe280..891d1460 100644 --- a/docs/SecretKeyPacket.html +++ b/docs/SecretKeyPacket.html @@ -191,7 +191,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -308,7 +308,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -387,7 +387,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -466,7 +466,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -545,7 +545,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -624,7 +624,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -688,7 +688,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -767,7 +767,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -831,7 +831,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -905,7 +905,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -984,7 +984,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -1053,7 +1053,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -1134,7 +1134,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -1208,7 +1208,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -1282,7 +1282,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -1361,7 +1361,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -1430,7 +1430,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -1519,7 +1519,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -1614,7 +1614,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -1709,7 +1709,7 @@ includes the secret-key material after all the public-key fields.

    Source:
    @@ -1851,7 +1851,7 @@ otherwise calls to this function will throw an error.

    Source:
    @@ -2065,7 +2065,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2189,7 +2189,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2306,7 +2306,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2419,7 +2419,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2536,7 +2536,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2653,7 +2653,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2770,7 +2770,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2888,7 +2888,7 @@ Returns false for gnu-dummy keys and null for public keys.

    Source:
    @@ -2999,7 +2999,7 @@ Returns false for gnu-dummy keys and null for public keys.

    Source:
    @@ -3114,7 +3114,7 @@ Such keys are:

    Source:
    @@ -3266,7 +3266,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
    Source:
    @@ -3411,7 +3411,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
    Source:
    @@ -3501,7 +3501,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
    Source:
    @@ -3625,7 +3625,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
    Source:
    @@ -3791,7 +3791,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
    Source:
    diff --git a/docs/SecretSubkeyPacket.html b/docs/SecretSubkeyPacket.html index ee0599fb..c5f4ec4f 100644 --- a/docs/SecretSubkeyPacket.html +++ b/docs/SecretSubkeyPacket.html @@ -190,7 +190,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -312,7 +312,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -391,7 +391,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -470,7 +470,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -549,7 +549,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -628,7 +628,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -697,7 +697,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -776,7 +776,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -845,7 +845,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -924,7 +924,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -1003,7 +1003,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -1072,7 +1072,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -1158,7 +1158,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -1237,7 +1237,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -1316,7 +1316,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -1395,7 +1395,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -1464,7 +1464,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -1558,7 +1558,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -1653,7 +1653,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -1748,7 +1748,7 @@ Key packet and has exactly the same format.

    Source:
    @@ -1895,7 +1895,7 @@ otherwise calls to this function will throw an error.

    Source:
    @@ -2114,7 +2114,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2238,7 +2238,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2355,7 +2355,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2468,7 +2468,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2585,7 +2585,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2702,7 +2702,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2819,7 +2819,7 @@ This can be used to remove passphrase protection after calling decrypt().

    Source:
    @@ -2937,7 +2937,7 @@ Returns false for gnu-dummy keys and null for public keys.

    Source:
    @@ -3053,7 +3053,7 @@ Returns false for gnu-dummy keys and null for public keys.

    Source:
    @@ -3173,7 +3173,7 @@ Such keys are:

    Source:
    @@ -3330,7 +3330,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
    Source:
    @@ -3475,7 +3475,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
    Source:
    @@ -3570,7 +3570,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
    Source:
    @@ -3694,7 +3694,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
    Source:
    @@ -3860,7 +3860,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
    Source:
    diff --git a/docs/Signature.html b/docs/Signature.html index 4582acd6..213afc94 100644 --- a/docs/Signature.html +++ b/docs/Signature.html @@ -144,7 +144,7 @@
    Source:
    @@ -322,7 +322,7 @@
    Source:
    @@ -434,7 +434,7 @@
    Source:
    @@ -546,7 +546,7 @@
    Source:
    diff --git a/docs/SignaturePacket.html b/docs/SignaturePacket.html index f66bdac0..468477fe 100644 --- a/docs/SignaturePacket.html +++ b/docs/SignaturePacket.html @@ -99,7 +99,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    @@ -201,7 +201,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    @@ -271,7 +271,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    @@ -341,7 +341,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    @@ -423,7 +423,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    @@ -599,7 +599,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    @@ -760,7 +760,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    @@ -1048,7 +1048,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    @@ -1427,7 +1427,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    @@ -1546,7 +1546,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    @@ -1654,7 +1654,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    @@ -1765,7 +1765,7 @@ block of text, and a signature that is a certification of a User ID.

    Source:
    diff --git a/docs/SymEncryptedIntegrityProtectedDataPacket.html b/docs/SymEncryptedIntegrityProtectedDataPacket.html index 25b1b415..525f9dcf 100644 --- a/docs/SymEncryptedIntegrityProtectedDataPacket.html +++ b/docs/SymEncryptedIntegrityProtectedDataPacket.html @@ -101,7 +101,7 @@ packet.

    Source:
    @@ -203,7 +203,7 @@ packet.

    Source:
    @@ -273,7 +273,7 @@ packet.

    Source:
    @@ -478,7 +478,7 @@ packet.

    Source:
    @@ -738,7 +738,7 @@ packet.

    Source:
    diff --git a/docs/SymEncryptedSessionKeyPacket.html b/docs/SymEncryptedSessionKeyPacket.html index 144b2d9d..3322b140 100644 --- a/docs/SymEncryptedSessionKeyPacket.html +++ b/docs/SymEncryptedSessionKeyPacket.html @@ -165,7 +165,7 @@ the Symmetric-Key Encrypted Session Key packet.

    Source:
    @@ -271,7 +271,7 @@ the Symmetric-Key Encrypted Session Key packet.

    Source:
    @@ -345,7 +345,7 @@ the Symmetric-Key Encrypted Session Key packet.

    Source:
    @@ -419,7 +419,7 @@ the Symmetric-Key Encrypted Session Key packet.

    Source:
    @@ -550,7 +550,7 @@ the Symmetric-Key Encrypted Session Key packet.

    Source:
    @@ -761,7 +761,7 @@ the Symmetric-Key Encrypted Session Key packet.

    Source:
    @@ -929,7 +929,7 @@ the Symmetric-Key Encrypted Session Key packet.

    Source:
    @@ -1019,7 +1019,7 @@ the Symmetric-Key Encrypted Session Key packet.

    Source:
    diff --git a/docs/SymmetricallyEncryptedDataPacket.html b/docs/SymmetricallyEncryptedDataPacket.html index 27cc835c..3b648d27 100644 --- a/docs/SymmetricallyEncryptedDataPacket.html +++ b/docs/SymmetricallyEncryptedDataPacket.html @@ -101,7 +101,7 @@ that form whole OpenPGP messages).

    Source:
    @@ -197,7 +197,7 @@ that form whole OpenPGP messages).

    Source:
    @@ -271,7 +271,7 @@ that form whole OpenPGP messages).

    Source:
    @@ -477,7 +477,7 @@ See RFC 4880 9.2 f
    Source:
    @@ -720,7 +720,7 @@ See RFC 4880 9.2 f
    Source:
    diff --git a/docs/TrustPacket.html b/docs/TrustPacket.html index 5e0f1a24..00171290 100644 --- a/docs/TrustPacket.html +++ b/docs/TrustPacket.html @@ -105,7 +105,7 @@ other than local keyring files.

    Source:
    @@ -216,7 +216,7 @@ Currently not implemented as we ignore trust packets

    Source:
    diff --git a/docs/UserAttributePacket.html b/docs/UserAttributePacket.html index 1cbaf2c6..24770244 100644 --- a/docs/UserAttributePacket.html +++ b/docs/UserAttributePacket.html @@ -107,7 +107,7 @@ an implementation may use any method desired.

    Source:
    @@ -266,7 +266,7 @@ an implementation may use any method desired.

    Source:
    @@ -427,7 +427,7 @@ an implementation may use any method desired.

    Source:
    @@ -517,7 +517,7 @@ an implementation may use any method desired.

    Source:
    diff --git a/docs/UserIDPacket.html b/docs/UserIDPacket.html index 35436bb1..7ff0b5d3 100644 --- a/docs/UserIDPacket.html +++ b/docs/UserIDPacket.html @@ -100,7 +100,7 @@ specifies the length of the User ID.

    Source:
    @@ -207,7 +207,7 @@ John Doe john@example.com

    Source:
    @@ -338,7 +338,7 @@ John Doe john@example.com

    Source:
    @@ -495,7 +495,7 @@ John Doe john@example.com

    Source:
    @@ -585,7 +585,7 @@ John Doe john@example.com

    Source:
    diff --git a/docs/global.html b/docs/global.html index 5e078cd4..ce62f9ef 100644 --- a/docs/global.html +++ b/docs/global.html @@ -419,7 +419,7 @@
    Source:
    @@ -632,7 +632,7 @@
    Source:
    @@ -771,7 +771,7 @@
    Source:
    @@ -1180,7 +1180,7 @@
    Source:
    @@ -1761,7 +1761,7 @@ One of decryptionKeys, sessionkeys or passwords<
    Source:
    @@ -2064,7 +2064,7 @@ This method does not change the original key.

    Source:
    @@ -2423,7 +2423,7 @@ One of decryptionKeys or passwords must be specified.<
    Source:
    @@ -3227,7 +3227,7 @@ must be specified. If signing keys are specified, those will be used to sign the
    Source:
    @@ -3515,7 +3515,7 @@ This method does not change the original key.

    Source:
    @@ -4135,7 +4135,7 @@ At least one of encryptionKeys or passwords must be sp
    Source:
    @@ -4351,7 +4351,7 @@ At least one of encryptionKeys or passwords must be sp
    Source:
    @@ -4952,7 +4952,7 @@ default to main key options, except for sign parameter that default
    Source:
    @@ -5302,7 +5302,7 @@ default to main key options, except for sign parameter that default
    Source:
    @@ -5463,7 +5463,7 @@ default to main key options, except for sign parameter that default
    Source:
    @@ -5602,7 +5602,7 @@ default to main key options, except for sign parameter that default
    Source:
    @@ -5741,7 +5741,7 @@ default to main key options, except for sign parameter that default
    Source:
    @@ -5891,7 +5891,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -6071,7 +6071,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -6215,7 +6215,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -6405,7 +6405,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -6797,7 +6797,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -7038,7 +7038,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -7326,7 +7326,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -7614,7 +7614,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -7908,7 +7908,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -8196,7 +8196,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -8484,7 +8484,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -8772,7 +8772,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
    @@ -9234,7 +9234,7 @@ to set the same date as the key creation time to ensure that old message signatu
    Source:
    @@ -9763,7 +9763,7 @@ If a revocation certificate is passed, the reasonForRevocation parameter will be
    Source:
    @@ -9978,7 +9978,7 @@ If a revocation certificate is passed, the reasonForRevocation parameter will be
    Source:
    @@ -10527,7 +10527,7 @@ If a revocation certificate is passed, the reasonForRevocation parameter will be
    Source:
    @@ -10689,7 +10689,7 @@ the encoded bytes

    Source:
    @@ -11151,7 +11151,7 @@ an attribute "data" containing a stream of bytes and "type"
    Source:
    @@ -11396,7 +11396,7 @@ The new key includes a revocation certificate that must be removed before return
    Source:
    @@ -11576,7 +11576,7 @@ The new key includes a revocation certificate that must be removed before return
    Source:
    diff --git a/docs/index.html b/docs/index.html index 6259911b..4c20fedd 100644 --- a/docs/index.html +++ b/docs/index.html @@ -85,10 +85,10 @@

    Platform Support

    • -

      The dist/openpgp.min.js (or .mjs) bundle works with recent versions of Chrome, Firefox, Edge and Safari 13+.

      +

      The dist/openpgp.min.js (or .mjs) bundle works with recent versions of Chrome, Firefox, Edge and Safari 14+.

    • -

      The dist/node/openpgp.min.mjs (or .cjs) bundle works in Node.js v16+: it is used by default when you import ... from 'openpgp' (resp. require('openpgp')).

      +

      The dist/node/openpgp.min.mjs (or .cjs) bundle works in Node.js v18+: it is used by default when you import ... from 'openpgp' (resp. require('openpgp')).

    • Streaming support: the latest versions of Chrome, Firefox, Edge and Safari implement the diff --git a/docs/module-config.html b/docs/module-config.html index ead6d452..b9882cec 100644 --- a/docs/module-config.html +++ b/docs/module-config.html @@ -89,7 +89,7 @@

      Source:
      @@ -247,7 +247,7 @@ as a global config setting, but can be used for specific function calls (e.g. de
      Source:
      @@ -365,7 +365,7 @@ Must be an integer value from 0 to 56.

      Source:
      @@ -489,7 +489,7 @@ Note: not all OpenPGP implementations are compatible with this option.
    • Source:
      @@ -614,7 +614,7 @@ where key flags were ignored when selecting a key for encryption.

      Source:
      @@ -733,7 +733,7 @@ and have self-signature's creation date that does not match the primary key crea
      Source:
      @@ -854,7 +854,7 @@ This is an insecure setting:

      Source:
      @@ -979,7 +979,7 @@ and deferring checking their integrity until the decrypted stream has been read
      Source:
      @@ -1091,7 +1091,7 @@ and deferring checking their integrity until the decrypted stream has been read
      Source:
      @@ -1213,7 +1213,7 @@ See also constantTimePKCS1DecryptionSupportedSymmetricAlgorithms.Source:
      @@ -1331,7 +1331,7 @@ However, the more algorithms are added, the slower the decryption procedure beco
      Source:
      @@ -1443,7 +1443,7 @@ However, the more algorithms are added, the slower the decryption procedure beco
      Source:
      @@ -1555,7 +1555,7 @@ However, the more algorithms are added, the slower the decryption procedure beco
      Source:
      @@ -1672,7 +1672,7 @@ validation error when the notation is marked as critical.

      Source:
      @@ -1788,7 +1788,7 @@ validation error when the notation is marked as critical.

      Source:
      @@ -1905,7 +1905,7 @@ The default is 2047 since due to a bug, previous versions of OpenPGP.js could ge
      Source:
      @@ -2022,7 +2022,7 @@ The default is 2047 since due to a bug, previous versions of OpenPGP.js could ge
      Source:
      @@ -2139,7 +2139,7 @@ Only has an effect when aeadProtect is set to true.

      Source:
      @@ -2251,7 +2251,7 @@ Only has an effect when aeadProtect is set to true.

      Source:
      @@ -2363,7 +2363,7 @@ Only has an effect when aeadProtect is set to true.

      Source:
      @@ -2475,7 +2475,7 @@ Only has an effect when aeadProtect is set to true.

      Source:
      @@ -2591,7 +2591,7 @@ Only has an effect when aeadProtect is set to true.

      Source:
      @@ -2707,7 +2707,7 @@ Only has an effect when aeadProtect is set to true.

      Source:
      @@ -2823,7 +2823,7 @@ Only has an effect when aeadProtect is set to true.

      Source:
      @@ -2939,7 +2939,7 @@ Only has an effect when aeadProtect is set to true.

      Source:
      @@ -3154,7 +3154,7 @@ For more details on the choice of parameters, see https://tools.ietf.org/html/rf
      Source:
      @@ -3273,7 +3273,7 @@ Note: this is the exponent value, not the final number of iterations (refer to s
      Source:
      @@ -3395,7 +3395,7 @@ Note: Argon2 is the strongest option but not all OpenPGP implementations are com
      Source:
      @@ -3507,7 +3507,7 @@ Note: Argon2 is the strongest option but not all OpenPGP implementations are com
      Source:
      @@ -3619,7 +3619,7 @@ Note: Argon2 is the strongest option but not all OpenPGP implementations are com
      Source:
      @@ -3736,7 +3736,7 @@ When false, certain standard curves will not be supported (depending on the plat
      Source:
      @@ -3854,7 +3854,7 @@ Note: not all OpenPGP implementations are compatible with this option.
      Source:
      @@ -3966,7 +3966,7 @@ Note: not all OpenPGP implementations are compatible with this option.
      Source:
      diff --git a/docs/module-crypto.html b/docs/module-crypto.html index df3ddf0d..c046252b 100644 --- a/docs/module-crypto.html +++ b/docs/module-crypto.html @@ -89,7 +89,7 @@
      Source:
      diff --git a/docs/module-crypto_aes_kw.html b/docs/module-crypto_aes_kw.html index 9d025e00..e83e6ffb 100644 --- a/docs/module-crypto_aes_kw.html +++ b/docs/module-crypto_aes_kw.html @@ -89,7 +89,7 @@
      Source:
      @@ -308,7 +308,7 @@
      Source:
      @@ -521,7 +521,7 @@
      Source:
      diff --git a/docs/module-crypto_cmac.html b/docs/module-crypto_cmac.html index 609ac1c6..55d906a3 100644 --- a/docs/module-crypto_cmac.html +++ b/docs/module-crypto_cmac.html @@ -90,7 +90,7 @@ native AES-CBC using either the WebCrypto API or Node.js' crypto API.

      Source:
      @@ -195,7 +195,7 @@ The OMAC authors indicate that they will promulgate this modification
      Source:
      @@ -352,7 +352,7 @@ simplify the implementation.

      Source:
      diff --git a/docs/module-crypto_crypto.html b/docs/module-crypto_crypto.html index 3f48ad01..5fe0e8e2 100644 --- a/docs/module-crypto_crypto.html +++ b/docs/module-crypto_crypto.html @@ -90,7 +90,7 @@ well as key generation and parameter handling for all public-key cryptosystems.<
      Source:
      @@ -296,7 +296,7 @@ well as key generation and parameter handling for all public-key cryptosystems.<
      Source:
      @@ -458,7 +458,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -619,7 +619,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -848,7 +848,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -1030,7 +1030,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -1170,7 +1170,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -1354,7 +1354,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -1561,7 +1561,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -1745,7 +1745,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -2075,7 +2075,7 @@ See RFC 4880 5.5.3Source:
      @@ -2361,7 +2361,7 @@ See RFC 4880 9.1 f
      Source:
      @@ -2545,7 +2545,7 @@ See RFC 4880 9.1 f
      Source:
      @@ -2752,7 +2752,7 @@ See RFC 4880 9.1 f
      Source:
      @@ -2913,7 +2913,7 @@ See RFC 4880 9.1 f
      Source:
      diff --git a/docs/module-crypto_hash.html b/docs/module-crypto_hash.html index b255106d..539bf90c 100644 --- a/docs/module-crypto_hash.html +++ b/docs/module-crypto_hash.html @@ -89,7 +89,7 @@
      Source:
      @@ -191,7 +191,7 @@
      Source:
      @@ -352,7 +352,7 @@
      Source:
      @@ -513,7 +513,7 @@
      Source:
      diff --git a/docs/module-crypto_hkdf.html b/docs/module-crypto_hkdf.html index 53442804..bf6f33e8 100644 --- a/docs/module-crypto_hkdf.html +++ b/docs/module-crypto_hkdf.html @@ -89,7 +89,7 @@
      Source:
      diff --git a/docs/module-crypto_mode.html b/docs/module-crypto_mode.html index 1b7a62a5..240de5b0 100644 --- a/docs/module-crypto_mode.html +++ b/docs/module-crypto_mode.html @@ -89,7 +89,7 @@
      Source:
      @@ -182,7 +182,7 @@
      Source:
      @@ -249,7 +249,7 @@
      Source:
      @@ -316,7 +316,7 @@
      Source:
      @@ -383,7 +383,7 @@
      Source:
      diff --git a/docs/module-crypto_mode_cfb.html b/docs/module-crypto_mode_cfb.html index 8cae2db7..af2dbde4 100644 --- a/docs/module-crypto_mode_cfb.html +++ b/docs/module-crypto_mode_cfb.html @@ -236,7 +236,7 @@
      Source:
      @@ -477,7 +477,7 @@
      Source:
      diff --git a/docs/module-crypto_mode_eax.html b/docs/module-crypto_mode_eax.html index 6a9a2ef4..989b3107 100644 --- a/docs/module-crypto_mode_eax.html +++ b/docs/module-crypto_mode_eax.html @@ -90,7 +90,7 @@ native AES-CTR using either the WebCrypto API or Node.js' crypto API.

      Source:
      @@ -296,7 +296,7 @@ native AES-CTR using either the WebCrypto API or Node.js' crypto API.

      Source:
      @@ -480,7 +480,7 @@ native AES-CTR using either the WebCrypto API or Node.js' crypto API.

      Source:
      @@ -665,7 +665,7 @@ native AES-CTR using either the WebCrypto API or Node.js' crypto API.

      Source:
      diff --git a/docs/module-crypto_mode_gcm.html b/docs/module-crypto_mode_gcm.html index 1746d55b..253c1a93 100644 --- a/docs/module-crypto_mode_gcm.html +++ b/docs/module-crypto_mode_gcm.html @@ -90,7 +90,7 @@ the WebCrypto api as well as node.js' crypto api.

      Source:
      @@ -273,7 +273,7 @@ the WebCrypto api as well as node.js' crypto api.

      Source:
      diff --git a/docs/module-crypto_mode_ocb.html b/docs/module-crypto_mode_ocb.html index 0cafab9f..073b1375 100644 --- a/docs/module-crypto_mode_ocb.html +++ b/docs/module-crypto_mode_ocb.html @@ -89,7 +89,7 @@
      Source:
      @@ -295,7 +295,7 @@
      Source:
      @@ -502,7 +502,7 @@
      Source:
      @@ -686,7 +686,7 @@
      Source:
      diff --git a/docs/module-crypto_pkcs1.html b/docs/module-crypto_pkcs1.html index 4144f142..406d8095 100644 --- a/docs/module-crypto_pkcs1.html +++ b/docs/module-crypto_pkcs1.html @@ -89,7 +89,7 @@
      Source:
      @@ -197,7 +197,7 @@
      Source:
      @@ -358,7 +358,7 @@
      Source:
      @@ -578,7 +578,7 @@
      Source:
      @@ -792,7 +792,7 @@
      Source:
      diff --git a/docs/module-crypto_public_key.html b/docs/module-crypto_public_key.html index 111496b0..86f155da 100644 --- a/docs/module-crypto_public_key.html +++ b/docs/module-crypto_public_key.html @@ -89,7 +89,7 @@
      Source:
      @@ -182,7 +182,7 @@
      Source:
      @@ -249,7 +249,7 @@
      Source:
      @@ -316,7 +316,7 @@
      Source:
      @@ -383,7 +383,7 @@
      Source:
      diff --git a/docs/module-crypto_public_key_dsa.html b/docs/module-crypto_public_key_dsa.html index 6dc8058d..679d0cd0 100644 --- a/docs/module-crypto_public_key_dsa.html +++ b/docs/module-crypto_public_key_dsa.html @@ -89,7 +89,7 @@
      Source:
      @@ -188,7 +188,7 @@ Expect y == y'

      Source:
      @@ -434,7 +434,7 @@ Expect y == y'

      Source:
      @@ -683,7 +683,7 @@ Expect y == y'

      Source:
      @@ -1005,7 +1005,7 @@ Expect y == y'

      Source:
      diff --git a/docs/module-crypto_public_key_elgamal.html b/docs/module-crypto_public_key_elgamal.html index 77f82b90..2ebbcaa3 100644 --- a/docs/module-crypto_public_key_elgamal.html +++ b/docs/module-crypto_public_key_elgamal.html @@ -89,7 +89,7 @@
      Source:
      @@ -188,7 +188,7 @@ Expect y == y'

      Source:
      @@ -412,7 +412,7 @@ Expect y == y'

      Source:
      @@ -672,7 +672,7 @@ Note that in OpenPGP, the message needs to be padded with PKCS#1 (same as RSA)Source:
      @@ -898,7 +898,7 @@ Note that in OpenPGP, the message needs to be padded with PKCS#1 (same as RSA)Source:
      diff --git a/docs/module-crypto_public_key_elliptic.html b/docs/module-crypto_public_key_elliptic.html index 0d398def..02577f24 100644 --- a/docs/module-crypto_public_key_elliptic.html +++ b/docs/module-crypto_public_key_elliptic.html @@ -89,7 +89,7 @@
      Source:
      diff --git a/docs/module-crypto_public_key_elliptic_curve.html b/docs/module-crypto_public_key_elliptic_curve.html index b473c720..c1a2a812 100644 --- a/docs/module-crypto_public_key_elliptic_curve.html +++ b/docs/module-crypto_public_key_elliptic_curve.html @@ -89,7 +89,7 @@
      Source:
      @@ -140,6 +140,97 @@

      Methods

      + + + + + + +

      (inner) checkPublicPointEnconding()

      + + + + + + +
      +

      Check whether the public point has a valid encoding. +NB: this function does not check e.g. whether the point belongs to the curve.

      +
      + + + + + + + + + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Source:
      +
      + + + + + + + +
      + + + + + + + + + + + + + + + + + + + + @@ -249,7 +340,7 @@
      Source:
      @@ -406,7 +497,7 @@
      Source:
      @@ -632,7 +723,7 @@
      Source:
      @@ -835,7 +926,7 @@
      Source:
      @@ -1066,7 +1157,7 @@ Not suitable for EdDSA (different secret key format)

      Source:
      diff --git a/docs/module-crypto_public_key_elliptic_ecdh.html b/docs/module-crypto_public_key_elliptic_ecdh.html index 9ed650c6..684fd46e 100644 --- a/docs/module-crypto_public_key_elliptic_ecdh.html +++ b/docs/module-crypto_public_key_elliptic_ecdh.html @@ -91,7 +91,7 @@
      Source:
      @@ -169,7 +169,7 @@
      Source:
      @@ -424,7 +424,7 @@ -

      Recipient fingerprint

      +

      Recipient fingerprint, already truncated depending on the key version

      @@ -467,7 +467,7 @@
      Source:
      @@ -720,7 +720,7 @@
      Source:
      @@ -930,7 +930,7 @@ -

      Recipient fingerprint

      +

      Recipient fingerprint, already truncated depending on the key version

      @@ -973,7 +973,7 @@
      Source:
      @@ -1176,7 +1176,7 @@
      Source:
      @@ -1337,7 +1337,7 @@
      Source:
      @@ -1540,7 +1540,7 @@
      Source:
      @@ -1747,7 +1747,7 @@
      Source:
      @@ -1977,7 +1977,7 @@
      Source:
      @@ -2157,7 +2157,7 @@
      Source:
      @@ -2360,7 +2360,7 @@
      Source:
      @@ -2540,7 +2540,7 @@
      Source:
      @@ -2766,7 +2766,7 @@
      Source:
      @@ -2946,7 +2946,7 @@
      Source:
      @@ -3077,7 +3077,7 @@
      Source:
      @@ -3155,7 +3155,7 @@
      Source:
      @@ -3410,7 +3410,7 @@ -

      Recipient fingerprint

      +

      Recipient fingerprint, already truncated depending on the key version

      @@ -3453,7 +3453,7 @@
      Source:
      @@ -3706,7 +3706,7 @@
      Source:
      @@ -3916,7 +3916,7 @@ -

      Recipient fingerprint

      +

      Recipient fingerprint, already truncated depending on the key version

      @@ -3959,7 +3959,7 @@
      Source:
      @@ -4162,7 +4162,7 @@
      Source:
      @@ -4323,7 +4323,7 @@
      Source:
      @@ -4526,7 +4526,7 @@
      Source:
      @@ -4733,7 +4733,7 @@
      Source:
      @@ -4963,7 +4963,7 @@
      Source:
      @@ -5143,7 +5143,7 @@
      Source:
      @@ -5346,7 +5346,7 @@
      Source:
      @@ -5526,7 +5526,7 @@
      Source:
      @@ -5752,7 +5752,7 @@
      Source:
      @@ -5932,7 +5932,7 @@
      Source:
      diff --git a/docs/module-crypto_public_key_elliptic_ecdsa.html b/docs/module-crypto_public_key_elliptic_ecdsa.html index db7b2c8a..7ac250b6 100644 --- a/docs/module-crypto_public_key_elliptic_ecdsa.html +++ b/docs/module-crypto_public_key_elliptic_ecdsa.html @@ -89,7 +89,7 @@
      Source:
      @@ -364,7 +364,7 @@
      Source:
      @@ -571,7 +571,7 @@
      Source:
      @@ -847,7 +847,7 @@
      Source:
      @@ -956,7 +956,7 @@ To be used if no native implementation is available for the given curve/operatio
      Source:
      diff --git a/docs/module-crypto_public_key_elliptic_eddsa.html b/docs/module-crypto_public_key_elliptic_eddsa.html index 5bf9bccf..a0a144f2 100644 --- a/docs/module-crypto_public_key_elliptic_eddsa.html +++ b/docs/module-crypto_public_key_elliptic_eddsa.html @@ -89,7 +89,7 @@
      Source:
      @@ -249,7 +249,7 @@
      Source:
      @@ -521,7 +521,7 @@
      Source:
      @@ -751,7 +751,7 @@
      Source:
      @@ -1027,7 +1027,7 @@
      Source:
      diff --git a/docs/module-crypto_public_key_elliptic_eddsa_legacy.html b/docs/module-crypto_public_key_elliptic_eddsa_legacy.html index 832516db..461a7a0c 100644 --- a/docs/module-crypto_public_key_elliptic_eddsa_legacy.html +++ b/docs/module-crypto_public_key_elliptic_eddsa_legacy.html @@ -90,7 +90,7 @@ This key type has been deprecated by the crypto-refresh RFC.

      Source:
      @@ -365,7 +365,7 @@ This key type has been deprecated by the crypto-refresh RFC.

      Source:
      @@ -572,7 +572,7 @@ This key type has been deprecated by the crypto-refresh RFC.

      Source:
      @@ -848,7 +848,7 @@ This key type has been deprecated by the crypto-refresh RFC.

      Source:
      diff --git a/docs/module-crypto_public_key_rsa.html b/docs/module-crypto_public_key_rsa.html index bcb3d1a4..bcdec3ec 100644 --- a/docs/module-crypto_public_key_rsa.html +++ b/docs/module-crypto_public_key_rsa.html @@ -89,7 +89,7 @@
      Source:
      @@ -411,7 +411,7 @@
      Source:
      @@ -647,7 +647,7 @@
      Source:
      @@ -833,7 +833,7 @@
      Source:
      @@ -1186,7 +1186,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

      Source:
      @@ -1462,7 +1462,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

      Source:
      @@ -1738,7 +1738,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

      Source:
      @@ -1846,7 +1846,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

      Source:
      @@ -2123,7 +2123,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

      Source:
      @@ -2308,7 +2308,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

      Source:
      diff --git a/docs/module-crypto_random.html b/docs/module-crypto_random.html index 5e4aade2..c3565064 100644 --- a/docs/module-crypto_random.html +++ b/docs/module-crypto_random.html @@ -89,7 +89,7 @@
      Source:
      @@ -272,7 +272,7 @@
      Source:
      @@ -433,7 +433,7 @@
      Source:
      diff --git a/docs/module-crypto_signature.html b/docs/module-crypto_signature.html index d32f4ffa..f1840a6e 100644 --- a/docs/module-crypto_signature.html +++ b/docs/module-crypto_signature.html @@ -89,7 +89,7 @@
      Source:
      @@ -276,7 +276,7 @@ See RFC 4880 5.2.2.<
      Source:
      @@ -555,7 +555,7 @@ for public key and hash algorithms.

      Source:
      @@ -834,7 +834,7 @@ for public key and hash algorithms.

      Source:
      diff --git a/docs/module-encoding_base64.html b/docs/module-encoding_base64.html index 6909128f..a276a070 100644 --- a/docs/module-encoding_base64.html +++ b/docs/module-encoding_base64.html @@ -168,7 +168,7 @@
      Source:
      @@ -332,7 +332,7 @@
      Source:
      @@ -499,7 +499,7 @@
      Source:
      @@ -686,7 +686,7 @@
      Source:
      diff --git a/docs/module-enums.html b/docs/module-enums.html index 927be691..408ddd44 100644 --- a/docs/module-enums.html +++ b/docs/module-enums.html @@ -235,7 +235,7 @@
      Source:
      @@ -499,7 +499,7 @@
      Source:
      @@ -694,7 +694,7 @@
      Source:
      @@ -1119,7 +1119,7 @@
      Source:
      @@ -1323,7 +1323,7 @@ fingerprint format

      Source:
      @@ -1633,7 +1633,7 @@ fingerprint format

      Source:
      @@ -1899,7 +1899,7 @@ possession of more than one person.

      Source:
      @@ -2094,7 +2094,7 @@ possession of more than one person.

      Source:
      @@ -2634,7 +2634,7 @@ possession of more than one person.

      Source:
      @@ -3060,7 +3060,7 @@ possession of more than one person.

      Source:
      @@ -3278,7 +3278,7 @@ possession of more than one person.

      Source:
      @@ -3496,7 +3496,7 @@ possession of more than one person.

      Source:
      @@ -4013,7 +4013,7 @@ document) that cannot include a target subpacket.

      Source:
      @@ -4737,7 +4737,7 @@ document) that cannot include a target subpacket.

      Source:
      @@ -5024,7 +5024,7 @@ document) that cannot include a target subpacket.

      Source:
      @@ -5220,7 +5220,7 @@ document) that cannot include a target subpacket.

      Source:
      @@ -5374,7 +5374,7 @@ document) that cannot include a target subpacket.

      Source:
      @@ -5590,7 +5590,7 @@ document) that cannot include a target subpacket.

      Source:
      diff --git a/docs/module-key_Subkey-Subkey.html b/docs/module-key_Subkey-Subkey.html index 378ae6c5..4265ae71 100644 --- a/docs/module-key_Subkey-Subkey.html +++ b/docs/module-key_Subkey-Subkey.html @@ -171,7 +171,7 @@
      Source:
      @@ -281,7 +281,7 @@
      Source:
      @@ -394,7 +394,7 @@
      Source:
      @@ -511,7 +511,7 @@
      Source:
      @@ -628,7 +628,7 @@
      Source:
      @@ -741,7 +741,7 @@
      Source:
      @@ -942,7 +942,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -1055,7 +1055,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -1172,7 +1172,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -1289,7 +1289,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -1406,7 +1406,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -1523,7 +1523,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -1640,7 +1640,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -1757,7 +1757,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -1873,7 +1873,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -2149,7 +2149,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -2487,7 +2487,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -2599,7 +2599,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -2832,7 +2832,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -3044,7 +3044,7 @@ and valid binding signature.

      Source:
      diff --git a/docs/module-key_User-User.html b/docs/module-key_User-User.html index 21762695..8d2c238b 100644 --- a/docs/module-key_User-User.html +++ b/docs/module-key_User-User.html @@ -171,7 +171,7 @@
      Source:
      @@ -404,7 +404,7 @@
      Source:
      @@ -516,7 +516,7 @@
      Source:
      @@ -789,7 +789,7 @@
      Source:
      @@ -1127,7 +1127,7 @@
      Source:
      @@ -1239,7 +1239,7 @@
      Source:
      @@ -1442,7 +1442,7 @@
      Source:
      @@ -1623,7 +1623,7 @@ and validity of self signature.

      Source:
      @@ -1887,7 +1887,7 @@ and validity of self signature.

      Source:
      @@ -2154,7 +2154,7 @@ Signature validity is null if the verification keys do not correspond to the cer
      Source:
      diff --git a/docs/module-key_helper.html b/docs/module-key_helper.html index 9d9d5e74..9ad65643 100644 --- a/docs/module-key_helper.html +++ b/docs/module-key_helper.html @@ -89,7 +89,7 @@
      Source:
      @@ -281,7 +281,7 @@
      Source:
      @@ -518,7 +518,7 @@
      Source:
      @@ -928,7 +928,7 @@
      Source:
      @@ -1116,7 +1116,7 @@ The expiration time of the signature is ignored.

      Source:
      @@ -1177,7 +1177,7 @@ The expiration time of the signature is ignored.

      -

      (async, static) getLatestValidSignature(signatures, publicKey, date, config) → {Promise.<SignaturePacket>}

      +

      (async, static) getLatestValidSignature(signatures, publicKey, signatureType, date, config) → {Promise.<SignaturePacket>}

      @@ -1268,6 +1268,30 @@ The expiration time of the signature is ignored.

      + + + signatureType + + + + + +module:enums.signature + + + + + + + + + +

      Signature type to determine how to hash the data (NB: for userID signatures, +enums.signatures.certGeneric should be given regardless of the actual trust level)

      + + + + date @@ -1352,7 +1376,7 @@ The expiration time of the signature is ignored.

      Source:
      @@ -1624,7 +1648,7 @@ The expiration time of the signature is ignored.

      Source:
      @@ -1896,7 +1920,7 @@ The expiration time of the signature is ignored.

      Source:
      @@ -2200,7 +2224,7 @@ The expiration time of the signature is ignored.

      Source:
      @@ -2507,7 +2531,7 @@ The expiration time of the signature is ignored.

      Source:
      @@ -2806,7 +2830,7 @@ The expiration time of the signature is ignored.

      Source:
      diff --git a/docs/module-packet_packet.html b/docs/module-packet_packet.html index 99303fe7..87ddc5ff 100644 --- a/docs/module-packet_packet.html +++ b/docs/module-packet_packet.html @@ -89,7 +89,7 @@
      Source:
      @@ -275,7 +275,7 @@
      Source:
      @@ -436,7 +436,7 @@
      Source:
      @@ -621,7 +621,7 @@ string

      Source:
      @@ -783,7 +783,7 @@ string

      Source:
      diff --git a/docs/module-type_ecdh_symkey.html b/docs/module-type_ecdh_symkey.html index 9c559b3f..e9197ca1 100644 --- a/docs/module-type_ecdh_symkey.html +++ b/docs/module-type_ecdh_symkey.html @@ -89,7 +89,7 @@
      Source:
      diff --git a/docs/module-type_kdf_params-KDFParams.html b/docs/module-type_kdf_params-KDFParams.html index 2c364142..c3f4c8a0 100644 --- a/docs/module-type_kdf_params-KDFParams.html +++ b/docs/module-type_kdf_params-KDFParams.html @@ -163,7 +163,7 @@
      Source:
      @@ -322,7 +322,7 @@
      Source:
      @@ -434,7 +434,7 @@
      Source:
      diff --git a/docs/module-type_keyid-KeyID.html b/docs/module-type_keyid-KeyID.html index fda5c8e1..159d107c 100644 --- a/docs/module-type_keyid-KeyID.html +++ b/docs/module-type_keyid-KeyID.html @@ -101,7 +101,7 @@ formed.

      Source:
      @@ -295,7 +295,7 @@ formed.

      Source:
      @@ -385,7 +385,7 @@ formed.

      Source:
      @@ -497,7 +497,7 @@ formed.

      Source:
      @@ -658,7 +658,7 @@ formed.

      Source:
      @@ -748,7 +748,7 @@ formed.

      Source:
      @@ -860,7 +860,7 @@ formed.

      Source:
      diff --git a/docs/module-type_oid.html b/docs/module-type_oid.html index bd4a59f0..c0268f57 100644 --- a/docs/module-type_oid.html +++ b/docs/module-type_oid.html @@ -100,7 +100,7 @@ sequence of octets is the valid representation of a curve OID.

      Source:
      diff --git a/docs/module-type_s2k-GenericS2K.html b/docs/module-type_s2k-GenericS2K.html index ec13966a..9c4cb114 100644 --- a/docs/module-type_s2k-GenericS2K.html +++ b/docs/module-type_s2k-GenericS2K.html @@ -153,7 +153,7 @@
      Source:
      @@ -262,7 +262,7 @@
      Source:
      @@ -332,7 +332,7 @@
      Source:
      @@ -406,7 +406,7 @@
      Source:
      @@ -480,7 +480,7 @@
      Source:
      @@ -612,7 +612,7 @@ hashAlgorithm

      Source:
      @@ -774,7 +774,7 @@ hashAlgorithm hash length

      Source:
      @@ -886,7 +886,7 @@ hashAlgorithm hash length

      Source:
      diff --git a/docs/module-type_s2k.html b/docs/module-type_s2k.html index 202ddfa5..34f9574f 100644 --- a/docs/module-type_s2k.html +++ b/docs/module-type_s2k.html @@ -95,7 +95,7 @@ symmetrically encrypted messages.

      Source:
      diff --git a/docs/module-type_x25519x448_symkey.html b/docs/module-type_x25519x448_symkey.html index 305c14ab..b3ce3751 100644 --- a/docs/module-type_x25519x448_symkey.html +++ b/docs/module-type_x25519x448_symkey.html @@ -91,7 +91,7 @@ the former includes an algorithm byte preceeding the encrypted session key.

      <
      Source:
      diff --git a/docs/module-util.html b/docs/module-util.html index 68123fe2..c19d5d0a 100644 --- a/docs/module-util.html +++ b/docs/module-util.html @@ -89,7 +89,7 @@
      Source:
      diff --git a/package-lock.json b/package-lock.json index a21289d1..cd99b765 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "openpgp", - "version": "6.0.0-beta.1", + "version": "6.0.0-beta.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "openpgp", - "version": "6.0.0-beta.1", + "version": "6.0.0-beta.2", "license": "LGPL-3.0+", "devDependencies": { "@noble/curves": "^1.4.0", diff --git a/package.json b/package.json index 6a06fd28..51f026cb 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "openpgp", "description": "OpenPGP.js is a Javascript implementation of the OpenPGP protocol. This is defined in RFC 4880.", - "version": "6.0.0-beta.1", + "version": "6.0.0-beta.2", "license": "LGPL-3.0+", "homepage": "https://openpgpjs.org/", "engines": { From efb0324330095741b17bbc66a83e22ae6016d59a Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Mon, 15 Jul 2024 15:14:27 +0200 Subject: [PATCH 160/201] TS: add definition for `config.enableParsingV5Entities` [skip ci] --- openpgp.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/openpgp.d.ts b/openpgp.d.ts index 405a99b3..b4d54b5b 100644 --- a/openpgp.d.ts +++ b/openpgp.d.ts @@ -340,6 +340,7 @@ interface Config { constantTimePKCS1Decryption: boolean; constantTimePKCS1DecryptionSupportedSymmetricAlgorithms: Set; v6Keys: boolean; + enableParsingV5Entities: boolean; preferredAEADAlgorithm: enums.aead; aeadChunkSizeByte: number; s2kType: enums.s2k.iterated | enums.s2k.argon2; From fca699373a9300a8d6539cd866e5e6640407113c Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Mon, 12 Aug 2024 11:52:52 +0200 Subject: [PATCH 161/201] Try more AEAD ciphersuites for SEIPDv2 (#1781) Stick more closely to the algorithm preferences when creating an SEIPDv2 message, by trying additional combinations of the preferred symmetric algorithm and the preferred AEAD algorithm. If one of them is supported but not the other, we still use it (with the mandatory-to-implement algorithm for the other one). --- src/key/helper.js | 19 +++++++++++++------ test/general/key.js | 28 ++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/src/key/helper.js b/src/key/helper.js index 16f47acd..e803acab 100644 --- a/src/key/helper.js +++ b/src/key/helper.js @@ -178,12 +178,19 @@ export async function getPreferredCipherSuite(keys = [], date = new Date(), user if (withAEAD) { const defaultCipherSuite = { symmetricAlgo: enums.symmetric.aes128, aeadAlgo: enums.aead.ocb }; - const desiredCipherSuite = { symmetricAlgo: config.preferredSymmetricAlgorithm, aeadAlgo: config.preferredAEADAlgorithm }; - return selfSigs.every(selfSig => selfSig.preferredCipherSuites && selfSig.preferredCipherSuites.some( - cipherSuite => cipherSuite[0] === desiredCipherSuite.symmetricAlgo && cipherSuite[1] === desiredCipherSuite.aeadAlgo - )) ? - desiredCipherSuite : - defaultCipherSuite; + const desiredCipherSuites = [ + { symmetricAlgo: config.preferredSymmetricAlgorithm, aeadAlgo: config.preferredAEADAlgorithm }, + { symmetricAlgo: config.preferredSymmetricAlgorithm, aeadAlgo: enums.aead.ocb }, + { symmetricAlgo: enums.symmetric.aes128, aeadAlgo: config.preferredAEADAlgorithm } + ]; + for (const desiredCipherSuite of desiredCipherSuites) { + if (selfSigs.every(selfSig => selfSig.preferredCipherSuites && selfSig.preferredCipherSuites.some( + cipherSuite => cipherSuite[0] === desiredCipherSuite.symmetricAlgo && cipherSuite[1] === desiredCipherSuite.aeadAlgo + ))) { + return desiredCipherSuite; + } + } + return defaultCipherSuite; } const defaultSymAlgo = enums.symmetric.aes128; const desiredSymAlgo = config.preferredSymmetricAlgorithm; diff --git a/test/general/key.js b/test/general/key.js index 9aed9d57..06ed5ab4 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -4129,6 +4129,34 @@ CNa5yq6lyexhsn2Vs8DsX+SOSUyNJiy5FyIJ expect(aeadAlgo).to.equal(openpgp.enums.aead.gcm); }); + it('getPreferredCipherSuite with AEAD - one key - AES256-OCB', async function() { + const [key1] = await openpgp.readKeys({ armoredKeys: twoKeys }); + const primaryUser = await key1.getPrimaryUser(); + primaryUser.selfCertification.features = [9]; // Monkey-patch SEIPDv2 feature flag + primaryUser.selfCertification.preferredCipherSuites = [[openpgp.enums.symmetric.aes256, openpgp.enums.aead.ocb]]; + const { symmetricAlgo, aeadAlgo } = await getPreferredCipherSuite([key1], undefined, undefined, { + ...openpgp.config, + aeadProtect: true, + preferredAEADAlgorithm: openpgp.enums.aead.gcm + }); + expect(symmetricAlgo).to.equal(openpgp.enums.symmetric.aes256); + expect(aeadAlgo).to.equal(openpgp.enums.aead.ocb); + }); + + it('getPreferredCipherSuite with AEAD - one key - AES128-GCM', async function() { + const [key1] = await openpgp.readKeys({ armoredKeys: twoKeys }); + const primaryUser = await key1.getPrimaryUser(); + primaryUser.selfCertification.features = [9]; // Monkey-patch SEIPDv2 feature flag + primaryUser.selfCertification.preferredCipherSuites = [[openpgp.enums.symmetric.aes128, openpgp.enums.aead.gcm]]; + const { symmetricAlgo, aeadAlgo } = await getPreferredCipherSuite([key1], undefined, undefined, { + ...openpgp.config, + aeadProtect: true, + preferredAEADAlgorithm: openpgp.enums.aead.gcm + }); + expect(symmetricAlgo).to.equal(openpgp.enums.symmetric.aes128); + expect(aeadAlgo).to.equal(openpgp.enums.aead.gcm); + }); + it('getPreferredCipherSuite with AEAD - two keys - one without pref', async function() { const keys = await openpgp.readKeys({ armoredKeys: twoKeys }); const key1 = keys[0]; From bcaaa7e2d29ad21309ae42dd651329816ca81e73 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Thu, 11 Jul 2024 10:26:35 +0200 Subject: [PATCH 162/201] Use WebCrypto for ed25519 when available --- src/crypto/public_key/elliptic/eddsa.js | 95 ++++++++++++++++--- .../public_key/elliptic/eddsa_legacy.js | 8 +- src/crypto/public_key/elliptic/oid_curves.js | 7 +- 3 files changed, 92 insertions(+), 18 deletions(-) diff --git a/src/crypto/public_key/elliptic/eddsa.js b/src/crypto/public_key/elliptic/eddsa.js index 1e6aac2f..776dfedd 100644 --- a/src/crypto/public_key/elliptic/eddsa.js +++ b/src/crypto/public_key/elliptic/eddsa.js @@ -25,6 +25,7 @@ import util from '../../../util'; import enums from '../../../enums'; import hash from '../../hash'; import { getRandomBytes } from '../../random'; +import { b64ToUint8Array, uint8ArrayToB64 } from '../../../encoding/base64'; /** @@ -34,11 +35,27 @@ import { getRandomBytes } from '../../random'; */ export async function generate(algo) { switch (algo) { - case enums.publicKey.ed25519: { - const seed = getRandomBytes(getPayloadSize(algo)); - const { publicKey: A } = ed25519.sign.keyPair.fromSeed(seed); - return { A, seed }; - } + case enums.publicKey.ed25519: + try { + const webCrypto = util.getWebCrypto(); + const webCryptoKey = await webCrypto.generateKey('Ed25519', true, ['sign', 'verify']); + + const privateKey = await webCrypto.exportKey('jwk', webCryptoKey.privateKey); + const publicKey = await webCrypto.exportKey('jwk', webCryptoKey.publicKey); + + return { + A: new Uint8Array(b64ToUint8Array(publicKey.x)), + seed: b64ToUint8Array(privateKey.d, true) + }; + } catch (err) { + if (err.name !== 'NotSupportedError') { + throw err; + } + const seed = getRandomBytes(getPayloadSize(algo)); + const { publicKey: A } = ed25519.sign.keyPair.fromSeed(seed); + return { A, seed }; + } + case enums.publicKey.ed448: { const ed448 = await util.getNobleCurve(enums.publicKey.ed448); const seed = ed448.utils.randomPrivateKey(); @@ -68,11 +85,26 @@ export async function sign(algo, hashAlgo, message, publicKey, privateKey, hashe throw new Error('Hash algorithm too weak for EdDSA.'); } switch (algo) { - case enums.publicKey.ed25519: { - const secretKey = util.concatUint8Array([privateKey, publicKey]); - const signature = ed25519.sign.detached(hashed, secretKey); - return { RS: signature }; - } + case enums.publicKey.ed25519: + try { + const webCrypto = util.getWebCrypto(); + const jwk = privateKeyToJWK(algo, publicKey, privateKey); + const key = await webCrypto.importKey('jwk', jwk, 'Ed25519', false, ['sign']); + + const signature = new Uint8Array( + await webCrypto.sign('Ed25519', key, hashed) + ); + + return { RS: signature }; + } catch (err) { + if (err.name !== 'NotSupportedError') { + throw err; + } + const secretKey = util.concatUint8Array([privateKey, publicKey]); + const signature = ed25519.sign.detached(hashed, secretKey); + return { RS: signature }; + } + case enums.publicKey.ed448: { const ed448 = await util.getNobleCurve(enums.publicKey.ed448); const signature = ed448.sign(hashed, privateKey); @@ -101,7 +133,19 @@ export async function verify(algo, hashAlgo, { RS }, m, publicKey, hashed) { } switch (algo) { case enums.publicKey.ed25519: - return ed25519.sign.detached.verify(hashed, RS, publicKey); + try { + const webCrypto = util.getWebCrypto(); + const jwk = publicKeyToJWK(algo, publicKey); + const key = await webCrypto.importKey('jwk', jwk, 'Ed25519', false, ['verify']); + const verified = await webCrypto.verify('Ed25519', key, RS, hashed); + return verified; + } catch (err) { + if (err.name !== 'NotSupportedError') { + throw err; + } + return ed25519.sign.detached.verify(hashed, RS, publicKey); + } + case enums.publicKey.ed448: { const ed448 = await util.getNobleCurve(enums.publicKey.ed448); return ed448.verify(RS, hashed, publicKey); @@ -125,6 +169,7 @@ export async function validateParams(algo, A, seed) { /** * Derive public point A' from private key * and expect A == A' + * TODO: move to sign-verify using WebCrypto (same as ECDSA) when curve is more widely implemented */ const { publicKey } = ed25519.sign.keyPair.fromSeed(seed); return util.equalsUint8Array(A, publicKey); @@ -164,3 +209,31 @@ export function getPreferredHashAlgo(algo) { throw new Error('Unknown EdDSA algo'); } } + +const publicKeyToJWK = (algo, publicKey) => { + switch (algo) { + case enums.publicKey.ed25519: { + const jwk = { + kty: 'OKP', + crv: 'Ed25519', + x: uint8ArrayToB64(publicKey, true), + ext: true + }; + return jwk; + } + default: + throw new Error('Unsupported EdDSA algorithm'); + } +}; + +const privateKeyToJWK = (algo, publicKey, privateKey) => { + switch (algo) { + case enums.publicKey.ed25519: { + const jwk = publicKeyToJWK(algo, publicKey); + jwk.d = uint8ArrayToB64(privateKey, true); + return jwk; + } + default: + throw new Error('Unsupported EdDSA algorithm'); + } +}; diff --git a/src/crypto/public_key/elliptic/eddsa_legacy.js b/src/crypto/public_key/elliptic/eddsa_legacy.js index b564b176..28c72d4e 100644 --- a/src/crypto/public_key/elliptic/eddsa_legacy.js +++ b/src/crypto/public_key/elliptic/eddsa_legacy.js @@ -26,6 +26,7 @@ import util from '../../../util'; import enums from '../../../enums'; import hash from '../../hash'; import { CurveWithOID, checkPublicPointEnconding } from './oid_curves'; +import { sign as eddsaSign, verify as eddsaVerify } from './eddsa'; /** * Sign a message using the provided legacy EdDSA key @@ -48,8 +49,7 @@ export async function sign(oid, hashAlgo, message, publicKey, privateKey, hashed // see https://tools.ietf.org/id/draft-ietf-openpgp-rfc4880bis-10.html#section-15-7.2 throw new Error('Hash algorithm too weak for EdDSA.'); } - const secretKey = util.concatUint8Array([privateKey, publicKey.subarray(1)]); - const signature = nacl.sign.detached(hashed, secretKey); + const { RS: signature } = await eddsaSign(enums.publicKey.ed25519, hashAlgo, message, publicKey.subarray(1), privateKey, hashed); // EdDSA signature params are returned in little-endian format return { r: signature.subarray(0, 32), @@ -75,8 +75,8 @@ export async function verify(oid, hashAlgo, { r, s }, m, publicKey, hashed) { if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(enums.hash.sha256)) { throw new Error('Hash algorithm too weak for EdDSA.'); } - const signature = util.concatUint8Array([r, s]); - return nacl.sign.detached.verify(hashed, signature, publicKey.subarray(1)); + const RS = util.concatUint8Array([r, s]); + return eddsaVerify(enums.publicKey.ed25519, hashAlgo, { RS }, m, publicKey.subarray(1), hashed); } /** * Validate legacy EdDSA parameters diff --git a/src/crypto/public_key/elliptic/oid_curves.js b/src/crypto/public_key/elliptic/oid_curves.js index 079c6f43..4e83de0c 100644 --- a/src/crypto/public_key/elliptic/oid_curves.js +++ b/src/crypto/public_key/elliptic/oid_curves.js @@ -26,6 +26,8 @@ import util from '../../../util'; import { uint8ArrayToB64, b64ToUint8Array } from '../../../encoding/base64'; import OID from '../../../type/oid'; import { UnsupportedError } from '../../../packet/packet'; +import { generate as eddsaGenerate } from './eddsa'; +import { generate as ecdhXGenerate } from './ecdh_x'; const webCrypto = util.getWebCrypto(); const nodeCrypto = util.getNodeCrypto(); @@ -190,9 +192,8 @@ class CurveWithOID { return { publicKey, privateKey }; } case 'ed25519Legacy': { - const privateKey = getRandomBytes(32); - const keyPair = nacl.sign.keyPair.fromSeed(privateKey); - const publicKey = util.concatUint8Array([new Uint8Array([this.wireFormatLeadingByte]), keyPair.publicKey]); + const { seed: privateKey, A } = await eddsaGenerate(enums.publicKey.ed25519); + const publicKey = util.concatUint8Array([new Uint8Array([this.wireFormatLeadingByte]), A]); return { publicKey, privateKey }; } default: From 7698790d1ccde2d37b178abaf7000cc39aac1821 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Thu, 11 Jul 2024 13:28:30 +0200 Subject: [PATCH 163/201] Use WebCrypto for x25519 when available --- src/crypto/public_key/elliptic/ecdh.js | 11 +- src/crypto/public_key/elliptic/ecdh_x.js | 176 +++++++++++++++---- src/crypto/public_key/elliptic/oid_curves.js | 10 +- 3 files changed, 147 insertions(+), 50 deletions(-) diff --git a/src/crypto/public_key/elliptic/ecdh.js b/src/crypto/public_key/elliptic/ecdh.js index 9f5cd1f6..18bdc664 100644 --- a/src/crypto/public_key/elliptic/ecdh.js +++ b/src/crypto/public_key/elliptic/ecdh.js @@ -20,16 +20,15 @@ * @module crypto/public_key/elliptic/ecdh */ -import nacl from '@openpgp/tweetnacl'; import { CurveWithOID, jwkToRawPublic, rawPublicToJWK, privateToJWK, validateStandardParams, checkPublicPointEnconding } from './oid_curves'; import * as aesKW from '../../aes_kw'; -import { getRandomBytes } from '../../random'; import hash from '../../hash'; import enums from '../../../enums'; import util from '../../../util'; import { b64ToUint8Array } from '../../../encoding/base64'; import * as pkcs5 from '../../pkcs5'; import { getCipherParams } from '../../cipher'; +import { generateEphemeralEncryptionMaterial as ecdhXGenerateEphemeralEncryptionMaterial, recomputeSharedSecret as ecdhXRecomputeSharedSecret } from './ecdh_x'; const webCrypto = util.getWebCrypto(); const nodeCrypto = util.getNodeCrypto(); @@ -92,10 +91,8 @@ async function kdf(hashAlgo, X, length, param, stripLeading = false, stripTraili async function genPublicEphemeralKey(curve, Q) { switch (curve.type) { case 'curve25519Legacy': { - const d = getRandomBytes(32); - const { secretKey, sharedKey } = await genPrivateEphemeralKey(curve, Q, null, d); - let { publicKey } = nacl.box.keyPair.fromSecretKey(secretKey); - publicKey = util.concatUint8Array([new Uint8Array([curve.wireFormatLeadingByte]), publicKey]); + const { sharedSecret: sharedKey, ephemeralPublicKey } = await ecdhXGenerateEphemeralEncryptionMaterial(enums.publicKey.x25519, Q.subarray(1)); + const publicKey = util.concatUint8Array([new Uint8Array([curve.wireFormatLeadingByte]), ephemeralPublicKey]); return { publicKey, sharedKey }; // Note: sharedKey is little-endian here, unlike below } case 'web': @@ -159,7 +156,7 @@ async function genPrivateEphemeralKey(curve, V, Q, d) { switch (curve.type) { case 'curve25519Legacy': { const secretKey = d.slice().reverse(); - const sharedKey = nacl.scalarMult(secretKey, V.subarray(1)); + const sharedKey = await ecdhXRecomputeSharedSecret(enums.publicKey.x25519, V.subarray(1), Q.subarray(1), secretKey); return { secretKey, sharedKey }; // Note: sharedKey is little-endian here, unlike below } case 'web': diff --git a/src/crypto/public_key/elliptic/ecdh_x.js b/src/crypto/public_key/elliptic/ecdh_x.js index 641af020..1dfc96e8 100644 --- a/src/crypto/public_key/elliptic/ecdh_x.js +++ b/src/crypto/public_key/elliptic/ecdh_x.js @@ -11,6 +11,7 @@ import enums from '../../../enums'; import util from '../../../util'; import computeHKDF from '../../hkdf'; import { getCipherParams } from '../../cipher'; +import { b64ToUint8Array, uint8ArrayToB64 } from '../../../encoding/base64'; const HKDF_INFO = { x25519: util.encodeUTF8('OpenPGP X25519'), @@ -24,12 +25,28 @@ const HKDF_INFO = { */ export async function generate(algo) { switch (algo) { - case enums.publicKey.x25519: { - // k stays in little-endian, unlike legacy ECDH over curve25519 - const k = getRandomBytes(32); - const { publicKey: A } = x25519.box.keyPair.fromSecretKey(k); - return { A, k }; - } + case enums.publicKey.x25519: + try { + const webCrypto = util.getWebCrypto(); + const webCryptoKey = await webCrypto.generateKey('X25519', true, ['deriveKey', 'deriveBits']); + + const privateKey = await webCrypto.exportKey('jwk', webCryptoKey.privateKey); + const publicKey = await webCrypto.exportKey('jwk', webCryptoKey.publicKey); + + return { + A: new Uint8Array(b64ToUint8Array(publicKey.x)), + k: b64ToUint8Array(privateKey.d, true) + }; + } catch (err) { + if (err.name !== 'NotSupportedError') { + throw err; + } + // k stays in little-endian, unlike legacy ECDH over curve25519 + const k = getRandomBytes(32); + const { publicKey: A } = x25519.box.keyPair.fromSecretKey(k); + return { A, k }; + } + case enums.publicKey.x448: { const x448 = await util.getNobleCurve(enums.publicKey.x448); const k = x448.utils.randomPrivateKey(); @@ -87,16 +104,14 @@ export async function validateParams(algo, A, k) { * @async */ export async function encrypt(algo, data, recipientA) { + const { ephemeralPublicKey, sharedSecret } = await generateEphemeralEncryptionMaterial(algo, recipientA); + const hkdfInput = util.concatUint8Array([ + ephemeralPublicKey, + recipientA, + sharedSecret + ]); switch (algo) { case enums.publicKey.x25519: { - const ephemeralSecretKey = getRandomBytes(32); - const sharedSecret = x25519.scalarMult(ephemeralSecretKey, recipientA); - const { publicKey: ephemeralPublicKey } = x25519.box.keyPair.fromSecretKey(ephemeralSecretKey); - const hkdfInput = util.concatUint8Array([ - ephemeralPublicKey, - recipientA, - sharedSecret - ]); const cipherAlgo = enums.symmetric.aes128; const { keySize } = getCipherParams(cipherAlgo); const encryptionKey = await computeHKDF(enums.hash.sha256, hkdfInput, new Uint8Array(), HKDF_INFO.x25519, keySize); @@ -104,15 +119,6 @@ export async function encrypt(algo, data, recipientA) { return { ephemeralPublicKey, wrappedKey }; } case enums.publicKey.x448: { - const x448 = await util.getNobleCurve(enums.publicKey.x448); - const ephemeralSecretKey = x448.utils.randomPrivateKey(); - const sharedSecret = x448.getSharedSecret(ephemeralSecretKey, recipientA); - const ephemeralPublicKey = x448.getPublicKey(ephemeralSecretKey); - const hkdfInput = util.concatUint8Array([ - ephemeralPublicKey, - recipientA, - sharedSecret - ]); const cipherAlgo = enums.symmetric.aes256; const { keySize } = getCipherParams(enums.symmetric.aes256); const encryptionKey = await computeHKDF(enums.hash.sha512, hkdfInput, new Uint8Array(), HKDF_INFO.x448, keySize); @@ -137,27 +143,20 @@ export async function encrypt(algo, data, recipientA) { * @async */ export async function decrypt(algo, ephemeralPublicKey, wrappedKey, A, k) { + const sharedSecret = await recomputeSharedSecret(algo, ephemeralPublicKey, A, k); + const hkdfInput = util.concatUint8Array([ + ephemeralPublicKey, + A, + sharedSecret + ]); switch (algo) { case enums.publicKey.x25519: { - const sharedSecret = x25519.scalarMult(k, ephemeralPublicKey); - const hkdfInput = util.concatUint8Array([ - ephemeralPublicKey, - A, - sharedSecret - ]); const cipherAlgo = enums.symmetric.aes128; const { keySize } = getCipherParams(cipherAlgo); const encryptionKey = await computeHKDF(enums.hash.sha256, hkdfInput, new Uint8Array(), HKDF_INFO.x25519, keySize); return aesKW.unwrap(cipherAlgo, encryptionKey, wrappedKey); } case enums.publicKey.x448: { - const x448 = await util.getNobleCurve(enums.publicKey.x448); - const sharedSecret = x448.getSharedSecret(k, ephemeralPublicKey); - const hkdfInput = util.concatUint8Array([ - ephemeralPublicKey, - A, - sharedSecret - ]); const cipherAlgo = enums.symmetric.aes256; const { keySize } = getCipherParams(enums.symmetric.aes256); const encryptionKey = await computeHKDF(enums.hash.sha512, hkdfInput, new Uint8Array(), HKDF_INFO.x448, keySize); @@ -180,3 +179,108 @@ export function getPayloadSize(algo) { throw new Error('Unsupported ECDH algorithm'); } } + +/** + * Generate shared secret and ephemeral public key for encryption + * @returns {Promise<{ ephemeralPublicKey: Uint8Array, sharedSecret: Uint8Array }>} ephemeral public key (K_A) and shared secret + * @async + */ +export async function generateEphemeralEncryptionMaterial(algo, recipientA) { + switch (algo) { + case enums.publicKey.x25519: + try { + const webCrypto = util.getWebCrypto(); + const jwk = publicKeyToJWK(algo, recipientA); + const ephemeralKeyPair = await webCrypto.generateKey('X25519', true, ['deriveKey', 'deriveBits']); + const recipientPublicKey = await webCrypto.importKey('jwk', jwk, 'X25519', false, []); + const sharedSecretBuffer = await webCrypto.deriveBits( + { name: 'X25519', public: recipientPublicKey }, + ephemeralKeyPair.privateKey, + getPayloadSize(algo) * 8 // in bits + ); + const ephemeralPublicKeyJwt = await webCrypto.exportKey('jwk', ephemeralKeyPair.publicKey); + return { + sharedSecret: new Uint8Array(sharedSecretBuffer), + ephemeralPublicKey: new Uint8Array(b64ToUint8Array(ephemeralPublicKeyJwt.x)) + }; + } catch (err) { + if (err.name !== 'NotSupportedError') { + throw err; + } + const ephemeralSecretKey = getRandomBytes(getPayloadSize(algo)); + const sharedSecret = x25519.scalarMult(ephemeralSecretKey, recipientA); + const { publicKey: ephemeralPublicKey } = x25519.box.keyPair.fromSecretKey(ephemeralSecretKey); + + return { ephemeralPublicKey, sharedSecret }; + } + case enums.publicKey.x448: { + const x448 = await util.getNobleCurve(enums.publicKey.x448); + const ephemeralSecretKey = x448.utils.randomPrivateKey(); + const sharedSecret = x448.getSharedSecret(ephemeralSecretKey, recipientA); + const ephemeralPublicKey = x448.getPublicKey(ephemeralSecretKey); + return { ephemeralPublicKey, sharedSecret }; + } + default: + throw new Error('Unsupported ECDH algorithm'); + } +} + +export async function recomputeSharedSecret(algo, ephemeralPublicKey, A, k) { + switch (algo) { + case enums.publicKey.x25519: + try { + const webCrypto = util.getWebCrypto(); + const privateKeyJWK = privateKeyToJWK(algo, A, k); + const ephemeralPublicKeyJWK = publicKeyToJWK(algo, ephemeralPublicKey); + const privateKey = await webCrypto.importKey('jwk', privateKeyJWK, 'X25519', false, ['deriveKey', 'deriveBits']); + const ephemeralPublicKeyReference = await webCrypto.importKey('jwk', ephemeralPublicKeyJWK, 'X25519', false, []); + const sharedSecretBuffer = await webCrypto.deriveBits( + { name: 'X25519', public: ephemeralPublicKeyReference }, + privateKey, + getPayloadSize(algo) * 8 // in bits + ); + return new Uint8Array(sharedSecretBuffer); + } catch (err) { + if (err.name !== 'NotSupportedError') { + throw err; + } + return x25519.scalarMult(k, ephemeralPublicKey); + } + case enums.publicKey.x448: { + const x448 = await util.getNobleCurve(enums.publicKey.x448); + const sharedSecret = x448.getSharedSecret(k, ephemeralPublicKey); + return sharedSecret; + } + default: + throw new Error('Unsupported ECDH algorithm'); + } +} + + +function publicKeyToJWK(algo, publicKey) { + switch (algo) { + case enums.publicKey.x25519: { + const jwk = { + kty: 'OKP', + crv: 'X25519', + x: uint8ArrayToB64(publicKey, true), + ext: true + }; + return jwk; + } + default: + throw new Error('Unsupported ECDH algorithm'); + } +} + +function privateKeyToJWK(algo, publicKey, privateKey) { + switch (algo) { + case enums.publicKey.x25519: { + const jwk = publicKeyToJWK(algo, publicKey); + jwk.d = uint8ArrayToB64(privateKey, true); + return jwk; + } + default: + throw new Error('Unsupported ECDH algorithm'); + } +} diff --git a/src/crypto/public_key/elliptic/oid_curves.js b/src/crypto/public_key/elliptic/oid_curves.js index 4e83de0c..a66decdc 100644 --- a/src/crypto/public_key/elliptic/oid_curves.js +++ b/src/crypto/public_key/elliptic/oid_curves.js @@ -20,7 +20,6 @@ * @module crypto/public_key/elliptic/curve */ import nacl from '@openpgp/tweetnacl'; -import { getRandomBytes } from '../../random'; import enums from '../../../enums'; import util from '../../../util'; import { uint8ArrayToB64, b64ToUint8Array } from '../../../encoding/base64'; @@ -183,12 +182,9 @@ class CurveWithOID { case 'node': return nodeGenKeyPair(this.name); case 'curve25519Legacy': { - const privateKey = getRandomBytes(32); - privateKey[0] = (privateKey[0] & 127) | 64; - privateKey[31] &= 248; - const secretKey = privateKey.slice().reverse(); - const { publicKey: rawPublicKey } = nacl.box.keyPair.fromSecretKey(secretKey); - const publicKey = util.concatUint8Array([new Uint8Array([this.wireFormatLeadingByte]), rawPublicKey]); + const { k, A } = await ecdhXGenerate(enums.publicKey.x25519); + const privateKey = k.slice().reverse(); + const publicKey = util.concatUint8Array([new Uint8Array([this.wireFormatLeadingByte]), A]); return { publicKey, privateKey }; } case 'ed25519Legacy': { From db82968b48ecd1c8037afb96746580d365927c88 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Mon, 15 Jul 2024 15:32:32 +0200 Subject: [PATCH 164/201] Tests: do not test RFC8032 test vectors on Safari As it implements a different RFC for non-deterministic signature generation --- test/general/x25519.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/general/x25519.js b/test/general/x25519.js index 93bc8c26..e0cc8628 100644 --- a/test/general/x25519.js +++ b/test/general/x25519.js @@ -12,7 +12,9 @@ import util from '../../src/util'; import * as input from './testInputs'; -export default () => (openpgp.config.ci ? describe.skip : describe)('X25519 Cryptography (legacy format)', function () { +const isSafariOrHeadlessWebKit = () => typeof window !== 'undefined' && window.navigator.userAgent.match(/WebKit/) && !window.navigator.userAgent.match(/Chrome/); + +export default () => describe('X25519 Cryptography (legacy format)', function () { const data = { light: { id: '1ecdf026c0245830', @@ -216,7 +218,9 @@ export default () => (openpgp.config.ci ? describe.skip : describe)('X25519 Cryp expect(await result.signatures[0].verified).to.be.true; }); - describe('Ed25519 Test Vectors from RFC8032', function () { + // Safari implements the non-deterministic version of EdDSA (https://cfrg.github.io/draft-irtf-cfrg-det-sigs-with-noise/draft-irtf-cfrg-det-sigs-with-noise.html), + // hence these test vectors do not apply. + (isSafariOrHeadlessWebKit() ? describe.skip : describe)('Ed25519 Test Vectors from RFC8032', function () { // https://tools.ietf.org/html/rfc8032#section-7.1 function testVector(vector) { const curve = new elliptic.CurveWithOID(openpgp.enums.curve.ed25519Legacy); From 5c583341d716a7b3f1bc0724f8e0fef9905d3b63 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Tue, 16 Jul 2024 15:24:28 +0200 Subject: [PATCH 165/201] Update README --- README.md | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 0ae026c8..2c60f3d2 100644 --- a/README.md +++ b/README.md @@ -57,19 +57,18 @@ library to convert back and forth between them. | Curve | Encryption | Signature | NodeCrypto | WebCrypto | Constant-Time | |:---------------:|:----------:|:---------:|:----------:|:---------:|:-----------------:| - | curve25519 | ECDH | N/A | No | No | Algorithmically** | - | ed25519 | N/A | EdDSA | No | No | Algorithmically** | - | nistP256 | ECDH | ECDSA | Yes* | Yes* | If native*** | - | nistP384 | ECDH | ECDSA | Yes* | Yes* | If native*** | - | nistP521 | ECDH | ECDSA | Yes* | Yes* | If native*** | - | brainpoolP256r1 | ECDH | ECDSA | Yes* | No | If native*** | - | brainpoolP384r1 | ECDH | ECDSA | Yes* | No | If native*** | - | brainpoolP512r1 | ECDH | ECDSA | Yes* | No | If native*** | - | secp256k1 | ECDH | ECDSA | Yes* | No | If native*** | + | curve25519 | ECDH | N/A | No | Yes* | If native** | + | ed25519 | N/A | EdDSA | No | Yes* | If native** | + | nistP256 | ECDH | ECDSA | Yes* | Yes* | If native** | + | nistP384 | ECDH | ECDSA | Yes* | Yes* | If native** | + | nistP521 | ECDH | ECDSA | Yes* | Yes* | If native** | + | brainpoolP256r1 | ECDH | ECDSA | Yes* | No | If native** | + | brainpoolP384r1 | ECDH | ECDSA | Yes* | No | If native** | + | brainpoolP512r1 | ECDH | ECDSA | Yes* | No | If native** | + | secp256k1 | ECDH | ECDSA | Yes* | No | If native** | - \* when available - \** the curve25519 and ed25519 implementations are algorithmically constant-time, but may not be constant-time after optimizations of the JavaScript compiler - \*** these curves are only constant-time if the underlying native implementation is available and constant-time + \* when available + \** these curves are only constant-time if the underlying native implementation is available and constant-time * If the user's browser supports [native WebCrypto](https://caniuse.com/#feat=cryptography) via the `window.crypto.subtle` API, this will be used. Under Node.js the native [crypto module](https://nodejs.org/api/crypto.html#crypto_crypto) is used. From 5fd7ef370fc19043ffb6859c7b451c73db233d3e Mon Sep 17 00:00:00 2001 From: larabr Date: Wed, 21 Aug 2024 12:59:23 +0200 Subject: [PATCH 166/201] Drop asmcrypto.js for AES fallbacks in favor of noble-ciphers (#1785) Asm.js has now been deprecated for many years, and no performance gain is recorded for AES compared to vanilla JS. The relevant AES fallback code is primarily used if the WebCrypto (resp. NodeCrypto) implementation is not available. --- package-lock.json | 29 ++++++----- package.json | 2 +- src/crypto/aes_kw.js | 98 ++-------------------------------- src/crypto/cmac.js | 5 +- src/crypto/mode/cfb.js | 116 +++++++++++++++++++++++++++++++++++++---- src/crypto/mode/eax.js | 5 +- src/crypto/mode/gcm.js | 10 ++-- src/crypto/mode/ocb.js | 7 +-- 8 files changed, 138 insertions(+), 134 deletions(-) diff --git a/package-lock.json b/package-lock.json index cd99b765..3462369f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,9 +9,9 @@ "version": "6.0.0-beta.2", "license": "LGPL-3.0+", "devDependencies": { + "@noble/ciphers": "^0.6.0", "@noble/curves": "^1.4.0", "@noble/hashes": "^1.4.0", - "@openpgp/asmcrypto.js": "^3.1.0", "@openpgp/jsdoc": "^3.6.11", "@openpgp/seek-bzip": "^1.0.5-git", "@openpgp/tweetnacl": "^1.0.4-1", @@ -801,6 +801,15 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@noble/ciphers": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.6.0.tgz", + "integrity": "sha512-mIbq/R9QXk5/cTfESb1OKtyFnk7oc1Om/8onA1158K9/OZUQFDEVy55jVTato+xmp3XX6F6Qh0zz0Nc1AxAlRQ==", + "dev": true, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@noble/curves": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.0.tgz", @@ -860,12 +869,6 @@ "node": ">= 8" } }, - "node_modules/@openpgp/asmcrypto.js": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@openpgp/asmcrypto.js/-/asmcrypto.js-3.1.0.tgz", - "integrity": "sha512-LlQZE/Vtkx/KFnJxg7BB0iwD7oYKDeC8eRECHxKLhYyL2Ad0+xT137VZwv8SZTJB2euPqpx7xkj04ieV0Q665w==", - "dev": true - }, "node_modules/@openpgp/jsdoc": { "version": "3.6.11", "resolved": "https://registry.npmjs.org/@openpgp/jsdoc/-/jsdoc-3.6.11.tgz", @@ -9041,6 +9044,12 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "@noble/ciphers": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.6.0.tgz", + "integrity": "sha512-mIbq/R9QXk5/cTfESb1OKtyFnk7oc1Om/8onA1158K9/OZUQFDEVy55jVTato+xmp3XX6F6Qh0zz0Nc1AxAlRQ==", + "dev": true + }, "@noble/curves": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.0.tgz", @@ -9082,12 +9091,6 @@ "fastq": "^1.6.0" } }, - "@openpgp/asmcrypto.js": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@openpgp/asmcrypto.js/-/asmcrypto.js-3.1.0.tgz", - "integrity": "sha512-LlQZE/Vtkx/KFnJxg7BB0iwD7oYKDeC8eRECHxKLhYyL2Ad0+xT137VZwv8SZTJB2euPqpx7xkj04ieV0Q665w==", - "dev": true - }, "@openpgp/jsdoc": { "version": "3.6.11", "resolved": "https://registry.npmjs.org/@openpgp/jsdoc/-/jsdoc-3.6.11.tgz", diff --git a/package.json b/package.json index 51f026cb..89ad6293 100644 --- a/package.json +++ b/package.json @@ -62,9 +62,9 @@ "postversion": "git push && git push --tags && npm publish" }, "devDependencies": { + "@noble/ciphers": "^0.6.0", "@noble/curves": "^1.4.0", "@noble/hashes": "^1.4.0", - "@openpgp/asmcrypto.js": "^3.1.0", "@openpgp/jsdoc": "^3.6.11", "@openpgp/seek-bzip": "^1.0.5-git", "@openpgp/tweetnacl": "^1.0.4-1", diff --git a/src/crypto/aes_kw.js b/src/crypto/aes_kw.js index 52288b31..0ef54f78 100644 --- a/src/crypto/aes_kw.js +++ b/src/crypto/aes_kw.js @@ -21,7 +21,7 @@ * @module crypto/aes_kw */ -import { AES_CBC } from '@openpgp/asmcrypto.js/aes/cbc.js'; +import { aeskw as nobleAesKW } from '@noble/ciphers/aes'; import { getCipherParams } from './cipher'; import util from '../util'; @@ -55,7 +55,7 @@ export async function wrap(algo, key, dataToWrap) { util.printDebugError('Browser did not support operation: ' + err.message); } - return asmcryptoWrap(algo, key, dataToWrap); + return nobleAesKW(key).encrypt(dataToWrap); } /** @@ -82,7 +82,7 @@ export async function unwrap(algo, key, wrappedData) { throw err; } util.printDebugError('Browser did not support operation: ' + err.message); - return asmcryptoUnwrap(algo, key, wrappedData); + return nobleAesKW(key).decrypt(wrappedData); } try { @@ -95,95 +95,3 @@ export async function unwrap(algo, key, wrappedData) { throw err; } } - -function asmcryptoWrap(aesAlgo, key, data) { - const aesInstance = new AES_CBC(key, new Uint8Array(16), false); - const IV = new Uint32Array([0xA6A6A6A6, 0xA6A6A6A6]); - const P = unpack(data); - let A = IV; - const R = P; - const n = P.length / 2; - const t = new Uint32Array([0, 0]); - let B = new Uint32Array(4); - for (let j = 0; j <= 5; ++j) { - for (let i = 0; i < n; ++i) { - t[1] = n * j + (1 + i); - // B = A - B[0] = A[0]; - B[1] = A[1]; - // B = A || R[i] - B[2] = R[2 * i]; - B[3] = R[2 * i + 1]; - // B = AES(K, B) - B = unpack(aesInstance.encrypt(pack(B))); - // A = MSB(64, B) ^ t - A = B.subarray(0, 2); - A[0] ^= t[0]; - A[1] ^= t[1]; - // R[i] = LSB(64, B) - R[2 * i] = B[2]; - R[2 * i + 1] = B[3]; - } - } - return pack(A, R); -} - -function asmcryptoUnwrap(aesAlgo, key, data) { - const aesInstance = new AES_CBC(key, new Uint8Array(16), false); - const IV = new Uint32Array([0xA6A6A6A6, 0xA6A6A6A6]); - const C = unpack(data); - let A = C.subarray(0, 2); - const R = C.subarray(2); - const n = C.length / 2 - 1; - const t = new Uint32Array([0, 0]); - let B = new Uint32Array(4); - for (let j = 5; j >= 0; --j) { - for (let i = n - 1; i >= 0; --i) { - t[1] = n * j + (i + 1); - // B = A ^ t - B[0] = A[0] ^ t[0]; - B[1] = A[1] ^ t[1]; - // B = (A ^ t) || R[i] - B[2] = R[2 * i]; - B[3] = R[2 * i + 1]; - // B = AES-1(B) - B = unpack(aesInstance.decrypt(pack(B))); - // A = MSB(64, B) - A = B.subarray(0, 2); - // R[i] = LSB(64, B) - R[2 * i] = B[2]; - R[2 * i + 1] = B[3]; - } - } - if (A[0] === IV[0] && A[1] === IV[1]) { - return pack(R); - } - throw new Error('Key Data Integrity failed'); -} - -function unpack(data) { - const buffer = data.buffer; - const view = new DataView(buffer); - const arr = new Uint32Array(data.length / 4); - for (let i = 0; i < data.length / 4; ++i) { - arr[i] = view.getUint32(4 * i); - } - return arr; -} - -function pack() { - let length = 0; - for (let k = 0; k < arguments.length; ++k) { - length += 4 * arguments[k].length; - } - const buffer = new ArrayBuffer(length); - const view = new DataView(buffer); - let offset = 0; - for (let i = 0; i < arguments.length; ++i) { - for (let j = 0; j < arguments[i].length; ++j) { - view.setUint32(offset + 4 * j, arguments[i][j]); - } - offset += 4 * arguments[i].length; - } - return new Uint8Array(buffer); -} diff --git a/src/crypto/cmac.js b/src/crypto/cmac.js index 19d996a8..6159cdf7 100644 --- a/src/crypto/cmac.js +++ b/src/crypto/cmac.js @@ -4,7 +4,7 @@ * @module crypto/cmac */ -import { AES_CBC } from '@openpgp/asmcrypto.js/aes/cbc.js'; +import { cbc as nobleAesCbc } from '@noble/ciphers/aes'; import util from '../util'; const webCrypto = util.getWebCrypto(); @@ -97,8 +97,7 @@ async function CBC(key) { } } - // asm.js fallback return async function(pt) { - return AES_CBC.encrypt(pt, key, false, zeroBlock); + return nobleAesCbc(key, zeroBlock, { disablePadding: true }).encrypt(pt); }; } diff --git a/src/crypto/mode/cfb.js b/src/crypto/mode/cfb.js index 128b28e9..829a0d29 100644 --- a/src/crypto/mode/cfb.js +++ b/src/crypto/mode/cfb.js @@ -21,7 +21,8 @@ * @module crypto/mode/cfb */ -import { AES_CFB } from '@openpgp/asmcrypto.js/aes/cfb.js'; +import { cfb as nobleAesCfb, unsafe as nobleAesHelpers } from '@noble/ciphers/aes'; + import * as stream from '@openpgp/web-stream-tools'; import util from '../../util'; import enums from '../../enums'; @@ -174,17 +175,17 @@ class WebCryptoEncryptor { const encryptedBlocks = await this._runCBC(toEncrypt); xorMut(encryptedBlocks, plaintext); - this.prevBlock = encryptedBlocks.subarray(-this.blockSize).slice(); + this.prevBlock = encryptedBlocks.slice(-this.blockSize); // take care of leftover data - if (leftover > 0) this.nextBlock.set(value.subarray(-leftover).slice()); + if (leftover > 0) this.nextBlock.set(value.subarray(-leftover)); this.i = leftover; return encryptedBlocks; } this.i += added.length; - let encryptedBlock = new Uint8Array(); + let encryptedBlock; if (this.i === this.nextBlock.length) { // block ready to be encrypted const curBlock = this.nextBlock; encryptedBlock = await this._runCBC(this.prevBlock); @@ -195,6 +196,8 @@ class WebCryptoEncryptor { const remaining = value.subarray(added.length); this.nextBlock.set(remaining, this.i); this.i += remaining.length; + } else { + encryptedBlock = new Uint8Array(); } return encryptedBlock; @@ -237,22 +240,111 @@ class WebCryptoEncryptor { } } +class NobleStreamProcessor { + constructor(forEncryption, algo, key, iv) { + this.forEncryption = forEncryption; + const { blockSize } = getCipherParams(algo); + this.key = nobleAesHelpers.expandKeyLE(key); + + if (iv.byteOffset % 4 !== 0) iv = iv.slice(); // aligned arrays required by noble-ciphers + this.prevBlock = getUint32Array(iv); + this.nextBlock = new Uint8Array(blockSize); + this.i = 0; // pointer inside next block + this.blockSize = blockSize; + } + + _runCFB(src) { + const src32 = getUint32Array(src); + const dst = new Uint8Array(src.length); + const dst32 = getUint32Array(dst); + for (let i = 0; i + 4 <= dst32.length; i += 4) { + const { s0: e0, s1: e1, s2: e2, s3: e3 } = nobleAesHelpers.encrypt(this.key, this.prevBlock[0], this.prevBlock[1], this.prevBlock[2], this.prevBlock[3]); + dst32[i + 0] = src32[i + 0] ^ e0; + dst32[i + 1] = src32[i + 1] ^ e1; + dst32[i + 2] = src32[i + 2] ^ e2; + dst32[i + 3] = src32[i + 3] ^ e3; + this.prevBlock = (this.forEncryption ? dst32 : src32).slice(i, i + 4); + } + return dst; + } + + async processChunk(value) { + const missing = this.nextBlock.length - this.i; + const added = value.subarray(0, missing); + this.nextBlock.set(added, this.i); + + if ((this.i + value.length) >= (2 * this.blockSize)) { + const leftover = (value.length - missing) % this.blockSize; + const toProcess = util.concatUint8Array([ + this.nextBlock, + value.subarray(missing, value.length - leftover) + ]); + + const processedBlocks = this._runCFB(toProcess); + + // take care of leftover data + if (leftover > 0) this.nextBlock.set(value.subarray(-leftover)); + this.i = leftover; + + return processedBlocks; + } + + this.i += added.length; + + let processedBlock; + if (this.i === this.nextBlock.length) { // block ready to be encrypted + processedBlock = this._runCFB(this.nextBlock); + this.i = 0; + + const remaining = value.subarray(added.length); + this.nextBlock.set(remaining, this.i); + this.i += remaining.length; + } else { + processedBlock = new Uint8Array(); + } + + return processedBlock; + } + + async finish() { + let result; + if (this.i === 0) { // nothing more to encrypt + result = new Uint8Array(); + } else { + const processedBlock = this._runCFB(this.nextBlock); + + result = processedBlock.subarray(0, this.i); + } + + this.clearSensitiveData(); + return result; + } + + clearSensitiveData() { + this.nextBlock.fill(0); + this.prevBlock.fill(0); + this.key.fill(0); + } +} + + async function aesEncrypt(algo, key, pt, iv) { if (webCrypto && await WebCryptoEncryptor.isSupported(algo)) { // Chromium does not implement AES with 192-bit keys const cfb = new WebCryptoEncryptor(algo, key, iv); return util.isStream(pt) ? stream.transform(pt, value => cfb.encryptChunk(value), () => cfb.finish()) : cfb.encrypt(pt); - } else { - const cfb = new AES_CFB(key, iv); - return stream.transform(pt, value => cfb.aes.AES_Encrypt_process(value), () => cfb.aes.AES_Encrypt_finish()); + } else if (util.isStream(pt)) { // async callbacks are not accepted by stream.transform unless the input is a stream + const cfb = new NobleStreamProcessor(true, algo, key, iv); + return stream.transform(pt, value => cfb.processChunk(value), () => cfb.finish()); } + return nobleAesCfb(key, iv).encrypt(pt); } -function aesDecrypt(algo, key, ct, iv) { +async function aesDecrypt(algo, key, ct, iv) { if (util.isStream(ct)) { - const cfb = new AES_CFB(key, iv); - return stream.transform(ct, value => cfb.aes.AES_Decrypt_process(value), () => cfb.aes.AES_Decrypt_finish()); + const cfb = new NobleStreamProcessor(false, algo, key, iv); + return stream.transform(ct, value => cfb.processChunk(value), () => cfb.finish()); } - return AES_CFB.decrypt(ct, key, iv); + return nobleAesCfb(key, iv).decrypt(ct); } function xorMut(a, b) { @@ -262,6 +354,8 @@ function xorMut(a, b) { } } +const getUint32Array = arr => new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4)); + function nodeEncrypt(algo, key, pt, iv) { const algoName = enums.read(enums.symmetric, algo); const cipherObj = new nodeCrypto.createCipheriv(nodeAlgos[algoName], key, iv); diff --git a/src/crypto/mode/eax.js b/src/crypto/mode/eax.js index ab64ec6b..1ea2284d 100644 --- a/src/crypto/mode/eax.js +++ b/src/crypto/mode/eax.js @@ -21,7 +21,7 @@ * @module crypto/mode/eax */ -import { AES_CTR } from '@openpgp/asmcrypto.js/aes/ctr.js'; +import { ctr as nobleAesCtr } from '@noble/ciphers/aes'; import CMAC from '../cmac'; import util from '../../util'; import enums from '../../enums'; @@ -72,9 +72,8 @@ async function CTR(key) { } } - // asm.js fallback return async function(pt, iv) { - return AES_CTR.encrypt(pt, key, iv); + return nobleAesCtr(key, iv).encrypt(pt); }; } diff --git a/src/crypto/mode/gcm.js b/src/crypto/mode/gcm.js index b482a5dc..b1d2cfe4 100644 --- a/src/crypto/mode/gcm.js +++ b/src/crypto/mode/gcm.js @@ -21,7 +21,7 @@ * @module crypto/mode/gcm */ -import { AES_GCM } from '@openpgp/asmcrypto.js/aes/gcm.js'; +import { gcm as nobleAesGcm } from '@noble/ciphers/aes'; import util from '../../util'; import enums from '../../enums'; @@ -74,7 +74,7 @@ async function GCM(cipher, key) { return { encrypt: async function(pt, iv, adata = new Uint8Array()) { if (webcryptoEmptyMessagesUnsupported && !pt.length) { - return AES_GCM.encrypt(pt, key, iv, adata); + return nobleAesGcm(key, iv, adata).encrypt(pt); } const ct = await webCrypto.encrypt({ name: ALGO, iv, additionalData: adata, tagLength: tagLength * 8 }, _key, pt); return new Uint8Array(ct); @@ -82,7 +82,7 @@ async function GCM(cipher, key) { decrypt: async function(ct, iv, adata = new Uint8Array()) { if (webcryptoEmptyMessagesUnsupported && ct.length === tagLength) { - return AES_GCM.decrypt(ct, key, iv, adata); + return nobleAesGcm(key, iv, adata).decrypt(ct); } try { const pt = await webCrypto.decrypt({ name: ALGO, iv, additionalData: adata, tagLength: tagLength * 8 }, _key, ct); @@ -106,11 +106,11 @@ async function GCM(cipher, key) { return { encrypt: async function(pt, iv, adata) { - return AES_GCM.encrypt(pt, key, iv, adata); + return nobleAesGcm(key, iv, adata).encrypt(pt); }, decrypt: async function(ct, iv, adata) { - return AES_GCM.decrypt(ct, key, iv, adata); + return nobleAesGcm(key, iv, adata).decrypt(ct); } }; } diff --git a/src/crypto/mode/ocb.js b/src/crypto/mode/ocb.js index 868c67b9..e8b8cabf 100644 --- a/src/crypto/mode/ocb.js +++ b/src/crypto/mode/ocb.js @@ -20,7 +20,7 @@ * @module crypto/mode/ocb */ -import { AES_CBC } from '@openpgp/asmcrypto.js/aes/cbc.js'; +import { cbc as nobleAesCbc } from '@noble/ciphers/aes'; import { getCipherParams } from '../cipher'; import util from '../../util'; @@ -73,8 +73,9 @@ async function OCB(cipher, key) { // `encipher` and `decipher` cannot be async, since `crypt` shares state across calls, // hence its execution cannot be broken up. // As a result, WebCrypto cannot currently be used for `encipher`. - const encipher = block => AES_CBC.encrypt(block, key, false); - const decipher = block => AES_CBC.decrypt(block, key, false); + const aes = nobleAesCbc(key, zeroBlock, { disablePadding: true }); + const encipher = block => aes.encrypt(block); + const decipher = block => aes.decrypt(block); let mask; constructKeyVariables(cipher, key); From 2f185481a76df50739ba1f2f893496a2a5507538 Mon Sep 17 00:00:00 2001 From: larabr Date: Tue, 3 Sep 2024 14:40:06 +0200 Subject: [PATCH 167/201] `PrivateKey.getDecryptionKeys`: throw if no decryption key is found (#1789) To avoid returning dummy key packets, and improving error reporting. This new behavior is also better aligned with that of `Key.getSigningKey()`. This is a breaking change for apps that call `getDecryptionKeys()` directly. The related error messages returned by `openpgp.decrypt` have also changed, becoming more specific. This change is also made in preparation of supporting private keys with public key packets. --- src/key/private_key.js | 25 +++++++++++++++++++++---- src/message.js | 14 +++++++++----- test/general/key.js | 7 ++++++- test/general/openpgp.js | 6 +++--- 4 files changed, 39 insertions(+), 13 deletions(-) diff --git a/src/key/private_key.js b/src/key/private_key.js index 904c09a0..37cd4588 100644 --- a/src/key/private_key.js +++ b/src/key/private_key.js @@ -77,28 +77,45 @@ class PrivateKey extends PublicKey { * @param {String} userID, optional * @param {Object} [config] - Full configuration, defaults to openpgp.config * @returns {Promise>} Array of decryption keys. + * @throws {Error} if no decryption key is found * @async */ async getDecryptionKeys(keyID, date = new Date(), userID = {}, config = defaultConfig) { const primaryKey = this.keyPacket; const keys = []; + let exception = null; for (let i = 0; i < this.subkeys.length; i++) { if (!keyID || this.subkeys[i].getKeyID().equals(keyID, true)) { + if (this.subkeys[i].keyPacket.isDummy()) { + exception = exception || new Error('Gnu-dummy key packets cannot be used for decryption'); + continue; + } + try { const dataToVerify = { key: primaryKey, bind: this.subkeys[i].keyPacket }; const bindingSignature = await helper.getLatestValidSignature(this.subkeys[i].bindingSignatures, primaryKey, enums.signature.subkeyBinding, dataToVerify, date, config); if (helper.validateDecryptionKeyPacket(this.subkeys[i].keyPacket, bindingSignature, config)) { keys.push(this.subkeys[i]); } - } catch (e) {} + } catch (e) { + exception = e; + } } } // evaluate primary key const selfCertification = await this.getPrimarySelfSignature(date, userID, config); - if ((!keyID || primaryKey.getKeyID().equals(keyID, true)) && - helper.validateDecryptionKeyPacket(primaryKey, selfCertification, config)) { - keys.push(this); + if ((!keyID || primaryKey.getKeyID().equals(keyID, true)) && helper.validateDecryptionKeyPacket(primaryKey, selfCertification, config)) { + if (primaryKey.isDummy()) { + exception = exception || new Error('Gnu-dummy key packets cannot be used for decryption'); + } else { + keys.push(this); + } + } + + if (keys.length === 0) { + // eslint-disable-next-line @typescript-eslint/no-throw-literal + throw exception || new Error('No decryption key packets found'); } return keys; diff --git a/src/message.js b/src/message.js index 113d5623..fb12e8e4 100644 --- a/src/message.js +++ b/src/message.js @@ -199,6 +199,15 @@ export class Message { } await Promise.all(pkeskPackets.map(async function(pkeskPacket) { await Promise.all(decryptionKeys.map(async function(decryptionKey) { + let decryptionKeyPackets; + try { + // do not check key expiration to allow decryption of old messages + decryptionKeyPackets = (await decryptionKey.getDecryptionKeys(pkeskPacket.publicKeyID, null, undefined, config)).map(key => key.keyPacket); + } catch (err) { + exception = err; + return; + } + let algos = [ enums.symmetric.aes256, // Old OpenPGP.js default fallback enums.symmetric.aes128, // RFC4880bis fallback @@ -212,12 +221,7 @@ export class Message { } } catch (e) {} - // do not check key expiration to allow decryption of old messages - const decryptionKeyPackets = (await decryptionKey.getDecryptionKeys(pkeskPacket.publicKeyID, null, undefined, config)).map(key => key.keyPacket); await Promise.all(decryptionKeyPackets.map(async function(decryptionKeyPacket) { - if (!decryptionKeyPacket || decryptionKeyPacket.isDummy()) { - return; - } if (!decryptionKeyPacket.isDecrypted()) { throw new Error('Decryption key is not decrypted.'); } diff --git a/test/general/key.js b/test/general/key.js index 06ed5ab4..995c32b5 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -3541,7 +3541,7 @@ PzIEeL7UH3trraFmi+Gq8u4kAA== await expect(openpgp.decrypt({ message: await openpgp.readMessage({ armoredMessage: encryptedRsaSignOnly }), decryptionKeys: key - })).to.be.rejectedWith(/Session key decryption failed/); + })).to.be.rejectedWith(/No decryption key packets found/); await expect(openpgp.decrypt({ message: await openpgp.readMessage({ armoredMessage: encryptedRsaSignOnly }), @@ -3550,6 +3550,11 @@ PzIEeL7UH3trraFmi+Gq8u4kAA== })).to.be.fulfilled; }); + it('PrivateKey.getDecryptionKeys() - should throw for sign-only key', async function() { + const key = await openpgp.readKey({ armoredKey: rsaSignOnly }); + await expect(key.getDecryptionKeys()).to.be.rejectedWith(/No decryption key packets found/); + }); + it('Key.getExpirationTime()', async function() { const [, pubKey] = await openpgp.readKeys({ armoredKeys: twoKeys }); expect(pubKey).to.exist; diff --git a/test/general/openpgp.js b/test/general/openpgp.js index e6f5bbca..fe9ae8c2 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -1768,7 +1768,7 @@ aOU= message: await openpgp.readMessage({ armoredMessage: encrypted }), decryptionKeys: privateKeyRSA, config - })).to.be.rejectedWith(/Session key decryption failed/); + })).to.be.rejectedWith(/No decryption key packets found/); // decryption using ECC key should succeed (PKCS1 is not used, so constant time countermeasures are not applied) const { data } = await openpgp.decrypt({ message: await openpgp.readMessage({ armoredMessage: encrypted }), @@ -2642,7 +2642,7 @@ XfA3pqV4mTzF }).then(() => { throw new Error('Should not decrypt with invalid key'); }).catch(error => { - expect(error.message).to.match(/Error decrypting session keys: Session key decryption failed./); + expect(error.message).to.match(/Error decrypting session keys: Could not find valid subkey binding signature in key/); }); }); }); @@ -4174,7 +4174,7 @@ XfA3pqV4mTzF decryptionKeys: decryptedKeyDE }; // binding signature is invalid - await expect(openpgp.decrypt(decOpt)).to.be.rejectedWith(/Session key decryption failed/); + await expect(openpgp.decrypt(decOpt)).to.be.rejectedWith(/Could not find valid subkey binding signature in key/); }); it('RSA decryption with PKCS1 padding of wrong length should fail', async function() { From f36be640cc3134ffbfd90d6e0b8cdd3ee5899764 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Wed, 4 Sep 2024 17:46:40 +0200 Subject: [PATCH 168/201] Fallback to js implementation on WebCrypto EdDSA key generation failure Workaround random failures in WebKit (Linux). --- src/crypto/public_key/elliptic/eddsa.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/crypto/public_key/elliptic/eddsa.js b/src/crypto/public_key/elliptic/eddsa.js index 776dfedd..d22cd8bd 100644 --- a/src/crypto/public_key/elliptic/eddsa.js +++ b/src/crypto/public_key/elliptic/eddsa.js @@ -48,7 +48,7 @@ export async function generate(algo) { seed: b64ToUint8Array(privateKey.d, true) }; } catch (err) { - if (err.name !== 'NotSupportedError') { + if (err.name !== 'NotSupportedError' && err.name !== 'OperationError') { // Temporary (hopefully) fix for WebKit on Linux throw err; } const seed = getRandomBytes(getPayloadSize(algo)); From ab8445116c71575fd8b86fd81d94ca966eb6af6e Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Wed, 4 Sep 2024 16:49:56 +0200 Subject: [PATCH 169/201] CI: update SOP test suite docker image to v1.1.10 Add rsop to tested libraries. --- .github/test-suite/config.json.template | 3 +++ .github/test-suite/prepare_config.sh | 3 ++- .github/workflows/sop-test-suite.yml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/test-suite/config.json.template b/.github/test-suite/config.json.template index 168cccf1..8e9a9d3f 100644 --- a/.github/test-suite/config.json.template +++ b/.github/test-suite/config.json.template @@ -27,6 +27,9 @@ }, { "path": "__RNP_SOP__" + }, + { + "path": "__RSOP__" } ], "rlimits": { diff --git a/.github/test-suite/prepare_config.sh b/.github/test-suite/prepare_config.sh index f7ff0b51..7cd12984 100755 --- a/.github/test-suite/prepare_config.sh +++ b/.github/test-suite/prepare_config.sh @@ -7,7 +7,8 @@ cat $CONFIG_TEMPLATE \ | sed "s@__OPENPGPJS_MAIN__@${OPENPGPJS_MAIN}@g" \ | sed "s@__SQOP__@${SQOP}@g" \ | sed "s@__GPGME_SOP__@${GPGME_SOP}@g" \ - | sed "s@__GOSOP_V2__@${GOSOP_DIR_V2}/gosop@g" \ + | sed "s@__GOSOP_V2__@${GOSOP_V2}@g" \ | sed "s@__SOP_OPENPGPJS__@${SOP_OPENPGPJS_V2}@g" \ | sed "s@__RNP_SOP__@${RNP_SOP}@g" \ + | sed "s@__RSOP__@${RSOP}@g" \ > $CONFIG_OUTPUT \ No newline at end of file diff --git a/.github/workflows/sop-test-suite.yml b/.github/workflows/sop-test-suite.yml index 193a91ac..2e29721a 100644 --- a/.github/workflows/sop-test-suite.yml +++ b/.github/workflows/sop-test-suite.yml @@ -10,7 +10,7 @@ jobs: name: Run interoperability test suite runs-on: ubuntu-latest container: - image: ghcr.io/protonmail/openpgp-interop-test-docker:v1.1.7 + image: ghcr.io/protonmail/openpgp-interop-test-docker:v1.1.10 credentials: username: ${{ github.actor }} password: ${{ secrets.github_token }} From e7b7f6c6b1818bda1a9da801e39385df5faf638c Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Wed, 4 Sep 2024 12:22:31 +0200 Subject: [PATCH 170/201] Run npm update --- package-lock.json | 7653 +++++---------------------------------------- package.json | 32 +- 2 files changed, 803 insertions(+), 6882 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3462369f..2c8386b8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,7 +1,7 @@ { "name": "openpgp", "version": "6.0.0-beta.2", - "lockfileVersion": 2, + "lockfileVersion": 3, "requires": true, "packages": { "": { @@ -10,21 +10,21 @@ "license": "LGPL-3.0+", "devDependencies": { "@noble/ciphers": "^0.6.0", - "@noble/curves": "^1.4.0", - "@noble/hashes": "^1.4.0", + "@noble/curves": "^1.6.0", + "@noble/hashes": "^1.5.0", "@openpgp/jsdoc": "^3.6.11", "@openpgp/seek-bzip": "^1.0.5-git", "@openpgp/tweetnacl": "^1.0.4-1", "@openpgp/web-stream-tools": "~0.1.3", "@rollup/plugin-alias": "^5.1.0", - "@rollup/plugin-commonjs": "^25.0.7", + "@rollup/plugin-commonjs": "^25.0.8", "@rollup/plugin-node-resolve": "^15.2.3", - "@rollup/plugin-replace": "^5.0.5", + "@rollup/plugin-replace": "^5.0.7", "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-typescript": "^11.1.6", "@rollup/plugin-wasm": "^6.2.2", - "@types/chai": "^4.3.16", - "@typescript-eslint/parser": "^7.9.0", + "@types/chai": "^4.3.19", + "@typescript-eslint/parser": "^7.18.0", "argon2id": "^1.0.1", "benchmark": "^2.1.4", "bn.js": "^5.2.1", @@ -36,27 +36,27 @@ "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-airbnb-typescript": "^18.0.0", - "eslint-import-resolver-typescript": "^3.6.1", + "eslint-import-resolver-typescript": "^3.6.3", "eslint-plugin-chai-friendly": "^0.7.4", - "eslint-plugin-import": "^2.29.1", + "eslint-plugin-import": "^2.30.0", "eslint-plugin-unicorn": "^48.0.1", "fflate": "^0.7.4", "http-server": "^14.1.1", - "karma": "^6.4.3", + "karma": "^6.4.4", "karma-browserstack-launcher": "^1.6.0", "karma-chrome-launcher": "^3.2.0", "karma-firefox-launcher": "^2.1.3", "karma-mocha": "^2.0.1", "karma-mocha-reporter": "^2.2.5", - "karma-webkit-launcher": "^2.4.0", - "mocha": "^10.4.0", - "playwright": "^1.44.0", - "rollup": "^4.17.2", + "karma-webkit-launcher": "^2.6.0", + "mocha": "^10.7.3", + "playwright": "^1.46.1", + "rollup": "^4.21.2", "sinon": "^17.0.1", "ts-node": "^10.9.2", - "tslib": "^2.6.2", - "tsx": "^4.10.4", - "typescript": "^5.5.2", + "tslib": "^2.7.0", + "tsx": "^4.19.0", + "typescript": "^5.5.4", "web-streams-polyfill": "^4.0.0" }, "engines": { @@ -64,34 +64,43 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", - "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", "dev": true, "dependencies": { - "@babel/highlight": "^7.24.2", + "@babel/highlight": "^7.24.7", "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/helper-string-parser": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.5.tgz", - "integrity": "sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.5.tgz", - "integrity": "sha512-8lLmua6AVh/8SLJRRVD6V8p73Hir9w5mJrhE+IPpILG31KKlI9iz5zmBYKcWPS59qSfgP9RaSBQSHHE81WKuEw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.24.5", + "@babel/helper-validator-identifier": "^7.24.7", "chalk": "^2.4.2", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" @@ -172,10 +181,13 @@ } }, "node_modules/@babel/parser": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.5.tgz", - "integrity": "sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", + "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", "dev": true, + "dependencies": { + "@babel/types": "^7.25.6" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -183,14 +195,15 @@ "node": ">=6.0.0" } }, - "node_modules/@babel/runtime": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz", - "integrity": "sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==", + "node_modules/@babel/types": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", + "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", "dev": true, - "peer": true, "dependencies": { - "regenerator-runtime": "^0.14.0" + "@babel/helper-string-parser": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" }, "engines": { "node": ">=6.9.0" @@ -234,9 +247,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", - "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz", + "integrity": "sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==", "cpu": [ "ppc64" ], @@ -246,13 +259,13 @@ "aix" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", - "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.1.tgz", + "integrity": "sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==", "cpu": [ "arm" ], @@ -262,13 +275,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", - "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz", + "integrity": "sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==", "cpu": [ "arm64" ], @@ -278,13 +291,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", - "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.1.tgz", + "integrity": "sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==", "cpu": [ "x64" ], @@ -294,13 +307,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", - "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz", + "integrity": "sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==", "cpu": [ "arm64" ], @@ -310,13 +323,13 @@ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", - "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz", + "integrity": "sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==", "cpu": [ "x64" ], @@ -326,13 +339,13 @@ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", - "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz", + "integrity": "sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==", "cpu": [ "arm64" ], @@ -342,13 +355,13 @@ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", - "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz", + "integrity": "sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==", "cpu": [ "x64" ], @@ -358,13 +371,13 @@ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", - "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz", + "integrity": "sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==", "cpu": [ "arm" ], @@ -374,13 +387,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", - "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz", + "integrity": "sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==", "cpu": [ "arm64" ], @@ -390,13 +403,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", - "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz", + "integrity": "sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==", "cpu": [ "ia32" ], @@ -406,13 +419,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", - "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz", + "integrity": "sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==", "cpu": [ "loong64" ], @@ -422,13 +435,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", - "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz", + "integrity": "sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==", "cpu": [ "mips64el" ], @@ -438,13 +451,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", - "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz", + "integrity": "sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==", "cpu": [ "ppc64" ], @@ -454,13 +467,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", - "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz", + "integrity": "sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==", "cpu": [ "riscv64" ], @@ -470,13 +483,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", - "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz", + "integrity": "sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==", "cpu": [ "s390x" ], @@ -486,13 +499,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", - "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz", + "integrity": "sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==", "cpu": [ "x64" ], @@ -502,13 +515,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", - "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz", + "integrity": "sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==", "cpu": [ "x64" ], @@ -518,13 +531,29 @@ "netbsd" ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz", + "integrity": "sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", - "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz", + "integrity": "sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==", "cpu": [ "x64" ], @@ -534,13 +563,13 @@ "openbsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", - "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz", + "integrity": "sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==", "cpu": [ "x64" ], @@ -550,13 +579,13 @@ "sunos" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", - "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz", + "integrity": "sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==", "cpu": [ "arm64" ], @@ -566,13 +595,13 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", - "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz", + "integrity": "sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==", "cpu": [ "ia32" ], @@ -582,13 +611,13 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", - "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz", + "integrity": "sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==", "cpu": [ "x64" ], @@ -598,7 +627,7 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@eslint-community/eslint-utils": { @@ -617,9 +646,9 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", + "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" @@ -683,6 +712,7 @@ "version": "0.11.14", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "deprecated": "Use @eslint/config-array instead", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^2.0.2", @@ -732,6 +762,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", "dev": true }, "node_modules/@istanbuljs/schema": { @@ -786,9 +817,9 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", "dev": true }, "node_modules/@jridgewell/trace-mapping": { @@ -811,24 +842,27 @@ } }, "node_modules/@noble/curves": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.0.tgz", - "integrity": "sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.6.0.tgz", + "integrity": "sha512-TlaHRXDehJuRNR9TfZDNQ45mMEd5dwUwmicsafcIX4SsNiqnCHKjE/1alYPd/lDRVhxdhUAlv8uEhMCI5zjIJQ==", "dev": true, "dependencies": { - "@noble/hashes": "1.4.0" + "@noble/hashes": "1.5.0" + }, + "engines": { + "node": "^14.21.3 || >=16" }, "funding": { "url": "https://paulmillr.com/funding/" } }, "node_modules/@noble/hashes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", - "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.5.0.tgz", + "integrity": "sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==", "dev": true, "engines": { - "node": ">= 16" + "node": "^14.21.3 || >=16" }, "funding": { "url": "https://paulmillr.com/funding/" @@ -869,6 +903,15 @@ "node": ">= 8" } }, + "node_modules/@nolyfill/is-core-module": { + "version": "1.0.39", + "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", + "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", + "dev": true, + "engines": { + "node": ">=12.4.0" + } + }, "node_modules/@openpgp/jsdoc": { "version": "3.6.11", "resolved": "https://registry.npmjs.org/@openpgp/jsdoc/-/jsdoc-3.6.11.tgz", @@ -955,9 +998,9 @@ } }, "node_modules/@rollup/plugin-commonjs": { - "version": "25.0.7", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.7.tgz", - "integrity": "sha512-nEvcR+LRjEjsaSsc4x3XZfCCvZIaSMenZu/OiwOKGN2UhQpAYI7ru7czFvyWbErlpoGjnSX3D5Ch5FcMA3kRWQ==", + "version": "25.0.8", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.8.tgz", + "integrity": "sha512-ZEZWTK5n6Qde0to4vS9Mr5x/0UZoqCxPVR9KRUjU4kA2sO7GEUn1fop0DAwpO6z0Nw/kJON9bDmSxdWxO/TT1A==", "dev": true, "dependencies": { "@rollup/pluginutils": "^5.0.1", @@ -1005,9 +1048,9 @@ } }, "node_modules/@rollup/plugin-replace": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-5.0.5.tgz", - "integrity": "sha512-rYO4fOi8lMaTg/z5Jb+hKnrHHVn8j2lwkqwyS4kTRhKyWOLf2wST2sWXr4WzWiTcoHTp2sTjqUbqIj2E39slKQ==", + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-5.0.7.tgz", + "integrity": "sha512-PqxSfuorkHz/SPpyngLyg5GCEkOcee9M1bkxiVDr41Pd61mqP1PLOoDPbpl44SB2mQGKwV/In74gqQmGITOhEQ==", "dev": true, "dependencies": { "@rollup/pluginutils": "^5.0.1", @@ -1116,9 +1159,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.17.2.tgz", - "integrity": "sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.2.tgz", + "integrity": "sha512-fSuPrt0ZO8uXeS+xP3b+yYTCBUd05MoSp2N/MFOgjhhUhMmchXlpTQrTpI8T+YAwAQuK7MafsCOxW7VrPMrJcg==", "cpu": [ "arm" ], @@ -1129,9 +1172,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.17.2.tgz", - "integrity": "sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.2.tgz", + "integrity": "sha512-xGU5ZQmPlsjQS6tzTTGwMsnKUtu0WVbl0hYpTPauvbRAnmIvpInhJtgjj3mcuJpEiuUw4v1s4BimkdfDWlh7gA==", "cpu": [ "arm64" ], @@ -1142,9 +1185,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.17.2.tgz", - "integrity": "sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.2.tgz", + "integrity": "sha512-99AhQ3/ZMxU7jw34Sq8brzXqWH/bMnf7ZVhvLk9QU2cOepbQSVTns6qoErJmSiAvU3InRqC2RRZ5ovh1KN0d0Q==", "cpu": [ "arm64" ], @@ -1155,9 +1198,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.17.2.tgz", - "integrity": "sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.2.tgz", + "integrity": "sha512-ZbRaUvw2iN/y37x6dY50D8m2BnDbBjlnMPotDi/qITMJ4sIxNY33HArjikDyakhSv0+ybdUxhWxE6kTI4oX26w==", "cpu": [ "x64" ], @@ -1168,9 +1211,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.17.2.tgz", - "integrity": "sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.2.tgz", + "integrity": "sha512-ztRJJMiE8nnU1YFcdbd9BcH6bGWG1z+jP+IPW2oDUAPxPjo9dverIOyXz76m6IPA6udEL12reYeLojzW2cYL7w==", "cpu": [ "arm" ], @@ -1181,9 +1224,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.17.2.tgz", - "integrity": "sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.2.tgz", + "integrity": "sha512-flOcGHDZajGKYpLV0JNc0VFH361M7rnV1ee+NTeC/BQQ1/0pllYcFmxpagltANYt8FYf9+kL6RSk80Ziwyhr7w==", "cpu": [ "arm" ], @@ -1194,9 +1237,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.17.2.tgz", - "integrity": "sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.2.tgz", + "integrity": "sha512-69CF19Kp3TdMopyteO/LJbWufOzqqXzkrv4L2sP8kfMaAQ6iwky7NoXTp7bD6/irKgknDKM0P9E/1l5XxVQAhw==", "cpu": [ "arm64" ], @@ -1207,9 +1250,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.17.2.tgz", - "integrity": "sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.2.tgz", + "integrity": "sha512-48pD/fJkTiHAZTnZwR0VzHrao70/4MlzJrq0ZsILjLW/Ab/1XlVUStYyGt7tdyIiVSlGZbnliqmult/QGA2O2w==", "cpu": [ "arm64" ], @@ -1220,9 +1263,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.17.2.tgz", - "integrity": "sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.2.tgz", + "integrity": "sha512-cZdyuInj0ofc7mAQpKcPR2a2iu4YM4FQfuUzCVA2u4HI95lCwzjoPtdWjdpDKyHxI0UO82bLDoOaLfpZ/wviyQ==", "cpu": [ "ppc64" ], @@ -1233,9 +1276,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.17.2.tgz", - "integrity": "sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.2.tgz", + "integrity": "sha512-RL56JMT6NwQ0lXIQmMIWr1SW28z4E4pOhRRNqwWZeXpRlykRIlEpSWdsgNWJbYBEWD84eocjSGDu/XxbYeCmwg==", "cpu": [ "riscv64" ], @@ -1246,9 +1289,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.17.2.tgz", - "integrity": "sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.2.tgz", + "integrity": "sha512-PMxkrWS9z38bCr3rWvDFVGD6sFeZJw4iQlhrup7ReGmfn7Oukrr/zweLhYX6v2/8J6Cep9IEA/SmjXjCmSbrMQ==", "cpu": [ "s390x" ], @@ -1259,9 +1302,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz", - "integrity": "sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.2.tgz", + "integrity": "sha512-B90tYAUoLhU22olrafY3JQCFLnT3NglazdwkHyxNDYF/zAxJt5fJUB/yBoWFoIQ7SQj+KLe3iL4BhOMa9fzgpw==", "cpu": [ "x64" ], @@ -1272,9 +1315,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.17.2.tgz", - "integrity": "sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.2.tgz", + "integrity": "sha512-7twFizNXudESmC9oneLGIUmoHiiLppz/Xs5uJQ4ShvE6234K0VB1/aJYU3f/4g7PhssLGKBVCC37uRkkOi8wjg==", "cpu": [ "x64" ], @@ -1285,9 +1328,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.17.2.tgz", - "integrity": "sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.2.tgz", + "integrity": "sha512-9rRero0E7qTeYf6+rFh3AErTNU1VCQg2mn7CQcI44vNUWM9Ze7MSRS/9RFuSsox+vstRt97+x3sOhEey024FRQ==", "cpu": [ "arm64" ], @@ -1298,9 +1341,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.17.2.tgz", - "integrity": "sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.2.tgz", + "integrity": "sha512-5rA4vjlqgrpbFVVHX3qkrCo/fZTj1q0Xxpg+Z7yIo3J2AilW7t2+n6Q8Jrx+4MrYpAnjttTYF8rr7bP46BPzRw==", "cpu": [ "ia32" ], @@ -1311,9 +1354,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.17.2.tgz", - "integrity": "sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.2.tgz", + "integrity": "sha512-6UUxd0+SKomjdzuAcp+HAmxw1FlGBnl1v2yEPSabtx4lBfdXHDVsW7+lQkgz9cNFJGY3AWR7+V8P5BqkD9L9nA==", "cpu": [ "x64" ], @@ -1323,6 +1366,12 @@ "win32" ] }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true + }, "node_modules/@sinonjs/commons": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", @@ -1332,13 +1381,22 @@ "type-detect": "4.0.8" } }, + "node_modules/@sinonjs/commons/node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/@sinonjs/fake-timers": { - "version": "11.2.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", - "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", + "version": "11.3.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.3.1.tgz", + "integrity": "sha512-EVJO7nW5M/F5Tur0Rf2z/QoMo+1Ia963RiMtapiQrEWvY0iBUvADo8Beegwjpnle5BHkyHuoxSTW3jF43H1XRA==", "dev": true, "dependencies": { - "@sinonjs/commons": "^3.0.0" + "@sinonjs/commons": "^3.0.1" } }, "node_modules/@sinonjs/samsam": { @@ -1361,10 +1419,19 @@ "type-detect": "4.0.8" } }, + "node_modules/@sinonjs/samsam/node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/@sinonjs/text-encoding": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", - "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.3.tgz", + "integrity": "sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA==", "dev": true }, "node_modules/@socket.io/component-emitter": { @@ -1398,9 +1465,9 @@ "dev": true }, "node_modules/@types/chai": { - "version": "4.3.16", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.16.tgz", - "integrity": "sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ==", + "version": "4.3.19", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.19.tgz", + "integrity": "sha512-2hHHvQBVE2FiSK4eN0Br6snX9MtolHaTo/batnLjlGRhoQzlCL61iVpxoqO7SfFyOw+P/pwv+0zNHzKoGWz9Cw==", "dev": true }, "node_modules/@types/cookie": { @@ -1459,12 +1526,12 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.12.12", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz", - "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==", + "version": "22.5.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.3.tgz", + "integrity": "sha512-njripolh85IA9SQGTAqbmnNZTdxv7X/4OYGPz8tgy5JDr8MP+uDBa921GpYEoDDnwm0Hmn5ZPeJgiiSTPoOzkQ==", "dev": true, "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~6.19.2" } }, "node_modules/@types/normalize-package-data": { @@ -1480,17 +1547,17 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.9.0.tgz", - "integrity": "sha512-6e+X0X3sFe/G/54aC3jt0txuMTURqLyekmEHViqyA2VnxhLMpvA6nqmcjIy+Cr9tLDHPssA74BP5Mx9HQIxBEA==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz", + "integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==", "dev": true, "peer": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.9.0", - "@typescript-eslint/type-utils": "7.9.0", - "@typescript-eslint/utils": "7.9.0", - "@typescript-eslint/visitor-keys": "7.9.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/type-utils": "7.18.0", + "@typescript-eslint/utils": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -1514,15 +1581,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.9.0.tgz", - "integrity": "sha512-qHMJfkL5qvgQB2aLvhUSXxbK7OLnDkwPzFalg458pxQgfxKDfT1ZDbHQM/I6mDIf/svlMkj21kzKuQ2ixJlatQ==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz", + "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.9.0", - "@typescript-eslint/types": "7.9.0", - "@typescript-eslint/typescript-estree": "7.9.0", - "@typescript-eslint/visitor-keys": "7.9.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", "debug": "^4.3.4" }, "engines": { @@ -1542,13 +1609,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.9.0.tgz", - "integrity": "sha512-ZwPK4DeCDxr3GJltRz5iZejPFAAr4Wk3+2WIBaj1L5PYK5RgxExu/Y68FFVclN0y6GGwH8q+KgKRCvaTmFBbgQ==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", + "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.9.0", - "@typescript-eslint/visitor-keys": "7.9.0" + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -1559,14 +1626,14 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.9.0.tgz", - "integrity": "sha512-6Qy8dfut0PFrFRAZsGzuLoM4hre4gjzWJB6sUvdunCYZsYemTkzZNwF1rnGea326PHPT3zn5Lmg32M/xfJfByA==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz", + "integrity": "sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==", "dev": true, "peer": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.9.0", - "@typescript-eslint/utils": "7.9.0", + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/utils": "7.18.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -1587,9 +1654,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.9.0.tgz", - "integrity": "sha512-oZQD9HEWQanl9UfsbGVcZ2cGaR0YT5476xfWE0oE5kQa2sNK2frxOlkeacLOTh9po4AlUT5rtkGyYM5kew0z5w==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz", + "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -1600,13 +1667,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.9.0.tgz", - "integrity": "sha512-zBCMCkrb2YjpKV3LA0ZJubtKCDxLttxfdGmwZvTqqWevUPN0FZvSI26FalGFFUZU/9YQK/A4xcQF9o/VVaCKAg==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", + "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.9.0", - "@typescript-eslint/visitor-keys": "7.9.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -1628,16 +1695,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.9.0.tgz", - "integrity": "sha512-5KVRQCzZajmT4Ep+NEgjXCvjuypVvYHUW7RHlXzNPuak2oWpVoD1jf5xCP0dPAuNIchjC7uQyvbdaSTFaLqSdA==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz", + "integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==", "dev": true, "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.9.0", - "@typescript-eslint/types": "7.9.0", - "@typescript-eslint/typescript-estree": "7.9.0" + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -1651,12 +1718,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.9.0.tgz", - "integrity": "sha512-iESPx2TNLDNGQLyjKhUvIKprlP49XNEK+MvIf9nIO7ZZaZdbnfWKHnXAgufpxqfA0YryH8XToi4+CjBgVnFTSQ==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", + "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.9.0", + "@typescript-eslint/types": "7.18.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -1687,9 +1754,9 @@ } }, "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -1708,10 +1775,13 @@ } }, "node_modules/acorn-walk": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", - "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", + "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", "dev": true, + "dependencies": { + "acorn": "^8.11.0" + }, "engines": { "node": ">=0.4.0" } @@ -1745,9 +1815,9 @@ } }, "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "dev": true, "engines": { "node": ">=6" @@ -1809,13 +1879,13 @@ "dev": true }, "node_modules/aria-query": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", - "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", + "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", "dev": true, "peer": true, "dependencies": { - "dequal": "^2.0.3" + "deep-equal": "^2.0.5" } }, "node_modules/array-buffer-byte-length": { @@ -1940,31 +2010,21 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array.prototype.toreversed": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz", - "integrity": "sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - } - }, "node_modules/array.prototype.tosorted": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.3.tgz", - "integrity": "sha512-/DdH4TiTmOKzyQbp/eadcCVexiCb36xJg7HshYOYJnNZFDj33GEv0P7GxsynpShhq4OLYJzbGcBDkLsDt7MnNg==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", "dev": true, "peer": true, "dependencies": { - "call-bind": "^1.0.5", + "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.1.0", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/arraybuffer.prototype.slice": { @@ -2030,9 +2090,9 @@ } }, "node_modules/axe-core": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.0.tgz", - "integrity": "sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.0.tgz", + "integrity": "sha512-Mr2ZakwQ7XUAjp7pAwQWRhhK8mQQ6JAaNWSjmjxil0R8BPioMtQsTLOolGYkji1rcL++3dCqZA3zWqpT+9Ew6g==", "dev": true, "peer": true, "engines": { @@ -2040,13 +2100,13 @@ } }, "node_modules/axobject-query": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", - "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", "dev": true, "peer": true, - "dependencies": { - "dequal": "^2.0.3" + "engines": { + "node": ">= 0.4" } }, "node_modules/balanced-match": { @@ -2678,9 +2738,9 @@ } }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -2707,9 +2767,9 @@ } }, "node_modules/deep-eql": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", - "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", "dev": true, "dependencies": { "type-detect": "^4.0.0" @@ -2718,6 +2778,39 @@ "node": ">=6" } }, + "node_modules/deep-equal": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", + "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", + "dev": true, + "peer": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.5", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.2", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -2776,16 +2869,6 @@ "node": ">= 0.8" } }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, "node_modules/destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", @@ -2803,9 +2886,9 @@ "dev": true }, "node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", "dev": true, "engines": { "node": ">=0.3.1" @@ -2903,18 +2986,18 @@ } }, "node_modules/engine.io-parser": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.2.tgz", - "integrity": "sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", "dev": true, "engines": { "node": ">=10.0.0" } }, "node_modules/enhanced-resolve": { - "version": "5.16.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.1.tgz", - "integrity": "sha512-4U5pNsuDl0EhuZpq46M5xPslstkviJuhrdobaRDBk2Jy2KO37FDAJl4lb2KlNabxT0m4MTK2UHNrsAcphE8nyw==", + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", "dev": true, "dependencies": { "graceful-fs": "^4.2.4", @@ -2925,10 +3008,16 @@ } }, "node_modules/ent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==", - "dev": true + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.1.tgz", + "integrity": "sha512-QHuXVeZx9d+tIQAz/XztU0ZwZf2Agg9CcXcgE1rurqvdBeDBrpSwjl8/6XUqMg7tw2Y7uAdKb2sRv+bSEFqQ5A==", + "dev": true, + "dependencies": { + "punycode": "^1.4.1" + }, + "engines": { + "node": ">= 0.4" + } }, "node_modules/entities": { "version": "2.1.0", @@ -3029,6 +3118,27 @@ "node": ">= 0.4" } }, + "node_modules/es-get-iterator": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", + "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", + "dev": true, + "peer": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "is-arguments": "^1.1.1", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.7", + "isarray": "^2.0.5", + "stop-iteration-iterator": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/es-iterator-helpers": { "version": "1.0.19", "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz", @@ -3123,47 +3233,48 @@ } }, "node_modules/esbuild": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", - "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz", + "integrity": "sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==", "dev": true, "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" }, "engines": { - "node": ">=12" + "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.20.2", - "@esbuild/android-arm": "0.20.2", - "@esbuild/android-arm64": "0.20.2", - "@esbuild/android-x64": "0.20.2", - "@esbuild/darwin-arm64": "0.20.2", - "@esbuild/darwin-x64": "0.20.2", - "@esbuild/freebsd-arm64": "0.20.2", - "@esbuild/freebsd-x64": "0.20.2", - "@esbuild/linux-arm": "0.20.2", - "@esbuild/linux-arm64": "0.20.2", - "@esbuild/linux-ia32": "0.20.2", - "@esbuild/linux-loong64": "0.20.2", - "@esbuild/linux-mips64el": "0.20.2", - "@esbuild/linux-ppc64": "0.20.2", - "@esbuild/linux-riscv64": "0.20.2", - "@esbuild/linux-s390x": "0.20.2", - "@esbuild/linux-x64": "0.20.2", - "@esbuild/netbsd-x64": "0.20.2", - "@esbuild/openbsd-x64": "0.20.2", - "@esbuild/sunos-x64": "0.20.2", - "@esbuild/win32-arm64": "0.20.2", - "@esbuild/win32-ia32": "0.20.2", - "@esbuild/win32-x64": "0.20.2" + "@esbuild/aix-ppc64": "0.23.1", + "@esbuild/android-arm": "0.23.1", + "@esbuild/android-arm64": "0.23.1", + "@esbuild/android-x64": "0.23.1", + "@esbuild/darwin-arm64": "0.23.1", + "@esbuild/darwin-x64": "0.23.1", + "@esbuild/freebsd-arm64": "0.23.1", + "@esbuild/freebsd-x64": "0.23.1", + "@esbuild/linux-arm": "0.23.1", + "@esbuild/linux-arm64": "0.23.1", + "@esbuild/linux-ia32": "0.23.1", + "@esbuild/linux-loong64": "0.23.1", + "@esbuild/linux-mips64el": "0.23.1", + "@esbuild/linux-ppc64": "0.23.1", + "@esbuild/linux-riscv64": "0.23.1", + "@esbuild/linux-s390x": "0.23.1", + "@esbuild/linux-x64": "0.23.1", + "@esbuild/netbsd-x64": "0.23.1", + "@esbuild/openbsd-arm64": "0.23.1", + "@esbuild/openbsd-x64": "0.23.1", + "@esbuild/sunos-x64": "0.23.1", + "@esbuild/win32-arm64": "0.23.1", + "@esbuild/win32-ia32": "0.23.1", + "@esbuild/win32-x64": "0.23.1" } }, "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, "engines": { "node": ">=6" @@ -3323,17 +3434,18 @@ } }, "node_modules/eslint-import-resolver-typescript": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz", - "integrity": "sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.3.tgz", + "integrity": "sha512-ud9aw4szY9cCT1EWWdGv1L1XR6hh2PaRWif0j2QjQ0pgTY/69iw+W0Z4qZv5wHahOl8isEr+k/JnyAqNQkLkIA==", "dev": true, "dependencies": { - "debug": "^4.3.4", - "enhanced-resolve": "^5.12.0", - "eslint-module-utils": "^2.7.4", - "fast-glob": "^3.3.1", - "get-tsconfig": "^4.5.0", - "is-core-module": "^2.11.0", + "@nolyfill/is-core-module": "1.0.39", + "debug": "^4.3.5", + "enhanced-resolve": "^5.15.0", + "eslint-module-utils": "^2.8.1", + "fast-glob": "^3.3.2", + "get-tsconfig": "^4.7.5", + "is-bun-module": "^1.0.2", "is-glob": "^4.0.3" }, "engines": { @@ -3344,13 +3456,22 @@ }, "peerDependencies": { "eslint": "*", - "eslint-plugin-import": "*" + "eslint-plugin-import": "*", + "eslint-plugin-import-x": "*" + }, + "peerDependenciesMeta": { + "eslint-plugin-import": { + "optional": true + }, + "eslint-plugin-import-x": { + "optional": true + } } }, "node_modules/eslint-module-utils": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", - "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.9.0.tgz", + "integrity": "sha512-McVbYmwA3NEKwRQY5g4aWMdcZE5xZxV8i8l7CqJSrameuGSQJtSWaL/LxTEzSKKaCcOhlpDR8XEfYXWPrdo/ZQ==", "dev": true, "dependencies": { "debug": "^3.2.7" @@ -3386,26 +3507,27 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", - "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.30.0.tgz", + "integrity": "sha512-/mHNE9jINJfiD2EKkg1BKyPyUk4zdnT54YgbOgfjSakWT5oyX/qQLVNTkehyfpcMxZXMy1zyonZ2v7hZTX43Yw==", "dev": true, "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.8", + "array.prototype.findlastindex": "^1.2.5", "array.prototype.flat": "^1.3.2", "array.prototype.flatmap": "^1.3.2", "debug": "^3.2.7", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", + "eslint-module-utils": "^2.9.0", + "hasown": "^2.0.2", + "is-core-module": "^2.15.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.0", "semver": "^6.3.1", "tsconfig-paths": "^3.15.0" }, @@ -3469,34 +3591,34 @@ } }, "node_modules/eslint-plugin-jsx-a11y": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.8.0.tgz", - "integrity": "sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.0.tgz", + "integrity": "sha512-ySOHvXX8eSN6zz8Bywacm7CvGNhUtdjvqfQDVe6020TUK34Cywkw7m0KsCCk1Qtm9G1FayfTN1/7mMYnYO2Bhg==", "dev": true, "peer": true, "dependencies": { - "@babel/runtime": "^7.23.2", - "aria-query": "^5.3.0", - "array-includes": "^3.1.7", + "aria-query": "~5.1.3", + "array-includes": "^3.1.8", "array.prototype.flatmap": "^1.3.2", "ast-types-flow": "^0.0.8", - "axe-core": "=4.7.0", - "axobject-query": "^3.2.1", + "axe-core": "^4.10.0", + "axobject-query": "^4.1.0", "damerau-levenshtein": "^1.0.8", "emoji-regex": "^9.2.2", - "es-iterator-helpers": "^1.0.15", - "hasown": "^2.0.0", + "es-iterator-helpers": "^1.0.19", + "hasown": "^2.0.2", "jsx-ast-utils": "^3.3.5", "language-tags": "^1.0.9", "minimatch": "^3.1.2", - "object.entries": "^1.1.7", - "object.fromentries": "^2.0.7" + "object.fromentries": "^2.0.8", + "safe-regex-test": "^1.0.3", + "string.prototype.includes": "^2.0.0" }, "engines": { "node": ">=4.0" }, "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" } }, "node_modules/eslint-plugin-jsx-a11y/node_modules/brace-expansion": { @@ -3524,36 +3646,36 @@ } }, "node_modules/eslint-plugin-react": { - "version": "7.34.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.1.tgz", - "integrity": "sha512-N97CxlouPT1AHt8Jn0mhhN2RrADlUAsk1/atcT2KyA/l9Q/E6ll7OIGwNumFmWfZ9skV3XXccYS19h80rHtgkw==", + "version": "7.35.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.35.2.tgz", + "integrity": "sha512-Rbj2R9zwP2GYNcIak4xoAMV57hrBh3hTaR0k7hVjwCQgryE/pw5px4b13EYjduOI0hfXyZhwBxaGpOTbWSGzKQ==", "dev": true, "peer": true, "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlast": "^1.2.4", + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", "array.prototype.flatmap": "^1.3.2", - "array.prototype.toreversed": "^1.1.2", - "array.prototype.tosorted": "^1.1.3", + "array.prototype.tosorted": "^1.1.4", "doctrine": "^2.1.0", - "es-iterator-helpers": "^1.0.17", + "es-iterator-helpers": "^1.0.19", "estraverse": "^5.3.0", + "hasown": "^2.0.2", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", - "object.entries": "^1.1.7", - "object.fromentries": "^2.0.7", - "object.hasown": "^1.1.3", - "object.values": "^1.1.7", + "object.entries": "^1.1.8", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.0", "prop-types": "^15.8.1", "resolve": "^2.0.0-next.5", "semver": "^6.3.1", - "string.prototype.matchall": "^4.0.10" + "string.prototype.matchall": "^4.0.11", + "string.prototype.repeat": "^1.0.0" }, "engines": { "node": ">=4" }, "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" } }, "node_modules/eslint-plugin-react-hooks": { @@ -3746,9 +3868,9 @@ } }, "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, "dependencies": { "estraverse": "^5.1.0" @@ -3996,9 +4118,9 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "version": "1.15.8", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.8.tgz", + "integrity": "sha512-xgrmBhBToVKay1q2Tao5LI26B83UhrB/vM1avwVSDzt8rx3rO6AizBAaF46EgksTVr+rFTQaqZZ9MVBfUe4nig==", "dev": true, "funding": [ { @@ -4168,9 +4290,9 @@ } }, "node_modules/get-tsconfig": { - "version": "4.7.5", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.5.tgz", - "integrity": "sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.0.tgz", + "integrity": "sha512-Pgba6TExTZ0FJAn1qkJAjIeKoDJ3CsI2ChuLohJnZl/tTU8MVrq3b+2t5UOPfRa4RMsorClBjJALkJUMjG1PAw==", "dev": true, "dependencies": { "resolve-pkg-maps": "^1.0.0" @@ -4183,6 +4305,7 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", @@ -4539,9 +4662,9 @@ } }, "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "engines": { "node": ">= 4" @@ -4585,6 +4708,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, "dependencies": { "once": "^1.3.0", @@ -4611,6 +4735,23 @@ "node": ">= 0.4" } }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dev": true, + "peer": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-array-buffer": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", @@ -4704,6 +4845,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-bun-module": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-1.1.0.tgz", + "integrity": "sha512-4mTAVPlrXpaN3jtF0lsnPCMGnq4+qZjVIKq0HCpfcqf8OC1SM5oATCIAPM5V5FN05qp2NNnFndphmdZS9CV3hA==", + "dev": true, + "dependencies": { + "semver": "^7.6.3" + } + }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -4729,12 +4879,15 @@ } }, "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", "dev": true, "dependencies": { - "hasown": "^2.0.0" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5268,9 +5421,9 @@ "dev": true }, "node_modules/karma": { - "version": "6.4.3", - "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.3.tgz", - "integrity": "sha512-LuucC/RE92tJ8mlCwqEoRWXP38UMAqpnq98vktmS9SznSoUPPUJQbc91dHcxcunROvfQjdORVA/YFviH+Xci9Q==", + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.4.tgz", + "integrity": "sha512-LrtUxbdvt1gOpo3gxG+VAJlJAEMhbWlM4YrFQgql98FwF7+K8K12LYO4hnDdUkNjeztYrOXEMqgTajSWgmtI/w==", "dev": true, "dependencies": { "@colors/colors": "1.5.0", @@ -5481,13 +5634,13 @@ } }, "node_modules/karma-webkit-launcher": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/karma-webkit-launcher/-/karma-webkit-launcher-2.4.0.tgz", - "integrity": "sha512-k6fmeEwRt5PiPwb/B8stLNbtqcCqBcdMVUsep58da2uS0pEYr4X/RgP1/ThJK12Q6uispGgWVtDtp6O0hDOF+Q==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/karma-webkit-launcher/-/karma-webkit-launcher-2.6.0.tgz", + "integrity": "sha512-IDURopxJ1SbuqnvPaE+lP2qiP2Ie7I+ojwJRBpr0tfGwObsaVdjMkUkmZ1BcXUtYRt5ogs9cyCH2Wb9sNv0BbQ==", "dev": true, "dependencies": { "is-ci": "^3.0.1", - "uuid": "^9.0.1" + "uuid": "^10.0.0" }, "peerDependenciesMeta": { "playwright": { @@ -5520,6 +5673,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", @@ -5618,9 +5772,9 @@ } }, "node_modules/language-subtag-registry": { - "version": "0.3.22", - "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", - "integrity": "sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==", + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", + "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", "dev": true, "peer": true }, @@ -5820,12 +5974,12 @@ } }, "node_modules/magic-string": { - "version": "0.30.10", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", - "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "version": "0.30.11", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", + "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", "dev": true, "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" + "@jridgewell/sourcemap-codec": "^1.5.0" } }, "node_modules/make-dir": { @@ -5918,12 +6072,12 @@ } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -5973,9 +6127,9 @@ } }, "node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -6009,31 +6163,31 @@ } }, "node_modules/mocha": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.4.0.tgz", - "integrity": "sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA==", + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.3.tgz", + "integrity": "sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A==", "dev": true, "dependencies": { - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.4", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "8.1.0", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "5.0.1", - "ms": "2.1.3", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "workerpool": "6.2.1", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^8.1.0", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" }, "bin": { "_mocha": "bin/_mocha", @@ -6043,33 +6197,6 @@ "node": ">= 14.0.0" } }, - "node_modules/mocha/node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, "node_modules/mocha/node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -6093,18 +6220,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mocha/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/mocha/node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -6122,9 +6237,9 @@ } }, "node_modules/mocha/node_modules/minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -6139,15 +6254,6 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, - "node_modules/mocha/node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, "node_modules/mocha/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -6182,9 +6288,9 @@ } }, "node_modules/mocha/node_modules/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true, "engines": { "node": ">=10" @@ -6264,10 +6370,30 @@ } }, "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", + "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", + "dev": true, + "peer": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -6345,24 +6471,6 @@ "node": ">= 0.4" } }, - "node_modules/object.hasown": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.4.tgz", - "integrity": "sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==", - "dev": true, - "peer": true, - "dependencies": { - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/object.values": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", @@ -6572,9 +6680,9 @@ } }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", "dev": true }, "node_modules/picomatch": { @@ -6596,33 +6704,33 @@ "dev": true }, "node_modules/playwright": { - "version": "1.44.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.44.0.tgz", - "integrity": "sha512-F9b3GUCLQ3Nffrfb6dunPOkE5Mh68tR7zN32L4jCk4FjQamgesGay7/dAAe1WaMEGV04DkdJfcJzjoCKygUaRQ==", + "version": "1.46.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.46.1.tgz", + "integrity": "sha512-oPcr1yqoXLCkgKtD5eNUPLiN40rYEM39odNpIb6VE6S7/15gJmA1NzVv6zJYusV0e7tzvkU/utBFNa/Kpxmwng==", "dev": true, "dependencies": { - "playwright-core": "1.44.0" + "playwright-core": "1.46.1" }, "bin": { "playwright": "cli.js" }, "engines": { - "node": ">=16" + "node": ">=18" }, "optionalDependencies": { "fsevents": "2.3.2" } }, "node_modules/playwright-core": { - "version": "1.44.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.44.0.tgz", - "integrity": "sha512-ZTbkNpFfYcGWohvTTl+xewITm7EOuqIqex0c7dNZ+aXsbrLj0qI8XlGKfPpipjm0Wny/4Lt4CJsWJk1stVS5qQ==", + "version": "1.46.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.46.1.tgz", + "integrity": "sha512-h9LqIQaAv+CYvWzsZ+h3RsrqCStkBHlgo6/TJlFst3cOTlLghBQlJwPOZKQJTKNaD3QIB7aAVQ+gfWbN3NXB7A==", "dev": true, "bin": { "playwright-core": "cli.js" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/playwright/node_modules/fsevents": { @@ -6729,18 +6837,16 @@ } }, "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "engines": { - "node": ">=6" - } + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true }, "node_modules/q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", + "deprecated": "You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.\n\n(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)", "dev": true, "engines": { "node": ">=0.6.0", @@ -6967,13 +7073,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "dev": true, - "peer": true - }, "node_modules/regexp-tree": { "version": "0.1.27", "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", @@ -7092,15 +7191,16 @@ } }, "node_modules/rfdc": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.1.tgz", - "integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", "dev": true }, "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, "dependencies": { "glob": "^7.1.3" @@ -7126,6 +7226,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", @@ -7155,9 +7256,9 @@ } }, "node_modules/rollup": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.17.2.tgz", - "integrity": "sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.2.tgz", + "integrity": "sha512-e3TapAgYf9xjdLvKQCkQTnbTKd4a6jwlpQSJJFokHGaX2IVjoEqkIIhiQfqsi0cdwlOD+tQGuOd5AJkc5RngBw==", "dev": true, "dependencies": { "@types/estree": "1.0.5" @@ -7170,22 +7271,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.17.2", - "@rollup/rollup-android-arm64": "4.17.2", - "@rollup/rollup-darwin-arm64": "4.17.2", - "@rollup/rollup-darwin-x64": "4.17.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.17.2", - "@rollup/rollup-linux-arm-musleabihf": "4.17.2", - "@rollup/rollup-linux-arm64-gnu": "4.17.2", - "@rollup/rollup-linux-arm64-musl": "4.17.2", - "@rollup/rollup-linux-powerpc64le-gnu": "4.17.2", - "@rollup/rollup-linux-riscv64-gnu": "4.17.2", - "@rollup/rollup-linux-s390x-gnu": "4.17.2", - "@rollup/rollup-linux-x64-gnu": "4.17.2", - "@rollup/rollup-linux-x64-musl": "4.17.2", - "@rollup/rollup-win32-arm64-msvc": "4.17.2", - "@rollup/rollup-win32-ia32-msvc": "4.17.2", - "@rollup/rollup-win32-x64-msvc": "4.17.2", + "@rollup/rollup-android-arm-eabi": "4.21.2", + "@rollup/rollup-android-arm64": "4.21.2", + "@rollup/rollup-darwin-arm64": "4.21.2", + "@rollup/rollup-darwin-x64": "4.21.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.21.2", + "@rollup/rollup-linux-arm-musleabihf": "4.21.2", + "@rollup/rollup-linux-arm64-gnu": "4.21.2", + "@rollup/rollup-linux-arm64-musl": "4.21.2", + "@rollup/rollup-linux-powerpc64le-gnu": "4.21.2", + "@rollup/rollup-linux-riscv64-gnu": "4.21.2", + "@rollup/rollup-linux-s390x-gnu": "4.21.2", + "@rollup/rollup-linux-x64-gnu": "4.21.2", + "@rollup/rollup-linux-x64-musl": "4.21.2", + "@rollup/rollup-win32-arm64-msvc": "4.21.2", + "@rollup/rollup-win32-ia32-msvc": "4.21.2", + "@rollup/rollup-win32-x64-msvc": "4.21.2", "fsevents": "~2.3.2" } }, @@ -7266,9 +7367,9 @@ "dev": true }, "node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -7387,15 +7488,6 @@ "url": "https://opencollective.com/sinon" } }, - "node_modules/sinon/node_modules/diff": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", - "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/slash": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", @@ -7501,9 +7593,9 @@ } }, "node_modules/spdx-license-ids": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz", - "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==", + "version": "3.0.20", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", + "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", "dev": true }, "node_modules/split": { @@ -7527,6 +7619,19 @@ "node": ">= 0.6" } }, + "node_modules/stop-iteration-iterator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", + "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", + "dev": true, + "peer": true, + "dependencies": { + "internal-slot": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/stream-combiner": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", @@ -7570,6 +7675,17 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "node_modules/string.prototype.includes": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.0.tgz", + "integrity": "sha512-E34CkBgyeqNDcrbU76cDjL5JLcVrtSdYq0MEh/B10r17pRP4ciHLwTgnuLV8Ay6cgEMLkcBkFCKyFZ43YldYzg==", + "dev": true, + "peer": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, "node_modules/string.prototype.matchall": { "version": "4.0.11", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", @@ -7597,6 +7713,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "peer": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, "node_modules/string.prototype.trim": { "version": "1.2.9", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", @@ -7756,6 +7883,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", @@ -7788,6 +7916,7 @@ "version": "2.5.4", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz", "integrity": "sha512-Lw7SHMjssciQb/rRz7JyPIy9+bbUshEucPoLRvWqy09vC5zQixl8Uet+Zl+SROBB/JMWHJRdCk1qdxNWHNMvlQ==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, "dependencies": { "glob": "^7.0.5" @@ -7797,9 +7926,9 @@ } }, "node_modules/terser": { - "version": "5.31.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.0.tgz", - "integrity": "sha512-Q1JFAoUKE5IMfI4Z/lkE/E6+SwgzO+x4tq4v1AyBLRj8VSYvRO6A/rQrPg1yud4g0En9EKI1TvFRF2tQFcoUkg==", + "version": "5.31.6", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz", + "integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==", "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -7848,6 +7977,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", @@ -7897,6 +8027,15 @@ "node": ">=14.14" } }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -7995,18 +8134,18 @@ } }, "node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", "dev": true }, "node_modules/tsx": { - "version": "4.10.4", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.10.4.tgz", - "integrity": "sha512-Gtg9qnZWNqC/OtcgiXfoAUdAKx3/cgKOYvEocAsv+m21MV/eKpV/WUjRXe6/sDCaGBl2/v8S6v29BpUnGMCX5A==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.0.tgz", + "integrity": "sha512-bV30kM7bsLZKZIOCHeMNVMJ32/LuJzLVajkQI/qf92J2Qr08ueLQvW00PUZGiuLPP760UINwupgUj8qrSCPUKg==", "dev": true, "dependencies": { - "esbuild": "~0.20.2", + "esbuild": "~0.23.0", "get-tsconfig": "^4.7.5" }, "bin": { @@ -8139,9 +8278,9 @@ } }, "node_modules/typescript": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", - "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -8152,9 +8291,9 @@ } }, "node_modules/ua-parser-js": { - "version": "0.7.37", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.37.tgz", - "integrity": "sha512-xV8kqRKM+jhMvcHWUKthV9fNebIzrNy//2O9ZwWcfiBFR5f25XVZPLlEajk/sf3Ra15V92isyQqnIEXRDaZWEA==", + "version": "0.7.38", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.38.tgz", + "integrity": "sha512-fYmIy7fKTSFAhG3fuPlubeGaMoAd6r0rSnfEsO5nEY55i26KSLt9EH7PLQiiqPUhNqYIJvSkTy1oArIcXAbPbA==", "dev": true, "funding": [ { @@ -8196,15 +8335,15 @@ } }, "node_modules/underscore": { - "version": "1.13.6", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", - "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", + "version": "1.13.7", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.7.tgz", + "integrity": "sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==", "dev": true }, "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "dev": true }, "node_modules/union": { @@ -8246,6 +8385,15 @@ "punycode": "^2.1.0" } }, + "node_modules/uri-js/node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/url-join": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", @@ -8262,9 +8410,9 @@ } }, "node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", "dev": true, "funding": [ "https://github.com/sponsors/broofa", @@ -8281,9 +8429,9 @@ "dev": true }, "node_modules/v8-to-istanbul": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", - "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", "dev": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", @@ -8387,14 +8535,14 @@ } }, "node_modules/which-builtin-type": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz", - "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.4.tgz", + "integrity": "sha512-bppkmBSsHFmIMSl8BO9TbsyzsvGjVoppt8xUiGzwiu/bhDCGxnpOKCxgqj6GuyHE0mINMDecBFPlOm2hzY084w==", "dev": true, "peer": true, "dependencies": { - "function.prototype.name": "^1.1.5", - "has-tostringtag": "^1.0.0", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", "is-async-function": "^2.0.0", "is-date-object": "^1.0.5", "is-finalizationregistry": "^1.0.2", @@ -8403,8 +8551,8 @@ "is-weakref": "^1.0.2", "isarray": "^2.0.5", "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.9" + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.15" }, "engines": { "node": ">= 0.4" @@ -8461,9 +8609,9 @@ } }, "node_modules/workerpool": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", - "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", "dev": true }, "node_modules/wrap-ansi": { @@ -8588,6232 +8736,5 @@ "url": "https://github.com/sponsors/sindresorhus" } } - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", - "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", - "dev": true, - "requires": { - "@babel/highlight": "^7.24.2", - "picocolors": "^1.0.0" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.5.tgz", - "integrity": "sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA==", - "dev": true - }, - "@babel/highlight": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.5.tgz", - "integrity": "sha512-8lLmua6AVh/8SLJRRVD6V8p73Hir9w5mJrhE+IPpILG31KKlI9iz5zmBYKcWPS59qSfgP9RaSBQSHHE81WKuEw==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.24.5", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/parser": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.5.tgz", - "integrity": "sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==", - "dev": true - }, - "@babel/runtime": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz", - "integrity": "sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==", - "dev": true, - "peer": true, - "requires": { - "regenerator-runtime": "^0.14.0" - } - }, - "@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, - "@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "dev": true - }, - "@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "dependencies": { - "@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - } - } - }, - "@esbuild/aix-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", - "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", - "dev": true, - "optional": true - }, - "@esbuild/android-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", - "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", - "dev": true, - "optional": true - }, - "@esbuild/android-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", - "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", - "dev": true, - "optional": true - }, - "@esbuild/android-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", - "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", - "dev": true, - "optional": true - }, - "@esbuild/darwin-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", - "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", - "dev": true, - "optional": true - }, - "@esbuild/darwin-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", - "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", - "dev": true, - "optional": true - }, - "@esbuild/freebsd-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", - "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", - "dev": true, - "optional": true - }, - "@esbuild/freebsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", - "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", - "dev": true, - "optional": true - }, - "@esbuild/linux-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", - "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", - "dev": true, - "optional": true - }, - "@esbuild/linux-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", - "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", - "dev": true, - "optional": true - }, - "@esbuild/linux-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", - "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", - "dev": true, - "optional": true - }, - "@esbuild/linux-loong64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", - "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", - "dev": true, - "optional": true - }, - "@esbuild/linux-mips64el": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", - "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", - "dev": true, - "optional": true - }, - "@esbuild/linux-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", - "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", - "dev": true, - "optional": true - }, - "@esbuild/linux-riscv64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", - "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", - "dev": true, - "optional": true - }, - "@esbuild/linux-s390x": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", - "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", - "dev": true, - "optional": true - }, - "@esbuild/linux-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", - "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", - "dev": true, - "optional": true - }, - "@esbuild/netbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", - "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", - "dev": true, - "optional": true - }, - "@esbuild/openbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", - "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", - "dev": true, - "optional": true - }, - "@esbuild/sunos-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", - "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", - "dev": true, - "optional": true - }, - "@esbuild/win32-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", - "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", - "dev": true, - "optional": true - }, - "@esbuild/win32-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", - "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", - "dev": true, - "optional": true - }, - "@esbuild/win32-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", - "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", - "dev": true, - "optional": true - }, - "@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^3.3.0" - } - }, - "@eslint-community/regexpp": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", - "dev": true - }, - "@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, - "@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "dev": true - }, - "@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, - "@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true - }, - "@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "dev": true - }, - "@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true - }, - "@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true - }, - "@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true - }, - "@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", - "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" - } - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "@noble/ciphers": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.6.0.tgz", - "integrity": "sha512-mIbq/R9QXk5/cTfESb1OKtyFnk7oc1Om/8onA1158K9/OZUQFDEVy55jVTato+xmp3XX6F6Qh0zz0Nc1AxAlRQ==", - "dev": true - }, - "@noble/curves": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.0.tgz", - "integrity": "sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==", - "dev": true, - "requires": { - "@noble/hashes": "1.4.0" - } - }, - "@noble/hashes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", - "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", - "dev": true - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@openpgp/jsdoc": { - "version": "3.6.11", - "resolved": "https://registry.npmjs.org/@openpgp/jsdoc/-/jsdoc-3.6.11.tgz", - "integrity": "sha512-mwvKQrW9raTU4CM3Oa93deRPh3TknFL0PUaGJWXwk3Inqf5nT8x4Z867ctqKYPekqw9FdDGyTaGb4rkbyPl9fA==", - "dev": true, - "requires": { - "@babel/parser": "^7.9.4", - "@types/markdown-it": "^12.2.3", - "bluebird": "^3.7.2", - "catharsis": "^0.9.0", - "escape-string-regexp": "^2.0.0", - "js2xmlparser": "^4.0.2", - "klaw": "^3.0.0", - "markdown-it": "^12.3.2", - "markdown-it-anchor": "^8.4.1", - "marked": "^4.0.10", - "mkdirp": "^1.0.4", - "requizzle": "^0.2.3", - "strip-json-comments": "^3.1.0", - "taffydb": "2.6.2", - "underscore": "~1.13.2" - } - }, - "@openpgp/seek-bzip": { - "version": "1.0.5-git", - "resolved": "https://registry.npmjs.org/@openpgp/seek-bzip/-/seek-bzip-1.0.5-git.tgz", - "integrity": "sha512-1493w5yzXmAss9GEbNPYwX9UjROLfCTB8vjiTlT/HNzSH9b1FL4kJFH5iBV/+v6Ur5wlbCatGHinvqPeY0BwCw==", - "dev": true, - "requires": { - "commander": "~2.8.1" - } - }, - "@openpgp/tweetnacl": { - "version": "1.0.4-1", - "resolved": "https://registry.npmjs.org/@openpgp/tweetnacl/-/tweetnacl-1.0.4-1.tgz", - "integrity": "sha512-coYo04Op1+g4h6yE6q0GglGdvWkdfvpQWKmR9nDIrW+LqdTtwHFXIyIQGs5cosR4tCajxRn9aF/+WK207zxFrg==", - "dev": true - }, - "@openpgp/web-stream-tools": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@openpgp/web-stream-tools/-/web-stream-tools-0.1.3.tgz", - "integrity": "sha512-mT/ds43cH6c+AO5RFpxs+LkACr7KjC3/dZWHrP6KPrWJu4uJ/XJ+p7telaoYiqUfdjiiIvdNSOfhezW9fkmboQ==", - "dev": true, - "requires": {} - }, - "@rollup/plugin-alias": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.1.0.tgz", - "integrity": "sha512-lpA3RZ9PdIG7qqhEfv79tBffNaoDuukFDrmhLqg9ifv99u/ehn+lOg30x2zmhf8AQqQUZaMk/B9fZraQ6/acDQ==", - "dev": true, - "requires": { - "slash": "^4.0.0" - } - }, - "@rollup/plugin-commonjs": { - "version": "25.0.7", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.7.tgz", - "integrity": "sha512-nEvcR+LRjEjsaSsc4x3XZfCCvZIaSMenZu/OiwOKGN2UhQpAYI7ru7czFvyWbErlpoGjnSX3D5Ch5FcMA3kRWQ==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^5.0.1", - "commondir": "^1.0.1", - "estree-walker": "^2.0.2", - "glob": "^8.0.3", - "is-reference": "1.2.1", - "magic-string": "^0.30.3" - } - }, - "@rollup/plugin-node-resolve": { - "version": "15.2.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz", - "integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^5.0.1", - "@types/resolve": "1.20.2", - "deepmerge": "^4.2.2", - "is-builtin-module": "^3.2.1", - "is-module": "^1.0.0", - "resolve": "^1.22.1" - } - }, - "@rollup/plugin-replace": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-5.0.5.tgz", - "integrity": "sha512-rYO4fOi8lMaTg/z5Jb+hKnrHHVn8j2lwkqwyS4kTRhKyWOLf2wST2sWXr4WzWiTcoHTp2sTjqUbqIj2E39slKQ==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^5.0.1", - "magic-string": "^0.30.3" - } - }, - "@rollup/plugin-terser": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", - "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", - "dev": true, - "requires": { - "serialize-javascript": "^6.0.1", - "smob": "^1.0.0", - "terser": "^5.17.4" - } - }, - "@rollup/plugin-typescript": { - "version": "11.1.6", - "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.6.tgz", - "integrity": "sha512-R92yOmIACgYdJ7dJ97p4K69I8gg6IEHt8M7dUBxN3W6nrO8uUxX5ixl0yU/N3aZTi8WhPuICvOHXQvF6FaykAA==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^5.1.0", - "resolve": "^1.22.1" - } - }, - "@rollup/plugin-wasm": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-wasm/-/plugin-wasm-6.2.2.tgz", - "integrity": "sha512-gpC4R1G9Ni92ZIRTexqbhX7U+9estZrbhP+9SRb0DW9xpB9g7j34r+J2hqrcW/lRI7dJaU84MxZM0Rt82tqYPQ==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^5.0.2" - } - }, - "@rollup/pluginutils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", - "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", - "dev": true, - "requires": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" - } - }, - "@rollup/rollup-android-arm-eabi": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.17.2.tgz", - "integrity": "sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==", - "dev": true, - "optional": true - }, - "@rollup/rollup-android-arm64": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.17.2.tgz", - "integrity": "sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw==", - "dev": true, - "optional": true - }, - "@rollup/rollup-darwin-arm64": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.17.2.tgz", - "integrity": "sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==", - "dev": true, - "optional": true - }, - "@rollup/rollup-darwin-x64": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.17.2.tgz", - "integrity": "sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.17.2.tgz", - "integrity": "sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-arm-musleabihf": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.17.2.tgz", - "integrity": "sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-arm64-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.17.2.tgz", - "integrity": "sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-arm64-musl": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.17.2.tgz", - "integrity": "sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.17.2.tgz", - "integrity": "sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-riscv64-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.17.2.tgz", - "integrity": "sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-s390x-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.17.2.tgz", - "integrity": "sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-x64-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz", - "integrity": "sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-x64-musl": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.17.2.tgz", - "integrity": "sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==", - "dev": true, - "optional": true - }, - "@rollup/rollup-win32-arm64-msvc": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.17.2.tgz", - "integrity": "sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA==", - "dev": true, - "optional": true - }, - "@rollup/rollup-win32-ia32-msvc": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.17.2.tgz", - "integrity": "sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ==", - "dev": true, - "optional": true - }, - "@rollup/rollup-win32-x64-msvc": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.17.2.tgz", - "integrity": "sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==", - "dev": true, - "optional": true - }, - "@sinonjs/commons": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "11.2.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", - "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", - "dev": true, - "requires": { - "@sinonjs/commons": "^3.0.0" - } - }, - "@sinonjs/samsam": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", - "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", - "dev": true, - "requires": { - "@sinonjs/commons": "^2.0.0", - "lodash.get": "^4.4.2", - "type-detect": "^4.0.8" - }, - "dependencies": { - "@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - } - } - }, - "@sinonjs/text-encoding": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", - "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", - "dev": true - }, - "@socket.io/component-emitter": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", - "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", - "dev": true - }, - "@tsconfig/node10": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", - "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "dev": true - }, - "@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true - }, - "@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true - }, - "@types/chai": { - "version": "4.3.16", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.16.tgz", - "integrity": "sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ==", - "dev": true - }, - "@types/cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", - "dev": true - }, - "@types/cors": { - "version": "2.8.17", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", - "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "dev": true - }, - "@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true - }, - "@types/linkify-it": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", - "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", - "dev": true - }, - "@types/markdown-it": { - "version": "12.2.3", - "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz", - "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==", - "dev": true, - "requires": { - "@types/linkify-it": "*", - "@types/mdurl": "*" - } - }, - "@types/mdurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", - "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", - "dev": true - }, - "@types/node": { - "version": "20.12.12", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz", - "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==", - "dev": true, - "requires": { - "undici-types": "~5.26.4" - } - }, - "@types/normalize-package-data": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", - "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", - "dev": true - }, - "@types/resolve": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", - "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", - "dev": true - }, - "@typescript-eslint/eslint-plugin": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.9.0.tgz", - "integrity": "sha512-6e+X0X3sFe/G/54aC3jt0txuMTURqLyekmEHViqyA2VnxhLMpvA6nqmcjIy+Cr9tLDHPssA74BP5Mx9HQIxBEA==", - "dev": true, - "peer": true, - "requires": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.9.0", - "@typescript-eslint/type-utils": "7.9.0", - "@typescript-eslint/utils": "7.9.0", - "@typescript-eslint/visitor-keys": "7.9.0", - "graphemer": "^1.4.0", - "ignore": "^5.3.1", - "natural-compare": "^1.4.0", - "ts-api-utils": "^1.3.0" - } - }, - "@typescript-eslint/parser": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.9.0.tgz", - "integrity": "sha512-qHMJfkL5qvgQB2aLvhUSXxbK7OLnDkwPzFalg458pxQgfxKDfT1ZDbHQM/I6mDIf/svlMkj21kzKuQ2ixJlatQ==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "7.9.0", - "@typescript-eslint/types": "7.9.0", - "@typescript-eslint/typescript-estree": "7.9.0", - "@typescript-eslint/visitor-keys": "7.9.0", - "debug": "^4.3.4" - } - }, - "@typescript-eslint/scope-manager": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.9.0.tgz", - "integrity": "sha512-ZwPK4DeCDxr3GJltRz5iZejPFAAr4Wk3+2WIBaj1L5PYK5RgxExu/Y68FFVclN0y6GGwH8q+KgKRCvaTmFBbgQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "7.9.0", - "@typescript-eslint/visitor-keys": "7.9.0" - } - }, - "@typescript-eslint/type-utils": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.9.0.tgz", - "integrity": "sha512-6Qy8dfut0PFrFRAZsGzuLoM4hre4gjzWJB6sUvdunCYZsYemTkzZNwF1rnGea326PHPT3zn5Lmg32M/xfJfByA==", - "dev": true, - "peer": true, - "requires": { - "@typescript-eslint/typescript-estree": "7.9.0", - "@typescript-eslint/utils": "7.9.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" - } - }, - "@typescript-eslint/types": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.9.0.tgz", - "integrity": "sha512-oZQD9HEWQanl9UfsbGVcZ2cGaR0YT5476xfWE0oE5kQa2sNK2frxOlkeacLOTh9po4AlUT5rtkGyYM5kew0z5w==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.9.0.tgz", - "integrity": "sha512-zBCMCkrb2YjpKV3LA0ZJubtKCDxLttxfdGmwZvTqqWevUPN0FZvSI26FalGFFUZU/9YQK/A4xcQF9o/VVaCKAg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "7.9.0", - "@typescript-eslint/visitor-keys": "7.9.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - } - }, - "@typescript-eslint/utils": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.9.0.tgz", - "integrity": "sha512-5KVRQCzZajmT4Ep+NEgjXCvjuypVvYHUW7RHlXzNPuak2oWpVoD1jf5xCP0dPAuNIchjC7uQyvbdaSTFaLqSdA==", - "dev": true, - "peer": true, - "requires": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.9.0", - "@typescript-eslint/types": "7.9.0", - "@typescript-eslint/typescript-estree": "7.9.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.9.0.tgz", - "integrity": "sha512-iESPx2TNLDNGQLyjKhUvIKprlP49XNEK+MvIf9nIO7ZZaZdbnfWKHnXAgufpxqfA0YryH8XToi4+CjBgVnFTSQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "7.9.0", - "eslint-visitor-keys": "^3.4.3" - } - }, - "@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, - "accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dev": true, - "requires": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - } - }, - "acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} - }, - "acorn-walk": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", - "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", - "dev": true - }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "requires": { - "debug": "4" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "argon2id": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/argon2id/-/argon2id-1.0.1.tgz", - "integrity": "sha512-rsiD3lX+0L0CsiZARp3bf9EGxprtuWAT7PpiJd+Fk53URV0/USOQkBIP1dLTV8t6aui0ECbymQ9W9YCcTd6XgA==", - "dev": true - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "aria-query": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", - "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", - "dev": true, - "peer": true, - "requires": { - "dequal": "^2.0.3" - } - }, - "array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", - "dev": true, - "requires": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" - } - }, - "array-includes": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", - "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.4", - "is-string": "^1.0.7" - } - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "array.prototype.findlast": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", - "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", - "dev": true, - "peer": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" - } - }, - "array.prototype.findlastindex": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", - "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" - } - }, - "array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - } - }, - "array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - } - }, - "array.prototype.toreversed": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz", - "integrity": "sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==", - "dev": true, - "peer": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - } - }, - "array.prototype.tosorted": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.3.tgz", - "integrity": "sha512-/DdH4TiTmOKzyQbp/eadcCVexiCb36xJg7HshYOYJnNZFDj33GEv0P7GxsynpShhq4OLYJzbGcBDkLsDt7MnNg==", - "dev": true, - "peer": true, - "requires": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.1.0", - "es-shim-unscopables": "^1.0.2" - } - }, - "arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", - "dev": true, - "requires": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" - } - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "ast-types-flow": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", - "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", - "dev": true, - "peer": true - }, - "async": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", - "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dev": true, - "requires": { - "possible-typed-array-names": "^1.0.0" - } - }, - "axe-core": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.0.tgz", - "integrity": "sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==", - "dev": true, - "peer": true - }, - "axobject-query": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", - "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", - "dev": true, - "peer": true, - "requires": { - "dequal": "^2.0.3" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "base64id": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", - "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", - "dev": true - }, - "basic-auth": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", - "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", - "dev": true, - "requires": { - "safe-buffer": "5.1.2" - } - }, - "benchmark": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/benchmark/-/benchmark-2.1.4.tgz", - "integrity": "sha512-l9MlfN4M1K/H2fbhfMy3B7vJd6AGKJVQn2h6Sg/Yx+KckoUA7ewS5Vv6TjSq18ooE1kS9hhAlQRH3AkXIh/aOQ==", - "dev": true, - "requires": { - "lodash": "^4.17.4", - "platform": "^1.3.3" - } - }, - "binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", - "dev": true, - "requires": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - } - } - }, - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "requires": { - "fill-range": "^7.1.1" - } - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserstack": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/browserstack/-/browserstack-1.5.3.tgz", - "integrity": "sha512-AO+mECXsW4QcqC9bxwM29O7qWa7bJT94uBFzeb5brylIQwawuEziwq20dPYbins95GlWzOawgyDNdjYAo32EKg==", - "dev": true, - "requires": { - "https-proxy-agent": "^2.2.1" - } - }, - "browserstack-local": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/browserstack-local/-/browserstack-local-1.5.5.tgz", - "integrity": "sha512-jKne7yosrMcptj3hqxp36TP9k0ZW2sCqhyurX24rUL4G3eT7OLgv+CSQN8iq5dtkv5IK+g+v8fWvsiC/S9KxMg==", - "dev": true, - "requires": { - "agent-base": "^6.0.2", - "https-proxy-agent": "^5.0.1", - "is-running": "^2.1.0", - "ps-tree": "=1.2.0", - "temp-fs": "^0.9.9" - }, - "dependencies": { - "https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" - } - } - } - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", - "dev": true - }, - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true - }, - "c8": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/c8/-/c8-8.0.1.tgz", - "integrity": "sha512-EINpopxZNH1mETuI0DzRA4MZpAUH+IFiRhnmFD3vFr3vdrgxqi3VfE3KL0AIL+zDq8rC9bZqwM/VDmmoe04y7w==", - "dev": true, - "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@istanbuljs/schema": "^0.1.3", - "find-up": "^5.0.0", - "foreground-child": "^2.0.0", - "istanbul-lib-coverage": "^3.2.0", - "istanbul-lib-report": "^3.0.1", - "istanbul-reports": "^3.1.6", - "rimraf": "^3.0.2", - "test-exclude": "^6.0.0", - "v8-to-istanbul": "^9.0.0", - "yargs": "^17.7.2", - "yargs-parser": "^21.1.1" - } - }, - "call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dev": true, - "requires": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - }, - "catharsis": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", - "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", - "dev": true, - "requires": { - "lodash": "^4.17.15" - } - }, - "chai": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", - "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.3", - "deep-eql": "^4.1.3", - "get-func-name": "^2.0.2", - "loupe": "^2.3.6", - "pathval": "^1.1.1", - "type-detect": "^4.0.8" - } - }, - "chai-as-promised": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.2.tgz", - "integrity": "sha512-aBDHZxRzYnUYuIAIPBH2s511DjlKPzXNlXSGFC8CwmroWQLfrW0LtE1nK3MAwwNhJPa9raEjNCmRoFpG0Hurdw==", - "dev": true, - "requires": { - "check-error": "^1.0.2" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "check-error": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", - "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", - "dev": true, - "requires": { - "get-func-name": "^2.0.2" - } - }, - "chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "dependencies": { - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - } - } - }, - "ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "dev": true - }, - "clean-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", - "integrity": "sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - }, - "dependencies": { - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - } - } - }, - "cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "commander": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", - "integrity": "sha512-+pJLBFVk+9ZZdlAOB5WuIElVPPth47hILFkmGym57aq8kwxsowvByvB0DHs1vQAhyMZzdcpTtF0VDKGkSDR4ZQ==", - "dev": true, - "requires": { - "graceful-readlink": ">= 1.0.0" - } - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "confusing-browser-globals": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", - "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", - "dev": true - }, - "connect": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", - "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", - "dev": true, - "requires": { - "debug": "2.6.9", - "finalhandler": "1.1.2", - "parseurl": "~1.3.3", - "utils-merge": "1.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - } - } - }, - "content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "dev": true - }, - "convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, - "cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "dev": true - }, - "cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dev": true, - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, - "corser": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", - "integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==", - "dev": true - }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "custom-event": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", - "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==", - "dev": true - }, - "damerau-levenshtein": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", - "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", - "dev": true, - "peer": true - }, - "data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", - "dev": true, - "requires": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - } - }, - "data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - } - }, - "data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", - "dev": true, - "requires": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - } - }, - "date-format": { - "version": "4.0.14", - "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", - "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", - "dev": true - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true - }, - "deep-eql": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", - "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true - }, - "define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, - "requires": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - } - }, - "define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, - "requires": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - } - }, - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true - }, - "dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "dev": true, - "peer": true - }, - "destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "dev": true - }, - "di": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", - "integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==", - "dev": true - }, - "diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "dom-serialize": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", - "integrity": "sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ==", - "dev": true, - "requires": { - "custom-event": "~1.0.0", - "ent": "~2.2.0", - "extend": "^3.0.0", - "void-elements": "^2.0.0" - } - }, - "duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", - "dev": true - }, - "eckey-utils": { - "version": "0.7.14", - "resolved": "https://registry.npmjs.org/eckey-utils/-/eckey-utils-0.7.14.tgz", - "integrity": "sha512-s/mENS+mMnJjDSydy0muBQQHMTWJ1nPe8EiphANZrf+lv/1u35aP9WvWHTWqCBJ21blNIurGF7UoLjtaOpoCFw==", - "dev": true - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "dev": true - }, - "emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "peer": true - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "dev": true - }, - "engine.io": { - "version": "6.5.5", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.5.tgz", - "integrity": "sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==", - "dev": true, - "requires": { - "@types/cookie": "^0.4.1", - "@types/cors": "^2.8.12", - "@types/node": ">=10.0.0", - "accepts": "~1.3.4", - "base64id": "2.0.0", - "cookie": "~0.4.1", - "cors": "~2.8.5", - "debug": "~4.3.1", - "engine.io-parser": "~5.2.1", - "ws": "~8.17.1" - } - }, - "engine.io-parser": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.2.tgz", - "integrity": "sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==", - "dev": true - }, - "enhanced-resolve": { - "version": "5.16.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.1.tgz", - "integrity": "sha512-4U5pNsuDl0EhuZpq46M5xPslstkviJuhrdobaRDBk2Jy2KO37FDAJl4lb2KlNabxT0m4MTK2UHNrsAcphE8nyw==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - } - }, - "ent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==", - "dev": true - }, - "entities": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", - "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", - "dev": true - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", - "dev": true, - "requires": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", - "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" - } - }, - "es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dev": true, - "requires": { - "get-intrinsic": "^1.2.4" - } - }, - "es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true - }, - "es-iterator-helpers": { - "version": "1.0.19", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz", - "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==", - "dev": true, - "peer": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.3", - "es-errors": "^1.3.0", - "es-set-tostringtag": "^2.0.3", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "globalthis": "^1.0.3", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.7", - "iterator.prototype": "^1.1.2", - "safe-array-concat": "^1.1.2" - } - }, - "es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", - "dev": true, - "requires": { - "es-errors": "^1.3.0" - } - }, - "es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", - "dev": true, - "requires": { - "get-intrinsic": "^1.2.4", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" - } - }, - "es-shim-unscopables": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", - "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", - "dev": true, - "requires": { - "hasown": "^2.0.0" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", - "dev": true - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", - "dev": true, - "requires": { - "es6-promise": "^4.0.3" - } - }, - "esbuild": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", - "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", - "dev": true, - "requires": { - "@esbuild/aix-ppc64": "0.20.2", - "@esbuild/android-arm": "0.20.2", - "@esbuild/android-arm64": "0.20.2", - "@esbuild/android-x64": "0.20.2", - "@esbuild/darwin-arm64": "0.20.2", - "@esbuild/darwin-x64": "0.20.2", - "@esbuild/freebsd-arm64": "0.20.2", - "@esbuild/freebsd-x64": "0.20.2", - "@esbuild/linux-arm": "0.20.2", - "@esbuild/linux-arm64": "0.20.2", - "@esbuild/linux-ia32": "0.20.2", - "@esbuild/linux-loong64": "0.20.2", - "@esbuild/linux-mips64el": "0.20.2", - "@esbuild/linux-ppc64": "0.20.2", - "@esbuild/linux-riscv64": "0.20.2", - "@esbuild/linux-s390x": "0.20.2", - "@esbuild/linux-x64": "0.20.2", - "@esbuild/netbsd-x64": "0.20.2", - "@esbuild/openbsd-x64": "0.20.2", - "@esbuild/sunos-x64": "0.20.2", - "@esbuild/win32-arm64": "0.20.2", - "@esbuild/win32-ia32": "0.20.2", - "@esbuild/win32-x64": "0.20.2" - } - }, - "escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "dev": true - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "dev": true - }, - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - }, - "eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, - "eslint-config-airbnb": { - "version": "19.0.4", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-19.0.4.tgz", - "integrity": "sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew==", - "dev": true, - "requires": { - "eslint-config-airbnb-base": "^15.0.0", - "object.assign": "^4.1.2", - "object.entries": "^1.1.5" - } - }, - "eslint-config-airbnb-base": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz", - "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==", - "dev": true, - "requires": { - "confusing-browser-globals": "^1.0.10", - "object.assign": "^4.1.2", - "object.entries": "^1.1.5", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "eslint-config-airbnb-typescript": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-18.0.0.tgz", - "integrity": "sha512-oc+Lxzgzsu8FQyFVa4QFaVKiitTYiiW3frB9KYW5OWdPrqFc7FzxgB20hP4cHMlr+MBzGcLl3jnCOVOydL9mIg==", - "dev": true, - "requires": { - "eslint-config-airbnb-base": "^15.0.0" - } - }, - "eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dev": true, - "requires": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "eslint-import-resolver-typescript": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz", - "integrity": "sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==", - "dev": true, - "requires": { - "debug": "^4.3.4", - "enhanced-resolve": "^5.12.0", - "eslint-module-utils": "^2.7.4", - "fast-glob": "^3.3.1", - "get-tsconfig": "^4.5.0", - "is-core-module": "^2.11.0", - "is-glob": "^4.0.3" - } - }, - "eslint-module-utils": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", - "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", - "dev": true, - "requires": { - "debug": "^3.2.7" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "eslint-plugin-chai-friendly": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-chai-friendly/-/eslint-plugin-chai-friendly-0.7.4.tgz", - "integrity": "sha512-PGPjJ8diYgX1mjLxGJqRop2rrGwZRKImoEOwUOgoIhg0p80MkTaqvmFLe5TF7/iagZHggasvIfQlUyHIhK/PYg==", - "dev": true, - "requires": {} - }, - "eslint-plugin-import": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", - "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", - "dev": true, - "requires": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", - "semver": "^6.3.1", - "tsconfig-paths": "^3.15.0" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "eslint-plugin-jsx-a11y": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.8.0.tgz", - "integrity": "sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==", - "dev": true, - "peer": true, - "requires": { - "@babel/runtime": "^7.23.2", - "aria-query": "^5.3.0", - "array-includes": "^3.1.7", - "array.prototype.flatmap": "^1.3.2", - "ast-types-flow": "^0.0.8", - "axe-core": "=4.7.0", - "axobject-query": "^3.2.1", - "damerau-levenshtein": "^1.0.8", - "emoji-regex": "^9.2.2", - "es-iterator-helpers": "^1.0.15", - "hasown": "^2.0.0", - "jsx-ast-utils": "^3.3.5", - "language-tags": "^1.0.9", - "minimatch": "^3.1.2", - "object.entries": "^1.1.7", - "object.fromentries": "^2.0.7" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "peer": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "peer": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, - "eslint-plugin-react": { - "version": "7.34.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.1.tgz", - "integrity": "sha512-N97CxlouPT1AHt8Jn0mhhN2RrADlUAsk1/atcT2KyA/l9Q/E6ll7OIGwNumFmWfZ9skV3XXccYS19h80rHtgkw==", - "dev": true, - "peer": true, - "requires": { - "array-includes": "^3.1.7", - "array.prototype.findlast": "^1.2.4", - "array.prototype.flatmap": "^1.3.2", - "array.prototype.toreversed": "^1.1.2", - "array.prototype.tosorted": "^1.1.3", - "doctrine": "^2.1.0", - "es-iterator-helpers": "^1.0.17", - "estraverse": "^5.3.0", - "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "minimatch": "^3.1.2", - "object.entries": "^1.1.7", - "object.fromentries": "^2.0.7", - "object.hasown": "^1.1.3", - "object.values": "^1.1.7", - "prop-types": "^15.8.1", - "resolve": "^2.0.0-next.5", - "semver": "^6.3.1", - "string.prototype.matchall": "^4.0.10" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "peer": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "peer": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "peer": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "resolve": { - "version": "2.0.0-next.5", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", - "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", - "dev": true, - "peer": true, - "requires": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "peer": true - } - } - }, - "eslint-plugin-react-hooks": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", - "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", - "dev": true, - "peer": true, - "requires": {} - }, - "eslint-plugin-unicorn": { - "version": "48.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-48.0.1.tgz", - "integrity": "sha512-FW+4r20myG/DqFcCSzoumaddKBicIPeFnTrifon2mWIzlfyvzwyqZjqVP7m4Cqr/ZYisS2aiLghkUWaPg6vtCw==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.22.5", - "@eslint-community/eslint-utils": "^4.4.0", - "ci-info": "^3.8.0", - "clean-regexp": "^1.0.0", - "esquery": "^1.5.0", - "indent-string": "^4.0.0", - "is-builtin-module": "^3.2.1", - "jsesc": "^3.0.2", - "lodash": "^4.17.21", - "pluralize": "^8.0.0", - "read-pkg-up": "^7.0.1", - "regexp-tree": "^0.1.27", - "regjsparser": "^0.10.0", - "semver": "^7.5.4", - "strip-indent": "^3.0.0" - } - }, - "eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true - }, - "espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "requires": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - } - }, - "esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, - "estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "event-stream": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", - "integrity": "sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==", - "dev": true, - "requires": { - "duplexer": "~0.1.1", - "from": "~0", - "map-stream": "~0.1.0", - "pause-stream": "0.0.11", - "split": "0.3", - "stream-combiner": "~0.0.4", - "through": "~2.3.1" - } - }, - "eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "dependencies": { - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - } - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "fflate": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.4.tgz", - "integrity": "sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==", - "dev": true - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - } - } - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true - }, - "flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "requires": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true - }, - "follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", - "dev": true - }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "requires": { - "is-callable": "^1.1.3" - } - }, - "foreground-child": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", - "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.0", - "signal-exit": "^3.0.2" - } - }, - "from": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", - "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==", - "dev": true - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true - }, - "function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - } - }, - "functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", - "dev": true - }, - "get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dev": true, - "requires": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - } - }, - "get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", - "dev": true, - "requires": { - "call-bind": "^1.0.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" - } - }, - "get-tsconfig": { - "version": "4.7.5", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.5.tgz", - "integrity": "sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==", - "dev": true, - "requires": { - "resolve-pkg-maps": "^1.0.0" - } - }, - "glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "dependencies": { - "minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } - } - }, - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "dev": true, - "requires": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - } - }, - "globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "dependencies": { - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - } - } - }, - "gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.3" - } - }, - "graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "graceful-readlink": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w==", - "dev": true - }, - "graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, - "requires": { - "es-define-property": "^1.0.0" - } - }, - "has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "dev": true - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true - }, - "has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.3" - } - }, - "hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, - "requires": { - "function-bind": "^1.1.2" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "html-encoding-sniffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", - "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", - "dev": true, - "requires": { - "whatwg-encoding": "^2.0.0" - } - }, - "html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dev": true, - "requires": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "dependencies": { - "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true - } - } - }, - "http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "dev": true, - "requires": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - } - }, - "http-server": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz", - "integrity": "sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==", - "dev": true, - "requires": { - "basic-auth": "^2.0.1", - "chalk": "^4.1.2", - "corser": "^2.0.1", - "he": "^1.2.0", - "html-encoding-sniffer": "^3.0.0", - "http-proxy": "^1.18.1", - "mime": "^1.6.0", - "minimist": "^1.2.6", - "opener": "^1.5.1", - "portfinder": "^1.0.28", - "secure-compare": "3.0.1", - "union": "~0.5.0", - "url-join": "^4.0.1" - } - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "dev": true, - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - }, - "dependencies": { - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "dev": true, - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true - }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", - "dev": true, - "requires": { - "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" - } - }, - "is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "is-async-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", - "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", - "dev": true, - "peer": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "requires": { - "has-bigints": "^1.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-builtin-module": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", - "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", - "dev": true, - "requires": { - "builtin-modules": "^3.3.0" - } - }, - "is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true - }, - "is-ci": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", - "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", - "dev": true, - "requires": { - "ci-info": "^3.2.0" - } - }, - "is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "dev": true, - "requires": { - "hasown": "^2.0.0" - } - }, - "is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", - "dev": true, - "requires": { - "is-typed-array": "^1.1.13" - } - }, - "is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true - }, - "is-finalizationregistry": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", - "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", - "dev": true, - "peer": true, - "requires": { - "call-bind": "^1.0.2" - } - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dev": true, - "peer": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", - "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", - "dev": true, - "peer": true - }, - "is-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", - "dev": true - }, - "is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "dev": true - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true - }, - "is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true - }, - "is-reference": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", - "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", - "dev": true, - "requires": { - "@types/estree": "*" - } - }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-running": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-running/-/is-running-2.1.0.tgz", - "integrity": "sha512-mjJd3PujZMl7j+D395WTIO5tU5RIDBfVSRtRR4VOJou3H66E38UjbjvDGh3slJzPuolsb+yQFqwHNNdyp5jg3w==", - "dev": true - }, - "is-set": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", - "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", - "dev": true, - "peer": true - }, - "is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", - "dev": true, - "requires": { - "call-bind": "^1.0.7" - } - }, - "is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", - "dev": true, - "requires": { - "which-typed-array": "^1.1.14" - } - }, - "is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true - }, - "is-weakmap": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", - "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", - "dev": true, - "peer": true - }, - "is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2" - } - }, - "is-weakset": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", - "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", - "dev": true, - "peer": true, - "requires": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4" - } - }, - "is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "requires": { - "is-docker": "^2.0.0" - } - }, - "isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true - }, - "isbinaryfile": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", - "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "dev": true - }, - "istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - } - }, - "istanbul-reports": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", - "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", - "dev": true, - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "iterator.prototype": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", - "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", - "dev": true, - "peer": true, - "requires": { - "define-properties": "^1.2.1", - "get-intrinsic": "^1.2.1", - "has-symbols": "^1.0.3", - "reflect.getprototypeof": "^1.0.4", - "set-function-name": "^2.0.1" - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "js2xmlparser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", - "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==", - "dev": true, - "requires": { - "xmlcreate": "^2.0.4" - } - }, - "jsesc": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", - "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", - "dev": true - }, - "json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsx-ast-utils": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", - "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", - "dev": true, - "peer": true, - "requires": { - "array-includes": "^3.1.6", - "array.prototype.flat": "^1.3.1", - "object.assign": "^4.1.4", - "object.values": "^1.1.6" - } - }, - "just-extend": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", - "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", - "dev": true - }, - "karma": { - "version": "6.4.3", - "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.3.tgz", - "integrity": "sha512-LuucC/RE92tJ8mlCwqEoRWXP38UMAqpnq98vktmS9SznSoUPPUJQbc91dHcxcunROvfQjdORVA/YFviH+Xci9Q==", - "dev": true, - "requires": { - "@colors/colors": "1.5.0", - "body-parser": "^1.19.0", - "braces": "^3.0.2", - "chokidar": "^3.5.1", - "connect": "^3.7.0", - "di": "^0.0.1", - "dom-serialize": "^2.2.1", - "glob": "^7.1.7", - "graceful-fs": "^4.2.6", - "http-proxy": "^1.18.1", - "isbinaryfile": "^4.0.8", - "lodash": "^4.17.21", - "log4js": "^6.4.1", - "mime": "^2.5.2", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.5", - "qjobs": "^1.2.0", - "range-parser": "^1.2.1", - "rimraf": "^3.0.2", - "socket.io": "^4.7.2", - "source-map": "^0.6.1", - "tmp": "^0.2.1", - "ua-parser-js": "^0.7.30", - "yargs": "^16.1.1" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", - "dev": true - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "requires": { - "minimist": "^1.2.6" - } - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - }, - "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true - } - } - }, - "karma-browserstack-launcher": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/karma-browserstack-launcher/-/karma-browserstack-launcher-1.6.0.tgz", - "integrity": "sha512-Y/UWPdHZkHIVH2To4GWHCTzmrsB6H7PBWy6pw+TWz5sr4HW2mcE+Uj6qWgoVNxvQU1Pfn5LQQzI6EQ65p8QbiQ==", - "dev": true, - "requires": { - "browserstack": "~1.5.1", - "browserstack-local": "^1.3.7", - "q": "~1.5.0" - } - }, - "karma-chrome-launcher": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.2.0.tgz", - "integrity": "sha512-rE9RkUPI7I9mAxByQWkGJFXfFD6lE4gC5nPuZdobf/QdTEJI6EU4yIay/cfU/xV4ZxlM5JiTv7zWYgA64NpS5Q==", - "dev": true, - "requires": { - "which": "^1.2.1" - }, - "dependencies": { - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "karma-firefox-launcher": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-2.1.3.tgz", - "integrity": "sha512-LMM2bseebLbYjODBOVt7TCPP9OI2vZIXCavIXhkO9m+10Uj5l7u/SKoeRmYx8FYHTVGZSpk6peX+3BMHC1WwNw==", - "dev": true, - "requires": { - "is-wsl": "^2.2.0", - "which": "^3.0.0" - }, - "dependencies": { - "which": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", - "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "karma-mocha": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/karma-mocha/-/karma-mocha-2.0.1.tgz", - "integrity": "sha512-Tzd5HBjm8his2OA4bouAsATYEpZrp9vC7z5E5j4C5Of5Rrs1jY67RAwXNcVmd/Bnk1wgvQRou0zGVLey44G4tQ==", - "dev": true, - "requires": { - "minimist": "^1.2.3" - } - }, - "karma-mocha-reporter": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/karma-mocha-reporter/-/karma-mocha-reporter-2.2.5.tgz", - "integrity": "sha512-Hr6nhkIp0GIJJrvzY8JFeHpQZNseuIakGac4bpw8K1+5F0tLb6l7uvXRa8mt2Z+NVwYgCct4QAfp2R2QP6o00w==", - "dev": true, - "requires": { - "chalk": "^2.1.0", - "log-symbols": "^2.1.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "karma-webkit-launcher": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/karma-webkit-launcher/-/karma-webkit-launcher-2.4.0.tgz", - "integrity": "sha512-k6fmeEwRt5PiPwb/B8stLNbtqcCqBcdMVUsep58da2uS0pEYr4X/RgP1/ThJK12Q6uispGgWVtDtp6O0hDOF+Q==", - "dev": true, - "requires": { - "is-ci": "^3.0.1", - "uuid": "^9.0.1" - } - }, - "keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "requires": { - "json-buffer": "3.0.1" - } - }, - "klaw": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", - "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.9" - } - }, - "language-subtag-registry": { - "version": "0.3.22", - "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", - "integrity": "sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==", - "dev": true, - "peer": true - }, - "language-tags": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", - "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", - "dev": true, - "peer": true, - "requires": { - "language-subtag-registry": "^0.3.20" - } - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "linkify-it": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", - "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", - "dev": true, - "requires": { - "uc.micro": "^1.0.1" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", - "dev": true - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", - "dev": true, - "requires": { - "chalk": "^2.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "log4js": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz", - "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==", - "dev": true, - "requires": { - "date-format": "^4.0.14", - "debug": "^4.3.4", - "flatted": "^3.2.7", - "rfdc": "^1.3.0", - "streamroller": "^3.1.5" - } - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "peer": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "loupe": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", - "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", - "dev": true, - "requires": { - "get-func-name": "^2.0.1" - } - }, - "magic-string": { - "version": "0.30.10", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", - "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", - "dev": true, - "requires": { - "@jridgewell/sourcemap-codec": "^1.4.15" - } - }, - "make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "dev": true, - "requires": { - "semver": "^7.5.3" - } - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "map-stream": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", - "integrity": "sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==", - "dev": true - }, - "markdown-it": { - "version": "12.3.2", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", - "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", - "dev": true, - "requires": { - "argparse": "^2.0.1", - "entities": "~2.1.0", - "linkify-it": "^3.0.1", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" - } - }, - "markdown-it-anchor": { - "version": "8.6.7", - "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz", - "integrity": "sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==", - "dev": true, - "requires": {} - }, - "marked": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", - "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", - "dev": true - }, - "mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", - "dev": true - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "dev": true - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "requires": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "requires": { - "mime-db": "1.52.0" - } - }, - "min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "dev": true - }, - "minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - }, - "minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, - "mocha": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.4.0.tgz", - "integrity": "sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA==", - "dev": true, - "requires": { - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.4", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "8.1.0", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "5.0.1", - "ms": "2.1.3", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "workerpool": "6.2.1", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "dependencies": { - "chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - } - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - } - }, - "minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - }, - "yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true - } - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "dev": true - }, - "nise": { - "version": "5.1.9", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.9.tgz", - "integrity": "sha512-qOnoujW4SV6e40dYxJOb3uvuoPHtmLzIk4TFo+j0jPJoC+5Z9xja5qH5JZobEPsa8+YYphMrOSwnrshEhG2qww==", - "dev": true, - "requires": { - "@sinonjs/commons": "^3.0.0", - "@sinonjs/fake-timers": "^11.2.2", - "@sinonjs/text-encoding": "^0.7.2", - "just-extend": "^6.2.0", - "path-to-regexp": "^6.2.1" - } - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true - }, - "object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - } - }, - "object.entries": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", - "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - } - }, - "object.fromentries": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", - "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" - } - }, - "object.groupby": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", - "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2" - } - }, - "object.hasown": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.4.tgz", - "integrity": "sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==", - "dev": true, - "peer": true, - "requires": { - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" - } - }, - "object.values": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", - "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - } - }, - "on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opener": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", - "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", - "dev": true - }, - "optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "path-to-regexp": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", - "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", - "dev": true - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true - }, - "pause-stream": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", - "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==", - "dev": true, - "requires": { - "through": "~2.3" - } - }, - "picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - }, - "platform": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz", - "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==", - "dev": true - }, - "playwright": { - "version": "1.44.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.44.0.tgz", - "integrity": "sha512-F9b3GUCLQ3Nffrfb6dunPOkE5Mh68tR7zN32L4jCk4FjQamgesGay7/dAAe1WaMEGV04DkdJfcJzjoCKygUaRQ==", - "dev": true, - "requires": { - "fsevents": "2.3.2", - "playwright-core": "1.44.0" - }, - "dependencies": { - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - } - } - }, - "playwright-core": { - "version": "1.44.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.44.0.tgz", - "integrity": "sha512-ZTbkNpFfYcGWohvTTl+xewITm7EOuqIqex0c7dNZ+aXsbrLj0qI8XlGKfPpipjm0Wny/4Lt4CJsWJk1stVS5qQ==", - "dev": true - }, - "pluralize": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", - "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", - "dev": true - }, - "portfinder": { - "version": "1.0.32", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz", - "integrity": "sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==", - "dev": true, - "requires": { - "async": "^2.6.4", - "debug": "^3.2.7", - "mkdirp": "^0.5.6" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "requires": { - "minimist": "^1.2.6" - } - } - } - }, - "possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", - "dev": true - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, - "peer": true, - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - } - }, - "ps-tree": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz", - "integrity": "sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==", - "dev": true, - "requires": { - "event-stream": "=3.3.4" - } - }, - "punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", - "dev": true - }, - "qjobs": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", - "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", - "dev": true - }, - "qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true - }, - "raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "dev": true, - "requires": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true, - "peer": true - }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } - } - }, - "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true - } - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "reflect.getprototypeof": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", - "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", - "dev": true, - "peer": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.1", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "globalthis": "^1.0.3", - "which-builtin-type": "^1.1.3" - } - }, - "regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "dev": true, - "peer": true - }, - "regexp-tree": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", - "integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==", - "dev": true - }, - "regexp.prototype.flags": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", - "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", - "dev": true, - "requires": { - "call-bind": "^1.0.6", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "set-function-name": "^2.0.1" - } - }, - "regjsparser": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.10.0.tgz", - "integrity": "sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==", - "dev": true, - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", - "dev": true - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true - }, - "requizzle": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.4.tgz", - "integrity": "sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==", - "dev": true, - "requires": { - "lodash": "^4.17.21" - } - }, - "resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, - "requires": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "resolve-pkg-maps": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", - "dev": true - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rfdc": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.1.tgz", - "integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, - "rollup": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.17.2.tgz", - "integrity": "sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==", - "dev": true, - "requires": { - "@rollup/rollup-android-arm-eabi": "4.17.2", - "@rollup/rollup-android-arm64": "4.17.2", - "@rollup/rollup-darwin-arm64": "4.17.2", - "@rollup/rollup-darwin-x64": "4.17.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.17.2", - "@rollup/rollup-linux-arm-musleabihf": "4.17.2", - "@rollup/rollup-linux-arm64-gnu": "4.17.2", - "@rollup/rollup-linux-arm64-musl": "4.17.2", - "@rollup/rollup-linux-powerpc64le-gnu": "4.17.2", - "@rollup/rollup-linux-riscv64-gnu": "4.17.2", - "@rollup/rollup-linux-s390x-gnu": "4.17.2", - "@rollup/rollup-linux-x64-gnu": "4.17.2", - "@rollup/rollup-linux-x64-musl": "4.17.2", - "@rollup/rollup-win32-arm64-msvc": "4.17.2", - "@rollup/rollup-win32-ia32-msvc": "4.17.2", - "@rollup/rollup-win32-x64-msvc": "4.17.2", - "@types/estree": "1.0.5", - "fsevents": "~2.3.2" - } - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "safe-regex-test": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", - "dev": true, - "requires": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-regex": "^1.1.4" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "secure-compare": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", - "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==", - "dev": true - }, - "semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", - "dev": true - }, - "serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dev": true, - "requires": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - } - }, - "set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "dev": true, - "requires": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - } - }, - "setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - } - }, - "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "sinon": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.1.tgz", - "integrity": "sha512-wmwE19Lie0MLT+ZYNpDymasPHUKTaZHUH/pKEubRXIzySv9Atnlw+BUMGCzWgV7b7wO+Hw6f1TEOr0IUnmU8/g==", - "dev": true, - "requires": { - "@sinonjs/commons": "^3.0.0", - "@sinonjs/fake-timers": "^11.2.2", - "@sinonjs/samsam": "^8.0.0", - "diff": "^5.1.0", - "nise": "^5.1.5", - "supports-color": "^7.2.0" - }, - "dependencies": { - "diff": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", - "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", - "dev": true - } - } - }, - "slash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", - "dev": true - }, - "smob": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz", - "integrity": "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==", - "dev": true - }, - "socket.io": { - "version": "4.7.5", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz", - "integrity": "sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==", - "dev": true, - "requires": { - "accepts": "~1.3.4", - "base64id": "~2.0.0", - "cors": "~2.8.5", - "debug": "~4.3.2", - "engine.io": "~6.5.2", - "socket.io-adapter": "~2.5.2", - "socket.io-parser": "~4.2.4" - } - }, - "socket.io-adapter": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz", - "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", - "dev": true, - "requires": { - "debug": "~4.3.4", - "ws": "~8.17.1" - } - }, - "socket.io-parser": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", - "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", - "dev": true, - "requires": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", - "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz", - "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==", - "dev": true - }, - "split": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", - "integrity": "sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==", - "dev": true, - "requires": { - "through": "2" - } - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", - "dev": true - }, - "stream-combiner": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", - "integrity": "sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==", - "dev": true, - "requires": { - "duplexer": "~0.1.1" - } - }, - "streamroller": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz", - "integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==", - "dev": true, - "requires": { - "date-format": "^4.0.14", - "debug": "^4.3.4", - "fs-extra": "^8.1.0" - } - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - } - } - }, - "string.prototype.matchall": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", - "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", - "dev": true, - "peer": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.7", - "regexp.prototype.flags": "^1.5.2", - "set-function-name": "^2.0.2", - "side-channel": "^1.0.6" - } - }, - "string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" - } - }, - "string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - } - }, - "string.prototype.trimstart": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true - }, - "strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "dev": true, - "requires": { - "min-indent": "^1.0.0" - } - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true - }, - "taffydb": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz", - "integrity": "sha512-y3JaeRSplks6NYQuCOj3ZFMO3j60rTwbuKCvZxsAraGYH2epusatvZ0baZYA01WsGqJBq/Dl6vOrMUJqyMj8kA==", - "dev": true - }, - "tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true - }, - "temp-fs": { - "version": "0.9.9", - "resolved": "https://registry.npmjs.org/temp-fs/-/temp-fs-0.9.9.tgz", - "integrity": "sha512-WfecDCR1xC9b0nsrzSaxPf3ZuWeWLUWblW4vlDQAa1biQaKHiImHnJfeQocQe/hXKMcolRzgkcVX/7kK4zoWbw==", - "dev": true, - "requires": { - "rimraf": "~2.5.2" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "rimraf": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz", - "integrity": "sha512-Lw7SHMjssciQb/rRz7JyPIy9+bbUshEucPoLRvWqy09vC5zQixl8Uet+Zl+SROBB/JMWHJRdCk1qdxNWHNMvlQ==", - "dev": true, - "requires": { - "glob": "^7.0.5" - } - } - } - }, - "terser": { - "version": "5.31.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.0.tgz", - "integrity": "sha512-Q1JFAoUKE5IMfI4Z/lkE/E6+SwgzO+x4tq4v1AyBLRj8VSYvRO6A/rQrPg1yud4g0En9EKI1TvFRF2tQFcoUkg==", - "dev": true, - "requires": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } - } - }, - "test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "requires": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, - "tmp": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", - "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", - "dev": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "dev": true - }, - "ts-api-utils": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", - "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", - "dev": true, - "requires": {} - }, - "ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, - "requires": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "dependencies": { - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - } - } - }, - "tsconfig-paths": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", - "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", - "dev": true, - "requires": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", - "dev": true - }, - "tsx": { - "version": "4.10.4", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.10.4.tgz", - "integrity": "sha512-Gtg9qnZWNqC/OtcgiXfoAUdAKx3/cgKOYvEocAsv+m21MV/eKpV/WUjRXe6/sDCaGBl2/v8S6v29BpUnGMCX5A==", - "dev": true, - "requires": { - "esbuild": "~0.20.2", - "fsevents": "~2.3.3", - "get-tsconfig": "^4.7.5" - } - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" - } - }, - "typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - } - }, - "typed-array-byte-offset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - } - }, - "typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" - } - }, - "typescript": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", - "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", - "dev": true - }, - "ua-parser-js": { - "version": "0.7.37", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.37.tgz", - "integrity": "sha512-xV8kqRKM+jhMvcHWUKthV9fNebIzrNy//2O9ZwWcfiBFR5f25XVZPLlEajk/sf3Ra15V92isyQqnIEXRDaZWEA==", - "dev": true - }, - "uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", - "dev": true - }, - "unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - } - }, - "underscore": { - "version": "1.13.6", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", - "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", - "dev": true - }, - "undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true - }, - "union": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", - "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==", - "dev": true, - "requires": { - "qs": "^6.4.0" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "dev": true - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "url-join": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", - "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", - "dev": true - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "dev": true - }, - "uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "dev": true - }, - "v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, - "v8-to-istanbul": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", - "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "^0.3.12", - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^2.0.0" - } - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "dev": true - }, - "void-elements": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", - "integrity": "sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==", - "dev": true - }, - "web-streams-polyfill": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0.tgz", - "integrity": "sha512-0zJXHRAYEjM2tUfZ2DiSOHAa2aw1tisnnhU3ufD57R8iefL+DcdJyRBRyJpG+NUimDgbTI/lH+gAE1PAvV3Cgw==", - "dev": true - }, - "whatwg-encoding": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", - "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", - "dev": true, - "requires": { - "iconv-lite": "0.6.3" - }, - "dependencies": { - "iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - } - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "which-builtin-type": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz", - "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==", - "dev": true, - "peer": true, - "requires": { - "function.prototype.name": "^1.1.5", - "has-tostringtag": "^1.0.0", - "is-async-function": "^2.0.0", - "is-date-object": "^1.0.5", - "is-finalizationregistry": "^1.0.2", - "is-generator-function": "^1.0.10", - "is-regex": "^1.1.4", - "is-weakref": "^1.0.2", - "isarray": "^2.0.5", - "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.9" - } - }, - "which-collection": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", - "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", - "dev": true, - "peer": true, - "requires": { - "is-map": "^2.0.3", - "is-set": "^2.0.3", - "is-weakmap": "^2.0.2", - "is-weakset": "^2.0.3" - } - }, - "which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.2" - } - }, - "word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true - }, - "workerpool": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", - "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", - "dev": true - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "ws": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", - "dev": true, - "requires": {} - }, - "xmlcreate": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", - "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", - "dev": true - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "requires": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - } - }, - "yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true - }, - "yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "requires": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - } - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true - } } } diff --git a/package.json b/package.json index 89ad6293..242c31cf 100644 --- a/package.json +++ b/package.json @@ -63,21 +63,21 @@ }, "devDependencies": { "@noble/ciphers": "^0.6.0", - "@noble/curves": "^1.4.0", - "@noble/hashes": "^1.4.0", + "@noble/curves": "^1.6.0", + "@noble/hashes": "^1.5.0", "@openpgp/jsdoc": "^3.6.11", "@openpgp/seek-bzip": "^1.0.5-git", "@openpgp/tweetnacl": "^1.0.4-1", "@openpgp/web-stream-tools": "~0.1.3", "@rollup/plugin-alias": "^5.1.0", - "@rollup/plugin-commonjs": "^25.0.7", + "@rollup/plugin-commonjs": "^25.0.8", "@rollup/plugin-node-resolve": "^15.2.3", - "@rollup/plugin-replace": "^5.0.5", + "@rollup/plugin-replace": "^5.0.7", "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-typescript": "^11.1.6", "@rollup/plugin-wasm": "^6.2.2", - "@types/chai": "^4.3.16", - "@typescript-eslint/parser": "^7.9.0", + "@types/chai": "^4.3.19", + "@typescript-eslint/parser": "^7.18.0", "argon2id": "^1.0.1", "benchmark": "^2.1.4", "bn.js": "^5.2.1", @@ -89,27 +89,27 @@ "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-airbnb-typescript": "^18.0.0", - "eslint-import-resolver-typescript": "^3.6.1", + "eslint-import-resolver-typescript": "^3.6.3", "eslint-plugin-chai-friendly": "^0.7.4", - "eslint-plugin-import": "^2.29.1", + "eslint-plugin-import": "^2.30.0", "eslint-plugin-unicorn": "^48.0.1", "fflate": "^0.7.4", "http-server": "^14.1.1", - "karma": "^6.4.3", + "karma": "^6.4.4", "karma-browserstack-launcher": "^1.6.0", "karma-chrome-launcher": "^3.2.0", "karma-firefox-launcher": "^2.1.3", "karma-mocha": "^2.0.1", "karma-mocha-reporter": "^2.2.5", - "karma-webkit-launcher": "^2.4.0", - "mocha": "^10.4.0", - "playwright": "^1.44.0", - "rollup": "^4.17.2", + "karma-webkit-launcher": "^2.6.0", + "mocha": "^10.7.3", + "playwright": "^1.46.1", + "rollup": "^4.21.2", "sinon": "^17.0.1", "ts-node": "^10.9.2", - "tslib": "^2.6.2", - "tsx": "^4.10.4", - "typescript": "^5.5.2", + "tslib": "^2.7.0", + "tsx": "^4.19.0", + "typescript": "^5.5.4", "web-streams-polyfill": "^4.0.0" }, "repository": { From 1bcce67c68de7aff28e3d822e1e4bc06608f6027 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Wed, 4 Sep 2024 17:58:27 +0200 Subject: [PATCH 171/201] CI: test also on Node 22 --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index fad99b2d..8b9ce5fe 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -31,7 +31,7 @@ jobs: strategy: fail-fast: false # if tests for one version fail, continue with the rest matrix: - node-version: [18.x, 20.x] + node-version: [18.x, 20.x, 22.x] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ name: Node ${{ matrix.node-version }} From a3839f6db5aad673f14d6fa35df4010f82fae965 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Thu, 5 Sep 2024 13:24:51 +0200 Subject: [PATCH 172/201] 6.0.0-beta.3 --- docs/AEADEncryptedDataPacket.html | 14 +- docs/Argon2S2K.html | 16 +- docs/CleartextMessage.html | 12 +- docs/CompressedDataPacket.html | 16 +- docs/Key.html | 56 ++-- docs/LiteralDataPacket.html | 20 +- docs/MarkerPacket.html | 4 +- docs/Message.html | 40 +-- docs/OnePassSignaturePacket.html | 22 +- docs/PacketList.html | 14 +- docs/PaddingPacket.html | 8 +- docs/PrivateKey.html | 49 ++- docs/PublicKey.html | 8 +- docs/PublicKeyEncryptedSessionKeyPacket.html | 14 +- docs/PublicKeyPacket.html | 46 +-- docs/PublicSubkeyPacket.html | 46 +-- docs/SecretKeyPacket.html | 72 ++--- docs/SecretSubkeyPacket.html | 72 ++--- docs/Signature.html | 8 +- docs/SignaturePacket.html | 24 +- ...EncryptedIntegrityProtectedDataPacket.html | 10 +- docs/SymEncryptedSessionKeyPacket.html | 16 +- docs/SymmetricallyEncryptedDataPacket.html | 10 +- docs/TrustPacket.html | 4 +- docs/UserAttributePacket.html | 8 +- docs/UserIDPacket.html | 10 +- docs/global.html | 72 ++--- docs/index.html | 27 +- docs/module-config.html | 66 ++-- docs/module-crypto.html | 2 +- docs/module-crypto_aes_kw.html | 6 +- docs/module-crypto_cmac.html | 6 +- docs/module-crypto_crypto.html | 30 +- docs/module-crypto_hash.html | 8 +- docs/module-crypto_hkdf.html | 2 +- docs/module-crypto_mode.html | 10 +- docs/module-crypto_mode_cfb.html | 4 +- docs/module-crypto_mode_eax.html | 8 +- docs/module-crypto_mode_gcm.html | 4 +- docs/module-crypto_mode_ocb.html | 8 +- docs/module-crypto_pkcs1.html | 10 +- docs/module-crypto_public_key.html | 10 +- docs/module-crypto_public_key_dsa.html | 10 +- docs/module-crypto_public_key_elgamal.html | 10 +- docs/module-crypto_public_key_elliptic.html | 2 +- ...dule-crypto_public_key_elliptic_curve.html | 14 +- ...odule-crypto_public_key_elliptic_ecdh.html | 284 ++++++++++++++++-- ...dule-crypto_public_key_elliptic_ecdsa.html | 10 +- ...dule-crypto_public_key_elliptic_eddsa.html | 10 +- ...ypto_public_key_elliptic_eddsa_legacy.html | 8 +- docs/module-crypto_public_key_rsa.html | 20 +- docs/module-crypto_random.html | 6 +- docs/module-crypto_signature.html | 8 +- docs/module-encoding_base64.html | 8 +- docs/module-enums.html | 36 +-- docs/module-key_Subkey-Subkey.html | 40 +-- docs/module-key_User-User.html | 20 +- docs/module-key_helper.html | 22 +- docs/module-packet_packet.html | 10 +- docs/module-type_ecdh_symkey.html | 2 +- docs/module-type_kdf_params-KDFParams.html | 6 +- docs/module-type_keyid-KeyID.html | 14 +- docs/module-type_oid.html | 2 +- docs/module-type_s2k-GenericS2K.html | 16 +- docs/module-type_s2k.html | 2 +- docs/module-type_x25519x448_symkey.html | 2 +- docs/module-util.html | 2 +- package-lock.json | 4 +- package.json | 2 +- 69 files changed, 857 insertions(+), 605 deletions(-) diff --git a/docs/AEADEncryptedDataPacket.html b/docs/AEADEncryptedDataPacket.html index 7c3364c2..ec729f0d 100644 --- a/docs/AEADEncryptedDataPacket.html +++ b/docs/AEADEncryptedDataPacket.html @@ -98,7 +98,7 @@ AEAD Protected Data Packet

      Source:
      @@ -200,7 +200,7 @@ AEAD Protected Data Packet

      Source:
      @@ -270,7 +270,7 @@ AEAD Protected Data Packet

      Source:
      @@ -475,7 +475,7 @@ AEAD Protected Data Packet

      Source:
      @@ -717,7 +717,7 @@ AEAD Protected Data Packet

      Source:
      @@ -888,7 +888,7 @@ AEAD Protected Data Packet

      Source:
      @@ -1007,7 +1007,7 @@ AEAD Protected Data Packet

      Source:
      diff --git a/docs/Argon2S2K.html b/docs/Argon2S2K.html index 80020ce8..799219d2 100644 --- a/docs/Argon2S2K.html +++ b/docs/Argon2S2K.html @@ -152,7 +152,7 @@
      Source:
      @@ -258,7 +258,7 @@
      Source:
      @@ -332,7 +332,7 @@
      Source:
      @@ -406,7 +406,7 @@
      Source:
      @@ -480,7 +480,7 @@
      Source:
      @@ -612,7 +612,7 @@ hashAlgorithm

      Source:
      @@ -791,7 +791,7 @@ hashAlgorithm

      Source:
      @@ -903,7 +903,7 @@ hashAlgorithm

      Source:
      diff --git a/docs/CleartextMessage.html b/docs/CleartextMessage.html index 64d9974f..e633180f 100644 --- a/docs/CleartextMessage.html +++ b/docs/CleartextMessage.html @@ -168,7 +168,7 @@ See https://tools.ietf.o
      Source:
      @@ -346,7 +346,7 @@ See https://tools.ietf.o
      Source:
      @@ -461,7 +461,7 @@ See https://tools.ietf.o
      Source:
      @@ -573,7 +573,7 @@ See https://tools.ietf.o
      Source:
      @@ -974,7 +974,7 @@ See https://tools.ietf.o
      Source:
      @@ -1211,7 +1211,7 @@ See https://tools.ietf.o
      Source:
      diff --git a/docs/CompressedDataPacket.html b/docs/CompressedDataPacket.html index 8485f380..32ce9a61 100644 --- a/docs/CompressedDataPacket.html +++ b/docs/CompressedDataPacket.html @@ -160,7 +160,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

      Source:
      @@ -266,7 +266,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

      Source:
      @@ -343,7 +343,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

      Source:
      @@ -417,7 +417,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

      Source:
      @@ -499,7 +499,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

      Source:
      @@ -651,7 +651,7 @@ read by read_packet

      Source:
      @@ -836,7 +836,7 @@ read by read_packet

      Source:
      @@ -926,7 +926,7 @@ read by read_packet

      Source:
      diff --git a/docs/Key.html b/docs/Key.html index f8623449..483230a2 100644 --- a/docs/Key.html +++ b/docs/Key.html @@ -96,7 +96,7 @@ Can contain additional subkeys, signatures, user ids, user attributes.

      Source:
      @@ -333,7 +333,7 @@ if it is a valid revocation signature.

      Source:
      @@ -514,7 +514,7 @@ if it is a valid revocation signature.

      Source:
      @@ -626,7 +626,7 @@ if it is a valid revocation signature.

      Source:
      @@ -738,7 +738,7 @@ if it is a valid revocation signature.

      Source:
      @@ -1006,7 +1006,7 @@ if it is a valid revocation signature.

      Source:
      @@ -1225,7 +1225,7 @@ Returns Infinity if the key doesn't expire, or null if
      Source:
      @@ -1333,7 +1333,7 @@ Returns Infinity if the key doesn't expire, or null if
      Source:
      @@ -1445,7 +1445,7 @@ Returns Infinity if the key doesn't expire, or null if
      Source:
      @@ -1557,7 +1557,7 @@ Returns Infinity if the key doesn't expire, or null if
      Source:
      @@ -1735,7 +1735,7 @@ If no keyID is given, returns all keys, starting with the primary key.

      Source:
      @@ -1977,7 +1977,7 @@ algorithm preferences, and so on.

      Source:
      @@ -2220,7 +2220,7 @@ algorithm preferences, and so on.

      Source:
      @@ -2425,7 +2425,7 @@ algorithm preferences, and so on.

      Source:
      @@ -2717,7 +2717,7 @@ algorithm preferences, and so on.

      Source:
      @@ -2911,7 +2911,7 @@ If no keyID is given, returns all subkeys.

      Source:
      @@ -3023,7 +3023,7 @@ If no keyID is given, returns all subkeys.

      Source:
      @@ -3135,7 +3135,7 @@ If no keyID is given, returns all subkeys.

      Source:
      @@ -3412,7 +3412,7 @@ If no keyID is given, returns all subkeys.

      Source:
      @@ -3596,7 +3596,7 @@ If no keyID is given, returns all subkeys.

      Source:
      @@ -3811,7 +3811,7 @@ If no keyID is given, returns all subkeys.

      Source:
      @@ -4081,7 +4081,7 @@ If no keyID is given, returns all subkeys.

      Source:
      @@ -4193,7 +4193,7 @@ If no keyID is given, returns all subkeys.

      Source:
      @@ -4434,7 +4434,7 @@ a private key is returned.

      Source:
      @@ -4677,7 +4677,7 @@ a private key is returned.

      Source:
      @@ -4918,7 +4918,7 @@ and valid self signature. Throws if the primary key is invalid.

      Source:
      @@ -5201,7 +5201,7 @@ and valid self signature. Throws if the primary key is invalid.

      Source:
      @@ -5314,7 +5314,7 @@ Signature validity is null if the verification keys do not correspond to the cer
      Source:
      diff --git a/docs/LiteralDataPacket.html b/docs/LiteralDataPacket.html index 55048840..897b13a1 100644 --- a/docs/LiteralDataPacket.html +++ b/docs/LiteralDataPacket.html @@ -147,7 +147,7 @@ further interpreted.

      Source:
      @@ -326,7 +326,7 @@ further interpreted.

      Source:
      @@ -441,7 +441,7 @@ further interpreted.

      Source:
      @@ -623,7 +623,7 @@ with normalized end of line to \n

      Source:
      @@ -790,7 +790,7 @@ with normalized end of line to \n

      Source:
      @@ -977,7 +977,7 @@ with normalized end of line to \n

      Source:
      @@ -1116,7 +1116,7 @@ with normalized end of line to \n

      Source:
      @@ -1302,7 +1302,7 @@ will be normalized to \r\n and by default text is converted to UTF8

      Source:
      @@ -1392,7 +1392,7 @@ will be normalized to \r\n and by default text is converted to UTF8

      Source:
      @@ -1507,7 +1507,7 @@ will be normalized to \r\n and by default text is converted to UTF8

      Source:
      diff --git a/docs/MarkerPacket.html b/docs/MarkerPacket.html index 2db07b12..b457d8da 100644 --- a/docs/MarkerPacket.html +++ b/docs/MarkerPacket.html @@ -106,7 +106,7 @@ software is necessary to process the message.

      Source:
      @@ -265,7 +265,7 @@ software is necessary to process the message.

      Source:
      diff --git a/docs/Message.html b/docs/Message.html index 17b36998..2df92a9c 100644 --- a/docs/Message.html +++ b/docs/Message.html @@ -146,7 +146,7 @@ See https://tools.iet
      Source:
      @@ -661,7 +661,7 @@ See https://tools.iet
      Source:
      @@ -933,7 +933,7 @@ See https://tools.iet
      Source:
      @@ -1140,7 +1140,7 @@ See https://tools.iet
      Source:
      @@ -1291,7 +1291,7 @@ See https://tools.iet
      Source:
      @@ -1495,7 +1495,7 @@ See https://tools.iet
      Source:
      @@ -1800,7 +1800,7 @@ See https://tools.iet
      Source:
      @@ -2105,7 +2105,7 @@ See https://tools.iet
      Source:
      @@ -2545,7 +2545,7 @@ See https://tools.iet
      Source:
      @@ -2657,7 +2657,7 @@ See https://tools.iet
      Source:
      @@ -2769,7 +2769,7 @@ See https://tools.iet
      Source:
      @@ -2884,7 +2884,7 @@ See https://tools.iet
      Source:
      @@ -2999,7 +2999,7 @@ See https://tools.iet
      Source:
      @@ -3111,7 +3111,7 @@ See https://tools.iet
      Source:
      @@ -3515,7 +3515,7 @@ See https://tools.iet
      Source:
      @@ -3916,7 +3916,7 @@ See https://tools.iet
      Source:
      @@ -4028,7 +4028,7 @@ See https://tools.iet
      Source:
      @@ -4265,7 +4265,7 @@ See https://tools.iet
      Source:
      @@ -4531,7 +4531,7 @@ See https://tools.iet
      Source:
      @@ -4643,7 +4643,7 @@ See https://tools.iet
      Source:
      diff --git a/docs/OnePassSignaturePacket.html b/docs/OnePassSignaturePacket.html index be20f102..a8292484 100644 --- a/docs/OnePassSignaturePacket.html +++ b/docs/OnePassSignaturePacket.html @@ -101,7 +101,7 @@ can compute the entire signed message in one pass.

      Source:
      @@ -199,7 +199,7 @@ that describes another signature to be applied to the same message data.

      Source:
      @@ -273,7 +273,7 @@ that describes another signature to be applied to the same message data.

      Source:
      @@ -344,7 +344,7 @@ that describes another signature to be applied to the same message data.

      Source:
      @@ -408,7 +408,7 @@ that describes another signature to be applied to the same message data.

      Source:
      @@ -482,7 +482,7 @@ that describes another signature to be applied to the same message data.

      Source:
      @@ -553,7 +553,7 @@ that describes another signature to be applied to the same message data.

      Source:
      @@ -629,7 +629,7 @@ Signature types are described in
      Source:
      @@ -693,7 +693,7 @@ Signature types are described in
      Source:
      @@ -824,7 +824,7 @@ Signature types are described in
      Source:
      @@ -936,7 +936,7 @@ Signature types are described in
      Source:
      diff --git a/docs/PacketList.html b/docs/PacketList.html index da633f5c..4a5b94dc 100644 --- a/docs/PacketList.html +++ b/docs/PacketList.html @@ -97,7 +97,7 @@ are stored as numerical indices.

      Source:
      @@ -345,7 +345,7 @@ Equivalent to calling read on an empty PacketList instance.

      Source:
      @@ -530,7 +530,7 @@ Equivalent to calling read on an empty PacketList instance.

      Source:
      @@ -687,7 +687,7 @@ Equivalent to calling read on an empty PacketList instance.

      Source:
      @@ -859,7 +859,7 @@ Equivalent to calling read on an empty PacketList instance.

      Source:
      @@ -1097,7 +1097,7 @@ Equivalent to calling read on an empty PacketList instance.

      Source:
      @@ -1200,7 +1200,7 @@ class instance.

      Source:
      diff --git a/docs/PaddingPacket.html b/docs/PaddingPacket.html index 96cdc345..2ec9a895 100644 --- a/docs/PaddingPacket.html +++ b/docs/PaddingPacket.html @@ -97,7 +97,7 @@ Padding Packet

      Source:
      @@ -256,7 +256,7 @@ Padding Packet

      Source:
      @@ -427,7 +427,7 @@ Padding Packet

      Source:
      @@ -517,7 +517,7 @@ Padding Packet

      Source:
      diff --git a/docs/PrivateKey.html b/docs/PrivateKey.html index 389ec78f..177a0eb5 100644 --- a/docs/PrivateKey.html +++ b/docs/PrivateKey.html @@ -144,7 +144,7 @@
      Source:
      @@ -453,7 +453,7 @@ Note: Curve448 and Curve25519 are not widely supported yet.

      Source:
      @@ -622,7 +622,7 @@ Note: Curve448 and Curve25519 are not widely supported yet.

      Source:
      @@ -734,7 +734,7 @@ Note: Curve448 and Curve25519 are not widely supported yet.

      Source:
      @@ -979,7 +979,7 @@ This is useful to retrieve keys for session key decryption

      Source:
      @@ -1002,6 +1002,35 @@ This is useful to retrieve keys for session key decryption

      +
      Throws:
      + + + +
      +
      +
      +

      if no decryption key is found

      +
      +
      +
      +
      +
      +
      + Type +
      +
      + +Error + + +
      +
      +
      +
      +
      + + +
      Returns:
      @@ -1092,7 +1121,7 @@ A dummy key is considered encrypted.

      Source:
      @@ -1182,7 +1211,7 @@ A dummy key is considered encrypted.

      Source:
      @@ -1485,7 +1514,7 @@ A dummy key is considered encrypted.

      Source:
      @@ -1597,7 +1626,7 @@ A dummy key is considered encrypted.

      Source:
      @@ -1774,7 +1803,7 @@ If only gnu-dummy keys are found, we cannot properly validate so we throw an err
      Source:
      diff --git a/docs/PublicKey.html b/docs/PublicKey.html index 65b93cac..3299e23b 100644 --- a/docs/PublicKey.html +++ b/docs/PublicKey.html @@ -144,7 +144,7 @@
      Source:
      @@ -315,7 +315,7 @@
      Source:
      @@ -427,7 +427,7 @@
      Source:
      @@ -535,7 +535,7 @@
      Source:
      diff --git a/docs/PublicKeyEncryptedSessionKeyPacket.html b/docs/PublicKeyEncryptedSessionKeyPacket.html index aefcc673..c561875d 100644 --- a/docs/PublicKeyEncryptedSessionKeyPacket.html +++ b/docs/PublicKeyEncryptedSessionKeyPacket.html @@ -107,7 +107,7 @@ decrypt the message.

      Source:
      @@ -209,7 +209,7 @@ decrypt the message.

      Source:
      @@ -283,7 +283,7 @@ decrypt the message.

      Source:
      @@ -458,7 +458,7 @@ This is needed for constant-time processing. Expected object of the form: { sess
      Source:
      @@ -626,7 +626,7 @@ This is needed for constant-time processing. Expected object of the form: { sess
      Source:
      @@ -794,7 +794,7 @@ This is needed for constant-time processing. Expected object of the form: { sess
      Source:
      @@ -884,7 +884,7 @@ This is needed for constant-time processing. Expected object of the form: { sess
      Source:
      diff --git a/docs/PublicKeyPacket.html b/docs/PublicKeyPacket.html index a762bc19..aa97adde 100644 --- a/docs/PublicKeyPacket.html +++ b/docs/PublicKeyPacket.html @@ -195,7 +195,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -301,7 +301,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -375,7 +375,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -449,7 +449,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -523,7 +523,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -597,7 +597,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -671,7 +671,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -735,7 +735,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -816,7 +816,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -880,7 +880,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -1018,7 +1018,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -1130,7 +1130,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -1220,7 +1220,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -1310,7 +1310,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -1422,7 +1422,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -1530,7 +1530,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -1642,7 +1642,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -1754,7 +1754,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -1866,7 +1866,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -1978,7 +1978,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -2138,7 +2138,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -2250,7 +2250,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -2411,7 +2411,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      diff --git a/docs/PublicSubkeyPacket.html b/docs/PublicSubkeyPacket.html index 8d4a64e2..76b527d4 100644 --- a/docs/PublicSubkeyPacket.html +++ b/docs/PublicSubkeyPacket.html @@ -193,7 +193,7 @@ services.

      Source:
      @@ -315,7 +315,7 @@ services.

      Source:
      @@ -394,7 +394,7 @@ services.

      Source:
      @@ -473,7 +473,7 @@ services.

      Source:
      @@ -552,7 +552,7 @@ services.

      Source:
      @@ -631,7 +631,7 @@ services.

      Source:
      @@ -710,7 +710,7 @@ services.

      Source:
      @@ -779,7 +779,7 @@ services.

      Source:
      @@ -865,7 +865,7 @@ services.

      Source:
      @@ -934,7 +934,7 @@ services.

      Source:
      @@ -1072,7 +1072,7 @@ services.

      Source:
      @@ -1189,7 +1189,7 @@ services.

      Source:
      @@ -1284,7 +1284,7 @@ services.

      Source:
      @@ -1379,7 +1379,7 @@ services.

      Source:
      @@ -1496,7 +1496,7 @@ services.

      Source:
      @@ -1609,7 +1609,7 @@ services.

      Source:
      @@ -1726,7 +1726,7 @@ services.

      Source:
      @@ -1843,7 +1843,7 @@ services.

      Source:
      @@ -1960,7 +1960,7 @@ services.

      Source:
      @@ -2077,7 +2077,7 @@ services.

      Source:
      @@ -2242,7 +2242,7 @@ services.

      Source:
      @@ -2359,7 +2359,7 @@ services.

      Source:
      @@ -2525,7 +2525,7 @@ services.

      Source:
      diff --git a/docs/SecretKeyPacket.html b/docs/SecretKeyPacket.html index 891d1460..9902d76c 100644 --- a/docs/SecretKeyPacket.html +++ b/docs/SecretKeyPacket.html @@ -191,7 +191,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -308,7 +308,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -387,7 +387,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -466,7 +466,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -545,7 +545,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -624,7 +624,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -688,7 +688,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -767,7 +767,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -831,7 +831,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -905,7 +905,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -984,7 +984,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -1053,7 +1053,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -1134,7 +1134,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -1208,7 +1208,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -1282,7 +1282,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -1361,7 +1361,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -1430,7 +1430,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -1519,7 +1519,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -1614,7 +1614,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -1709,7 +1709,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -1851,7 +1851,7 @@ otherwise calls to this function will throw an error.

      Source:
      @@ -2065,7 +2065,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2189,7 +2189,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2306,7 +2306,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2419,7 +2419,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2536,7 +2536,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2653,7 +2653,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2770,7 +2770,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2888,7 +2888,7 @@ Returns false for gnu-dummy keys and null for public keys.

      Source:
      @@ -2999,7 +2999,7 @@ Returns false for gnu-dummy keys and null for public keys.

      Source:
      @@ -3114,7 +3114,7 @@ Such keys are:

      Source:
      @@ -3266,7 +3266,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
      Source:
      @@ -3411,7 +3411,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
      Source:
      @@ -3501,7 +3501,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
      Source:
      @@ -3625,7 +3625,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
      Source:
      @@ -3791,7 +3791,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
      Source:
      diff --git a/docs/SecretSubkeyPacket.html b/docs/SecretSubkeyPacket.html index c5f4ec4f..115d31a2 100644 --- a/docs/SecretSubkeyPacket.html +++ b/docs/SecretSubkeyPacket.html @@ -190,7 +190,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -312,7 +312,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -391,7 +391,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -470,7 +470,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -549,7 +549,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -628,7 +628,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -697,7 +697,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -776,7 +776,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -845,7 +845,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -924,7 +924,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -1003,7 +1003,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -1072,7 +1072,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -1158,7 +1158,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -1237,7 +1237,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -1316,7 +1316,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -1395,7 +1395,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -1464,7 +1464,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -1558,7 +1558,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -1653,7 +1653,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -1748,7 +1748,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -1895,7 +1895,7 @@ otherwise calls to this function will throw an error.

      Source:
      @@ -2114,7 +2114,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2238,7 +2238,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2355,7 +2355,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2468,7 +2468,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2585,7 +2585,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2702,7 +2702,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2819,7 +2819,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2937,7 +2937,7 @@ Returns false for gnu-dummy keys and null for public keys.

      Source:
      @@ -3053,7 +3053,7 @@ Returns false for gnu-dummy keys and null for public keys.

      Source:
      @@ -3173,7 +3173,7 @@ Such keys are:

      Source:
      @@ -3330,7 +3330,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
      Source:
      @@ -3475,7 +3475,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
      Source:
      @@ -3570,7 +3570,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
      Source:
      @@ -3694,7 +3694,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
      Source:
      @@ -3860,7 +3860,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
      Source:
      diff --git a/docs/Signature.html b/docs/Signature.html index 213afc94..ef6e917b 100644 --- a/docs/Signature.html +++ b/docs/Signature.html @@ -144,7 +144,7 @@
      Source:
      @@ -322,7 +322,7 @@
      Source:
      @@ -434,7 +434,7 @@
      Source:
      @@ -546,7 +546,7 @@
      Source:
      diff --git a/docs/SignaturePacket.html b/docs/SignaturePacket.html index 468477fe..d89f42a4 100644 --- a/docs/SignaturePacket.html +++ b/docs/SignaturePacket.html @@ -99,7 +99,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      @@ -201,7 +201,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      @@ -271,7 +271,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      @@ -341,7 +341,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      @@ -423,7 +423,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      @@ -599,7 +599,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      @@ -760,7 +760,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      @@ -1048,7 +1048,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      @@ -1427,7 +1427,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      @@ -1546,7 +1546,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      @@ -1654,7 +1654,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      @@ -1765,7 +1765,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      diff --git a/docs/SymEncryptedIntegrityProtectedDataPacket.html b/docs/SymEncryptedIntegrityProtectedDataPacket.html index 525f9dcf..2682579e 100644 --- a/docs/SymEncryptedIntegrityProtectedDataPacket.html +++ b/docs/SymEncryptedIntegrityProtectedDataPacket.html @@ -101,7 +101,7 @@ packet.

      Source:
      @@ -203,7 +203,7 @@ packet.

      Source:
      @@ -273,7 +273,7 @@ packet.

      Source:
      @@ -478,7 +478,7 @@ packet.

      Source:
      @@ -738,7 +738,7 @@ packet.

      Source:
      diff --git a/docs/SymEncryptedSessionKeyPacket.html b/docs/SymEncryptedSessionKeyPacket.html index 3322b140..20fd10ae 100644 --- a/docs/SymEncryptedSessionKeyPacket.html +++ b/docs/SymEncryptedSessionKeyPacket.html @@ -165,7 +165,7 @@ the Symmetric-Key Encrypted Session Key packet.

      Source:
      @@ -271,7 +271,7 @@ the Symmetric-Key Encrypted Session Key packet.

      Source:
      @@ -345,7 +345,7 @@ the Symmetric-Key Encrypted Session Key packet.

      Source:
      @@ -419,7 +419,7 @@ the Symmetric-Key Encrypted Session Key packet.

      Source:
      @@ -550,7 +550,7 @@ the Symmetric-Key Encrypted Session Key packet.

      Source:
      @@ -761,7 +761,7 @@ the Symmetric-Key Encrypted Session Key packet.

      Source:
      @@ -929,7 +929,7 @@ the Symmetric-Key Encrypted Session Key packet.

      Source:
      @@ -1019,7 +1019,7 @@ the Symmetric-Key Encrypted Session Key packet.

      Source:
      diff --git a/docs/SymmetricallyEncryptedDataPacket.html b/docs/SymmetricallyEncryptedDataPacket.html index 3b648d27..6bb7cbf7 100644 --- a/docs/SymmetricallyEncryptedDataPacket.html +++ b/docs/SymmetricallyEncryptedDataPacket.html @@ -101,7 +101,7 @@ that form whole OpenPGP messages).

      Source:
      @@ -197,7 +197,7 @@ that form whole OpenPGP messages).

      Source:
      @@ -271,7 +271,7 @@ that form whole OpenPGP messages).

      Source:
      @@ -477,7 +477,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -720,7 +720,7 @@ See RFC 4880 9.2 f
      Source:
      diff --git a/docs/TrustPacket.html b/docs/TrustPacket.html index 00171290..81cf349d 100644 --- a/docs/TrustPacket.html +++ b/docs/TrustPacket.html @@ -105,7 +105,7 @@ other than local keyring files.

      Source:
      @@ -216,7 +216,7 @@ Currently not implemented as we ignore trust packets

      Source:
      diff --git a/docs/UserAttributePacket.html b/docs/UserAttributePacket.html index 24770244..93bc692e 100644 --- a/docs/UserAttributePacket.html +++ b/docs/UserAttributePacket.html @@ -107,7 +107,7 @@ an implementation may use any method desired.

      Source:
      @@ -266,7 +266,7 @@ an implementation may use any method desired.

      Source:
      @@ -427,7 +427,7 @@ an implementation may use any method desired.

      Source:
      @@ -517,7 +517,7 @@ an implementation may use any method desired.

      Source:
      diff --git a/docs/UserIDPacket.html b/docs/UserIDPacket.html index 7ff0b5d3..c3cae23e 100644 --- a/docs/UserIDPacket.html +++ b/docs/UserIDPacket.html @@ -100,7 +100,7 @@ specifies the length of the User ID.

      Source:
      @@ -207,7 +207,7 @@ John Doe john@example.com

      Source:
      @@ -338,7 +338,7 @@ John Doe john@example.com

      Source:
      @@ -495,7 +495,7 @@ John Doe john@example.com

      Source:
      @@ -585,7 +585,7 @@ John Doe john@example.com

      Source:
      diff --git a/docs/global.html b/docs/global.html index ce62f9ef..dd6de10c 100644 --- a/docs/global.html +++ b/docs/global.html @@ -419,7 +419,7 @@
      Source:
      @@ -632,7 +632,7 @@
      Source:
      @@ -771,7 +771,7 @@
      Source:
      @@ -1180,7 +1180,7 @@
      Source:
      @@ -1761,7 +1761,7 @@ One of decryptionKeys, sessionkeys or passwords<
      Source:
      @@ -2064,7 +2064,7 @@ This method does not change the original key.

      Source:
      @@ -2423,7 +2423,7 @@ One of decryptionKeys or passwords must be specified.<
      Source:
      @@ -3227,7 +3227,7 @@ must be specified. If signing keys are specified, those will be used to sign the
      Source:
      @@ -3515,7 +3515,7 @@ This method does not change the original key.

      Source:
      @@ -4135,7 +4135,7 @@ At least one of encryptionKeys or passwords must be sp
      Source:
      @@ -4351,7 +4351,7 @@ At least one of encryptionKeys or passwords must be sp
      Source:
      @@ -4952,7 +4952,7 @@ default to main key options, except for sign parameter that default
      Source:
      @@ -5302,7 +5302,7 @@ default to main key options, except for sign parameter that default
      Source:
      @@ -5463,7 +5463,7 @@ default to main key options, except for sign parameter that default
      Source:
      @@ -5602,7 +5602,7 @@ default to main key options, except for sign parameter that default
      Source:
      @@ -5741,7 +5741,7 @@ default to main key options, except for sign parameter that default
      Source:
      @@ -5891,7 +5891,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -6071,7 +6071,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -6215,7 +6215,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -6405,7 +6405,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -6797,7 +6797,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -7038,7 +7038,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -7326,7 +7326,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -7614,7 +7614,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -7908,7 +7908,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -8196,7 +8196,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -8484,7 +8484,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -8772,7 +8772,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -9234,7 +9234,7 @@ to set the same date as the key creation time to ensure that old message signatu
      Source:
      @@ -9763,7 +9763,7 @@ If a revocation certificate is passed, the reasonForRevocation parameter will be
      Source:
      @@ -9978,7 +9978,7 @@ If a revocation certificate is passed, the reasonForRevocation parameter will be
      Source:
      @@ -10527,7 +10527,7 @@ If a revocation certificate is passed, the reasonForRevocation parameter will be
      Source:
      @@ -10689,7 +10689,7 @@ the encoded bytes

      Source:
      @@ -11151,7 +11151,7 @@ an attribute "data" containing a stream of bytes and "type"
      Source:
      @@ -11396,7 +11396,7 @@ The new key includes a revocation certificate that must be removed before return
      Source:
      @@ -11576,7 +11576,7 @@ The new key includes a revocation certificate that must be removed before return
      Source:
      diff --git a/docs/index.html b/docs/index.html index 4c20fedd..6144c371 100644 --- a/docs/index.html +++ b/docs/index.html @@ -127,16 +127,16 @@ library to convert back and forth between them.

      ECDH N/A No -No -Algorithmically** +Yes* +If native** ed25519 N/A EdDSA No -No -Algorithmically** +Yes* +If native** nistP256 @@ -144,7 +144,7 @@ library to convert back and forth between them.

      ECDSA Yes* Yes* -If native*** +If native** nistP384 @@ -152,7 +152,7 @@ library to convert back and forth between them.

      ECDSA Yes* Yes* -If native*** +If native** nistP521 @@ -160,7 +160,7 @@ library to convert back and forth between them.

      ECDSA Yes* Yes* -If native*** +If native** brainpoolP256r1 @@ -168,7 +168,7 @@ library to convert back and forth between them.

      ECDSA Yes* No -If native*** +If native** brainpoolP384r1 @@ -176,7 +176,7 @@ library to convert back and forth between them.

      ECDSA Yes* No -If native*** +If native** brainpoolP512r1 @@ -184,7 +184,7 @@ library to convert back and forth between them.

      ECDSA Yes* No -If native*** +If native** secp256k1 @@ -192,13 +192,12 @@ library to convert back and forth between them.

      ECDSA Yes* No -If native*** +If native** -

      * when available
      -** the curve25519 and ed25519 implementations are algorithmically constant-time, but may not be constant-time after optimizations of the JavaScript compiler
      -*** these curves are only constant-time if the underlying native implementation is available and constant-time

      +

      * when available +** these curves are only constant-time if the underlying native implementation is available and constant-time

    • If the user's browser supports native WebCrypto via the window.crypto.subtle API, this will be used. Under Node.js the native crypto module is used.

      diff --git a/docs/module-config.html b/docs/module-config.html index b9882cec..30f51dd9 100644 --- a/docs/module-config.html +++ b/docs/module-config.html @@ -89,7 +89,7 @@
      Source:
      @@ -247,7 +247,7 @@ as a global config setting, but can be used for specific function calls (e.g. de
      Source:
      @@ -365,7 +365,7 @@ Must be an integer value from 0 to 56.

      Source:
      @@ -489,7 +489,7 @@ Note: not all OpenPGP implementations are compatible with this option.
    • Source:
      @@ -614,7 +614,7 @@ where key flags were ignored when selecting a key for encryption.

      Source:
      @@ -733,7 +733,7 @@ and have self-signature's creation date that does not match the primary key crea
      Source:
      @@ -854,7 +854,7 @@ This is an insecure setting:

      Source:
      @@ -979,7 +979,7 @@ and deferring checking their integrity until the decrypted stream has been read
      Source:
      @@ -1091,7 +1091,7 @@ and deferring checking their integrity until the decrypted stream has been read
      Source:
      @@ -1213,7 +1213,7 @@ See also constantTimePKCS1DecryptionSupportedSymmetricAlgorithms.Source:
      @@ -1331,7 +1331,7 @@ However, the more algorithms are added, the slower the decryption procedure beco
      Source:
      @@ -1443,7 +1443,7 @@ However, the more algorithms are added, the slower the decryption procedure beco
      Source:
      @@ -1555,7 +1555,7 @@ However, the more algorithms are added, the slower the decryption procedure beco
      Source:
      @@ -1672,7 +1672,7 @@ validation error when the notation is marked as critical.

      Source:
      @@ -1788,7 +1788,7 @@ validation error when the notation is marked as critical.

      Source:
      @@ -1905,7 +1905,7 @@ The default is 2047 since due to a bug, previous versions of OpenPGP.js could ge
      Source:
      @@ -2022,7 +2022,7 @@ The default is 2047 since due to a bug, previous versions of OpenPGP.js could ge
      Source:
      @@ -2139,7 +2139,7 @@ Only has an effect when aeadProtect is set to true.

      Source:
      @@ -2251,7 +2251,7 @@ Only has an effect when aeadProtect is set to true.

      Source:
      @@ -2363,7 +2363,7 @@ Only has an effect when aeadProtect is set to true.

      Source:
      @@ -2475,7 +2475,7 @@ Only has an effect when aeadProtect is set to true.

      Source:
      @@ -2591,7 +2591,7 @@ Only has an effect when aeadProtect is set to true.

      Source:
      @@ -2707,7 +2707,7 @@ Only has an effect when aeadProtect is set to true.

      Source:
      @@ -2823,7 +2823,7 @@ Only has an effect when aeadProtect is set to true.

      Source:
      @@ -2939,7 +2939,7 @@ Only has an effect when aeadProtect is set to true.

      Source:
      @@ -3154,7 +3154,7 @@ For more details on the choice of parameters, see https://tools.ietf.org/html/rf
      Source:
      @@ -3273,7 +3273,7 @@ Note: this is the exponent value, not the final number of iterations (refer to s
      Source:
      @@ -3395,7 +3395,7 @@ Note: Argon2 is the strongest option but not all OpenPGP implementations are com
      Source:
      @@ -3507,7 +3507,7 @@ Note: Argon2 is the strongest option but not all OpenPGP implementations are com
      Source:
      @@ -3619,7 +3619,7 @@ Note: Argon2 is the strongest option but not all OpenPGP implementations are com
      Source:
      @@ -3736,7 +3736,7 @@ When false, certain standard curves will not be supported (depending on the plat
      Source:
      @@ -3854,7 +3854,7 @@ Note: not all OpenPGP implementations are compatible with this option.
      Source:
      @@ -3966,7 +3966,7 @@ Note: not all OpenPGP implementations are compatible with this option.
      Source:
      diff --git a/docs/module-crypto.html b/docs/module-crypto.html index c046252b..791cc4a9 100644 --- a/docs/module-crypto.html +++ b/docs/module-crypto.html @@ -89,7 +89,7 @@
      Source:
      diff --git a/docs/module-crypto_aes_kw.html b/docs/module-crypto_aes_kw.html index e83e6ffb..a26c710d 100644 --- a/docs/module-crypto_aes_kw.html +++ b/docs/module-crypto_aes_kw.html @@ -89,7 +89,7 @@
      Source:
      @@ -308,7 +308,7 @@
      Source:
      @@ -521,7 +521,7 @@
      Source:
      diff --git a/docs/module-crypto_cmac.html b/docs/module-crypto_cmac.html index 55d906a3..162cbde8 100644 --- a/docs/module-crypto_cmac.html +++ b/docs/module-crypto_cmac.html @@ -90,7 +90,7 @@ native AES-CBC using either the WebCrypto API or Node.js' crypto API.

      Source:
      @@ -195,7 +195,7 @@ The OMAC authors indicate that they will promulgate this modification
      Source:
      @@ -352,7 +352,7 @@ simplify the implementation.

      Source:
      diff --git a/docs/module-crypto_crypto.html b/docs/module-crypto_crypto.html index 5fe0e8e2..44d1ad3c 100644 --- a/docs/module-crypto_crypto.html +++ b/docs/module-crypto_crypto.html @@ -90,7 +90,7 @@ well as key generation and parameter handling for all public-key cryptosystems.<
      Source:
      @@ -296,7 +296,7 @@ well as key generation and parameter handling for all public-key cryptosystems.<
      Source:
      @@ -458,7 +458,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -619,7 +619,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -848,7 +848,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -1030,7 +1030,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -1170,7 +1170,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -1354,7 +1354,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -1561,7 +1561,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -1745,7 +1745,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -2075,7 +2075,7 @@ See RFC 4880 5.5.3Source:
      @@ -2361,7 +2361,7 @@ See RFC 4880 9.1 f
      Source:
      @@ -2545,7 +2545,7 @@ See RFC 4880 9.1 f
      Source:
      @@ -2752,7 +2752,7 @@ See RFC 4880 9.1 f
      Source:
      @@ -2913,7 +2913,7 @@ See RFC 4880 9.1 f
      Source:
      diff --git a/docs/module-crypto_hash.html b/docs/module-crypto_hash.html index 539bf90c..808e8b87 100644 --- a/docs/module-crypto_hash.html +++ b/docs/module-crypto_hash.html @@ -89,7 +89,7 @@
      Source:
      @@ -191,7 +191,7 @@
      Source:
      @@ -352,7 +352,7 @@
      Source:
      @@ -513,7 +513,7 @@
      Source:
      diff --git a/docs/module-crypto_hkdf.html b/docs/module-crypto_hkdf.html index bf6f33e8..17c7dad0 100644 --- a/docs/module-crypto_hkdf.html +++ b/docs/module-crypto_hkdf.html @@ -89,7 +89,7 @@
      Source:
      diff --git a/docs/module-crypto_mode.html b/docs/module-crypto_mode.html index 240de5b0..f979ec2c 100644 --- a/docs/module-crypto_mode.html +++ b/docs/module-crypto_mode.html @@ -89,7 +89,7 @@
      Source:
      @@ -182,7 +182,7 @@
      Source:
      @@ -249,7 +249,7 @@
      Source:
      @@ -316,7 +316,7 @@
      Source:
      @@ -383,7 +383,7 @@
      Source:
      diff --git a/docs/module-crypto_mode_cfb.html b/docs/module-crypto_mode_cfb.html index af2dbde4..1ae71358 100644 --- a/docs/module-crypto_mode_cfb.html +++ b/docs/module-crypto_mode_cfb.html @@ -236,7 +236,7 @@
      Source:
      @@ -477,7 +477,7 @@
      Source:
      diff --git a/docs/module-crypto_mode_eax.html b/docs/module-crypto_mode_eax.html index 989b3107..0a549bd4 100644 --- a/docs/module-crypto_mode_eax.html +++ b/docs/module-crypto_mode_eax.html @@ -90,7 +90,7 @@ native AES-CTR using either the WebCrypto API or Node.js' crypto API.

      Source:
      @@ -296,7 +296,7 @@ native AES-CTR using either the WebCrypto API or Node.js' crypto API.

      Source:
      @@ -480,7 +480,7 @@ native AES-CTR using either the WebCrypto API or Node.js' crypto API.

      Source:
      @@ -665,7 +665,7 @@ native AES-CTR using either the WebCrypto API or Node.js' crypto API.

      Source:
      diff --git a/docs/module-crypto_mode_gcm.html b/docs/module-crypto_mode_gcm.html index 253c1a93..76b78e1c 100644 --- a/docs/module-crypto_mode_gcm.html +++ b/docs/module-crypto_mode_gcm.html @@ -90,7 +90,7 @@ the WebCrypto api as well as node.js' crypto api.

      Source:
      @@ -273,7 +273,7 @@ the WebCrypto api as well as node.js' crypto api.

      Source:
      diff --git a/docs/module-crypto_mode_ocb.html b/docs/module-crypto_mode_ocb.html index 073b1375..420bcad2 100644 --- a/docs/module-crypto_mode_ocb.html +++ b/docs/module-crypto_mode_ocb.html @@ -89,7 +89,7 @@
      Source:
      @@ -295,7 +295,7 @@
      Source:
      @@ -502,7 +502,7 @@
      Source:
      @@ -686,7 +686,7 @@
      Source:
      diff --git a/docs/module-crypto_pkcs1.html b/docs/module-crypto_pkcs1.html index 406d8095..4e4040cb 100644 --- a/docs/module-crypto_pkcs1.html +++ b/docs/module-crypto_pkcs1.html @@ -89,7 +89,7 @@
      Source:
      @@ -197,7 +197,7 @@
      Source:
      @@ -358,7 +358,7 @@
      Source:
      @@ -578,7 +578,7 @@
      Source:
      @@ -792,7 +792,7 @@
      Source:
      diff --git a/docs/module-crypto_public_key.html b/docs/module-crypto_public_key.html index 86f155da..24dcf64f 100644 --- a/docs/module-crypto_public_key.html +++ b/docs/module-crypto_public_key.html @@ -89,7 +89,7 @@
      Source:
      @@ -182,7 +182,7 @@
      Source:
      @@ -249,7 +249,7 @@
      Source:
      @@ -316,7 +316,7 @@
      Source:
      @@ -383,7 +383,7 @@
      Source:
      diff --git a/docs/module-crypto_public_key_dsa.html b/docs/module-crypto_public_key_dsa.html index 679d0cd0..1d932e11 100644 --- a/docs/module-crypto_public_key_dsa.html +++ b/docs/module-crypto_public_key_dsa.html @@ -89,7 +89,7 @@
      Source:
      @@ -188,7 +188,7 @@ Expect y == y'

      Source:
      @@ -434,7 +434,7 @@ Expect y == y'

      Source:
      @@ -683,7 +683,7 @@ Expect y == y'

      Source:
      @@ -1005,7 +1005,7 @@ Expect y == y'

      Source:
      diff --git a/docs/module-crypto_public_key_elgamal.html b/docs/module-crypto_public_key_elgamal.html index 2ebbcaa3..c69d3541 100644 --- a/docs/module-crypto_public_key_elgamal.html +++ b/docs/module-crypto_public_key_elgamal.html @@ -89,7 +89,7 @@
      Source:
      @@ -188,7 +188,7 @@ Expect y == y'

      Source:
      @@ -412,7 +412,7 @@ Expect y == y'

      Source:
      @@ -672,7 +672,7 @@ Note that in OpenPGP, the message needs to be padded with PKCS#1 (same as RSA)Source:
      @@ -898,7 +898,7 @@ Note that in OpenPGP, the message needs to be padded with PKCS#1 (same as RSA)Source:
      diff --git a/docs/module-crypto_public_key_elliptic.html b/docs/module-crypto_public_key_elliptic.html index 02577f24..d23d6a90 100644 --- a/docs/module-crypto_public_key_elliptic.html +++ b/docs/module-crypto_public_key_elliptic.html @@ -89,7 +89,7 @@
      Source:
      diff --git a/docs/module-crypto_public_key_elliptic_curve.html b/docs/module-crypto_public_key_elliptic_curve.html index c1a2a812..90d41f65 100644 --- a/docs/module-crypto_public_key_elliptic_curve.html +++ b/docs/module-crypto_public_key_elliptic_curve.html @@ -89,7 +89,7 @@
      Source:
      @@ -201,7 +201,7 @@ NB: this function does not check e.g. whether the point belongs to the curve.

      Source:
      @@ -340,7 +340,7 @@ NB: this function does not check e.g. whether the point belongs to the curve.

      Source:
      @@ -497,7 +497,7 @@ NB: this function does not check e.g. whether the point belongs to the curve.

      Source:
      @@ -723,7 +723,7 @@ NB: this function does not check e.g. whether the point belongs to the curve.

      Source:
      @@ -926,7 +926,7 @@ NB: this function does not check e.g. whether the point belongs to the curve.

      Source:
      @@ -1157,7 +1157,7 @@ Not suitable for EdDSA (different secret key format)

      Source:
      diff --git a/docs/module-crypto_public_key_elliptic_ecdh.html b/docs/module-crypto_public_key_elliptic_ecdh.html index 684fd46e..fa26bf5a 100644 --- a/docs/module-crypto_public_key_elliptic_ecdh.html +++ b/docs/module-crypto_public_key_elliptic_ecdh.html @@ -91,7 +91,7 @@
      Source:
      @@ -169,7 +169,7 @@
      Source:
      @@ -467,7 +467,7 @@
      Source:
      @@ -720,7 +720,7 @@
      Source:
      @@ -973,7 +973,7 @@
      Source:
      @@ -1176,7 +1176,7 @@
      Source:
      @@ -1337,7 +1337,7 @@
      Source:
      @@ -1391,6 +1391,118 @@ +

      (async, static) generateEphemeralEncryptionMaterial() → {Promise.<{ephemeralPublicKey: Uint8Array, sharedSecret: Uint8Array}>}

      + + + + + + +
      +

      Generate shared secret and ephemeral public key for encryption

      +
      + + + + + + + + + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Source:
      +
      + + + + + + + +
      + + + + + + + + + + + + + + + +
      Returns:
      + + +
      +

      ephemeral public key (K_A) and shared secret

      +
      + + + +
      +
      + Type +
      +
      + +Promise.<{ephemeralPublicKey: Uint8Array, sharedSecret: Uint8Array}> + + +
      +
      + + + + + + + + + + + + +

      (async, static) validateParams(oid, Q, d) → {Promise.<Boolean>}

      @@ -1540,7 +1652,7 @@
      Source:
      @@ -1747,7 +1859,7 @@
      Source:
      @@ -1977,7 +2089,7 @@
      Source:
      @@ -2157,7 +2269,7 @@
      Source:
      @@ -2360,7 +2472,7 @@
      Source:
      @@ -2540,7 +2652,7 @@
      Source:
      @@ -2766,7 +2878,7 @@
      Source:
      @@ -2946,7 +3058,7 @@
      Source:
      @@ -3077,7 +3189,7 @@
      Source:
      @@ -3155,7 +3267,7 @@
      Source:
      @@ -3453,7 +3565,7 @@
      Source:
      @@ -3706,7 +3818,7 @@
      Source:
      @@ -3959,7 +4071,7 @@
      Source:
      @@ -4162,7 +4274,7 @@
      Source:
      @@ -4323,7 +4435,7 @@
      Source:
      @@ -4377,6 +4489,118 @@ +

      (async, static) generateEphemeralEncryptionMaterial() → {Promise.<{ephemeralPublicKey: Uint8Array, sharedSecret: Uint8Array}>}

      + + + + + + +
      +

      Generate shared secret and ephemeral public key for encryption

      +
      + + + + + + + + + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Source:
      +
      + + + + + + + +
      + + + + + + + + + + + + + + + +
      Returns:
      + + +
      +

      ephemeral public key (K_A) and shared secret

      +
      + + + +
      +
      + Type +
      +
      + +Promise.<{ephemeralPublicKey: Uint8Array, sharedSecret: Uint8Array}> + + +
      +
      + + + + + + + + + + + + +

      (async, static) validateParams(oid, Q, d) → {Promise.<Boolean>}

      @@ -4526,7 +4750,7 @@
      Source:
      @@ -4733,7 +4957,7 @@
      Source:
      @@ -4963,7 +5187,7 @@
      Source:
      @@ -5143,7 +5367,7 @@
      Source:
      @@ -5346,7 +5570,7 @@
      Source:
      @@ -5526,7 +5750,7 @@
      Source:
      @@ -5752,7 +5976,7 @@
      Source:
      @@ -5932,7 +6156,7 @@
      Source:
      diff --git a/docs/module-crypto_public_key_elliptic_ecdsa.html b/docs/module-crypto_public_key_elliptic_ecdsa.html index 7ac250b6..a3ab7d7d 100644 --- a/docs/module-crypto_public_key_elliptic_ecdsa.html +++ b/docs/module-crypto_public_key_elliptic_ecdsa.html @@ -89,7 +89,7 @@
      Source:
      @@ -364,7 +364,7 @@
      Source:
      @@ -571,7 +571,7 @@
      Source:
      @@ -847,7 +847,7 @@
      Source:
      @@ -956,7 +956,7 @@ To be used if no native implementation is available for the given curve/operatio
      Source:
      diff --git a/docs/module-crypto_public_key_elliptic_eddsa.html b/docs/module-crypto_public_key_elliptic_eddsa.html index a0a144f2..a3c355b7 100644 --- a/docs/module-crypto_public_key_elliptic_eddsa.html +++ b/docs/module-crypto_public_key_elliptic_eddsa.html @@ -89,7 +89,7 @@
      Source:
      @@ -249,7 +249,7 @@
      Source:
      @@ -521,7 +521,7 @@
      Source:
      @@ -751,7 +751,7 @@
      Source:
      @@ -1027,7 +1027,7 @@
      Source:
      diff --git a/docs/module-crypto_public_key_elliptic_eddsa_legacy.html b/docs/module-crypto_public_key_elliptic_eddsa_legacy.html index 461a7a0c..843291f6 100644 --- a/docs/module-crypto_public_key_elliptic_eddsa_legacy.html +++ b/docs/module-crypto_public_key_elliptic_eddsa_legacy.html @@ -90,7 +90,7 @@ This key type has been deprecated by the crypto-refresh RFC.

      Source:
      @@ -365,7 +365,7 @@ This key type has been deprecated by the crypto-refresh RFC.

      Source:
      @@ -572,7 +572,7 @@ This key type has been deprecated by the crypto-refresh RFC.

      Source:
      @@ -848,7 +848,7 @@ This key type has been deprecated by the crypto-refresh RFC.

      Source:
      diff --git a/docs/module-crypto_public_key_rsa.html b/docs/module-crypto_public_key_rsa.html index bcdec3ec..9c159eb1 100644 --- a/docs/module-crypto_public_key_rsa.html +++ b/docs/module-crypto_public_key_rsa.html @@ -89,7 +89,7 @@
      Source:
      @@ -411,7 +411,7 @@
      Source:
      @@ -647,7 +647,7 @@
      Source:
      @@ -833,7 +833,7 @@
      Source:
      @@ -1186,7 +1186,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

      Source:
      @@ -1462,7 +1462,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

      Source:
      @@ -1738,7 +1738,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

      Source:
      @@ -1846,7 +1846,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

      Source:
      @@ -2123,7 +2123,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

      Source:
      @@ -2308,7 +2308,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

      Source:
      diff --git a/docs/module-crypto_random.html b/docs/module-crypto_random.html index c3565064..589e17c2 100644 --- a/docs/module-crypto_random.html +++ b/docs/module-crypto_random.html @@ -89,7 +89,7 @@
      Source:
      @@ -272,7 +272,7 @@
      Source:
      @@ -433,7 +433,7 @@
      Source:
      diff --git a/docs/module-crypto_signature.html b/docs/module-crypto_signature.html index f1840a6e..40cdc169 100644 --- a/docs/module-crypto_signature.html +++ b/docs/module-crypto_signature.html @@ -89,7 +89,7 @@
      Source:
      @@ -276,7 +276,7 @@ See RFC 4880 5.2.2.<
      Source:
      @@ -555,7 +555,7 @@ for public key and hash algorithms.

      Source:
      @@ -834,7 +834,7 @@ for public key and hash algorithms.

      Source:
      diff --git a/docs/module-encoding_base64.html b/docs/module-encoding_base64.html index a276a070..a5fca60e 100644 --- a/docs/module-encoding_base64.html +++ b/docs/module-encoding_base64.html @@ -168,7 +168,7 @@
      Source:
      @@ -332,7 +332,7 @@
      Source:
      @@ -499,7 +499,7 @@
      Source:
      @@ -686,7 +686,7 @@
      Source:
      diff --git a/docs/module-enums.html b/docs/module-enums.html index 408ddd44..5a5a1151 100644 --- a/docs/module-enums.html +++ b/docs/module-enums.html @@ -235,7 +235,7 @@
      Source:
      @@ -499,7 +499,7 @@
      Source:
      @@ -694,7 +694,7 @@
      Source:
      @@ -1119,7 +1119,7 @@
      Source:
      @@ -1323,7 +1323,7 @@ fingerprint format

      Source:
      @@ -1633,7 +1633,7 @@ fingerprint format

      Source:
      @@ -1899,7 +1899,7 @@ possession of more than one person.

      Source:
      @@ -2094,7 +2094,7 @@ possession of more than one person.

      Source:
      @@ -2634,7 +2634,7 @@ possession of more than one person.

      Source:
      @@ -3060,7 +3060,7 @@ possession of more than one person.

      Source:
      @@ -3278,7 +3278,7 @@ possession of more than one person.

      Source:
      @@ -3496,7 +3496,7 @@ possession of more than one person.

      Source:
      @@ -4013,7 +4013,7 @@ document) that cannot include a target subpacket.

      Source:
      @@ -4737,7 +4737,7 @@ document) that cannot include a target subpacket.

      Source:
      @@ -5024,7 +5024,7 @@ document) that cannot include a target subpacket.

      Source:
      @@ -5220,7 +5220,7 @@ document) that cannot include a target subpacket.

      Source:
      @@ -5374,7 +5374,7 @@ document) that cannot include a target subpacket.

      Source:
      @@ -5590,7 +5590,7 @@ document) that cannot include a target subpacket.

      Source:
      diff --git a/docs/module-key_Subkey-Subkey.html b/docs/module-key_Subkey-Subkey.html index 4265ae71..f7684bba 100644 --- a/docs/module-key_Subkey-Subkey.html +++ b/docs/module-key_Subkey-Subkey.html @@ -171,7 +171,7 @@
      Source:
      @@ -281,7 +281,7 @@
      Source:
      @@ -394,7 +394,7 @@
      Source:
      @@ -511,7 +511,7 @@
      Source:
      @@ -628,7 +628,7 @@
      Source:
      @@ -741,7 +741,7 @@
      Source:
      @@ -942,7 +942,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -1055,7 +1055,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -1172,7 +1172,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -1289,7 +1289,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -1406,7 +1406,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -1523,7 +1523,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -1640,7 +1640,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -1757,7 +1757,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -1873,7 +1873,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -2149,7 +2149,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -2487,7 +2487,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -2599,7 +2599,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -2832,7 +2832,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -3044,7 +3044,7 @@ and valid binding signature.

      Source:
      diff --git a/docs/module-key_User-User.html b/docs/module-key_User-User.html index 8d2c238b..e9f14f35 100644 --- a/docs/module-key_User-User.html +++ b/docs/module-key_User-User.html @@ -171,7 +171,7 @@
      Source:
      @@ -404,7 +404,7 @@
      Source:
      @@ -516,7 +516,7 @@
      Source:
      @@ -789,7 +789,7 @@
      Source:
      @@ -1127,7 +1127,7 @@
      Source:
      @@ -1239,7 +1239,7 @@
      Source:
      @@ -1442,7 +1442,7 @@
      Source:
      @@ -1623,7 +1623,7 @@ and validity of self signature.

      Source:
      @@ -1887,7 +1887,7 @@ and validity of self signature.

      Source:
      @@ -2154,7 +2154,7 @@ Signature validity is null if the verification keys do not correspond to the cer
      Source:
      diff --git a/docs/module-key_helper.html b/docs/module-key_helper.html index 9ad65643..1b6d0762 100644 --- a/docs/module-key_helper.html +++ b/docs/module-key_helper.html @@ -89,7 +89,7 @@
      Source:
      @@ -281,7 +281,7 @@
      Source:
      @@ -518,7 +518,7 @@
      Source:
      @@ -928,7 +928,7 @@
      Source:
      @@ -1116,7 +1116,7 @@ The expiration time of the signature is ignored.

      Source:
      @@ -1376,7 +1376,7 @@ The expiration time of the signature is ignored.

      Source:
      @@ -1648,7 +1648,7 @@ The expiration time of the signature is ignored.

      Source:
      @@ -1920,7 +1920,7 @@ The expiration time of the signature is ignored.

      Source:
      @@ -2224,7 +2224,7 @@ The expiration time of the signature is ignored.

      Source:
      @@ -2531,7 +2531,7 @@ The expiration time of the signature is ignored.

      Source:
      @@ -2830,7 +2830,7 @@ The expiration time of the signature is ignored.

      Source:
      diff --git a/docs/module-packet_packet.html b/docs/module-packet_packet.html index 87ddc5ff..9fc00c19 100644 --- a/docs/module-packet_packet.html +++ b/docs/module-packet_packet.html @@ -89,7 +89,7 @@
      Source:
      @@ -275,7 +275,7 @@
      Source:
      @@ -436,7 +436,7 @@
      Source:
      @@ -621,7 +621,7 @@ string

      Source:
      @@ -783,7 +783,7 @@ string

      Source:
      diff --git a/docs/module-type_ecdh_symkey.html b/docs/module-type_ecdh_symkey.html index e9197ca1..182d51ec 100644 --- a/docs/module-type_ecdh_symkey.html +++ b/docs/module-type_ecdh_symkey.html @@ -89,7 +89,7 @@
      Source:
      diff --git a/docs/module-type_kdf_params-KDFParams.html b/docs/module-type_kdf_params-KDFParams.html index c3f4c8a0..e75a3931 100644 --- a/docs/module-type_kdf_params-KDFParams.html +++ b/docs/module-type_kdf_params-KDFParams.html @@ -163,7 +163,7 @@
      Source:
      @@ -322,7 +322,7 @@
      Source:
      @@ -434,7 +434,7 @@
      Source:
      diff --git a/docs/module-type_keyid-KeyID.html b/docs/module-type_keyid-KeyID.html index 159d107c..edff315f 100644 --- a/docs/module-type_keyid-KeyID.html +++ b/docs/module-type_keyid-KeyID.html @@ -101,7 +101,7 @@ formed.

      Source:
      @@ -295,7 +295,7 @@ formed.

      Source:
      @@ -385,7 +385,7 @@ formed.

      Source:
      @@ -497,7 +497,7 @@ formed.

      Source:
      @@ -658,7 +658,7 @@ formed.

      Source:
      @@ -748,7 +748,7 @@ formed.

      Source:
      @@ -860,7 +860,7 @@ formed.

      Source:
      diff --git a/docs/module-type_oid.html b/docs/module-type_oid.html index c0268f57..e81019c0 100644 --- a/docs/module-type_oid.html +++ b/docs/module-type_oid.html @@ -100,7 +100,7 @@ sequence of octets is the valid representation of a curve OID.

      Source:
      diff --git a/docs/module-type_s2k-GenericS2K.html b/docs/module-type_s2k-GenericS2K.html index 9c4cb114..c2bc5a00 100644 --- a/docs/module-type_s2k-GenericS2K.html +++ b/docs/module-type_s2k-GenericS2K.html @@ -153,7 +153,7 @@
      Source:
      @@ -262,7 +262,7 @@
      Source:
      @@ -332,7 +332,7 @@
      Source:
      @@ -406,7 +406,7 @@
      Source:
      @@ -480,7 +480,7 @@
      Source:
      @@ -612,7 +612,7 @@ hashAlgorithm

      Source:
      @@ -774,7 +774,7 @@ hashAlgorithm hash length

      Source:
      @@ -886,7 +886,7 @@ hashAlgorithm hash length

      Source:
      diff --git a/docs/module-type_s2k.html b/docs/module-type_s2k.html index 34f9574f..6bbb80b2 100644 --- a/docs/module-type_s2k.html +++ b/docs/module-type_s2k.html @@ -95,7 +95,7 @@ symmetrically encrypted messages.

      Source:
      diff --git a/docs/module-type_x25519x448_symkey.html b/docs/module-type_x25519x448_symkey.html index b3ce3751..4978e8ea 100644 --- a/docs/module-type_x25519x448_symkey.html +++ b/docs/module-type_x25519x448_symkey.html @@ -91,7 +91,7 @@ the former includes an algorithm byte preceeding the encrypted session key.

      <
      Source:
      diff --git a/docs/module-util.html b/docs/module-util.html index c19d5d0a..f0c11d7f 100644 --- a/docs/module-util.html +++ b/docs/module-util.html @@ -89,7 +89,7 @@
      Source:
      diff --git a/package-lock.json b/package-lock.json index 2c8386b8..4bbb88b0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "openpgp", - "version": "6.0.0-beta.2", + "version": "6.0.0-beta.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "openpgp", - "version": "6.0.0-beta.2", + "version": "6.0.0-beta.3", "license": "LGPL-3.0+", "devDependencies": { "@noble/ciphers": "^0.6.0", diff --git a/package.json b/package.json index 242c31cf..25184836 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "openpgp", "description": "OpenPGP.js is a Javascript implementation of the OpenPGP protocol. This is defined in RFC 4880.", - "version": "6.0.0-beta.2", + "version": "6.0.0-beta.3", "license": "LGPL-3.0+", "homepage": "https://openpgpjs.org/", "engines": { From 8d8033383b00ee6d729d15f712303ebf469d981d Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Mon, 9 Sep 2024 10:37:58 +0200 Subject: [PATCH 173/201] Fix regression in x25519 (legacy) key generation: store clamped secret scalar Fixes regression from changes in #1782, as the spec mandates that legacy x25519 store the secret scalar already clamped. Keys generated using v6.0.0-beta.3 are still expected to be functional, since the scalar is to be clamped before computing the ECDH shared secret. --- src/crypto/public_key/elliptic/oid_curves.js | 3 +++ test/crypto/ecdh.js | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/src/crypto/public_key/elliptic/oid_curves.js b/src/crypto/public_key/elliptic/oid_curves.js index a66decdc..7404cbe6 100644 --- a/src/crypto/public_key/elliptic/oid_curves.js +++ b/src/crypto/public_key/elliptic/oid_curves.js @@ -182,8 +182,11 @@ class CurveWithOID { case 'node': return nodeGenKeyPair(this.name); case 'curve25519Legacy': { + // the private key must be stored in big endian and already clamped: https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-13.html#section-5.5.5.6.1.1-3 const { k, A } = await ecdhXGenerate(enums.publicKey.x25519); const privateKey = k.slice().reverse(); + privateKey[0] = (privateKey[0] & 127) | 64; + privateKey[31] &= 248; const publicKey = util.concatUint8Array([new Uint8Array([this.wireFormatLeadingByte]), A]); return { publicKey, privateKey }; } diff --git a/test/crypto/ecdh.js b/test/crypto/ecdh.js index 54408418..b44c8a3f 100644 --- a/test/crypto/ecdh.js +++ b/test/crypto/ecdh.js @@ -1,3 +1,4 @@ +import x25519 from '@openpgp/tweetnacl'; import sinon from 'sinon'; import { use as chaiUse, expect } from 'chai'; import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import @@ -67,6 +68,16 @@ export default () => describe('ECDH key exchange @lightweight', function () { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]); + it('Generated legacy x25519 secret scalar is stored clamped', async function () { + const curve = new elliptic_curves.CurveWithOID(openpgp.enums.curve.curve25519Legacy); + const { privateKey, publicKey } = await curve.genKeyPair(); + const clampedKey = privateKey.slice(); + clampedKey[0] = (clampedKey[0] & 127) | 64; + clampedKey[31] &= 248; + expect(privateKey).to.deep.equal(clampedKey); + const { publicKey: expectedPublicKey } = x25519.box.keyPair.fromSecretKey(privateKey.slice().reverse()); + expect(publicKey.subarray(1)).to.deep.equal(expectedPublicKey); + }); it('Invalid curve oid', function (done) { expect(decrypt_message( '', 2, 7, [], [], [], [], [] From f2818429dbd665b750ecbf5c7737aecdc3a74c15 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Mon, 9 Sep 2024 11:47:41 +0200 Subject: [PATCH 174/201] 6.0.0-beta.3.patch.0 --- docs/AEADEncryptedDataPacket.html | 14 ++-- docs/Argon2S2K.html | 16 ++--- docs/CleartextMessage.html | 12 ++-- docs/CompressedDataPacket.html | 16 ++--- docs/Key.html | 56 +++++++-------- docs/LiteralDataPacket.html | 20 +++--- docs/MarkerPacket.html | 4 +- docs/Message.html | 40 +++++------ docs/OnePassSignaturePacket.html | 22 +++--- docs/PacketList.html | 14 ++-- docs/PaddingPacket.html | 8 +-- docs/PrivateKey.html | 20 +++--- docs/PublicKey.html | 8 +-- docs/PublicKeyEncryptedSessionKeyPacket.html | 14 ++-- docs/PublicKeyPacket.html | 46 ++++++------ docs/PublicSubkeyPacket.html | 46 ++++++------ docs/SecretKeyPacket.html | 72 +++++++++---------- docs/SecretSubkeyPacket.html | 72 +++++++++---------- docs/Signature.html | 8 +-- docs/SignaturePacket.html | 24 +++---- ...EncryptedIntegrityProtectedDataPacket.html | 10 +-- docs/SymEncryptedSessionKeyPacket.html | 16 ++--- docs/SymmetricallyEncryptedDataPacket.html | 10 +-- docs/TrustPacket.html | 4 +- docs/UserAttributePacket.html | 8 +-- docs/UserIDPacket.html | 10 +-- docs/global.html | 72 +++++++++---------- docs/module-config.html | 66 ++++++++--------- docs/module-crypto.html | 2 +- docs/module-crypto_aes_kw.html | 6 +- docs/module-crypto_cmac.html | 6 +- docs/module-crypto_crypto.html | 30 ++++---- docs/module-crypto_hash.html | 8 +-- docs/module-crypto_hkdf.html | 2 +- docs/module-crypto_mode.html | 10 +-- docs/module-crypto_mode_cfb.html | 4 +- docs/module-crypto_mode_eax.html | 8 +-- docs/module-crypto_mode_gcm.html | 4 +- docs/module-crypto_mode_ocb.html | 8 +-- docs/module-crypto_pkcs1.html | 10 +-- docs/module-crypto_public_key.html | 10 +-- docs/module-crypto_public_key_dsa.html | 10 +-- docs/module-crypto_public_key_elgamal.html | 10 +-- docs/module-crypto_public_key_elliptic.html | 2 +- ...dule-crypto_public_key_elliptic_curve.html | 14 ++-- ...odule-crypto_public_key_elliptic_ecdh.html | 64 ++++++++--------- ...dule-crypto_public_key_elliptic_ecdsa.html | 10 +-- ...dule-crypto_public_key_elliptic_eddsa.html | 10 +-- ...ypto_public_key_elliptic_eddsa_legacy.html | 8 +-- docs/module-crypto_public_key_rsa.html | 20 +++--- docs/module-crypto_random.html | 6 +- docs/module-crypto_signature.html | 8 +-- docs/module-encoding_base64.html | 8 +-- docs/module-enums.html | 36 +++++----- docs/module-key_Subkey-Subkey.html | 40 +++++------ docs/module-key_User-User.html | 20 +++--- docs/module-key_helper.html | 22 +++--- docs/module-packet_packet.html | 10 +-- docs/module-type_ecdh_symkey.html | 2 +- docs/module-type_kdf_params-KDFParams.html | 6 +- docs/module-type_keyid-KeyID.html | 14 ++-- docs/module-type_oid.html | 2 +- docs/module-type_s2k-GenericS2K.html | 16 ++--- docs/module-type_s2k.html | 2 +- docs/module-type_x25519x448_symkey.html | 2 +- docs/module-util.html | 2 +- package-lock.json | 4 +- package.json | 2 +- 68 files changed, 593 insertions(+), 593 deletions(-) diff --git a/docs/AEADEncryptedDataPacket.html b/docs/AEADEncryptedDataPacket.html index ec729f0d..e2376f69 100644 --- a/docs/AEADEncryptedDataPacket.html +++ b/docs/AEADEncryptedDataPacket.html @@ -98,7 +98,7 @@ AEAD Protected Data Packet

      Source:
      @@ -200,7 +200,7 @@ AEAD Protected Data Packet

      Source:
      @@ -270,7 +270,7 @@ AEAD Protected Data Packet

      Source:
      @@ -475,7 +475,7 @@ AEAD Protected Data Packet

      Source:
      @@ -717,7 +717,7 @@ AEAD Protected Data Packet

      Source:
      @@ -888,7 +888,7 @@ AEAD Protected Data Packet

      Source:
      @@ -1007,7 +1007,7 @@ AEAD Protected Data Packet

      Source:
      diff --git a/docs/Argon2S2K.html b/docs/Argon2S2K.html index 799219d2..8771e2dd 100644 --- a/docs/Argon2S2K.html +++ b/docs/Argon2S2K.html @@ -152,7 +152,7 @@
      Source:
      @@ -258,7 +258,7 @@
      Source:
      @@ -332,7 +332,7 @@
      Source:
      @@ -406,7 +406,7 @@
      Source:
      @@ -480,7 +480,7 @@
      Source:
      @@ -612,7 +612,7 @@ hashAlgorithm

      Source:
      @@ -791,7 +791,7 @@ hashAlgorithm

      Source:
      @@ -903,7 +903,7 @@ hashAlgorithm

      Source:
      diff --git a/docs/CleartextMessage.html b/docs/CleartextMessage.html index e633180f..28c7d8fb 100644 --- a/docs/CleartextMessage.html +++ b/docs/CleartextMessage.html @@ -168,7 +168,7 @@ See https://tools.ietf.o
      Source:
      @@ -346,7 +346,7 @@ See https://tools.ietf.o
      Source:
      @@ -461,7 +461,7 @@ See https://tools.ietf.o
      Source:
      @@ -573,7 +573,7 @@ See https://tools.ietf.o
      Source:
      @@ -974,7 +974,7 @@ See https://tools.ietf.o
      Source:
      @@ -1211,7 +1211,7 @@ See https://tools.ietf.o
      Source:
      diff --git a/docs/CompressedDataPacket.html b/docs/CompressedDataPacket.html index 32ce9a61..eeeee439 100644 --- a/docs/CompressedDataPacket.html +++ b/docs/CompressedDataPacket.html @@ -160,7 +160,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

      Source:
      @@ -266,7 +266,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

      Source:
      @@ -343,7 +343,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

      Source:
      @@ -417,7 +417,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

      Source:
      @@ -499,7 +499,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

      Source:
      @@ -651,7 +651,7 @@ read by read_packet

      Source:
      @@ -836,7 +836,7 @@ read by read_packet

      Source:
      @@ -926,7 +926,7 @@ read by read_packet

      Source:
      diff --git a/docs/Key.html b/docs/Key.html index 483230a2..c969e643 100644 --- a/docs/Key.html +++ b/docs/Key.html @@ -96,7 +96,7 @@ Can contain additional subkeys, signatures, user ids, user attributes.

      Source:
      @@ -333,7 +333,7 @@ if it is a valid revocation signature.

      Source:
      @@ -514,7 +514,7 @@ if it is a valid revocation signature.

      Source:
      @@ -626,7 +626,7 @@ if it is a valid revocation signature.

      Source:
      @@ -738,7 +738,7 @@ if it is a valid revocation signature.

      Source:
      @@ -1006,7 +1006,7 @@ if it is a valid revocation signature.

      Source:
      @@ -1225,7 +1225,7 @@ Returns Infinity if the key doesn't expire, or null if
      Source:
      @@ -1333,7 +1333,7 @@ Returns Infinity if the key doesn't expire, or null if
      Source:
      @@ -1445,7 +1445,7 @@ Returns Infinity if the key doesn't expire, or null if
      Source:
      @@ -1557,7 +1557,7 @@ Returns Infinity if the key doesn't expire, or null if
      Source:
      @@ -1735,7 +1735,7 @@ If no keyID is given, returns all keys, starting with the primary key.

      Source:
      @@ -1977,7 +1977,7 @@ algorithm preferences, and so on.

      Source:
      @@ -2220,7 +2220,7 @@ algorithm preferences, and so on.

      Source:
      @@ -2425,7 +2425,7 @@ algorithm preferences, and so on.

      Source:
      @@ -2717,7 +2717,7 @@ algorithm preferences, and so on.

      Source:
      @@ -2911,7 +2911,7 @@ If no keyID is given, returns all subkeys.

      Source:
      @@ -3023,7 +3023,7 @@ If no keyID is given, returns all subkeys.

      Source:
      @@ -3135,7 +3135,7 @@ If no keyID is given, returns all subkeys.

      Source:
      @@ -3412,7 +3412,7 @@ If no keyID is given, returns all subkeys.

      Source:
      @@ -3596,7 +3596,7 @@ If no keyID is given, returns all subkeys.

      Source:
      @@ -3811,7 +3811,7 @@ If no keyID is given, returns all subkeys.

      Source:
      @@ -4081,7 +4081,7 @@ If no keyID is given, returns all subkeys.

      Source:
      @@ -4193,7 +4193,7 @@ If no keyID is given, returns all subkeys.

      Source:
      @@ -4434,7 +4434,7 @@ a private key is returned.

      Source:
      @@ -4677,7 +4677,7 @@ a private key is returned.

      Source:
      @@ -4918,7 +4918,7 @@ and valid self signature. Throws if the primary key is invalid.

      Source:
      @@ -5201,7 +5201,7 @@ and valid self signature. Throws if the primary key is invalid.

      Source:
      @@ -5314,7 +5314,7 @@ Signature validity is null if the verification keys do not correspond to the cer
      Source:
      diff --git a/docs/LiteralDataPacket.html b/docs/LiteralDataPacket.html index 897b13a1..ea3f0044 100644 --- a/docs/LiteralDataPacket.html +++ b/docs/LiteralDataPacket.html @@ -147,7 +147,7 @@ further interpreted.

      Source:
      @@ -326,7 +326,7 @@ further interpreted.

      Source:
      @@ -441,7 +441,7 @@ further interpreted.

      Source:
      @@ -623,7 +623,7 @@ with normalized end of line to \n

      Source:
      @@ -790,7 +790,7 @@ with normalized end of line to \n

      Source:
      @@ -977,7 +977,7 @@ with normalized end of line to \n

      Source:
      @@ -1116,7 +1116,7 @@ with normalized end of line to \n

      Source:
      @@ -1302,7 +1302,7 @@ will be normalized to \r\n and by default text is converted to UTF8

      Source:
      @@ -1392,7 +1392,7 @@ will be normalized to \r\n and by default text is converted to UTF8

      Source:
      @@ -1507,7 +1507,7 @@ will be normalized to \r\n and by default text is converted to UTF8

      Source:
      diff --git a/docs/MarkerPacket.html b/docs/MarkerPacket.html index b457d8da..011264ca 100644 --- a/docs/MarkerPacket.html +++ b/docs/MarkerPacket.html @@ -106,7 +106,7 @@ software is necessary to process the message.

      Source:
      @@ -265,7 +265,7 @@ software is necessary to process the message.

      Source:
      diff --git a/docs/Message.html b/docs/Message.html index 2df92a9c..70303b1f 100644 --- a/docs/Message.html +++ b/docs/Message.html @@ -146,7 +146,7 @@ See https://tools.iet
      Source:
      @@ -661,7 +661,7 @@ See https://tools.iet
      Source:
      @@ -933,7 +933,7 @@ See https://tools.iet
      Source:
      @@ -1140,7 +1140,7 @@ See https://tools.iet
      Source:
      @@ -1291,7 +1291,7 @@ See https://tools.iet
      Source:
      @@ -1495,7 +1495,7 @@ See https://tools.iet
      Source:
      @@ -1800,7 +1800,7 @@ See https://tools.iet
      Source:
      @@ -2105,7 +2105,7 @@ See https://tools.iet
      Source:
      @@ -2545,7 +2545,7 @@ See https://tools.iet
      Source:
      @@ -2657,7 +2657,7 @@ See https://tools.iet
      Source:
      @@ -2769,7 +2769,7 @@ See https://tools.iet
      Source:
      @@ -2884,7 +2884,7 @@ See https://tools.iet
      Source:
      @@ -2999,7 +2999,7 @@ See https://tools.iet
      Source:
      @@ -3111,7 +3111,7 @@ See https://tools.iet
      Source:
      @@ -3515,7 +3515,7 @@ See https://tools.iet
      Source:
      @@ -3916,7 +3916,7 @@ See https://tools.iet
      Source:
      @@ -4028,7 +4028,7 @@ See https://tools.iet
      Source:
      @@ -4265,7 +4265,7 @@ See https://tools.iet
      Source:
      @@ -4531,7 +4531,7 @@ See https://tools.iet
      Source:
      @@ -4643,7 +4643,7 @@ See https://tools.iet
      Source:
      diff --git a/docs/OnePassSignaturePacket.html b/docs/OnePassSignaturePacket.html index a8292484..92e6bc86 100644 --- a/docs/OnePassSignaturePacket.html +++ b/docs/OnePassSignaturePacket.html @@ -101,7 +101,7 @@ can compute the entire signed message in one pass.

      Source:
      @@ -199,7 +199,7 @@ that describes another signature to be applied to the same message data.

      Source:
      @@ -273,7 +273,7 @@ that describes another signature to be applied to the same message data.

      Source:
      @@ -344,7 +344,7 @@ that describes another signature to be applied to the same message data.

      Source:
      @@ -408,7 +408,7 @@ that describes another signature to be applied to the same message data.

      Source:
      @@ -482,7 +482,7 @@ that describes another signature to be applied to the same message data.

      Source:
      @@ -553,7 +553,7 @@ that describes another signature to be applied to the same message data.

      Source:
      @@ -629,7 +629,7 @@ Signature types are described in
      Source:
      @@ -693,7 +693,7 @@ Signature types are described in
      Source:
      @@ -824,7 +824,7 @@ Signature types are described in
      Source:
      @@ -936,7 +936,7 @@ Signature types are described in
      Source:
      diff --git a/docs/PacketList.html b/docs/PacketList.html index 4a5b94dc..f86282ca 100644 --- a/docs/PacketList.html +++ b/docs/PacketList.html @@ -97,7 +97,7 @@ are stored as numerical indices.

      Source:
      @@ -345,7 +345,7 @@ Equivalent to calling read on an empty PacketList instance.

      Source:
      @@ -530,7 +530,7 @@ Equivalent to calling read on an empty PacketList instance.

      Source:
      @@ -687,7 +687,7 @@ Equivalent to calling read on an empty PacketList instance.

      Source:
      @@ -859,7 +859,7 @@ Equivalent to calling read on an empty PacketList instance.

      Source:
      @@ -1097,7 +1097,7 @@ Equivalent to calling read on an empty PacketList instance.

      Source:
      @@ -1200,7 +1200,7 @@ class instance.

      Source:
      diff --git a/docs/PaddingPacket.html b/docs/PaddingPacket.html index 2ec9a895..e1225f97 100644 --- a/docs/PaddingPacket.html +++ b/docs/PaddingPacket.html @@ -97,7 +97,7 @@ Padding Packet

      Source:
      @@ -256,7 +256,7 @@ Padding Packet

      Source:
      @@ -427,7 +427,7 @@ Padding Packet

      Source:
      @@ -517,7 +517,7 @@ Padding Packet

      Source:
      diff --git a/docs/PrivateKey.html b/docs/PrivateKey.html index 177a0eb5..3aed4897 100644 --- a/docs/PrivateKey.html +++ b/docs/PrivateKey.html @@ -144,7 +144,7 @@
      Source:
      @@ -453,7 +453,7 @@ Note: Curve448 and Curve25519 are not widely supported yet.

      Source:
      @@ -622,7 +622,7 @@ Note: Curve448 and Curve25519 are not widely supported yet.

      Source:
      @@ -734,7 +734,7 @@ Note: Curve448 and Curve25519 are not widely supported yet.

      Source:
      @@ -979,7 +979,7 @@ This is useful to retrieve keys for session key decryption

      Source:
      @@ -1121,7 +1121,7 @@ A dummy key is considered encrypted.

      Source:
      @@ -1211,7 +1211,7 @@ A dummy key is considered encrypted.

      Source:
      @@ -1514,7 +1514,7 @@ A dummy key is considered encrypted.

      Source:
      @@ -1626,7 +1626,7 @@ A dummy key is considered encrypted.

      Source:
      @@ -1803,7 +1803,7 @@ If only gnu-dummy keys are found, we cannot properly validate so we throw an err
      Source:
      diff --git a/docs/PublicKey.html b/docs/PublicKey.html index 3299e23b..040b6c8f 100644 --- a/docs/PublicKey.html +++ b/docs/PublicKey.html @@ -144,7 +144,7 @@
      Source:
      @@ -315,7 +315,7 @@
      Source:
      @@ -427,7 +427,7 @@
      Source:
      @@ -535,7 +535,7 @@
      Source:
      diff --git a/docs/PublicKeyEncryptedSessionKeyPacket.html b/docs/PublicKeyEncryptedSessionKeyPacket.html index c561875d..772b1084 100644 --- a/docs/PublicKeyEncryptedSessionKeyPacket.html +++ b/docs/PublicKeyEncryptedSessionKeyPacket.html @@ -107,7 +107,7 @@ decrypt the message.

      Source:
      @@ -209,7 +209,7 @@ decrypt the message.

      Source:
      @@ -283,7 +283,7 @@ decrypt the message.

      Source:
      @@ -458,7 +458,7 @@ This is needed for constant-time processing. Expected object of the form: { sess
      Source:
      @@ -626,7 +626,7 @@ This is needed for constant-time processing. Expected object of the form: { sess
      Source:
      @@ -794,7 +794,7 @@ This is needed for constant-time processing. Expected object of the form: { sess
      Source:
      @@ -884,7 +884,7 @@ This is needed for constant-time processing. Expected object of the form: { sess
      Source:
      diff --git a/docs/PublicKeyPacket.html b/docs/PublicKeyPacket.html index aa97adde..104bfff3 100644 --- a/docs/PublicKeyPacket.html +++ b/docs/PublicKeyPacket.html @@ -195,7 +195,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -301,7 +301,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -375,7 +375,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -449,7 +449,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -523,7 +523,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -597,7 +597,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -671,7 +671,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -735,7 +735,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -816,7 +816,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -880,7 +880,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -1018,7 +1018,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -1130,7 +1130,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -1220,7 +1220,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -1310,7 +1310,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -1422,7 +1422,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -1530,7 +1530,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -1642,7 +1642,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -1754,7 +1754,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -1866,7 +1866,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -1978,7 +1978,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -2138,7 +2138,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -2250,7 +2250,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -2411,7 +2411,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      diff --git a/docs/PublicSubkeyPacket.html b/docs/PublicSubkeyPacket.html index 76b527d4..1a1e0e09 100644 --- a/docs/PublicSubkeyPacket.html +++ b/docs/PublicSubkeyPacket.html @@ -193,7 +193,7 @@ services.

      Source:
      @@ -315,7 +315,7 @@ services.

      Source:
      @@ -394,7 +394,7 @@ services.

      Source:
      @@ -473,7 +473,7 @@ services.

      Source:
      @@ -552,7 +552,7 @@ services.

      Source:
      @@ -631,7 +631,7 @@ services.

      Source:
      @@ -710,7 +710,7 @@ services.

      Source:
      @@ -779,7 +779,7 @@ services.

      Source:
      @@ -865,7 +865,7 @@ services.

      Source:
      @@ -934,7 +934,7 @@ services.

      Source:
      @@ -1072,7 +1072,7 @@ services.

      Source:
      @@ -1189,7 +1189,7 @@ services.

      Source:
      @@ -1284,7 +1284,7 @@ services.

      Source:
      @@ -1379,7 +1379,7 @@ services.

      Source:
      @@ -1496,7 +1496,7 @@ services.

      Source:
      @@ -1609,7 +1609,7 @@ services.

      Source:
      @@ -1726,7 +1726,7 @@ services.

      Source:
      @@ -1843,7 +1843,7 @@ services.

      Source:
      @@ -1960,7 +1960,7 @@ services.

      Source:
      @@ -2077,7 +2077,7 @@ services.

      Source:
      @@ -2242,7 +2242,7 @@ services.

      Source:
      @@ -2359,7 +2359,7 @@ services.

      Source:
      @@ -2525,7 +2525,7 @@ services.

      Source:
      diff --git a/docs/SecretKeyPacket.html b/docs/SecretKeyPacket.html index 9902d76c..2ddb26c7 100644 --- a/docs/SecretKeyPacket.html +++ b/docs/SecretKeyPacket.html @@ -191,7 +191,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -308,7 +308,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -387,7 +387,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -466,7 +466,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -545,7 +545,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -624,7 +624,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -688,7 +688,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -767,7 +767,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -831,7 +831,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -905,7 +905,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -984,7 +984,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -1053,7 +1053,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -1134,7 +1134,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -1208,7 +1208,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -1282,7 +1282,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -1361,7 +1361,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -1430,7 +1430,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -1519,7 +1519,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -1614,7 +1614,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -1709,7 +1709,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -1851,7 +1851,7 @@ otherwise calls to this function will throw an error.

      Source:
      @@ -2065,7 +2065,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2189,7 +2189,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2306,7 +2306,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2419,7 +2419,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2536,7 +2536,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2653,7 +2653,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2770,7 +2770,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2888,7 +2888,7 @@ Returns false for gnu-dummy keys and null for public keys.

      Source:
      @@ -2999,7 +2999,7 @@ Returns false for gnu-dummy keys and null for public keys.

      Source:
      @@ -3114,7 +3114,7 @@ Such keys are:

      Source:
      @@ -3266,7 +3266,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
      Source:
      @@ -3411,7 +3411,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
      Source:
      @@ -3501,7 +3501,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
      Source:
      @@ -3625,7 +3625,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
      Source:
      @@ -3791,7 +3791,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
      Source:
      diff --git a/docs/SecretSubkeyPacket.html b/docs/SecretSubkeyPacket.html index 115d31a2..d26a2dda 100644 --- a/docs/SecretSubkeyPacket.html +++ b/docs/SecretSubkeyPacket.html @@ -190,7 +190,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -312,7 +312,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -391,7 +391,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -470,7 +470,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -549,7 +549,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -628,7 +628,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -697,7 +697,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -776,7 +776,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -845,7 +845,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -924,7 +924,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -1003,7 +1003,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -1072,7 +1072,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -1158,7 +1158,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -1237,7 +1237,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -1316,7 +1316,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -1395,7 +1395,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -1464,7 +1464,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -1558,7 +1558,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -1653,7 +1653,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -1748,7 +1748,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -1895,7 +1895,7 @@ otherwise calls to this function will throw an error.

      Source:
      @@ -2114,7 +2114,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2238,7 +2238,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2355,7 +2355,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2468,7 +2468,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2585,7 +2585,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2702,7 +2702,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2819,7 +2819,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2937,7 +2937,7 @@ Returns false for gnu-dummy keys and null for public keys.

      Source:
      @@ -3053,7 +3053,7 @@ Returns false for gnu-dummy keys and null for public keys.

      Source:
      @@ -3173,7 +3173,7 @@ Such keys are:

      Source:
      @@ -3330,7 +3330,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
      Source:
      @@ -3475,7 +3475,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
      Source:
      @@ -3570,7 +3570,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
      Source:
      @@ -3694,7 +3694,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
      Source:
      @@ -3860,7 +3860,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
      Source:
      diff --git a/docs/Signature.html b/docs/Signature.html index ef6e917b..6081ce46 100644 --- a/docs/Signature.html +++ b/docs/Signature.html @@ -144,7 +144,7 @@
      Source:
      @@ -322,7 +322,7 @@
      Source:
      @@ -434,7 +434,7 @@
      Source:
      @@ -546,7 +546,7 @@
      Source:
      diff --git a/docs/SignaturePacket.html b/docs/SignaturePacket.html index d89f42a4..ef7efde6 100644 --- a/docs/SignaturePacket.html +++ b/docs/SignaturePacket.html @@ -99,7 +99,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      @@ -201,7 +201,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      @@ -271,7 +271,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      @@ -341,7 +341,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      @@ -423,7 +423,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      @@ -599,7 +599,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      @@ -760,7 +760,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      @@ -1048,7 +1048,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      @@ -1427,7 +1427,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      @@ -1546,7 +1546,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      @@ -1654,7 +1654,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      @@ -1765,7 +1765,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      diff --git a/docs/SymEncryptedIntegrityProtectedDataPacket.html b/docs/SymEncryptedIntegrityProtectedDataPacket.html index 2682579e..480c32ba 100644 --- a/docs/SymEncryptedIntegrityProtectedDataPacket.html +++ b/docs/SymEncryptedIntegrityProtectedDataPacket.html @@ -101,7 +101,7 @@ packet.

      Source:
      @@ -203,7 +203,7 @@ packet.

      Source:
      @@ -273,7 +273,7 @@ packet.

      Source:
      @@ -478,7 +478,7 @@ packet.

      Source:
      @@ -738,7 +738,7 @@ packet.

      Source:
      diff --git a/docs/SymEncryptedSessionKeyPacket.html b/docs/SymEncryptedSessionKeyPacket.html index 20fd10ae..4d1358c2 100644 --- a/docs/SymEncryptedSessionKeyPacket.html +++ b/docs/SymEncryptedSessionKeyPacket.html @@ -165,7 +165,7 @@ the Symmetric-Key Encrypted Session Key packet.

      Source:
      @@ -271,7 +271,7 @@ the Symmetric-Key Encrypted Session Key packet.

      Source:
      @@ -345,7 +345,7 @@ the Symmetric-Key Encrypted Session Key packet.

      Source:
      @@ -419,7 +419,7 @@ the Symmetric-Key Encrypted Session Key packet.

      Source:
      @@ -550,7 +550,7 @@ the Symmetric-Key Encrypted Session Key packet.

      Source:
      @@ -761,7 +761,7 @@ the Symmetric-Key Encrypted Session Key packet.

      Source:
      @@ -929,7 +929,7 @@ the Symmetric-Key Encrypted Session Key packet.

      Source:
      @@ -1019,7 +1019,7 @@ the Symmetric-Key Encrypted Session Key packet.

      Source:
      diff --git a/docs/SymmetricallyEncryptedDataPacket.html b/docs/SymmetricallyEncryptedDataPacket.html index 6bb7cbf7..abed83b1 100644 --- a/docs/SymmetricallyEncryptedDataPacket.html +++ b/docs/SymmetricallyEncryptedDataPacket.html @@ -101,7 +101,7 @@ that form whole OpenPGP messages).

      Source:
      @@ -197,7 +197,7 @@ that form whole OpenPGP messages).

      Source:
      @@ -271,7 +271,7 @@ that form whole OpenPGP messages).

      Source:
      @@ -477,7 +477,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -720,7 +720,7 @@ See RFC 4880 9.2 f
      Source:
      diff --git a/docs/TrustPacket.html b/docs/TrustPacket.html index 81cf349d..ce94c8a7 100644 --- a/docs/TrustPacket.html +++ b/docs/TrustPacket.html @@ -105,7 +105,7 @@ other than local keyring files.

      Source:
      @@ -216,7 +216,7 @@ Currently not implemented as we ignore trust packets

      Source:
      diff --git a/docs/UserAttributePacket.html b/docs/UserAttributePacket.html index 93bc692e..1e3734d3 100644 --- a/docs/UserAttributePacket.html +++ b/docs/UserAttributePacket.html @@ -107,7 +107,7 @@ an implementation may use any method desired.

      Source:
      @@ -266,7 +266,7 @@ an implementation may use any method desired.

      Source:
      @@ -427,7 +427,7 @@ an implementation may use any method desired.

      Source:
      @@ -517,7 +517,7 @@ an implementation may use any method desired.

      Source:
      diff --git a/docs/UserIDPacket.html b/docs/UserIDPacket.html index c3cae23e..29e0807e 100644 --- a/docs/UserIDPacket.html +++ b/docs/UserIDPacket.html @@ -100,7 +100,7 @@ specifies the length of the User ID.

      Source:
      @@ -207,7 +207,7 @@ John Doe john@example.com

      Source:
      @@ -338,7 +338,7 @@ John Doe john@example.com

      Source:
      @@ -495,7 +495,7 @@ John Doe john@example.com

      Source:
      @@ -585,7 +585,7 @@ John Doe john@example.com

      Source:
      diff --git a/docs/global.html b/docs/global.html index dd6de10c..8769aec7 100644 --- a/docs/global.html +++ b/docs/global.html @@ -419,7 +419,7 @@
      Source:
      @@ -632,7 +632,7 @@
      Source:
      @@ -771,7 +771,7 @@
      Source:
      @@ -1180,7 +1180,7 @@
      Source:
      @@ -1761,7 +1761,7 @@ One of decryptionKeys, sessionkeys or passwords<
      Source:
      @@ -2064,7 +2064,7 @@ This method does not change the original key.

      Source:
      @@ -2423,7 +2423,7 @@ One of decryptionKeys or passwords must be specified.<
      Source:
      @@ -3227,7 +3227,7 @@ must be specified. If signing keys are specified, those will be used to sign the
      Source:
      @@ -3515,7 +3515,7 @@ This method does not change the original key.

      Source:
      @@ -4135,7 +4135,7 @@ At least one of encryptionKeys or passwords must be sp
      Source:
      @@ -4351,7 +4351,7 @@ At least one of encryptionKeys or passwords must be sp
      Source:
      @@ -4952,7 +4952,7 @@ default to main key options, except for sign parameter that default
      Source:
      @@ -5302,7 +5302,7 @@ default to main key options, except for sign parameter that default
      Source:
      @@ -5463,7 +5463,7 @@ default to main key options, except for sign parameter that default
      Source:
      @@ -5602,7 +5602,7 @@ default to main key options, except for sign parameter that default
      Source:
      @@ -5741,7 +5741,7 @@ default to main key options, except for sign parameter that default
      Source:
      @@ -5891,7 +5891,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -6071,7 +6071,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -6215,7 +6215,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -6405,7 +6405,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -6797,7 +6797,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -7038,7 +7038,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -7326,7 +7326,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -7614,7 +7614,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -7908,7 +7908,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -8196,7 +8196,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -8484,7 +8484,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -8772,7 +8772,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -9234,7 +9234,7 @@ to set the same date as the key creation time to ensure that old message signatu
      Source:
      @@ -9763,7 +9763,7 @@ If a revocation certificate is passed, the reasonForRevocation parameter will be
      Source:
      @@ -9978,7 +9978,7 @@ If a revocation certificate is passed, the reasonForRevocation parameter will be
      Source:
      @@ -10527,7 +10527,7 @@ If a revocation certificate is passed, the reasonForRevocation parameter will be
      Source:
      @@ -10689,7 +10689,7 @@ the encoded bytes

      Source:
      @@ -11151,7 +11151,7 @@ an attribute "data" containing a stream of bytes and "type"
      Source:
      @@ -11396,7 +11396,7 @@ The new key includes a revocation certificate that must be removed before return
      Source:
      @@ -11576,7 +11576,7 @@ The new key includes a revocation certificate that must be removed before return
      Source:
      diff --git a/docs/module-config.html b/docs/module-config.html index 30f51dd9..0b618fcc 100644 --- a/docs/module-config.html +++ b/docs/module-config.html @@ -89,7 +89,7 @@
      Source:
      @@ -247,7 +247,7 @@ as a global config setting, but can be used for specific function calls (e.g. de
      Source:
      @@ -365,7 +365,7 @@ Must be an integer value from 0 to 56.

      Source:
      @@ -489,7 +489,7 @@ Note: not all OpenPGP implementations are compatible with this option.
      Source:
      @@ -614,7 +614,7 @@ where key flags were ignored when selecting a key for encryption.

      Source:
      @@ -733,7 +733,7 @@ and have self-signature's creation date that does not match the primary key crea
      Source:
      @@ -854,7 +854,7 @@ This is an insecure setting:

      Source:
      @@ -979,7 +979,7 @@ and deferring checking their integrity until the decrypted stream has been read
      Source:
      @@ -1091,7 +1091,7 @@ and deferring checking their integrity until the decrypted stream has been read
      Source:
      @@ -1213,7 +1213,7 @@ See also constantTimePKCS1DecryptionSupportedSymmetricAlgorithms.Source:
      @@ -1331,7 +1331,7 @@ However, the more algorithms are added, the slower the decryption procedure beco
      Source:
      @@ -1443,7 +1443,7 @@ However, the more algorithms are added, the slower the decryption procedure beco
      Source:
      @@ -1555,7 +1555,7 @@ However, the more algorithms are added, the slower the decryption procedure beco
      Source:
      @@ -1672,7 +1672,7 @@ validation error when the notation is marked as critical.

      Source:
      @@ -1788,7 +1788,7 @@ validation error when the notation is marked as critical.

      Source:
      @@ -1905,7 +1905,7 @@ The default is 2047 since due to a bug, previous versions of OpenPGP.js could ge
      Source:
      @@ -2022,7 +2022,7 @@ The default is 2047 since due to a bug, previous versions of OpenPGP.js could ge
      Source:
      @@ -2139,7 +2139,7 @@ Only has an effect when aeadProtect is set to true.

      Source:
      @@ -2251,7 +2251,7 @@ Only has an effect when aeadProtect is set to true.

      Source:
      @@ -2363,7 +2363,7 @@ Only has an effect when aeadProtect is set to true.

      Source:
      @@ -2475,7 +2475,7 @@ Only has an effect when aeadProtect is set to true.

      Source:
      @@ -2591,7 +2591,7 @@ Only has an effect when aeadProtect is set to true.

      Source:
      @@ -2707,7 +2707,7 @@ Only has an effect when aeadProtect is set to true.

      Source:
      @@ -2823,7 +2823,7 @@ Only has an effect when aeadProtect is set to true.

      Source:
      @@ -2939,7 +2939,7 @@ Only has an effect when aeadProtect is set to true.

      Source:
      @@ -3154,7 +3154,7 @@ For more details on the choice of parameters, see https://tools.ietf.org/html/rf
      Source:
      @@ -3273,7 +3273,7 @@ Note: this is the exponent value, not the final number of iterations (refer to s
      Source:
      @@ -3395,7 +3395,7 @@ Note: Argon2 is the strongest option but not all OpenPGP implementations are com
      Source:
      @@ -3507,7 +3507,7 @@ Note: Argon2 is the strongest option but not all OpenPGP implementations are com
      Source:
      @@ -3619,7 +3619,7 @@ Note: Argon2 is the strongest option but not all OpenPGP implementations are com
      Source:
      @@ -3736,7 +3736,7 @@ When false, certain standard curves will not be supported (depending on the plat
      Source:
      @@ -3854,7 +3854,7 @@ Note: not all OpenPGP implementations are compatible with this option.
      Source:
      @@ -3966,7 +3966,7 @@ Note: not all OpenPGP implementations are compatible with this option.
      Source:
      diff --git a/docs/module-crypto.html b/docs/module-crypto.html index 791cc4a9..732727f8 100644 --- a/docs/module-crypto.html +++ b/docs/module-crypto.html @@ -89,7 +89,7 @@
      Source:
      diff --git a/docs/module-crypto_aes_kw.html b/docs/module-crypto_aes_kw.html index a26c710d..5e0decfe 100644 --- a/docs/module-crypto_aes_kw.html +++ b/docs/module-crypto_aes_kw.html @@ -89,7 +89,7 @@
      Source:
      @@ -308,7 +308,7 @@
      Source:
      @@ -521,7 +521,7 @@
      Source:
      diff --git a/docs/module-crypto_cmac.html b/docs/module-crypto_cmac.html index 162cbde8..817189aa 100644 --- a/docs/module-crypto_cmac.html +++ b/docs/module-crypto_cmac.html @@ -90,7 +90,7 @@ native AES-CBC using either the WebCrypto API or Node.js' crypto API.

      Source:
      @@ -195,7 +195,7 @@ The OMAC authors indicate that they will promulgate this modification
      Source:
      @@ -352,7 +352,7 @@ simplify the implementation.

      Source:
      diff --git a/docs/module-crypto_crypto.html b/docs/module-crypto_crypto.html index 44d1ad3c..fb44263a 100644 --- a/docs/module-crypto_crypto.html +++ b/docs/module-crypto_crypto.html @@ -90,7 +90,7 @@ well as key generation and parameter handling for all public-key cryptosystems.<
      Source:
      @@ -296,7 +296,7 @@ well as key generation and parameter handling for all public-key cryptosystems.<
      Source:
      @@ -458,7 +458,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -619,7 +619,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -848,7 +848,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -1030,7 +1030,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -1170,7 +1170,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -1354,7 +1354,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -1561,7 +1561,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -1745,7 +1745,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -2075,7 +2075,7 @@ See RFC 4880 5.5.3Source:
      @@ -2361,7 +2361,7 @@ See RFC 4880 9.1 f
      Source:
      @@ -2545,7 +2545,7 @@ See RFC 4880 9.1 f
      Source:
      @@ -2752,7 +2752,7 @@ See RFC 4880 9.1 f
      Source:
      @@ -2913,7 +2913,7 @@ See RFC 4880 9.1 f
      Source:
      diff --git a/docs/module-crypto_hash.html b/docs/module-crypto_hash.html index 808e8b87..f967e6cf 100644 --- a/docs/module-crypto_hash.html +++ b/docs/module-crypto_hash.html @@ -89,7 +89,7 @@
      Source:
      @@ -191,7 +191,7 @@
      Source:
      @@ -352,7 +352,7 @@
      Source:
      @@ -513,7 +513,7 @@
      Source:
      diff --git a/docs/module-crypto_hkdf.html b/docs/module-crypto_hkdf.html index 17c7dad0..b4462118 100644 --- a/docs/module-crypto_hkdf.html +++ b/docs/module-crypto_hkdf.html @@ -89,7 +89,7 @@
      Source:
      diff --git a/docs/module-crypto_mode.html b/docs/module-crypto_mode.html index f979ec2c..6f422ea0 100644 --- a/docs/module-crypto_mode.html +++ b/docs/module-crypto_mode.html @@ -89,7 +89,7 @@
      Source:
      @@ -182,7 +182,7 @@
      Source:
      @@ -249,7 +249,7 @@
      Source:
      @@ -316,7 +316,7 @@
      Source:
      @@ -383,7 +383,7 @@
      Source:
      diff --git a/docs/module-crypto_mode_cfb.html b/docs/module-crypto_mode_cfb.html index 1ae71358..aeedf8e6 100644 --- a/docs/module-crypto_mode_cfb.html +++ b/docs/module-crypto_mode_cfb.html @@ -236,7 +236,7 @@
      Source:
      @@ -477,7 +477,7 @@
      Source:
      diff --git a/docs/module-crypto_mode_eax.html b/docs/module-crypto_mode_eax.html index 0a549bd4..e91b2f8b 100644 --- a/docs/module-crypto_mode_eax.html +++ b/docs/module-crypto_mode_eax.html @@ -90,7 +90,7 @@ native AES-CTR using either the WebCrypto API or Node.js' crypto API.

      Source:
      @@ -296,7 +296,7 @@ native AES-CTR using either the WebCrypto API or Node.js' crypto API.

      Source:
      @@ -480,7 +480,7 @@ native AES-CTR using either the WebCrypto API or Node.js' crypto API.

      Source:
      @@ -665,7 +665,7 @@ native AES-CTR using either the WebCrypto API or Node.js' crypto API.

      Source:
      diff --git a/docs/module-crypto_mode_gcm.html b/docs/module-crypto_mode_gcm.html index 76b78e1c..e855263c 100644 --- a/docs/module-crypto_mode_gcm.html +++ b/docs/module-crypto_mode_gcm.html @@ -90,7 +90,7 @@ the WebCrypto api as well as node.js' crypto api.

      Source:
      @@ -273,7 +273,7 @@ the WebCrypto api as well as node.js' crypto api.

      Source:
      diff --git a/docs/module-crypto_mode_ocb.html b/docs/module-crypto_mode_ocb.html index 420bcad2..d0519205 100644 --- a/docs/module-crypto_mode_ocb.html +++ b/docs/module-crypto_mode_ocb.html @@ -89,7 +89,7 @@
      Source:
      @@ -295,7 +295,7 @@
      Source:
      @@ -502,7 +502,7 @@
      Source:
      @@ -686,7 +686,7 @@
      Source:
      diff --git a/docs/module-crypto_pkcs1.html b/docs/module-crypto_pkcs1.html index 4e4040cb..f38a3713 100644 --- a/docs/module-crypto_pkcs1.html +++ b/docs/module-crypto_pkcs1.html @@ -89,7 +89,7 @@
      Source:
      @@ -197,7 +197,7 @@
      Source:
      @@ -358,7 +358,7 @@
      Source:
      @@ -578,7 +578,7 @@
      Source:
      @@ -792,7 +792,7 @@
      Source:
      diff --git a/docs/module-crypto_public_key.html b/docs/module-crypto_public_key.html index 24dcf64f..1675c9d9 100644 --- a/docs/module-crypto_public_key.html +++ b/docs/module-crypto_public_key.html @@ -89,7 +89,7 @@
      Source:
      @@ -182,7 +182,7 @@
      Source:
      @@ -249,7 +249,7 @@
      Source:
      @@ -316,7 +316,7 @@
      Source:
      @@ -383,7 +383,7 @@
      Source:
      diff --git a/docs/module-crypto_public_key_dsa.html b/docs/module-crypto_public_key_dsa.html index 1d932e11..0f14596c 100644 --- a/docs/module-crypto_public_key_dsa.html +++ b/docs/module-crypto_public_key_dsa.html @@ -89,7 +89,7 @@
      Source:
      @@ -188,7 +188,7 @@ Expect y == y'

      Source:
      @@ -434,7 +434,7 @@ Expect y == y'

      Source:
      @@ -683,7 +683,7 @@ Expect y == y'

      Source:
      @@ -1005,7 +1005,7 @@ Expect y == y'

      Source:
      diff --git a/docs/module-crypto_public_key_elgamal.html b/docs/module-crypto_public_key_elgamal.html index c69d3541..a3d026fd 100644 --- a/docs/module-crypto_public_key_elgamal.html +++ b/docs/module-crypto_public_key_elgamal.html @@ -89,7 +89,7 @@
      Source:
      @@ -188,7 +188,7 @@ Expect y == y'

      Source:
      @@ -412,7 +412,7 @@ Expect y == y'

      Source:
      @@ -672,7 +672,7 @@ Note that in OpenPGP, the message needs to be padded with PKCS#1 (same as RSA)Source:
      @@ -898,7 +898,7 @@ Note that in OpenPGP, the message needs to be padded with PKCS#1 (same as RSA)Source:
      diff --git a/docs/module-crypto_public_key_elliptic.html b/docs/module-crypto_public_key_elliptic.html index d23d6a90..67255ff1 100644 --- a/docs/module-crypto_public_key_elliptic.html +++ b/docs/module-crypto_public_key_elliptic.html @@ -89,7 +89,7 @@
      Source:
      diff --git a/docs/module-crypto_public_key_elliptic_curve.html b/docs/module-crypto_public_key_elliptic_curve.html index 90d41f65..4c764f79 100644 --- a/docs/module-crypto_public_key_elliptic_curve.html +++ b/docs/module-crypto_public_key_elliptic_curve.html @@ -89,7 +89,7 @@
      Source:
      @@ -201,7 +201,7 @@ NB: this function does not check e.g. whether the point belongs to the curve.

      Source:
      @@ -340,7 +340,7 @@ NB: this function does not check e.g. whether the point belongs to the curve.

      Source:
      @@ -497,7 +497,7 @@ NB: this function does not check e.g. whether the point belongs to the curve.

      Source:
      @@ -723,7 +723,7 @@ NB: this function does not check e.g. whether the point belongs to the curve.

      Source:
      @@ -926,7 +926,7 @@ NB: this function does not check e.g. whether the point belongs to the curve.

      Source:
      @@ -1157,7 +1157,7 @@ Not suitable for EdDSA (different secret key format)

      Source:
      diff --git a/docs/module-crypto_public_key_elliptic_ecdh.html b/docs/module-crypto_public_key_elliptic_ecdh.html index fa26bf5a..d87dd699 100644 --- a/docs/module-crypto_public_key_elliptic_ecdh.html +++ b/docs/module-crypto_public_key_elliptic_ecdh.html @@ -91,7 +91,7 @@
      Source:
      @@ -169,7 +169,7 @@
      Source:
      @@ -467,7 +467,7 @@
      Source:
      @@ -720,7 +720,7 @@
      Source:
      @@ -973,7 +973,7 @@
      Source:
      @@ -1176,7 +1176,7 @@
      Source:
      @@ -1337,7 +1337,7 @@
      Source:
      @@ -1445,7 +1445,7 @@
      Source:
      @@ -1652,7 +1652,7 @@
      Source:
      @@ -1859,7 +1859,7 @@
      Source:
      @@ -2089,7 +2089,7 @@
      Source:
      @@ -2269,7 +2269,7 @@
      Source:
      @@ -2472,7 +2472,7 @@
      Source:
      @@ -2652,7 +2652,7 @@
      Source:
      @@ -2878,7 +2878,7 @@
      Source:
      @@ -3058,7 +3058,7 @@
      Source:
      @@ -3189,7 +3189,7 @@
      Source:
      @@ -3267,7 +3267,7 @@
      Source:
      @@ -3565,7 +3565,7 @@
      Source:
      @@ -3818,7 +3818,7 @@
      Source:
      @@ -4071,7 +4071,7 @@
      Source:
      @@ -4274,7 +4274,7 @@
      Source:
      @@ -4435,7 +4435,7 @@
      Source:
      @@ -4543,7 +4543,7 @@
      Source:
      @@ -4750,7 +4750,7 @@
      Source:
      @@ -4957,7 +4957,7 @@
      Source:
      @@ -5187,7 +5187,7 @@
      Source:
      @@ -5367,7 +5367,7 @@
      Source:
      @@ -5570,7 +5570,7 @@
      Source:
      @@ -5750,7 +5750,7 @@
      Source:
      @@ -5976,7 +5976,7 @@
      Source:
      @@ -6156,7 +6156,7 @@
      Source:
      diff --git a/docs/module-crypto_public_key_elliptic_ecdsa.html b/docs/module-crypto_public_key_elliptic_ecdsa.html index a3ab7d7d..4d62b446 100644 --- a/docs/module-crypto_public_key_elliptic_ecdsa.html +++ b/docs/module-crypto_public_key_elliptic_ecdsa.html @@ -89,7 +89,7 @@
      Source:
      @@ -364,7 +364,7 @@
      Source:
      @@ -571,7 +571,7 @@
      Source:
      @@ -847,7 +847,7 @@
      Source:
      @@ -956,7 +956,7 @@ To be used if no native implementation is available for the given curve/operatio
      Source:
      diff --git a/docs/module-crypto_public_key_elliptic_eddsa.html b/docs/module-crypto_public_key_elliptic_eddsa.html index a3c355b7..bf98d533 100644 --- a/docs/module-crypto_public_key_elliptic_eddsa.html +++ b/docs/module-crypto_public_key_elliptic_eddsa.html @@ -89,7 +89,7 @@
      Source:
      @@ -249,7 +249,7 @@
      Source:
      @@ -521,7 +521,7 @@
      Source:
      @@ -751,7 +751,7 @@
      Source:
      @@ -1027,7 +1027,7 @@
      Source:
      diff --git a/docs/module-crypto_public_key_elliptic_eddsa_legacy.html b/docs/module-crypto_public_key_elliptic_eddsa_legacy.html index 843291f6..fe2e5ff2 100644 --- a/docs/module-crypto_public_key_elliptic_eddsa_legacy.html +++ b/docs/module-crypto_public_key_elliptic_eddsa_legacy.html @@ -90,7 +90,7 @@ This key type has been deprecated by the crypto-refresh RFC.

      Source:
      @@ -365,7 +365,7 @@ This key type has been deprecated by the crypto-refresh RFC.

      Source:
      @@ -572,7 +572,7 @@ This key type has been deprecated by the crypto-refresh RFC.

      Source:
      @@ -848,7 +848,7 @@ This key type has been deprecated by the crypto-refresh RFC.

      Source:
      diff --git a/docs/module-crypto_public_key_rsa.html b/docs/module-crypto_public_key_rsa.html index 9c159eb1..ca343f70 100644 --- a/docs/module-crypto_public_key_rsa.html +++ b/docs/module-crypto_public_key_rsa.html @@ -89,7 +89,7 @@
      Source:
      @@ -411,7 +411,7 @@
      Source:
      @@ -647,7 +647,7 @@
      Source:
      @@ -833,7 +833,7 @@
      Source:
      @@ -1186,7 +1186,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

      Source:
      @@ -1462,7 +1462,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

      Source:
      @@ -1738,7 +1738,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

      Source:
      @@ -1846,7 +1846,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

      Source:
      @@ -2123,7 +2123,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

      Source:
      @@ -2308,7 +2308,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

      Source:
      diff --git a/docs/module-crypto_random.html b/docs/module-crypto_random.html index 589e17c2..f3ecd169 100644 --- a/docs/module-crypto_random.html +++ b/docs/module-crypto_random.html @@ -89,7 +89,7 @@
      Source:
      @@ -272,7 +272,7 @@
      Source:
      @@ -433,7 +433,7 @@
      Source:
      diff --git a/docs/module-crypto_signature.html b/docs/module-crypto_signature.html index 40cdc169..a2088487 100644 --- a/docs/module-crypto_signature.html +++ b/docs/module-crypto_signature.html @@ -89,7 +89,7 @@
      Source:
      @@ -276,7 +276,7 @@ See RFC 4880 5.2.2.<
      Source:
      @@ -555,7 +555,7 @@ for public key and hash algorithms.

      Source:
      @@ -834,7 +834,7 @@ for public key and hash algorithms.

      Source:
      diff --git a/docs/module-encoding_base64.html b/docs/module-encoding_base64.html index a5fca60e..6d2bb183 100644 --- a/docs/module-encoding_base64.html +++ b/docs/module-encoding_base64.html @@ -168,7 +168,7 @@
      Source:
      @@ -332,7 +332,7 @@
      Source:
      @@ -499,7 +499,7 @@
      Source:
      @@ -686,7 +686,7 @@
      Source:
      diff --git a/docs/module-enums.html b/docs/module-enums.html index 5a5a1151..3741e708 100644 --- a/docs/module-enums.html +++ b/docs/module-enums.html @@ -235,7 +235,7 @@
      Source:
      @@ -499,7 +499,7 @@
      Source:
      @@ -694,7 +694,7 @@
      Source:
      @@ -1119,7 +1119,7 @@
      Source:
      @@ -1323,7 +1323,7 @@ fingerprint format

      Source:
      @@ -1633,7 +1633,7 @@ fingerprint format

      Source:
      @@ -1899,7 +1899,7 @@ possession of more than one person.

      Source:
      @@ -2094,7 +2094,7 @@ possession of more than one person.

      Source:
      @@ -2634,7 +2634,7 @@ possession of more than one person.

      Source:
      @@ -3060,7 +3060,7 @@ possession of more than one person.

      Source:
      @@ -3278,7 +3278,7 @@ possession of more than one person.

      Source:
      @@ -3496,7 +3496,7 @@ possession of more than one person.

      Source:
      @@ -4013,7 +4013,7 @@ document) that cannot include a target subpacket.

      Source:
      @@ -4737,7 +4737,7 @@ document) that cannot include a target subpacket.

      Source:
      @@ -5024,7 +5024,7 @@ document) that cannot include a target subpacket.

      Source:
      @@ -5220,7 +5220,7 @@ document) that cannot include a target subpacket.

      Source:
      @@ -5374,7 +5374,7 @@ document) that cannot include a target subpacket.

      Source:
      @@ -5590,7 +5590,7 @@ document) that cannot include a target subpacket.

      Source:
      diff --git a/docs/module-key_Subkey-Subkey.html b/docs/module-key_Subkey-Subkey.html index f7684bba..75e2b191 100644 --- a/docs/module-key_Subkey-Subkey.html +++ b/docs/module-key_Subkey-Subkey.html @@ -171,7 +171,7 @@
      Source:
      @@ -281,7 +281,7 @@
      Source:
      @@ -394,7 +394,7 @@
      Source:
      @@ -511,7 +511,7 @@
      Source:
      @@ -628,7 +628,7 @@
      Source:
      @@ -741,7 +741,7 @@
      Source:
      @@ -942,7 +942,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -1055,7 +1055,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -1172,7 +1172,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -1289,7 +1289,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -1406,7 +1406,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -1523,7 +1523,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -1640,7 +1640,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -1757,7 +1757,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -1873,7 +1873,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -2149,7 +2149,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -2487,7 +2487,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -2599,7 +2599,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -2832,7 +2832,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -3044,7 +3044,7 @@ and valid binding signature.

      Source:
      diff --git a/docs/module-key_User-User.html b/docs/module-key_User-User.html index e9f14f35..eddb767a 100644 --- a/docs/module-key_User-User.html +++ b/docs/module-key_User-User.html @@ -171,7 +171,7 @@
      Source:
      @@ -404,7 +404,7 @@
      Source:
      @@ -516,7 +516,7 @@
      Source:
      @@ -789,7 +789,7 @@
      Source:
      @@ -1127,7 +1127,7 @@
      Source:
      @@ -1239,7 +1239,7 @@
      Source:
      @@ -1442,7 +1442,7 @@
      Source:
      @@ -1623,7 +1623,7 @@ and validity of self signature.

      Source:
      @@ -1887,7 +1887,7 @@ and validity of self signature.

      Source:
      @@ -2154,7 +2154,7 @@ Signature validity is null if the verification keys do not correspond to the cer
      Source:
      diff --git a/docs/module-key_helper.html b/docs/module-key_helper.html index 1b6d0762..f837c1e5 100644 --- a/docs/module-key_helper.html +++ b/docs/module-key_helper.html @@ -89,7 +89,7 @@
      Source:
      @@ -281,7 +281,7 @@
      Source:
      @@ -518,7 +518,7 @@
      Source:
      @@ -928,7 +928,7 @@
      Source:
      @@ -1116,7 +1116,7 @@ The expiration time of the signature is ignored.

      Source:
      @@ -1376,7 +1376,7 @@ The expiration time of the signature is ignored.

      Source:
      @@ -1648,7 +1648,7 @@ The expiration time of the signature is ignored.

      Source:
      @@ -1920,7 +1920,7 @@ The expiration time of the signature is ignored.

      Source:
      @@ -2224,7 +2224,7 @@ The expiration time of the signature is ignored.

      Source:
      @@ -2531,7 +2531,7 @@ The expiration time of the signature is ignored.

      Source:
      @@ -2830,7 +2830,7 @@ The expiration time of the signature is ignored.

      Source:
      diff --git a/docs/module-packet_packet.html b/docs/module-packet_packet.html index 9fc00c19..8071dce5 100644 --- a/docs/module-packet_packet.html +++ b/docs/module-packet_packet.html @@ -89,7 +89,7 @@
      Source:
      @@ -275,7 +275,7 @@
      Source:
      @@ -436,7 +436,7 @@
      Source:
      @@ -621,7 +621,7 @@ string

      Source:
      @@ -783,7 +783,7 @@ string

      Source:
      diff --git a/docs/module-type_ecdh_symkey.html b/docs/module-type_ecdh_symkey.html index 182d51ec..d74d3d40 100644 --- a/docs/module-type_ecdh_symkey.html +++ b/docs/module-type_ecdh_symkey.html @@ -89,7 +89,7 @@
      Source:
      diff --git a/docs/module-type_kdf_params-KDFParams.html b/docs/module-type_kdf_params-KDFParams.html index e75a3931..89cf9c4a 100644 --- a/docs/module-type_kdf_params-KDFParams.html +++ b/docs/module-type_kdf_params-KDFParams.html @@ -163,7 +163,7 @@
      Source:
      @@ -322,7 +322,7 @@
      Source:
      @@ -434,7 +434,7 @@
      Source:
      diff --git a/docs/module-type_keyid-KeyID.html b/docs/module-type_keyid-KeyID.html index edff315f..7043255c 100644 --- a/docs/module-type_keyid-KeyID.html +++ b/docs/module-type_keyid-KeyID.html @@ -101,7 +101,7 @@ formed.

      Source:
      @@ -295,7 +295,7 @@ formed.

      Source:
      @@ -385,7 +385,7 @@ formed.

      Source:
      @@ -497,7 +497,7 @@ formed.

      Source:
      @@ -658,7 +658,7 @@ formed.

      Source:
      @@ -748,7 +748,7 @@ formed.

      Source:
      @@ -860,7 +860,7 @@ formed.

      Source:
      diff --git a/docs/module-type_oid.html b/docs/module-type_oid.html index e81019c0..80fffeab 100644 --- a/docs/module-type_oid.html +++ b/docs/module-type_oid.html @@ -100,7 +100,7 @@ sequence of octets is the valid representation of a curve OID.

      Source:
      diff --git a/docs/module-type_s2k-GenericS2K.html b/docs/module-type_s2k-GenericS2K.html index c2bc5a00..fb86cd1f 100644 --- a/docs/module-type_s2k-GenericS2K.html +++ b/docs/module-type_s2k-GenericS2K.html @@ -153,7 +153,7 @@
      Source:
      @@ -262,7 +262,7 @@
      Source:
      @@ -332,7 +332,7 @@
      Source:
      @@ -406,7 +406,7 @@
      Source:
      @@ -480,7 +480,7 @@
      Source:
      @@ -612,7 +612,7 @@ hashAlgorithm

      Source:
      @@ -774,7 +774,7 @@ hashAlgorithm hash length

      Source:
      @@ -886,7 +886,7 @@ hashAlgorithm hash length

      Source:
      diff --git a/docs/module-type_s2k.html b/docs/module-type_s2k.html index 6bbb80b2..e083c286 100644 --- a/docs/module-type_s2k.html +++ b/docs/module-type_s2k.html @@ -95,7 +95,7 @@ symmetrically encrypted messages.

      Source:
      diff --git a/docs/module-type_x25519x448_symkey.html b/docs/module-type_x25519x448_symkey.html index 4978e8ea..35aa0976 100644 --- a/docs/module-type_x25519x448_symkey.html +++ b/docs/module-type_x25519x448_symkey.html @@ -91,7 +91,7 @@ the former includes an algorithm byte preceeding the encrypted session key.

      <
      Source:
      diff --git a/docs/module-util.html b/docs/module-util.html index f0c11d7f..9680800b 100644 --- a/docs/module-util.html +++ b/docs/module-util.html @@ -89,7 +89,7 @@
      Source:
      diff --git a/package-lock.json b/package-lock.json index 4bbb88b0..b93f82a7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "openpgp", - "version": "6.0.0-beta.3", + "version": "6.0.0-beta.3.patch.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "openpgp", - "version": "6.0.0-beta.3", + "version": "6.0.0-beta.3.patch.0", "license": "LGPL-3.0+", "devDependencies": { "@noble/ciphers": "^0.6.0", diff --git a/package.json b/package.json index 25184836..e2aae539 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "openpgp", "description": "OpenPGP.js is a Javascript implementation of the OpenPGP protocol. This is defined in RFC 4880.", - "version": "6.0.0-beta.3", + "version": "6.0.0-beta.3.patch.0", "license": "LGPL-3.0+", "homepage": "https://openpgpjs.org/", "engines": { From 0255fcba863e7a0bbdaeb41722b9addd3a736182 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Wed, 11 Sep 2024 10:39:51 +0200 Subject: [PATCH 175/201] CI: update playwright to test latest browser versions --- package-lock.json | 18 ++++++++++-------- package.json | 2 +- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index b93f82a7..103bd1a0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -50,7 +50,7 @@ "karma-mocha-reporter": "^2.2.5", "karma-webkit-launcher": "^2.6.0", "mocha": "^10.7.3", - "playwright": "^1.46.1", + "playwright": "^1.47.0", "rollup": "^4.21.2", "sinon": "^17.0.1", "ts-node": "^10.9.2", @@ -6704,12 +6704,13 @@ "dev": true }, "node_modules/playwright": { - "version": "1.46.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.46.1.tgz", - "integrity": "sha512-oPcr1yqoXLCkgKtD5eNUPLiN40rYEM39odNpIb6VE6S7/15gJmA1NzVv6zJYusV0e7tzvkU/utBFNa/Kpxmwng==", + "version": "1.47.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.47.0.tgz", + "integrity": "sha512-jOWiRq2pdNAX/mwLiwFYnPHpEZ4rM+fRSQpRHwEwZlP2PUANvL3+aJOF/bvISMhFD30rqMxUB4RJx9aQbfh4Ww==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.46.1" + "playwright-core": "1.47.0" }, "bin": { "playwright": "cli.js" @@ -6722,10 +6723,11 @@ } }, "node_modules/playwright-core": { - "version": "1.46.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.46.1.tgz", - "integrity": "sha512-h9LqIQaAv+CYvWzsZ+h3RsrqCStkBHlgo6/TJlFst3cOTlLghBQlJwPOZKQJTKNaD3QIB7aAVQ+gfWbN3NXB7A==", + "version": "1.47.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.47.0.tgz", + "integrity": "sha512-1DyHT8OqkcfCkYUD9zzUTfg7EfTd+6a8MkD/NWOvjo0u/SCNd5YmY/lJwFvUZOxJbWNds+ei7ic2+R/cRz/PDg==", "dev": true, + "license": "Apache-2.0", "bin": { "playwright-core": "cli.js" }, diff --git a/package.json b/package.json index e2aae539..01fbeabb 100644 --- a/package.json +++ b/package.json @@ -103,7 +103,7 @@ "karma-mocha-reporter": "^2.2.5", "karma-webkit-launcher": "^2.6.0", "mocha": "^10.7.3", - "playwright": "^1.46.1", + "playwright": "^1.47.0", "rollup": "^4.21.2", "sinon": "^17.0.1", "ts-node": "^10.9.2", From 2b9a07e8405566622dca3d637dedb0b045c0097d Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Wed, 11 Sep 2024 10:42:37 +0200 Subject: [PATCH 176/201] Run npm audit --- package-lock.json | 92 ++++++++++++++++++++++------------------------- package.json | 2 +- 2 files changed, 44 insertions(+), 50 deletions(-) diff --git a/package-lock.json b/package-lock.json index 103bd1a0..54ff5644 100644 --- a/package-lock.json +++ b/package-lock.json @@ -52,7 +52,7 @@ "mocha": "^10.7.3", "playwright": "^1.47.0", "rollup": "^4.21.2", - "sinon": "^17.0.1", + "sinon": "^18.0.1", "ts-node": "^10.9.2", "tslib": "^2.7.0", "tsx": "^4.19.0", @@ -1377,26 +1377,19 @@ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "type-detect": "4.0.8" } }, - "node_modules/@sinonjs/commons/node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/@sinonjs/fake-timers": { - "version": "11.3.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.3.1.tgz", - "integrity": "sha512-EVJO7nW5M/F5Tur0Rf2z/QoMo+1Ia963RiMtapiQrEWvY0iBUvADo8Beegwjpnle5BHkyHuoxSTW3jF43H1XRA==", + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", + "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "@sinonjs/commons": "^3.0.1" + "@sinonjs/commons": "^3.0.0" } }, "node_modules/@sinonjs/samsam": { @@ -1419,20 +1412,12 @@ "type-detect": "4.0.8" } }, - "node_modules/@sinonjs/samsam/node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/@sinonjs/text-encoding": { "version": "0.7.3", "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.3.tgz", "integrity": "sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA==", - "dev": true + "dev": true, + "license": "(Unlicense OR Apache-2.0)" }, "node_modules/@socket.io/component-emitter": { "version": "3.1.2", @@ -2171,10 +2156,11 @@ "dev": true }, "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", "dev": true, + "license": "MIT", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", @@ -2184,7 +2170,7 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.11.0", + "qs": "6.13.0", "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" @@ -5418,7 +5404,8 @@ "version": "6.2.0", "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/karma": { "version": "6.4.4", @@ -6318,16 +6305,17 @@ } }, "node_modules/nise": { - "version": "5.1.9", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.9.tgz", - "integrity": "sha512-qOnoujW4SV6e40dYxJOb3uvuoPHtmLzIk4TFo+j0jPJoC+5Z9xja5qH5JZobEPsa8+YYphMrOSwnrshEhG2qww==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/nise/-/nise-6.0.1.tgz", + "integrity": "sha512-DAyWGPQEuJVlL2eqKw6gdZKT+E/jo/ZrjEUDAslJLluCz81nWy+KSYybNp3KFm887Yvp7hv12jSM82ld8BmLxg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@sinonjs/commons": "^3.0.0", "@sinonjs/fake-timers": "^11.2.2", "@sinonjs/text-encoding": "^0.7.2", "just-extend": "^6.2.0", - "path-to-regexp": "^6.2.1" + "path-to-regexp": "^8.1.0" } }, "node_modules/normalize-package-data": { @@ -6647,10 +6635,14 @@ "dev": true }, "node_modules/path-to-regexp": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", - "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", - "dev": true + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.1.0.tgz", + "integrity": "sha512-Bqn3vc8CMHty6zuD+tG23s6v2kwxslHEhTj4eYaVKGIEB+YX/2wd0/rgXLFD9G9id9KCtbVy/3ZgmvZjpa0UdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + } }, "node_modules/path-type": { "version": "4.0.0", @@ -6865,12 +6857,13 @@ } }, "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.0.4" + "side-channel": "^1.0.6" }, "engines": { "node": ">=0.6" @@ -7473,17 +7466,18 @@ "dev": true }, "node_modules/sinon": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.1.tgz", - "integrity": "sha512-wmwE19Lie0MLT+ZYNpDymasPHUKTaZHUH/pKEubRXIzySv9Atnlw+BUMGCzWgV7b7wO+Hw6f1TEOr0IUnmU8/g==", + "version": "18.0.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-18.0.1.tgz", + "integrity": "sha512-a2N2TDY1uGviajJ6r4D1CyRAkzE9NNVlYOV1wX5xQDuAk0ONgzgRl0EjCQuRCPxOwp13ghsMwt9Gdldujs39qw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "@sinonjs/commons": "^3.0.0", - "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/commons": "^3.0.1", + "@sinonjs/fake-timers": "11.2.2", "@sinonjs/samsam": "^8.0.0", - "diff": "^5.1.0", - "nise": "^5.1.5", - "supports-color": "^7.2.0" + "diff": "^5.2.0", + "nise": "^6.0.0", + "supports-color": "^7" }, "funding": { "type": "opencollective", diff --git a/package.json b/package.json index 01fbeabb..6366c68d 100644 --- a/package.json +++ b/package.json @@ -105,7 +105,7 @@ "mocha": "^10.7.3", "playwright": "^1.47.0", "rollup": "^4.21.2", - "sinon": "^17.0.1", + "sinon": "^18.0.1", "ts-node": "^10.9.2", "tslib": "^2.7.0", "tsx": "^4.19.0", From ccb040ae96acd127a29161ffaf3b82b5b18c062f Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Wed, 11 Sep 2024 10:50:50 +0200 Subject: [PATCH 177/201] Revert to not using the WebCrypto for X25519 (ECDH only) Due to missing support in WebKit and Chrome (without experimental flags), and broken support in Firefox, for now we go back to using a JS implementation. This change only affects encryption and decryption using X25519. For signing and verification using Ed25519 we keep relying on WebCrypto when available (namely in WebKit, Firefox, and Node). --- src/crypto/public_key/elliptic/ecdh_x.js | 107 +++-------------------- 1 file changed, 13 insertions(+), 94 deletions(-) diff --git a/src/crypto/public_key/elliptic/ecdh_x.js b/src/crypto/public_key/elliptic/ecdh_x.js index 1dfc96e8..a7bf3bd5 100644 --- a/src/crypto/public_key/elliptic/ecdh_x.js +++ b/src/crypto/public_key/elliptic/ecdh_x.js @@ -11,7 +11,6 @@ import enums from '../../../enums'; import util from '../../../util'; import computeHKDF from '../../hkdf'; import { getCipherParams } from '../../cipher'; -import { b64ToUint8Array, uint8ArrayToB64 } from '../../../encoding/base64'; const HKDF_INFO = { x25519: util.encodeUTF8('OpenPGP X25519'), @@ -25,27 +24,12 @@ const HKDF_INFO = { */ export async function generate(algo) { switch (algo) { - case enums.publicKey.x25519: - try { - const webCrypto = util.getWebCrypto(); - const webCryptoKey = await webCrypto.generateKey('X25519', true, ['deriveKey', 'deriveBits']); - - const privateKey = await webCrypto.exportKey('jwk', webCryptoKey.privateKey); - const publicKey = await webCrypto.exportKey('jwk', webCryptoKey.publicKey); - - return { - A: new Uint8Array(b64ToUint8Array(publicKey.x)), - k: b64ToUint8Array(privateKey.d, true) - }; - } catch (err) { - if (err.name !== 'NotSupportedError') { - throw err; - } - // k stays in little-endian, unlike legacy ECDH over curve25519 - const k = getRandomBytes(32); - const { publicKey: A } = x25519.box.keyPair.fromSecretKey(k); - return { A, k }; - } + case enums.publicKey.x25519: { + // k stays in little-endian, unlike legacy ECDH over curve25519 + const k = getRandomBytes(32); + const { publicKey: A } = x25519.box.keyPair.fromSecretKey(k); + return { A, k }; + } case enums.publicKey.x448: { const x448 = await util.getNobleCurve(enums.publicKey.x448); @@ -187,32 +171,13 @@ export function getPayloadSize(algo) { */ export async function generateEphemeralEncryptionMaterial(algo, recipientA) { switch (algo) { - case enums.publicKey.x25519: - try { - const webCrypto = util.getWebCrypto(); - const jwk = publicKeyToJWK(algo, recipientA); - const ephemeralKeyPair = await webCrypto.generateKey('X25519', true, ['deriveKey', 'deriveBits']); - const recipientPublicKey = await webCrypto.importKey('jwk', jwk, 'X25519', false, []); - const sharedSecretBuffer = await webCrypto.deriveBits( - { name: 'X25519', public: recipientPublicKey }, - ephemeralKeyPair.privateKey, - getPayloadSize(algo) * 8 // in bits - ); - const ephemeralPublicKeyJwt = await webCrypto.exportKey('jwk', ephemeralKeyPair.publicKey); - return { - sharedSecret: new Uint8Array(sharedSecretBuffer), - ephemeralPublicKey: new Uint8Array(b64ToUint8Array(ephemeralPublicKeyJwt.x)) - }; - } catch (err) { - if (err.name !== 'NotSupportedError') { - throw err; - } - const ephemeralSecretKey = getRandomBytes(getPayloadSize(algo)); - const sharedSecret = x25519.scalarMult(ephemeralSecretKey, recipientA); - const { publicKey: ephemeralPublicKey } = x25519.box.keyPair.fromSecretKey(ephemeralSecretKey); + case enums.publicKey.x25519: { + const ephemeralSecretKey = getRandomBytes(getPayloadSize(algo)); + const sharedSecret = x25519.scalarMult(ephemeralSecretKey, recipientA); + const { publicKey: ephemeralPublicKey } = x25519.box.keyPair.fromSecretKey(ephemeralSecretKey); - return { ephemeralPublicKey, sharedSecret }; - } + return { ephemeralPublicKey, sharedSecret }; + } case enums.publicKey.x448: { const x448 = await util.getNobleCurve(enums.publicKey.x448); const ephemeralSecretKey = x448.utils.randomPrivateKey(); @@ -228,24 +193,7 @@ export async function generateEphemeralEncryptionMaterial(algo, recipientA) { export async function recomputeSharedSecret(algo, ephemeralPublicKey, A, k) { switch (algo) { case enums.publicKey.x25519: - try { - const webCrypto = util.getWebCrypto(); - const privateKeyJWK = privateKeyToJWK(algo, A, k); - const ephemeralPublicKeyJWK = publicKeyToJWK(algo, ephemeralPublicKey); - const privateKey = await webCrypto.importKey('jwk', privateKeyJWK, 'X25519', false, ['deriveKey', 'deriveBits']); - const ephemeralPublicKeyReference = await webCrypto.importKey('jwk', ephemeralPublicKeyJWK, 'X25519', false, []); - const sharedSecretBuffer = await webCrypto.deriveBits( - { name: 'X25519', public: ephemeralPublicKeyReference }, - privateKey, - getPayloadSize(algo) * 8 // in bits - ); - return new Uint8Array(sharedSecretBuffer); - } catch (err) { - if (err.name !== 'NotSupportedError') { - throw err; - } - return x25519.scalarMult(k, ephemeralPublicKey); - } + return x25519.scalarMult(k, ephemeralPublicKey); case enums.publicKey.x448: { const x448 = await util.getNobleCurve(enums.publicKey.x448); const sharedSecret = x448.getSharedSecret(k, ephemeralPublicKey); @@ -255,32 +203,3 @@ export async function recomputeSharedSecret(algo, ephemeralPublicKey, A, k) { throw new Error('Unsupported ECDH algorithm'); } } - - -function publicKeyToJWK(algo, publicKey) { - switch (algo) { - case enums.publicKey.x25519: { - const jwk = { - kty: 'OKP', - crv: 'X25519', - x: uint8ArrayToB64(publicKey, true), - ext: true - }; - return jwk; - } - default: - throw new Error('Unsupported ECDH algorithm'); - } -} - -function privateKeyToJWK(algo, publicKey, privateKey) { - switch (algo) { - case enums.publicKey.x25519: { - const jwk = publicKeyToJWK(algo, publicKey); - jwk.d = uint8ArrayToB64(privateKey, true); - return jwk; - } - default: - throw new Error('Unsupported ECDH algorithm'); - } -} From 148fff91e861833c6ae388867c2fa20a9b271bbe Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Wed, 11 Sep 2024 10:55:46 +0200 Subject: [PATCH 178/201] Docs: fix `type` tag warnings --- src/type/s2k/argon2.js | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/type/s2k/argon2.js b/src/type/s2k/argon2.js index f79e3ef6..84200a6b 100644 --- a/src/type/s2k/argon2.js +++ b/src/type/s2k/argon2.js @@ -33,13 +33,25 @@ class Argon2S2K { const { passes, parallelism, memoryExponent } = config.s2kArgon2Params; this.type = 'argon2'; - /** @type {Uint8Array} 16 bytes of salt */ + /** + * 16 bytes of salt + * @type {Uint8Array} + */ this.salt = null; - /** @type {Integer} number of passes */ + /** + * number of passes + * @type {Integer} + */ this.t = passes; - /** @type {Integer} degree of parallelism (lanes) */ + /** + * degree of parallelism (lanes) + * @type {Integer} + */ this.p = parallelism; - /** @type {Integer} exponent indicating memory size */ + /** + * exponent indicating memory size + * @type {Integer} + */ this.encodedM = memoryExponent; } From 6ac17dc71c0742b330e671ec448a8e714c440610 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Wed, 11 Sep 2024 10:57:20 +0200 Subject: [PATCH 179/201] 6.0.0-beta.3.patch.1 --- docs/AEADEncryptedDataPacket.html | 14 ++-- docs/Argon2S2K.html | 16 ++--- docs/CleartextMessage.html | 12 ++-- docs/CompressedDataPacket.html | 16 ++--- docs/Key.html | 56 +++++++-------- docs/LiteralDataPacket.html | 20 +++--- docs/MarkerPacket.html | 4 +- docs/Message.html | 40 +++++------ docs/OnePassSignaturePacket.html | 22 +++--- docs/PacketList.html | 14 ++-- docs/PaddingPacket.html | 8 +-- docs/PrivateKey.html | 20 +++--- docs/PublicKey.html | 8 +-- docs/PublicKeyEncryptedSessionKeyPacket.html | 14 ++-- docs/PublicKeyPacket.html | 46 ++++++------ docs/PublicSubkeyPacket.html | 46 ++++++------ docs/SecretKeyPacket.html | 72 +++++++++---------- docs/SecretSubkeyPacket.html | 72 +++++++++---------- docs/Signature.html | 8 +-- docs/SignaturePacket.html | 24 +++---- ...EncryptedIntegrityProtectedDataPacket.html | 10 +-- docs/SymEncryptedSessionKeyPacket.html | 16 ++--- docs/SymmetricallyEncryptedDataPacket.html | 10 +-- docs/TrustPacket.html | 4 +- docs/UserAttributePacket.html | 8 +-- docs/UserIDPacket.html | 10 +-- docs/global.html | 72 +++++++++---------- docs/module-config.html | 66 ++++++++--------- docs/module-crypto.html | 2 +- docs/module-crypto_aes_kw.html | 6 +- docs/module-crypto_cmac.html | 6 +- docs/module-crypto_crypto.html | 30 ++++---- docs/module-crypto_hash.html | 8 +-- docs/module-crypto_hkdf.html | 2 +- docs/module-crypto_mode.html | 10 +-- docs/module-crypto_mode_cfb.html | 4 +- docs/module-crypto_mode_eax.html | 8 +-- docs/module-crypto_mode_gcm.html | 4 +- docs/module-crypto_mode_ocb.html | 8 +-- docs/module-crypto_pkcs1.html | 10 +-- docs/module-crypto_public_key.html | 10 +-- docs/module-crypto_public_key_dsa.html | 10 +-- docs/module-crypto_public_key_elgamal.html | 10 +-- docs/module-crypto_public_key_elliptic.html | 2 +- ...dule-crypto_public_key_elliptic_curve.html | 14 ++-- ...odule-crypto_public_key_elliptic_ecdh.html | 64 ++++++++--------- ...dule-crypto_public_key_elliptic_ecdsa.html | 10 +-- ...dule-crypto_public_key_elliptic_eddsa.html | 10 +-- ...ypto_public_key_elliptic_eddsa_legacy.html | 8 +-- docs/module-crypto_public_key_rsa.html | 20 +++--- docs/module-crypto_random.html | 6 +- docs/module-crypto_signature.html | 8 +-- docs/module-encoding_base64.html | 8 +-- docs/module-enums.html | 36 +++++----- docs/module-key_Subkey-Subkey.html | 40 +++++------ docs/module-key_User-User.html | 20 +++--- docs/module-key_helper.html | 22 +++--- docs/module-packet_packet.html | 10 +-- docs/module-type_ecdh_symkey.html | 2 +- docs/module-type_kdf_params-KDFParams.html | 6 +- docs/module-type_keyid-KeyID.html | 14 ++-- docs/module-type_oid.html | 2 +- docs/module-type_s2k-GenericS2K.html | 16 ++--- docs/module-type_s2k.html | 2 +- docs/module-type_x25519x448_symkey.html | 2 +- docs/module-util.html | 2 +- package-lock.json | 4 +- package.json | 2 +- 68 files changed, 593 insertions(+), 593 deletions(-) diff --git a/docs/AEADEncryptedDataPacket.html b/docs/AEADEncryptedDataPacket.html index e2376f69..1e1678fe 100644 --- a/docs/AEADEncryptedDataPacket.html +++ b/docs/AEADEncryptedDataPacket.html @@ -98,7 +98,7 @@ AEAD Protected Data Packet

      Source:
      @@ -200,7 +200,7 @@ AEAD Protected Data Packet

      Source:
      @@ -270,7 +270,7 @@ AEAD Protected Data Packet

      Source:
      @@ -475,7 +475,7 @@ AEAD Protected Data Packet

      Source:
      @@ -717,7 +717,7 @@ AEAD Protected Data Packet

      Source:
      @@ -888,7 +888,7 @@ AEAD Protected Data Packet

      Source:
      @@ -1007,7 +1007,7 @@ AEAD Protected Data Packet

      Source:
      diff --git a/docs/Argon2S2K.html b/docs/Argon2S2K.html index 8771e2dd..71db5758 100644 --- a/docs/Argon2S2K.html +++ b/docs/Argon2S2K.html @@ -152,7 +152,7 @@
      Source:
      @@ -258,7 +258,7 @@
      Source:
      @@ -332,7 +332,7 @@
      Source:
      @@ -406,7 +406,7 @@
      Source:
      @@ -480,7 +480,7 @@
      Source:
      @@ -612,7 +612,7 @@ hashAlgorithm

      Source:
      @@ -791,7 +791,7 @@ hashAlgorithm

      Source:
      @@ -903,7 +903,7 @@ hashAlgorithm

      Source:
      diff --git a/docs/CleartextMessage.html b/docs/CleartextMessage.html index 28c7d8fb..6f620e61 100644 --- a/docs/CleartextMessage.html +++ b/docs/CleartextMessage.html @@ -168,7 +168,7 @@ See https://tools.ietf.o
      Source:
      @@ -346,7 +346,7 @@ See https://tools.ietf.o
      Source:
      @@ -461,7 +461,7 @@ See https://tools.ietf.o
      Source:
      @@ -573,7 +573,7 @@ See https://tools.ietf.o
      Source:
      @@ -974,7 +974,7 @@ See https://tools.ietf.o
      Source:
      @@ -1211,7 +1211,7 @@ See https://tools.ietf.o
      Source:
      diff --git a/docs/CompressedDataPacket.html b/docs/CompressedDataPacket.html index eeeee439..56aee417 100644 --- a/docs/CompressedDataPacket.html +++ b/docs/CompressedDataPacket.html @@ -160,7 +160,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

      Source:
      @@ -266,7 +266,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

      Source:
      @@ -343,7 +343,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

      Source:
      @@ -417,7 +417,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

      Source:
      @@ -499,7 +499,7 @@ a Signature or One-Pass Signature packet, and contains a literal data packet.

      Source:
      @@ -651,7 +651,7 @@ read by read_packet

      Source:
      @@ -836,7 +836,7 @@ read by read_packet

      Source:
      @@ -926,7 +926,7 @@ read by read_packet

      Source:
      diff --git a/docs/Key.html b/docs/Key.html index c969e643..4f4585c1 100644 --- a/docs/Key.html +++ b/docs/Key.html @@ -96,7 +96,7 @@ Can contain additional subkeys, signatures, user ids, user attributes.

      Source:
      @@ -333,7 +333,7 @@ if it is a valid revocation signature.

      Source:
      @@ -514,7 +514,7 @@ if it is a valid revocation signature.

      Source:
      @@ -626,7 +626,7 @@ if it is a valid revocation signature.

      Source:
      @@ -738,7 +738,7 @@ if it is a valid revocation signature.

      Source:
      @@ -1006,7 +1006,7 @@ if it is a valid revocation signature.

      Source:
      @@ -1225,7 +1225,7 @@ Returns Infinity if the key doesn't expire, or null if
      Source:
      @@ -1333,7 +1333,7 @@ Returns Infinity if the key doesn't expire, or null if
      Source:
      @@ -1445,7 +1445,7 @@ Returns Infinity if the key doesn't expire, or null if
      Source:
      @@ -1557,7 +1557,7 @@ Returns Infinity if the key doesn't expire, or null if
      Source:
      @@ -1735,7 +1735,7 @@ If no keyID is given, returns all keys, starting with the primary key.

      Source:
      @@ -1977,7 +1977,7 @@ algorithm preferences, and so on.

      Source:
      @@ -2220,7 +2220,7 @@ algorithm preferences, and so on.

      Source:
      @@ -2425,7 +2425,7 @@ algorithm preferences, and so on.

      Source:
      @@ -2717,7 +2717,7 @@ algorithm preferences, and so on.

      Source:
      @@ -2911,7 +2911,7 @@ If no keyID is given, returns all subkeys.

      Source:
      @@ -3023,7 +3023,7 @@ If no keyID is given, returns all subkeys.

      Source:
      @@ -3135,7 +3135,7 @@ If no keyID is given, returns all subkeys.

      Source:
      @@ -3412,7 +3412,7 @@ If no keyID is given, returns all subkeys.

      Source:
      @@ -3596,7 +3596,7 @@ If no keyID is given, returns all subkeys.

      Source:
      @@ -3811,7 +3811,7 @@ If no keyID is given, returns all subkeys.

      Source:
      @@ -4081,7 +4081,7 @@ If no keyID is given, returns all subkeys.

      Source:
      @@ -4193,7 +4193,7 @@ If no keyID is given, returns all subkeys.

      Source:
      @@ -4434,7 +4434,7 @@ a private key is returned.

      Source:
      @@ -4677,7 +4677,7 @@ a private key is returned.

      Source:
      @@ -4918,7 +4918,7 @@ and valid self signature. Throws if the primary key is invalid.

      Source:
      @@ -5201,7 +5201,7 @@ and valid self signature. Throws if the primary key is invalid.

      Source:
      @@ -5314,7 +5314,7 @@ Signature validity is null if the verification keys do not correspond to the cer
      Source:
      diff --git a/docs/LiteralDataPacket.html b/docs/LiteralDataPacket.html index ea3f0044..70c71a40 100644 --- a/docs/LiteralDataPacket.html +++ b/docs/LiteralDataPacket.html @@ -147,7 +147,7 @@ further interpreted.

      Source:
      @@ -326,7 +326,7 @@ further interpreted.

      Source:
      @@ -441,7 +441,7 @@ further interpreted.

      Source:
      @@ -623,7 +623,7 @@ with normalized end of line to \n

      Source:
      @@ -790,7 +790,7 @@ with normalized end of line to \n

      Source:
      @@ -977,7 +977,7 @@ with normalized end of line to \n

      Source:
      @@ -1116,7 +1116,7 @@ with normalized end of line to \n

      Source:
      @@ -1302,7 +1302,7 @@ will be normalized to \r\n and by default text is converted to UTF8

      Source:
      @@ -1392,7 +1392,7 @@ will be normalized to \r\n and by default text is converted to UTF8

      Source:
      @@ -1507,7 +1507,7 @@ will be normalized to \r\n and by default text is converted to UTF8

      Source:
      diff --git a/docs/MarkerPacket.html b/docs/MarkerPacket.html index 011264ca..28d65ca3 100644 --- a/docs/MarkerPacket.html +++ b/docs/MarkerPacket.html @@ -106,7 +106,7 @@ software is necessary to process the message.

      Source:
      @@ -265,7 +265,7 @@ software is necessary to process the message.

      Source:
      diff --git a/docs/Message.html b/docs/Message.html index 70303b1f..f93d7717 100644 --- a/docs/Message.html +++ b/docs/Message.html @@ -146,7 +146,7 @@ See https://tools.iet
      Source:
      @@ -661,7 +661,7 @@ See https://tools.iet
      Source:
      @@ -933,7 +933,7 @@ See https://tools.iet
      Source:
      @@ -1140,7 +1140,7 @@ See https://tools.iet
      Source:
      @@ -1291,7 +1291,7 @@ See https://tools.iet
      Source:
      @@ -1495,7 +1495,7 @@ See https://tools.iet
      Source:
      @@ -1800,7 +1800,7 @@ See https://tools.iet
      Source:
      @@ -2105,7 +2105,7 @@ See https://tools.iet
      Source:
      @@ -2545,7 +2545,7 @@ See https://tools.iet
      Source:
      @@ -2657,7 +2657,7 @@ See https://tools.iet
      Source:
      @@ -2769,7 +2769,7 @@ See https://tools.iet
      Source:
      @@ -2884,7 +2884,7 @@ See https://tools.iet
      Source:
      @@ -2999,7 +2999,7 @@ See https://tools.iet
      Source:
      @@ -3111,7 +3111,7 @@ See https://tools.iet
      Source:
      @@ -3515,7 +3515,7 @@ See https://tools.iet
      Source:
      @@ -3916,7 +3916,7 @@ See https://tools.iet
      Source:
      @@ -4028,7 +4028,7 @@ See https://tools.iet
      Source:
      @@ -4265,7 +4265,7 @@ See https://tools.iet
      Source:
      @@ -4531,7 +4531,7 @@ See https://tools.iet
      Source:
      @@ -4643,7 +4643,7 @@ See https://tools.iet
      Source:
      diff --git a/docs/OnePassSignaturePacket.html b/docs/OnePassSignaturePacket.html index 92e6bc86..93533815 100644 --- a/docs/OnePassSignaturePacket.html +++ b/docs/OnePassSignaturePacket.html @@ -101,7 +101,7 @@ can compute the entire signed message in one pass.

      Source:
      @@ -199,7 +199,7 @@ that describes another signature to be applied to the same message data.

      Source:
      @@ -273,7 +273,7 @@ that describes another signature to be applied to the same message data.

      Source:
      @@ -344,7 +344,7 @@ that describes another signature to be applied to the same message data.

      Source:
      @@ -408,7 +408,7 @@ that describes another signature to be applied to the same message data.

      Source:
      @@ -482,7 +482,7 @@ that describes another signature to be applied to the same message data.

      Source:
      @@ -553,7 +553,7 @@ that describes another signature to be applied to the same message data.

      Source:
      @@ -629,7 +629,7 @@ Signature types are described in
      Source:
      @@ -693,7 +693,7 @@ Signature types are described in
      Source:
      @@ -824,7 +824,7 @@ Signature types are described in
      Source:
      @@ -936,7 +936,7 @@ Signature types are described in
      Source:
      diff --git a/docs/PacketList.html b/docs/PacketList.html index f86282ca..f4ad9a85 100644 --- a/docs/PacketList.html +++ b/docs/PacketList.html @@ -97,7 +97,7 @@ are stored as numerical indices.

      Source:
      @@ -345,7 +345,7 @@ Equivalent to calling read on an empty PacketList instance.

      Source:
      @@ -530,7 +530,7 @@ Equivalent to calling read on an empty PacketList instance.

      Source:
      @@ -687,7 +687,7 @@ Equivalent to calling read on an empty PacketList instance.

      Source:
      @@ -859,7 +859,7 @@ Equivalent to calling read on an empty PacketList instance.

      Source:
      @@ -1097,7 +1097,7 @@ Equivalent to calling read on an empty PacketList instance.

      Source:
      @@ -1200,7 +1200,7 @@ class instance.

      Source:
      diff --git a/docs/PaddingPacket.html b/docs/PaddingPacket.html index e1225f97..aedccc51 100644 --- a/docs/PaddingPacket.html +++ b/docs/PaddingPacket.html @@ -97,7 +97,7 @@ Padding Packet

      Source:
      @@ -256,7 +256,7 @@ Padding Packet

      Source:
      @@ -427,7 +427,7 @@ Padding Packet

      Source:
      @@ -517,7 +517,7 @@ Padding Packet

      Source:
      diff --git a/docs/PrivateKey.html b/docs/PrivateKey.html index 3aed4897..16ea6745 100644 --- a/docs/PrivateKey.html +++ b/docs/PrivateKey.html @@ -144,7 +144,7 @@
      Source:
      @@ -453,7 +453,7 @@ Note: Curve448 and Curve25519 are not widely supported yet.

      Source:
      @@ -622,7 +622,7 @@ Note: Curve448 and Curve25519 are not widely supported yet.

      Source:
      @@ -734,7 +734,7 @@ Note: Curve448 and Curve25519 are not widely supported yet.

      Source:
      @@ -979,7 +979,7 @@ This is useful to retrieve keys for session key decryption

      Source:
      @@ -1121,7 +1121,7 @@ A dummy key is considered encrypted.

      Source:
      @@ -1211,7 +1211,7 @@ A dummy key is considered encrypted.

      Source:
      @@ -1514,7 +1514,7 @@ A dummy key is considered encrypted.

      Source:
      @@ -1626,7 +1626,7 @@ A dummy key is considered encrypted.

      Source:
      @@ -1803,7 +1803,7 @@ If only gnu-dummy keys are found, we cannot properly validate so we throw an err
      Source:
      diff --git a/docs/PublicKey.html b/docs/PublicKey.html index 040b6c8f..f6717ddd 100644 --- a/docs/PublicKey.html +++ b/docs/PublicKey.html @@ -144,7 +144,7 @@
      Source:
      @@ -315,7 +315,7 @@
      Source:
      @@ -427,7 +427,7 @@
      Source:
      @@ -535,7 +535,7 @@
      Source:
      diff --git a/docs/PublicKeyEncryptedSessionKeyPacket.html b/docs/PublicKeyEncryptedSessionKeyPacket.html index 772b1084..9d3b1827 100644 --- a/docs/PublicKeyEncryptedSessionKeyPacket.html +++ b/docs/PublicKeyEncryptedSessionKeyPacket.html @@ -107,7 +107,7 @@ decrypt the message.

      Source:
      @@ -209,7 +209,7 @@ decrypt the message.

      Source:
      @@ -283,7 +283,7 @@ decrypt the message.

      Source:
      @@ -458,7 +458,7 @@ This is needed for constant-time processing. Expected object of the form: { sess
      Source:
      @@ -626,7 +626,7 @@ This is needed for constant-time processing. Expected object of the form: { sess
      Source:
      @@ -794,7 +794,7 @@ This is needed for constant-time processing. Expected object of the form: { sess
      Source:
      @@ -884,7 +884,7 @@ This is needed for constant-time processing. Expected object of the form: { sess
      Source:
      diff --git a/docs/PublicKeyPacket.html b/docs/PublicKeyPacket.html index 104bfff3..d6cc0850 100644 --- a/docs/PublicKeyPacket.html +++ b/docs/PublicKeyPacket.html @@ -195,7 +195,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -301,7 +301,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -375,7 +375,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -449,7 +449,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -523,7 +523,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -597,7 +597,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -671,7 +671,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -735,7 +735,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -816,7 +816,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -880,7 +880,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -1018,7 +1018,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -1130,7 +1130,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -1220,7 +1220,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -1310,7 +1310,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -1422,7 +1422,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -1530,7 +1530,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -1642,7 +1642,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -1754,7 +1754,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -1866,7 +1866,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -1978,7 +1978,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -2138,7 +2138,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -2250,7 +2250,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      @@ -2411,7 +2411,7 @@ key (sometimes called an OpenPGP certificate).

      Source:
      diff --git a/docs/PublicSubkeyPacket.html b/docs/PublicSubkeyPacket.html index 1a1e0e09..6bd9cee6 100644 --- a/docs/PublicSubkeyPacket.html +++ b/docs/PublicSubkeyPacket.html @@ -193,7 +193,7 @@ services.

      Source:
      @@ -315,7 +315,7 @@ services.

      Source:
      @@ -394,7 +394,7 @@ services.

      Source:
      @@ -473,7 +473,7 @@ services.

      Source:
      @@ -552,7 +552,7 @@ services.

      Source:
      @@ -631,7 +631,7 @@ services.

      Source:
      @@ -710,7 +710,7 @@ services.

      Source:
      @@ -779,7 +779,7 @@ services.

      Source:
      @@ -865,7 +865,7 @@ services.

      Source:
      @@ -934,7 +934,7 @@ services.

      Source:
      @@ -1072,7 +1072,7 @@ services.

      Source:
      @@ -1189,7 +1189,7 @@ services.

      Source:
      @@ -1284,7 +1284,7 @@ services.

      Source:
      @@ -1379,7 +1379,7 @@ services.

      Source:
      @@ -1496,7 +1496,7 @@ services.

      Source:
      @@ -1609,7 +1609,7 @@ services.

      Source:
      @@ -1726,7 +1726,7 @@ services.

      Source:
      @@ -1843,7 +1843,7 @@ services.

      Source:
      @@ -1960,7 +1960,7 @@ services.

      Source:
      @@ -2077,7 +2077,7 @@ services.

      Source:
      @@ -2242,7 +2242,7 @@ services.

      Source:
      @@ -2359,7 +2359,7 @@ services.

      Source:
      @@ -2525,7 +2525,7 @@ services.

      Source:
      diff --git a/docs/SecretKeyPacket.html b/docs/SecretKeyPacket.html index 2ddb26c7..065f5ef8 100644 --- a/docs/SecretKeyPacket.html +++ b/docs/SecretKeyPacket.html @@ -191,7 +191,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -308,7 +308,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -387,7 +387,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -466,7 +466,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -545,7 +545,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -624,7 +624,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -688,7 +688,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -767,7 +767,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -831,7 +831,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -905,7 +905,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -984,7 +984,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -1053,7 +1053,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -1134,7 +1134,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -1208,7 +1208,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -1282,7 +1282,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -1361,7 +1361,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -1430,7 +1430,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -1519,7 +1519,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -1614,7 +1614,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -1709,7 +1709,7 @@ includes the secret-key material after all the public-key fields.

      Source:
      @@ -1851,7 +1851,7 @@ otherwise calls to this function will throw an error.

      Source:
      @@ -2065,7 +2065,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2189,7 +2189,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2306,7 +2306,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2419,7 +2419,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2536,7 +2536,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2653,7 +2653,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2770,7 +2770,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2888,7 +2888,7 @@ Returns false for gnu-dummy keys and null for public keys.

      Source:
      @@ -2999,7 +2999,7 @@ Returns false for gnu-dummy keys and null for public keys.

      Source:
      @@ -3114,7 +3114,7 @@ Such keys are:

      Source:
      @@ -3266,7 +3266,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
      Source:
      @@ -3411,7 +3411,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
      Source:
      @@ -3501,7 +3501,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
      Source:
      @@ -3625,7 +3625,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
      Source:
      @@ -3791,7 +3791,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
      Source:
      diff --git a/docs/SecretSubkeyPacket.html b/docs/SecretSubkeyPacket.html index d26a2dda..567923fa 100644 --- a/docs/SecretSubkeyPacket.html +++ b/docs/SecretSubkeyPacket.html @@ -190,7 +190,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -312,7 +312,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -391,7 +391,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -470,7 +470,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -549,7 +549,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -628,7 +628,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -697,7 +697,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -776,7 +776,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -845,7 +845,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -924,7 +924,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -1003,7 +1003,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -1072,7 +1072,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -1158,7 +1158,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -1237,7 +1237,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -1316,7 +1316,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -1395,7 +1395,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -1464,7 +1464,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -1558,7 +1558,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -1653,7 +1653,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -1748,7 +1748,7 @@ Key packet and has exactly the same format.

      Source:
      @@ -1895,7 +1895,7 @@ otherwise calls to this function will throw an error.

      Source:
      @@ -2114,7 +2114,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2238,7 +2238,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2355,7 +2355,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2468,7 +2468,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2585,7 +2585,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2702,7 +2702,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2819,7 +2819,7 @@ This can be used to remove passphrase protection after calling decrypt().

      Source:
      @@ -2937,7 +2937,7 @@ Returns false for gnu-dummy keys and null for public keys.

      Source:
      @@ -3053,7 +3053,7 @@ Returns false for gnu-dummy keys and null for public keys.

      Source:
      @@ -3173,7 +3173,7 @@ Such keys are:

      Source:
      @@ -3330,7 +3330,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
      Source:
      @@ -3475,7 +3475,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
      Source:
      @@ -3570,7 +3570,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
      Source:
      @@ -3694,7 +3694,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
      Source:
      @@ -3860,7 +3860,7 @@ The resulting key cannot be used for signing/decrypting but can still verify sig
      Source:
      diff --git a/docs/Signature.html b/docs/Signature.html index 6081ce46..60ea8fd1 100644 --- a/docs/Signature.html +++ b/docs/Signature.html @@ -144,7 +144,7 @@
      Source:
      @@ -322,7 +322,7 @@
      Source:
      @@ -434,7 +434,7 @@
      Source:
      @@ -546,7 +546,7 @@
      Source:
      diff --git a/docs/SignaturePacket.html b/docs/SignaturePacket.html index ef7efde6..a44a3a8b 100644 --- a/docs/SignaturePacket.html +++ b/docs/SignaturePacket.html @@ -99,7 +99,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      @@ -201,7 +201,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      @@ -271,7 +271,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      @@ -341,7 +341,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      @@ -423,7 +423,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      @@ -599,7 +599,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      @@ -760,7 +760,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      @@ -1048,7 +1048,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      @@ -1427,7 +1427,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      @@ -1546,7 +1546,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      @@ -1654,7 +1654,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      @@ -1765,7 +1765,7 @@ block of text, and a signature that is a certification of a User ID.

      Source:
      diff --git a/docs/SymEncryptedIntegrityProtectedDataPacket.html b/docs/SymEncryptedIntegrityProtectedDataPacket.html index 480c32ba..9e1863d8 100644 --- a/docs/SymEncryptedIntegrityProtectedDataPacket.html +++ b/docs/SymEncryptedIntegrityProtectedDataPacket.html @@ -101,7 +101,7 @@ packet.

      Source:
      @@ -203,7 +203,7 @@ packet.

      Source:
      @@ -273,7 +273,7 @@ packet.

      Source:
      @@ -478,7 +478,7 @@ packet.

      Source:
      @@ -738,7 +738,7 @@ packet.

      Source:
      diff --git a/docs/SymEncryptedSessionKeyPacket.html b/docs/SymEncryptedSessionKeyPacket.html index 4d1358c2..91f8b57a 100644 --- a/docs/SymEncryptedSessionKeyPacket.html +++ b/docs/SymEncryptedSessionKeyPacket.html @@ -165,7 +165,7 @@ the Symmetric-Key Encrypted Session Key packet.

      Source:
      @@ -271,7 +271,7 @@ the Symmetric-Key Encrypted Session Key packet.

      Source:
      @@ -345,7 +345,7 @@ the Symmetric-Key Encrypted Session Key packet.

      Source:
      @@ -419,7 +419,7 @@ the Symmetric-Key Encrypted Session Key packet.

      Source:
      @@ -550,7 +550,7 @@ the Symmetric-Key Encrypted Session Key packet.

      Source:
      @@ -761,7 +761,7 @@ the Symmetric-Key Encrypted Session Key packet.

      Source:
      @@ -929,7 +929,7 @@ the Symmetric-Key Encrypted Session Key packet.

      Source:
      @@ -1019,7 +1019,7 @@ the Symmetric-Key Encrypted Session Key packet.

      Source:
      diff --git a/docs/SymmetricallyEncryptedDataPacket.html b/docs/SymmetricallyEncryptedDataPacket.html index abed83b1..74cbb54e 100644 --- a/docs/SymmetricallyEncryptedDataPacket.html +++ b/docs/SymmetricallyEncryptedDataPacket.html @@ -101,7 +101,7 @@ that form whole OpenPGP messages).

      Source:
      @@ -197,7 +197,7 @@ that form whole OpenPGP messages).

      Source:
      @@ -271,7 +271,7 @@ that form whole OpenPGP messages).

      Source:
      @@ -477,7 +477,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -720,7 +720,7 @@ See RFC 4880 9.2 f
      Source:
      diff --git a/docs/TrustPacket.html b/docs/TrustPacket.html index ce94c8a7..ba1e690f 100644 --- a/docs/TrustPacket.html +++ b/docs/TrustPacket.html @@ -105,7 +105,7 @@ other than local keyring files.

      Source:
      @@ -216,7 +216,7 @@ Currently not implemented as we ignore trust packets

      Source:
      diff --git a/docs/UserAttributePacket.html b/docs/UserAttributePacket.html index 1e3734d3..9781021c 100644 --- a/docs/UserAttributePacket.html +++ b/docs/UserAttributePacket.html @@ -107,7 +107,7 @@ an implementation may use any method desired.

      Source:
      @@ -266,7 +266,7 @@ an implementation may use any method desired.

      Source:
      @@ -427,7 +427,7 @@ an implementation may use any method desired.

      Source:
      @@ -517,7 +517,7 @@ an implementation may use any method desired.

      Source:
      diff --git a/docs/UserIDPacket.html b/docs/UserIDPacket.html index 29e0807e..ea8111cd 100644 --- a/docs/UserIDPacket.html +++ b/docs/UserIDPacket.html @@ -100,7 +100,7 @@ specifies the length of the User ID.

      Source:
      @@ -207,7 +207,7 @@ John Doe john@example.com

      Source:
      @@ -338,7 +338,7 @@ John Doe john@example.com

      Source:
      @@ -495,7 +495,7 @@ John Doe john@example.com

      Source:
      @@ -585,7 +585,7 @@ John Doe john@example.com

      Source:
      diff --git a/docs/global.html b/docs/global.html index 8769aec7..f05ae33e 100644 --- a/docs/global.html +++ b/docs/global.html @@ -419,7 +419,7 @@
      Source:
      @@ -632,7 +632,7 @@
      Source:
      @@ -771,7 +771,7 @@
      Source:
      @@ -1180,7 +1180,7 @@
      Source:
      @@ -1761,7 +1761,7 @@ One of decryptionKeys, sessionkeys or passwords<
      Source:
      @@ -2064,7 +2064,7 @@ This method does not change the original key.

      Source:
      @@ -2423,7 +2423,7 @@ One of decryptionKeys or passwords must be specified.<
      Source:
      @@ -3227,7 +3227,7 @@ must be specified. If signing keys are specified, those will be used to sign the
      Source:
      @@ -3515,7 +3515,7 @@ This method does not change the original key.

      Source:
      @@ -4135,7 +4135,7 @@ At least one of encryptionKeys or passwords must be sp
      Source:
      @@ -4351,7 +4351,7 @@ At least one of encryptionKeys or passwords must be sp
      Source:
      @@ -4952,7 +4952,7 @@ default to main key options, except for sign parameter that default
      Source:
      @@ -5302,7 +5302,7 @@ default to main key options, except for sign parameter that default
      Source:
      @@ -5463,7 +5463,7 @@ default to main key options, except for sign parameter that default
      Source:
      @@ -5602,7 +5602,7 @@ default to main key options, except for sign parameter that default
      Source:
      @@ -5741,7 +5741,7 @@ default to main key options, except for sign parameter that default
      Source:
      @@ -5891,7 +5891,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -6071,7 +6071,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -6215,7 +6215,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -6405,7 +6405,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -6797,7 +6797,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -7038,7 +7038,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -7326,7 +7326,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -7614,7 +7614,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -7908,7 +7908,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -8196,7 +8196,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -8484,7 +8484,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -8772,7 +8772,7 @@ NB: the return instatiator functions will throw when called if the provided Source:
      @@ -9234,7 +9234,7 @@ to set the same date as the key creation time to ensure that old message signatu
      Source:
      @@ -9763,7 +9763,7 @@ If a revocation certificate is passed, the reasonForRevocation parameter will be
      Source:
      @@ -9978,7 +9978,7 @@ If a revocation certificate is passed, the reasonForRevocation parameter will be
      Source:
      @@ -10527,7 +10527,7 @@ If a revocation certificate is passed, the reasonForRevocation parameter will be
      Source:
      @@ -10689,7 +10689,7 @@ the encoded bytes

      Source:
      @@ -11151,7 +11151,7 @@ an attribute "data" containing a stream of bytes and "type"
      Source:
      @@ -11396,7 +11396,7 @@ The new key includes a revocation certificate that must be removed before return
      Source:
      @@ -11576,7 +11576,7 @@ The new key includes a revocation certificate that must be removed before return
      Source:
      diff --git a/docs/module-config.html b/docs/module-config.html index 0b618fcc..f0eeb13f 100644 --- a/docs/module-config.html +++ b/docs/module-config.html @@ -89,7 +89,7 @@
      Source:
      @@ -247,7 +247,7 @@ as a global config setting, but can be used for specific function calls (e.g. de
      Source:
      @@ -365,7 +365,7 @@ Must be an integer value from 0 to 56.

      Source:
      @@ -489,7 +489,7 @@ Note: not all OpenPGP implementations are compatible with this option.
      Source:
      @@ -614,7 +614,7 @@ where key flags were ignored when selecting a key for encryption.

      Source:
      @@ -733,7 +733,7 @@ and have self-signature's creation date that does not match the primary key crea
      Source:
      @@ -854,7 +854,7 @@ This is an insecure setting:

      Source:
      @@ -979,7 +979,7 @@ and deferring checking their integrity until the decrypted stream has been read
      Source:
      @@ -1091,7 +1091,7 @@ and deferring checking their integrity until the decrypted stream has been read
      Source:
      @@ -1213,7 +1213,7 @@ See also constantTimePKCS1DecryptionSupportedSymmetricAlgorithms.Source:
      @@ -1331,7 +1331,7 @@ However, the more algorithms are added, the slower the decryption procedure beco
      Source:
      @@ -1443,7 +1443,7 @@ However, the more algorithms are added, the slower the decryption procedure beco
      Source:
      @@ -1555,7 +1555,7 @@ However, the more algorithms are added, the slower the decryption procedure beco
      Source:
      @@ -1672,7 +1672,7 @@ validation error when the notation is marked as critical.

      Source:
      @@ -1788,7 +1788,7 @@ validation error when the notation is marked as critical.

      Source:
      @@ -1905,7 +1905,7 @@ The default is 2047 since due to a bug, previous versions of OpenPGP.js could ge
      Source:
      @@ -2022,7 +2022,7 @@ The default is 2047 since due to a bug, previous versions of OpenPGP.js could ge
      Source:
      @@ -2139,7 +2139,7 @@ Only has an effect when aeadProtect is set to true.

      Source:
      @@ -2251,7 +2251,7 @@ Only has an effect when aeadProtect is set to true.

      Source:
      @@ -2363,7 +2363,7 @@ Only has an effect when aeadProtect is set to true.

      Source:
      @@ -2475,7 +2475,7 @@ Only has an effect when aeadProtect is set to true.

      Source:
      @@ -2591,7 +2591,7 @@ Only has an effect when aeadProtect is set to true.

      Source:
      @@ -2707,7 +2707,7 @@ Only has an effect when aeadProtect is set to true.

      Source:
      @@ -2823,7 +2823,7 @@ Only has an effect when aeadProtect is set to true.

      Source:
      @@ -2939,7 +2939,7 @@ Only has an effect when aeadProtect is set to true.

      Source:
      @@ -3154,7 +3154,7 @@ For more details on the choice of parameters, see https://tools.ietf.org/html/rf
      Source:
      @@ -3273,7 +3273,7 @@ Note: this is the exponent value, not the final number of iterations (refer to s
      Source:
      @@ -3395,7 +3395,7 @@ Note: Argon2 is the strongest option but not all OpenPGP implementations are com
      Source:
      @@ -3507,7 +3507,7 @@ Note: Argon2 is the strongest option but not all OpenPGP implementations are com
      Source:
      @@ -3619,7 +3619,7 @@ Note: Argon2 is the strongest option but not all OpenPGP implementations are com
      Source:
      @@ -3736,7 +3736,7 @@ When false, certain standard curves will not be supported (depending on the plat
      Source:
      @@ -3854,7 +3854,7 @@ Note: not all OpenPGP implementations are compatible with this option.
      Source:
      @@ -3966,7 +3966,7 @@ Note: not all OpenPGP implementations are compatible with this option.
      Source:
      diff --git a/docs/module-crypto.html b/docs/module-crypto.html index 732727f8..447bb1b7 100644 --- a/docs/module-crypto.html +++ b/docs/module-crypto.html @@ -89,7 +89,7 @@
      Source:
      diff --git a/docs/module-crypto_aes_kw.html b/docs/module-crypto_aes_kw.html index 5e0decfe..b1dd518e 100644 --- a/docs/module-crypto_aes_kw.html +++ b/docs/module-crypto_aes_kw.html @@ -89,7 +89,7 @@
      Source:
      @@ -308,7 +308,7 @@
      Source:
      @@ -521,7 +521,7 @@
      Source:
      diff --git a/docs/module-crypto_cmac.html b/docs/module-crypto_cmac.html index 817189aa..cc9ec4f1 100644 --- a/docs/module-crypto_cmac.html +++ b/docs/module-crypto_cmac.html @@ -90,7 +90,7 @@ native AES-CBC using either the WebCrypto API or Node.js' crypto API.

      Source:
      @@ -195,7 +195,7 @@ The OMAC authors indicate that they will promulgate this modification
      Source:
      @@ -352,7 +352,7 @@ simplify the implementation.

      Source:
      diff --git a/docs/module-crypto_crypto.html b/docs/module-crypto_crypto.html index fb44263a..27f56994 100644 --- a/docs/module-crypto_crypto.html +++ b/docs/module-crypto_crypto.html @@ -90,7 +90,7 @@ well as key generation and parameter handling for all public-key cryptosystems.<
      Source:
      @@ -296,7 +296,7 @@ well as key generation and parameter handling for all public-key cryptosystems.<
      Source:
      @@ -458,7 +458,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -619,7 +619,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -848,7 +848,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -1030,7 +1030,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -1170,7 +1170,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -1354,7 +1354,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -1561,7 +1561,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -1745,7 +1745,7 @@ See RFC 4880 9.2 f
      Source:
      @@ -2075,7 +2075,7 @@ See RFC 4880 5.5.3Source:
      @@ -2361,7 +2361,7 @@ See RFC 4880 9.1 f
      Source:
      @@ -2545,7 +2545,7 @@ See RFC 4880 9.1 f
      Source:
      @@ -2752,7 +2752,7 @@ See RFC 4880 9.1 f
      Source:
      @@ -2913,7 +2913,7 @@ See RFC 4880 9.1 f
      Source:
      diff --git a/docs/module-crypto_hash.html b/docs/module-crypto_hash.html index f967e6cf..8c3e17e1 100644 --- a/docs/module-crypto_hash.html +++ b/docs/module-crypto_hash.html @@ -89,7 +89,7 @@
      Source:
      @@ -191,7 +191,7 @@
      Source:
      @@ -352,7 +352,7 @@
      Source:
      @@ -513,7 +513,7 @@
      Source:
      diff --git a/docs/module-crypto_hkdf.html b/docs/module-crypto_hkdf.html index b4462118..1f5418fd 100644 --- a/docs/module-crypto_hkdf.html +++ b/docs/module-crypto_hkdf.html @@ -89,7 +89,7 @@
      Source:
      diff --git a/docs/module-crypto_mode.html b/docs/module-crypto_mode.html index 6f422ea0..3c067e26 100644 --- a/docs/module-crypto_mode.html +++ b/docs/module-crypto_mode.html @@ -89,7 +89,7 @@
      Source:
      @@ -182,7 +182,7 @@
      Source:
      @@ -249,7 +249,7 @@
      Source:
      @@ -316,7 +316,7 @@
      Source:
      @@ -383,7 +383,7 @@
      Source:
      diff --git a/docs/module-crypto_mode_cfb.html b/docs/module-crypto_mode_cfb.html index aeedf8e6..70dd781f 100644 --- a/docs/module-crypto_mode_cfb.html +++ b/docs/module-crypto_mode_cfb.html @@ -236,7 +236,7 @@
      Source:
      @@ -477,7 +477,7 @@
      Source:
      diff --git a/docs/module-crypto_mode_eax.html b/docs/module-crypto_mode_eax.html index e91b2f8b..d72c957e 100644 --- a/docs/module-crypto_mode_eax.html +++ b/docs/module-crypto_mode_eax.html @@ -90,7 +90,7 @@ native AES-CTR using either the WebCrypto API or Node.js' crypto API.

      Source:
      @@ -296,7 +296,7 @@ native AES-CTR using either the WebCrypto API or Node.js' crypto API.

      Source:
      @@ -480,7 +480,7 @@ native AES-CTR using either the WebCrypto API or Node.js' crypto API.

      Source:
      @@ -665,7 +665,7 @@ native AES-CTR using either the WebCrypto API or Node.js' crypto API.

      Source:
      diff --git a/docs/module-crypto_mode_gcm.html b/docs/module-crypto_mode_gcm.html index e855263c..1b64afe0 100644 --- a/docs/module-crypto_mode_gcm.html +++ b/docs/module-crypto_mode_gcm.html @@ -90,7 +90,7 @@ the WebCrypto api as well as node.js' crypto api.

      Source:
      @@ -273,7 +273,7 @@ the WebCrypto api as well as node.js' crypto api.

      Source:
      diff --git a/docs/module-crypto_mode_ocb.html b/docs/module-crypto_mode_ocb.html index d0519205..b90df5b5 100644 --- a/docs/module-crypto_mode_ocb.html +++ b/docs/module-crypto_mode_ocb.html @@ -89,7 +89,7 @@
      Source:
      @@ -295,7 +295,7 @@
      Source:
      @@ -502,7 +502,7 @@
      Source:
      @@ -686,7 +686,7 @@
      Source:
      diff --git a/docs/module-crypto_pkcs1.html b/docs/module-crypto_pkcs1.html index f38a3713..309d1e8d 100644 --- a/docs/module-crypto_pkcs1.html +++ b/docs/module-crypto_pkcs1.html @@ -89,7 +89,7 @@
      Source:
      @@ -197,7 +197,7 @@
      Source:
      @@ -358,7 +358,7 @@
      Source:
      @@ -578,7 +578,7 @@
      Source:
      @@ -792,7 +792,7 @@
      Source:
      diff --git a/docs/module-crypto_public_key.html b/docs/module-crypto_public_key.html index 1675c9d9..123b2b83 100644 --- a/docs/module-crypto_public_key.html +++ b/docs/module-crypto_public_key.html @@ -89,7 +89,7 @@
      Source:
      @@ -182,7 +182,7 @@
      Source:
      @@ -249,7 +249,7 @@
      Source:
      @@ -316,7 +316,7 @@
      Source:
      @@ -383,7 +383,7 @@
      Source:
      diff --git a/docs/module-crypto_public_key_dsa.html b/docs/module-crypto_public_key_dsa.html index 0f14596c..52c051a3 100644 --- a/docs/module-crypto_public_key_dsa.html +++ b/docs/module-crypto_public_key_dsa.html @@ -89,7 +89,7 @@
      Source:
      @@ -188,7 +188,7 @@ Expect y == y'

      Source:
      @@ -434,7 +434,7 @@ Expect y == y'

      Source:
      @@ -683,7 +683,7 @@ Expect y == y'

      Source:
      @@ -1005,7 +1005,7 @@ Expect y == y'

      Source:
      diff --git a/docs/module-crypto_public_key_elgamal.html b/docs/module-crypto_public_key_elgamal.html index a3d026fd..44ed8b38 100644 --- a/docs/module-crypto_public_key_elgamal.html +++ b/docs/module-crypto_public_key_elgamal.html @@ -89,7 +89,7 @@
      Source:
      @@ -188,7 +188,7 @@ Expect y == y'

      Source:
      @@ -412,7 +412,7 @@ Expect y == y'

      Source:
      @@ -672,7 +672,7 @@ Note that in OpenPGP, the message needs to be padded with PKCS#1 (same as RSA)Source:
      @@ -898,7 +898,7 @@ Note that in OpenPGP, the message needs to be padded with PKCS#1 (same as RSA)Source:
      diff --git a/docs/module-crypto_public_key_elliptic.html b/docs/module-crypto_public_key_elliptic.html index 67255ff1..37f56eda 100644 --- a/docs/module-crypto_public_key_elliptic.html +++ b/docs/module-crypto_public_key_elliptic.html @@ -89,7 +89,7 @@
      Source:
      diff --git a/docs/module-crypto_public_key_elliptic_curve.html b/docs/module-crypto_public_key_elliptic_curve.html index 4c764f79..ea23377b 100644 --- a/docs/module-crypto_public_key_elliptic_curve.html +++ b/docs/module-crypto_public_key_elliptic_curve.html @@ -89,7 +89,7 @@
      Source:
      @@ -201,7 +201,7 @@ NB: this function does not check e.g. whether the point belongs to the curve.

      Source:
      @@ -340,7 +340,7 @@ NB: this function does not check e.g. whether the point belongs to the curve.

      Source:
      @@ -497,7 +497,7 @@ NB: this function does not check e.g. whether the point belongs to the curve.

      Source:
      @@ -723,7 +723,7 @@ NB: this function does not check e.g. whether the point belongs to the curve.

      Source:
      @@ -926,7 +926,7 @@ NB: this function does not check e.g. whether the point belongs to the curve.

      Source:
      @@ -1157,7 +1157,7 @@ Not suitable for EdDSA (different secret key format)

      Source:
      diff --git a/docs/module-crypto_public_key_elliptic_ecdh.html b/docs/module-crypto_public_key_elliptic_ecdh.html index d87dd699..e2ae3b7f 100644 --- a/docs/module-crypto_public_key_elliptic_ecdh.html +++ b/docs/module-crypto_public_key_elliptic_ecdh.html @@ -91,7 +91,7 @@
      Source:
      @@ -169,7 +169,7 @@
      Source:
      @@ -467,7 +467,7 @@
      Source:
      @@ -720,7 +720,7 @@
      Source:
      @@ -973,7 +973,7 @@
      Source:
      @@ -1176,7 +1176,7 @@
      Source:
      @@ -1337,7 +1337,7 @@
      Source:
      @@ -1445,7 +1445,7 @@
      Source:
      @@ -1652,7 +1652,7 @@
      Source:
      @@ -1859,7 +1859,7 @@
      Source:
      @@ -2089,7 +2089,7 @@
      Source:
      @@ -2269,7 +2269,7 @@
      Source:
      @@ -2472,7 +2472,7 @@
      Source:
      @@ -2652,7 +2652,7 @@
      Source:
      @@ -2878,7 +2878,7 @@
      Source:
      @@ -3058,7 +3058,7 @@
      Source:
      @@ -3189,7 +3189,7 @@
      Source:
      @@ -3267,7 +3267,7 @@
      Source:
      @@ -3565,7 +3565,7 @@
      Source:
      @@ -3818,7 +3818,7 @@
      Source:
      @@ -4071,7 +4071,7 @@
      Source:
      @@ -4274,7 +4274,7 @@
      Source:
      @@ -4435,7 +4435,7 @@
      Source:
      @@ -4543,7 +4543,7 @@
      Source:
      @@ -4750,7 +4750,7 @@
      Source:
      @@ -4957,7 +4957,7 @@
      Source:
      @@ -5187,7 +5187,7 @@
      Source:
      @@ -5367,7 +5367,7 @@
      Source:
      @@ -5570,7 +5570,7 @@
      Source:
      @@ -5750,7 +5750,7 @@
      Source:
      @@ -5976,7 +5976,7 @@
      Source:
      @@ -6156,7 +6156,7 @@
      Source:
      diff --git a/docs/module-crypto_public_key_elliptic_ecdsa.html b/docs/module-crypto_public_key_elliptic_ecdsa.html index 4d62b446..e3fa7950 100644 --- a/docs/module-crypto_public_key_elliptic_ecdsa.html +++ b/docs/module-crypto_public_key_elliptic_ecdsa.html @@ -89,7 +89,7 @@
      Source:
      @@ -364,7 +364,7 @@
      Source:
      @@ -571,7 +571,7 @@
      Source:
      @@ -847,7 +847,7 @@
      Source:
      @@ -956,7 +956,7 @@ To be used if no native implementation is available for the given curve/operatio
      Source:
      diff --git a/docs/module-crypto_public_key_elliptic_eddsa.html b/docs/module-crypto_public_key_elliptic_eddsa.html index bf98d533..8656469e 100644 --- a/docs/module-crypto_public_key_elliptic_eddsa.html +++ b/docs/module-crypto_public_key_elliptic_eddsa.html @@ -89,7 +89,7 @@
      Source:
      @@ -249,7 +249,7 @@
      Source:
      @@ -521,7 +521,7 @@
      Source:
      @@ -751,7 +751,7 @@
      Source:
      @@ -1027,7 +1027,7 @@
      Source:
      diff --git a/docs/module-crypto_public_key_elliptic_eddsa_legacy.html b/docs/module-crypto_public_key_elliptic_eddsa_legacy.html index fe2e5ff2..ccd81de7 100644 --- a/docs/module-crypto_public_key_elliptic_eddsa_legacy.html +++ b/docs/module-crypto_public_key_elliptic_eddsa_legacy.html @@ -90,7 +90,7 @@ This key type has been deprecated by the crypto-refresh RFC.

      Source:
      @@ -365,7 +365,7 @@ This key type has been deprecated by the crypto-refresh RFC.

      Source:
      @@ -572,7 +572,7 @@ This key type has been deprecated by the crypto-refresh RFC.

      Source:
      @@ -848,7 +848,7 @@ This key type has been deprecated by the crypto-refresh RFC.

      Source:
      diff --git a/docs/module-crypto_public_key_rsa.html b/docs/module-crypto_public_key_rsa.html index ca343f70..c11c76a5 100644 --- a/docs/module-crypto_public_key_rsa.html +++ b/docs/module-crypto_public_key_rsa.html @@ -89,7 +89,7 @@
      Source:
      @@ -411,7 +411,7 @@
      Source:
      @@ -647,7 +647,7 @@
      Source:
      @@ -833,7 +833,7 @@
      Source:
      @@ -1186,7 +1186,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

      Source:
      @@ -1462,7 +1462,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

      Source:
      @@ -1738,7 +1738,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

      Source:
      @@ -1846,7 +1846,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

      Source:
      @@ -2123,7 +2123,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

      Source:
      @@ -2308,7 +2308,7 @@ RSA private prime p, RSA private prime q, u = p ** -1 mod q

      Source:
      diff --git a/docs/module-crypto_random.html b/docs/module-crypto_random.html index f3ecd169..f0074018 100644 --- a/docs/module-crypto_random.html +++ b/docs/module-crypto_random.html @@ -89,7 +89,7 @@
      Source:
      @@ -272,7 +272,7 @@
      Source:
      @@ -433,7 +433,7 @@
      Source:
      diff --git a/docs/module-crypto_signature.html b/docs/module-crypto_signature.html index a2088487..74e33e53 100644 --- a/docs/module-crypto_signature.html +++ b/docs/module-crypto_signature.html @@ -89,7 +89,7 @@
      Source:
      @@ -276,7 +276,7 @@ See RFC 4880 5.2.2.<
      Source:
      @@ -555,7 +555,7 @@ for public key and hash algorithms.

      Source:
      @@ -834,7 +834,7 @@ for public key and hash algorithms.

      Source:
      diff --git a/docs/module-encoding_base64.html b/docs/module-encoding_base64.html index 6d2bb183..ae26bfde 100644 --- a/docs/module-encoding_base64.html +++ b/docs/module-encoding_base64.html @@ -168,7 +168,7 @@
      Source:
      @@ -332,7 +332,7 @@
      Source:
      @@ -499,7 +499,7 @@
      Source:
      @@ -686,7 +686,7 @@
      Source:
      diff --git a/docs/module-enums.html b/docs/module-enums.html index 3741e708..65f76fb0 100644 --- a/docs/module-enums.html +++ b/docs/module-enums.html @@ -235,7 +235,7 @@
      Source:
      @@ -499,7 +499,7 @@
      Source:
      @@ -694,7 +694,7 @@
      Source:
      @@ -1119,7 +1119,7 @@
      Source:
      @@ -1323,7 +1323,7 @@ fingerprint format

      Source:
      @@ -1633,7 +1633,7 @@ fingerprint format

      Source:
      @@ -1899,7 +1899,7 @@ possession of more than one person.

      Source:
      @@ -2094,7 +2094,7 @@ possession of more than one person.

      Source:
      @@ -2634,7 +2634,7 @@ possession of more than one person.

      Source:
      @@ -3060,7 +3060,7 @@ possession of more than one person.

      Source:
      @@ -3278,7 +3278,7 @@ possession of more than one person.

      Source:
      @@ -3496,7 +3496,7 @@ possession of more than one person.

      Source:
      @@ -4013,7 +4013,7 @@ document) that cannot include a target subpacket.

      Source:
      @@ -4737,7 +4737,7 @@ document) that cannot include a target subpacket.

      Source:
      @@ -5024,7 +5024,7 @@ document) that cannot include a target subpacket.

      Source:
      @@ -5220,7 +5220,7 @@ document) that cannot include a target subpacket.

      Source:
      @@ -5374,7 +5374,7 @@ document) that cannot include a target subpacket.

      Source:
      @@ -5590,7 +5590,7 @@ document) that cannot include a target subpacket.

      Source:
      diff --git a/docs/module-key_Subkey-Subkey.html b/docs/module-key_Subkey-Subkey.html index 75e2b191..bed9f3e6 100644 --- a/docs/module-key_Subkey-Subkey.html +++ b/docs/module-key_Subkey-Subkey.html @@ -171,7 +171,7 @@
      Source:
      @@ -281,7 +281,7 @@
      Source:
      @@ -394,7 +394,7 @@
      Source:
      @@ -511,7 +511,7 @@
      Source:
      @@ -628,7 +628,7 @@
      Source:
      @@ -741,7 +741,7 @@
      Source:
      @@ -942,7 +942,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -1055,7 +1055,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -1172,7 +1172,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -1289,7 +1289,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -1406,7 +1406,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -1523,7 +1523,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -1640,7 +1640,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -1757,7 +1757,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -1873,7 +1873,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -2149,7 +2149,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -2487,7 +2487,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -2599,7 +2599,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -2832,7 +2832,7 @@ Returns null if the subkey is invalid.

      Source:
      @@ -3044,7 +3044,7 @@ and valid binding signature.

      Source:
      diff --git a/docs/module-key_User-User.html b/docs/module-key_User-User.html index eddb767a..c34cc575 100644 --- a/docs/module-key_User-User.html +++ b/docs/module-key_User-User.html @@ -171,7 +171,7 @@
      Source:
      @@ -404,7 +404,7 @@
      Source:
      @@ -516,7 +516,7 @@
      Source:
      @@ -789,7 +789,7 @@
      Source:
      @@ -1127,7 +1127,7 @@
      Source:
      @@ -1239,7 +1239,7 @@
      Source:
      @@ -1442,7 +1442,7 @@
      Source:
      @@ -1623,7 +1623,7 @@ and validity of self signature.

      Source:
      @@ -1887,7 +1887,7 @@ and validity of self signature.

      Source:
      @@ -2154,7 +2154,7 @@ Signature validity is null if the verification keys do not correspond to the cer
      Source:
      diff --git a/docs/module-key_helper.html b/docs/module-key_helper.html index f837c1e5..b12b096d 100644 --- a/docs/module-key_helper.html +++ b/docs/module-key_helper.html @@ -89,7 +89,7 @@
      Source:
      @@ -281,7 +281,7 @@
      Source:
      @@ -518,7 +518,7 @@
      Source:
      @@ -928,7 +928,7 @@
      Source:
      @@ -1116,7 +1116,7 @@ The expiration time of the signature is ignored.

      Source:
      @@ -1376,7 +1376,7 @@ The expiration time of the signature is ignored.

      Source:
      @@ -1648,7 +1648,7 @@ The expiration time of the signature is ignored.

      Source:
      @@ -1920,7 +1920,7 @@ The expiration time of the signature is ignored.

      Source:
      @@ -2224,7 +2224,7 @@ The expiration time of the signature is ignored.

      Source:
      @@ -2531,7 +2531,7 @@ The expiration time of the signature is ignored.

      Source:
      @@ -2830,7 +2830,7 @@ The expiration time of the signature is ignored.

      Source:
      diff --git a/docs/module-packet_packet.html b/docs/module-packet_packet.html index 8071dce5..b44b87f0 100644 --- a/docs/module-packet_packet.html +++ b/docs/module-packet_packet.html @@ -89,7 +89,7 @@
      Source:
      @@ -275,7 +275,7 @@
      Source:
      @@ -436,7 +436,7 @@
      Source:
      @@ -621,7 +621,7 @@ string

      Source:
      @@ -783,7 +783,7 @@ string

      Source:
      diff --git a/docs/module-type_ecdh_symkey.html b/docs/module-type_ecdh_symkey.html index d74d3d40..02b27bc6 100644 --- a/docs/module-type_ecdh_symkey.html +++ b/docs/module-type_ecdh_symkey.html @@ -89,7 +89,7 @@
      Source:
      diff --git a/docs/module-type_kdf_params-KDFParams.html b/docs/module-type_kdf_params-KDFParams.html index 89cf9c4a..9dabe344 100644 --- a/docs/module-type_kdf_params-KDFParams.html +++ b/docs/module-type_kdf_params-KDFParams.html @@ -163,7 +163,7 @@
      Source:
      @@ -322,7 +322,7 @@
      Source:
      @@ -434,7 +434,7 @@
      Source:
      diff --git a/docs/module-type_keyid-KeyID.html b/docs/module-type_keyid-KeyID.html index 7043255c..470acc8a 100644 --- a/docs/module-type_keyid-KeyID.html +++ b/docs/module-type_keyid-KeyID.html @@ -101,7 +101,7 @@ formed.

      Source:
      @@ -295,7 +295,7 @@ formed.

      Source:
      @@ -385,7 +385,7 @@ formed.

      Source:
      @@ -497,7 +497,7 @@ formed.

      Source:
      @@ -658,7 +658,7 @@ formed.

      Source:
      @@ -748,7 +748,7 @@ formed.

      Source:
      @@ -860,7 +860,7 @@ formed.

      Source:
      diff --git a/docs/module-type_oid.html b/docs/module-type_oid.html index 80fffeab..524d78c1 100644 --- a/docs/module-type_oid.html +++ b/docs/module-type_oid.html @@ -100,7 +100,7 @@ sequence of octets is the valid representation of a curve OID.

      Source:
      diff --git a/docs/module-type_s2k-GenericS2K.html b/docs/module-type_s2k-GenericS2K.html index fb86cd1f..c557dd41 100644 --- a/docs/module-type_s2k-GenericS2K.html +++ b/docs/module-type_s2k-GenericS2K.html @@ -153,7 +153,7 @@
      Source:
      @@ -262,7 +262,7 @@
      Source:
      @@ -332,7 +332,7 @@
      Source:
      @@ -406,7 +406,7 @@
      Source:
      @@ -480,7 +480,7 @@
      Source:
      @@ -612,7 +612,7 @@ hashAlgorithm

      Source:
      @@ -774,7 +774,7 @@ hashAlgorithm hash length

      Source:
      @@ -886,7 +886,7 @@ hashAlgorithm hash length

      Source:
      diff --git a/docs/module-type_s2k.html b/docs/module-type_s2k.html index e083c286..9121ad81 100644 --- a/docs/module-type_s2k.html +++ b/docs/module-type_s2k.html @@ -95,7 +95,7 @@ symmetrically encrypted messages.

      Source:
      diff --git a/docs/module-type_x25519x448_symkey.html b/docs/module-type_x25519x448_symkey.html index 35aa0976..958650bd 100644 --- a/docs/module-type_x25519x448_symkey.html +++ b/docs/module-type_x25519x448_symkey.html @@ -91,7 +91,7 @@ the former includes an algorithm byte preceeding the encrypted session key.

      <
      Source:
      diff --git a/docs/module-util.html b/docs/module-util.html index 9680800b..7675f6db 100644 --- a/docs/module-util.html +++ b/docs/module-util.html @@ -89,7 +89,7 @@
      Source:
      diff --git a/package-lock.json b/package-lock.json index 54ff5644..bae4b324 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "openpgp", - "version": "6.0.0-beta.3.patch.0", + "version": "6.0.0-beta.3.patch.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "openpgp", - "version": "6.0.0-beta.3.patch.0", + "version": "6.0.0-beta.3.patch.1", "license": "LGPL-3.0+", "devDependencies": { "@noble/ciphers": "^0.6.0", diff --git a/package.json b/package.json index 6366c68d..e1c9633f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "openpgp", "description": "OpenPGP.js is a Javascript implementation of the OpenPGP protocol. This is defined in RFC 4880.", - "version": "6.0.0-beta.3.patch.0", + "version": "6.0.0-beta.3.patch.1", "license": "LGPL-3.0+", "homepage": "https://openpgpjs.org/", "engines": { From e454faab0cebfc3cc393c6e6bd21a2eec1bc9967 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Wed, 11 Sep 2024 19:34:48 +0200 Subject: [PATCH 180/201] CI: setup Dependabot to update playwright and test latest browser versions --- .github/.dependabot.yml | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .github/.dependabot.yml diff --git a/.github/.dependabot.yml b/.github/.dependabot.yml new file mode 100644 index 00000000..bf639dfc --- /dev/null +++ b/.github/.dependabot.yml @@ -0,0 +1,9 @@ +version: 2 +updates: + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "daily" + allow: + - dependency-name: "playwright" + versioning-strategy: increase From e80d71bdfc6f4a3a98c1561256e2baa763d09516 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Wed, 11 Sep 2024 19:41:57 +0200 Subject: [PATCH 181/201] CI: setup Dependabot to update non-dev dependencies We unfortunately need to manually list them as they are still declared as dev dependencies in the package.json, due to the fact that we bundle them. --- .github/.dependabot.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/.github/.dependabot.yml b/.github/.dependabot.yml index bf639dfc..fd6f4c38 100644 --- a/.github/.dependabot.yml +++ b/.github/.dependabot.yml @@ -7,3 +7,23 @@ updates: allow: - dependency-name: "playwright" versioning-strategy: increase + + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "weekly" + allow: + - dependency-name: "@noble*" + - dependency-name: "fflate" + versioning-strategy: increase + groups: + # Any packages matching the pattern @noble* where the highest resolvable + # version is minor or patch will be grouped together. + # Grouping rules apply to version updates only. + noble: + applies-to: version-updates + patterns: + - "@noble*" + update-types: + - "minor" + - "patch" \ No newline at end of file From ada794cab6eb1102a8d6f5d2ede3cae4783050b5 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Thu, 12 Sep 2024 13:31:55 +0200 Subject: [PATCH 182/201] Throw on (unexpected) low order points in ECDH over Curve25519/448 These points do not pose a security threat in the context of OpenPGP ECDH, and would simply result in an all-zero shared secret being generated. However, they represent unexpected inputs, so we prefer to warn the user. --- src/crypto/public_key/elliptic/ecdh_x.js | 27 ++++++++- test/crypto/ecdh.js | 70 ++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 3 deletions(-) diff --git a/src/crypto/public_key/elliptic/ecdh_x.js b/src/crypto/public_key/elliptic/ecdh_x.js index a7bf3bd5..b293d4e5 100644 --- a/src/crypto/public_key/elliptic/ecdh_x.js +++ b/src/crypto/public_key/elliptic/ecdh_x.js @@ -174,14 +174,15 @@ export async function generateEphemeralEncryptionMaterial(algo, recipientA) { case enums.publicKey.x25519: { const ephemeralSecretKey = getRandomBytes(getPayloadSize(algo)); const sharedSecret = x25519.scalarMult(ephemeralSecretKey, recipientA); + assertNonZeroArray(sharedSecret); const { publicKey: ephemeralPublicKey } = x25519.box.keyPair.fromSecretKey(ephemeralSecretKey); - return { ephemeralPublicKey, sharedSecret }; } case enums.publicKey.x448: { const x448 = await util.getNobleCurve(enums.publicKey.x448); const ephemeralSecretKey = x448.utils.randomPrivateKey(); const sharedSecret = x448.getSharedSecret(ephemeralSecretKey, recipientA); + assertNonZeroArray(sharedSecret); const ephemeralPublicKey = x448.getPublicKey(ephemeralSecretKey); return { ephemeralPublicKey, sharedSecret }; } @@ -192,14 +193,34 @@ export async function generateEphemeralEncryptionMaterial(algo, recipientA) { export async function recomputeSharedSecret(algo, ephemeralPublicKey, A, k) { switch (algo) { - case enums.publicKey.x25519: - return x25519.scalarMult(k, ephemeralPublicKey); + case enums.publicKey.x25519: { + const sharedSecret = x25519.scalarMult(k, ephemeralPublicKey); + assertNonZeroArray(sharedSecret); + return sharedSecret; + } case enums.publicKey.x448: { const x448 = await util.getNobleCurve(enums.publicKey.x448); const sharedSecret = x448.getSharedSecret(k, ephemeralPublicKey); + assertNonZeroArray(sharedSecret); return sharedSecret; } default: throw new Error('Unsupported ECDH algorithm'); } } + +/** + * x25519 and x448 produce an all-zero value when given as input a point with small order. + * This does not lead to a security issue in the context of ECDH, but it is still unexpected, + * hence we throw. + * @param {Uint8Array} sharedSecret + */ +function assertNonZeroArray(sharedSecret) { + let acc = 0; + for (let i = 0; i < sharedSecret.length; i++) { + acc |= sharedSecret[i]; + } + if (acc === 0) { + throw new Error('Unexpected low order point'); + } +} diff --git a/test/crypto/ecdh.js b/test/crypto/ecdh.js index b44c8a3f..72a8892b 100644 --- a/test/crypto/ecdh.js +++ b/test/crypto/ecdh.js @@ -203,6 +203,76 @@ export default () => describe('ECDH key exchange @lightweight', function () { expect(await ecdhX.decrypt(openpgp.enums.publicKey.x448, ephemeralPublicKey, wrappedKey, K_B, b)).to.deep.equal(data); }); + it('Detect small order points in x25519', async () => { + const vectors = [ + { + 'order': '0', + 'vector': '0000000000000000000000000000000000000000000000000000000000000000' + }, + { + 'order': '1', + 'vector': '0100000000000000000000000000000000000000000000000000000000000000' + }, + { + 'order': '8', + 'vector': 'e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b800' + }, + { + 'order': 'p-1 (order 2)', + 'vector': 'ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f' + }, + { + 'order': 'p (=0, order 4)', + 'vector': 'edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f' + }, + { + 'order': 'p+1 (=1, order 1)', + 'vector': 'eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f' + } + ]; + const data = random.getRandomBytes(16); + for (const { vector } of vectors) { + const lowOrderPoint = util.hexToUint8Array(vector); + const { A: K_A, k: a } = await elliptic_curves.ecdhX.generate(openpgp.enums.publicKey.x25519); + await expect(elliptic_curves.ecdhX.encrypt(openpgp.enums.publicKey.x25519, data, lowOrderPoint)).to.be.rejectedWith(/low order point/); + const dummyWrappedKey = new Uint8Array(32); // expected to be unused + await expect(elliptic_curves.ecdhX.decrypt(openpgp.enums.publicKey.x25519, lowOrderPoint, dummyWrappedKey, K_A, a)).to.be.rejectedWith(/low order point/); + } + }); + + it('Detect small order points in x448', async () => { + const vectors = [ + { + 'order': '0', + 'vector': '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + }, + { + 'order': '1', + 'vector': '0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + }, + { + 'order': 'p-1 (order 2)', + 'vector': 'fefffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffff' + }, + { + 'order': 'p (=0, order 4)', + 'vector': 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffff' + }, + { + 'order': 'p+1 (=1, order 1)', + 'vector': '00000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff' + } + ]; + const data = random.getRandomBytes(16); + for (const { vector } of vectors) { + const lowOrderPoint = util.hexToUint8Array(vector); + const { A: K_A, k: a } = await elliptic_curves.ecdhX.generate(openpgp.enums.publicKey.x448); + await expect(elliptic_curves.ecdhX.encrypt(openpgp.enums.publicKey.x448, data, lowOrderPoint)).to.be.rejectedWith(/Invalid private or public key received|expected valid u|low order point/); + const dummyWrappedKey = new Uint8Array(32); // expected to be unused + await expect(elliptic_curves.ecdhX.decrypt(openpgp.enums.publicKey.x448, lowOrderPoint, dummyWrappedKey, K_A, a)).to.be.rejectedWith(/Invalid private or public key received|expected valid u|low order point/); + } + }); + const allCurves = ['secp256k1', 'nistP256', 'nistP384', 'nistP521', 'brainpoolP256r1', 'brainpoolP384r1', 'brainpoolP512r1']; allCurves.forEach(curveName => { it(`${curveName} - Successful exchange`, async function () { From 5ee854140a687fc2fd9f05eb77028d3b24a0b9ea Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Thu, 3 Oct 2024 16:44:55 +0200 Subject: [PATCH 183/201] CI: update SOP test suite docker image to v1.1.12 Includes rsop with crypto-refresh support --- .github/workflows/sop-test-suite.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sop-test-suite.yml b/.github/workflows/sop-test-suite.yml index 2e29721a..16b56829 100644 --- a/.github/workflows/sop-test-suite.yml +++ b/.github/workflows/sop-test-suite.yml @@ -10,7 +10,7 @@ jobs: name: Run interoperability test suite runs-on: ubuntu-latest container: - image: ghcr.io/protonmail/openpgp-interop-test-docker:v1.1.10 + image: ghcr.io/protonmail/openpgp-interop-test-docker:v1.1.12 credentials: username: ${{ github.actor }} password: ${{ secrets.github_token }} From a57bffc84a68dba9bb75d2c406353805a5a3bd55 Mon Sep 17 00:00:00 2001 From: larabr Date: Mon, 14 Oct 2024 12:15:33 +0200 Subject: [PATCH 184/201] Fix key and signature parsing of `EdDSALegacy` entities with unsupported curves (e.g. `Curve448Legacy`) (#1798) Signature parsing would fail in case of unexpected payload sizes, causing key parsing to always throw when processing e.g. an (unsupported) Curve448Legacy subkey instead of ignoring it. To address this, we now throw on signature verification instead of parsing (as done for ECDSA). NB: the bug and this fix are not relevant for the new Ed25519/Ed448 entities as standardized by the crypto-refresh. --- src/crypto/signature.js | 21 ++++++++++------- src/util.js | 3 +++ test/general/key.js | 51 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 8 deletions(-) diff --git a/src/crypto/signature.js b/src/crypto/signature.js index d9574ad1..4f78a1ad 100644 --- a/src/crypto/signature.js +++ b/src/crypto/signature.js @@ -38,6 +38,8 @@ export function parseSignatureParams(algo, signature) { case enums.publicKey.dsa: case enums.publicKey.ecdsa: { + // If the signature payload sizes are unexpected, we will throw on verification, + // where we also have access to the OID curve from the key. const r = util.readMPI(signature.subarray(read)); read += r.length + 2; const s = util.readMPI(signature.subarray(read)); read += s.length + 2; return { read, signatureParams: { r, s } }; @@ -46,12 +48,11 @@ export function parseSignatureParams(algo, signature) { // - MPI of an EC point r. // - EdDSA value s, in MPI, in the little endian representation case enums.publicKey.eddsaLegacy: { - // When parsing little-endian MPI data, we always need to left-pad it, as done with big-endian values: - // https://www.ietf.org/archive/id/draft-ietf-openpgp-rfc4880bis-10.html#section-3.2-9 - let r = util.readMPI(signature.subarray(read)); read += r.length + 2; - r = util.leftPad(r, 32); - let s = util.readMPI(signature.subarray(read)); read += s.length + 2; - s = util.leftPad(s, 32); + // Only Curve25519Legacy is supported (no Curve448Legacy), but the relevant checks are done on key parsing and signature + // verification: if the signature payload sizes are unexpected, we will throw on verification, + // where we also have access to the OID curve from the key. + const r = util.readMPI(signature.subarray(read)); read += r.length + 2; + const s = util.readMPI(signature.subarray(read)); read += s.length + 2; return { read, signatureParams: { r, s } }; } // Algorithm-Specific Fields for Ed25519 signatures: @@ -108,8 +109,12 @@ export async function verify(algo, hashAlgo, signature, publicParams, data, hash } case enums.publicKey.eddsaLegacy: { const { oid, Q } = publicParams; - // signature already padded on parsing - return publicKey.elliptic.eddsaLegacy.verify(oid, hashAlgo, signature, data, Q, hashed); + const curveSize = new publicKey.elliptic.CurveWithOID(oid).payloadSize; + // When dealing little-endian MPI data, we always need to left-pad it, as done with big-endian values: + // https://www.ietf.org/archive/id/draft-ietf-openpgp-rfc4880bis-10.html#section-3.2-9 + const r = util.leftPad(signature.r, curveSize); + const s = util.leftPad(signature.s, curveSize); + return publicKey.elliptic.eddsaLegacy.verify(oid, hashAlgo, { r, s }, data, Q, hashed); } case enums.publicKey.ed25519: case enums.publicKey.ed448: { diff --git a/src/util.js b/src/util.js index d4635cad..d13052c0 100644 --- a/src/util.js +++ b/src/util.js @@ -148,6 +148,9 @@ const util = { * @returns {Uint8Array} Padded bytes. */ leftPad(bytes, length) { + if (bytes.length > length) { + throw new Error('Input array too long'); + } const padded = new Uint8Array(length); const offset = length - bytes.length; padded.set(bytes, offset); diff --git a/test/general/key.js b/test/general/key.js index 995c32b5..151a7116 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -3299,6 +3299,57 @@ ruh8m7Xo2ehSSFyWRSuTSZe5tm/KXgYG } }); + it('Parsing EdDSALegacy key with unsupported OID (Curve448Legacy)', async function() { + // Key with unknown OID (corresponding to curve448) which is not supported for EdDSALegacy + const armoredEdDSALegacyCurve448Key = `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xYUEYV2UmRYDK2VxAc9AFyxgh5xnSbyt50TWl558mw9xdMN+/UBLr5+UMP8IsrvV +MdXuTIE8CyaUQKSotHtH2RkYEXj5nsMAAAHPQIbTMSzjIWug8UFECzAex5FHgAgH +gYF3RK+TS8D24wX8kOu2C/NoVxwGY+p+i0JHaB+7yljriSKAGxs6wsBEBB8WCgCD +BYJhXZSZBYkFpI+9AwsJBwkQppmYlfq6zlJHFAAAAAAAHgAgc2FsdEBub3RhdGlv +bnMuc2VxdW9pYS1wZ3Aub3Jn5wSpIutJ5HncJWk4ruUV8GzQF390rR5+qWEAnAoY +akcDFQoIApsBAh4BFiEEwdtl1YDXuSJyVEseppmYlfq6zlIAALzdA5dA/fsgYg/J +qaQriYKaPUkyHL7EB3BXhV2d1h/gk+qJLvXQuU2WEJ/XSs3GrsBRiiZwvPH4o+7b +mleAxjy5wpS523vqrrBR2YZ5FwIku7WS4litSdn4AtVam/TlLdMNIf41CtFeZKBe +c5R5VNdQy8y7qy8AAADNEUN1cnZlNDQ4IE9wdGlvbiA4wsBHBBMWCgCGBYJhXZSZ +BYkFpI+9AwsJBwkQppmYlfq6zlJHFAAAAAAAHgAgc2FsdEBub3RhdGlvbnMuc2Vx +dW9pYS1wZ3Aub3JnD55UsYMzE6OACP+mgw5zvT+BBgol8/uFQjHg4krjUCMDFQoI +ApkBApsBAh4BFiEEwdtl1YDXuSJyVEseppmYlfq6zlIAAPQJA5dA0Xqwzn/0uwCq +RlsOVCB3f5NOj1exKnlBvRw0xT1VBee1yxvlUt5eIAoCxWoRlWBJob3TTkhm9AEA +8dyhwPmyGfWHzPw5NFG3xsXrZdNXNvit9WMVAPcmsyR7teXuDlJItxRAdJJc/qfJ +YVbBFoaNrhYAAADHhQRhXZSZFgMrZXEBz0BL7THZ9MnCLfSPJ1FMLim9eGkQ3Bfn +M3he5rOwO3t14QI1LjI96OjkeJipMgcFAmEP1Bq/ZHGO7oAAAc9AFnE8iNBaT3OU +EFtxkmWHXtdaYMmGGRdopw9JPXr/UxuunDln5o9dxPxf7q7z26zXrZen+qed/Isa +HsDCwSwEGBYKAWsFgmFdlJkFiQWkj70JEKaZmJX6us5SRxQAAAAAAB4AIHNhbHRA +bm90YXRpb25zLnNlcXVvaWEtcGdwLm9yZxREUizdTcepBzgSMOv2VWQCWbl++3CZ +EbgAWDryvSsyApsCwDGgBBkWCgBvBYJhXZSZCRBKo3SL4S5djkcUAAAAAAAeACBz +YWx0QG5vdGF0aW9ucy5zZXF1b2lhLXBncC5vcmemoGTDjmNQiIzw6HOEddvS0OB7 +UZ/P07jM/EVmnYxTlBYhBAxsnkGpx1UCiH6gUUqjdIvhLl2OAAALYQOXQAMB1oKq +OWxSFmvmgCKNcbAAyA3piF5ERIqs4z07oJvqDYrOWt75UsEIH/04gU/vHc4EmfG2 +JDLJgOLlyTUPkL/08f0ydGZPofFQBhn8HkuFFjnNtJ5oz3GIP4cdWMQFaUw0uvjb +PM9Tm3ptENGd6Ts1AAAAFiEEwdtl1YDXuSJyVEseppmYlfq6zlIAAGpTA5dATR6i +U2GrpUcQgpG+JqfAsGmF4yAOhgFxc1UfidFk3nTup3fLgjipkYY170WLRNbyKkVO +Sodx93GAs58rizO1acDAWiLq3cyEPBFXbyFThbcNPcLl+/77Uk/mgkYrPQFAQWdK +1kSRm4SizDBK37K8ChAAAADHhwRhXZSZEgMrZW8Bx0DMhzvhQo+OsXeqQ6QVw4sF +CaexHh6rLohh7TzL3hQSjoJ27fV6JBkIWdn0LfrMlJIDbSv2SLdlgQMBCgkAAcdA +MO7Dc1myF6Co1fAH+EuP+OxhxP/7V6ljuSCZENDfA49tQkzTta+PniG+pOVB2LHb +huyaKBkqiaogo8LAOQQYFgoAeAWCYV2UmQWJBaSPvQkQppmYlfq6zlJHFAAAAAAA +HgAgc2FsdEBub3RhdGlvbnMuc2VxdW9pYS1wZ3Aub3JnEjBMQAmc/2u45u5FQGmB +QAytjSG2LM3JQN+PPVl5vEkCmwwWIQTB22XVgNe5InJUSx6mmZiV+rrOUgAASdYD +l0DXEHQ9ykNP2rZP35ET1dmiFagFtTj/hLQcWlg16LqvJNGqOgYXuqTerbiOOt02 +XLCBln+wdewpU4ChEffMUDRBfqfQco/YsMqWV7bHJHAO0eC/DMKCjyU90xdH7R/d +QgqsfguR1PqPuJxpXV4bSr6CGAAAAA== +=MSvh +-----END PGP PRIVATE KEY BLOCK----- +`; + await expect(openpgp.readKey({ armoredKey: armoredEdDSALegacyCurve448Key })).to.be.rejectedWith(/No key packet found/); + + await expect(openpgp.readKey({ + armoredKey: armoredEdDSALegacyCurve448Key, + config: { ignoreUnsupportedPackets: false } + })).to.be.rejectedWith(/Unknown curve OID/); + }); + it('Parsing ECDH key with unknown kdf param version', async function() { // subkey with unknown kdfParam version 255. Parsing should not fail, the subkey should simply dropped const key = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- From e58c02d5ee0be727996b2728dd2274ce3e1ddb6c Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Thu, 17 Oct 2024 17:23:17 +0200 Subject: [PATCH 185/201] Check session key size on SEIPD decryption This is especially important for SEIPDv2 session keys, as a key derivation step is run where the resulting key will always match the expected cipher size, but we want to ensure that the input key isn't e.g. too short. --- .../sym_encrypted_integrity_protected_data.js | 25 +- test/general/packet.js | 610 +++++++----------- 2 files changed, 244 insertions(+), 391 deletions(-) diff --git a/src/packet/sym_encrypted_integrity_protected_data.js b/src/packet/sym_encrypted_integrity_protected_data.js index 4512aaa2..c2762c83 100644 --- a/src/packet/sym_encrypted_integrity_protected_data.js +++ b/src/packet/sym_encrypted_integrity_protected_data.js @@ -128,6 +128,16 @@ class SymEncryptedIntegrityProtectedDataPacket { * @async */ async encrypt(sessionKeyAlgorithm, key, config = defaultConfig) { + // We check that the session key size matches the one expected by the symmetric algorithm. + // This is especially important for SEIPDv2 session keys, as a key derivation step is run where the resulting key will always match the expected cipher size, + // but we want to ensure that the input key isn't e.g. too short. + // The check is done here, instead of on encrypted session key (ESK) encryption, because v6 ESK packets do not store the session key algorithm, + // which is instead included in the SEIPDv2 data. + const { blockSize, keySize } = crypto.getCipherParams(sessionKeyAlgorithm); + if (key.length !== keySize) { + throw new Error('Unexpected session key size'); + } + let bytes = this.packets.write(); if (stream.isArrayStream(bytes)) bytes = await stream.readToEnd(bytes); @@ -138,8 +148,6 @@ class SymEncryptedIntegrityProtectedDataPacket { this.chunkSizeByte = config.aeadChunkSizeByte; this.encrypted = await runAEAD(this, 'encrypt', key, bytes); } else { - const { blockSize } = crypto.getCipherParams(sessionKeyAlgorithm); - const prefix = await crypto.getPrefixRandom(sessionKeyAlgorithm); const mdc = new Uint8Array([0xD3, 0x14]); // modification detection code packet @@ -162,11 +170,24 @@ class SymEncryptedIntegrityProtectedDataPacket { * @async */ async decrypt(sessionKeyAlgorithm, key, config = defaultConfig) { + // We check that the session key size matches the one expected by the symmetric algorithm. + // This is especially important for SEIPDv2 session keys, as a key derivation step is run where the resulting key will always match the expected cipher size, + // but we want to ensure that the input key isn't e.g. too short. + // The check is done here, instead of on encrypted session key (ESK) decryption, because v6 ESK packets do not store the session key algorithm, + // which is instead included in the SEIPDv2 data. + if (key.length !== crypto.getCipherParams(sessionKeyAlgorithm).keySize) { + throw new Error('Unexpected session key size'); + } + let encrypted = stream.clone(this.encrypted); if (stream.isArrayStream(encrypted)) encrypted = await stream.readToEnd(encrypted); let packetbytes; if (this.version === 2) { + if (this.cipherAlgorithm !== sessionKeyAlgorithm) { + // sanity check + throw new Error('Unexpected session key algorithm'); + } packetbytes = await runAEAD(this, 'decrypt', key, encrypted); } else { const { blockSize } = crypto.getCipherParams(sessionKeyAlgorithm); diff --git a/test/general/packet.js b/test/general/packet.js index 78f5d621..4f8a58d0 100644 --- a/test/general/packet.js +++ b/test/general/packet.js @@ -9,7 +9,7 @@ import openpgp from '../initOpenpgp.js'; import crypto from '../../src/crypto'; import util from '../../src/util.js'; import * as packet from '../../src/packet'; - +import * as random from '../../src/crypto/random'; import * as input from './testInputs.js'; @@ -155,6 +155,50 @@ export default () => describe('Packet', function() { expect(await stringify(msg2[0].packets[0].data)).to.equal(stringify(literal.data)); }); + describe('Sym. encrypted integrity protected packet - throw on unexpected session key size', async () => { + async function testSEIPD(packetOptions) { + const symmetricAlgo = openpgp.enums.symmetric.aes256; + const key = random.getRandomBytes(crypto.getCipherParams(symmetricAlgo).keySize); + const unexpectedSymmetricAlgo = openpgp.enums.symmetric.aes128; + const keyWithUnexpectedSize = random.getRandomBytes(crypto.getCipherParams(unexpectedSymmetricAlgo).keySize); + + const plaintext = 'hello world'; + const literal = new openpgp.LiteralDataPacket(); + literal.setText(plaintext); + const seipd = openpgp.SymEncryptedIntegrityProtectedDataPacket.fromObject(packetOptions); + seipd.packets = new openpgp.PacketList(); + seipd.packets.push(literal); + + await expect( + seipd.encrypt(symmetricAlgo, keyWithUnexpectedSize, undefined, openpgp.config)).to.be.rejectedWith(/Unexpected session key size/); + expect(seipd.encrypted).to.be.null; + await seipd.encrypt(symmetricAlgo, key, undefined, openpgp.config); + expect(seipd.encrypted).to.not.be.null; + + const seipdParsed = new openpgp.SymEncryptedIntegrityProtectedDataPacket(); + await seipdParsed.read(seipd.write()); + await expect( + seipdParsed.decrypt(unexpectedSymmetricAlgo, keyWithUnexpectedSize, undefined, openpgp.config) + ).to.be.rejectedWith( + seipdParsed.version === 1 ? + /Modification detected/ : // SEIPDv1 does not store info about the symmetric algo + /Unexpected session key algo/ + ); + await expect( + seipdParsed.decrypt(unexpectedSymmetricAlgo, key, undefined, openpgp.config) + ).to.be.rejectedWith(/Unexpected session key size/); + await expect( + seipdParsed.decrypt(symmetricAlgo, keyWithUnexpectedSize, undefined, openpgp.config) + ).to.be.rejectedWith(/Unexpected session key size/); + await seipdParsed.decrypt(symmetricAlgo, key, undefined, openpgp.config); + + expect(seipdParsed.packets[0].getText()).to.equal(plaintext); + } + + it('SEIPDv1', () => testSEIPD({ version: 1 })); + it('SEIPDv2', () => testSEIPD({ version: 2, aeadAlgorithm: openpgp.enums.aead.gcm })); + }); + it('Sym. encrypted AEAD protected packet (AEADP)', function() { const aeadProtectVal = openpgp.config.aeadProtect; openpgp.config.aeadProtect = false; @@ -284,166 +328,101 @@ export default () => describe('Packet', function() { } }); - it('Sym. encrypted AEAD protected packet test vector (SEIPDv2 - EAX)', async function() { - // From https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh#appendix-A-5 - const nodeCrypto = util.getNodeCrypto(); - if (!nodeCrypto) return; + describe('Sym. encrypted integrity protected packet reading/writing test vector (SEIPDv2)', async function () { + const testVectors = [{ + // from https://datatracker.ietf.org/doc/html/rfc9580#appendix-A.9 + algoLabel: 'EAX', + aeadAlgo: openpgp.enums.aead.eax, + padding: util.hexToUint8Array('ae 5b f0 cd 67 05 50 03 55 81 6c b0 c8 ff'.replace(/\s+/g, '')), + sessionKey: util.hexToUint8Array('38 81 ba fe 98 54 12 45 9b 86 c3 6f 98 cb 9a 5e'.replace(/\s+/g, '')), + salt: util.hexToUint8Array('9f f9 0e 3b 32 19 64 f3 a4 29 13 c8 dc c6 61 93 25 01 52 27 ef b7 ea ea a4 9f 04 c2 e6 74 17 5d'.replace(/\s+/g, '')), + encryptedPacketBytes: util.hexToUint8Array(` + d2 69 02 07 01 06 + 9f f9 0e 3b 32 19 64 f3 a4 29 13 c8 dc c6 61 93 + 25 01 52 27 ef b7 ea ea a4 9f 04 c2 e6 74 17 5d + 4a 3d 22 6e d6 af cb 9c a9 ac 12 2c 14 70 e1 1c + 63 d4 c0 ab 24 1c 6a 93 8a d4 8b f9 9a 5a 99 b9 + 0b ba 83 25 de + 61 04 75 40 25 8a b7 95 9a 95 ad 05 1d da 96 eb + 15 43 1d fe f5 f5 e2 25 5c a7 82 61 54 6e 33 9a + `.replace(/\s+/g, '')) + }, + { + // from https://datatracker.ietf.org/doc/html/rfc9580#appendix-A.10 + algoLabel: 'OCB', + aeadAlgo: openpgp.enums.aead.ocb, + padding: util.hexToUint8Array('ae 6a a1 64 9b 56 aa 83 5b 26 13 90 2b d2'.replace(/\s+/g, '')), + sessionKey: util.hexToUint8Array('28 e7 9a b8 23 97 d3 c6 3d e2 4a c2 17 d7 b7 91'.replace(/\s+/g, '')), + salt: util.hexToUint8Array('20 a6 61 f7 31 fc 9a 30 32 b5 62 33 26 02 7e 3a 5d 8d b5 74 8e be ff 0b 0c 59 10 d0 9e cd d6 41'.replace(/\s+/g, '')), + encryptedPacketBytes: util.hexToUint8Array(` + d2 69 02 07 02 06 + 20 a6 61 f7 31 fc 9a 30 32 b5 62 33 26 02 7e 3a + 5d 8d b5 74 8e be ff 0b 0c 59 10 d0 9e cd d6 41 + ff 9f d3 85 62 75 80 35 bc 49 75 4c e1 bf 3f ff + a7 da d0 a3 b8 10 4f 51 33 cf 42 a4 10 0a 83 ee + f4 ca 1b 48 01 + a8 84 6b f4 2b cd a7 c8 ce 9d 65 e2 12 f3 01 cb + cd 98 fd ca de 69 4a 87 7a d4 24 73 23 f6 e8 57 + `.replace(/\s+/g, '')) + }, + { + // from https://datatracker.ietf.org/doc/html/rfc9580#appendix-A.11 + algoLabel: 'GCM', + aeadAlgo: openpgp.enums.aead.gcm, + padding: util.hexToUint8Array('1c e2 26 9a 9e dd ef 81 03 21 72 b7 ed 7c'.replace(/\s+/g, '')), + sessionKey: util.hexToUint8Array('19 36 fc 85 68 98 02 74 bb 90 0d 83 19 36 0c 77'.replace(/\s+/g, '')), + salt: util.hexToUint8Array('fc b9 44 90 bc b9 8b bd c9 d1 06 c6 09 02 66 94 0f 72 e8 9e dc 21 b5 59 6b 15 76 b1 01 ed 0f 9f'.replace(/\s+/g, '')), + encryptedPacketBytes: util.hexToUint8Array(` + d2 69 02 07 03 06 + fc b9 44 90 bc b9 8b bd c9 d1 06 c6 09 02 66 94 + 0f 72 e8 9e dc 21 b5 59 6b 15 76 b1 01 ed 0f 9f + fc 6f c6 d6 5b bf d2 4d cd 07 90 96 6e 6d 1e 85 + a3 00 53 78 4c b1 d8 b6 a0 69 9e f1 21 55 a7 b2 + ad 62 58 53 1b + 57 65 1f d7 77 79 12 fa 95 e3 5d 9b 40 21 6f 69 + a4 c2 48 db 28 ff 43 31 f1 63 29 07 39 9e 6f f9 + `.replace(/\s+/g, '')) + }]; - const packetBytes = util.hexToUint8Array(` - d2 69 02 07 01 06 - 9f f9 0e 3b 32 19 64 f3 a4 29 13 c8 dc c6 61 93 - 25 01 52 27 ef b7 ea ea a4 9f 04 c2 e6 74 17 5d - 4a 3d 22 6e d6 af cb 9c a9 ac 12 2c 14 70 e1 1c - 63 d4 c0 ab 24 1c 6a 93 8a d4 8b f9 9a 5a 99 b9 - 0b ba 83 25 de - 61 04 75 40 25 8a b7 95 9a 95 ad 05 1d da 96 eb - 15 43 1d fe f5 f5 e2 25 5c a7 82 61 54 6e 33 9a - `.replace(/\s+/g, '')); + testVectors.forEach(testVector => it(testVector.algoLabel, async function () { + const nodeCrypto = util.getNodeCrypto(); + if (!nodeCrypto) return; - const padding = util.hexToUint8Array('ae 5b f0 cd 67 05 50 03 55 81 6c b0 c8 ff'.replace(/\s+/g, '')); - const salt = util.hexToUint8Array('9f f9 0e 3b 32 19 64 f3 a4 29 13 c8 dc c6 61 93 25 01 52 27 ef b7 ea ea a4 9f 04 c2 e6 74 17 5d'.replace(/\s+/g, '')); - const key = util.hexToUint8Array('38 81 ba fe 98 54 12 45 9b 86 c3 6f 98 cb 9a 5e'.replace(/\s+/g, '')); - const algo = openpgp.enums.symmetric.aes128; + const symmetricAlgo = openpgp.enums.symmetric.aes128; - const randomBytesStub = sinon.stub(nodeCrypto, 'randomBytes'); - randomBytesStub.withArgs(14).returns(padding); - randomBytesStub.withArgs(32).returns(salt); + const { aeadAlgo: expectedAEADAlgo, padding, salt, sessionKey, encryptedPacketBytes: expectedEncryptedPacketBytes } = testVector; - const literal = new openpgp.LiteralDataPacket(0); - literal.setBytes(util.stringToUint8Array('Hello, world!'), openpgp.enums.literal.binary); - literal.filename = ''; - const pad = new openpgp.PaddingPacket(); - await pad.createPadding(14); - const enc = new openpgp.SymEncryptedIntegrityProtectedDataPacket(); - enc.version = 2; - enc.aeadAlgorithm = openpgp.enums.aead.eax; - enc.packets = new openpgp.PacketList(); - enc.packets.push(literal); - enc.packets.push(pad); - const msg = new openpgp.PacketList(); - msg.push(enc); + const randomBytesStub = sinon.stub(nodeCrypto, 'randomBytes'); + randomBytesStub.withArgs(14).returns(padding); + randomBytesStub.withArgs(32).returns(salt); - const msg2 = new openpgp.PacketList(); + const literal = new openpgp.LiteralDataPacket(0); + literal.setBytes(util.stringToUint8Array('Hello, world!'), openpgp.enums.literal.binary); + literal.filename = ''; + const pad = new openpgp.PaddingPacket(); + await pad.createPadding(14); + const seipdv2 = openpgp.SymEncryptedIntegrityProtectedDataPacket.fromObject({ version: 2, aeadAlgorithm: expectedAEADAlgo }); + seipdv2.packets = new openpgp.PacketList(); + seipdv2.packets.push(literal); + seipdv2.packets.push(pad); + const msg = new openpgp.PacketList(); + msg.push(seipdv2); - try { - await enc.encrypt(algo, key, { ...openpgp.config, aeadChunkSizeByte: 6 }); - const data = msg.write(); - expect(await stream.readToEnd(stream.clone(data))).to.deep.equal(packetBytes); - await msg2.read(data, allAllowedPackets); - await msg2[0].decrypt(algo, key); - expect(await stream.readToEnd(msg2[0].packets[0].data)).to.deep.equal(literal.data); - } finally { - randomBytesStub.restore(); - } - }); + try { + await seipdv2.encrypt(symmetricAlgo, sessionKey, { ...openpgp.config, aeadChunkSizeByte: 6 }); + const data = msg.write(); + expect(await stream.readToEnd(stream.clone(data))).to.deep.equal(expectedEncryptedPacketBytes); - it('Sym. encrypted AEAD protected packet test vector (SEIPDv2 - OCB)', async function() { - // From https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh#appendix-A-5 - - const nodeCrypto = util.getNodeCrypto(); - if (!nodeCrypto) return; - - const packetBytes = util.hexToUint8Array(` - d2 69 02 07 02 06 - 20 a6 61 f7 31 fc 9a 30 32 b5 62 33 26 02 7e 3a - 5d 8d b5 74 8e be ff 0b 0c 59 10 d0 9e cd d6 41 - ff 9f d3 85 62 75 80 35 bc 49 75 4c e1 bf 3f ff - a7 da d0 a3 b8 10 4f 51 33 cf 42 a4 10 0a 83 ee - f4 ca 1b 48 01 - a8 84 6b f4 2b cd a7 c8 ce 9d 65 e2 12 f3 01 cb - cd 98 fd ca de 69 4a 87 7a d4 24 73 23 f6 e8 57 - `.replace(/\s+/g, '')); - - const padding = util.hexToUint8Array('ae 6a a1 64 9b 56 aa 83 5b 26 13 90 2b d2'.replace(/\s+/g, '')); - const salt = util.hexToUint8Array('20 a6 61 f7 31 fc 9a 30 32 b5 62 33 26 02 7e 3a 5d 8d b5 74 8e be ff 0b 0c 59 10 d0 9e cd d6 41'.replace(/\s+/g, '')); - const key = util.hexToUint8Array('28 e7 9a b8 23 97 d3 c6 3d e2 4a c2 17 d7 b7 91'.replace(/\s+/g, '')); - const algo = openpgp.enums.symmetric.aes128; - - const randomBytesStub = sinon.stub(nodeCrypto, 'randomBytes'); - randomBytesStub.withArgs(14).returns(padding); - randomBytesStub.withArgs(32).returns(salt); - - const literal = new openpgp.LiteralDataPacket(0); - literal.setBytes(util.stringToUint8Array('Hello, world!'), openpgp.enums.literal.binary); - literal.filename = ''; - const pad = new openpgp.PaddingPacket(); - await pad.createPadding(14); - const enc = new openpgp.SymEncryptedIntegrityProtectedDataPacket(); - enc.version = 2; - enc.aeadAlgorithm = openpgp.enums.aead.ocb; - enc.packets = new openpgp.PacketList(); - enc.packets.push(literal); - enc.packets.push(pad); - const msg = new openpgp.PacketList(); - msg.push(enc); - - const msg2 = new openpgp.PacketList(); - - try { - await enc.encrypt(algo, key, { ...openpgp.config, aeadChunkSizeByte: 6 }); - const data = msg.write(); - expect(await stream.readToEnd(stream.clone(data))).to.deep.equal(packetBytes); - await msg2.read(data, allAllowedPackets); - await msg2[0].decrypt(algo, key); - expect(await stream.readToEnd(msg2[0].packets[0].data)).to.deep.equal(literal.data); - } finally { - randomBytesStub.restore(); - } - }); - - it('Sym. encrypted AEAD protected packet test vector (SEIPDv2 - GCM)', async function() { - // From https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh#appendix-A-5 - - const nodeCrypto = util.getNodeCrypto(); - if (!nodeCrypto) return; - - const packetBytes = util.hexToUint8Array(` - d2 69 02 07 03 06 - fc b9 44 90 bc b9 8b bd c9 d1 06 c6 09 02 66 94 - 0f 72 e8 9e dc 21 b5 59 6b 15 76 b1 01 ed 0f 9f - fc 6f c6 d6 5b bf d2 4d cd 07 90 96 6e 6d 1e 85 - a3 00 53 78 4c b1 d8 b6 a0 69 9e f1 21 55 a7 b2 - ad 62 58 53 1b - 57 65 1f d7 77 79 12 fa 95 e3 5d 9b 40 21 6f 69 - a4 c2 48 db 28 ff 43 31 f1 63 29 07 39 9e 6f f9 - `.replace(/\s+/g, '')); - - const padding = util.hexToUint8Array('1c e2 26 9a 9e dd ef 81 03 21 72 b7 ed 7c'.replace(/\s+/g, '')); - const salt = util.hexToUint8Array('fc b9 44 90 bc b9 8b bd c9 d1 06 c6 09 02 66 94 0f 72 e8 9e dc 21 b5 59 6b 15 76 b1 01 ed 0f 9f'.replace(/\s+/g, '')); - const key = util.hexToUint8Array('19 36 fc 85 68 98 02 74 bb 90 0d 83 19 36 0c 77'.replace(/\s+/g, '')); - const algo = openpgp.enums.symmetric.aes128; - - const randomBytesStub = sinon.stub(nodeCrypto, 'randomBytes'); - randomBytesStub.withArgs(14).returns(padding); - randomBytesStub.withArgs(32).returns(salt); - - const literal = new openpgp.LiteralDataPacket(0); - literal.setBytes(util.stringToUint8Array('Hello, world!'), openpgp.enums.literal.binary); - literal.filename = ''; - const pad = new openpgp.PaddingPacket(); - await pad.createPadding(14); - const enc = new openpgp.SymEncryptedIntegrityProtectedDataPacket(); - enc.version = 2; - enc.aeadAlgorithm = openpgp.enums.aead.gcm; - enc.packets = new openpgp.PacketList(); - enc.packets.push(literal); - enc.packets.push(pad); - const msg = new openpgp.PacketList(); - msg.push(enc); - - const msg2 = new openpgp.PacketList(); - - try { - await enc.encrypt(algo, key, { ...openpgp.config, aeadChunkSizeByte: 6 }); - const data = msg.write(); - expect(await stream.readToEnd(stream.clone(data))).to.deep.equal(packetBytes); - await msg2.read(data, allAllowedPackets); - await msg2[0].decrypt(algo, key); - expect(await stream.readToEnd(msg2[0].packets[0].data)).to.deep.equal(literal.data); - } finally { - randomBytesStub.restore(); - } + const msg2 = new openpgp.PacketList(); + await msg2.read(data, allAllowedPackets); + expect(msg2[0].cipherAlgorithm).to.equal(openpgp.enums.symmetric.aes128); + await msg2[0].decrypt(symmetricAlgo, sessionKey); + expect(await stream.readToEnd(msg2[0].packets[0].data)).to.deep.equal(literal.data); + } finally { + randomBytesStub.restore(); + } + })); }); it('Sym. encrypted session key with a compressed packet', async function() { @@ -914,245 +893,98 @@ export default () => describe('Packet', function() { } }); - it('Sym. encrypted session key reading/writing test vector (SEIPDv2, EAX)', async function() { - // From https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh#appendix-A.5 + describe('Sym. encrypted session key reading/writing test vector (SKESK v6)', async function () { + const testVectors = [{ + // from https://datatracker.ietf.org/doc/html/rfc9580#appendix-A.9.1 + algoLabel: 'EAX', + aeadAlgo: openpgp.enums.aead.eax, + s2kSalt: util.hexToUint8Array('a5 ae 57 9d 1f c5 d8 2b'.replace(/\s+/g, '')), + sessionKey: util.hexToUint8Array('38 81 ba fe 98 54 12 45 9b 86 c3 6f 98 cb 9a 5e'.replace(/\s+/g, '')), + sessionIV: util.hexToUint8Array('69 22 4f 91 99 93 b3 50 6f a3 b5 9a 6a 73 cf f8'.replace(/\s+/g, '')), + encryptedPacketBytes: util.hexToUint8Array(` + c3 40 06 1e 07 01 0b 03 + 08 a5 ae 57 9d 1f c5 d8 + 2b ff 69 22 4f 91 99 93 + b3 50 6f a3 b5 9a 6a 73 + cf f8 c5 ef c5 f4 1c 57 + fb 54 e1 c2 26 81 5d 78 + 28 f5 f9 2c 45 4e b6 5e + be 00 ab 59 86 c6 8e 6e + 7c 55`.replace(/\s+/g, '')) + }, + { + algoLabel: 'OCB', + aeadAlgo: openpgp.enums.aead.ocb, + padding: util.hexToUint8Array('ae 6a a1 64 9b 56 aa 83 5b 26 13 90 2b d2'.replace(/\s+/g, '')), + s2kSalt: util.hexToUint8Array('56 a2 98 d2 f5 e3 64 53'.replace(/\s+/g, '')), + sessionKey: util.hexToUint8Array('28 e7 9a b8 23 97 d3 c6 3d e2 4a c2 17 d7 b7 91'.replace(/\s+/g, '')), + sessionIV: util.hexToUint8Array('cf cc 5c 11 66 4e db 9d b4 25 90 d7 dc 46 b0'.replace(/\s+/g, '')), + encryptedPacketBytes: util.hexToUint8Array(` + c3 3f 06 1d 07 02 0b 03 + 08 56 a2 98 d2 f5 e3 64 + 53 ff cf cc 5c 11 66 4e + db 9d b4 25 90 d7 dc 46 + b0 72 41 b6 12 c3 81 2c + ff fb ea 00 f2 34 7b 25 + 64 11 23 f8 87 ae 60 d4 + fd 61 4e 08 37 d8 19 d3 + 6c`.replace(/\s+/g, '')) + }, + { + algoLabel: 'GCM', + aeadAlgo: openpgp.enums.aead.gcm, + s2kSalt: util.hexToUint8Array('e9 d3 97 85 b2 07 00 08'.replace(/\s+/g, '')), + sessionKey: util.hexToUint8Array('19 36 fc 85 68 98 02 74 bb 90 0d 83 19 36 0c 77'.replace(/\s+/g, '')), + sessionIV: util.hexToUint8Array('b4 2e 7c 48 3e f4 88 44 57 cb 37 26'.replace(/\s+/g, '')), + encryptedPacketBytes: util.hexToUint8Array(` + c3 3c 06 1a 07 03 0b 03 + 08 e9 d3 97 85 b2 07 00 + 08 ff b4 2e 7c 48 3e f4 + 88 44 57 cb 37 26 b9 b3 + db 9f f7 76 e5 f4 d9 a4 + 09 52 e2 44 72 98 85 1a + bf ff 75 26 df 2d d5 54 + 41 75 79 a7 79 9f`.replace(/\s+/g, '')) + }]; - const nodeCrypto = util.getNodeCrypto(); - if (!nodeCrypto) return; + testVectors.forEach(testVector => it(testVector.algoLabel, async function () { + const nodeCrypto = util.getNodeCrypto(); - const aeadProtectVal = openpgp.config.aeadProtect; - const aeadChunkSizeByteVal = openpgp.config.aeadChunkSizeByte; - const s2kIterationCountByteVal = openpgp.config.s2kIterationCountByte; - openpgp.config.aeadProtect = true; - openpgp.config.aeadChunkSizeByte = 6; - openpgp.config.s2kIterationCountByte = 255; + const { aeadAlgo: expectedAEADAlgo, s2kSalt, sessionKey, sessionIV, encryptedPacketBytes: expectedEncryptedPacketBytes } = testVector; + const randomBytesStub = sinon.stub(nodeCrypto, 'randomBytes'); + randomBytesStub.onCall(0).returns(s2kSalt); + randomBytesStub.onCall(1).returns(sessionKey); + randomBytesStub.onCall(2).returns(sessionIV); - const padding = util.hexToUint8Array('ae 5b f0 cd 67 05 50 03 55 81 6c b0 c8 ff'.replace(/\s+/g, '')); - const salt = util.hexToUint8Array('a5 ae 57 9d 1f c5 d8 2b'.replace(/\s+/g, '')); - const sessionKey = util.hexToUint8Array('38 81 ba fe 98 54 12 45 9b 86 c3 6f 98 cb 9a 5e'.replace(/\s+/g, '')); - const sessionIV = util.hexToUint8Array('69 22 4f 91 99 93 b3 50 6f a3 b5 9a 6a 73 cf f8'.replace(/\s+/g, '')); - const dataSalt = util.hexToUint8Array('9f f9 0e 3b 32 19 64 f3 a4 29 13 c8 dc c6 61 93 25 01 52 27 ef b7 ea ea a4 9f 04 c2 e6 74 17 5d'.replace(/\s+/g, '')); - - const randomBytesStub = sinon.stub(nodeCrypto, 'randomBytes'); - randomBytesStub.onCall(0).returns(padding); - randomBytesStub.onCall(1).returns(salt); - randomBytesStub.onCall(2).returns(sessionKey); - randomBytesStub.onCall(3).returns(sessionIV); - randomBytesStub.onCall(4).returns(dataSalt); - - const { data: packetBytes } = await openpgp.unarmor(`-----BEGIN PGP MESSAGE----- - -w0AGHgcBCwMIpa5XnR/F2Cv/aSJPkZmTs1Bvo7WaanPP+MXvxfQcV/tU4cImgV14 -KPX5LEVOtl6+AKtZhsaObnxV0mkCBwEGn/kOOzIZZPOkKRPI3MZhkyUBUifvt+rq -pJ8EwuZ0F11KPSJu1q/LnKmsEiwUcOEcY9TAqyQcapOK1Iv5mlqZuQu6gyXeYQR1 -QCWKt5Wala0FHdqW6xVDHf719eIlXKeCYVRuM5o= ------END PGP MESSAGE----- -`); - - try { - const passphrase = 'password'; - const algo = openpgp.enums.symmetric.aes128; - - const skesk = new openpgp.SymEncryptedSessionKeyPacket(); - skesk.sessionKeyAlgorithm = algo; - const literal = new openpgp.LiteralDataPacket(0); - literal.setBytes(util.stringToUint8Array('Hello, world!'), openpgp.enums.literal.binary); - literal.filename = ''; - const pad = new openpgp.PaddingPacket(); - await pad.createPadding(14); - const enc = new openpgp.SymEncryptedIntegrityProtectedDataPacket(); - enc.version = 2; - enc.aeadAlgorithm = skesk.aeadAlgorithm = openpgp.enums.aead.eax; - enc.packets = new openpgp.PacketList(); - enc.packets.push(literal); - enc.packets.push(pad); - const msg = new openpgp.PacketList(); - msg.push(skesk); - msg.push(enc); - - await skesk.encrypt(passphrase, openpgp.config); - - const key = skesk.sessionKey; - await enc.encrypt(algo, key, undefined, openpgp.config); - - const data = msg.write(); - expect(await stream.readToEnd(stream.clone(data))).to.deep.equal(packetBytes); - - const msg2 = new openpgp.PacketList(); - await msg2.read(data, allAllowedPackets); - - await msg2[0].decrypt(passphrase); - const key2 = msg2[0].sessionKey; - await msg2[1].decrypt(msg2[0].sessionKeyAlgorithm, key2); - - expect(await stringify(msg2[1].packets[0].data)).to.equal(stringify(literal.data)); - } finally { - openpgp.config.aeadProtect = aeadProtectVal; - openpgp.config.aeadChunkSizeByte = aeadChunkSizeByteVal; - openpgp.config.s2kIterationCountByte = s2kIterationCountByteVal; - randomBytesStub.restore(); - } - }); - - it('Sym. encrypted session key reading/writing test vector (SEIPDv2, OCB)', async function() { - // From https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh#appendix-A.6 - - const nodeCrypto = util.getNodeCrypto(); - if (!nodeCrypto) return; - - const aeadProtectVal = openpgp.config.aeadProtect; - const aeadChunkSizeByteVal = openpgp.config.aeadChunkSizeByte; - const s2kIterationCountByteVal = openpgp.config.s2kIterationCountByte; - openpgp.config.aeadProtect = true; - openpgp.config.aeadChunkSizeByte = 6; - openpgp.config.s2kIterationCountByte = 255; - - const padding = util.hexToUint8Array('ae 6a a1 64 9b 56 aa 83 5b 26 13 90 2b d2'.replace(/\s+/g, '')); - const salt = util.hexToUint8Array('56 a2 98 d2 f5 e3 64 53'.replace(/\s+/g, '')); - const sessionKey = util.hexToUint8Array('28 e7 9a b8 23 97 d3 c6 3d e2 4a c2 17 d7 b7 91'.replace(/\s+/g, '')); - const sessionIV = util.hexToUint8Array('cf cc 5c 11 66 4e db 9d b4 25 90 d7 dc 46 b0'.replace(/\s+/g, '')); - const dataSalt = util.hexToUint8Array('20 a6 61 f7 31 fc 9a 30 32 b5 62 33 26 02 7e 3a 5d 8d b5 74 8e be ff 0b 0c 59 10 d0 9e cd d6 41'.replace(/\s+/g, '')); - - const randomBytesStub = sinon.stub(nodeCrypto, 'randomBytes'); - randomBytesStub.onCall(0).returns(padding); - randomBytesStub.onCall(1).returns(salt); - randomBytesStub.onCall(2).returns(sessionKey); - randomBytesStub.onCall(3).returns(sessionIV); - randomBytesStub.onCall(4).returns(dataSalt); - - const { data: packetBytes } = await openpgp.unarmor(`-----BEGIN PGP MESSAGE----- - -wz8GHQcCCwMIVqKY0vXjZFP/z8xcEWZO2520JZDX3EawckG2EsOBLP/76gDyNHsl -ZBEj+IeuYNT9YU4IN9gZ02zSaQIHAgYgpmH3MfyaMDK1YjMmAn46XY21dI6+/wsM -WRDQns3WQf+f04VidYA1vEl1TOG/P/+n2tCjuBBPUTPPQqQQCoPu9MobSAGohGv0 -K82nyM6dZeIS8wHLzZj9yt5pSod61CRzI/boVw== ------END PGP MESSAGE----- -`); - - try { - const passphrase = 'password'; - const algo = openpgp.enums.symmetric.aes128; - - const skesk = new openpgp.SymEncryptedSessionKeyPacket(); - skesk.sessionKeyAlgorithm = algo; - const literal = new openpgp.LiteralDataPacket(0); - literal.setBytes(util.stringToUint8Array('Hello, world!'), openpgp.enums.literal.binary); - literal.filename = ''; - const pad = new openpgp.PaddingPacket(); - await pad.createPadding(14); - const enc = new openpgp.SymEncryptedIntegrityProtectedDataPacket(); - enc.version = 2; - enc.aeadAlgorithm = skesk.aeadAlgorithm = openpgp.enums.aead.ocb; - enc.packets = new openpgp.PacketList(); - enc.packets.push(literal); - enc.packets.push(pad); - const msg = new openpgp.PacketList(); - msg.push(skesk); - msg.push(enc); - - await skesk.encrypt(passphrase, openpgp.config); - - const key = skesk.sessionKey; - await enc.encrypt(algo, key, undefined, openpgp.config); - - const data = msg.write(); - expect(await stream.readToEnd(stream.clone(data))).to.deep.equal(packetBytes); - - const msg2 = new openpgp.PacketList(); - await msg2.read(data, allAllowedPackets); - - await msg2[0].decrypt(passphrase); - const key2 = msg2[0].sessionKey; - await msg2[1].decrypt(msg2[0].sessionKeyAlgorithm, key2); - - expect(await stringify(msg2[1].packets[0].data)).to.equal(stringify(literal.data)); - } finally { - openpgp.config.aeadProtect = aeadProtectVal; - openpgp.config.aeadChunkSizeByte = aeadChunkSizeByteVal; - openpgp.config.s2kIterationCountByte = s2kIterationCountByteVal; - randomBytesStub.restore(); - } - }); - - it('Sym. encrypted session key reading/writing test vector (SEIPDv2, GCM)', async function() { - // From https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh#appendix-A.7 - - const nodeCrypto = util.getNodeCrypto(); - if (!nodeCrypto) return; - - const aeadProtectVal = openpgp.config.aeadProtect; - const aeadChunkSizeByteVal = openpgp.config.aeadChunkSizeByte; - const s2kIterationCountByteVal = openpgp.config.s2kIterationCountByte; - openpgp.config.aeadProtect = true; - openpgp.config.aeadChunkSizeByte = 6; - openpgp.config.s2kIterationCountByte = 255; - - const padding = util.hexToUint8Array('1c e2 26 9a 9e dd ef 81 03 21 72 b7 ed 7c'.replace(/\s+/g, '')); - const salt = util.hexToUint8Array('e9 d3 97 85 b2 07 00 08'.replace(/\s+/g, '')); - const sessionKey = util.hexToUint8Array('19 36 fc 85 68 98 02 74 bb 90 0d 83 19 36 0c 77'.replace(/\s+/g, '')); - const sessionIV = util.hexToUint8Array('b4 2e 7c 48 3e f4 88 44 57 cb 37 26'.replace(/\s+/g, '')); - const dataSalt = util.hexToUint8Array('fc b9 44 90 bc b9 8b bd c9 d1 06 c6 09 02 66 94 0f 72 e8 9e dc 21 b5 59 6b 15 76 b1 01 ed 0f 9f'.replace(/\s+/g, '')); - - const randomBytesStub = sinon.stub(nodeCrypto, 'randomBytes'); - randomBytesStub.onCall(0).returns(padding); - randomBytesStub.onCall(1).returns(salt); - randomBytesStub.onCall(2).returns(sessionKey); - randomBytesStub.onCall(3).returns(sessionIV); - randomBytesStub.onCall(4).returns(dataSalt); - - const { data: packetBytes } = await openpgp.unarmor(`-----BEGIN PGP MESSAGE----- - -wzwGGgcDCwMI6dOXhbIHAAj/tC58SD70iERXyzcmubPbn/d25fTZpAlS4kRymIUa -v/91Jt8t1VRBdXmneZ/SaQIHAwb8uUSQvLmLvcnRBsYJAmaUD3LontwhtVlrFXax -Ae0Pn/xvxtZbv9JNzQeQlm5tHoWjAFN4TLHYtqBpnvEhVaeyrWJYUxtXZR/Xd3kS -+pXjXZtAIW9ppMJI2yj/QzHxYykHOZ5v+Q== ------END PGP MESSAGE----- -`); - - try { - const passphrase = 'password'; - const algo = openpgp.enums.symmetric.aes128; - - const skesk = new openpgp.SymEncryptedSessionKeyPacket(); - skesk.sessionKeyAlgorithm = algo; - const literal = new openpgp.LiteralDataPacket(0); - literal.setBytes(util.stringToUint8Array('Hello, world!'), openpgp.enums.literal.binary); - literal.filename = ''; - const pad = new openpgp.PaddingPacket(); - await pad.createPadding(14); - const enc = new openpgp.SymEncryptedIntegrityProtectedDataPacket(); - enc.version = 2; - enc.aeadAlgorithm = skesk.aeadAlgorithm = openpgp.enums.aead.gcm; - enc.packets = new openpgp.PacketList(); - enc.packets.push(literal); - enc.packets.push(pad); - const msg = new openpgp.PacketList(); - msg.push(skesk); - msg.push(enc); - - await skesk.encrypt(passphrase, openpgp.config); - - const key = skesk.sessionKey; - await enc.encrypt(algo, key, undefined, openpgp.config); - - const data = msg.write(); - expect(await stream.readToEnd(stream.clone(data))).to.deep.equal(packetBytes); - - const msg2 = new openpgp.PacketList(); - await msg2.read(data, allAllowedPackets); - - await msg2[0].decrypt(passphrase); - const key2 = msg2[0].sessionKey; - await msg2[1].decrypt(msg2[0].sessionKeyAlgorithm, key2); - - expect(await stringify(msg2[1].packets[0].data)).to.equal(stringify(literal.data)); - } finally { - openpgp.config.aeadProtect = aeadProtectVal; - openpgp.config.aeadChunkSizeByte = aeadChunkSizeByteVal; - openpgp.config.s2kIterationCountByte = s2kIterationCountByteVal; - randomBytesStub.restore(); - } - }); + try { + const passphrase = 'password'; + const symmetricAlgo = openpgp.enums.symmetric.aes128; + + const skesk = new openpgp.SymEncryptedSessionKeyPacket(); + skesk.version = 6; + skesk.sessionKeyAlgorithm = symmetricAlgo; + skesk.aeadAlgorithm = expectedAEADAlgo; + const msg = new openpgp.PacketList(); + msg.push(skesk); + + await skesk.encrypt(passphrase, { ...openpgp.config, aeadChunkSizeByte: 6, s2kIterationCountByte: 255 }); + + const serialized = msg.write(); + expect(await stream.readToEnd(stream.clone(serialized))).to.deep.equal(expectedEncryptedPacketBytes); + + const msg2 = new openpgp.PacketList(); + await msg2.read(serialized, allAllowedPackets); + + await msg2[0].decrypt(passphrase); + const decryptedSessionKey = msg2[0].sessionKey; + const decryptedSessionKeyAlgo = msg2[0].sessionKeyAlgorithm; + expect(decryptedSessionKey).to.deep.equal(sessionKey); + expect(decryptedSessionKeyAlgo).to.be.null; + } finally { + randomBytesStub.restore(); + } + })); + }) it('Secret key encryption/decryption test', async function() { const armored_msg = From 3cdaab7894cdba91c581c0d58991e024c06be90a Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Thu, 17 Oct 2024 17:29:04 +0200 Subject: [PATCH 186/201] Check session key size on v3 SKESK and PKESK packet decryption For v3 SKESK and PKESK packets, the session key algorithm is part of the payload, so we can check the session key size on packet decryption. This is helpful to catch errors early, when using e.g. `decryptSessionKeys`. In v6 packets, the session key size check can only be done on SEIPDv2 decryption. --- src/packet/public_key_encrypted_session_key.js | 13 ++++++++----- src/packet/sym_encrypted_session_key.js | 6 +++++- test/crypto/eax.js | 2 +- test/crypto/gcm.js | 4 ++-- test/general/openpgp.js | 4 ++-- 5 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/packet/public_key_encrypted_session_key.js b/src/packet/public_key_encrypted_session_key.js index f0bdc402..eaa5dacd 100644 --- a/src/packet/public_key_encrypted_session_key.js +++ b/src/packet/public_key_encrypted_session_key.js @@ -208,11 +208,14 @@ class PublicKeyEncryptedSessionKeyPacket { const { sessionKey, sessionKeyAlgorithm } = decodeSessionKey(this.version, this.publicKeyAlgorithm, decryptedData, randomSessionKey); - // v3 Montgomery curves have cleartext cipher algo - if (this.version === 3 && ( - this.publicKeyAlgorithm !== enums.publicKey.x25519 && this.publicKeyAlgorithm !== enums.publicKey.x448) - ) { - this.sessionKeyAlgorithm = sessionKeyAlgorithm; + if (this.version === 3) { + // v3 Montgomery curves have cleartext cipher algo + const hasEncryptedAlgo = this.publicKeyAlgorithm !== enums.publicKey.x25519 && this.publicKeyAlgorithm !== enums.publicKey.x448; + this.sessionKeyAlgorithm = hasEncryptedAlgo ? sessionKeyAlgorithm : this.sessionKeyAlgorithm; + + if (sessionKey.length !== crypto.getCipherParams(this.sessionKeyAlgorithm).keySize) { + throw new Error('Unexpected session key size'); + } } this.sessionKey = sessionKey; } diff --git a/src/packet/sym_encrypted_session_key.js b/src/packet/sym_encrypted_session_key.js index 464be72e..4ea592f9 100644 --- a/src/packet/sym_encrypted_session_key.js +++ b/src/packet/sym_encrypted_session_key.js @@ -56,7 +56,7 @@ class SymEncryptedSessionKeyPacket { * Algorithm to encrypt the message with * @type {enums.symmetric} */ - this.sessionKeyAlgorithm = enums.symmetric.aes256; + this.sessionKeyAlgorithm = null; /** * AEAD mode to encrypt the session key with (if AEAD protection is enabled) * @type {enums.aead} @@ -177,7 +177,11 @@ class SymEncryptedSessionKeyPacket { this.sessionKeyAlgorithm = enums.write(enums.symmetric, decrypted[0]); this.sessionKey = decrypted.subarray(1, decrypted.length); + if (this.sessionKey.length !== crypto.getCipherParams(this.sessionKeyAlgorithm).keySize) { + throw new Error('Unexpected session key size'); + } } else { + // session key size is checked as part of SEIPDv2 decryption, where we know the expected symmetric algo this.sessionKey = key; } } diff --git a/test/crypto/eax.js b/test/crypto/eax.js index d5191b37..a18688a2 100644 --- a/test/crypto/eax.js +++ b/test/crypto/eax.js @@ -159,7 +159,7 @@ export default () => describe('Symmetric AES-EAX', function() { testAESEAX(); }); - describe('Symmetric AES-EAX (asm.js fallback)', function() { + describe('Symmetric AES-EAX (non-native fallback)', function() { beforeEach(function () { sinonSandbox = sinon.createSandbox(); disableNative(); diff --git a/test/crypto/gcm.js b/test/crypto/gcm.js index f564c400..cf4e6600 100644 --- a/test/crypto/gcm.js +++ b/test/crypto/gcm.js @@ -77,11 +77,11 @@ export default () => describe('Symmetric AES-GCM (experimental)', function() { testAESGCM('12345678901234567890123456789012345678901234567890', true, true); }); - describe('Symmetric AES-GCM (asm.js fallback)', function() { + describe('Symmetric AES-GCM (non-native)', function() { testAESGCM('12345678901234567890123456789012345678901234567890', false, false); }); - describe('Symmetric AES-GCM (native encrypt, asm.js decrypt)', function() { + describe('Symmetric AES-GCM (native encrypt, non-native decrypt)', function() { testAESGCM('12345678901234567890123456789012345678901234567890', true, false); }); }); diff --git a/test/general/openpgp.js b/test/general/openpgp.js index fe9ae8c2..c141206e 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -2532,7 +2532,7 @@ XfA3pqV4mTzF } }); - tryTests('CFB mode (asm.js)', tests, { + tryTests('CFB mode', tests, { if: true, beforeEach: function() { openpgp.config.aeadProtect = false; @@ -2582,7 +2582,7 @@ XfA3pqV4mTzF function tests() { describe('encryptSessionKey, decryptSessionKeys', function() { - const sk = new Uint8Array([0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01]); + const sk = new Uint8Array([0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01]); let decryptedPrivateKey; // to avoid decrypting key before each test beforeEach(async function() { From 05fbc637320a76abbfdf32a80aed984b422e2686 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Fri, 18 Oct 2024 17:34:33 +0200 Subject: [PATCH 187/201] Use `WebCrypto.getRandomValues` in Node To move towards uniform code with across platforms. --- src/crypto/random.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/crypto/random.js b/src/crypto/random.js index c7e53169..3ebe4a1f 100644 --- a/src/crypto/random.js +++ b/src/crypto/random.js @@ -32,16 +32,13 @@ const nodeCrypto = util.getNodeCrypto(); * @returns {Uint8Array} Random byte array. */ export function getRandomBytes(length) { - const buf = new Uint8Array(length); - if (nodeCrypto) { - const bytes = nodeCrypto.randomBytes(buf.length); - buf.set(bytes); - } else if (typeof crypto !== 'undefined' && crypto.getRandomValues) { - crypto.getRandomValues(buf); + const webcrypto = typeof crypto !== 'undefined' ? crypto : nodeCrypto?.webcrypto; + if (webcrypto?.getRandomValues) { + const buf = new Uint8Array(length); + return webcrypto.getRandomValues(buf); } else { throw new Error('No secure random number generator available.'); } - return buf; } /** From 88f20974dd5de3fb1b3572c8fc3f2f198e5ac19a Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Fri, 18 Oct 2024 17:50:52 +0200 Subject: [PATCH 188/201] Tests: add support for RNG mocking in browser tests The affected tests were previously only run in Node. --- package-lock.json | 18 ++ package.json | 1 + test/general/packet.js | 521 ++++++++++++++++++----------------------- test/mockRandom.ts | 29 +++ 4 files changed, 279 insertions(+), 290 deletions(-) create mode 100644 test/mockRandom.ts diff --git a/package-lock.json b/package-lock.json index bae4b324..63873e27 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@rollup/plugin-wasm": "^6.2.2", "@types/chai": "^4.3.19", + "@types/sinon": "^17.0.3", "@typescript-eslint/parser": "^7.18.0", "argon2id": "^1.0.1", "benchmark": "^2.1.4", @@ -1531,6 +1532,23 @@ "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", "dev": true }, + "node_modules/@types/sinon": { + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.3.tgz", + "integrity": "sha512-j3uovdn8ewky9kRBG19bOwaZbexJu/XjtkHyjvUgt4xfPFz18dcORIMqnYh66Fx3Powhcr85NT5+er3+oViapw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/sinonjs__fake-timers": "*" + } + }, + "node_modules/@types/sinonjs__fake-timers": { + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.5.tgz", + "integrity": "sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "7.18.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz", diff --git a/package.json b/package.json index e1c9633f..6a848d4f 100644 --- a/package.json +++ b/package.json @@ -77,6 +77,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@rollup/plugin-wasm": "^6.2.2", "@types/chai": "^4.3.19", + "@types/sinon": "^17.0.3", "@typescript-eslint/parser": "^7.18.0", "argon2id": "^1.0.1", "benchmark": "^2.1.4", diff --git a/test/general/packet.js b/test/general/packet.js index 4f8a58d0..e977ebab 100644 --- a/test/general/packet.js +++ b/test/general/packet.js @@ -12,6 +12,7 @@ import * as packet from '../../src/packet'; import * as random from '../../src/crypto/random'; import * as input from './testInputs.js'; +import { mockCryptoRandomGenerator, restoreCryptoRandomGenerator } from '../mockRandom.ts'; function stringify(array) { if (stream.isStream(array)) { @@ -287,9 +288,6 @@ export default () => describe('Packet', function() { it('AEAD Encrypted Data packet test vector (AEADP)', async function() { // From https://gitlab.com/openpgp-wg/rfc4880bis/commit/00b20923e6233fb6ff1666ecd5acfefceb32907d - const nodeCrypto = util.getNodeCrypto(); - if (!nodeCrypto) return; - const packetBytes = util.hexToUint8Array(` d4 4a 01 07 01 0e b7 32 37 9f 73 c4 92 8d e2 5f ac fe 65 17 ec 10 5d c1 1a 81 dc 0c b8 a2 f6 f3 @@ -311,12 +309,16 @@ export default () => describe('Packet', function() { const msg = new openpgp.PacketList(); msg.push(enc); - const msg2 = new openpgp.PacketList(); - - const randomBytesStub = sinon.stub(nodeCrypto, 'randomBytes'); - randomBytesStub.returns(iv); try { + const msg2 = new openpgp.PacketList(); + + const randomBytesStub = sinon.stub(); + randomBytesStub.onCall(0).returns(iv); + // no more random calls expected, so we throw as a reminder to update behavior if needed in the future + randomBytesStub.throws('random mock behavior not defined'); + mockCryptoRandomGenerator(randomBytesStub); + await enc.encrypt(algo, key, { ...openpgp.config, aeadChunkSizeByte: 14 }); const data = msg.write(); expect(await stream.readToEnd(stream.clone(data))).to.deep.equal(packetBytes); @@ -324,92 +326,92 @@ export default () => describe('Packet', function() { await msg2[0].decrypt(algo, key); expect(await stream.readToEnd(msg2[0].packets[0].data)).to.deep.equal(literal.data); } finally { - randomBytesStub.restore(); + restoreCryptoRandomGenerator(); } }); describe('Sym. encrypted integrity protected packet reading/writing test vector (SEIPDv2)', async function () { const testVectors = [{ - // from https://datatracker.ietf.org/doc/html/rfc9580#appendix-A.9 - algoLabel: 'EAX', - aeadAlgo: openpgp.enums.aead.eax, - padding: util.hexToUint8Array('ae 5b f0 cd 67 05 50 03 55 81 6c b0 c8 ff'.replace(/\s+/g, '')), - sessionKey: util.hexToUint8Array('38 81 ba fe 98 54 12 45 9b 86 c3 6f 98 cb 9a 5e'.replace(/\s+/g, '')), - salt: util.hexToUint8Array('9f f9 0e 3b 32 19 64 f3 a4 29 13 c8 dc c6 61 93 25 01 52 27 ef b7 ea ea a4 9f 04 c2 e6 74 17 5d'.replace(/\s+/g, '')), - encryptedPacketBytes: util.hexToUint8Array(` - d2 69 02 07 01 06 - 9f f9 0e 3b 32 19 64 f3 a4 29 13 c8 dc c6 61 93 - 25 01 52 27 ef b7 ea ea a4 9f 04 c2 e6 74 17 5d - 4a 3d 22 6e d6 af cb 9c a9 ac 12 2c 14 70 e1 1c - 63 d4 c0 ab 24 1c 6a 93 8a d4 8b f9 9a 5a 99 b9 - 0b ba 83 25 de - 61 04 75 40 25 8a b7 95 9a 95 ad 05 1d da 96 eb - 15 43 1d fe f5 f5 e2 25 5c a7 82 61 54 6e 33 9a - `.replace(/\s+/g, '')) - }, - { - // from https://datatracker.ietf.org/doc/html/rfc9580#appendix-A.10 - algoLabel: 'OCB', - aeadAlgo: openpgp.enums.aead.ocb, - padding: util.hexToUint8Array('ae 6a a1 64 9b 56 aa 83 5b 26 13 90 2b d2'.replace(/\s+/g, '')), - sessionKey: util.hexToUint8Array('28 e7 9a b8 23 97 d3 c6 3d e2 4a c2 17 d7 b7 91'.replace(/\s+/g, '')), - salt: util.hexToUint8Array('20 a6 61 f7 31 fc 9a 30 32 b5 62 33 26 02 7e 3a 5d 8d b5 74 8e be ff 0b 0c 59 10 d0 9e cd d6 41'.replace(/\s+/g, '')), - encryptedPacketBytes: util.hexToUint8Array(` - d2 69 02 07 02 06 - 20 a6 61 f7 31 fc 9a 30 32 b5 62 33 26 02 7e 3a - 5d 8d b5 74 8e be ff 0b 0c 59 10 d0 9e cd d6 41 - ff 9f d3 85 62 75 80 35 bc 49 75 4c e1 bf 3f ff - a7 da d0 a3 b8 10 4f 51 33 cf 42 a4 10 0a 83 ee - f4 ca 1b 48 01 - a8 84 6b f4 2b cd a7 c8 ce 9d 65 e2 12 f3 01 cb - cd 98 fd ca de 69 4a 87 7a d4 24 73 23 f6 e8 57 - `.replace(/\s+/g, '')) - }, - { - // from https://datatracker.ietf.org/doc/html/rfc9580#appendix-A.11 - algoLabel: 'GCM', - aeadAlgo: openpgp.enums.aead.gcm, - padding: util.hexToUint8Array('1c e2 26 9a 9e dd ef 81 03 21 72 b7 ed 7c'.replace(/\s+/g, '')), - sessionKey: util.hexToUint8Array('19 36 fc 85 68 98 02 74 bb 90 0d 83 19 36 0c 77'.replace(/\s+/g, '')), - salt: util.hexToUint8Array('fc b9 44 90 bc b9 8b bd c9 d1 06 c6 09 02 66 94 0f 72 e8 9e dc 21 b5 59 6b 15 76 b1 01 ed 0f 9f'.replace(/\s+/g, '')), - encryptedPacketBytes: util.hexToUint8Array(` - d2 69 02 07 03 06 - fc b9 44 90 bc b9 8b bd c9 d1 06 c6 09 02 66 94 - 0f 72 e8 9e dc 21 b5 59 6b 15 76 b1 01 ed 0f 9f - fc 6f c6 d6 5b bf d2 4d cd 07 90 96 6e 6d 1e 85 - a3 00 53 78 4c b1 d8 b6 a0 69 9e f1 21 55 a7 b2 - ad 62 58 53 1b - 57 65 1f d7 77 79 12 fa 95 e3 5d 9b 40 21 6f 69 - a4 c2 48 db 28 ff 43 31 f1 63 29 07 39 9e 6f f9 - `.replace(/\s+/g, '')) + // from https://datatracker.ietf.org/doc/html/rfc9580#appendix-A.9 + algoLabel: 'EAX', + aeadAlgo: openpgp.enums.aead.eax, + padding: util.hexToUint8Array('ae 5b f0 cd 67 05 50 03 55 81 6c b0 c8 ff'.replace(/\s+/g, '')), + sessionKey: util.hexToUint8Array('38 81 ba fe 98 54 12 45 9b 86 c3 6f 98 cb 9a 5e'.replace(/\s+/g, '')), + salt: util.hexToUint8Array('9f f9 0e 3b 32 19 64 f3 a4 29 13 c8 dc c6 61 93 25 01 52 27 ef b7 ea ea a4 9f 04 c2 e6 74 17 5d'.replace(/\s+/g, '')), + encryptedPacketBytes: util.hexToUint8Array(` + d2 69 02 07 01 06 + 9f f9 0e 3b 32 19 64 f3 a4 29 13 c8 dc c6 61 93 + 25 01 52 27 ef b7 ea ea a4 9f 04 c2 e6 74 17 5d + 4a 3d 22 6e d6 af cb 9c a9 ac 12 2c 14 70 e1 1c + 63 d4 c0 ab 24 1c 6a 93 8a d4 8b f9 9a 5a 99 b9 + 0b ba 83 25 de + 61 04 75 40 25 8a b7 95 9a 95 ad 05 1d da 96 eb + 15 43 1d fe f5 f5 e2 25 5c a7 82 61 54 6e 33 9a + `.replace(/\s+/g, '')) + }, + { + // from https://datatracker.ietf.org/doc/html/rfc9580#appendix-A.10 + algoLabel: 'OCB', + aeadAlgo: openpgp.enums.aead.ocb, + padding: util.hexToUint8Array('ae 6a a1 64 9b 56 aa 83 5b 26 13 90 2b d2'.replace(/\s+/g, '')), + sessionKey: util.hexToUint8Array('28 e7 9a b8 23 97 d3 c6 3d e2 4a c2 17 d7 b7 91'.replace(/\s+/g, '')), + salt: util.hexToUint8Array('20 a6 61 f7 31 fc 9a 30 32 b5 62 33 26 02 7e 3a 5d 8d b5 74 8e be ff 0b 0c 59 10 d0 9e cd d6 41'.replace(/\s+/g, '')), + encryptedPacketBytes: util.hexToUint8Array(` + d2 69 02 07 02 06 + 20 a6 61 f7 31 fc 9a 30 32 b5 62 33 26 02 7e 3a + 5d 8d b5 74 8e be ff 0b 0c 59 10 d0 9e cd d6 41 + ff 9f d3 85 62 75 80 35 bc 49 75 4c e1 bf 3f ff + a7 da d0 a3 b8 10 4f 51 33 cf 42 a4 10 0a 83 ee + f4 ca 1b 48 01 + a8 84 6b f4 2b cd a7 c8 ce 9d 65 e2 12 f3 01 cb + cd 98 fd ca de 69 4a 87 7a d4 24 73 23 f6 e8 57 + `.replace(/\s+/g, '')) + }, + { + // from https://datatracker.ietf.org/doc/html/rfc9580#appendix-A.11 + algoLabel: 'GCM', + aeadAlgo: openpgp.enums.aead.gcm, + padding: util.hexToUint8Array('1c e2 26 9a 9e dd ef 81 03 21 72 b7 ed 7c'.replace(/\s+/g, '')), + sessionKey: util.hexToUint8Array('19 36 fc 85 68 98 02 74 bb 90 0d 83 19 36 0c 77'.replace(/\s+/g, '')), + salt: util.hexToUint8Array('fc b9 44 90 bc b9 8b bd c9 d1 06 c6 09 02 66 94 0f 72 e8 9e dc 21 b5 59 6b 15 76 b1 01 ed 0f 9f'.replace(/\s+/g, '')), + encryptedPacketBytes: util.hexToUint8Array(` + d2 69 02 07 03 06 + fc b9 44 90 bc b9 8b bd c9 d1 06 c6 09 02 66 94 + 0f 72 e8 9e dc 21 b5 59 6b 15 76 b1 01 ed 0f 9f + fc 6f c6 d6 5b bf d2 4d cd 07 90 96 6e 6d 1e 85 + a3 00 53 78 4c b1 d8 b6 a0 69 9e f1 21 55 a7 b2 + ad 62 58 53 1b + 57 65 1f d7 77 79 12 fa 95 e3 5d 9b 40 21 6f 69 + a4 c2 48 db 28 ff 43 31 f1 63 29 07 39 9e 6f f9 + `.replace(/\s+/g, '')) }]; testVectors.forEach(testVector => it(testVector.algoLabel, async function () { - const nodeCrypto = util.getNodeCrypto(); - if (!nodeCrypto) return; - const symmetricAlgo = openpgp.enums.symmetric.aes128; const { aeadAlgo: expectedAEADAlgo, padding, salt, sessionKey, encryptedPacketBytes: expectedEncryptedPacketBytes } = testVector; - const randomBytesStub = sinon.stub(nodeCrypto, 'randomBytes'); - randomBytesStub.withArgs(14).returns(padding); - randomBytesStub.withArgs(32).returns(salt); - - const literal = new openpgp.LiteralDataPacket(0); - literal.setBytes(util.stringToUint8Array('Hello, world!'), openpgp.enums.literal.binary); - literal.filename = ''; - const pad = new openpgp.PaddingPacket(); - await pad.createPadding(14); - const seipdv2 = openpgp.SymEncryptedIntegrityProtectedDataPacket.fromObject({ version: 2, aeadAlgorithm: expectedAEADAlgo }); - seipdv2.packets = new openpgp.PacketList(); - seipdv2.packets.push(literal); - seipdv2.packets.push(pad); - const msg = new openpgp.PacketList(); - msg.push(seipdv2); - try { + const randomBytesStub = sinon.stub(); + randomBytesStub.onCall(0).returns(padding); + randomBytesStub.onCall(1).returns(salt); + // no more random calls expected, so we throw as a reminder to update behavior if needed in the future + randomBytesStub.onCall(2).throws('random mock behavior not defined'); + mockCryptoRandomGenerator(randomBytesStub); + + const literal = new openpgp.LiteralDataPacket(0); + literal.setBytes(util.stringToUint8Array('Hello, world!'), openpgp.enums.literal.binary); + literal.filename = ''; + const pad = new openpgp.PaddingPacket(); + await pad.createPadding(14); + const seipdv2 = openpgp.SymEncryptedIntegrityProtectedDataPacket.fromObject({ version: 2, aeadAlgorithm: expectedAEADAlgo }); + seipdv2.packets = new openpgp.PacketList(); + seipdv2.packets.push(literal); + seipdv2.packets.push(pad); + const msg = new openpgp.PacketList(); + msg.push(seipdv2); + await seipdv2.encrypt(symmetricAlgo, sessionKey, { ...openpgp.config, aeadChunkSizeByte: 6 }); const data = msg.write(); expect(await stream.readToEnd(stream.clone(data))).to.deep.equal(expectedEncryptedPacketBytes); @@ -420,7 +422,7 @@ export default () => describe('Packet', function() { await msg2[0].decrypt(symmetricAlgo, sessionKey); expect(await stream.readToEnd(msg2[0].packets[0].data)).to.deep.equal(literal.data); } finally { - randomBytesStub.restore(); + restoreCryptoRandomGenerator(); } })); }); @@ -735,256 +737,195 @@ export default () => describe('Packet', function() { } }); - it('Sym. encrypted session key reading/writing test vector (AEAD, EAX)', async function() { - // From https://gitlab.com/openpgp-wg/rfc4880bis/blob/00b20923/back.mkd#sample-aead-eax-encryption-and-decryption + describe('Sym. encrypted session key reading/writing test vector (SKESK with AEADP)', () => { + const testVectors = [{ + // From https://gitlab.com/openpgp-wg/rfc4880bis/blob/00b20923/back.mkd#sample-aead-eax-encryption-and-decryption + algoLabel: 'EAX', + aeadAlgo: openpgp.enums.aead.eax, + salt: util.hexToUint8Array('cd5a9f70fbe0bc65'), + sessionKey: util.hexToUint8Array('86 f1 ef b8 69 52 32 9f 24 ac d3 bf d0 e5 34 6d'.replace(/\s+/g, '')), + sessionIV: util.hexToUint8Array('bc 66 9e 34 e5 00 dc ae dc 5b 32 aa 2d ab 02 35'.replace(/\s+/g, '')), + dataIV: util.hexToUint8Array('b7 32 37 9f 73 c4 92 8d e2 5f ac fe 65 17 ec 10'.replace(/\s+/g, '')), + packetBytes: util.hexToUint8Array(` + c3 3e 05 07 01 03 08 cd 5a 9f 70 fb e0 bc 65 90 + bc 66 9e 34 e5 00 dc ae dc 5b 32 aa 2d ab 02 35 + 9d ee 19 d0 7c 34 46 c4 31 2a 34 ae 19 67 a2 fb + 7e 92 8e a5 b4 fa 80 12 bd 45 6d 17 38 c6 3c 36 - const nodeCrypto = util.getNodeCrypto(); - if (!nodeCrypto) return; + d4 4a 01 07 01 0e b7 32 37 9f 73 c4 92 8d e2 5f + ac fe 65 17 ec 10 5d c1 1a 81 dc 0c b8 a2 f6 f3 + d9 00 16 38 4a 56 fc 82 1a e1 1a e8 db cb 49 86 + 26 55 de a8 8d 06 a8 14 86 80 1b 0f f3 87 bd 2e + ab 01 3d e1 25 95 86 90 6e ab 24 76 + `.replace(/\s+/g, '')) + }, + { + algoLabel: 'OCB', + aeadAlgo: openpgp.enums.aead.ocb, + salt: util.hexToUint8Array('9f0b7da3e5ea6477'), + sessionKey: util.hexToUint8Array('d1 f0 1b a3 0e 13 0a a7 d2 58 2c 16 e0 50 ae 44'.replace(/\s+/g, '')), + sessionIV: util.hexToUint8Array('99 e3 26 e5 40 0a 90 93 6c ef b4 e8 eb a0 8c'.replace(/\s+/g, '')), + dataIV: util.hexToUint8Array('5e d2 bc 1e 47 0a be 8f 1d 64 4c 7a 6c 8a 56'.replace(/\s+/g, '')), + packetBytes: util.hexToUint8Array(` + c3 3d 05 07 02 03 08 9f 0b 7d a3 e5 ea 64 77 90 + 99 e3 26 e5 40 0a 90 93 6c ef b4 e8 eb a0 8c 67 + 73 71 6d 1f 27 14 54 0a 38 fc ac 52 99 49 da c5 + 29 d3 de 31 e1 5b 4a eb 72 9e 33 00 33 db ed + + d4 49 01 07 02 0e 5e d2 bc 1e 47 0a be 8f 1d 64 + 4c 7a 6c 8a 56 7b 0f 77 01 19 66 11 a1 54 ba 9c + 25 74 cd 05 62 84 a8 ef 68 03 5c 62 3d 93 cc 70 + 8a 43 21 1b b6 ea f2 b2 7f 7c 18 d5 71 bc d8 3b + 20 ad d3 a0 8b 73 af 15 b9 a0 98 + `.replace(/\s+/g, '')) + }]; - const aeadProtectVal = openpgp.config.aeadProtect; - const aeadChunkSizeByteVal = openpgp.config.aeadChunkSizeByte; - const s2kIterationCountByteVal = openpgp.config.s2kIterationCountByte; - openpgp.config.aeadProtect = true; - openpgp.config.aeadChunkSizeByte = 14; - openpgp.config.s2kIterationCountByte = 0x90; + testVectors.forEach(testVector => it(testVector.algoLabel, async function () { + const { aeadAlgo, salt, sessionKey, sessionIV, dataIV, packetBytes: expectedEncryptedPacketBytes } = testVector; - const salt = util.hexToUint8Array('cd5a9f70fbe0bc65'); - const sessionKey = util.hexToUint8Array('86 f1 ef b8 69 52 32 9f 24 ac d3 bf d0 e5 34 6d'.replace(/\s+/g, '')); - const sessionIV = util.hexToUint8Array('bc 66 9e 34 e5 00 dc ae dc 5b 32 aa 2d ab 02 35'.replace(/\s+/g, '')); - const dataIV = util.hexToUint8Array('b7 32 37 9f 73 c4 92 8d e2 5f ac fe 65 17 ec 10'.replace(/\s+/g, '')); + try { + const passphrase = 'password'; + const algo = openpgp.enums.symmetric.aes128; - const randomBytesStub = sinon.stub(nodeCrypto, 'randomBytes'); - randomBytesStub.onCall(0).returns(salt); - randomBytesStub.onCall(1).returns(sessionKey); - randomBytesStub.onCall(2).returns(sessionIV); - randomBytesStub.onCall(3).returns(dataIV); + const randomBytesStub = sinon.stub(); + randomBytesStub.onCall(0).returns(salt); + randomBytesStub.onCall(1).returns(sessionKey); + randomBytesStub.onCall(2).returns(sessionIV); + randomBytesStub.onCall(3).returns(dataIV); + // no more random calls expected, so we throw as a reminder to update behavior if needed in the future + randomBytesStub.onCall(4).throws('random mock behavior not defined'); + mockCryptoRandomGenerator(randomBytesStub); - const packetBytes = util.hexToUint8Array(` - c3 3e 05 07 01 03 08 cd 5a 9f 70 fb e0 bc 65 90 - bc 66 9e 34 e5 00 dc ae dc 5b 32 aa 2d ab 02 35 - 9d ee 19 d0 7c 34 46 c4 31 2a 34 ae 19 67 a2 fb - 7e 92 8e a5 b4 fa 80 12 bd 45 6d 17 38 c6 3c 36 + const literal = new openpgp.LiteralDataPacket(0); + literal.setBytes(util.stringToUint8Array('Hello, world!\n'), openpgp.enums.literal.binary); + literal.filename = ''; + const skesk = new openpgp.SymEncryptedSessionKeyPacket(); + skesk.version = 5; + skesk.sessionKeyAlgorithm = algo; + const encData = new openpgp.AEADEncryptedDataPacket(); + encData.packets = new openpgp.PacketList(); + encData.packets.push(literal); + encData.aeadAlgorithm = skesk.aeadAlgorithm = aeadAlgo; + const msg = new openpgp.PacketList(); + msg.push(skesk); + msg.push(encData); - d4 4a 01 07 01 0e b7 32 37 9f 73 c4 92 8d e2 5f - ac fe 65 17 ec 10 5d c1 1a 81 dc 0c b8 a2 f6 f3 - d9 00 16 38 4a 56 fc 82 1a e1 1a e8 db cb 49 86 - 26 55 de a8 8d 06 a8 14 86 80 1b 0f f3 87 bd 2e - ab 01 3d e1 25 95 86 90 6e ab 24 76 - `.replace(/\s+/g, '')); + await skesk.encrypt(passphrase, { ...openpgp.config, s2kIterationCountByte: 0x90 }); - try { - const passphrase = 'password'; - const algo = openpgp.enums.symmetric.aes128; + const key = skesk.sessionKey; + await encData.encrypt(algo, key, { ...openpgp.config, aeadChunkSizeByte: 14 }); - const literal = new openpgp.LiteralDataPacket(0); - literal.setBytes(util.stringToUint8Array('Hello, world!\n'), openpgp.enums.literal.binary); - literal.filename = ''; - const skesk = new openpgp.SymEncryptedSessionKeyPacket(); - skesk.version = 5; - skesk.sessionKeyAlgorithm = algo; - const encData = new openpgp.AEADEncryptedDataPacket(); - encData.packets = new openpgp.PacketList(); - encData.packets.push(literal); - encData.aeadAlgorithm = skesk.aeadAlgorithm = openpgp.enums.aead.eax; - const msg = new openpgp.PacketList(); - msg.push(skesk); - msg.push(encData); + const data = msg.write(); + expect(await stream.readToEnd(stream.clone(data))).to.deep.equal(expectedEncryptedPacketBytes); - await skesk.encrypt(passphrase, openpgp.config); + const msg2 = new openpgp.PacketList(); + await msg2.read(data, allAllowedPackets); - const key = skesk.sessionKey; - await encData.encrypt(algo, key, undefined, openpgp.config); + await msg2[0].decrypt(passphrase); + const key2 = msg2[0].sessionKey; + await msg2[1].decrypt(msg2[0].sessionKeyAlgorithm, key2); - const data = msg.write(); - expect(await stream.readToEnd(stream.clone(data))).to.deep.equal(packetBytes); - - const msg2 = new openpgp.PacketList(); - await msg2.read(data, allAllowedPackets); - - await msg2[0].decrypt(passphrase); - const key2 = msg2[0].sessionKey; - await msg2[1].decrypt(msg2[0].sessionKeyAlgorithm, key2); - - expect(await stringify(msg2[1].packets[0].data)).to.equal(stringify(literal.data)); - } finally { - openpgp.config.aeadProtect = aeadProtectVal; - openpgp.config.aeadChunkSizeByte = aeadChunkSizeByteVal; - openpgp.config.s2kIterationCountByte = s2kIterationCountByteVal; - randomBytesStub.restore(); - } - }); - - it('Sym. encrypted session key reading/writing test vector (AEAD, OCB)', async function() { - // From https://gitlab.com/openpgp-wg/rfc4880bis/blob/00b20923/back.mkd#sample-aead-ocb-encryption-and-decryption - - const nodeCrypto = util.getNodeCrypto(); - if (!nodeCrypto) return; - - const aeadProtectVal = openpgp.config.aeadProtect; - const aeadChunkSizeByteVal = openpgp.config.aeadChunkSizeByte; - const s2kIterationCountByteVal = openpgp.config.s2kIterationCountByte; - openpgp.config.aeadProtect = true; - openpgp.config.aeadChunkSizeByte = 14; - openpgp.config.s2kIterationCountByte = 0x90; - - const salt = util.hexToUint8Array('9f0b7da3e5ea6477'); - const sessionKey = util.hexToUint8Array('d1 f0 1b a3 0e 13 0a a7 d2 58 2c 16 e0 50 ae 44'.replace(/\s+/g, '')); - const sessionIV = util.hexToUint8Array('99 e3 26 e5 40 0a 90 93 6c ef b4 e8 eb a0 8c'.replace(/\s+/g, '')); - const dataIV = util.hexToUint8Array('5e d2 bc 1e 47 0a be 8f 1d 64 4c 7a 6c 8a 56'.replace(/\s+/g, '')); - - const randomBytesStub = sinon.stub(nodeCrypto, 'randomBytes'); - randomBytesStub.onCall(0).returns(salt); - randomBytesStub.onCall(1).returns(sessionKey); - randomBytesStub.onCall(2).returns(sessionIV); - randomBytesStub.onCall(3).returns(dataIV); - - const packetBytes = util.hexToUint8Array(` - c3 3d 05 07 02 03 08 9f 0b 7d a3 e5 ea 64 77 90 - 99 e3 26 e5 40 0a 90 93 6c ef b4 e8 eb a0 8c 67 - 73 71 6d 1f 27 14 54 0a 38 fc ac 52 99 49 da c5 - 29 d3 de 31 e1 5b 4a eb 72 9e 33 00 33 db ed - - d4 49 01 07 02 0e 5e d2 bc 1e 47 0a be 8f 1d 64 - 4c 7a 6c 8a 56 7b 0f 77 01 19 66 11 a1 54 ba 9c - 25 74 cd 05 62 84 a8 ef 68 03 5c 62 3d 93 cc 70 - 8a 43 21 1b b6 ea f2 b2 7f 7c 18 d5 71 bc d8 3b - 20 ad d3 a0 8b 73 af 15 b9 a0 98 - `.replace(/\s+/g, '')); - - try { - const passphrase = 'password'; - const algo = openpgp.enums.symmetric.aes128; - - const literal = new openpgp.LiteralDataPacket(0); - literal.setBytes(util.stringToUint8Array('Hello, world!\n'), openpgp.enums.literal.binary); - literal.filename = ''; - const skesk = new openpgp.SymEncryptedSessionKeyPacket(); - skesk.version = 5; - skesk.sessionKeyAlgorithm = algo; - const enc = new openpgp.AEADEncryptedDataPacket(); - enc.packets = new openpgp.PacketList(); - enc.packets.push(literal); - enc.aeadAlgorithm = skesk.aeadAlgorithm = openpgp.enums.aead.ocb; - const msg = new openpgp.PacketList(); - msg.push(skesk); - msg.push(enc); - - await skesk.encrypt(passphrase, openpgp.config); - - const key = skesk.sessionKey; - await enc.encrypt(algo, key, undefined, openpgp.config); - - const data = msg.write(); - expect(await stream.readToEnd(stream.clone(data))).to.deep.equal(packetBytes); - - const msg2 = new openpgp.PacketList(); - await msg2.read(data, allAllowedPackets); - - await msg2[0].decrypt(passphrase); - const key2 = msg2[0].sessionKey; - await msg2[1].decrypt(msg2[0].sessionKeyAlgorithm, key2); - - expect(await stringify(msg2[1].packets[0].data)).to.equal(stringify(literal.data)); - } finally { - openpgp.config.aeadProtect = aeadProtectVal; - openpgp.config.aeadChunkSizeByte = aeadChunkSizeByteVal; - openpgp.config.s2kIterationCountByte = s2kIterationCountByteVal; - randomBytesStub.restore(); - } + expect(await stringify(msg2[1].packets[0].data)).to.equal(stringify(literal.data)); + } finally { + restoreCryptoRandomGenerator(); + } + })); }); describe('Sym. encrypted session key reading/writing test vector (SKESK v6)', async function () { const testVectors = [{ - // from https://datatracker.ietf.org/doc/html/rfc9580#appendix-A.9.1 - algoLabel: 'EAX', - aeadAlgo: openpgp.enums.aead.eax, - s2kSalt: util.hexToUint8Array('a5 ae 57 9d 1f c5 d8 2b'.replace(/\s+/g, '')), - sessionKey: util.hexToUint8Array('38 81 ba fe 98 54 12 45 9b 86 c3 6f 98 cb 9a 5e'.replace(/\s+/g, '')), - sessionIV: util.hexToUint8Array('69 22 4f 91 99 93 b3 50 6f a3 b5 9a 6a 73 cf f8'.replace(/\s+/g, '')), - encryptedPacketBytes: util.hexToUint8Array(` - c3 40 06 1e 07 01 0b 03 - 08 a5 ae 57 9d 1f c5 d8 - 2b ff 69 22 4f 91 99 93 - b3 50 6f a3 b5 9a 6a 73 - cf f8 c5 ef c5 f4 1c 57 - fb 54 e1 c2 26 81 5d 78 - 28 f5 f9 2c 45 4e b6 5e - be 00 ab 59 86 c6 8e 6e - 7c 55`.replace(/\s+/g, '')) - }, - { - algoLabel: 'OCB', - aeadAlgo: openpgp.enums.aead.ocb, - padding: util.hexToUint8Array('ae 6a a1 64 9b 56 aa 83 5b 26 13 90 2b d2'.replace(/\s+/g, '')), - s2kSalt: util.hexToUint8Array('56 a2 98 d2 f5 e3 64 53'.replace(/\s+/g, '')), - sessionKey: util.hexToUint8Array('28 e7 9a b8 23 97 d3 c6 3d e2 4a c2 17 d7 b7 91'.replace(/\s+/g, '')), - sessionIV: util.hexToUint8Array('cf cc 5c 11 66 4e db 9d b4 25 90 d7 dc 46 b0'.replace(/\s+/g, '')), - encryptedPacketBytes: util.hexToUint8Array(` - c3 3f 06 1d 07 02 0b 03 - 08 56 a2 98 d2 f5 e3 64 - 53 ff cf cc 5c 11 66 4e - db 9d b4 25 90 d7 dc 46 - b0 72 41 b6 12 c3 81 2c - ff fb ea 00 f2 34 7b 25 - 64 11 23 f8 87 ae 60 d4 - fd 61 4e 08 37 d8 19 d3 - 6c`.replace(/\s+/g, '')) - }, - { - algoLabel: 'GCM', - aeadAlgo: openpgp.enums.aead.gcm, - s2kSalt: util.hexToUint8Array('e9 d3 97 85 b2 07 00 08'.replace(/\s+/g, '')), - sessionKey: util.hexToUint8Array('19 36 fc 85 68 98 02 74 bb 90 0d 83 19 36 0c 77'.replace(/\s+/g, '')), - sessionIV: util.hexToUint8Array('b4 2e 7c 48 3e f4 88 44 57 cb 37 26'.replace(/\s+/g, '')), - encryptedPacketBytes: util.hexToUint8Array(` - c3 3c 06 1a 07 03 0b 03 - 08 e9 d3 97 85 b2 07 00 - 08 ff b4 2e 7c 48 3e f4 - 88 44 57 cb 37 26 b9 b3 - db 9f f7 76 e5 f4 d9 a4 - 09 52 e2 44 72 98 85 1a - bf ff 75 26 df 2d d5 54 - 41 75 79 a7 79 9f`.replace(/\s+/g, '')) + // from https://datatracker.ietf.org/doc/html/rfc9580#appendix-A.9.1 + algoLabel: 'EAX', + aeadAlgo: openpgp.enums.aead.eax, + s2kSalt: util.hexToUint8Array('a5 ae 57 9d 1f c5 d8 2b'.replace(/\s+/g, '')), + sessionKey: util.hexToUint8Array('38 81 ba fe 98 54 12 45 9b 86 c3 6f 98 cb 9a 5e'.replace(/\s+/g, '')), + sessionIV: util.hexToUint8Array('69 22 4f 91 99 93 b3 50 6f a3 b5 9a 6a 73 cf f8'.replace(/\s+/g, '')), + encryptedPacketBytes: util.hexToUint8Array(` + c3 40 06 1e 07 01 0b 03 + 08 a5 ae 57 9d 1f c5 d8 + 2b ff 69 22 4f 91 99 93 + b3 50 6f a3 b5 9a 6a 73 + cf f8 c5 ef c5 f4 1c 57 + fb 54 e1 c2 26 81 5d 78 + 28 f5 f9 2c 45 4e b6 5e + be 00 ab 59 86 c6 8e 6e + 7c 55`.replace(/\s+/g, '')) + }, + { + algoLabel: 'OCB', + aeadAlgo: openpgp.enums.aead.ocb, + padding: util.hexToUint8Array('ae 6a a1 64 9b 56 aa 83 5b 26 13 90 2b d2'.replace(/\s+/g, '')), + s2kSalt: util.hexToUint8Array('56 a2 98 d2 f5 e3 64 53'.replace(/\s+/g, '')), + sessionKey: util.hexToUint8Array('28 e7 9a b8 23 97 d3 c6 3d e2 4a c2 17 d7 b7 91'.replace(/\s+/g, '')), + sessionIV: util.hexToUint8Array('cf cc 5c 11 66 4e db 9d b4 25 90 d7 dc 46 b0'.replace(/\s+/g, '')), + encryptedPacketBytes: util.hexToUint8Array(` + c3 3f 06 1d 07 02 0b 03 + 08 56 a2 98 d2 f5 e3 64 + 53 ff cf cc 5c 11 66 4e + db 9d b4 25 90 d7 dc 46 + b0 72 41 b6 12 c3 81 2c + ff fb ea 00 f2 34 7b 25 + 64 11 23 f8 87 ae 60 d4 + fd 61 4e 08 37 d8 19 d3 + 6c`.replace(/\s+/g, '')) + }, + { + algoLabel: 'GCM', + aeadAlgo: openpgp.enums.aead.gcm, + s2kSalt: util.hexToUint8Array('e9 d3 97 85 b2 07 00 08'.replace(/\s+/g, '')), + sessionKey: util.hexToUint8Array('19 36 fc 85 68 98 02 74 bb 90 0d 83 19 36 0c 77'.replace(/\s+/g, '')), + sessionIV: util.hexToUint8Array('b4 2e 7c 48 3e f4 88 44 57 cb 37 26'.replace(/\s+/g, '')), + encryptedPacketBytes: util.hexToUint8Array(` + c3 3c 06 1a 07 03 0b 03 + 08 e9 d3 97 85 b2 07 00 + 08 ff b4 2e 7c 48 3e f4 + 88 44 57 cb 37 26 b9 b3 + db 9f f7 76 e5 f4 d9 a4 + 09 52 e2 44 72 98 85 1a + bf ff 75 26 df 2d d5 54 + 41 75 79 a7 79 9f`.replace(/\s+/g, '')) }]; testVectors.forEach(testVector => it(testVector.algoLabel, async function () { - const nodeCrypto = util.getNodeCrypto(); - const { aeadAlgo: expectedAEADAlgo, s2kSalt, sessionKey, sessionIV, encryptedPacketBytes: expectedEncryptedPacketBytes } = testVector; - const randomBytesStub = sinon.stub(nodeCrypto, 'randomBytes'); - randomBytesStub.onCall(0).returns(s2kSalt); - randomBytesStub.onCall(1).returns(sessionKey); - randomBytesStub.onCall(2).returns(sessionIV); + + const passphrase = 'password'; + const symmetricAlgo = openpgp.enums.symmetric.aes128; try { - const passphrase = 'password'; - const symmetricAlgo = openpgp.enums.symmetric.aes128; - + const randomBytesStub = sinon.stub(); + randomBytesStub.onCall(0).returns(s2kSalt); + randomBytesStub.onCall(1).returns(sessionKey); + randomBytesStub.onCall(2).returns(sessionIV); + // no more random calls expected, so we throw as a reminder to update behavior if needed in the future + randomBytesStub.onCall(3).throws('random mock behavior not defined'); + mockCryptoRandomGenerator(randomBytesStub); + const skesk = new openpgp.SymEncryptedSessionKeyPacket(); skesk.version = 6; skesk.sessionKeyAlgorithm = symmetricAlgo; skesk.aeadAlgorithm = expectedAEADAlgo; const msg = new openpgp.PacketList(); msg.push(skesk); - + await skesk.encrypt(passphrase, { ...openpgp.config, aeadChunkSizeByte: 6, s2kIterationCountByte: 255 }); - + const serialized = msg.write(); expect(await stream.readToEnd(stream.clone(serialized))).to.deep.equal(expectedEncryptedPacketBytes); - + const msg2 = new openpgp.PacketList(); await msg2.read(serialized, allAllowedPackets); - + await msg2[0].decrypt(passphrase); const decryptedSessionKey = msg2[0].sessionKey; const decryptedSessionKeyAlgo = msg2[0].sessionKeyAlgorithm; expect(decryptedSessionKey).to.deep.equal(sessionKey); expect(decryptedSessionKeyAlgo).to.be.null; } finally { - randomBytesStub.restore(); + restoreCryptoRandomGenerator(); } })); - }) + }); it('Secret key encryption/decryption test', async function() { const armored_msg = diff --git a/test/mockRandom.ts b/test/mockRandom.ts new file mode 100644 index 00000000..47f7b509 --- /dev/null +++ b/test/mockRandom.ts @@ -0,0 +1,29 @@ +import type { SinonStub } from 'sinon'; +import util from '../src/util'; + +const webcrypto = typeof crypto !== 'undefined' ? crypto : util.nodeRequire('crypto')?.webcrypto; + +type GetRandomValuesFn = typeof crypto.getRandomValues; +let original: GetRandomValuesFn | null = null; + +/** + * Mock `crypto.getRandomValues` using the mocked implementation + */ +export const mockCryptoRandomGenerator = ( + mockedImplementation: GetRandomValuesFn | SinonStub) => { + if (original !== null) { + throw new Error('random mock already initialized'); + } + + original = webcrypto.getRandomValues; + webcrypto.getRandomValues = mockedImplementation; +}; + +export const restoreCryptoRandomGenerator = () => { + if (!original) { + throw new Error('random mock was not initialized'); + } + + webcrypto.getRandomValues = original; + original = null; +}; From 4b017f6c67bb27f6831040e430bebe456c94a121 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Wed, 18 Sep 2024 12:17:11 +0200 Subject: [PATCH 189/201] Tests: drop karma (deprecated) in favor of web-test-runner --- .github/workflows/tests.yml | 8 +- package-lock.json | 5671 ++++++++++++++++++++++++++------ package.json | 19 +- test/karma.conf.cjs | 136 - test/unittests.html | 47 +- test/web-test-runner.config.js | 52 + 6 files changed, 4742 insertions(+), 1191 deletions(-) delete mode 100644 test/karma.conf.cjs create mode 100644 test/web-test-runner.config.js diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8b9ce5fe..b61a727d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -100,12 +100,12 @@ jobs: run: npx playwright install --with-deps webkit - name: Run browser tests - run: npm run test-browser + run: npm run test-browser -- --static-logging - name: Run browser tests (lightweight) # overwrite test/lib run: | npm run build-test --lightweight - npm run test-browser + npm run test-browser -- --static-logging test-browsers-compatibility: name: Browsers (older, on Browserstack) @@ -139,12 +139,12 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Run browserstack tests - run: npm run test-browserstack + run: npm run test-browserstack -- --static-logging - name: Run browserstack tests (lightweight) # overwrite test/lib run: | npm run build-test --lightweight - npm run test-browserstack + npm run test-browserstack -- --static-logging env: LIGHTWEIGHT: true diff --git a/package-lock.json b/package-lock.json index 63873e27..74383bd7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,6 +26,10 @@ "@types/chai": "^4.3.19", "@types/sinon": "^17.0.3", "@typescript-eslint/parser": "^7.18.0", + "@web/test-runner": "^0.19.0", + "@web/test-runner-browserstack": "^0.7.2", + "@web/test-runner-mocha": "^0.9.0", + "@web/test-runner-playwright": "^0.11.0", "argon2id": "^1.0.1", "benchmark": "^2.1.4", "bn.js": "^5.2.1", @@ -42,14 +46,6 @@ "eslint-plugin-import": "^2.30.0", "eslint-plugin-unicorn": "^48.0.1", "fflate": "^0.7.4", - "http-server": "^14.1.1", - "karma": "^6.4.4", - "karma-browserstack-launcher": "^1.6.0", - "karma-chrome-launcher": "^3.2.0", - "karma-firefox-launcher": "^2.1.3", - "karma-mocha": "^2.0.1", - "karma-mocha-reporter": "^2.2.5", - "karma-webkit-launcher": "^2.6.0", "mocha": "^10.7.3", "playwright": "^1.47.0", "rollup": "^4.21.2", @@ -216,15 +212,6 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "node_modules/@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "dev": true, - "engines": { - "node": ">=0.1.90" - } - }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -709,6 +696,13 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@hapi/bourne": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-3.0.0.tgz", + "integrity": "sha512-Waj1cwPXJDucOib4a3bAISsKJVb15MKi9IvmTI/7ssVEm6sywXGjVJDhl6/umt1pK1ZS7PacXU3A1PmFKHEZ2w==", + "dev": true, + "license": "BSD-3-Clause" + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.14", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", @@ -766,6 +760,102 @@ "deprecated": "Use @eslint/object-schema instead", "dev": true }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", @@ -978,6 +1068,60 @@ } } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@promptbook/utils": { + "version": "0.70.0-1", + "resolved": "https://registry.npmjs.org/@promptbook/utils/-/utils-0.70.0-1.tgz", + "integrity": "sha512-qd2lLRRN+sE6UuNMi2tEeUUeb4zmXnxY5EMdfHVXNE+bqBDpUC7/aEfXgA3jnUXEr+xFjQ8PTFQgWvBMaKvw0g==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://buymeacoffee.com/hejny" + }, + { + "type": "github", + "url": "https://github.com/webgptorg/promptbook/blob/main/README.md#%EF%B8%8F-contributing" + } + ], + "license": "CC-BY-4.0", + "dependencies": { + "spacetrim": "0.11.39" + } + }, + "node_modules/@puppeteer/browsers": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.4.0.tgz", + "integrity": "sha512-x8J1csfIygOwf6D6qUAZ0ASk3z63zPb7wkNeHRerCMh82qWKUrOgkuP005AJC8lDL6/evtXETGEJVcwykKT4/g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "debug": "^4.3.6", + "extract-zip": "^2.0.1", + "progress": "^2.0.3", + "proxy-agent": "^6.4.0", + "semver": "^7.6.3", + "tar-fs": "^3.0.6", + "unbzip2-stream": "^1.4.3", + "yargs": "^17.7.2" + }, + "bin": { + "browsers": "lib/cjs/main-cli.js" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@rollup/plugin-alias": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.1.0.tgz", @@ -1373,6 +1517,19 @@ "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", "dev": true }, + "node_modules/@sindresorhus/is": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", + "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, "node_modules/@sinonjs/commons": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", @@ -1420,11 +1577,25 @@ "dev": true, "license": "(Unlicense OR Apache-2.0)" }, - "node_modules/@socket.io/component-emitter": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", - "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", - "dev": true + "node_modules/@szmarczak/http-timer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "dev": true, + "license": "MIT", + "dependencies": { + "defer-to-connect": "^2.0.1" + }, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", + "dev": true, + "license": "MIT" }, "node_modules/@tsconfig/node10": { "version": "1.0.11", @@ -1450,45 +1621,221 @@ "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", "dev": true }, + "node_modules/@types/accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Pay9fq2lM2wXPWbteBsRAGiWH2hig4ZE2asK+mm7kUzlxRTfL961rj89I6zV/E3PcIkDqyuBEcMxFT7rccugeQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/babel__code-frame": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@types/babel__code-frame/-/babel__code-frame-7.0.6.tgz", + "integrity": "sha512-Anitqkl3+KrzcW2k77lRlg/GfLZLWXBuNgbEcIOU6M92yw42vsd3xV/Z/yAHEj8m+KUjL6bWOVOFqX8PFPJ4LA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, "node_modules/@types/chai": { "version": "4.3.19", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.19.tgz", "integrity": "sha512-2hHHvQBVE2FiSK4eN0Br6snX9MtolHaTo/batnLjlGRhoQzlCL61iVpxoqO7SfFyOw+P/pwv+0zNHzKoGWz9Cw==", "dev": true }, - "node_modules/@types/cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", - "dev": true - }, - "node_modules/@types/cors": { - "version": "2.8.17", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", - "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", + "node_modules/@types/co-body": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@types/co-body/-/co-body-6.1.3.tgz", + "integrity": "sha512-UhuhrQ5hclX6UJctv5m4Rfp52AfG9o9+d9/HwjxhVB5NjXxr5t9oKgJxN8xRHgr35oo8meUEHUPFWiKg6y71aA==", "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*" + } + }, + "node_modules/@types/command-line-args": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/command-line-args/-/command-line-args-5.2.3.tgz", + "integrity": "sha512-uv0aG6R0Y8WHZLTamZwtfsDLVRnOa+n+n5rEvFWL5Na5gZ8V2Teab/duDPFzIIIhs9qizDpcavCusCLJZu62Kw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } }, + "node_modules/@types/content-disposition": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.8.tgz", + "integrity": "sha512-QVSSvno3dE0MgO76pJhmv4Qyi/j0Yk9pBp0Y7TJ2Tlj+KCgJWY6qX7nnxCOLkZ3VYRSIk1WTxCvwUSdx6CCLdg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/convert-source-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/convert-source-map/-/convert-source-map-2.0.3.tgz", + "integrity": "sha512-ag0BfJLZf6CQz8VIuRIEYQ5Ggwk/82uvTQf27RcpyDNbY0Vw49LIPqAxk5tqYfrCs9xDaIMvl4aj7ZopnYL8bA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/cookies": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.9.0.tgz", + "integrity": "sha512-40Zk8qR147RABiQ7NQnBzWzDcjKzNrntB5BAmeGCb2p/MIyOE+4BVvc17wumsUqUw00bJYqoXFHYygQnEFh4/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/express": "*", + "@types/keygrip": "*", + "@types/node": "*" + } + }, + "node_modules/@types/debounce": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/debounce/-/debounce-1.2.4.tgz", + "integrity": "sha512-jBqiORIzKDOToaF63Fm//haOCHuwQuLa2202RK4MozpA6lh93eCBc+/8+wZn5OzjJt3ySdc+74SXWXB55Ewtyw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.5", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz", + "integrity": "sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-assert": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.5.tgz", + "integrity": "sha512-4+tE/lwdAahgZT1g30Jkdm9PzFRde0xwxBNUyRsCitRvCQB90iuA2uJYdUnhnANRcqGXaWOGY4FEoxeElNAK2g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", "dev": true }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, + "node_modules/@types/keygrip": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.6.tgz", + "integrity": "sha512-lZuNAY9xeJt7Bx4t4dx0rYCDqGPW8RXhQZK1td7d4H6E9zYbLoOtjBvfwdTKpsyxQI/2jv+armjX/RW+ZNpXOQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/koa": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.15.0.tgz", + "integrity": "sha512-7QFsywoE5URbuVnG3loe03QXuGajrnotr3gQkXcEBShORai23MePfFYdhz90FEtBBpkyIYQbVD+evKtloCgX3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/accepts": "*", + "@types/content-disposition": "*", + "@types/cookies": "*", + "@types/http-assert": "*", + "@types/http-errors": "*", + "@types/keygrip": "*", + "@types/koa-compose": "*", + "@types/node": "*" + } + }, + "node_modules/@types/koa-compose": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@types/koa-compose/-/koa-compose-3.2.8.tgz", + "integrity": "sha512-4Olc63RY+MKvxMwVknCUDhRQX1pFQoBZ/lXcRLP69PQkEpze/0cr8LNqJQe5NFb/b19DWi2a5bTi2VAlQzhJuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/koa": "*" + } + }, "node_modules/@types/linkify-it": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", @@ -1511,6 +1858,13 @@ "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", "dev": true }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/node": { "version": "22.5.3", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.3.tgz", @@ -1526,12 +1880,56 @@ "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", "dev": true }, + "node_modules/@types/parse5": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.3.tgz", + "integrity": "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/qs": { + "version": "6.9.16", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.16.tgz", + "integrity": "sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/resolve": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", "dev": true }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, "node_modules/@types/sinon": { "version": "17.0.3", "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.3.tgz", @@ -1549,6 +1947,34 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/which/-/which-2.0.2.tgz", + "integrity": "sha512-113D3mDkZDjo+EeUEHCFy0qniNc1ZpecGiAU7WSo7YDoSzolZIQKpYFHrPpjkB2nuyahcKfrmLXeQlh7gqJYdw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/ws": { + "version": "7.4.7", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", + "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "7.18.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz", @@ -1743,6 +2169,698 @@ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", "dev": true }, + "node_modules/@wdio/config": { + "version": "8.40.3", + "resolved": "https://registry.npmjs.org/@wdio/config/-/config-8.40.3.tgz", + "integrity": "sha512-HIi+JnHEDAExhzGRQuZOXw1HWIpe/bsVFHwNISJhY6wS4Nijaigmegs2p14Rv16ydOF19hGrxdKsl8k5STIP2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@wdio/logger": "8.38.0", + "@wdio/types": "8.40.3", + "@wdio/utils": "8.40.3", + "decamelize": "^6.0.0", + "deepmerge-ts": "^5.0.0", + "glob": "^10.2.2", + "import-meta-resolve": "^4.0.0" + }, + "engines": { + "node": "^16.13 || >=18" + } + }, + "node_modules/@wdio/config/node_modules/decamelize": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.0.tgz", + "integrity": "sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@wdio/config/node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@wdio/config/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@wdio/config/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@wdio/logger": { + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-8.38.0.tgz", + "integrity": "sha512-kcHL86RmNbcQP+Gq/vQUGlArfU6IIcbbnNp32rRIraitomZow+iEoc519rdQmSVusDozMS5DZthkgDdxK+vz6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^5.1.2", + "loglevel": "^1.6.0", + "loglevel-plugin-prefix": "^0.8.4", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": "^16.13 || >=18" + } + }, + "node_modules/@wdio/logger/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@wdio/logger/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@wdio/logger/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@wdio/protocols": { + "version": "8.40.3", + "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-8.40.3.tgz", + "integrity": "sha512-wK7+eyrB3TAei8RwbdkcyoNk2dPu+mduMBOdPJjp8jf/mavd15nIUXLID1zA+w5m1Qt1DsT1NbvaeO9+aJQ33A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@wdio/repl": { + "version": "8.40.3", + "resolved": "https://registry.npmjs.org/@wdio/repl/-/repl-8.40.3.tgz", + "integrity": "sha512-mWEiBbaC7CgxvSd2/ozpbZWebnRIc8KRu/J81Hlw/txUWio27S7IpXBlZGVvhEsNzq0+cuxB/8gDkkXvMPbesw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^22.2.0" + }, + "engines": { + "node": "^16.13 || >=18" + } + }, + "node_modules/@wdio/types": { + "version": "8.40.3", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.40.3.tgz", + "integrity": "sha512-zK17uyON3Ise3m+XwiF5VrrdZcXXmvqB8AWXoKe88DiksFUPMVoCOuVL2SSX1KnA2YLlZBA55qcFZT99GORVKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^22.2.0" + }, + "engines": { + "node": "^16.13 || >=18" + } + }, + "node_modules/@wdio/utils": { + "version": "8.40.3", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.40.3.tgz", + "integrity": "sha512-pv/848KGfPN3YXU4QRfTYGkAu4/lejIfoGzGpvGNDcACiVxgZhyRZkJ2xVaSnGaXzF0R7pMozrkU5/DnEhcxMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@puppeteer/browsers": "^1.6.0", + "@wdio/logger": "8.38.0", + "@wdio/types": "8.40.3", + "decamelize": "^6.0.0", + "deepmerge-ts": "^5.1.0", + "edgedriver": "^5.5.0", + "geckodriver": "^4.3.1", + "get-port": "^7.0.0", + "import-meta-resolve": "^4.0.0", + "locate-app": "^2.1.0", + "safaridriver": "^0.1.0", + "split2": "^4.2.0", + "wait-port": "^1.0.4" + }, + "engines": { + "node": "^16.13 || >=18" + } + }, + "node_modules/@wdio/utils/node_modules/@puppeteer/browsers": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.9.1.tgz", + "integrity": "sha512-PuvK6xZzGhKPvlx3fpfdM2kYY3P/hB1URtK8wA7XUJ6prn6pp22zvJHu48th0SGcHL9SutbPHrFuQgfXTFobWA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "debug": "4.3.4", + "extract-zip": "2.0.1", + "progress": "2.0.3", + "proxy-agent": "6.3.1", + "tar-fs": "3.0.4", + "unbzip2-stream": "1.4.3", + "yargs": "17.7.2" + }, + "bin": { + "browsers": "lib/cjs/main-cli.js" + }, + "engines": { + "node": ">=16.3.0" + } + }, + "node_modules/@wdio/utils/node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@wdio/utils/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@wdio/utils/node_modules/decamelize": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.0.tgz", + "integrity": "sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@wdio/utils/node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@wdio/utils/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/@wdio/utils/node_modules/proxy-agent": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.1.tgz", + "integrity": "sha512-Rb5RVBy1iyqOtNl15Cw/llpeLH8bsb37gM1FUfKQ+Wck6xHlbAhWGUFiTRHtkjqGTA5pSHz6+0hrPW/oECihPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.2", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.0.1", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@wdio/utils/node_modules/tar-fs": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", + "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + } + }, + "node_modules/@web/browser-logs": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@web/browser-logs/-/browser-logs-0.4.0.tgz", + "integrity": "sha512-/EBiDAUCJ2DzZhaFxTPRIznEPeafdLbXShIL6aTu7x73x7ZoxSDv7DGuTsh2rWNMUa4+AKli4UORrpyv6QBOiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "errorstacks": "^2.2.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web/config-loader": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@web/config-loader/-/config-loader-0.3.2.tgz", + "integrity": "sha512-Vrjv/FexBGmAdnCYpJKLHX1dfT1UaUdvHmX1JRaWos9OvDf/tFznYJ5SpJwww3Rl87/ewvLSYG7kfsMqEAsizQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web/dev-server": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/@web/dev-server/-/dev-server-0.4.6.tgz", + "integrity": "sha512-jj/1bcElAy5EZet8m2CcUdzxT+CRvUjIXGh8Lt7vxtthkN9PzY9wlhWx/9WOs5iwlnG1oj0VGo6f/zvbPO0s9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.11", + "@types/command-line-args": "^5.0.0", + "@web/config-loader": "^0.3.0", + "@web/dev-server-core": "^0.7.2", + "@web/dev-server-rollup": "^0.6.1", + "camelcase": "^6.2.0", + "command-line-args": "^5.1.1", + "command-line-usage": "^7.0.1", + "debounce": "^1.2.0", + "deepmerge": "^4.2.2", + "internal-ip": "^6.2.0", + "nanocolors": "^0.2.1", + "open": "^8.0.2", + "portfinder": "^1.0.32" + }, + "bin": { + "wds": "dist/bin.js", + "web-dev-server": "dist/bin.js" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web/dev-server-core": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@web/dev-server-core/-/dev-server-core-0.7.2.tgz", + "integrity": "sha512-Q/0jpF13Ipk+qGGQ+Yx/FW1TQBYazpkfgYHHo96HBE7qv4V4KKHqHglZcSUxti/zd4bToxX1cFTz8dmbTlb8JA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/koa": "^2.11.6", + "@types/ws": "^7.4.0", + "@web/parse5-utils": "^2.1.0", + "chokidar": "^3.4.3", + "clone": "^2.1.2", + "es-module-lexer": "^1.0.0", + "get-stream": "^6.0.0", + "is-stream": "^2.0.0", + "isbinaryfile": "^5.0.0", + "koa": "^2.13.0", + "koa-etag": "^4.0.0", + "koa-send": "^5.0.1", + "koa-static": "^5.0.0", + "lru-cache": "^8.0.4", + "mime-types": "^2.1.27", + "parse5": "^6.0.1", + "picomatch": "^2.2.2", + "ws": "^7.4.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web/dev-server-core/node_modules/isbinaryfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.2.tgz", + "integrity": "sha512-GvcjojwonMjWbTkfMpnVHVqXW/wKMYDfEpY94/8zy8HFMOqb/VL6oeONq9v87q4ttVlaTLnGXnJD4B5B1OTGIg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/@web/dev-server-core/node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/@web/dev-server-rollup": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@web/dev-server-rollup/-/dev-server-rollup-0.6.4.tgz", + "integrity": "sha512-sJZfTGCCrdku5xYnQQG51odGI092hKY9YFM0X3Z0tRY3iXKXcYRaLZrErw5KfCxr6g0JRuhe4BBhqXTA5Q2I3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/plugin-node-resolve": "^15.0.1", + "@web/dev-server-core": "^0.7.2", + "nanocolors": "^0.2.1", + "parse5": "^6.0.1", + "rollup": "^4.4.0", + "whatwg-url": "^14.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web/parse5-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@web/parse5-utils/-/parse5-utils-2.1.0.tgz", + "integrity": "sha512-GzfK5disEJ6wEjoPwx8AVNwUe9gYIiwc+x//QYxYDAFKUp4Xb1OJAGLc2l2gVrSQmtPGLKrTRcW90Hv4pEq1qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/parse5": "^6.0.1", + "parse5": "^6.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web/test-runner": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@web/test-runner/-/test-runner-0.19.0.tgz", + "integrity": "sha512-qLUupi88OK1Kl52cWPD/2JewUCRUxYsZ1V1DyLd05P7u09zCdrUYrtkB/cViWyxlBe/TOvqkSNpcTv6zLJ9GoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@web/browser-logs": "^0.4.0", + "@web/config-loader": "^0.3.0", + "@web/dev-server": "^0.4.0", + "@web/test-runner-chrome": "^0.17.0", + "@web/test-runner-commands": "^0.9.0", + "@web/test-runner-core": "^0.13.0", + "@web/test-runner-mocha": "^0.9.0", + "camelcase": "^6.2.0", + "command-line-args": "^5.1.1", + "command-line-usage": "^7.0.1", + "convert-source-map": "^2.0.0", + "diff": "^5.0.0", + "globby": "^11.0.1", + "nanocolors": "^0.2.1", + "portfinder": "^1.0.32", + "source-map": "^0.7.3" + }, + "bin": { + "web-test-runner": "dist/bin.js", + "wtr": "dist/bin.js" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web/test-runner-browserstack": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@web/test-runner-browserstack/-/test-runner-browserstack-0.7.2.tgz", + "integrity": "sha512-zFux8OLXsQPHHXZWGiU5m3dpESp19XXg21WgzxoazxC9iKE0stW1ZJ/DyypCQEi0c0m01izzwA+7isZVv4OIgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@web/test-runner-webdriver": "^0.8.0", + "browserstack-local": "^1.4.8", + "internal-ip": "^6.2.0", + "nanoid": "^3.1.25" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web/test-runner-chrome": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@web/test-runner-chrome/-/test-runner-chrome-0.17.0.tgz", + "integrity": "sha512-Il5N9z41NKWCrQM1TVgRaDWWYoJtG5Ha4fG+cN1MWL2OlzBS4WoOb4lFV3EylZ7+W3twZOFr1zy2Rx61yDYd/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@web/test-runner-core": "^0.13.0", + "@web/test-runner-coverage-v8": "^0.8.0", + "async-mutex": "0.4.0", + "chrome-launcher": "^0.15.0", + "puppeteer-core": "^23.2.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web/test-runner-commands": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@web/test-runner-commands/-/test-runner-commands-0.9.0.tgz", + "integrity": "sha512-zeLI6QdH0jzzJMDV5O42Pd8WLJtYqovgdt0JdytgHc0d1EpzXDsc7NTCJSImboc2NcayIsWAvvGGeRF69SMMYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@web/test-runner-core": "^0.13.0", + "mkdirp": "^1.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web/test-runner-core": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/@web/test-runner-core/-/test-runner-core-0.13.3.tgz", + "integrity": "sha512-ilDqF/v2sj0sD69FNSIDT7uw4M1yTVedLBt32/lXy3MMi6suCM7m/ZlhsBy8PXhf879WMvzBOl/vhJBpEMB9vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.11", + "@types/babel__code-frame": "^7.0.2", + "@types/co-body": "^6.1.0", + "@types/convert-source-map": "^2.0.0", + "@types/debounce": "^1.2.0", + "@types/istanbul-lib-coverage": "^2.0.3", + "@types/istanbul-reports": "^3.0.0", + "@web/browser-logs": "^0.4.0", + "@web/dev-server-core": "^0.7.2", + "chokidar": "^3.4.3", + "cli-cursor": "^3.1.0", + "co-body": "^6.1.0", + "convert-source-map": "^2.0.0", + "debounce": "^1.2.0", + "dependency-graph": "^0.11.0", + "globby": "^11.0.1", + "internal-ip": "^6.2.0", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.0.2", + "log-update": "^4.0.0", + "nanocolors": "^0.2.1", + "nanoid": "^3.1.25", + "open": "^8.0.2", + "picomatch": "^2.2.2", + "source-map": "^0.7.3" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web/test-runner-core/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@web/test-runner-coverage-v8": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@web/test-runner-coverage-v8/-/test-runner-coverage-v8-0.8.0.tgz", + "integrity": "sha512-PskiucYpjUtgNfR2zF2AWqWwjXL7H3WW/SnCAYmzUrtob7X9o/+BjdyZ4wKbOxWWSbJO4lEdGIDLu+8X2Xw+lA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@web/test-runner-core": "^0.13.0", + "istanbul-lib-coverage": "^3.0.0", + "lru-cache": "^8.0.4", + "picomatch": "^2.2.2", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web/test-runner-mocha": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@web/test-runner-mocha/-/test-runner-mocha-0.9.0.tgz", + "integrity": "sha512-ZL9F6FXd0DBQvo/h/+mSfzFTSRVxzV9st/AHhpgABtUtV/AIpVE9to6+xdkpu6827kwjezdpuadPfg+PlrBWqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@web/test-runner-core": "^0.13.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web/test-runner-playwright": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@web/test-runner-playwright/-/test-runner-playwright-0.11.0.tgz", + "integrity": "sha512-s+f43DSAcssKYVOD9SuzueUcctJdHzq1by45gAnSCKa9FQcaTbuYe8CzmxA21g+NcL5+ayo4z+MA9PO4H+PssQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@web/test-runner-core": "^0.13.0", + "@web/test-runner-coverage-v8": "^0.8.0", + "playwright": "^1.22.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web/test-runner-webdriver": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@web/test-runner-webdriver/-/test-runner-webdriver-0.8.0.tgz", + "integrity": "sha512-Ps+xJeHSh8uvTTRcSOTsDFPEVTjP0oW7r8XVc3wXP9qBmCOsTWyQhDALsYqWwT0FwHr9UV2iRiiSZK8FPBRHjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@web/test-runner-core": "^0.13.0", + "webdriverio": "^8.8.6" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web/test-runner/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@zip.js/zip.js": { + "version": "2.7.52", + "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.7.52.tgz", + "integrity": "sha512-+5g7FQswvrCHwYKNMd/KFxZSObctLSsQOgqBSi0LzwHo3li9Eh1w5cF5ndjQw9Zbr3ajVnd2+XyiX85gAetx1Q==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "bun": ">=0.7.0", + "deno": ">=1.0.0", + "node": ">=16.5.0" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dev": true, + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -1826,6 +2944,35 @@ "node": ">=6" } }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -1863,6 +3010,102 @@ "node": ">= 8" } }, + "node_modules/archiver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz", + "integrity": "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "archiver-utils": "^5.0.2", + "async": "^3.2.4", + "buffer-crc32": "^1.0.0", + "readable-stream": "^4.0.0", + "readdir-glob": "^1.1.2", + "tar-stream": "^3.0.0", + "zip-stream": "^6.0.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/archiver-utils": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-5.0.2.tgz", + "integrity": "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob": "^10.0.0", + "graceful-fs": "^4.2.0", + "is-stream": "^2.0.1", + "lazystream": "^1.0.0", + "lodash": "^4.17.15", + "normalize-path": "^3.0.0", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/archiver-utils/node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/archiver-utils/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/archiver-utils/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/archiver/node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "dev": true, + "license": "MIT" + }, "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -1886,11 +3129,20 @@ "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", "dev": true, - "peer": true, "dependencies": { "deep-equal": "^2.0.5" } }, + "node_modules/array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/array-buffer-byte-length": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", @@ -2061,6 +3313,19 @@ "node": "*" } }, + "node_modules/ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/ast-types-flow": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", @@ -2068,6 +3333,16 @@ "dev": true, "peer": true }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/async": { "version": "2.6.4", "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", @@ -2077,6 +3352,16 @@ "lodash": "^4.17.14" } }, + "node_modules/async-mutex": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.4.0.tgz", + "integrity": "sha512-eJFZ1YhRR8UN8eBLoNzcDPcy/jqjsg6I1AP+KvWQX80BqOSW1oJPJXDylPUEeMr2ZQvHgnQ//Lp6f3RQ1zI7HA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", @@ -2112,31 +3397,100 @@ "node": ">= 0.4" } }, + "node_modules/b4a": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", + "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "node_modules/base64id": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", - "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "node_modules/bare-events": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.4.2.tgz", + "integrity": "sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q==", "dev": true, - "engines": { - "node": "^4.5.0 || >= 5.9" + "license": "Apache-2.0", + "optional": true + }, + "node_modules/bare-fs": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.5.tgz", + "integrity": "sha512-SlE9eTxifPDJrT6YgemQ1WGFleevzwY+XAP1Xqgl56HtcrisC2CHCZ2tq6dBpcH2TnNxwUEUGhweo+lrQtYuiw==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-events": "^2.0.0", + "bare-path": "^2.0.0", + "bare-stream": "^2.0.0" } }, - "node_modules/basic-auth": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", - "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "node_modules/bare-os": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.4.4.tgz", + "integrity": "sha512-z3UiI2yi1mK0sXeRdc4O1Kk8aOa/e+FNWZcTiPB/dfTWyLypuE99LibgRaQki914Jq//yAWylcAt+mknKdixRQ==", "dev": true, + "license": "Apache-2.0", + "optional": true + }, + "node_modules/bare-path": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.3.tgz", + "integrity": "sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==", + "dev": true, + "license": "Apache-2.0", + "optional": true, "dependencies": { - "safe-buffer": "5.1.2" - }, + "bare-os": "^2.1.0" + } + }, + "node_modules/bare-stream": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.3.0.tgz", + "integrity": "sha512-pVRWciewGUeCyKEuRxwv06M079r+fRjAQjBEK2P6OYGrO43O+Z0LrPZZEjlc4mB6C2RpZ9AxJ1s7NLEtOHO6eA==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "b4a": "^1.6.6", + "streamx": "^2.20.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/basic-ftp": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", + "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", + "dev": true, + "license": "MIT", "engines": { - "node": ">= 0.8" + "node": ">=10.0.0" } }, "node_modules/benchmark": { @@ -2173,46 +3527,6 @@ "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", "dev": true }, - "node_modules/body-parser": { - "version": "1.20.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", - "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", - "dev": true, - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.13.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, "node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -2240,15 +3554,6 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, - "node_modules/browserstack": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/browserstack/-/browserstack-1.5.3.tgz", - "integrity": "sha512-AO+mECXsW4QcqC9bxwM29O7qWa7bJT94uBFzeb5brylIQwawuEziwq20dPYbins95GlWzOawgyDNdjYAo32EKg==", - "dev": true, - "dependencies": { - "https-proxy-agent": "^2.2.1" - } - }, "node_modules/browserstack-local": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/browserstack-local/-/browserstack-local-1.5.5.tgz", @@ -2275,6 +3580,41 @@ "node": ">= 6" } }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-crc32": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", + "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -2328,6 +3668,49 @@ "node": ">=12" } }, + "node_modules/cache-content-type": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-content-type/-/cache-content-type-1.0.1.tgz", + "integrity": "sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "^2.1.18", + "ylru": "^1.2.0" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/cacheable-lookup": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + } + }, + "node_modules/cacheable-request": { + "version": "10.2.14", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", + "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-cache-semantics": "^4.0.2", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.1", + "keyv": "^4.5.3", + "mimic-response": "^4.0.0", + "normalize-url": "^8.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + } + }, "node_modules/call-bind": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", @@ -2426,6 +3809,22 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/chalk-template": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-0.4.0.tgz", + "integrity": "sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/chalk-template?sponsor=1" + } + }, "node_modules/check-error": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", @@ -2474,6 +3873,53 @@ "node": ">= 6" } }, + "node_modules/chrome-launcher": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.15.2.tgz", + "integrity": "sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/node": "*", + "escape-string-regexp": "^4.0.0", + "is-wsl": "^2.2.0", + "lighthouse-logger": "^1.0.0" + }, + "bin": { + "print-chrome-path": "bin/print-chrome-path.js" + }, + "engines": { + "node": ">=12.13.0" + } + }, + "node_modules/chrome-launcher/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chromium-bidi": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.6.5.tgz", + "integrity": "sha512-RuLrmzYrxSb0s9SgpB+QN5jJucPduZQ/9SIe76MDxYJuecPW5mxMdacJ1f4EtgiV+R0p3sCkznTMvH0MPGFqjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "mitt": "3.0.1", + "urlpattern-polyfill": "10.0.0", + "zod": "3.23.8" + }, + "peerDependencies": { + "devtools-protocol": "*" + } + }, "node_modules/ci-info": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", @@ -2510,6 +3956,19 @@ "node": ">=0.8.0" } }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -2524,6 +3983,44 @@ "node": ">=12" } }, + "node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/co-body": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/co-body/-/co-body-6.2.0.tgz", + "integrity": "sha512-Kbpv2Yd1NdL1V/V4cwLVxraHDV6K8ayohr2rmH0J87Er8+zJjcTa6dAn9QMPC9CRgU8+aNajKbSf1TzDB1yKPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@hapi/bourne": "^3.0.0", + "inflation": "^2.0.0", + "qs": "^6.5.2", + "raw-body": "^2.3.3", + "type-is": "^1.6.16" + }, + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -2542,6 +4039,58 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/command-line-args": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", + "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-back": "^3.1.0", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/command-line-usage": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-7.0.3.tgz", + "integrity": "sha512-PqMLy5+YGwhMh1wS04mVG44oqDsgyLRSKJBdOo1bnYhMKBW65gZF1dRp2OZRhiTjgUHljy99qkO7bsctLaw35Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-back": "^6.2.2", + "chalk-template": "^0.4.0", + "table-layout": "^4.1.0", + "typical": "^7.1.1" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/command-line-usage/node_modules/array-back": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", + "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.17" + } + }, + "node_modules/command-line-usage/node_modules/typical": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-7.2.0.tgz", + "integrity": "sha512-W1+HdVRUl8fS3MZ9ogD51GOb46xMmhAZzR0WPw5jcgIZQJVvkddYzAl4YTU6g5w33Y1iRQLdIi2/1jhi2RNL0g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.17" + } + }, "node_modules/commander": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", @@ -2560,6 +4109,23 @@ "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", "dev": true }, + "node_modules/compress-commons": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-6.0.2.tgz", + "integrity": "sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "crc-32": "^1.2.0", + "crc32-stream": "^6.0.0", + "is-stream": "^2.0.1", + "normalize-path": "^3.0.0", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2572,35 +4138,39 @@ "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", "dev": true }, - "node_modules/connect": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", - "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "dev": true, + "license": "MIT", "dependencies": { - "debug": "2.6.9", - "finalhandler": "1.1.2", - "parseurl": "~1.3.3", - "utils-merge": "1.0.1" + "safe-buffer": "5.2.1" }, "engines": { - "node": ">= 0.10.0" + "node": ">= 0.6" } }, - "node_modules/connect/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/content-disposition/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/connect/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" }, "node_modules/content-type": { "version": "1.0.5", @@ -2617,35 +4187,52 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, - "node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "node_modules/cookies": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.9.1.tgz", + "integrity": "sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==", "dev": true, + "license": "MIT", "dependencies": { - "object-assign": "^4", - "vary": "^1" + "depd": "~2.0.0", + "keygrip": "~1.1.0" }, "engines": { - "node": ">= 0.10" + "node": ">= 0.8" } }, - "node_modules/corser": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", - "integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==", + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "dev": true, + "license": "MIT" + }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "crc32": "bin/crc32.njs" + }, "engines": { - "node": ">= 0.4.0" + "node": ">=0.8" + } + }, + "node_modules/crc32-stream": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-6.0.0.tgz", + "integrity": "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==", + "dev": true, + "license": "MIT", + "dependencies": { + "crc-32": "^1.2.0", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" } }, "node_modules/create-require": { @@ -2654,6 +4241,62 @@ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, + "node_modules/cross-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", + "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "node-fetch": "^2.6.12" + } + }, + "node_modules/cross-fetch/node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/cross-fetch/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/cross-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -2668,10 +4311,16 @@ "node": ">= 8" } }, - "node_modules/custom-event": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", - "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==", + "node_modules/css-shorthand-properties": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/css-shorthand-properties/-/css-shorthand-properties-1.1.1.tgz", + "integrity": "sha512-Md+Juc7M3uOdbAFwOYlTrccIZ7oCFuzrhKYQjdeUEW/sE1hv17Jp/Bws+ReOPpGVBTYCBoYo+G17V5Qo8QQ75A==", + "dev": true + }, + "node_modules/css-value": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/css-value/-/css-value-0.0.1.tgz", + "integrity": "sha512-FUV3xaJ63buRLgHrLQVlVgQnQdR4yqdLGaDu7g8CQcWjInDfM9plBTPI9FRfpahju1UBSaMckeb2/46ApS/V1Q==", "dev": true }, "node_modules/damerau-levenshtein": { @@ -2681,6 +4330,16 @@ "dev": true, "peer": true }, + "node_modules/data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, "node_modules/data-view-buffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", @@ -2732,22 +4391,21 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/date-format": { - "version": "4.0.14", - "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", - "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", + "node_modules/debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", "dev": true, - "engines": { - "node": ">=4.0" - } + "license": "MIT" }, "node_modules/debug": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", - "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -2758,6 +4416,13 @@ } } }, + "node_modules/debug/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, "node_modules/decamelize": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", @@ -2770,6 +4435,35 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/deep-eql": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", @@ -2787,7 +4481,6 @@ "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", "dev": true, - "peer": true, "dependencies": { "array-buffer-byte-length": "^1.0.0", "call-bind": "^1.0.5", @@ -2830,6 +4523,39 @@ "node": ">=0.10.0" } }, + "node_modules/deepmerge-ts": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/deepmerge-ts/-/deepmerge-ts-5.1.0.tgz", + "integrity": "sha512-eS8dRJOckyo9maw9Tu5O5RUi/4inFLrnoLkBe3cPfDMx3WZioXtmOew4TXQaxq7Rhl4xjDtR7c6x8nNTxOvbFw==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", @@ -2847,6 +4573,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/define-properties": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", @@ -2864,6 +4600,28 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "dev": true, + "license": "MIT" + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -2873,6 +4631,16 @@ "node": ">= 0.8" } }, + "node_modules/dependency-graph": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", + "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", @@ -2883,11 +4651,12 @@ "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/di": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", - "integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==", - "dev": true + "node_modules/devtools-protocol": { + "version": "0.0.1330662", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1330662.tgz", + "integrity": "sha512-pzh6YQ8zZfz3iKlCvgzVCu22NdpZ8hNmwU6WnQjNVquh0A9iVosPtNLWDwaWVGyrntQlltPFztTMK5Cg6lfCuw==", + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/diff": { "version": "5.2.0", @@ -2922,30 +4691,101 @@ "node": ">=6.0.0" } }, - "node_modules/dom-serialize": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", - "integrity": "sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ==", - "dev": true, - "dependencies": { - "custom-event": "~1.0.0", - "ent": "~2.2.0", - "extend": "^3.0.0", - "void-elements": "^2.0.0" - } - }, "node_modules/duplexer": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", "dev": true }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, "node_modules/eckey-utils": { "version": "0.7.14", "resolved": "https://registry.npmjs.org/eckey-utils/-/eckey-utils-0.7.14.tgz", "integrity": "sha512-s/mENS+mMnJjDSydy0muBQQHMTWJ1nPe8EiphANZrf+lv/1u35aP9WvWHTWqCBJ21blNIurGF7UoLjtaOpoCFw==", "dev": true }, + "node_modules/edge-paths": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/edge-paths/-/edge-paths-3.0.5.tgz", + "integrity": "sha512-sB7vSrDnFa4ezWQk9nZ/n0FdpdUuC6R1EOrlU3DL+bovcNFK28rqu2emmAUjujYEJTWIgQGqgVVWUZXMnc8iWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/which": "^2.0.1", + "which": "^2.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/shirshak55" + } + }, + "node_modules/edgedriver": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/edgedriver/-/edgedriver-5.6.1.tgz", + "integrity": "sha512-3Ve9cd5ziLByUdigw6zovVeWJjVs8QHVmqOB0sJ0WNeVPcwf4p18GnxMmVvlFmYRloUwf5suNuorea4QzwBIOA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@wdio/logger": "^8.38.0", + "@zip.js/zip.js": "^2.7.48", + "decamelize": "^6.0.0", + "edge-paths": "^3.0.5", + "fast-xml-parser": "^4.4.1", + "node-fetch": "^3.3.2", + "which": "^4.0.0" + }, + "bin": { + "edgedriver": "bin/edgedriver.js" + } + }, + "node_modules/edgedriver/node_modules/decamelize": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.0.tgz", + "integrity": "sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/edgedriver/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/edgedriver/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -2956,8 +4796,7 @@ "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/encodeurl": { "version": "1.0.2", @@ -2968,34 +4807,14 @@ "node": ">= 0.8" } }, - "node_modules/engine.io": { - "version": "6.5.5", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.5.tgz", - "integrity": "sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==", + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dev": true, + "license": "MIT", "dependencies": { - "@types/cookie": "^0.4.1", - "@types/cors": "^2.8.12", - "@types/node": ">=10.0.0", - "accepts": "~1.3.4", - "base64id": "2.0.0", - "cookie": "~0.4.1", - "cors": "~2.8.5", - "debug": "~4.3.1", - "engine.io-parser": "~5.2.1", - "ws": "~8.17.1" - }, - "engines": { - "node": ">=10.2.0" - } - }, - "node_modules/engine.io-parser": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", - "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", - "dev": true, - "engines": { - "node": ">=10.0.0" + "once": "^1.4.0" } }, "node_modules/enhanced-resolve": { @@ -3011,18 +4830,6 @@ "node": ">=10.13.0" } }, - "node_modules/ent": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.1.tgz", - "integrity": "sha512-QHuXVeZx9d+tIQAz/XztU0ZwZf2Agg9CcXcgE1rurqvdBeDBrpSwjl8/6XUqMg7tw2Y7uAdKb2sRv+bSEFqQ5A==", - "dev": true, - "dependencies": { - "punycode": "^1.4.1" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/entities": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", @@ -3041,6 +4848,13 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/errorstacks": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/errorstacks/-/errorstacks-2.4.1.tgz", + "integrity": "sha512-jE4i0SMYevwu/xxAuzhly/KTwtj0xDhbzB6m1xPImxTkw8wcCbgarOQPfCVMi5JKVyW7in29pNJCCJrry3Ynnw==", + "dev": true, + "license": "MIT" + }, "node_modules/es-abstract": { "version": "1.23.3", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", @@ -3127,7 +4941,6 @@ "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.3", @@ -3169,6 +4982,13 @@ "node": ">= 0.4" } }, + "node_modules/es-module-lexer": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", + "dev": true, + "license": "MIT" + }, "node_modules/es-object-atoms": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", @@ -3221,21 +5041,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", - "dev": true - }, - "node_modules/es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", - "dev": true, - "dependencies": { - "es6-promise": "^4.0.3" - } - }, "node_modules/esbuild": { "version": "0.23.1", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz", @@ -3299,6 +5104,28 @@ "node": ">=8" } }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, "node_modules/eslint": { "version": "8.57.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", @@ -3871,6 +5698,20 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/esquery": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", @@ -3919,6 +5760,16 @@ "node": ">=0.10.0" } }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/event-stream": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", @@ -3934,17 +5785,86 @@ "through": "~2.3.1" } }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/extract-zip/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/fast-deep-equal": { "version": "3.1.3", @@ -3952,6 +5872,13 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "dev": true, + "license": "MIT" + }, "node_modules/fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", @@ -3992,6 +5919,29 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "node_modules/fast-xml-parser": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.0.tgz", + "integrity": "sha512-/PlTQCI96+fZMAOLMZK4CWG1ItCbfZ/0jx7UIJFChPNrx7tcEgerUgWbeieCM9MfHInUDyK8DWYZ+YrywDJuTg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + }, + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + } + ], + "license": "MIT", + "dependencies": { + "strnum": "^1.0.5" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, "node_modules/fastq": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", @@ -4001,6 +5951,50 @@ "reusify": "^1.0.4" } }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/fetch-blob/node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, "node_modules/fflate": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.4.tgz", @@ -4031,49 +6025,17 @@ "node": ">=8" } }, - "node_modules/finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "node_modules/find-replace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", + "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", "dev": true, + "license": "MIT", "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" + "array-back": "^3.0.1" }, "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/finalhandler/node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", - "dev": true, - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" + "node": ">=4.0.0" } }, "node_modules/find-up": { @@ -4121,26 +6083,6 @@ "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, - "node_modules/follow-redirects": { - "version": "1.15.8", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.8.tgz", - "integrity": "sha512-xgrmBhBToVKay1q2Tao5LI26B83UhrB/vM1avwVSDzt8rx3rO6AizBAaF46EgksTVr+rFTQaqZZ9MVBfUe4nig==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -4163,26 +6105,45 @@ "node": ">=8.0.0" } }, + "node_modules/form-data-encoder": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", + "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.17" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/from": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==", "dev": true }, - "node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -4239,6 +6200,154 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/geckodriver": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/geckodriver/-/geckodriver-4.4.4.tgz", + "integrity": "sha512-0zaw19tcmWeluqx7+Y559JGBtidu1D0Lb8ElYKiNEQu8r3sCfrLUf5V10xypl8u29ZLbgRV7WflxCJVTCkCMFA==", + "dev": true, + "hasInstallScript": true, + "license": "MPL-2.0", + "dependencies": { + "@wdio/logger": "^9.0.0", + "@zip.js/zip.js": "^2.7.48", + "decamelize": "^6.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.5", + "node-fetch": "^3.3.2", + "tar-fs": "^3.0.6", + "which": "^4.0.0" + }, + "bin": { + "geckodriver": "bin/geckodriver.js" + }, + "engines": { + "node": "^16.13 || >=18 || >=20" + } + }, + "node_modules/geckodriver/node_modules/@wdio/logger": { + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-9.0.8.tgz", + "integrity": "sha512-uIyYIDBwLczmsp9JE5hN3ME8Xg+9WNBfSNXD69ICHrY9WPTzFf94UeTuavK7kwSKF3ro2eJbmNZItYOfnoovnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^5.1.2", + "loglevel": "^1.6.0", + "loglevel-plugin-prefix": "^0.8.4", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18.20.0" + } + }, + "node_modules/geckodriver/node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/geckodriver/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/geckodriver/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/geckodriver/node_modules/decamelize": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.0.tgz", + "integrity": "sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/geckodriver/node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/geckodriver/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/geckodriver/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/geckodriver/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -4276,6 +6385,32 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-port": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-7.1.0.tgz", + "integrity": "sha512-QB9NKEeDg3xxVwCCwJQ9+xycaz6pBB6iQ76wiWMl1927n0Kir6alPiP+yuiICLLU4jpMe08dXfpebuQppFA2zw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-symbol-description": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", @@ -4305,6 +6440,60 @@ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, + "node_modules/get-uri": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz", + "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==", + "dev": true, + "license": "MIT", + "dependencies": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4", + "fs-extra": "^11.2.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/get-uri/node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/get-uri/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/get-uri/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/glob": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", @@ -4421,6 +6610,32 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/got": { + "version": "12.6.1", + "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", + "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^5.2.0", + "@szmarczak/http-timer": "^5.0.1", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.8", + "decompress-response": "^6.0.0", + "form-data-encoder": "^2.1.2", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -4433,6 +6648,13 @@ "integrity": "sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w==", "dev": true }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true, + "license": "MIT" + }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -4535,24 +6757,67 @@ "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, - "node_modules/html-encoding-sniffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", - "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", - "dev": true, - "dependencies": { - "whatwg-encoding": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, + "node_modules/http-assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/http-assert/-/http-assert-1.5.0.tgz", + "integrity": "sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-equal": "~1.0.1", + "http-errors": "~1.8.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-assert/node_modules/deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/http-assert/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-assert/node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "dev": true, + "license": "BSD-2-Clause" + }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -4578,79 +6843,55 @@ "node": ">= 0.8" } }, - "node_modules/http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "dev": true, + "license": "MIT", "dependencies": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" + "agent-base": "^7.1.0", + "debug": "^4.3.4" }, "engines": { - "node": ">=8.0.0" + "node": ">= 14" } }, - "node_modules/http-server": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz", - "integrity": "sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==", + "node_modules/http-proxy-agent/node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dev": true, + "license": "MIT", "dependencies": { - "basic-auth": "^2.0.1", - "chalk": "^4.1.2", - "corser": "^2.0.1", - "he": "^1.2.0", - "html-encoding-sniffer": "^3.0.0", - "http-proxy": "^1.18.1", - "mime": "^1.6.0", - "minimist": "^1.2.6", - "opener": "^1.5.1", - "portfinder": "^1.0.28", - "secure-compare": "3.0.1", - "union": "~0.5.0", - "url-join": "^4.0.1" - }, - "bin": { - "http-server": "bin/http-server" + "debug": "^4.3.4" }, "engines": { - "node": ">=12" + "node": ">= 14" } }, - "node_modules/https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", + "node_modules/http2-wrapper": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", + "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", "dev": true, + "license": "MIT", "dependencies": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" }, "engines": { - "node": ">= 4.5.0" + "node": ">=10.19.0" } }, - "node_modules/https-proxy-agent/node_modules/agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, - "dependencies": { - "es6-promisify": "^5.0.0" - }, + "license": "Apache-2.0", "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/https-proxy-agent/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" + "node": ">=10.17.0" } }, "node_modules/iconv-lite": { @@ -4665,6 +6906,27 @@ "node": ">=0.10.0" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -4674,6 +6936,13 @@ "node": ">= 4" } }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "dev": true, + "license": "MIT" + }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -4690,6 +6959,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/import-meta-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", + "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -4708,6 +6988,16 @@ "node": ">=8" } }, + "node_modules/inflation": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/inflation/-/inflation-2.1.0.tgz", + "integrity": "sha512-t54PPJHG1Pp7VQvxyVCJ9mBbjG3Hqryges9bXoOO6GExCPa+//i/d5GSuFtpx3ALLd7lgIAur6zrIlBQyJuMlQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -4725,6 +7015,25 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "node_modules/internal-ip": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-6.2.0.tgz", + "integrity": "sha512-D8WGsR6yDt8uq7vDMu7mjcR+yRMm3dW8yufyChmszWRjcSHuxLBkR3GdS2HZAjodsaGuCvXeEJpueisXJULghg==", + "dev": true, + "license": "MIT", + "dependencies": { + "default-gateway": "^6.0.0", + "ipaddr.js": "^1.9.1", + "is-ip": "^3.1.0", + "p-event": "^4.2.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/internal-ip?sponsor=1" + } + }, "node_modules/internal-slot": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", @@ -4739,12 +7048,45 @@ "node": ">= 0.4" } }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/ip-regex": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz", + "integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/is-arguments": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -4870,18 +7212,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-ci": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", - "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", - "dev": true, - "dependencies": { - "ci-info": "^3.2.0" - }, - "bin": { - "is-ci": "bin.js" - } - }, "node_modules/is-core-module": { "version": "2.15.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", @@ -4978,7 +7308,6 @@ "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", "dev": true, - "peer": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -5001,12 +7330,24 @@ "node": ">=0.10.0" } }, + "node_modules/is-ip": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-3.1.0.tgz", + "integrity": "sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ip-regex": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-map": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", "dev": true, - "peer": true, "engines": { "node": ">= 0.4" }, @@ -5110,7 +7451,6 @@ "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", "dev": true, - "peer": true, "engines": { "node": ">= 0.4" }, @@ -5133,6 +7473,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-string": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", @@ -5195,7 +7548,6 @@ "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", "dev": true, - "peer": true, "engines": { "node": ">= 0.4" }, @@ -5220,7 +7572,6 @@ "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.7", "get-intrinsic": "^1.2.4" @@ -5250,18 +7601,6 @@ "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", "dev": true }, - "node_modules/isbinaryfile": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", - "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", - "dev": true, - "engines": { - "node": ">= 8.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/gjtorikian/" - } - }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -5318,6 +7657,22 @@ "set-function-name": "^2.0.1" } }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -5345,6 +7700,13 @@ "xmlcreate": "^2.0.4" } }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "dev": true, + "license": "MIT" + }, "node_modules/jsesc": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", @@ -5393,15 +7755,6 @@ "json5": "lib/cli.js" } }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, "node_modules/jsx-ast-utils": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", @@ -5418,6 +7771,52 @@ "node": ">=4.0" } }, + "node_modules/jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "dev": true, + "license": "(MIT OR GPL-3.0-or-later)", + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, + "node_modules/jszip/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jszip/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/jszip/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/just-extend": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", @@ -5425,337 +7824,17 @@ "dev": true, "license": "MIT" }, - "node_modules/karma": { - "version": "6.4.4", - "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.4.tgz", - "integrity": "sha512-LrtUxbdvt1gOpo3gxG+VAJlJAEMhbWlM4YrFQgql98FwF7+K8K12LYO4hnDdUkNjeztYrOXEMqgTajSWgmtI/w==", + "node_modules/keygrip": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz", + "integrity": "sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==", "dev": true, + "license": "MIT", "dependencies": { - "@colors/colors": "1.5.0", - "body-parser": "^1.19.0", - "braces": "^3.0.2", - "chokidar": "^3.5.1", - "connect": "^3.7.0", - "di": "^0.0.1", - "dom-serialize": "^2.2.1", - "glob": "^7.1.7", - "graceful-fs": "^4.2.6", - "http-proxy": "^1.18.1", - "isbinaryfile": "^4.0.8", - "lodash": "^4.17.21", - "log4js": "^6.4.1", - "mime": "^2.5.2", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.5", - "qjobs": "^1.2.0", - "range-parser": "^1.2.1", - "rimraf": "^3.0.2", - "socket.io": "^4.7.2", - "source-map": "^0.6.1", - "tmp": "^0.2.1", - "ua-parser-js": "^0.7.30", - "yargs": "^16.1.1" - }, - "bin": { - "karma": "bin/karma" + "tsscmp": "1.0.6" }, "engines": { - "node": ">= 10" - } - }, - "node_modules/karma-browserstack-launcher": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/karma-browserstack-launcher/-/karma-browserstack-launcher-1.6.0.tgz", - "integrity": "sha512-Y/UWPdHZkHIVH2To4GWHCTzmrsB6H7PBWy6pw+TWz5sr4HW2mcE+Uj6qWgoVNxvQU1Pfn5LQQzI6EQ65p8QbiQ==", - "dev": true, - "dependencies": { - "browserstack": "~1.5.1", - "browserstack-local": "^1.3.7", - "q": "~1.5.0" - }, - "peerDependencies": { - "karma": ">=0.9" - } - }, - "node_modules/karma-chrome-launcher": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.2.0.tgz", - "integrity": "sha512-rE9RkUPI7I9mAxByQWkGJFXfFD6lE4gC5nPuZdobf/QdTEJI6EU4yIay/cfU/xV4ZxlM5JiTv7zWYgA64NpS5Q==", - "dev": true, - "dependencies": { - "which": "^1.2.1" - } - }, - "node_modules/karma-chrome-launcher/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/karma-firefox-launcher": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-2.1.3.tgz", - "integrity": "sha512-LMM2bseebLbYjODBOVt7TCPP9OI2vZIXCavIXhkO9m+10Uj5l7u/SKoeRmYx8FYHTVGZSpk6peX+3BMHC1WwNw==", - "dev": true, - "dependencies": { - "is-wsl": "^2.2.0", - "which": "^3.0.0" - } - }, - "node_modules/karma-firefox-launcher/node_modules/which": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", - "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/karma-mocha": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/karma-mocha/-/karma-mocha-2.0.1.tgz", - "integrity": "sha512-Tzd5HBjm8his2OA4bouAsATYEpZrp9vC7z5E5j4C5Of5Rrs1jY67RAwXNcVmd/Bnk1wgvQRou0zGVLey44G4tQ==", - "dev": true, - "dependencies": { - "minimist": "^1.2.3" - } - }, - "node_modules/karma-mocha-reporter": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/karma-mocha-reporter/-/karma-mocha-reporter-2.2.5.tgz", - "integrity": "sha512-Hr6nhkIp0GIJJrvzY8JFeHpQZNseuIakGac4bpw8K1+5F0tLb6l7uvXRa8mt2Z+NVwYgCct4QAfp2R2QP6o00w==", - "dev": true, - "dependencies": { - "chalk": "^2.1.0", - "log-symbols": "^2.1.0", - "strip-ansi": "^4.0.0" - }, - "peerDependencies": { - "karma": ">=0.13" - } - }, - "node_modules/karma-mocha-reporter/node_modules/ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/karma-mocha-reporter/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/karma-mocha-reporter/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/karma-mocha-reporter/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/karma-mocha-reporter/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/karma-mocha-reporter/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/karma-mocha-reporter/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/karma-mocha-reporter/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dev": true, - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/karma-mocha-reporter/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/karma-webkit-launcher": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/karma-webkit-launcher/-/karma-webkit-launcher-2.6.0.tgz", - "integrity": "sha512-IDURopxJ1SbuqnvPaE+lP2qiP2Ie7I+ojwJRBpr0tfGwObsaVdjMkUkmZ1BcXUtYRt5ogs9cyCH2Wb9sNv0BbQ==", - "dev": true, - "dependencies": { - "is-ci": "^3.0.1", - "uuid": "^10.0.0" - }, - "peerDependenciesMeta": { - "playwright": { - "optional": true - } - } - }, - "node_modules/karma/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/karma/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/karma/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/karma/node_modules/mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", - "dev": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/karma/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/karma/node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/karma/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/karma/node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "engines": { - "node": ">=10" + "node": ">= 0.6" } }, "node_modules/keyv": { @@ -5776,6 +7855,178 @@ "graceful-fs": "^4.1.9" } }, + "node_modules/koa": { + "version": "2.15.3", + "resolved": "https://registry.npmjs.org/koa/-/koa-2.15.3.tgz", + "integrity": "sha512-j/8tY9j5t+GVMLeioLaxweJiKUayFhlGqNTzf2ZGwL0ZCQijd2RLHK0SLW5Tsko8YyyqCZC2cojIb0/s62qTAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "^1.3.5", + "cache-content-type": "^1.0.0", + "content-disposition": "~0.5.2", + "content-type": "^1.0.4", + "cookies": "~0.9.0", + "debug": "^4.3.2", + "delegates": "^1.0.0", + "depd": "^2.0.0", + "destroy": "^1.0.4", + "encodeurl": "^1.0.2", + "escape-html": "^1.0.3", + "fresh": "~0.5.2", + "http-assert": "^1.3.0", + "http-errors": "^1.6.3", + "is-generator-function": "^1.0.7", + "koa-compose": "^4.1.0", + "koa-convert": "^2.0.0", + "on-finished": "^2.3.0", + "only": "~0.0.2", + "parseurl": "^1.3.2", + "statuses": "^1.5.0", + "type-is": "^1.6.16", + "vary": "^1.1.2" + }, + "engines": { + "node": "^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4" + } + }, + "node_modules/koa-compose": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/koa-compose/-/koa-compose-4.1.0.tgz", + "integrity": "sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==", + "dev": true, + "license": "MIT" + }, + "node_modules/koa-convert": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/koa-convert/-/koa-convert-2.0.0.tgz", + "integrity": "sha512-asOvN6bFlSnxewce2e/DK3p4tltyfC4VM7ZwuTuepI7dEQVcvpyFuBcEARu1+Hxg8DIwytce2n7jrZtRlPrARA==", + "dev": true, + "license": "MIT", + "dependencies": { + "co": "^4.6.0", + "koa-compose": "^4.1.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/koa-etag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/koa-etag/-/koa-etag-4.0.0.tgz", + "integrity": "sha512-1cSdezCkBWlyuB9l6c/IFoe1ANCDdPBxkDkRiaIup40xpUub6U/wwRXoKBZw/O5BifX9OlqAjYnDyzM6+l+TAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "etag": "^1.8.1" + } + }, + "node_modules/koa-send": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/koa-send/-/koa-send-5.0.1.tgz", + "integrity": "sha512-tmcyQ/wXXuxpDxyNXv5yNNkdAMdFRqwtegBXUaowiQzUKqJehttS0x2j0eOZDQAyloAth5w6wwBImnFzkUz3pQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "http-errors": "^1.7.3", + "resolve-path": "^1.4.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/koa-send/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/koa-send/node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/koa-static": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/koa-static/-/koa-static-5.0.0.tgz", + "integrity": "sha512-UqyYyH5YEXaJrf9S8E23GoJFQZXkBVJ9zYYMPGz919MSX1KuvAcycIuS0ci150HCoPf4XQVhQ84Qf8xRPWxFaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.1.0", + "koa-send": "^5.0.0" + }, + "engines": { + "node": ">= 7.6.0" + } + }, + "node_modules/koa-static/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/koa/node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/koa/node_modules/http-errors/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ky": { + "version": "0.33.3", + "resolved": "https://registry.npmjs.org/ky/-/ky-0.33.3.tgz", + "integrity": "sha512-CasD9OCEQSFIam2U8efFK81Yeg8vNMTBUqtMOHlrcWQHqUX3HeCl9Dr31u4toV7emlH8Mymk5+9p0lL6mKb/Xw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/ky?sponsor=1" + } + }, "node_modules/language-subtag-registry": { "version": "0.3.23", "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", @@ -5796,6 +8047,52 @@ "node": ">=0.10" } }, + "node_modules/lazystream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, + "node_modules/lazystream/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lazystream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/lazystream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -5809,6 +8106,44 @@ "node": ">= 0.8.0" } }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "immediate": "~3.0.5" + } + }, + "node_modules/lighthouse-logger": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.4.2.tgz", + "integrity": "sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "debug": "^2.6.9", + "marky": "^1.2.2" + } + }, + "node_modules/lighthouse-logger/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/lighthouse-logger/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -5824,6 +8159,41 @@ "uc.micro": "^1.0.1" } }, + "node_modules/locate-app": { + "version": "2.4.43", + "resolved": "https://registry.npmjs.org/locate-app/-/locate-app-2.4.43.tgz", + "integrity": "sha512-BX6NEdECUGcDQw8aqqg02qLyF9rF8V+dAfyAnBzL2AofIlIvf4Q6EGXnzVWpWot9uBE+x/o8CjXHo7Zlegu91Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://buymeacoffee.com/hejny" + }, + { + "type": "github", + "url": "https://github.com/hejny/locate-app/blob/main/README.md#%EF%B8%8F-contributing" + } + ], + "license": "Apache-2.0", + "dependencies": { + "@promptbook/utils": "0.70.0-1", + "type-fest": "2.13.0", + "userhome": "1.0.0" + } + }, + "node_modules/locate-app/node_modules/type-fest": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.13.0.tgz", + "integrity": "sha512-lPfAm42MxE4/456+QyIaaVBAwgpJb6xZ8PRu09utnhPdWwcyj9vgy6Sq0Z5yNbJ21EdxB5dRU/Qg8bsyAMtlcw==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -5845,6 +8215,20 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", @@ -5857,104 +8241,67 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, - "node_modules/log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "node_modules/lodash.zip": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz", + "integrity": "sha512-C7IOaBBK/0gMORRBd8OETNx3kmOkgIWIPvyDpZSCTwUrpYmgZwJkjZeOD8ww4xbOUOs4/attY+pciKvadNfFbg==", "dev": true, + "license": "MIT" + }, + "node_modules/log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "license": "MIT", "dependencies": { - "chalk": "^2.0.1" + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/log-symbols/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, + "license": "MIT", "dependencies": { - "color-convert": "^1.9.0" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/log-symbols/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/loglevel": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.2.tgz", + "integrity": "sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==", "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "license": "MIT", + "engines": { + "node": ">= 0.6.0" }, - "engines": { - "node": ">=4" + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/loglevel" } }, - "node_modules/log-symbols/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/loglevel-plugin-prefix": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/loglevel-plugin-prefix/-/loglevel-plugin-prefix-0.8.4.tgz", + "integrity": "sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g==", "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/log-symbols/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/log-symbols/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/log-symbols/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/log-symbols/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/log4js": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz", - "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==", - "dev": true, - "dependencies": { - "date-format": "^4.0.14", - "debug": "^4.3.4", - "flatted": "^3.2.7", - "rfdc": "^1.3.0", - "streamroller": "^3.1.5" - }, - "engines": { - "node": ">=8.0" - } + "license": "MIT" }, "node_modules/loose-envify": { "version": "1.4.0", @@ -5978,6 +8325,29 @@ "get-func-name": "^2.0.1" } }, + "node_modules/lowercase-keys": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru-cache": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz", + "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16.14" + } + }, "node_modules/magic-string": { "version": "0.30.11", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", @@ -6052,6 +8422,13 @@ "node": ">= 12" } }, + "node_modules/marky": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/marky/-/marky-1.2.5.tgz", + "integrity": "sha512-q9JtQJKjpsVxCRVgQ+WapguSbKC3SQ5HEzFGPAJMStgh3QjCawp00UKv3MTTAArTmGmmPUvllHZoNbZ3gs0I+Q==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/mdurl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", @@ -6067,6 +8444,13 @@ "node": ">= 0.6" } }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -6089,18 +8473,6 @@ "node": ">=8.6" } }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -6122,6 +8494,29 @@ "node": ">= 0.6" } }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-response": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -6155,6 +8550,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "dev": true, + "license": "MIT" + }, "node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -6167,6 +8579,13 @@ "node": ">=10" } }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true, + "license": "MIT" + }, "node_modules/mocha": { "version": "10.7.3", "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.3.tgz", @@ -6307,6 +8726,32 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "node_modules/nanocolors": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/nanocolors/-/nanocolors-0.2.13.tgz", + "integrity": "sha512-0n3mSAQLPpGLV9ORXT5+C/D4mwew7Ebws69Hx4E2sgz2ZA5+32Q80B9tL8PbL7XHnRDiAxH/pnrUJ9a4fkTNTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -6322,6 +8767,16 @@ "node": ">= 0.6" } }, + "node_modules/netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/nise": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/nise/-/nise-6.0.1.tgz", @@ -6336,6 +8791,55 @@ "path-to-regexp": "^8.1.0" } }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/node-fetch/node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -6366,11 +8870,38 @@ "node": ">=0.10.0" } }, + "node_modules/normalize-url": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.1.tgz", + "integrity": "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true, + "peer": true, "engines": { "node": ">=0.10.0" } @@ -6392,7 +8923,6 @@ "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1" @@ -6515,13 +9045,44 @@ "wrappy": "1" } }, - "node_modules/opener": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", - "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, - "bin": { - "opener": "bin/opener-bin.js" + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/only": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/only/-/only-0.0.2.tgz", + "integrity": "sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ==", + "dev": true + }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/optionator": { @@ -6541,6 +9102,42 @@ "node": ">= 0.8.0" } }, + "node_modules/p-cancelable": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", + "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.20" + } + }, + "node_modules/p-event": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", + "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-timeout": "^3.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -6571,6 +9168,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -6580,6 +9190,81 @@ "node": ">=6" } }, + "node_modules/pac-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.2.tgz", + "integrity": "sha512-BFi3vZnO9X5Qt6NRz7ZOaPja3ic0PhlsmCRYLOpN11+mWBCR6XJDqW5RF3j8jm4WGGQZtBA+bTfxYzeKW73eHg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.5", + "pac-resolver": "^7.0.1", + "socks-proxy-agent": "^8.0.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-proxy-agent/node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-proxy-agent/node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "dev": true, + "license": "MIT", + "dependencies": { + "degenerator": "^5.0.0", + "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true, + "license": "(MIT AND Zlib)" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -6610,6 +9295,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true, + "license": "MIT" + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -6652,6 +9344,30 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, "node_modules/path-to-regexp": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.1.0.tgz", @@ -6689,6 +9405,13 @@ "through": "~2.3" } }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true, + "license": "MIT" + }, "node_modules/picocolors": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", @@ -6821,6 +9544,33 @@ "node": ">= 0.8.0" } }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true, + "license": "MIT" + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -6833,6 +9583,70 @@ "react-is": "^16.13.1" } }, + "node_modules/proxy-agent": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz", + "integrity": "sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.3", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.0.1", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true, + "license": "MIT" + }, "node_modules/ps-tree": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz", @@ -6848,30 +9662,55 @@ "node": ">= 0.10" } }, - "node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", - "dev": true - }, - "node_modules/q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", - "deprecated": "You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.\n\n(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)", + "node_modules/pump": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", "dev": true, - "engines": { - "node": ">=0.6.0", - "teleport": ">=0.2.0" + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" } }, - "node_modules/qjobs": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", - "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", + "node_modules/puppeteer-core": { + "version": "23.3.1", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-23.3.1.tgz", + "integrity": "sha512-m5gTpITEqqpSgAvPUI/Ch9igh5sNJV+BVVbqQMzqirRDVHDCkLGHaydEQZx2NZvSXdwCFrIV///cpSlX/uD0Sg==", "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@puppeteer/browsers": "2.4.0", + "chromium-bidi": "0.6.5", + "debug": "^4.3.7", + "devtools-protocol": "0.0.1330662", + "typed-query-selector": "^2.12.0", + "ws": "^8.18.0" + }, "engines": { - "node": ">=0.9" + "node": ">=18" + } + }, + "node_modules/puppeteer-core/node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, "node_modules/qs": { @@ -6890,6 +9729,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/query-selector-shadow-dom": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/query-selector-shadow-dom/-/query-selector-shadow-dom-1.0.1.tgz", + "integrity": "sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw==", + "dev": true, + "license": "MIT" + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -6910,6 +9756,26 @@ } ] }, + "node_modules/queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", + "dev": true, + "license": "MIT" + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -6919,15 +9785,6 @@ "safe-buffer": "^5.1.0" } }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/raw-body": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", @@ -7052,6 +9909,71 @@ "node": ">=8" } }, + "node_modules/readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/readable-stream/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/readdir-glob": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", + "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.1.0" + } + }, + "node_modules/readdir-glob/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -7143,12 +10065,6 @@ "node": ">=0.10.0" } }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true - }, "node_modules/requizzle": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.4.tgz", @@ -7175,6 +10091,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true, + "license": "MIT" + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -7184,6 +10107,60 @@ "node": ">=4" } }, + "node_modules/resolve-path": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/resolve-path/-/resolve-path-1.4.0.tgz", + "integrity": "sha512-i1xevIst/Qa+nA9olDxLWnLk8YZbi8R/7JPbCMcgyWaFR6bKWaexgJgEB5oc2PKMjYdrHynyz0NY+if+H98t1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "http-errors": "~1.6.2", + "path-is-absolute": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/resolve-path/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/resolve-path/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/resolve-path/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true, + "license": "ISC" + }, + "node_modules/resolve-path/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true, + "license": "ISC" + }, "node_modules/resolve-pkg-maps": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", @@ -7193,6 +10170,53 @@ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, + "node_modules/responselike": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", + "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", + "dev": true, + "license": "MIT", + "dependencies": { + "lowercase-keys": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/resq": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/resq/-/resq-1.11.0.tgz", + "integrity": "sha512-G10EBz+zAAy3zUd/CDoBbXRL6ia9kOo3xRHrMDsHljI0GDkhYlyjwoCx5+3eCC4swi1uCoZQhskuJkj7Gp57Bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^2.0.1" + } + }, + "node_modules/resq/node_modules/fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==", + "dev": true, + "license": "MIT" + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -7203,11 +10227,12 @@ "node": ">=0.10.0" } }, - "node_modules/rfdc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", - "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", - "dev": true + "node_modules/rgb2hex": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/rgb2hex/-/rgb2hex-0.2.5.tgz", + "integrity": "sha512-22MOP1Rh7sAo1BZpDG6R5RFYzR2lYEgwq7HEmyW2qcsOqR2lQKmn+O//xV3YG/0rrhMC6KVX2hU+ZXuaw9a5bw==", + "dev": true, + "license": "MIT" }, "node_modules/rimraf": { "version": "3.0.2", @@ -7326,6 +10351,13 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/safaridriver": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/safaridriver/-/safaridriver-0.1.2.tgz", + "integrity": "sha512-4R309+gWflJktzPXBQCobbWEHlzC4aK3a+Ov3tz2Ib2aBxiwd11phkdIBH1l0EO22x24CJMUQkpKFumRriCSRg==", + "dev": true, + "license": "MIT" + }, "node_modules/safe-array-concat": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", @@ -7373,12 +10405,6 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, - "node_modules/secure-compare": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", - "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==", - "dev": true - }, "node_modules/semver": { "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", @@ -7391,6 +10417,35 @@ "node": ">=10" } }, + "node_modules/serialize-error": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-11.0.3.tgz", + "integrity": "sha512-2G2y++21dhj2R7iHAdd0FIzjGwuKZld+7Pl/bTU6YIkrC2ZMbVUjm+luj6A6V34Rv9XfKJDKpTWu9W4Gse1D9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^2.12.2" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serialize-error/node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/serialize-javascript": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", @@ -7432,6 +10487,13 @@ "node": ">= 0.4" } }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "dev": true, + "license": "MIT" + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -7514,51 +10576,82 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, "node_modules/smob": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz", "integrity": "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==", "dev": true }, - "node_modules/socket.io": { - "version": "4.7.5", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz", - "integrity": "sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==", + "node_modules/socks": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", + "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", "dev": true, + "license": "MIT", "dependencies": { - "accepts": "~1.3.4", - "base64id": "~2.0.0", - "cors": "~2.8.5", - "debug": "~4.3.2", - "engine.io": "~6.5.2", - "socket.io-adapter": "~2.5.2", - "socket.io-parser": "~4.2.4" + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" }, "engines": { - "node": ">=10.2.0" + "node": ">= 10.0.0", + "npm": ">= 3.0.0" } }, - "node_modules/socket.io-adapter": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz", - "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", + "node_modules/socks-proxy-agent": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz", + "integrity": "sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==", "dev": true, + "license": "MIT", "dependencies": { - "debug": "~4.3.4", - "ws": "~8.17.1" - } - }, - "node_modules/socket.io-parser": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", - "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", - "dev": true, - "dependencies": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.1" + "agent-base": "^7.1.1", + "debug": "^4.3.4", + "socks": "^2.8.3" }, "engines": { - "node": ">=10.0.0" + "node": ">= 14" + } + }, + "node_modules/socks-proxy-agent/node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" } }, "node_modules/source-map": { @@ -7580,6 +10673,23 @@ "source-map": "^0.6.0" } }, + "node_modules/spacetrim": { + "version": "0.11.39", + "resolved": "https://registry.npmjs.org/spacetrim/-/spacetrim-0.11.39.tgz", + "integrity": "sha512-S/baW29azJ7py5ausQRE2S6uEDQnlxgMHOEEq4V770ooBDD1/9kZnxRcco/tjZYuDuqYXblCk/r3N13ZmvHZ2g==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://buymeacoffee.com/hejny" + }, + { + "type": "github", + "url": "https://github.com/hejny/spacetrim/blob/main/README.md#%EF%B8%8F-contributing" + } + ], + "license": "SEE LICENSE IN LICENSE" + }, "node_modules/spdx-correct": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", @@ -7624,6 +10734,23 @@ "node": "*" } }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true, + "license": "BSD-3-Clause" + }, "node_modules/statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", @@ -7638,7 +10765,6 @@ "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", "dev": true, - "peer": true, "dependencies": { "internal-slot": "^1.0.4" }, @@ -7655,20 +10781,52 @@ "duplexer": "~0.1.1" } }, - "node_modules/streamroller": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz", - "integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==", + "node_modules/streamx": { + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.1.tgz", + "integrity": "sha512-uTa0mU6WUC65iUvzKH4X9hEdvSW7rbPxPtwfWiLMSj3qTdQbAiUboZTxauKfpFuGIGa1C2BYijZ7wgdUXICJhA==", "dev": true, + "license": "MIT", "dependencies": { - "date-format": "^4.0.14", - "debug": "^4.3.4", - "fs-extra": "^8.1.0" + "fast-fifo": "^1.3.2", + "queue-tick": "^1.0.1", + "text-decoder": "^1.1.0" }, - "engines": { - "node": ">=8.0" + "optionalDependencies": { + "bare-events": "^2.2.0" } }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -7683,6 +10841,29 @@ "node": ">=8" } }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, "node_modules/string-width/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -7799,6 +10980,20 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -7808,6 +11003,16 @@ "node": ">=4" } }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/strip-indent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", @@ -7832,6 +11037,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", + "dev": true, + "license": "MIT" + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -7856,6 +11068,30 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/table-layout": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-4.1.1.tgz", + "integrity": "sha512-iK5/YhZxq5GO5z8wb0bY1317uDF3Zjpha0QFFLA8/trAoiLbQD0HUbMesEaxyzUgDxi2QlcbM8IvqOlEjgoXBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-back": "^6.2.2", + "wordwrapjs": "^5.1.0" + }, + "engines": { + "node": ">=12.17" + } + }, + "node_modules/table-layout/node_modules/array-back": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", + "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.17" + } + }, "node_modules/taffydb": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz", @@ -7871,6 +11107,33 @@ "node": ">=6" } }, + "node_modules/tar-fs": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.6.tgz", + "integrity": "sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + }, + "optionalDependencies": { + "bare-fs": "^2.1.1", + "bare-path": "^2.1.0" + } + }, + "node_modules/tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, "node_modules/temp-fs": { "version": "0.9.9", "resolved": "https://registry.npmjs.org/temp-fs/-/temp-fs-0.9.9.tgz", @@ -8020,6 +11283,16 @@ "node": "*" } }, + "node_modules/text-decoder": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.0.tgz", + "integrity": "sha512-n1yg1mOj9DNpk3NeZOx7T6jchTbyJS3i3cucbNN6FcdPriMZx7NsgrGpWWdWZZGxD7ES1XB+3uoqHMgOKaN+fg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "b4a": "^1.6.4" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -8032,15 +11305,6 @@ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true }, - "node_modules/tmp": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", - "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", - "dev": true, - "engines": { - "node": ">=14.14" - } - }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -8071,6 +11335,29 @@ "node": ">=0.6" } }, + "node_modules/tr46": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", + "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/tr46/node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/ts-api-utils": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", @@ -8153,6 +11440,16 @@ "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", "dev": true }, + "node_modules/tsscmp": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz", + "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6.x" + } + }, "node_modules/tsx": { "version": "4.19.0", "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.0.tgz", @@ -8291,6 +11588,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/typed-query-selector": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.0.tgz", + "integrity": "sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg==", + "dev": true, + "license": "MIT" + }, "node_modules/typescript": { "version": "5.5.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", @@ -8304,27 +11608,14 @@ "node": ">=14.17" } }, - "node_modules/ua-parser-js": { - "version": "0.7.38", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.38.tgz", - "integrity": "sha512-fYmIy7fKTSFAhG3fuPlubeGaMoAd6r0rSnfEsO5nEY55i26KSLt9EH7PLQiiqPUhNqYIJvSkTy1oArIcXAbPbA==", + "node_modules/typical": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", + "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/ua-parser-js" - }, - { - "type": "paypal", - "url": "https://paypal.me/faisalman" - }, - { - "type": "github", - "url": "https://github.com/sponsors/faisalman" - } - ], + "license": "MIT", "engines": { - "node": "*" + "node": ">=8" } }, "node_modules/uc.micro": { @@ -8348,6 +11639,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, "node_modules/underscore": { "version": "1.13.7", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.7.tgz", @@ -8360,27 +11662,6 @@ "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "dev": true }, - "node_modules/union": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", - "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==", - "dev": true, - "dependencies": { - "qs": "^6.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -8408,33 +11689,28 @@ "node": ">=6" } }, - "node_modules/url-join": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", - "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", - "dev": true + "node_modules/urlpattern-polyfill": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", + "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", + "dev": true, + "license": "MIT" }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "node_modules/userhome": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/userhome/-/userhome-1.0.0.tgz", + "integrity": "sha512-ayFKY3H+Pwfy4W98yPdtH1VqH4psDeyW8lYYFzfecR9d6hqLpqhecktvYR3SEEXt7vG0S1JEpciI3g94pMErig==", "dev": true, "engines": { - "node": ">= 0.4.0" + "node": ">= 0.8.0" } }, - "node_modules/uuid": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", - "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true, - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "bin": { - "uuid": "dist/bin/uuid" - } + "license": "MIT" }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", @@ -8475,13 +11751,32 @@ "node": ">= 0.8" } }, - "node_modules/void-elements": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", - "integrity": "sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==", + "node_modules/wait-port": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/wait-port/-/wait-port-1.1.0.tgz", + "integrity": "sha512-3e04qkoN3LxTMLakdqeWth8nih8usyg+sf1Bgdf9wwUkp05iuK1eSY/QpLvscT/+F/gA89+LpUmmgBtesbqI2Q==", "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "commander": "^9.3.0", + "debug": "^4.3.4" + }, + "bin": { + "wait-port": "bin/wait-port.js" + }, "engines": { - "node": ">=0.10.0" + "node": ">=10" + } + }, + "node_modules/wait-port/node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || >=14" } }, "node_modules/web-streams-polyfill": { @@ -8493,28 +11788,296 @@ "node": ">= 8" } }, - "node_modules/whatwg-encoding": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", - "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "node_modules/webdriver": { + "version": "8.40.3", + "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-8.40.3.tgz", + "integrity": "sha512-mc/pxLpgAQphnIaWvix/QXzp9CJpEvIA3YeF9t5plPaTbvbEaCAYYWkTP6e3vYPYWvx57krjGaYkNUnDCBNolA==", "dev": true, + "license": "MIT", "dependencies": { - "iconv-lite": "0.6.3" + "@types/node": "^22.2.0", + "@types/ws": "^8.5.3", + "@wdio/config": "8.40.3", + "@wdio/logger": "8.38.0", + "@wdio/protocols": "8.40.3", + "@wdio/types": "8.40.3", + "@wdio/utils": "8.40.3", + "deepmerge-ts": "^5.1.0", + "got": "^12.6.1", + "ky": "^0.33.0", + "ws": "^8.8.0" }, + "engines": { + "node": "^16.13 || >=18" + } + }, + "node_modules/webdriver/node_modules/@types/ws": { + "version": "8.5.12", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz", + "integrity": "sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/webdriverio": { + "version": "8.40.5", + "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.40.5.tgz", + "integrity": "sha512-fKzaAF8lbgVFWIP8i0eGk22MpjactVVTWP8qtUXDob5Kdo8ffrg1lCKP8mcyrz6fiZM1OY1m6dvkbFelf23Nxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^22.2.0", + "@wdio/config": "8.40.3", + "@wdio/logger": "8.38.0", + "@wdio/protocols": "8.40.3", + "@wdio/repl": "8.40.3", + "@wdio/types": "8.40.3", + "@wdio/utils": "8.40.3", + "archiver": "^7.0.0", + "aria-query": "^5.0.0", + "css-shorthand-properties": "^1.1.1", + "css-value": "^0.0.1", + "devtools-protocol": "^0.0.1342118", + "grapheme-splitter": "^1.0.2", + "import-meta-resolve": "^4.0.0", + "is-plain-obj": "^4.1.0", + "jszip": "^3.10.1", + "lodash.clonedeep": "^4.5.0", + "lodash.zip": "^4.2.0", + "minimatch": "^9.0.0", + "puppeteer-core": "^21.11.0", + "query-selector-shadow-dom": "^1.0.0", + "resq": "^1.9.1", + "rgb2hex": "0.2.5", + "serialize-error": "^11.0.1", + "webdriver": "8.40.3" + }, + "engines": { + "node": "^16.13 || >=18" + }, + "peerDependencies": { + "devtools": "^8.14.0" + }, + "peerDependenciesMeta": { + "devtools": { + "optional": true + } + } + }, + "node_modules/webdriverio/node_modules/@puppeteer/browsers": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.9.1.tgz", + "integrity": "sha512-PuvK6xZzGhKPvlx3fpfdM2kYY3P/hB1URtK8wA7XUJ6prn6pp22zvJHu48th0SGcHL9SutbPHrFuQgfXTFobWA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "debug": "4.3.4", + "extract-zip": "2.0.1", + "progress": "2.0.3", + "proxy-agent": "6.3.1", + "tar-fs": "3.0.4", + "unbzip2-stream": "1.4.3", + "yargs": "17.7.2" + }, + "bin": { + "browsers": "lib/cjs/main-cli.js" + }, + "engines": { + "node": ">=16.3.0" + } + }, + "node_modules/webdriverio/node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/webdriverio/node_modules/chromium-bidi": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.5.8.tgz", + "integrity": "sha512-blqh+1cEQbHBKmok3rVJkBlBxt9beKBgOsxbFgs7UJcoVbbeZ+K7+6liAsjgpc8l1Xd55cQUy14fXZdGSb4zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "mitt": "3.0.1", + "urlpattern-polyfill": "10.0.0" + }, + "peerDependencies": { + "devtools-protocol": "*" + } + }, + "node_modules/webdriverio/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/webdriverio/node_modules/devtools-protocol": { + "version": "0.0.1342118", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1342118.tgz", + "integrity": "sha512-75fMas7PkYNDTmDyb6PRJCH7ILmHLp+BhrZGeMsa4bCh40DTxgCz2NRy5UDzII4C5KuD0oBMZ9vXKhEl6UD/3w==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/webdriverio/node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/webdriverio/node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/webdriverio/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "license": "ISC", "engines": { "node": ">=12" } }, - "node_modules/whatwg-encoding/node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "node_modules/webdriverio/node_modules/proxy-agent": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.1.tgz", + "integrity": "sha512-Rb5RVBy1iyqOtNl15Cw/llpeLH8bsb37gM1FUfKQ+Wck6xHlbAhWGUFiTRHtkjqGTA5pSHz6+0hrPW/oECihPQ==", "dev": true, + "license": "MIT", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.2", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.0.1", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.2" }, "engines": { - "node": ">=0.10.0" + "node": ">= 14" + } + }, + "node_modules/webdriverio/node_modules/puppeteer-core": { + "version": "21.11.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-21.11.0.tgz", + "integrity": "sha512-ArbnyA3U5SGHokEvkfWjW+O8hOxV1RSJxOgriX/3A4xZRqixt9ZFHD0yPgZQF05Qj0oAqi8H/7stDorjoHY90Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@puppeteer/browsers": "1.9.1", + "chromium-bidi": "0.5.8", + "cross-fetch": "4.0.0", + "debug": "4.3.4", + "devtools-protocol": "0.0.1232444", + "ws": "8.16.0" + }, + "engines": { + "node": ">=16.13.2" + } + }, + "node_modules/webdriverio/node_modules/puppeteer-core/node_modules/devtools-protocol": { + "version": "0.0.1232444", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1232444.tgz", + "integrity": "sha512-pM27vqEfxSxRkTMnF+XCmxSEb6duO5R+t8A9DEEJgy4Wz2RVanje2mmj99B6A3zv2r/qGfYlOvYznUhuokizmg==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/webdriverio/node_modules/tar-fs": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", + "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + } + }, + "node_modules/webdriverio/node_modules/ws": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", + "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "^5.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" } }, "node_modules/which": { @@ -8580,7 +12143,6 @@ "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", "dev": true, - "peer": true, "dependencies": { "is-map": "^2.0.3", "is-set": "^2.0.3", @@ -8622,6 +12184,16 @@ "node": ">=0.10.0" } }, + "node_modules/wordwrapjs": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-5.1.0.tgz", + "integrity": "sha512-JNjcULU2e4KJwUNv6CHgI46UvDGitb6dGryHajXTDiLgg1/RiGoPSDw4kZfYnwGtEXf2ZMeIewDQgFGzkCB2Sg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.17" + } + }, "node_modules/workerpool": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", @@ -8645,6 +12217,25 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -8729,6 +12320,37 @@ "node": ">=10" } }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yauzl/node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/ylru": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ylru/-/ylru-1.4.0.tgz", + "integrity": "sha512-2OQsPNEmBCvXuFlIni/a+Rn+R2pHW9INm0BxXJ4hVDA8TirqMj+J/Rp9ItLatT/5pZqWwefVrTQcHpixsxnVlA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", @@ -8749,6 +12371,31 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zip-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", + "integrity": "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "archiver-utils": "^5.0.0", + "compress-commons": "^6.0.2", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/zod": { + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } } } diff --git a/package.json b/package.json index 6a848d4f..4883e418 100644 --- a/package.json +++ b/package.json @@ -49,11 +49,10 @@ "test-type-definitions": "tsx test/typescript/definitions.ts", "benchmark-time": "node test/benchmarks/time.js", "benchmark-memory-usage": "node test/benchmarks/memory_usage.js", - "start": "http-server", "prebrowsertest": "npm run build-test", - "browsertest": "npm start -- -o test/unittests.html", - "test-browser": "karma start test/karma.conf.cjs", - "test-browserstack": "karma start test/karma.conf.cjs --browsers bs_safari_latest,bs_ios_14,bs_safari_14", + "browsertest": "web-test-runner --config test/web-test-runner.config.js --group local --manual --open", + "test-browser": "web-test-runner --config test/web-test-runner.config.js --group local --playwright --browsers chromium firefox webkit", + "test-browserstack": "web-test-runner --config test/web-test-runner.config.js --group browserstack", "coverage": "c8 npm test", "lint": "eslint .", "docs": "jsdoc --configure .jsdocrc.cjs --destination docs --recurse README.md src && printf '%s' 'docs.openpgpjs.org' > docs/CNAME", @@ -79,6 +78,10 @@ "@types/chai": "^4.3.19", "@types/sinon": "^17.0.3", "@typescript-eslint/parser": "^7.18.0", + "@web/test-runner": "^0.19.0", + "@web/test-runner-browserstack": "^0.7.2", + "@web/test-runner-mocha": "^0.9.0", + "@web/test-runner-playwright": "^0.11.0", "argon2id": "^1.0.1", "benchmark": "^2.1.4", "bn.js": "^5.2.1", @@ -95,14 +98,6 @@ "eslint-plugin-import": "^2.30.0", "eslint-plugin-unicorn": "^48.0.1", "fflate": "^0.7.4", - "http-server": "^14.1.1", - "karma": "^6.4.4", - "karma-browserstack-launcher": "^1.6.0", - "karma-chrome-launcher": "^3.2.0", - "karma-firefox-launcher": "^2.1.3", - "karma-mocha": "^2.0.1", - "karma-mocha-reporter": "^2.2.5", - "karma-webkit-launcher": "^2.6.0", "mocha": "^10.7.3", "playwright": "^1.47.0", "rollup": "^4.21.2", diff --git a/test/karma.conf.cjs b/test/karma.conf.cjs deleted file mode 100644 index 30c7ba30..00000000 --- a/test/karma.conf.cjs +++ /dev/null @@ -1,136 +0,0 @@ -/* eslint-disable no-process-env */ -const { chromium, firefox, webkit } = require('playwright'); - -process.env.CHROME_BIN = chromium.executablePath(); -process.env.FIREFOX_BIN = firefox.executablePath(); -process.env.WEBKIT_HEADLESS_BIN = webkit.executablePath(); - -module.exports = function(config) { - config.set({ - - // base path that will be used to resolve all patterns (eg. files, exclude) - basePath: '..', - - // hostname for local - hostname: '127.0.0.1', - - // frameworks to use - // available frameworks: https://npmjs.org/browse/keyword/karma-adapter - frameworks: ['mocha'], - - // plugins - plugins: [ - 'karma-mocha', - 'karma-chrome-launcher', - 'karma-firefox-launcher', - 'karma-webkit-launcher', - 'karma-mocha-reporter', - 'karma-browserstack-launcher' - ], - - client: { - mocha: { - timeout: 30000, - grep: process.env.LIGHTWEIGHT ? '@lightweight' : undefined - } - }, - - // list of files / patterns to load in the browser - files: [ - { - pattern: 'test/lib/unittests-bundle.js', - type: 'module' - }, - { - pattern: 'dist/**/*', - included: false - }, - { - pattern: 'test/**/*', - included: false - } - ], - - proxies: { - '/lib': '/base/test/lib', - '/worker': '/base/test/worker', - '/dist': '/base/dist' - }, - - // list of files to exclude - exclude: [ - ], - - // preprocess matching files before serving them to the browser - // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor - preprocessors: { - }, - - // test results reporter to use - // possible values: 'dots', 'progress' - // available reporters: https://npmjs.org/browse/keyword/karma-reporter - reporters: ['mocha', 'BrowserStack'], - - // web server host and port - port: 9876, - - // enable / disable colors in the output (reporters and logs) - colors: true, - - // level of logging - // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG - logLevel: config.LOG_INFO, - - // enable / disable watching file and executing tests whenever any file changes - autoWatch: false, - - browserStack: { - username: process.env.BROWSERSTACK_USERNAME, - accessKey: process.env.BROWSERSTACK_ACCESS_KEY, - build: process.env.GITHUB_SHA, - name: process.env.GITHUB_WORKFLOW, - project: `openpgpjs/${process.env.GITHUB_EVENT_NAME || 'push'}${process.env.LIGHTWEIGHT ? '/lightweight' : ''}`, - timeout: 450 - }, - - // define browsers - customLaunchers: { - bs_safari_latest: { // Webkit and Safari can differ in behavior - base: 'BrowserStack', - browser: 'Safari', - browser_version: 'latest', - os: 'OS X', - os_version: 'Ventura' - }, - bs_safari_14: { - base: 'BrowserStack', - browser: 'Safari', - browser_version: '14', - os: 'OS X', - os_version: 'Big Sur' - }, - bs_ios_14: { - base: 'BrowserStack', - device: 'iPhone 12', - real_mobile: true, - os: 'ios', - os_version: '14' - } - }, - - captureTimeout: 6e5, - browserDisconnectTolerance: 0, - browserDisconnectTimeout: 6e5, - browserSocketTimeout: 3e5, - browserNoActivityTimeout: 6e5, - - // start these browsers - // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher - browsers: ['ChromeHeadless', 'FirefoxHeadless', 'WebkitHeadless'], - - // Continuous Integration mode - // if true, Karma captures browsers, runs the tests and exits - singleRun: true - - }); -}; diff --git a/test/unittests.html b/test/unittests.html index aedc5735..f8381f7e 100644 --- a/test/unittests.html +++ b/test/unittests.html @@ -3,38 +3,31 @@ OpenPGPJS Unit Tests - - - - - +
      diff --git a/test/web-test-runner.config.js b/test/web-test-runner.config.js new file mode 100644 index 00000000..8604a04d --- /dev/null +++ b/test/web-test-runner.config.js @@ -0,0 +1,52 @@ +import { browserstackLauncher } from '@web/test-runner-browserstack'; + +const sharedBrowserstackCapabilities = { + 'browserstack.user': process.env.BROWSERSTACK_USERNAME, + 'browserstack.key': process.env.BROWSERSTACK_ACCESS_KEY, + + project: `openpgpjs/${process.env.GITHUB_EVENT_NAME || 'push'}${process.env.LIGHTWEIGHT ? '/lightweight' : ''}`, + name: process.env.GITHUB_WORKFLOW, + build: process.env.GITHUB_SHA, + timeout: 450 +}; + +export default { + nodeResolve: true, // to resolve npm module imports in `unittests.html` + files: './test/unittests.html', + + groups: [ + { name: 'local' }, // group meant to be used with either --browser or --manual options via CLI + { + name: 'browserstack', + browsers: process.env.BROWSERSTACK_USERNAME && [ + browserstackLauncher({ + capabilities: { + ...sharedBrowserstackCapabilities, + browserName: 'Safari', + browser_version: 'latest', // Webkit and Safari can differ in behavior + os: 'OS X', + os_version: 'Ventura' + } + }), + browserstackLauncher({ + capabilities: { + ...sharedBrowserstackCapabilities, + browserName: 'Safari', + browser_version: '14', // min supported version + os: 'OS X', + os_version: 'Big Sur' + } + }), + browserstackLauncher({ + capabilities: { + ...sharedBrowserstackCapabilities, + device: 'iPhone 12', + real_mobile: true, + os: 'ios', + os_version: '14' + } + }) + ] + } + ] +}; From ae5698c62171ac50aec93856e04047a1c27b4bc1 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Wed, 18 Sep 2024 12:32:58 +0200 Subject: [PATCH 190/201] CI: fix playwright version parsing Only look at direct dependency --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b61a727d..6744d4dc 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -82,7 +82,7 @@ jobs: - name: Get Playwright version id: playwright-version run: | - PLAYWRIGHT_VERSION=$(npm ls playwright | grep playwright | sed 's/.*@//') + PLAYWRIGHT_VERSION=$(npm ls playwright --depth=0 | grep playwright | sed 's/.*@//') echo "version=$PLAYWRIGHT_VERSION" >> $GITHUB_OUTPUT - name: Check for cached browsers id: cache-playwright-browsers From 4ddadd4f539490ec480dd06f01d39ae0fae1ccb7 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Wed, 9 Oct 2024 17:20:16 +0200 Subject: [PATCH 191/201] CI: setup HTTPS in web-test-runner for BrowserStack tests To have tests work Browserstack Safari (also below iOS 15), as the tests are run in an iframe, rewriting localhost as hostname, making WebCrypto not available. We keep HTTP for the non-browserstack tests so that in local testing, generating self-signed certs is not required. --- .github/workflows/tests.yml | 13 +- README.md | 2 +- package-lock.json | 241 ++++++++++++++++++-- package.json | 6 +- test/web-test-runner.browserstack.config.js | 49 ++++ test/web-test-runner.config.js | 57 ++--- 6 files changed, 305 insertions(+), 63 deletions(-) create mode 100644 test/web-test-runner.browserstack.config.js diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 6744d4dc..9893a7e9 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -100,12 +100,12 @@ jobs: run: npx playwright install --with-deps webkit - name: Run browser tests - run: npm run test-browser -- --static-logging + run: npm run test-browser:ci -- --static-logging - name: Run browser tests (lightweight) # overwrite test/lib run: | npm run build-test --lightweight - npm run test-browser -- --static-logging + npm run test-browser:ci -- --static-logging test-browsers-compatibility: name: Browsers (older, on Browserstack) @@ -119,6 +119,15 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 + - name: Generate self-signed HTTPS certificates for web-test-runner server + uses: kofemann/action-create-certificate@v0.0.4 + with: + hostcert: '127.0.0.1.pem' + hostkey: '127.0.0.1-key.pem' + cachain: 'ca-chain.pem' + - name: Adjust HTTPS certificates permissions + run: sudo chown runner:docker *.pem + - name: Install dependencies run: npm ci --ignore-scripts diff --git a/README.md b/README.md index 2c60f3d2..68bcde05 100644 --- a/README.md +++ b/README.md @@ -667,7 +667,7 @@ To create your own build of the library, just run the following command after cl npm install && npm test -For debugging browser errors, you can run `npm start` and open [`http://localhost:8080/test/unittests.html`](http://localhost:8080/test/unittests.html) in a browser, or run the following command: +For debugging browser errors, run the following command: npm run browsertest diff --git a/package-lock.json b/package-lock.json index 74383bd7..411eef7d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2543,17 +2543,36 @@ "node": ">=18.0.0" } }, - "node_modules/@web/dev-server-core": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/@web/dev-server-core/-/dev-server-core-0.7.2.tgz", - "integrity": "sha512-Q/0jpF13Ipk+qGGQ+Yx/FW1TQBYazpkfgYHHo96HBE7qv4V4KKHqHglZcSUxti/zd4bToxX1cFTz8dmbTlb8JA==", + "node_modules/@web/dev-server-rollup": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@web/dev-server-rollup/-/dev-server-rollup-0.6.4.tgz", + "integrity": "sha512-sJZfTGCCrdku5xYnQQG51odGI092hKY9YFM0X3Z0tRY3iXKXcYRaLZrErw5KfCxr6g0JRuhe4BBhqXTA5Q2I3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/plugin-node-resolve": "^15.0.1", + "@web/dev-server-core": "^0.7.2", + "nanocolors": "^0.2.1", + "parse5": "^6.0.1", + "rollup": "^4.4.0", + "whatwg-url": "^14.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web/dev-server-rollup/node_modules/@web/dev-server-core": { + "name": "@openpgp/wtr-dev-server-core", + "version": "0.7.3-patch.0", + "resolved": "https://registry.npmjs.org/@openpgp/wtr-dev-server-core/-/wtr-dev-server-core-0.7.3-patch.0.tgz", + "integrity": "sha512-f6Vl/ZwvvExZJ9JB5g2nrGbm/H8Uy22zm3nojC/wokuYrPAhW65YMUn4AL5FbmI8Cx+4X1JeEBOfzvTrdeSgWQ==", "dev": true, "license": "MIT", "dependencies": { "@types/koa": "^2.11.6", "@types/ws": "^7.4.0", "@web/parse5-utils": "^2.1.0", - "chokidar": "^3.4.3", + "chokidar": "^4.0.1", "clone": "^2.1.2", "es-module-lexer": "^1.0.0", "get-stream": "^6.0.0", @@ -2567,26 +2586,43 @@ "mime-types": "^2.1.27", "parse5": "^6.0.1", "picomatch": "^2.2.2", - "ws": "^7.4.2" + "ws": "^7.5.10" }, "engines": { "node": ">=18.0.0" } }, - "node_modules/@web/dev-server-core/node_modules/isbinaryfile": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.2.tgz", - "integrity": "sha512-GvcjojwonMjWbTkfMpnVHVqXW/wKMYDfEpY94/8zy8HFMOqb/VL6oeONq9v87q4ttVlaTLnGXnJD4B5B1OTGIg==", + "node_modules/@web/dev-server-rollup/node_modules/chokidar": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", + "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@web/dev-server-rollup/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", "dev": true, "license": "MIT", "engines": { - "node": ">= 18.0.0" + "node": ">= 14.16.0" }, "funding": { - "url": "https://github.com/sponsors/gjtorikian/" + "type": "individual", + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@web/dev-server-core/node_modules/ws": { + "node_modules/@web/dev-server-rollup/node_modules/ws": { "version": "7.5.10", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", @@ -2608,24 +2644,89 @@ } } }, - "node_modules/@web/dev-server-rollup": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/@web/dev-server-rollup/-/dev-server-rollup-0.6.4.tgz", - "integrity": "sha512-sJZfTGCCrdku5xYnQQG51odGI092hKY9YFM0X3Z0tRY3iXKXcYRaLZrErw5KfCxr6g0JRuhe4BBhqXTA5Q2I3Q==", + "node_modules/@web/dev-server/node_modules/@web/dev-server-core": { + "name": "@openpgp/wtr-dev-server-core", + "version": "0.7.3-patch.0", + "resolved": "https://registry.npmjs.org/@openpgp/wtr-dev-server-core/-/wtr-dev-server-core-0.7.3-patch.0.tgz", + "integrity": "sha512-f6Vl/ZwvvExZJ9JB5g2nrGbm/H8Uy22zm3nojC/wokuYrPAhW65YMUn4AL5FbmI8Cx+4X1JeEBOfzvTrdeSgWQ==", "dev": true, "license": "MIT", "dependencies": { - "@rollup/plugin-node-resolve": "^15.0.1", - "@web/dev-server-core": "^0.7.2", - "nanocolors": "^0.2.1", + "@types/koa": "^2.11.6", + "@types/ws": "^7.4.0", + "@web/parse5-utils": "^2.1.0", + "chokidar": "^4.0.1", + "clone": "^2.1.2", + "es-module-lexer": "^1.0.0", + "get-stream": "^6.0.0", + "is-stream": "^2.0.0", + "isbinaryfile": "^5.0.0", + "koa": "^2.13.0", + "koa-etag": "^4.0.0", + "koa-send": "^5.0.1", + "koa-static": "^5.0.0", + "lru-cache": "^8.0.4", + "mime-types": "^2.1.27", "parse5": "^6.0.1", - "rollup": "^4.4.0", - "whatwg-url": "^14.0.0" + "picomatch": "^2.2.2", + "ws": "^7.5.10" }, "engines": { "node": ">=18.0.0" } }, + "node_modules/@web/dev-server/node_modules/chokidar": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", + "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@web/dev-server/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@web/dev-server/node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/@web/parse5-utils": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@web/parse5-utils/-/parse5-utils-2.1.0.tgz", @@ -2757,6 +2858,67 @@ "node": ">=18.0.0" } }, + "node_modules/@web/test-runner-core/node_modules/@web/dev-server-core": { + "name": "@openpgp/wtr-dev-server-core", + "version": "0.7.3-patch.0", + "resolved": "https://registry.npmjs.org/@openpgp/wtr-dev-server-core/-/wtr-dev-server-core-0.7.3-patch.0.tgz", + "integrity": "sha512-f6Vl/ZwvvExZJ9JB5g2nrGbm/H8Uy22zm3nojC/wokuYrPAhW65YMUn4AL5FbmI8Cx+4X1JeEBOfzvTrdeSgWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/koa": "^2.11.6", + "@types/ws": "^7.4.0", + "@web/parse5-utils": "^2.1.0", + "chokidar": "^4.0.1", + "clone": "^2.1.2", + "es-module-lexer": "^1.0.0", + "get-stream": "^6.0.0", + "is-stream": "^2.0.0", + "isbinaryfile": "^5.0.0", + "koa": "^2.13.0", + "koa-etag": "^4.0.0", + "koa-send": "^5.0.1", + "koa-static": "^5.0.0", + "lru-cache": "^8.0.4", + "mime-types": "^2.1.27", + "parse5": "^6.0.1", + "picomatch": "^2.2.2", + "ws": "^7.5.10" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web/test-runner-core/node_modules/@web/dev-server-core/node_modules/chokidar": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", + "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@web/test-runner-core/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@web/test-runner-core/node_modules/source-map": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", @@ -2767,6 +2929,28 @@ "node": ">= 8" } }, + "node_modules/@web/test-runner-core/node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/@web/test-runner-coverage-v8": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@web/test-runner-coverage-v8/-/test-runner-coverage-v8-0.8.0.tgz", @@ -7601,6 +7785,19 @@ "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", "dev": true }, + "node_modules/isbinaryfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.2.tgz", + "integrity": "sha512-GvcjojwonMjWbTkfMpnVHVqXW/wKMYDfEpY94/8zy8HFMOqb/VL6oeONq9v87q4ttVlaTLnGXnJD4B5B1OTGIg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", diff --git a/package.json b/package.json index 4883e418..71397ab0 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,8 @@ "prebrowsertest": "npm run build-test", "browsertest": "web-test-runner --config test/web-test-runner.config.js --group local --manual --open", "test-browser": "web-test-runner --config test/web-test-runner.config.js --group local --playwright --browsers chromium firefox webkit", - "test-browserstack": "web-test-runner --config test/web-test-runner.config.js --group browserstack", + "test-browser:ci": "web-test-runner --config test/web-test-runner.config.js --group headless:ci", + "test-browserstack": "web-test-runner --config test/web-test-runner.browserstack.config.js", "coverage": "c8 npm test", "lint": "eslint .", "docs": "jsdoc --configure .jsdocrc.cjs --destination docs --recurse README.md src && printf '%s' 'docs.openpgpjs.org' > docs/CNAME", @@ -108,6 +109,9 @@ "typescript": "^5.5.4", "web-streams-polyfill": "^4.0.0" }, + "overrides": { + "@web/dev-server-core": "npm:@openpgp/wtr-dev-server-core@0.7.3-patch.0" + }, "repository": { "type": "git", "url": "https://github.com/openpgpjs/openpgpjs" diff --git a/test/web-test-runner.browserstack.config.js b/test/web-test-runner.browserstack.config.js new file mode 100644 index 00000000..1f02314f --- /dev/null +++ b/test/web-test-runner.browserstack.config.js @@ -0,0 +1,49 @@ +import { browserstackLauncher } from '@web/test-runner-browserstack'; +import wtrConfig from './web-test-runner.config.js'; + +const sharedBrowserstackCapabilities = { + 'browserstack.user': process.env.BROWSERSTACK_USERNAME, + 'browserstack.key': process.env.BROWSERSTACK_ACCESS_KEY, + + project: `openpgpjs/${process.env.GITHUB_EVENT_NAME || 'push'}${process.env.LIGHTWEIGHT ? '/lightweight' : ''}`, + name: process.env.GITHUB_WORKFLOW || 'local', + build: process.env.GITHUB_SHA || 'local', + 'browserstack.acceptInsecureCerts': true +}; + +export default { + ...wtrConfig, + protocol: 'https:', + http2: true, + sslKey: './127.0.0.1-key.pem', + sslCert: './127.0.0.1.pem', + testsStartTimeout: 45000, + browserStartTimeout: 120000, + testsFinishTimeout: 450000, + concurrentBrowsers: 3, + concurrency: 1, // see https://github.com/modernweb-dev/web/issues/2706 + coverage: false, + groups: [], // overwrite the field coming from `wrtConfig` + browsers: [ + browserstackLauncher({ + capabilities: { + ...sharedBrowserstackCapabilities, + browserName: 'Safari iOS 14', + device: 'iPhone 12', + real_mobile: true, + os: 'ios', + os_version: '14' // min supported version (iOS/Safari < 14 does not support native BigInts) + } + }), + browserstackLauncher({ + capabilities: { + ...sharedBrowserstackCapabilities, + browserName: 'Safari iOS latest', + device: 'iPhone 16', + real_mobile: true, + os: 'ios', + os_version: 'latest' + } + }) + ] +}; diff --git a/test/web-test-runner.config.js b/test/web-test-runner.config.js index 8604a04d..706a8a05 100644 --- a/test/web-test-runner.config.js +++ b/test/web-test-runner.config.js @@ -1,50 +1,33 @@ -import { browserstackLauncher } from '@web/test-runner-browserstack'; +import { playwrightLauncher } from '@web/test-runner-playwright'; -const sharedBrowserstackCapabilities = { - 'browserstack.user': process.env.BROWSERSTACK_USERNAME, - 'browserstack.key': process.env.BROWSERSTACK_ACCESS_KEY, - - project: `openpgpjs/${process.env.GITHUB_EVENT_NAME || 'push'}${process.env.LIGHTWEIGHT ? '/lightweight' : ''}`, - name: process.env.GITHUB_WORKFLOW, - build: process.env.GITHUB_SHA, - timeout: 450 +const sharedPlaywrightCIOptions = { + // createBrowserContext: ({ browser }) => browser.newContext({ ignoreHTTPSErrors: true }), + headless: true }; export default { nodeResolve: true, // to resolve npm module imports in `unittests.html` files: './test/unittests.html', - + protocol: 'http:', + hostname: '127.0.0.1', + testsStartTimeout: 45000, + browserStartTimeout: 120000, + testsFinishTimeout: 450000, + concurrentBrowsers: 3, + concurrency: 1, // see https://github.com/modernweb-dev/web/issues/2706 + coverage: false, groups: [ { name: 'local' }, // group meant to be used with either --browser or --manual options via CLI { - name: 'browserstack', - browsers: process.env.BROWSERSTACK_USERNAME && [ - browserstackLauncher({ - capabilities: { - ...sharedBrowserstackCapabilities, - browserName: 'Safari', - browser_version: 'latest', // Webkit and Safari can differ in behavior - os: 'OS X', - os_version: 'Ventura' - } + name: 'headless:ci', + browsers: [ + playwrightLauncher({ + ...sharedPlaywrightCIOptions, + product: 'chromium' }), - browserstackLauncher({ - capabilities: { - ...sharedBrowserstackCapabilities, - browserName: 'Safari', - browser_version: '14', // min supported version - os: 'OS X', - os_version: 'Big Sur' - } - }), - browserstackLauncher({ - capabilities: { - ...sharedBrowserstackCapabilities, - device: 'iPhone 12', - real_mobile: true, - os: 'ios', - os_version: '14' - } + playwrightLauncher({ + ...sharedPlaywrightCIOptions, + product: 'firefox' }) ] } From 59c809c943781889ff2eda5912d8988eae9144ef Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Thu, 10 Oct 2024 14:32:54 +0200 Subject: [PATCH 192/201] CI: Browserstack: test only iOS latest and min supported version (iOS 14) Dropping Safari since Web Secure Sockets do not seem to work with the 'networkLogs' capability, which is in turn required for the HTTPS connection to work without insecure certs warnings. --- package.json | 2 +- test/unittests.html | 19 +++++++++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 71397ab0..fe2f311e 100644 --- a/package.json +++ b/package.json @@ -110,7 +110,7 @@ "web-streams-polyfill": "^4.0.0" }, "overrides": { - "@web/dev-server-core": "npm:@openpgp/wtr-dev-server-core@0.7.3-patch.0" + "@web/dev-server-core": "npm:@openpgp/wtr-dev-server-core@0.7.3-patch.1" }, "repository": { "type": "git", diff --git a/test/unittests.html b/test/unittests.html index f8381f7e..23784b22 100644 --- a/test/unittests.html +++ b/test/unittests.html @@ -18,12 +18,19 @@ timeout: 30000 }); - await import('./lib/unittests-bundle.js'); - - // run the tests, and notify the test runner after finishing - mocha.run(() => { - sessionFinished(); - }); + // Safari 14 does not support top-level await + import('./lib/unittests-bundle.js') + .then(() => { + // run the tests, and notify the test runner after finishing + mocha.run(() => { + sessionFinished(); + }); + }) + .catch(err => { + console.error(err); + // notify the test runner about errors + sessionFailed(err); + }); } catch (error) { console.error(error); // notify the test runner about errors From 013dffce707c1560cb6478c6449a6d0bb259773a Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Wed, 23 Oct 2024 17:59:48 +0200 Subject: [PATCH 193/201] CI: test latest Webkit on macOS, as a replacement for testing Safari on Browserstack We were previously testing the webkit engine on Linux, which however relies on a different WebCrypto API implementation compared to the macOS version (behind Safari). Also, increase mocha timeouts, as the argon2 memory-heavy test takes longer in Firefox. --- package-lock.json | 318 +++++++++------------------------ test/unittests.html | 2 +- test/web-test-runner.config.js | 4 + 3 files changed, 89 insertions(+), 235 deletions(-) diff --git a/package-lock.json b/package-lock.json index 411eef7d..f1bb83f4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2543,6 +2543,89 @@ "node": ">=18.0.0" } }, + "node_modules/@web/dev-server-core": { + "name": "@openpgp/wtr-dev-server-core", + "version": "0.7.3-patch.1", + "resolved": "https://registry.npmjs.org/@openpgp/wtr-dev-server-core/-/wtr-dev-server-core-0.7.3-patch.1.tgz", + "integrity": "sha512-aYTXhw5Q9Z4MAbhIi3ty5X+94tU2AnrE3ZYbIXoxWrfLZ3ibUkFQzPaEL0qtD+fARJJ3qBIQHwzJTfhaOm5NyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/koa": "^2.11.6", + "@types/ws": "^7.4.0", + "@web/parse5-utils": "^2.1.0", + "chokidar": "^4.0.1", + "clone": "^2.1.2", + "es-module-lexer": "^1.0.0", + "get-stream": "^6.0.0", + "is-stream": "^2.0.0", + "isbinaryfile": "^5.0.0", + "koa": "^2.13.0", + "koa-etag": "^4.0.0", + "koa-send": "^5.0.1", + "koa-static": "^5.0.0", + "lru-cache": "^8.0.4", + "mime-types": "^2.1.27", + "parse5": "^6.0.1", + "picomatch": "^2.2.2", + "ws": "^7.5.10" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@web/dev-server-core/node_modules/chokidar": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", + "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@web/dev-server-core/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@web/dev-server-core/node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/@web/dev-server-rollup": { "version": "0.6.4", "resolved": "https://registry.npmjs.org/@web/dev-server-rollup/-/dev-server-rollup-0.6.4.tgz", @@ -2561,172 +2644,6 @@ "node": ">=18.0.0" } }, - "node_modules/@web/dev-server-rollup/node_modules/@web/dev-server-core": { - "name": "@openpgp/wtr-dev-server-core", - "version": "0.7.3-patch.0", - "resolved": "https://registry.npmjs.org/@openpgp/wtr-dev-server-core/-/wtr-dev-server-core-0.7.3-patch.0.tgz", - "integrity": "sha512-f6Vl/ZwvvExZJ9JB5g2nrGbm/H8Uy22zm3nojC/wokuYrPAhW65YMUn4AL5FbmI8Cx+4X1JeEBOfzvTrdeSgWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/koa": "^2.11.6", - "@types/ws": "^7.4.0", - "@web/parse5-utils": "^2.1.0", - "chokidar": "^4.0.1", - "clone": "^2.1.2", - "es-module-lexer": "^1.0.0", - "get-stream": "^6.0.0", - "is-stream": "^2.0.0", - "isbinaryfile": "^5.0.0", - "koa": "^2.13.0", - "koa-etag": "^4.0.0", - "koa-send": "^5.0.1", - "koa-static": "^5.0.0", - "lru-cache": "^8.0.4", - "mime-types": "^2.1.27", - "parse5": "^6.0.1", - "picomatch": "^2.2.2", - "ws": "^7.5.10" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@web/dev-server-rollup/node_modules/chokidar": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", - "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "readdirp": "^4.0.1" - }, - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@web/dev-server-rollup/node_modules/readdirp": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", - "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@web/dev-server-rollup/node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/@web/dev-server/node_modules/@web/dev-server-core": { - "name": "@openpgp/wtr-dev-server-core", - "version": "0.7.3-patch.0", - "resolved": "https://registry.npmjs.org/@openpgp/wtr-dev-server-core/-/wtr-dev-server-core-0.7.3-patch.0.tgz", - "integrity": "sha512-f6Vl/ZwvvExZJ9JB5g2nrGbm/H8Uy22zm3nojC/wokuYrPAhW65YMUn4AL5FbmI8Cx+4X1JeEBOfzvTrdeSgWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/koa": "^2.11.6", - "@types/ws": "^7.4.0", - "@web/parse5-utils": "^2.1.0", - "chokidar": "^4.0.1", - "clone": "^2.1.2", - "es-module-lexer": "^1.0.0", - "get-stream": "^6.0.0", - "is-stream": "^2.0.0", - "isbinaryfile": "^5.0.0", - "koa": "^2.13.0", - "koa-etag": "^4.0.0", - "koa-send": "^5.0.1", - "koa-static": "^5.0.0", - "lru-cache": "^8.0.4", - "mime-types": "^2.1.27", - "parse5": "^6.0.1", - "picomatch": "^2.2.2", - "ws": "^7.5.10" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@web/dev-server/node_modules/chokidar": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", - "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "readdirp": "^4.0.1" - }, - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@web/dev-server/node_modules/readdirp": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", - "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@web/dev-server/node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/@web/parse5-utils": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@web/parse5-utils/-/parse5-utils-2.1.0.tgz", @@ -2858,42 +2775,11 @@ "node": ">=18.0.0" } }, - "node_modules/@web/test-runner-core/node_modules/@web/dev-server-core": { - "name": "@openpgp/wtr-dev-server-core", - "version": "0.7.3-patch.0", - "resolved": "https://registry.npmjs.org/@openpgp/wtr-dev-server-core/-/wtr-dev-server-core-0.7.3-patch.0.tgz", - "integrity": "sha512-f6Vl/ZwvvExZJ9JB5g2nrGbm/H8Uy22zm3nojC/wokuYrPAhW65YMUn4AL5FbmI8Cx+4X1JeEBOfzvTrdeSgWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/koa": "^2.11.6", - "@types/ws": "^7.4.0", - "@web/parse5-utils": "^2.1.0", - "chokidar": "^4.0.1", - "clone": "^2.1.2", - "es-module-lexer": "^1.0.0", - "get-stream": "^6.0.0", - "is-stream": "^2.0.0", - "isbinaryfile": "^5.0.0", - "koa": "^2.13.0", - "koa-etag": "^4.0.0", - "koa-send": "^5.0.1", - "koa-static": "^5.0.0", - "lru-cache": "^8.0.4", - "mime-types": "^2.1.27", - "parse5": "^6.0.1", - "picomatch": "^2.2.2", - "ws": "^7.5.10" - }, - "engines": { - "node": ">=18.0.0" - } - }, "node_modules/@web/test-runner-core/node_modules/@web/dev-server-core/node_modules/chokidar": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", - "dev": true, + "extraneous": true, "license": "MIT", "dependencies": { "readdirp": "^4.0.1" @@ -2905,20 +2791,6 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/@web/test-runner-core/node_modules/readdirp": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", - "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@web/test-runner-core/node_modules/source-map": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", @@ -2929,28 +2801,6 @@ "node": ">= 8" } }, - "node_modules/@web/test-runner-core/node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/@web/test-runner-coverage-v8": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@web/test-runner-coverage-v8/-/test-runner-coverage-v8-0.8.0.tgz", diff --git a/test/unittests.html b/test/unittests.html index 23784b22..1e35aa4b 100644 --- a/test/unittests.html +++ b/test/unittests.html @@ -15,7 +15,7 @@ // setup mocha mocha.setup({ ui: 'bdd', - timeout: 30000 + timeout: 45000 }); // Safari 14 does not support top-level await diff --git a/test/web-test-runner.config.js b/test/web-test-runner.config.js index 706a8a05..45e18856 100644 --- a/test/web-test-runner.config.js +++ b/test/web-test-runner.config.js @@ -28,6 +28,10 @@ export default { playwrightLauncher({ ...sharedPlaywrightCIOptions, product: 'firefox' + }), + playwrightLauncher({ + ...sharedPlaywrightCIOptions, + product: 'webkit' }) ] } From 693adb417e14471e7c8e2c7656c4676a22c56e40 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Thu, 24 Oct 2024 20:07:31 +0200 Subject: [PATCH 194/201] CI: run browser tests also on Linux To test platform potential specific code of e.g. the WebCrypto API Testing on Windows would be nice too, but all browsers fail to fetch resources from the web-test-runner server. --- .github/workflows/tests.yml | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 9893a7e9..291c02b3 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -57,8 +57,15 @@ jobs: test-browsers-latest: name: Browsers (latest) - runs-on: ubuntu-latest needs: build + strategy: + fail-fast: false # if tests for one version fail, continue with the rest + matrix: + # run on all main platforms to test platform-specific code, if present + # (e.g. webkit's WebCrypto API implementation is different in macOS vs Linux) + # TODO: windows-latest fails to fetch resources from the wtr server; investigate if the problem is with path declaration or permissions + runner: ['ubuntu-latest', 'macos-latest'] + runs-on: ${{ matrix.runner }} steps: - uses: actions/checkout@v4 @@ -79,17 +86,19 @@ jobs: npm pkg delete scripts.prepare npm ci - - name: Get Playwright version + - name: Get Playwright version and cache location id: playwright-version run: | PLAYWRIGHT_VERSION=$(npm ls playwright --depth=0 | grep playwright | sed 's/.*@//') echo "version=$PLAYWRIGHT_VERSION" >> $GITHUB_OUTPUT + PLAYWRIGHT_CACHE=${{ fromJSON('{"ubuntu-latest": "~/.cache/ms-playwright", "macos-latest": "~/Library/Caches/ms-playwright"}')[matrix.runner] }} + echo "playwright_cache=$PLAYWRIGHT_CACHE" >> $GITHUB_OUTPUT - name: Check for cached browsers id: cache-playwright-browsers uses: actions/cache@v4 with: - path: ~/.cache/ms-playwright - key: playwright-browsers-${{ steps.playwright-version.outputs.version }} + path: ${{ steps.playwright-version.outputs.playwright_cache }} + key: playwright-browsers-${{ matrix.runner }}-${{ steps.playwright-version.outputs.version }} - name: Install browsers if: steps.cache-playwright-browsers.outputs.cache-hit != 'true' run: | From 09095ced4f7fe7a245fba70ddf6640edcd337bda Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Mon, 28 Oct 2024 11:28:59 +0100 Subject: [PATCH 195/201] Run npm update as well as npm audit --- package-lock.json | 593 ++++++++++++++++++++++------------------------ package.json | 20 +- 2 files changed, 294 insertions(+), 319 deletions(-) diff --git a/package-lock.json b/package-lock.json index f1bb83f4..ecfdc9f0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,16 +9,16 @@ "version": "6.0.0-beta.3.patch.1", "license": "LGPL-3.0+", "devDependencies": { - "@noble/ciphers": "^0.6.0", + "@noble/ciphers": "^1.0.0", "@noble/curves": "^1.6.0", "@noble/hashes": "^1.5.0", "@openpgp/jsdoc": "^3.6.11", "@openpgp/seek-bzip": "^1.0.5-git", "@openpgp/tweetnacl": "^1.0.4-1", "@openpgp/web-stream-tools": "~0.1.3", - "@rollup/plugin-alias": "^5.1.0", + "@rollup/plugin-alias": "^5.1.1", "@rollup/plugin-commonjs": "^25.0.8", - "@rollup/plugin-node-resolve": "^15.2.3", + "@rollup/plugin-node-resolve": "^15.3.0", "@rollup/plugin-replace": "^5.0.7", "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-typescript": "^11.1.6", @@ -37,23 +37,23 @@ "chai": "^4.4.1", "chai-as-promised": "^7.1.2", "eckey-utils": "^0.7.14", - "eslint": "^8.57.0", + "eslint": "^8.57.1", "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-airbnb-typescript": "^18.0.0", "eslint-import-resolver-typescript": "^3.6.3", "eslint-plugin-chai-friendly": "^0.7.4", - "eslint-plugin-import": "^2.30.0", + "eslint-plugin-import": "^2.31.0", "eslint-plugin-unicorn": "^48.0.1", "fflate": "^0.7.4", "mocha": "^10.7.3", - "playwright": "^1.47.0", - "rollup": "^4.21.2", + "playwright": "^1.48.2", + "rollup": "^4.24.2", "sinon": "^18.0.1", "ts-node": "^10.9.2", - "tslib": "^2.7.0", - "tsx": "^4.19.0", - "typescript": "^5.5.4", + "tslib": "^2.8.0", + "tsx": "^4.19.2", + "typescript": "^5.6.3", "web-streams-polyfill": "^4.0.0" }, "engines": { @@ -688,10 +688,11 @@ } }, "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", "dev": true, + "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } @@ -704,13 +705,14 @@ "license": "BSD-3-Clause" }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", "deprecated": "Use @eslint/config-array instead", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", + "@humanwhocodes/object-schema": "^2.0.3", "debug": "^4.3.1", "minimatch": "^3.0.5" }, @@ -723,6 +725,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -733,6 +736,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -758,7 +762,8 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", "deprecated": "Use @eslint/object-schema instead", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/@isaacs/cliui": { "version": "8.0.2", @@ -924,10 +929,14 @@ } }, "node_modules/@noble/ciphers": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.6.0.tgz", - "integrity": "sha512-mIbq/R9QXk5/cTfESb1OKtyFnk7oc1Om/8onA1158K9/OZUQFDEVy55jVTato+xmp3XX6F6Qh0zz0Nc1AxAlRQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.0.0.tgz", + "integrity": "sha512-wH5EHOmLi0rEazphPbecAzmjd12I6/Yv/SiHdkA9LSycsQk7RuuTp7am5/o62qYr0RScE7Pc9icXGBbsr6cesA==", "dev": true, + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, "funding": { "url": "https://paulmillr.com/funding/" } @@ -1080,9 +1089,9 @@ } }, "node_modules/@promptbook/utils": { - "version": "0.70.0-1", - "resolved": "https://registry.npmjs.org/@promptbook/utils/-/utils-0.70.0-1.tgz", - "integrity": "sha512-qd2lLRRN+sE6UuNMi2tEeUUeb4zmXnxY5EMdfHVXNE+bqBDpUC7/aEfXgA3jnUXEr+xFjQ8PTFQgWvBMaKvw0g==", + "version": "0.69.5", + "resolved": "https://registry.npmjs.org/@promptbook/utils/-/utils-0.69.5.tgz", + "integrity": "sha512-xm5Ti/Hp3o4xHrsK9Yy3MS6KbDxYbq485hDsFvxqaNA7equHLPdo8H8faTitTeb14QCDfLW4iwCxdVYu5sn6YQ==", "dev": true, "funding": [ { @@ -1096,7 +1105,7 @@ ], "license": "CC-BY-4.0", "dependencies": { - "spacetrim": "0.11.39" + "spacetrim": "0.11.59" } }, "node_modules/@puppeteer/browsers": { @@ -1123,13 +1132,11 @@ } }, "node_modules/@rollup/plugin-alias": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.1.0.tgz", - "integrity": "sha512-lpA3RZ9PdIG7qqhEfv79tBffNaoDuukFDrmhLqg9ifv99u/ehn+lOg30x2zmhf8AQqQUZaMk/B9fZraQ6/acDQ==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.1.1.tgz", + "integrity": "sha512-PR9zDb+rOzkRb2VD+EuKB7UC41vU5DIwZ5qqCpk0KJudcWAyi8rvYOhS7+L5aZCspw1stTViLgN5v6FF1p5cgQ==", "dev": true, - "dependencies": { - "slash": "^4.0.0" - }, + "license": "MIT", "engines": { "node": ">=14.0.0" }, @@ -1168,15 +1175,15 @@ } }, "node_modules/@rollup/plugin-node-resolve": { - "version": "15.2.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz", - "integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==", + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.0.tgz", + "integrity": "sha512-9eO5McEICxMzJpDW9OnMYSv4Sta3hmt7VtBFz5zR9273suNOydOyq/FrGeGy+KsTRFm8w0SLVhzig2ILFT63Ag==", "dev": true, + "license": "MIT", "dependencies": { "@rollup/pluginutils": "^5.0.1", "@types/resolve": "1.20.2", "deepmerge": "^4.2.2", - "is-builtin-module": "^3.2.1", "is-module": "^1.0.0", "resolve": "^1.22.1" }, @@ -1304,208 +1311,252 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.2.tgz", - "integrity": "sha512-fSuPrt0ZO8uXeS+xP3b+yYTCBUd05MoSp2N/MFOgjhhUhMmchXlpTQrTpI8T+YAwAQuK7MafsCOxW7VrPMrJcg==", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.2.tgz", + "integrity": "sha512-ufoveNTKDg9t/b7nqI3lwbCG/9IJMhADBNjjz/Jn6LxIZxD7T5L8l2uO/wD99945F1Oo8FvgbbZJRguyk/BdzA==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.2.tgz", - "integrity": "sha512-xGU5ZQmPlsjQS6tzTTGwMsnKUtu0WVbl0hYpTPauvbRAnmIvpInhJtgjj3mcuJpEiuUw4v1s4BimkdfDWlh7gA==", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.2.tgz", + "integrity": "sha512-iZoYCiJz3Uek4NI0J06/ZxUgwAfNzqltK0MptPDO4OR0a88R4h0DSELMsflS6ibMCJ4PnLvq8f7O1d7WexUvIA==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.2.tgz", - "integrity": "sha512-99AhQ3/ZMxU7jw34Sq8brzXqWH/bMnf7ZVhvLk9QU2cOepbQSVTns6qoErJmSiAvU3InRqC2RRZ5ovh1KN0d0Q==", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.2.tgz", + "integrity": "sha512-/UhrIxobHYCBfhi5paTkUDQ0w+jckjRZDZ1kcBL132WeHZQ6+S5v9jQPVGLVrLbNUebdIRpIt00lQ+4Z7ys4Rg==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.2.tgz", - "integrity": "sha512-ZbRaUvw2iN/y37x6dY50D8m2BnDbBjlnMPotDi/qITMJ4sIxNY33HArjikDyakhSv0+ybdUxhWxE6kTI4oX26w==", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.2.tgz", + "integrity": "sha512-1F/jrfhxJtWILusgx63WeTvGTwE4vmsT9+e/z7cZLKU8sBMddwqw3UV5ERfOV+H1FuRK3YREZ46J4Gy0aP3qDA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ] }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.24.2.tgz", + "integrity": "sha512-1YWOpFcGuC6iGAS4EI+o3BV2/6S0H+m9kFOIlyFtp4xIX5rjSnL3AwbTBxROX0c8yWtiWM7ZI6mEPTI7VkSpZw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.24.2.tgz", + "integrity": "sha512-3qAqTewYrCdnOD9Gl9yvPoAoFAVmPJsBvleabvx4bnu1Kt6DrB2OALeRVag7BdWGWLhP1yooeMLEi6r2nYSOjg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.2.tgz", - "integrity": "sha512-ztRJJMiE8nnU1YFcdbd9BcH6bGWG1z+jP+IPW2oDUAPxPjo9dverIOyXz76m6IPA6udEL12reYeLojzW2cYL7w==", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.2.tgz", + "integrity": "sha512-ArdGtPHjLqWkqQuoVQ6a5UC5ebdX8INPuJuJNWRe0RGa/YNhVvxeWmCTFQ7LdmNCSUzVZzxAvUznKaYx645Rig==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.2.tgz", - "integrity": "sha512-flOcGHDZajGKYpLV0JNc0VFH361M7rnV1ee+NTeC/BQQ1/0pllYcFmxpagltANYt8FYf9+kL6RSk80Ziwyhr7w==", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.2.tgz", + "integrity": "sha512-B6UHHeNnnih8xH6wRKB0mOcJGvjZTww1FV59HqJoTJ5da9LCG6R4SEBt6uPqzlawv1LoEXSS0d4fBlHNWl6iYw==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.2.tgz", - "integrity": "sha512-69CF19Kp3TdMopyteO/LJbWufOzqqXzkrv4L2sP8kfMaAQ6iwky7NoXTp7bD6/irKgknDKM0P9E/1l5XxVQAhw==", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.2.tgz", + "integrity": "sha512-kr3gqzczJjSAncwOS6i7fpb4dlqcvLidqrX5hpGBIM1wtt0QEVtf4wFaAwVv8QygFU8iWUMYEoJZWuWxyua4GQ==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.2.tgz", - "integrity": "sha512-48pD/fJkTiHAZTnZwR0VzHrao70/4MlzJrq0ZsILjLW/Ab/1XlVUStYyGt7tdyIiVSlGZbnliqmult/QGA2O2w==", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.2.tgz", + "integrity": "sha512-TDdHLKCWgPuq9vQcmyLrhg/bgbOvIQ8rtWQK7MRxJ9nvaxKx38NvY7/Lo6cYuEnNHqf6rMqnivOIPIQt6H2AoA==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.2.tgz", - "integrity": "sha512-cZdyuInj0ofc7mAQpKcPR2a2iu4YM4FQfuUzCVA2u4HI95lCwzjoPtdWjdpDKyHxI0UO82bLDoOaLfpZ/wviyQ==", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.2.tgz", + "integrity": "sha512-xv9vS648T3X4AxFFZGWeB5Dou8ilsv4VVqJ0+loOIgDO20zIhYfDLkk5xoQiej2RiSQkld9ijF/fhLeonrz2mw==", "cpu": [ "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.2.tgz", - "integrity": "sha512-RL56JMT6NwQ0lXIQmMIWr1SW28z4E4pOhRRNqwWZeXpRlykRIlEpSWdsgNWJbYBEWD84eocjSGDu/XxbYeCmwg==", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.2.tgz", + "integrity": "sha512-tbtXwnofRoTt223WUZYiUnbxhGAOVul/3StZ947U4A5NNjnQJV5irKMm76G0LGItWs6y+SCjUn/Q0WaMLkEskg==", "cpu": [ "riscv64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.2.tgz", - "integrity": "sha512-PMxkrWS9z38bCr3rWvDFVGD6sFeZJw4iQlhrup7ReGmfn7Oukrr/zweLhYX6v2/8J6Cep9IEA/SmjXjCmSbrMQ==", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.2.tgz", + "integrity": "sha512-gc97UebApwdsSNT3q79glOSPdfwgwj5ELuiyuiMY3pEWMxeVqLGKfpDFoum4ujivzxn6veUPzkGuSYoh5deQ2Q==", "cpu": [ "s390x" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.2.tgz", - "integrity": "sha512-B90tYAUoLhU22olrafY3JQCFLnT3NglazdwkHyxNDYF/zAxJt5fJUB/yBoWFoIQ7SQj+KLe3iL4BhOMa9fzgpw==", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.2.tgz", + "integrity": "sha512-jOG/0nXb3z+EM6SioY8RofqqmZ+9NKYvJ6QQaa9Mvd3RQxlH68/jcB/lpyVt4lCiqr04IyaC34NzhUqcXbB5FQ==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.2.tgz", - "integrity": "sha512-7twFizNXudESmC9oneLGIUmoHiiLppz/Xs5uJQ4ShvE6234K0VB1/aJYU3f/4g7PhssLGKBVCC37uRkkOi8wjg==", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.2.tgz", + "integrity": "sha512-XAo7cJec80NWx9LlZFEJQxqKOMz/lX3geWs2iNT5CHIERLFfd90f3RYLLjiCBm1IMaQ4VOX/lTC9lWfzzQm14Q==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.2.tgz", - "integrity": "sha512-9rRero0E7qTeYf6+rFh3AErTNU1VCQg2mn7CQcI44vNUWM9Ze7MSRS/9RFuSsox+vstRt97+x3sOhEey024FRQ==", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.2.tgz", + "integrity": "sha512-A+JAs4+EhsTjnPQvo9XY/DC0ztaws3vfqzrMNMKlwQXuniBKOIIvAAI8M0fBYiTCxQnElYu7mLk7JrhlQ+HeOw==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.2.tgz", - "integrity": "sha512-5rA4vjlqgrpbFVVHX3qkrCo/fZTj1q0Xxpg+Z7yIo3J2AilW7t2+n6Q8Jrx+4MrYpAnjttTYF8rr7bP46BPzRw==", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.2.tgz", + "integrity": "sha512-ZhcrakbqA1SCiJRMKSU64AZcYzlZ/9M5LaYil9QWxx9vLnkQ9Vnkve17Qn4SjlipqIIBFKjBES6Zxhnvh0EAEw==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.2.tgz", - "integrity": "sha512-6UUxd0+SKomjdzuAcp+HAmxw1FlGBnl1v2yEPSabtx4lBfdXHDVsW7+lQkgz9cNFJGY3AWR7+V8P5BqkD9L9nA==", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.2.tgz", + "integrity": "sha512-2mLH46K1u3r6uwc95hU+OR9q/ggYMpnS7pSp83Ece1HUQgF9Nh/QwTK5rcgbFnV9j+08yBrU5sA/P0RK2MSBNA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -1718,10 +1769,11 @@ "license": "MIT" }, "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" }, "node_modules/@types/express": { "version": "4.17.21", @@ -2170,15 +2222,15 @@ "dev": true }, "node_modules/@wdio/config": { - "version": "8.40.3", - "resolved": "https://registry.npmjs.org/@wdio/config/-/config-8.40.3.tgz", - "integrity": "sha512-HIi+JnHEDAExhzGRQuZOXw1HWIpe/bsVFHwNISJhY6wS4Nijaigmegs2p14Rv16ydOF19hGrxdKsl8k5STIP2A==", + "version": "8.40.6", + "resolved": "https://registry.npmjs.org/@wdio/config/-/config-8.40.6.tgz", + "integrity": "sha512-rHCSmrhdJf7FlidcQPDvRKRPLYjklbrdxQa6J20BxHifTO4h2v23Wrq4OqqYIcq23gf9LpZvCA/PAMiET/QdVg==", "dev": true, "license": "MIT", "dependencies": { "@wdio/logger": "8.38.0", - "@wdio/types": "8.40.3", - "@wdio/utils": "8.40.3", + "@wdio/types": "8.40.6", + "@wdio/utils": "8.40.6", "decamelize": "^6.0.0", "deepmerge-ts": "^5.0.0", "glob": "^10.2.2", @@ -2331,9 +2383,9 @@ } }, "node_modules/@wdio/types": { - "version": "8.40.3", - "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.40.3.tgz", - "integrity": "sha512-zK17uyON3Ise3m+XwiF5VrrdZcXXmvqB8AWXoKe88DiksFUPMVoCOuVL2SSX1KnA2YLlZBA55qcFZT99GORVKQ==", + "version": "8.40.6", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.40.6.tgz", + "integrity": "sha512-ALftLri1BdsRuPrQkuW3evBNdOA5n4IkuoegOw6UE2z+R0f1YI5fHGSHNRWLnhtbOECbGyHXXqzbSxCEb+o+MA==", "dev": true, "license": "MIT", "dependencies": { @@ -2344,15 +2396,15 @@ } }, "node_modules/@wdio/utils": { - "version": "8.40.3", - "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.40.3.tgz", - "integrity": "sha512-pv/848KGfPN3YXU4QRfTYGkAu4/lejIfoGzGpvGNDcACiVxgZhyRZkJ2xVaSnGaXzF0R7pMozrkU5/DnEhcxMg==", + "version": "8.40.6", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.40.6.tgz", + "integrity": "sha512-+TWfV6h+4f8gs7QiYUAWbWEylpZudQ+xkJPN34tRzPJK6dOBYEnIT/j6+1m3j39m1WPDehyYxIf1wCsrGKBxNQ==", "dev": true, "license": "MIT", "dependencies": { "@puppeteer/browsers": "^1.6.0", "@wdio/logger": "8.38.0", - "@wdio/types": "8.40.3", + "@wdio/types": "8.40.6", "decamelize": "^6.0.0", "deepmerge-ts": "^5.1.0", "edgedriver": "^5.5.0", @@ -2434,20 +2486,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@wdio/utils/node_modules/https-proxy-agent": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/@wdio/utils/node_modules/lru-cache": { "version": "7.18.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", @@ -5161,16 +5199,18 @@ } }, "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", @@ -5334,10 +5374,11 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.9.0.tgz", - "integrity": "sha512-McVbYmwA3NEKwRQY5g4aWMdcZE5xZxV8i8l7CqJSrameuGSQJtSWaL/LxTEzSKKaCcOhlpDR8XEfYXWPrdo/ZQ==", + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz", + "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^3.2.7" }, @@ -5372,10 +5413,11 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.30.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.30.0.tgz", - "integrity": "sha512-/mHNE9jINJfiD2EKkg1BKyPyUk4zdnT54YgbOgfjSakWT5oyX/qQLVNTkehyfpcMxZXMy1zyonZ2v7hZTX43Yw==", + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", + "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", "dev": true, + "license": "MIT", "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.8", @@ -5385,7 +5427,7 @@ "debug": "^3.2.7", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.9.0", + "eslint-module-utils": "^2.12.0", "hasown": "^2.0.2", "is-core-module": "^2.15.1", "is-glob": "^4.0.3", @@ -5394,13 +5436,14 @@ "object.groupby": "^1.0.3", "object.values": "^1.2.0", "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.8", "tsconfig-paths": "^3.15.0" }, "engines": { "node": ">=4" }, "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" } }, "node_modules/eslint-plugin-import/node_modules/brace-expansion": { @@ -6235,9 +6278,9 @@ } }, "node_modules/geckodriver": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/geckodriver/-/geckodriver-4.4.4.tgz", - "integrity": "sha512-0zaw19tcmWeluqx7+Y559JGBtidu1D0Lb8ElYKiNEQu8r3sCfrLUf5V10xypl8u29ZLbgRV7WflxCJVTCkCMFA==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/geckodriver/-/geckodriver-4.5.1.tgz", + "integrity": "sha512-lGCRqPMuzbRNDWJOQcUqhNqPvNsIFu6yzXF8J/6K3WCYFd2r5ckbeF7h1cxsnjA7YLSEiWzERCt6/gjZ3tW0ug==", "dev": true, "hasInstallScript": true, "license": "MPL-2.0", @@ -6259,9 +6302,9 @@ } }, "node_modules/geckodriver/node_modules/@wdio/logger": { - "version": "9.0.8", - "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-9.0.8.tgz", - "integrity": "sha512-uIyYIDBwLczmsp9JE5hN3ME8Xg+9WNBfSNXD69ICHrY9WPTzFf94UeTuavK7kwSKF3ro2eJbmNZItYOfnoovnw==", + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-9.1.3.tgz", + "integrity": "sha512-cumRMK/gE1uedBUw3WmWXOQ7HtB6DR8EyKQioUz2P0IJtRRpglMBdZV7Svr3b++WWawOuzZHMfbTkJQmaVt8Gw==", "dev": true, "license": "MIT", "dependencies": { @@ -6274,19 +6317,6 @@ "node": ">=18.20.0" } }, - "node_modules/geckodriver/node_modules/agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/geckodriver/node_modules/ansi-regex": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", @@ -6326,20 +6356,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/geckodriver/node_modules/https-proxy-agent": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/geckodriver/node_modules/isexe": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", @@ -6918,6 +6934,33 @@ "node": ">=10.19.0" } }, + "node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent/node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -8207,9 +8250,9 @@ } }, "node_modules/locate-app": { - "version": "2.4.43", - "resolved": "https://registry.npmjs.org/locate-app/-/locate-app-2.4.43.tgz", - "integrity": "sha512-BX6NEdECUGcDQw8aqqg02qLyF9rF8V+dAfyAnBzL2AofIlIvf4Q6EGXnzVWpWot9uBE+x/o8CjXHo7Zlegu91Q==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/locate-app/-/locate-app-2.5.0.tgz", + "integrity": "sha512-xIqbzPMBYArJRmPGUZD9CzV9wOqmVtQnaAn3wrj3s6WYW0bQvPI7x+sPYUGmDTYMHefVK//zc6HEYZ1qnxIK+Q==", "dev": true, "funding": [ { @@ -8223,19 +8266,19 @@ ], "license": "Apache-2.0", "dependencies": { - "@promptbook/utils": "0.70.0-1", - "type-fest": "2.13.0", - "userhome": "1.0.0" + "@promptbook/utils": "0.69.5", + "type-fest": "4.26.0", + "userhome": "1.0.1" } }, "node_modules/locate-app/node_modules/type-fest": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.13.0.tgz", - "integrity": "sha512-lPfAm42MxE4/456+QyIaaVBAwgpJb6xZ8PRu09utnhPdWwcyj9vgy6Sq0Z5yNbJ21EdxB5dRU/Qg8bsyAMtlcw==", + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.0.tgz", + "integrity": "sha512-OduNjVJsFbifKb57UqZ2EMP1i4u64Xwow3NYXUtBbD4vIwJdQd4+xl8YDou1dlm4DVrtwT/7Ky8z8WyCULVfxw==", "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { - "node": ">=12.20" + "node": ">=16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -9270,20 +9313,6 @@ "node": ">= 14" } }, - "node_modules/pac-proxy-agent/node_modules/https-proxy-agent": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/pac-resolver": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", @@ -9484,13 +9513,13 @@ "dev": true }, "node_modules/playwright": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.47.0.tgz", - "integrity": "sha512-jOWiRq2pdNAX/mwLiwFYnPHpEZ4rM+fRSQpRHwEwZlP2PUANvL3+aJOF/bvISMhFD30rqMxUB4RJx9aQbfh4Ww==", + "version": "1.48.2", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.48.2.tgz", + "integrity": "sha512-NjYvYgp4BPmiwfe31j4gHLa3J7bD2WiBz8Lk2RoSsmX38SVIARZ18VYjxLjAcDsAhA+F4iSEXTSGgjua0rrlgQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.47.0" + "playwright-core": "1.48.2" }, "bin": { "playwright": "cli.js" @@ -9503,9 +9532,9 @@ } }, "node_modules/playwright-core": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.47.0.tgz", - "integrity": "sha512-1DyHT8OqkcfCkYUD9zzUTfg7EfTd+6a8MkD/NWOvjo0u/SCNd5YmY/lJwFvUZOxJbWNds+ei7ic2+R/cRz/PDg==", + "version": "1.48.2", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.48.2.tgz", + "integrity": "sha512-sjjw+qrLFlriJo64du+EK0kJgZzoQPsabGF4lBvsid+3CNIZIYLgnMj9V6JY5VhM2Peh20DJWIVpVljLLnlawA==", "dev": true, "license": "Apache-2.0", "bin": { @@ -9663,20 +9692,6 @@ "node": ">= 14" } }, - "node_modules/proxy-agent/node_modules/https-proxy-agent": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/proxy-agent/node_modules/lru-cache": { "version": "7.18.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", @@ -9738,28 +9753,6 @@ "node": ">=18" } }, - "node_modules/puppeteer-core/node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/qs": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", @@ -10341,12 +10334,13 @@ } }, "node_modules/rollup": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.2.tgz", - "integrity": "sha512-e3TapAgYf9xjdLvKQCkQTnbTKd4a6jwlpQSJJFokHGaX2IVjoEqkIIhiQfqsi0cdwlOD+tQGuOd5AJkc5RngBw==", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.2.tgz", + "integrity": "sha512-do/DFGq5g6rdDhdpPq5qb2ecoczeK6y+2UAjdJ5trjQJj5f1AiVdLRWRc9A9/fFukfvJRgM0UXzxBIYMovm5ww==", "dev": true, + "license": "MIT", "dependencies": { - "@types/estree": "1.0.5" + "@types/estree": "1.0.6" }, "bin": { "rollup": "dist/bin/rollup" @@ -10356,22 +10350,24 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.21.2", - "@rollup/rollup-android-arm64": "4.21.2", - "@rollup/rollup-darwin-arm64": "4.21.2", - "@rollup/rollup-darwin-x64": "4.21.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.21.2", - "@rollup/rollup-linux-arm-musleabihf": "4.21.2", - "@rollup/rollup-linux-arm64-gnu": "4.21.2", - "@rollup/rollup-linux-arm64-musl": "4.21.2", - "@rollup/rollup-linux-powerpc64le-gnu": "4.21.2", - "@rollup/rollup-linux-riscv64-gnu": "4.21.2", - "@rollup/rollup-linux-s390x-gnu": "4.21.2", - "@rollup/rollup-linux-x64-gnu": "4.21.2", - "@rollup/rollup-linux-x64-musl": "4.21.2", - "@rollup/rollup-win32-arm64-msvc": "4.21.2", - "@rollup/rollup-win32-ia32-msvc": "4.21.2", - "@rollup/rollup-win32-x64-msvc": "4.21.2", + "@rollup/rollup-android-arm-eabi": "4.24.2", + "@rollup/rollup-android-arm64": "4.24.2", + "@rollup/rollup-darwin-arm64": "4.24.2", + "@rollup/rollup-darwin-x64": "4.24.2", + "@rollup/rollup-freebsd-arm64": "4.24.2", + "@rollup/rollup-freebsd-x64": "4.24.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.24.2", + "@rollup/rollup-linux-arm-musleabihf": "4.24.2", + "@rollup/rollup-linux-arm64-gnu": "4.24.2", + "@rollup/rollup-linux-arm64-musl": "4.24.2", + "@rollup/rollup-linux-powerpc64le-gnu": "4.24.2", + "@rollup/rollup-linux-riscv64-gnu": "4.24.2", + "@rollup/rollup-linux-s390x-gnu": "4.24.2", + "@rollup/rollup-linux-x64-gnu": "4.24.2", + "@rollup/rollup-linux-x64-musl": "4.24.2", + "@rollup/rollup-win32-arm64-msvc": "4.24.2", + "@rollup/rollup-win32-ia32-msvc": "4.24.2", + "@rollup/rollup-win32-x64-msvc": "4.24.2", "fsevents": "~2.3.2" } }, @@ -10611,18 +10607,6 @@ "url": "https://opencollective.com/sinon" } }, - "node_modules/slash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/slice-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", @@ -10721,9 +10705,9 @@ } }, "node_modules/spacetrim": { - "version": "0.11.39", - "resolved": "https://registry.npmjs.org/spacetrim/-/spacetrim-0.11.39.tgz", - "integrity": "sha512-S/baW29azJ7py5ausQRE2S6uEDQnlxgMHOEEq4V770ooBDD1/9kZnxRcco/tjZYuDuqYXblCk/r3N13ZmvHZ2g==", + "version": "0.11.59", + "resolved": "https://registry.npmjs.org/spacetrim/-/spacetrim-0.11.59.tgz", + "integrity": "sha512-lLYsktklSRKprreOm7NXReW8YiX2VBjbgmXYEziOoGf/qsJqAEACaDvoTtUOycwjpaSh+bT8eu0KrJn7UNxiCg==", "dev": true, "funding": [ { @@ -10735,7 +10719,7 @@ "url": "https://github.com/hejny/spacetrim/blob/main/README.md#%EF%B8%8F-contributing" } ], - "license": "SEE LICENSE IN LICENSE" + "license": "Apache-2.0" }, "node_modules/spdx-correct": { "version": "3.2.0", @@ -11482,10 +11466,11 @@ } }, "node_modules/tslib": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", - "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", - "dev": true + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", + "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==", + "dev": true, + "license": "0BSD" }, "node_modules/tsscmp": { "version": "1.0.6", @@ -11498,10 +11483,11 @@ } }, "node_modules/tsx": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.0.tgz", - "integrity": "sha512-bV30kM7bsLZKZIOCHeMNVMJ32/LuJzLVajkQI/qf92J2Qr08ueLQvW00PUZGiuLPP760UINwupgUj8qrSCPUKg==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.2.tgz", + "integrity": "sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g==", "dev": true, + "license": "MIT", "dependencies": { "esbuild": "~0.23.0", "get-tsconfig": "^4.7.5" @@ -11643,10 +11629,11 @@ "license": "MIT" }, "node_modules/typescript": { - "version": "5.5.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", - "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -11744,10 +11731,11 @@ "license": "MIT" }, "node_modules/userhome": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/userhome/-/userhome-1.0.0.tgz", - "integrity": "sha512-ayFKY3H+Pwfy4W98yPdtH1VqH4psDeyW8lYYFzfecR9d6hqLpqhecktvYR3SEEXt7vG0S1JEpciI3g94pMErig==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/userhome/-/userhome-1.0.1.tgz", + "integrity": "sha512-5cnLm4gseXjAclKowC4IjByaGsjtAoV6PrOQOljplNB54ReUYJP8HdAFq2muHinSDAh09PPX/uXDPfdxRHvuSA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8.0" } @@ -11836,19 +11824,19 @@ } }, "node_modules/webdriver": { - "version": "8.40.3", - "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-8.40.3.tgz", - "integrity": "sha512-mc/pxLpgAQphnIaWvix/QXzp9CJpEvIA3YeF9t5plPaTbvbEaCAYYWkTP6e3vYPYWvx57krjGaYkNUnDCBNolA==", + "version": "8.40.6", + "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-8.40.6.tgz", + "integrity": "sha512-jkslwUvOmqhFfc1E21Tz48NgYD8ykiR+09iWZlVLtx3P43k4jOfS+CfasvQ+6hJiVck+N5dXjYfg6zDjpkIFRw==", "dev": true, "license": "MIT", "dependencies": { "@types/node": "^22.2.0", "@types/ws": "^8.5.3", - "@wdio/config": "8.40.3", + "@wdio/config": "8.40.6", "@wdio/logger": "8.38.0", "@wdio/protocols": "8.40.3", - "@wdio/types": "8.40.3", - "@wdio/utils": "8.40.3", + "@wdio/types": "8.40.6", + "@wdio/utils": "8.40.6", "deepmerge-ts": "^5.1.0", "got": "^12.6.1", "ky": "^0.33.0", @@ -11869,24 +11857,24 @@ } }, "node_modules/webdriverio": { - "version": "8.40.5", - "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.40.5.tgz", - "integrity": "sha512-fKzaAF8lbgVFWIP8i0eGk22MpjactVVTWP8qtUXDob5Kdo8ffrg1lCKP8mcyrz6fiZM1OY1m6dvkbFelf23Nxw==", + "version": "8.40.6", + "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.40.6.tgz", + "integrity": "sha512-hMFYRjVU5Nnk2e9Mi8kDx/IVFMWGaVyDCDpv/SeXXCP17DT9jAZtOWlwGhRaLVikN5JYYuHavHyatVa7gj6QTg==", "dev": true, "license": "MIT", "dependencies": { "@types/node": "^22.2.0", - "@wdio/config": "8.40.3", + "@wdio/config": "8.40.6", "@wdio/logger": "8.38.0", "@wdio/protocols": "8.40.3", "@wdio/repl": "8.40.3", - "@wdio/types": "8.40.3", - "@wdio/utils": "8.40.3", + "@wdio/types": "8.40.6", + "@wdio/utils": "8.40.6", "archiver": "^7.0.0", "aria-query": "^5.0.0", "css-shorthand-properties": "^1.1.1", "css-value": "^0.0.1", - "devtools-protocol": "^0.0.1342118", + "devtools-protocol": "^0.0.1359167", "grapheme-splitter": "^1.0.2", "import-meta-resolve": "^4.0.0", "is-plain-obj": "^4.1.0", @@ -11899,7 +11887,7 @@ "resq": "^1.9.1", "rgb2hex": "0.2.5", "serialize-error": "^11.0.1", - "webdriver": "8.40.3" + "webdriver": "8.40.6" }, "engines": { "node": "^16.13 || >=18" @@ -11981,26 +11969,12 @@ } }, "node_modules/webdriverio/node_modules/devtools-protocol": { - "version": "0.0.1342118", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1342118.tgz", - "integrity": "sha512-75fMas7PkYNDTmDyb6PRJCH7ILmHLp+BhrZGeMsa4bCh40DTxgCz2NRy5UDzII4C5KuD0oBMZ9vXKhEl6UD/3w==", + "version": "0.0.1359167", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1359167.tgz", + "integrity": "sha512-f/9PeTaSH3weS/WAwrQb5/s9R3KMOeTGe+Jkhg5952yInub7iDPjdlzRdrDgpLZfxHbTrBuG9aUkAMM+ocVkXQ==", "dev": true, "license": "BSD-3-Clause" }, - "node_modules/webdriverio/node_modules/https-proxy-agent": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/webdriverio/node_modules/is-plain-obj": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", @@ -12290,10 +12264,11 @@ "dev": true }, "node_modules/ws": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.0.0" }, diff --git a/package.json b/package.json index fe2f311e..7a3810ed 100644 --- a/package.json +++ b/package.json @@ -62,16 +62,16 @@ "postversion": "git push && git push --tags && npm publish" }, "devDependencies": { - "@noble/ciphers": "^0.6.0", + "@noble/ciphers": "^1.0.0", "@noble/curves": "^1.6.0", "@noble/hashes": "^1.5.0", "@openpgp/jsdoc": "^3.6.11", "@openpgp/seek-bzip": "^1.0.5-git", "@openpgp/tweetnacl": "^1.0.4-1", "@openpgp/web-stream-tools": "~0.1.3", - "@rollup/plugin-alias": "^5.1.0", + "@rollup/plugin-alias": "^5.1.1", "@rollup/plugin-commonjs": "^25.0.8", - "@rollup/plugin-node-resolve": "^15.2.3", + "@rollup/plugin-node-resolve": "^15.3.0", "@rollup/plugin-replace": "^5.0.7", "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-typescript": "^11.1.6", @@ -90,23 +90,23 @@ "chai": "^4.4.1", "chai-as-promised": "^7.1.2", "eckey-utils": "^0.7.14", - "eslint": "^8.57.0", + "eslint": "^8.57.1", "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-airbnb-typescript": "^18.0.0", "eslint-import-resolver-typescript": "^3.6.3", "eslint-plugin-chai-friendly": "^0.7.4", - "eslint-plugin-import": "^2.30.0", + "eslint-plugin-import": "^2.31.0", "eslint-plugin-unicorn": "^48.0.1", "fflate": "^0.7.4", "mocha": "^10.7.3", - "playwright": "^1.47.0", - "rollup": "^4.21.2", + "playwright": "^1.48.2", + "rollup": "^4.24.2", "sinon": "^18.0.1", "ts-node": "^10.9.2", - "tslib": "^2.7.0", - "tsx": "^4.19.0", - "typescript": "^5.5.4", + "tslib": "^2.8.0", + "tsx": "^4.19.2", + "typescript": "^5.6.3", "web-streams-polyfill": "^4.0.0" }, "overrides": { From 821f260ba9fe58e622420c74aa8a6508542e80f3 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Mon, 28 Oct 2024 12:33:52 +0100 Subject: [PATCH 196/201] Lightweight build: lazy load bzip decompression lib --- rollup.config.js | 237 ++++++++++++++++++---------------- src/packet/compressed_data.js | 14 +- 2 files changed, 133 insertions(+), 118 deletions(-) diff --git a/rollup.config.js b/rollup.config.js index ca145fc9..f61c53cc 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -23,13 +23,20 @@ const wasmOptions = { browser: { targetEnv: 'browser', maxFileSize: undefined } // always inlline (our wasm files are small) }; -const getChunkFileName = (chunkInfo, extension) => { - // index files result in chunks named simply 'index', so we rename them to include the package name - if (chunkInfo.name === 'index') { - const packageName = chunkInfo.facadeModuleId.split('/').at(-2); // assume index file is under the root folder - return `${packageName}.${extension}`; +const getChunkFileName = (chunkInfo, extension) => `[name].${extension}`; + +/** + * Dynamically imported modules which expose an index file as entrypoint end up with a chunk named `index` + * by default. We want to preserve the module name instead. + */ +const setManualChunkName = chunkId => { + if (chunkId.includes('seek-bzip')) { + return 'seek-bzip'; + } else if (chunkId.includes('argon2id')) { + return 'argon2id'; + } else { + return undefined; } - return `[name].${extension}`; }; const banner = @@ -50,112 +57,120 @@ const terserOptions = { } }; +const nodeBuild = { + input: 'src/index.js', + external: nodeBuiltinModules.concat(nodeDependencies), + output: [ + { file: 'dist/node/openpgp.cjs', format: 'cjs', name: pkg.name, banner, intro }, + { file: 'dist/node/openpgp.min.cjs', format: 'cjs', name: pkg.name, banner, intro, plugins: [terser(terserOptions)], sourcemap: true }, + { file: 'dist/node/openpgp.mjs', format: 'es', banner, intro }, + { file: 'dist/node/openpgp.min.mjs', format: 'es', banner, intro, plugins: [terser(terserOptions)], sourcemap: true } + ].map(options => ({ ...options, inlineDynamicImports: true })), + plugins: [ + resolve({ + exportConditions: ['node'] // needed for resolution of noble-curves import of '@noble/crypto' in Node 18 + }), + typescript({ + compilerOptions: { outDir: './dist/tmp-ts' } + }), + commonjs(), + replace({ + 'OpenPGP.js VERSION': `OpenPGP.js ${pkg.version}` + }), + wasm(wasmOptions.node) + ] +}; + +const fullBrowserBuild = { + input: 'src/index.js', + external: nodeBuiltinModules.concat(nodeDependencies), + output: [ + { file: 'dist/openpgp.js', format: 'iife', name: pkg.name, banner, intro }, + { file: 'dist/openpgp.min.js', format: 'iife', name: pkg.name, banner, intro, plugins: [terser(terserOptions)], sourcemap: true }, + { file: 'dist/openpgp.mjs', format: 'es', banner, intro }, + { file: 'dist/openpgp.min.mjs', format: 'es', banner, intro, plugins: [terser(terserOptions)], sourcemap: true } + ].map(options => ({ ...options, inlineDynamicImports: true })), + plugins: [ + resolve({ + browser: true + }), + typescript({ + compilerOptions: { outDir: './dist/tmp-ts' } // to avoid js files being overwritten + }), + commonjs({ + ignore: nodeBuiltinModules.concat(nodeDependencies) + }), + replace({ + 'OpenPGP.js VERSION': `OpenPGP.js ${pkg.version}`, + "import { createRequire } from 'module';": 'const createRequire = () => () => {}', + delimiters: ['', ''] + }), + wasm(wasmOptions.browser) + ] +}; + +const lightweightBrowserBuild = { + input: 'src/index.js', + external: nodeBuiltinModules.concat(nodeDependencies), + output: [ + { entryFileNames: 'openpgp.mjs', chunkFileNames: chunkInfo => getChunkFileName(chunkInfo, 'mjs') }, + { entryFileNames: 'openpgp.min.mjs', chunkFileNames: chunkInfo => getChunkFileName(chunkInfo, 'min.mjs'), plugins: [terser(terserOptions)], sourcemap: true } + ].map(options => ({ ...options, dir: 'dist/lightweight', manualChunks: setManualChunkName, format: 'es', banner, intro })), + preserveEntrySignatures: 'exports-only', + plugins: [ + resolve({ + browser: true + }), + typescript({ + compilerOptions: { outDir: './dist/lightweight/tmp-ts' } + }), + commonjs({ + ignore: nodeBuiltinModules.concat(nodeDependencies) + }), + replace({ + 'OpenPGP.js VERSION': `OpenPGP.js ${pkg.version}`, + "import { createRequire } from 'module';": 'const createRequire = () => () => {}', + delimiters: ['', ''] + }), + wasm(wasmOptions.browser) + ] +}; + +const testBuild = { + input: 'test/unittests.js', + output: [ + { file: 'test/lib/unittests-bundle.js', format: 'es', intro, sourcemap: true, inlineDynamicImports: true } + ], + external: nodeBuiltinModules.concat(nodeDependencies), + plugins: [ + alias({ + entries: { + openpgp: `./dist/${process.env.npm_config_lightweight ? 'lightweight/' : ''}openpgp.mjs` + } + }), + resolve({ + browser: true + }), + typescript({ + compilerOptions: { outDir: './test/lib/tmp-ts' } + }), + commonjs({ + ignore: nodeBuiltinModules.concat(nodeDependencies), + requireReturnsDefault: 'preferred' + }), + replace({ + "import { createRequire } from 'module';": 'const createRequire = () => () => {}', + delimiters: ['', ''] + }), + wasm(wasmOptions.browser) + ] +}; + export default Object.assign([ - { - input: 'src/index.js', - external: nodeBuiltinModules.concat(nodeDependencies), - output: [ - { file: 'dist/openpgp.js', format: 'iife', name: pkg.name, banner, intro }, - { file: 'dist/openpgp.min.js', format: 'iife', name: pkg.name, banner, intro, plugins: [terser(terserOptions)], sourcemap: true }, - { file: 'dist/openpgp.mjs', format: 'es', banner, intro }, - { file: 'dist/openpgp.min.mjs', format: 'es', banner, intro, plugins: [terser(terserOptions)], sourcemap: true } - ].map(options => ({ ...options, inlineDynamicImports: true })), - plugins: [ - resolve({ - browser: true - }), - typescript({ - compilerOptions: { outDir: './dist/tmp-ts' } // to avoid js files being overwritten - }), - commonjs({ - ignore: nodeBuiltinModules.concat(nodeDependencies) - }), - replace({ - 'OpenPGP.js VERSION': `OpenPGP.js ${pkg.version}`, - "import { createRequire } from 'module';": 'const createRequire = () => () => {}', - delimiters: ['', ''] - }), - wasm(wasmOptions.browser) - ] - }, - { - input: 'src/index.js', - external: nodeBuiltinModules.concat(nodeDependencies), - output: [ - { file: 'dist/node/openpgp.cjs', format: 'cjs', name: pkg.name, banner, intro }, - { file: 'dist/node/openpgp.min.cjs', format: 'cjs', name: pkg.name, banner, intro, plugins: [terser(terserOptions)], sourcemap: true }, - { file: 'dist/node/openpgp.mjs', format: 'es', banner, intro }, - { file: 'dist/node/openpgp.min.mjs', format: 'es', banner, intro, plugins: [terser(terserOptions)], sourcemap: true } - ].map(options => ({ ...options, inlineDynamicImports: true })), - plugins: [ - resolve({ - exportConditions: ['node'] // needed for resolution of noble-curves import of '@noble/crypto' in Node 18 - }), - typescript({ - compilerOptions: { outDir: './dist/tmp-ts' } - }), - commonjs(), - replace({ - 'OpenPGP.js VERSION': `OpenPGP.js ${pkg.version}` - }), - wasm(wasmOptions.node) - ] - }, - { - input: 'src/index.js', - external: nodeBuiltinModules.concat(nodeDependencies), - output: [ - { dir: 'dist/lightweight', entryFileNames: 'openpgp.mjs', chunkFileNames: chunkInfo => getChunkFileName(chunkInfo, 'mjs'), format: 'es', banner, intro }, - { dir: 'dist/lightweight', entryFileNames: 'openpgp.min.mjs', chunkFileNames: chunkInfo => getChunkFileName(chunkInfo, 'min.mjs'), format: 'es', banner, intro, plugins: [terser(terserOptions)], sourcemap: true } - ], - preserveEntrySignatures: 'exports-only', - plugins: [ - resolve({ - browser: true - }), - typescript({ - compilerOptions: { outDir: './dist/lightweight/tmp-ts' } - }), - commonjs({ - ignore: nodeBuiltinModules.concat(nodeDependencies) - }), - replace({ - 'OpenPGP.js VERSION': `OpenPGP.js ${pkg.version}`, - "import { createRequire } from 'module';": 'const createRequire = () => () => {}', - delimiters: ['', ''] - }), - wasm(wasmOptions.browser) - ] - }, - { - input: 'test/unittests.js', - output: [ - { file: 'test/lib/unittests-bundle.js', format: 'es', intro, sourcemap: true, inlineDynamicImports: true } - ], - external: nodeBuiltinModules.concat(nodeDependencies), - plugins: [ - alias({ - entries: { - openpgp: `./dist/${process.env.npm_config_lightweight ? 'lightweight/' : ''}openpgp.mjs` - } - }), - resolve({ - browser: true - }), - typescript({ - compilerOptions: { outDir: './test/lib/tmp-ts' } - }), - commonjs({ - ignore: nodeBuiltinModules.concat(nodeDependencies), - requireReturnsDefault: 'preferred' - }), - replace({ - "import { createRequire } from 'module';": 'const createRequire = () => () => {}', - delimiters: ['', ''] - }), - wasm(wasmOptions.browser) - ] - } + nodeBuild, + fullBrowserBuild, + lightweightBrowserBuild, + testBuild ].filter(config => { config.output = config.output.filter(output => { return (output.file || output.dir + '/' + output.entryFileNames).includes( diff --git a/src/packet/compressed_data.js b/src/packet/compressed_data.js index 9a46cd87..03de3529 100644 --- a/src/packet/compressed_data.js +++ b/src/packet/compressed_data.js @@ -16,7 +16,6 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA import { Inflate, Deflate, Zlib, Unzlib } from 'fflate'; -import { decode as BunzipDecode } from '@openpgp/seek-bzip'; import * as stream from '@openpgp/web-stream-tools'; import enums from '../enums'; import util from '../util'; @@ -108,12 +107,12 @@ class CompressedDataPacket { */ async decompress(config = defaultConfig) { const compressionName = enums.read(enums.compression, this.algorithm); - const decompressionFn = decompress_fns[compressionName]; + const decompressionFn = decompress_fns[compressionName]; // bzip decompression is async if (!decompressionFn) { throw new Error(`${compressionName} decompression not supported`); } - this.packets = await PacketList.fromBinary(decompressionFn(this.compressed), allowedPackets, config); + this.packets = await PacketList.fromBinary(await decompressionFn(this.compressed), allowedPackets, config); } /** @@ -202,9 +201,10 @@ function zlib(compressionStreamInstantiator, ZlibStreamedConstructor) { }; } -function bzip2(func) { - return function(data) { - return stream.fromAsync(async () => func(await stream.readToEnd(data))); +function bzip2Decompress() { + return async function(data) { + const { decode: bunzipDecode } = await import('@openpgp/seek-bzip'); + return stream.fromAsync(async () => bunzipDecode(await stream.readToEnd(data))); }; } @@ -229,6 +229,6 @@ const decompress_fns = { uncompressed: data => data, zip: /*#__PURE__*/ zlib(getCompressionStreamInstantiators('deflate-raw').decompressor, Inflate), zlib: /*#__PURE__*/ zlib(getCompressionStreamInstantiators('deflate').decompressor, Unzlib), - bzip2: /*#__PURE__*/ bzip2(BunzipDecode) + bzip2: /*#__PURE__*/ bzip2Decompress() // NB: async due to dynamic lib import }; From 0138b6935669e9e3f4ebf934202b865de070ffba Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Mon, 28 Oct 2024 13:37:54 +0100 Subject: [PATCH 197/201] CI: update Browserstack project id to include target branch --- test/web-test-runner.browserstack.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/web-test-runner.browserstack.config.js b/test/web-test-runner.browserstack.config.js index 1f02314f..966c4840 100644 --- a/test/web-test-runner.browserstack.config.js +++ b/test/web-test-runner.browserstack.config.js @@ -5,7 +5,7 @@ const sharedBrowserstackCapabilities = { 'browserstack.user': process.env.BROWSERSTACK_USERNAME, 'browserstack.key': process.env.BROWSERSTACK_ACCESS_KEY, - project: `openpgpjs/${process.env.GITHUB_EVENT_NAME || 'push'}${process.env.LIGHTWEIGHT ? '/lightweight' : ''}`, + project: `openpgpjs/${process.env.GITHUB_EVENT_NAME || 'push'}${process.env.LIGHTWEIGHT ? '/lightweight' : ''}@${process.env.GITHUB_REF_NAME}`, name: process.env.GITHUB_WORKFLOW || 'local', build: process.env.GITHUB_SHA || 'local', 'browserstack.acceptInsecureCerts': true From 12274a1543548c39eeb1db068a3d8891ec3cec68 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Mon, 28 Oct 2024 14:08:41 +0100 Subject: [PATCH 198/201] Update README [skip ci] --- README.md | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 68bcde05..deddede6 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -OpenPGP.js [![BrowserStack Status](https://automate.browserstack.com/badge.svg?badge_key=N1l2eHFOanVBMU9wYWxJM3ZnWERnc1lidkt5UkRqa3BralV3SWVhOGpGTT0tLVljSjE4Z3dzVmdiQjl6RWgxb2c3T2c9PQ==--5864052cd523f751b6b907d547ac9c4c5f88c8a3)](https://automate.browserstack.com/public-build/N1l2eHFOanVBMU9wYWxJM3ZnWERnc1lidkt5UkRqa3BralV3SWVhOGpGTT0tLVljSjE4Z3dzVmdiQjl6RWgxb2c3T2c9PQ==--5864052cd523f751b6b907d547ac9c4c5f88c8a3) [![Join the chat on Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/openpgpjs/openpgpjs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +OpenPGP.js [![Join the chat on Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/openpgpjs/openpgpjs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) ========== -[OpenPGP.js](https://openpgpjs.org/) is a JavaScript implementation of the OpenPGP protocol. It implements the [crypto-refresh](https://datatracker.ietf.org/doc/draft-ietf-openpgp-crypto-refresh) (superseding [RFC4880](https://tools.ietf.org/html/rfc4880) and [RFC4880bis](https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-10)). +[OpenPGP.js](https://openpgpjs.org/) is a JavaScript implementation of the OpenPGP protocol. It implements [RFC9580](https://datatracker.ietf.org/doc/rfc9580/) (superseding [RFC4880](https://tools.ietf.org/html/rfc4880) and [RFC4880bis](https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-10)). **Table of Contents** @@ -37,7 +37,8 @@ OpenPGP.js [![BrowserStack Status](https://automate.browserstack.com/badge.svg?b * The `dist/node/openpgp.min.mjs` (or `.cjs`) bundle works in Node.js v18+: it is used by default when you `import ... from 'openpgp'` (resp. `require('openpgp')`). -* Streaming support: the latest versions of Chrome, Firefox, Edge and Safari implement the +* Streaming support: + * in browsers: the latest versions of Chrome, Firefox, Edge and Safari implement the [Streams specification](https://streams.spec.whatwg.org/), including `TransformStream`s. These are needed if you use the library with streamed inputs. In previous versions of OpenPGP.js, WebStreams were automatically polyfilled by the library, @@ -50,14 +51,16 @@ In some edge cases, you might need to use the native object), in which case you should store a reference to it before loading the polyfills. There is also the [web-streams-adapter](https://github.com/MattiasBuelens/web-streams-adapter) library to convert back and forth between them. + * in Node.js: OpenPGP.js v6 no longer supports native Node `Readable` streams in input, and instead expects (and outputs) [Node's WebStreams](https://nodejs.org/api/webstreams.html#class-readablestream). [Node v17+ includes utilities to convert from and to Web Streams](https://nodejs.org/api/stream.html#streamreadabletowebstreamreadable-options). + ### Performance -* Version 3.0.0 of the library introduces support for public-key cryptography using [elliptic curves](https://wiki.gnupg.org/ECC). We use native implementations on browsers and Node.js when available. Elliptic curve cryptography provides stronger security per bits of key, which allows for much faster operations. Currently the following curves are supported: +* Version 3.0.0 of the library introduced support for public-key cryptography using [elliptic curves](https://wiki.gnupg.org/ECC). We use native implementations on browsers and Node.js when available. Compared to RSA, elliptic curve cryptography provides stronger security per bits of key, which allows for much faster operations. Currently the following curves are supported: | Curve | Encryption | Signature | NodeCrypto | WebCrypto | Constant-Time | |:---------------:|:----------:|:---------:|:----------:|:---------:|:-----------------:| - | curve25519 | ECDH | N/A | No | Yes* | If native** | + | curve25519 | ECDH | N/A | No | No | Algorithmically | | ed25519 | N/A | EdDSA | No | Yes* | If native** | | nistP256 | ECDH | ECDSA | Yes* | Yes* | If native** | | nistP384 | ECDH | ECDSA | Yes* | Yes* | If native** | @@ -72,20 +75,17 @@ library to convert back and forth between them. * If the user's browser supports [native WebCrypto](https://caniuse.com/#feat=cryptography) via the `window.crypto.subtle` API, this will be used. Under Node.js the native [crypto module](https://nodejs.org/api/crypto.html#crypto_crypto) is used. -* The library implements authenticated encryption (AEAD) as per the ["crypto refresh" draft standard](https://datatracker.ietf.org/doc/draft-ietf-openpgp-crypto-refresh) using AES-OCB, EAX, or GCM. This makes symmetric encryption faster on platforms with native implementations. However, since the specification is very recent and other OpenPGP implementations are in the process of adopting it, the feature is currently behind a flag. **Note: activating this setting can break compatibility with other OpenPGP implementations which have yet to implement the feature.** You can enable it by setting `openpgp.config.aeadProtect = true`. -Note that this setting has a different effect from the one in OpenPGP.js v6, which implemented support for a provisional version of AEAD from [RFC4880bis](https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-10), which was modified in a later draft of the crypto refresh. +* The library implements authenticated encryption (AEAD) as per [RFC9580](https://datatracker.ietf.org/doc/rfc9580/) using AES-GCM, OCB, or EAX. This makes symmetric encryption faster on platforms with native implementations. However, since the specification is very recent and other OpenPGP implementations are in the process of adopting it, the feature is currently behind a flag. **Note: activating this setting can break compatibility with other OpenPGP implementations which have yet to implement the feature.** You can enable it by setting `openpgp.config.aeadProtect = true`. +Note that this setting has a different effect from the one in OpenPGP.js v5, which implemented support for a provisional version of AEAD from [RFC4880bis](https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-10), which was modified in RFC9580. You can change the AEAD mode by setting one of the following options: ``` - openpgp.config.preferredAEADAlgorithm = openpgp.enums.aead.ocb; // Default (widest ecosystem support), non-native - openpgp.config.preferredAEADAlgorithm = openpgp.enums.aead.gcm; // Native in WebCrypto and Node.js + openpgp.config.preferredAEADAlgorithm = openpgp.enums.aead.gcm; // Default, native in WebCrypto and Node.js + openpgp.config.preferredAEADAlgorithm = openpgp.enums.aead.ocb; // Non-native, but supported across RFC9580 implementations openpgp.config.preferredAEADAlgorithm = openpgp.enums.aead.eax; // Native in Node.js ``` -* For environments that don't provide native crypto, the library falls back to [asm.js](https://caniuse.com/#feat=asmjs) AES and AEAD implementations. - - ### Getting started #### Node.js @@ -386,14 +386,8 @@ Where the value can be any of: })(); ``` -For more information on using ReadableStreams, see [the MDN Documentation on the -Streams API](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API). - -You can also pass a [Node.js `Readable` -stream](https://nodejs.org/api/stream.html#stream_class_stream_readable), in -which case OpenPGP.js will return a Node.js `Readable` stream as well, which you -can `.pipe()` to a `Writable` stream, for example. - +For more information on using ReadableStreams (both in browsers and Node.js), see [the MDN Documentation on the +Streams API](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API) . #### Streaming encrypt and decrypt *String* data with PGP keys From d3e75de23d8dce61d44e6f155303779007810901 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Tue, 29 Oct 2024 18:02:56 +0100 Subject: [PATCH 199/201] `openpgp.encrypt`: use `encryptionKeys` to determine preferred hash algo when signing In `openpgp.sign`, the signing key preferences are considered instead, since no "recipient keys" are available. The hash algo selection logic has been reworked as follows: if `config.preferredHashAlgo` appears in the prefs of all recipients, we pick it; otherwise, we use the strongest supported algo (note: SHA256 is always implicitly supported by all keys), as long as it is compatible with the signing key (e.g. ECC keys require minimum digest sizes). Previously, only the preferences of the signing key were used to determine the hash algo to use, but this is in contrast to the RFC: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.16-2 . Also, an algo stronger than `config.preferredHashAlgo` would be used, if the signing key declared it as first preference. With this change, `config.preferredHashAlgo` is picked even if it's weaker than the preferences of the recipient keys. --- src/cleartext.js | 10 +- src/crypto/public_key/elliptic/eddsa.js | 6 + .../public_key/elliptic/eddsa_legacy.js | 5 + src/key/factory.js | 6 +- src/key/helper.js | 106 ++++++-- src/key/private_key.js | 2 +- src/key/subkey.js | 2 +- src/key/user.js | 4 +- src/message.js | 28 +- src/openpgp.js | 6 +- test/general/key.js | 247 ++++++++++-------- test/general/openpgp.js | 14 +- 12 files changed, 278 insertions(+), 158 deletions(-) diff --git a/src/cleartext.js b/src/cleartext.js index a24f4a3e..61136c28 100644 --- a/src/cleartext.js +++ b/src/cleartext.js @@ -59,20 +59,22 @@ export class CleartextMessage { /** * Sign the cleartext message - * @param {Array} privateKeys - private keys with decrypted secret key data for signing + * @param {Array} signingKeys - private keys with decrypted secret key data for signing + * @param {Array} recipientKeys - recipient keys to get the signing preferences from * @param {Signature} [signature] - Any existing detached signature * @param {Array} [signingKeyIDs] - Array of key IDs to use for signing. Each signingKeyIDs[i] corresponds to privateKeys[i] * @param {Date} [date] - The creation time of the signature that should be created - * @param {Array} [userIDs] - User IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }] + * @param {Array} [signingKeyIDs] - User IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }] + * @param {Array} [recipientUserIDs] - User IDs associated with `recipientKeys` to get the signing preferences from * @param {Array} [notations] - Notation Data to add to the signatures, e.g. [{ name: 'test@example.org', value: new TextEncoder().encode('test'), humanReadable: true, critical: false }] * @param {Object} [config] - Full configuration, defaults to openpgp.config * @returns {Promise} New cleartext message with signed content. * @async */ - async sign(privateKeys, signature = null, signingKeyIDs = [], date = new Date(), userIDs = [], notations = [], config = defaultConfig) { + async sign(signingKeys, recipientKeys = [], signature = null, signingKeyIDs = [], date = new Date(), signingUserIDs = [], recipientUserIDs = [], notations = [], config = defaultConfig) { const literalDataPacket = new LiteralDataPacket(); literalDataPacket.setText(this.text); - const newSignature = new Signature(await createSignaturePackets(literalDataPacket, privateKeys, signature, signingKeyIDs, date, userIDs, notations, true, config)); + const newSignature = new Signature(await createSignaturePackets(literalDataPacket, signingKeys, recipientKeys, signature, signingKeyIDs, date, signingUserIDs, recipientUserIDs, notations, true, config)); return new CleartextMessage(this.text, newSignature); } diff --git a/src/crypto/public_key/elliptic/eddsa.js b/src/crypto/public_key/elliptic/eddsa.js index d22cd8bd..7b41eb23 100644 --- a/src/crypto/public_key/elliptic/eddsa.js +++ b/src/crypto/public_key/elliptic/eddsa.js @@ -82,6 +82,9 @@ export async function generate(algo) { */ export async function sign(algo, hashAlgo, message, publicKey, privateKey, hashed) { if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(getPreferredHashAlgo(algo))) { + // Enforce digest sizes: + // - Ed25519: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.4-4 + // - Ed448: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.5-4 throw new Error('Hash algorithm too weak for EdDSA.'); } switch (algo) { @@ -129,6 +132,9 @@ export async function sign(algo, hashAlgo, message, publicKey, privateKey, hashe */ export async function verify(algo, hashAlgo, { RS }, m, publicKey, hashed) { if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(getPreferredHashAlgo(algo))) { + // Enforce digest sizes: + // - Ed25519: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.4-4 + // - Ed448: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.5-4 throw new Error('Hash algorithm too weak for EdDSA.'); } switch (algo) { diff --git a/src/crypto/public_key/elliptic/eddsa_legacy.js b/src/crypto/public_key/elliptic/eddsa_legacy.js index 28c72d4e..a88e67b4 100644 --- a/src/crypto/public_key/elliptic/eddsa_legacy.js +++ b/src/crypto/public_key/elliptic/eddsa_legacy.js @@ -46,7 +46,9 @@ export async function sign(oid, hashAlgo, message, publicKey, privateKey, hashed const curve = new CurveWithOID(oid); checkPublicPointEnconding(curve, publicKey); if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(enums.hash.sha256)) { + // Enforce digest sizes, since the constraint was already present in RFC4880bis: // see https://tools.ietf.org/id/draft-ietf-openpgp-rfc4880bis-10.html#section-15-7.2 + // and https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.3-3 throw new Error('Hash algorithm too weak for EdDSA.'); } const { RS: signature } = await eddsaSign(enums.publicKey.ed25519, hashAlgo, message, publicKey.subarray(1), privateKey, hashed); @@ -73,6 +75,9 @@ export async function verify(oid, hashAlgo, { r, s }, m, publicKey, hashed) { const curve = new CurveWithOID(oid); checkPublicPointEnconding(curve, publicKey); if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(enums.hash.sha256)) { + // Enforce digest sizes, since the constraint was already present in RFC4880bis: + // see https://tools.ietf.org/id/draft-ietf-openpgp-rfc4880bis-10.html#section-15-7.2 + // and https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.3-3 throw new Error('Hash algorithm too weak for EdDSA.'); } const RS = util.concatUint8Array([r, s]); diff --git a/src/key/factory.js b/src/key/factory.js index e66eaa10..68cdfb95 100644 --- a/src/key/factory.js +++ b/src/key/factory.js @@ -246,7 +246,7 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, conf const signatureProperties = getKeySignatureProperties(); signatureProperties.signatureType = enums.signature.key; - const signaturePacket = await helper.createSignaturePacket(dataToSign, null, secretKeyPacket, signatureProperties, options.date, undefined, undefined, undefined, config); + const signaturePacket = await helper.createSignaturePacket(dataToSign, [], secretKeyPacket, signatureProperties, options.date, undefined, undefined, undefined, config); packetlist.push(signaturePacket); } @@ -262,7 +262,7 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, conf signatureProperties.isPrimaryUserID = true; } - const signaturePacket = await helper.createSignaturePacket(dataToSign, null, secretKeyPacket, signatureProperties, options.date, undefined, undefined, undefined, config); + const signaturePacket = await helper.createSignaturePacket(dataToSign, [], secretKeyPacket, signatureProperties, options.date, undefined, undefined, undefined, config); return { userIDPacket, signaturePacket }; })).then(list => { @@ -286,7 +286,7 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, conf // Add revocation signature packet for creating a revocation certificate. // This packet should be removed before returning the key. const dataToSign = { key: secretKeyPacket }; - packetlist.push(await helper.createSignaturePacket(dataToSign, null, secretKeyPacket, { + packetlist.push(await helper.createSignaturePacket(dataToSign, [], secretKeyPacket, { signatureType: enums.signature.keyRevocation, reasonForRevocationFlag: enums.reasonForRevocation.noReason, reasonForRevocationString: '' diff --git a/src/key/helper.js b/src/key/helper.js index e803acab..cd1643d5 100644 --- a/src/key/helper.js +++ b/src/key/helper.js @@ -90,7 +90,7 @@ export async function createBindingSignature(subkey, primaryKey, options, config const signatureProperties = { signatureType: enums.signature.subkeyBinding }; if (options.sign) { signatureProperties.keyFlags = [enums.keyFlags.signData]; - signatureProperties.embeddedSignature = await createSignaturePacket(dataToSign, null, subkey, { + signatureProperties.embeddedSignature = await createSignaturePacket(dataToSign, [], subkey, { signatureType: enums.signature.keyBinding }, options.date, undefined, undefined, undefined, config); } else { @@ -100,41 +100,95 @@ export async function createBindingSignature(subkey, primaryKey, options, config signatureProperties.keyExpirationTime = options.keyExpirationTime; signatureProperties.keyNeverExpires = false; } - const subkeySignaturePacket = await createSignaturePacket(dataToSign, null, primaryKey, signatureProperties, options.date, undefined, undefined, undefined, config); + const subkeySignaturePacket = await createSignaturePacket(dataToSign, [], primaryKey, signatureProperties, options.date, undefined, undefined, undefined, config); return subkeySignaturePacket; } /** - * Returns the preferred signature hash algorithm of a key - * @param {Key} [key] - The key to get preferences from - * @param {SecretKeyPacket|SecretSubkeyPacket} keyPacket - key packet used for signing + * Returns the preferred signature hash algorithm for a set of keys. + * @param {Array} [targetKeys] - The keys to get preferences from + * @param {SecretKeyPacket|SecretSubkeyPacket} signingKeyPacket - key packet used for signing * @param {Date} [date] - Use the given date for verification instead of the current time - * @param {Object} [userID] - User ID + * @param {Object} [targetUserID] - User IDs corresponding to `targetKeys` to get preferences from * @param {Object} config - full configuration * @returns {Promise} * @async */ -export async function getPreferredHashAlgo(key, keyPacket, date = new Date(), userID = {}, config) { - let hashAlgo = config.preferredHashAlgorithm; - let prefAlgo = hashAlgo; - if (key) { - const selfCertification = await key.getPrimarySelfSignature(date, userID, config); - if (selfCertification.preferredHashAlgorithms) { - [prefAlgo] = selfCertification.preferredHashAlgorithms; - hashAlgo = crypto.hash.getHashByteLength(hashAlgo) <= crypto.hash.getHashByteLength(prefAlgo) ? - prefAlgo : hashAlgo; +export async function getPreferredHashAlgo(targetKeys, signingKeyPacket, date = new Date(), targetUserIDs = [], config) { + /** + * If `preferredSenderAlgo` appears in the prefs of all recipients, we pick it; otherwise, we use the + * strongest supported algo (`defaultAlgo` is always implicitly supported by all keys). + * if no keys are available, `preferredSenderAlgo` is returned. + * For ECC signing key, the curve preferred hash is taken into account as well (see logic below). + */ + const defaultAlgo = enums.hash.sha256; // MUST implement + const preferredSenderAlgo = config.preferredHashAlgorithm; + + const supportedAlgosPerTarget = await Promise.all(targetKeys.map(async (key, i) => { + const selfCertification = await key.getPrimarySelfSignature(date, targetUserIDs[i], config); + const targetPrefs = selfCertification.preferredHashAlgorithms; + return targetPrefs; + })); + const supportedAlgosMap = new Map(); // use Map over object to preserve numeric keys + for (const supportedAlgos of supportedAlgosPerTarget) { + for (const hashAlgo of supportedAlgos) { + try { + // ensure that `hashAlgo` is recognized/implemented by us, otherwise e.g. `getHashByteLength` will throw later on + const supportedAlgo = enums.write(enums.hash, hashAlgo); + supportedAlgosMap.set( + supportedAlgo, + supportedAlgosMap.has(supportedAlgo) ? supportedAlgosMap.get(supportedAlgo) + 1 : 1 + ); + } catch {} } } - switch (keyPacket.algorithm) { - case enums.publicKey.ecdsa: - case enums.publicKey.eddsaLegacy: - case enums.publicKey.ed25519: - case enums.publicKey.ed448: - prefAlgo = crypto.getPreferredCurveHashAlgo(keyPacket.algorithm, keyPacket.publicParams.oid); + const isSupportedHashAlgo = hashAlgo => targetKeys.length === 0 || supportedAlgosMap.get(hashAlgo) === targetKeys.length || hashAlgo === defaultAlgo; + const getStrongestSupportedHashAlgo = () => { + if (supportedAlgosMap.size === 0) { + return defaultAlgo; + } + const sortedHashAlgos = Array.from(supportedAlgosMap.keys()) + .filter(hashAlgo => isSupportedHashAlgo(hashAlgo)) + .sort((algoA, algoB) => crypto.hash.getHashByteLength(algoA) - crypto.hash.getHashByteLength(algoB)); + const strongestHashAlgo = sortedHashAlgos[0]; + // defaultAlgo is always implicilty supported, and might be stronger than the rest + return crypto.hash.getHashByteLength(strongestHashAlgo) >= crypto.hash.getHashByteLength(defaultAlgo) ? strongestHashAlgo : defaultAlgo; + }; + + const eccAlgos = new Set([ + enums.publicKey.ecdsa, + enums.publicKey.eddsaLegacy, + enums.publicKey.ed25519, + enums.publicKey.ed448 + ]); + + if (eccAlgos.has(signingKeyPacket.algorithm)) { + // For ECC, the returned hash algo MUST be at least as strong as `preferredCurveHashAlgo`, see: + // - ECDSA: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.2-5 + // - EdDSALegacy: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.3-3 + // - Ed25519: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.4-4 + // - Ed448: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.5-4 + // Hence, we return the `preferredHashAlgo` as long as it's supported and strong enough; + // Otherwise, we look at the strongest supported algo, and ultimately fallback to the curve + // preferred algo, even if not supported by all targets. + const preferredCurveAlgo = crypto.getPreferredCurveHashAlgo(signingKeyPacket.algorithm, signingKeyPacket.publicParams.oid); + + const preferredSenderAlgoIsSupported = isSupportedHashAlgo(preferredSenderAlgo); + const preferredSenderAlgoStrongerThanCurveAlgo = crypto.hash.getHashByteLength(preferredSenderAlgo) >= crypto.hash.getHashByteLength(preferredCurveAlgo); + + if (preferredSenderAlgoIsSupported && preferredSenderAlgoStrongerThanCurveAlgo) { + return preferredSenderAlgo; + } else { + const strongestSupportedAlgo = getStrongestSupportedHashAlgo(); + return crypto.hash.getHashByteLength(strongestSupportedAlgo) >= crypto.hash.getHashByteLength(preferredCurveAlgo) ? + strongestSupportedAlgo : + preferredCurveAlgo; + } } - return crypto.hash.getHashByteLength(hashAlgo) <= crypto.hash.getHashByteLength(prefAlgo) ? - prefAlgo : hashAlgo; + // `preferredSenderAlgo` may be weaker than the default, but we do not guard against this, + // since it was manually set by the sender. + return isSupportedHashAlgo(preferredSenderAlgo) ? preferredSenderAlgo : getStrongestSupportedHashAlgo(); } /** @@ -205,7 +259,7 @@ export async function getPreferredCipherSuite(keys = [], date = new Date(), user /** * Create signature packet * @param {Object} dataToSign - Contains packets to be signed - * @param {PrivateKey} privateKey - key to get preferences from + * @param {Array} recipientKeys - keys to get preferences from * @param {SecretKeyPacket| * SecretSubkeyPacket} signingKeyPacket secret key packet for signing * @param {Object} [signatureProperties] - Properties to write on the signature packet before signing @@ -216,7 +270,7 @@ export async function getPreferredCipherSuite(keys = [], date = new Date(), user * @param {Object} config - full configuration * @returns {Promise} Signature packet. */ -export async function createSignaturePacket(dataToSign, privateKey, signingKeyPacket, signatureProperties, date, userID, notations = [], detached = false, config) { +export async function createSignaturePacket(dataToSign, recipientKeys, signingKeyPacket, signatureProperties, date, recipientUserIDs, notations = [], detached = false, config) { if (signingKeyPacket.isDummy()) { throw new Error('Cannot sign with a gnu-dummy key.'); } @@ -226,7 +280,7 @@ export async function createSignaturePacket(dataToSign, privateKey, signingKeyPa const signaturePacket = new SignaturePacket(); Object.assign(signaturePacket, signatureProperties); signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm; - signaturePacket.hashAlgorithm = await getPreferredHashAlgo(privateKey, signingKeyPacket, date, userID, config); + signaturePacket.hashAlgorithm = await getPreferredHashAlgo(recipientKeys, signingKeyPacket, date, recipientUserIDs, config); signaturePacket.rawNotations = [...notations]; await signaturePacket.sign(signingKeyPacket, dataToSign, date, detached, config); return signaturePacket; diff --git a/src/key/private_key.js b/src/key/private_key.js index 37cd4588..e82fa118 100644 --- a/src/key/private_key.js +++ b/src/key/private_key.js @@ -206,7 +206,7 @@ class PrivateKey extends PublicKey { } const dataToSign = { key: this.keyPacket }; const key = this.clone(); - key.revocationSignatures.push(await helper.createSignaturePacket(dataToSign, null, this.keyPacket, { + key.revocationSignatures.push(await helper.createSignaturePacket(dataToSign, [], this.keyPacket, { signatureType: enums.signature.keyRevocation, reasonForRevocationFlag: enums.write(enums.reasonForRevocation, reasonForRevocationFlag), reasonForRevocationString diff --git a/src/key/subkey.js b/src/key/subkey.js index 130155a7..49af01b5 100644 --- a/src/key/subkey.js +++ b/src/key/subkey.js @@ -185,7 +185,7 @@ class Subkey { ) { const dataToSign = { key: primaryKey, bind: this.keyPacket }; const subkey = new Subkey(this.keyPacket, this.mainKey); - subkey.revocationSignatures.push(await helper.createSignaturePacket(dataToSign, null, primaryKey, { + subkey.revocationSignatures.push(await helper.createSignaturePacket(dataToSign, [], primaryKey, { signatureType: enums.signature.subkeyRevocation, reasonForRevocationFlag: enums.write(enums.reasonForRevocation, reasonForRevocationFlag), reasonForRevocationString diff --git a/src/key/user.js b/src/key/user.js index 49159c5a..b401a742 100644 --- a/src/key/user.js +++ b/src/key/user.js @@ -72,7 +72,7 @@ class User { throw new Error("The user's own key can only be used for self-certifications"); } const signingKey = await privateKey.getSigningKey(undefined, date, undefined, config); - return createSignaturePacket(dataToSign, privateKey, signingKey.keyPacket, { + return createSignaturePacket(dataToSign, [privateKey], signingKey.keyPacket, { // Most OpenPGP implementations use generic certification (0x10) signatureType: enums.signature.certGeneric, keyFlags: [enums.keyFlags.certifyKeys | enums.keyFlags.signData] @@ -260,7 +260,7 @@ class User { key: primaryKey }; const user = new User(dataToSign.userID || dataToSign.userAttribute, this.mainKey); - user.revocationSignatures.push(await createSignaturePacket(dataToSign, null, primaryKey, { + user.revocationSignatures.push(await createSignaturePacket(dataToSign, [], primaryKey, { signatureType: enums.signature.certRevocation, reasonForRevocationFlag: enums.write(enums.reasonForRevocation, reasonForRevocationFlag), reasonForRevocationString diff --git a/src/message.js b/src/message.js index fb12e8e4..d90efb58 100644 --- a/src/message.js +++ b/src/message.js @@ -496,16 +496,18 @@ export class Message { /** * Sign the message (the literal data packet of the message) * @param {Array} signingKeys - private keys with decrypted secret key data for signing + * @param {Array} recipientKeys - recipient keys to get the signing preferences from * @param {Signature} [signature] - Any existing detached signature to add to the message * @param {Array} [signingKeyIDs] - Array of key IDs to use for signing. Each signingKeyIDs[i] corresponds to signingKeys[i] * @param {Date} [date] - Override the creation time of the signature - * @param {Array} [userIDs] - User IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }] + * @param {Array} [signingUserIDs] - User IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }] + * @param {Array} [recipientUserIDs] - User IDs associated with `recipientKeys` to get the signing preferences from * @param {Array} [notations] - Notation Data to add to the signatures, e.g. [{ name: 'test@example.org', value: new TextEncoder().encode('test'), humanReadable: true, critical: false }] * @param {Object} [config] - Full configuration, defaults to openpgp.config * @returns {Promise} New message with signed content. * @async */ - async sign(signingKeys = [], signature = null, signingKeyIDs = [], date = new Date(), userIDs = [], notations = [], config = defaultConfig) { + async sign(signingKeys = [], recipientKeys = [], signature = null, signingKeyIDs = [], date = new Date(), signingUserIDs = [], recipientUserIDs = [], notations = [], config = defaultConfig) { const packetlist = new PacketList(); const literalDataPacket = this.packets.findPacket(enums.packet.literalData); @@ -513,7 +515,7 @@ export class Message { throw new Error('No literal data packet to sign.'); } - const signaturePackets = await createSignaturePackets(literalDataPacket, signingKeys, signature, signingKeyIDs, date, userIDs, notations, false, config); // this returns the existing signature packets as well + const signaturePackets = await createSignaturePackets(literalDataPacket, signingKeys, recipientKeys, signature, signingKeyIDs, date, signingUserIDs, recipientUserIDs, notations, false, config); // this returns the existing signature packets as well const onePassSignaturePackets = signaturePackets.map( (signaturePacket, i) => OnePassSignaturePacket.fromSignaturePacket(signaturePacket, i === 0)) .reverse(); // innermost OPS refers to the first signature packet @@ -549,21 +551,23 @@ export class Message { /** * Create a detached signature for the message (the literal data packet of the message) * @param {Array} signingKeys - private keys with decrypted secret key data for signing + * @param {Array} recipientKeys - recipient keys to get the signing preferences from * @param {Signature} [signature] - Any existing detached signature * @param {Array} [signingKeyIDs] - Array of key IDs to use for signing. Each signingKeyIDs[i] corresponds to signingKeys[i] * @param {Date} [date] - Override the creation time of the signature - * @param {Array} [userIDs] - User IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }] + * @param {Array} [signingUserIDs] - User IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }] + * @param {Array} [recipientUserIDs] - User IDs associated with `recipientKeys` to get the signing preferences from * @param {Array} [notations] - Notation Data to add to the signatures, e.g. [{ name: 'test@example.org', value: new TextEncoder().encode('test'), humanReadable: true, critical: false }] * @param {Object} [config] - Full configuration, defaults to openpgp.config * @returns {Promise} New detached signature of message content. * @async */ - async signDetached(signingKeys = [], signature = null, signingKeyIDs = [], date = new Date(), userIDs = [], notations = [], config = defaultConfig) { + async signDetached(signingKeys = [], recipientKeys = [], signature = null, signingKeyIDs = [], recipientKeyIDs = [], date = new Date(), userIDs = [], notations = [], config = defaultConfig) { const literalDataPacket = this.packets.findPacket(enums.packet.literalData); if (!literalDataPacket) { throw new Error('No literal data packet to sign.'); } - return new Signature(await createSignaturePackets(literalDataPacket, signingKeys, signature, signingKeyIDs, date, userIDs, notations, true, config)); + return new Signature(await createSignaturePackets(literalDataPacket, signingKeys, recipientKeys, signature, signingKeyIDs, recipientKeyIDs, date, userIDs, notations, true, config)); } /** @@ -698,10 +702,12 @@ export class Message { * Create signature packets for the message * @param {LiteralDataPacket} literalDataPacket - the literal data packet to sign * @param {Array} [signingKeys] - private keys with decrypted secret key data for signing + * @param {Array} [recipientKeys] - recipient keys to get the signing preferences from * @param {Signature} [signature] - Any existing detached signature to append * @param {Array} [signingKeyIDs] - Array of key IDs to use for signing. Each signingKeyIDs[i] corresponds to signingKeys[i] * @param {Date} [date] - Override the creationtime of the signature - * @param {Array} [userIDs] - User IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }] + * @param {Array} [signingUserIDs] - User IDs to sign to, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }] + * @param {Array} [recipientUserIDs] - User IDs associated with `recipientKeys` to get the signing preferences from * @param {Array} [notations] - Notation Data to add to the signatures, e.g. [{ name: 'test@example.org', value: new TextEncoder().encode('test'), humanReadable: true, critical: false }] * @param {Array} [signatureSalts] - A list of signature salts matching the number of signingKeys that should be used for v6 signatures * @param {Boolean} [detached] - Whether to create detached signature packets @@ -710,7 +716,7 @@ export class Message { * @async * @private */ -export async function createSignaturePackets(literalDataPacket, signingKeys, signature = null, signingKeyIDs = [], date = new Date(), userIDs = [], notations = [], detached = false, config = defaultConfig) { +export async function createSignaturePackets(literalDataPacket, signingKeys, recipientKeys = [], signature = null, signingKeyIDs = [], date = new Date(), signingUserIDs = [], recipientUserIDs = [], notations = [], detached = false, config = defaultConfig) { const packetlist = new PacketList(); // If data packet was created from Uint8Array, use binary, otherwise use text @@ -718,12 +724,12 @@ export async function createSignaturePackets(literalDataPacket, signingKeys, sig enums.signature.binary : enums.signature.text; await Promise.all(signingKeys.map(async (primaryKey, i) => { - const userID = userIDs[i]; + const signingUserID = signingUserIDs[i]; if (!primaryKey.isPrivate()) { throw new Error('Need private key for signing'); } - const signingKey = await primaryKey.getSigningKey(signingKeyIDs[i], date, userID, config); - return createSignaturePacket(literalDataPacket, primaryKey, signingKey.keyPacket, { signatureType }, date, userID, notations, detached, config); + const signingKey = await primaryKey.getSigningKey(signingKeyIDs[i], date, signingUserID, config); + return createSignaturePacket(literalDataPacket, recipientKeys.length ? recipientKeys : [primaryKey], signingKey.keyPacket, { signatureType }, date, recipientUserIDs, notations, detached, config); })).then(signatureList => { packetlist.push(...signatureList); }); diff --git a/src/openpgp.js b/src/openpgp.js index 7fd8a938..5237a8f3 100644 --- a/src/openpgp.js +++ b/src/openpgp.js @@ -290,7 +290,7 @@ export async function encrypt({ message, encryptionKeys, signingKeys, passwords, try { if (signingKeys.length || signature) { // sign the message only if signing keys or signature is specified - message = await message.sign(signingKeys, signature, signingKeyIDs, date, signingUserIDs, signatureNotations, config); + message = await message.sign(signingKeys, encryptionKeys, signature, signingKeyIDs, date, signingUserIDs, encryptionKeyIDs, signatureNotations, config); } message = message.compress( await getPreferredCompressionAlgo(encryptionKeys, date, encryptionUserIDs, config), @@ -422,9 +422,9 @@ export async function sign({ message, signingKeys, format = 'armored', detached try { let signature; if (detached) { - signature = await message.signDetached(signingKeys, undefined, signingKeyIDs, date, signingUserIDs, signatureNotations, config); + signature = await message.signDetached(signingKeys, [], undefined, signingKeyIDs, date, signingUserIDs, undefined, signatureNotations, config); } else { - signature = await message.sign(signingKeys, undefined, signingKeyIDs, date, signingUserIDs, signatureNotations, config); + signature = await message.sign(signingKeys, [], undefined, signingKeyIDs, date, signingUserIDs, undefined, signatureNotations, config); } if (format === 'object') return signature; diff --git a/test/general/key.js b/test/general/key.js index 151a7116..ab082354 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -7,7 +7,7 @@ chaiUse(chaiAsPromised); import sinon from 'sinon'; import openpgp from '../initOpenpgp.js'; import util from '../../src/util.js'; -import { getPreferredCipherSuite } from '../../src/key'; +import { getPreferredCipherSuite, getPreferredHashAlgo } from '../../src/key'; import KeyID from '../../src/type/keyid.js'; const priv_key_arm2 = @@ -4136,113 +4136,152 @@ CNa5yq6lyexhsn2Vs8DsX+SOSUyNJiy5FyIJ expect(revKey.armor()).not.to.match(/Comment: This is a revocation certificate/); }); - it('getPreferredCipherSuite - one key', async function() { - const [key1] = await openpgp.readKeys({ armoredKeys: twoKeys }); - const { symmetricAlgo, aeadAlgo } = await getPreferredCipherSuite([key1], undefined, undefined, { - ...openpgp.config, preferredSymmetricAlgorithm: openpgp.enums.symmetric.aes256 + describe('getPreferredCipherSuite()', () => { + it('getPreferredCipherSuite - one key', async function() { + const [key1] = await openpgp.readKeys({ armoredKeys: twoKeys }); + const { symmetricAlgo, aeadAlgo } = await getPreferredCipherSuite([key1], undefined, undefined, { + ...openpgp.config, preferredSymmetricAlgorithm: openpgp.enums.symmetric.aes256 + }); + expect(symmetricAlgo).to.equal(openpgp.enums.symmetric.aes256); + expect(aeadAlgo).to.equal(undefined); + }); + + it('getPreferredCipherSuite - two keys', async function() { + const { aes128, aes192, cast5 } = openpgp.enums.symmetric; + const [key1, key2] = await openpgp.readKeys({ armoredKeys: twoKeys }); + const primaryUser = await key2.getPrimaryUser(); + primaryUser.selfCertification.preferredSymmetricAlgorithms = [6, aes192, cast5]; + const { symmetricAlgo, aeadAlgo } = await getPreferredCipherSuite([key1, key2], undefined, undefined, { + ...openpgp.config, preferredSymmetricAlgorithm: openpgp.enums.symmetric.aes192 + }); + expect(symmetricAlgo).to.equal(aes192); + expect(aeadAlgo).to.equal(undefined); + const { symmetricAlgo: symmetricAlgo2, aeadAlgo: aeadAlgo2 } = await getPreferredCipherSuite([key1, key2], undefined, undefined, { + ...openpgp.config, preferredSymmetricAlgorithm: openpgp.enums.symmetric.aes256 + }); + expect(symmetricAlgo2).to.equal(aes128); + expect(aeadAlgo2).to.equal(undefined); + }); + + it('getPreferredCipherSuite - two keys - one without pref', async function() { + const [key1, key2] = await openpgp.readKeys({ armoredKeys: twoKeys }); + const primaryUser = await key2.getPrimaryUser(); + primaryUser.selfCertification.preferredSymmetricAlgorithms = null; + const { symmetricAlgo, aeadAlgo } = await getPreferredCipherSuite([key1, key2]); + expect(symmetricAlgo).to.equal(openpgp.enums.symmetric.aes128); + expect(aeadAlgo).to.equal(undefined); + }); + + it('getPreferredCipherSuite with AEAD - one key - GCM', async function() { + const [key1] = await openpgp.readKeys({ armoredKeys: twoKeys }); + const primaryUser = await key1.getPrimaryUser(); + primaryUser.selfCertification.features = [9]; // Monkey-patch SEIPDv2 feature flag + primaryUser.selfCertification.preferredCipherSuites = [[9, 3], [9, 2]]; + const { symmetricAlgo, aeadAlgo } = await getPreferredCipherSuite([key1], undefined, undefined, { + ...openpgp.config, + aeadProtect: true, + preferredAEADAlgorithm: openpgp.enums.aead.gcm + }); + expect(symmetricAlgo).to.equal(openpgp.enums.symmetric.aes256); + expect(aeadAlgo).to.equal(openpgp.enums.aead.gcm); + }); + + it('getPreferredCipherSuite with AEAD - one key - AES256-OCB', async function() { + const [key1] = await openpgp.readKeys({ armoredKeys: twoKeys }); + const primaryUser = await key1.getPrimaryUser(); + primaryUser.selfCertification.features = [9]; // Monkey-patch SEIPDv2 feature flag + primaryUser.selfCertification.preferredCipherSuites = [[openpgp.enums.symmetric.aes256, openpgp.enums.aead.ocb]]; + const { symmetricAlgo, aeadAlgo } = await getPreferredCipherSuite([key1], undefined, undefined, { + ...openpgp.config, + aeadProtect: true, + preferredAEADAlgorithm: openpgp.enums.aead.gcm + }); + expect(symmetricAlgo).to.equal(openpgp.enums.symmetric.aes256); + expect(aeadAlgo).to.equal(openpgp.enums.aead.ocb); + }); + + it('getPreferredCipherSuite with AEAD - one key - AES128-GCM', async function() { + const [key1] = await openpgp.readKeys({ armoredKeys: twoKeys }); + const primaryUser = await key1.getPrimaryUser(); + primaryUser.selfCertification.features = [9]; // Monkey-patch SEIPDv2 feature flag + primaryUser.selfCertification.preferredCipherSuites = [[openpgp.enums.symmetric.aes128, openpgp.enums.aead.gcm]]; + const { symmetricAlgo, aeadAlgo } = await getPreferredCipherSuite([key1], undefined, undefined, { + ...openpgp.config, + aeadProtect: true, + preferredAEADAlgorithm: openpgp.enums.aead.gcm + }); + expect(symmetricAlgo).to.equal(openpgp.enums.symmetric.aes128); + expect(aeadAlgo).to.equal(openpgp.enums.aead.gcm); + }); + + it('getPreferredCipherSuite with AEAD - two keys - one without pref', async function() { + const keys = await openpgp.readKeys({ armoredKeys: twoKeys }); + const key1 = keys[0]; + const key2 = keys[1]; + const primaryUser = await key1.getPrimaryUser(); + primaryUser.selfCertification.features = [9]; // Monkey-patch SEIPDv2 feature flag + primaryUser.selfCertification.preferredCipherSuites = [[9, 3], [9, 2]]; + const primaryUser2 = await key2.getPrimaryUser(); + primaryUser2.selfCertification.features = [9]; // Monkey-patch SEIPDv2 feature flag + const { symmetricAlgo, aeadAlgo } = await getPreferredCipherSuite([key1, key2], undefined, undefined, { + ...openpgp.config, + aeadProtect: true + }); + expect(symmetricAlgo).to.equal(openpgp.enums.symmetric.aes128); + expect(aeadAlgo).to.equal(openpgp.enums.aead.ocb); + }); + + it('getPreferredCipherSuite with AEAD - two keys - one with no support', async function() { + const keys = await openpgp.readKeys({ armoredKeys: twoKeys }); + const key1 = keys[0]; + const key2 = keys[1]; + const primaryUser = await key1.getPrimaryUser(); + primaryUser.selfCertification.features = [9]; // Monkey-patch SEIPDv2 feature flag + primaryUser.selfCertification.preferredCipherSuites = [[9, 3], [9, 2]]; + const { symmetricAlgo, aeadAlgo } = await getPreferredCipherSuite([key1, key2], undefined, undefined, { + ...openpgp.config, + aeadProtect: true + }); + expect(symmetricAlgo).to.equal(openpgp.enums.symmetric.aes256); + expect(aeadAlgo).to.equal(undefined); }); - expect(symmetricAlgo).to.equal(openpgp.enums.symmetric.aes256); - expect(aeadAlgo).to.equal(undefined); }); - it('getPreferredCipherSuite - two keys', async function() { - const { aes128, aes192, cast5 } = openpgp.enums.symmetric; - const [key1, key2] = await openpgp.readKeys({ armoredKeys: twoKeys }); - const primaryUser = await key2.getPrimaryUser(); - primaryUser.selfCertification.preferredSymmetricAlgorithms = [6, aes192, cast5]; - const { symmetricAlgo, aeadAlgo } = await getPreferredCipherSuite([key1, key2], undefined, undefined, { - ...openpgp.config, preferredSymmetricAlgorithm: openpgp.enums.symmetric.aes192 - }); - expect(symmetricAlgo).to.equal(aes192); - expect(aeadAlgo).to.equal(undefined); - const { symmetricAlgo: symmetricAlgo2, aeadAlgo: aeadAlgo2 } = await getPreferredCipherSuite([key1, key2], undefined, undefined, { - ...openpgp.config, preferredSymmetricAlgorithm: openpgp.enums.symmetric.aes256 - }); - expect(symmetricAlgo2).to.equal(aes128); - expect(aeadAlgo2).to.equal(undefined); - }); + describe('getPreferredHashAlgo()', () => { + it('getPreferredHashAlgo - it can handle unknown hash algorithms', async function() { + // Preferred hash algo: SHA256 and unknown algo with ID '99' + const signingKeyWithUnknownAlgoPref = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- - it('getPreferredCipherSuite - two keys - one without pref', async function() { - const [key1, key2] = await openpgp.readKeys({ armoredKeys: twoKeys }); - const primaryUser = await key2.getPrimaryUser(); - primaryUser.selfCertification.preferredSymmetricAlgorithms = null; - const { symmetricAlgo, aeadAlgo } = await getPreferredCipherSuite([key1, key2]); - expect(symmetricAlgo).to.equal(openpgp.enums.symmetric.aes128); - expect(aeadAlgo).to.equal(undefined); - }); - - it('getPreferredCipherSuite with AEAD - one key - GCM', async function() { - const [key1] = await openpgp.readKeys({ armoredKeys: twoKeys }); - const primaryUser = await key1.getPrimaryUser(); - primaryUser.selfCertification.features = [9]; // Monkey-patch SEIPDv2 feature flag - primaryUser.selfCertification.preferredCipherSuites = [[9, 3], [9, 2]]; - const { symmetricAlgo, aeadAlgo } = await getPreferredCipherSuite([key1], undefined, undefined, { - ...openpgp.config, - aeadProtect: true, - preferredAEADAlgorithm: openpgp.enums.aead.gcm +xVgEZyJrexYJKwYBBAHaRw8BAQdAJwddYhjAmI6OzqxkW9cAXVBfZdSFxsaZ +0v9YAJA50fQAAQCK5y2PWn5MEoWnMre7WDMCv3HPs92No9r7ZrmXED3ZohDT +zQ48dGVzdEB0ZXN0Lml0PsLAEQQTFgoAgwWCZyJrewMLCQcJkPu0BwaBSfbo +RRQAAAAAABwAIHNhbHRAbm90YXRpb25zLm9wZW5wZ3Bqcy5vcmdJHbHl9Kh1 +AmD2A1I0IgJEsWl12eWrRzU2C5MilKZDXQMVCGMEFgACAQIZAQKbAwIeARYh +BDc1TCI+j6hTVaLvtfu0BwaBSfboAAA3cwEAwA/JVtszZ1PgowLYG2/ok+WL ++AcEbvhPBBoJV6B2gLsA/2S/WIFiNLJd9xVPCsnlsh6GSqjNjEYXZIag0u14 +WoEKx10EZyJrexIKKwYBBAGXVQEFAQEHQEnAXen/dnz9PZ+oJ9BYrDV+N/6y +c5nTJbTmMj01obBBAwEIBwAA/0izDCturSN2513OhRlrHc55biP/GL2CR6LK +e3Zo4XCoEFDCvgQYFgoAcAWCZyJrewmQ+7QHBoFJ9uhFFAAAAAAAHAAgc2Fs +dEBub3RhdGlvbnMub3BlbnBncGpzLm9yZ6bxx8jT55ZC4ZuKBMyd1j0ULyQ4 +PPAbypPTzwI7bN7zApsMFiEENzVMIj6PqFNVou+1+7QHBoFJ9ugAAPRMAP9k +45AQSzIKF8JmS28I8hSUDrPCjSVh1A3Aw01F6sRYLgEA1wq81Sxnmvo6ztxK +EVdFOaJsHYaJ0A23hIaCWML5nAs= +=jJaL +-----END PGP PRIVATE KEY BLOCK----- +` }); + const config = { + ...openpgp.config, + preferredHashAlgorithm: openpgp.enums.hash.sha512 // SHA512 is not in the key prefs + }; + const hashAlgo = await getPreferredHashAlgo( + [signingKeyWithUnknownAlgoPref], + signingKeyWithUnknownAlgoPref, + undefined, + undefined, + config + ); + expect(hashAlgo).to.equal(openpgp.enums.hash.sha256); }); - expect(symmetricAlgo).to.equal(openpgp.enums.symmetric.aes256); - expect(aeadAlgo).to.equal(openpgp.enums.aead.gcm); - }); - - it('getPreferredCipherSuite with AEAD - one key - AES256-OCB', async function() { - const [key1] = await openpgp.readKeys({ armoredKeys: twoKeys }); - const primaryUser = await key1.getPrimaryUser(); - primaryUser.selfCertification.features = [9]; // Monkey-patch SEIPDv2 feature flag - primaryUser.selfCertification.preferredCipherSuites = [[openpgp.enums.symmetric.aes256, openpgp.enums.aead.ocb]]; - const { symmetricAlgo, aeadAlgo } = await getPreferredCipherSuite([key1], undefined, undefined, { - ...openpgp.config, - aeadProtect: true, - preferredAEADAlgorithm: openpgp.enums.aead.gcm - }); - expect(symmetricAlgo).to.equal(openpgp.enums.symmetric.aes256); - expect(aeadAlgo).to.equal(openpgp.enums.aead.ocb); - }); - - it('getPreferredCipherSuite with AEAD - one key - AES128-GCM', async function() { - const [key1] = await openpgp.readKeys({ armoredKeys: twoKeys }); - const primaryUser = await key1.getPrimaryUser(); - primaryUser.selfCertification.features = [9]; // Monkey-patch SEIPDv2 feature flag - primaryUser.selfCertification.preferredCipherSuites = [[openpgp.enums.symmetric.aes128, openpgp.enums.aead.gcm]]; - const { symmetricAlgo, aeadAlgo } = await getPreferredCipherSuite([key1], undefined, undefined, { - ...openpgp.config, - aeadProtect: true, - preferredAEADAlgorithm: openpgp.enums.aead.gcm - }); - expect(symmetricAlgo).to.equal(openpgp.enums.symmetric.aes128); - expect(aeadAlgo).to.equal(openpgp.enums.aead.gcm); - }); - - it('getPreferredCipherSuite with AEAD - two keys - one without pref', async function() { - const keys = await openpgp.readKeys({ armoredKeys: twoKeys }); - const key1 = keys[0]; - const key2 = keys[1]; - const primaryUser = await key1.getPrimaryUser(); - primaryUser.selfCertification.features = [9]; // Monkey-patch SEIPDv2 feature flag - primaryUser.selfCertification.preferredCipherSuites = [[9, 3], [9, 2]]; - const primaryUser2 = await key2.getPrimaryUser(); - primaryUser2.selfCertification.features = [9]; // Monkey-patch SEIPDv2 feature flag - const { symmetricAlgo, aeadAlgo } = await getPreferredCipherSuite([key1, key2], undefined, undefined, { - ...openpgp.config, - aeadProtect: true - }); - expect(symmetricAlgo).to.equal(openpgp.enums.symmetric.aes128); - expect(aeadAlgo).to.equal(openpgp.enums.aead.ocb); - }); - - it('getPreferredCipherSuite with AEAD - two keys - one with no support', async function() { - const keys = await openpgp.readKeys({ armoredKeys: twoKeys }); - const key1 = keys[0]; - const key2 = keys[1]; - const primaryUser = await key1.getPrimaryUser(); - primaryUser.selfCertification.features = [9]; // Monkey-patch SEIPDv2 feature flag - primaryUser.selfCertification.preferredCipherSuites = [[9, 3], [9, 2]]; - const { symmetricAlgo, aeadAlgo } = await getPreferredCipherSuite([key1, key2], undefined, undefined, { - ...openpgp.config, - aeadProtect: true - }); - expect(symmetricAlgo).to.equal(openpgp.enums.symmetric.aes256); - expect(aeadAlgo).to.equal(undefined); }); it('User attribute packet read & write', async function() { @@ -4343,7 +4382,7 @@ VYGdb3eNlV8CfoEC privateKey.users[0].userID = openpgp.UserIDPacket.fromObject({ name: 'Test User', email: 'b@c.com' }); // Set second user to prefer aes128. We will select this user. privateKey.users[1].selfCertifications[0].preferredHashAlgorithms = [openpgp.enums.hash.sha512]; - const config = { minRSABits: 1024 }; + const config = { minRSABits: 1024, preferredHashAlgorithm: openpgp.enums.hash.sha512 }; const signed = await openpgp.sign({ message: await openpgp.createMessage({ text: 'hello' }), signingKeys: privateKey, signingUserIDs: { name: 'Test McTestington', email: 'test@example.com' }, format: 'binary', config }); diff --git a/test/general/openpgp.js b/test/general/openpgp.js index c141206e..1f2d6438 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -297,7 +297,7 @@ DECl1Qu4QyeXin29uEXWiekMpNlZVsEuc8icCw6ABhIZ =/7PI -----END PGP PRIVATE KEY BLOCK-----`; -const priv_key_sha3 = `-----BEGIN PGP PRIVATE KEY BLOCK----- +const priv_key_sha3_512 = `-----BEGIN PGP PRIVATE KEY BLOCK----- xUsGZN8edBsAAAAgdUMlFMFCVKNo7sdUd6FVBos6NNjpUpSdrodk6BfPb/kA+3bu A2+WY2LwyxlX5o07WR2VSn+wuegC3v28yO0tClHCtwYfGw4AAABIBYJk3x50BAsJ @@ -1957,8 +1957,8 @@ aOU= })).to.be.rejectedWith(/No signing keys provided/); }); - it('Signing with key which uses sha3 should generate a valid sha3 signature', async function() { - const privKey = await openpgp.readKey({ armoredKey: priv_key_sha3 }); + it('Signing with key which uses sha3 should generate a valid sha3 signature if `config.preferredHashAlgorithm` has been set accordingly', async function() { + const privKey = await openpgp.readKey({ armoredKey: priv_key_sha3_512 }); const pubKey = privKey.toPublic(); const text = 'Hello, world.'; const message = await openpgp.createCleartextMessage({ text }); @@ -1968,10 +1968,18 @@ aOU= expect(parsedArmored.signature.packets.filterByTag(openpgp.enums.packet.signature)).to.have.length(1); expect( parsedArmored.signature.packets.filterByTag(openpgp.enums.packet.signature)[0].hashAlgorithm + ).to.equal(openpgp.config.preferredHashAlgorithm); + const cleartextMessageWithSHA3 = await openpgp.sign({ message, signingKeys: privKey, format: 'armored', config: { preferredHashAlgorithm: openpgp.enums.hash.sha3_512 } }); + const parsedArmoredSHA3 = await openpgp.readCleartextMessage({ cleartextMessage: cleartextMessageWithSHA3 }); + expect(parsedArmoredSHA3.signature.packets.filterByTag(openpgp.enums.packet.signature)).to.have.length(1); + expect( + parsedArmoredSHA3.signature.packets.filterByTag(openpgp.enums.packet.signature)[0].hashAlgorithm ).to.equal(openpgp.enums.hash.sha3_512); const verified = await openpgp.verify({ message: parsedArmored, verificationKeys: pubKey, expectSigned: true }); + const verifiedSHA3 = await openpgp.verify({ message: parsedArmoredSHA3, verificationKeys: pubKey, expectSigned: true }); expect(verified.data).to.equal(text); + expect(verifiedSHA3.data).to.equal(text); }); it('should output cleartext message of expected format', async function() { From f9a3e54364437d15c77c2fcca1c2255ad3a2add3 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Tue, 29 Oct 2024 18:16:40 +0100 Subject: [PATCH 200/201] `openpgp.sign`: add `recipientKeys` option to get the signing prefs from If given, the signature will be generated using the preferred hash algo from the recipient keys. Otherwise, the signing key preferences are used (this was also the existing behavior). Note: when signing through `openpgp.encrypt`, the `encryptionKeys` are automatically used as recipient keys. --- src/openpgp.js | 10 ++++++---- test/general/openpgp.js | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/openpgp.js b/src/openpgp.js index 5237a8f3..22ac9077 100644 --- a/src/openpgp.js +++ b/src/openpgp.js @@ -392,21 +392,23 @@ export async function decrypt({ message, decryptionKeys, passwords, sessionKeys, * @param {Object} options * @param {CleartextMessage|Message} options.message - (cleartext) message to be signed * @param {PrivateKey|PrivateKey[]} options.signingKeys - Array of keys or single key with decrypted secret key data to sign cleartext + * @param {Key|Key[]} options.recipientKeys - Array of keys or single to get the signing preferences from * @param {'armored'|'binary'|'object'} [options.format='armored'] - Format of the returned message * @param {Boolean} [options.detached=false] - If the return value should contain a detached signature * @param {KeyID|KeyID[]} [options.signingKeyIDs=latest-created valid signing (sub)keys] - Array of key IDs to use for signing. Each signingKeyIDs[i] corresponds to signingKeys[i] * @param {Date} [options.date=current date] - Override the creation date of the signature * @param {Object|Object[]} [options.signingUserIDs=primary user IDs] - Array of user IDs to sign with, one per key in `signingKeys`, e.g. `[{ name: 'Steve Sender', email: 'steve@openpgp.org' }]` + * @param {Object|Object[]} [options.recipientUserIDs=primary user IDs] - Array of user IDs to get the signing preferences from, one per key in `recipientKeys` * @param {Object|Object[]} [options.signatureNotations=[]] - Array of notations to add to the signatures, e.g. `[{ name: 'test@example.org', value: new TextEncoder().encode('test'), humanReadable: true, critical: false }]` * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config} * @returns {Promise>} Signed message (string if `armor` was true, the default; Uint8Array if `armor` was false). * @async * @static */ -export async function sign({ message, signingKeys, format = 'armored', detached = false, signingKeyIDs = [], date = new Date(), signingUserIDs = [], signatureNotations = [], config, ...rest }) { +export async function sign({ message, signingKeys, recipientKeys = [], format = 'armored', detached = false, signingKeyIDs = [], date = new Date(), signingUserIDs = [], recipientUserIDs = [], signatureNotations = [], config, ...rest }) { config = { ...defaultConfig, ...config }; checkConfig(config); checkCleartextOrMessage(message); checkOutputMessageFormat(format); - signingKeys = toArray(signingKeys); signingKeyIDs = toArray(signingKeyIDs); signingUserIDs = toArray(signingUserIDs); signatureNotations = toArray(signatureNotations); + signingKeys = toArray(signingKeys); signingKeyIDs = toArray(signingKeyIDs); signingUserIDs = toArray(signingUserIDs); recipientKeys = toArray(recipientKeys); recipientUserIDs = toArray(recipientUserIDs); signatureNotations = toArray(signatureNotations); if (rest.privateKeys) throw new Error('The `privateKeys` option has been removed from openpgp.sign, pass `signingKeys` instead'); if (rest.armor !== undefined) throw new Error('The `armor` option has been removed from openpgp.sign, pass `format` instead.'); @@ -422,9 +424,9 @@ export async function sign({ message, signingKeys, format = 'armored', detached try { let signature; if (detached) { - signature = await message.signDetached(signingKeys, [], undefined, signingKeyIDs, date, signingUserIDs, undefined, signatureNotations, config); + signature = await message.signDetached(signingKeys, recipientKeys, undefined, signingKeyIDs, date, signingUserIDs, recipientUserIDs, signatureNotations, config); } else { - signature = await message.sign(signingKeys, [], undefined, signingKeyIDs, date, signingUserIDs, undefined, signatureNotations, config); + signature = await message.sign(signingKeys, recipientKeys, undefined, signingKeyIDs, date, signingUserIDs, recipientUserIDs, signatureNotations, config); } if (format === 'object') return signature; diff --git a/test/general/openpgp.js b/test/general/openpgp.js index 1f2d6438..3d380d92 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -2162,6 +2162,47 @@ aOU= }); expect(await stream.readToEnd(streamedData)).to.equal(text); }); + + it('should sign using hash algorithm preferred by `recipientKeys` if given', async function() { + const signingKeyWithoutSHA3Pref = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- + +xVgEZyID/RYJKwYBBAHaRw8BAQdAcdaUl/UXEQaT6rKNSEPmyKypikz9rIsf +BlFAQYjtsF8AAQDiW9ls2uBBRa3vA1Odl0NNNguRBolWhR9XGpdXnVBF3w5E +zQ48dGVzdEB0ZXN0Lml0PsLAEQQTFgoAgwWCZyID/QMLCQcJkJuH6wXn78D5 +RRQAAAAAABwAIHNhbHRAbm90YXRpb25zLm9wZW5wZ3Bqcy5vcmcNolfauRaj +NnItFJ0TOsiyZZhd6bMWVR4032v64tYRywMVCAoEFgACAQIZAQKbAwIeARYh +BGsOUiBRfu57iwuxh5uH6wXn78D5AACEQQEAz4YXoEKgOElvxRrIrkglUlpb +ilLZVU6mXqLxRSEtZi0BAK5xooNiLYbjF42eJuCDWUWriXufI9acT/vnruFr +p34Px10EZyID/RIKKwYBBAGXVQEFAQEHQOC8KcmOQ9+qEgoWBzc8xNgPUvoe +IVNw+mHbljD9eFBfAwEIBwAA/3iHMqnBfuM/c9tOIWKI4advW92aMYnjexrU +HdzPS2IoEU3CvgQYFgoAcAWCZyID/QmQm4frBefvwPlFFAAAAAAAHAAgc2Fs +dEBub3RhdGlvbnMub3BlbnBncGpzLm9yZ5M4VuJhTqDkHF/14D0i/wL8GTtM +fm9AIukMoYWXjGSGApsMFiEEaw5SIFF+7nuLC7GHm4frBefvwPkAAL0QAP9Z +oR7Vxyfuje3vAyEbef1gyfMN/RkIVbMKSiwy3A2W9AEA6QcBF5zUvwmHPpA4 ++SkLLMuq/yUGT6WhAq6kASQ8vgM= +=lluz +-----END PGP PRIVATE KEY BLOCK-----` }); + const recipientKeyWithSHA3Pref = await openpgp.readKey({ armoredKey: priv_key_sha3_512 }); + + const text = 'Hello, world.'; + const message = await openpgp.createCleartextMessage({ text }); + + // SHA3-512 is first preference of recipient key, and should be picked, + // even if not declared in the signing key prefs + const cleartextMessage = await openpgp.sign({ + message, + signingKeys: signingKeyWithoutSHA3Pref, + recipientKeys: recipientKeyWithSHA3Pref, + format: 'armored', + // the preferred hash algo is expected to picked when supported by the recipient keys + config: { preferredHashAlgorithm: openpgp.enums.hash.sha3_512 } + }); + const parsedArmored = await openpgp.readCleartextMessage({ cleartextMessage }); + expect(parsedArmored.signature.packets.filterByTag(openpgp.enums.packet.signature)).to.have.length(1); + expect( + parsedArmored.signature.packets.filterByTag(openpgp.enums.packet.signature)[0].hashAlgorithm + ).to.equal(openpgp.enums.hash.sha3_512); + }); }); describe('encrypt - unit tests', function() { From 42d504a69a474a5b6cb9641b00f3f712d3e2045e Mon Sep 17 00:00:00 2001 From: larabr Date: Thu, 31 Oct 2024 00:24:19 +0100 Subject: [PATCH 201/201] Switch to SHA512 as default preferred hash algo (`config.preferredHashAlgorithm`) (#1801) This affects the preferences of newly generated keys, which by default will have SHA512 as first hash algo preference. SHA512 will also be used when signing, as long as the recipient keys declare support for the algorithm. --- src/config/config.js | 2 +- src/crypto/public_key/rsa.js | 12 +++++++++--- test/crypto/rsa.js | 16 ++++++++++++++++ test/general/key.js | 6 +++--- test/general/openpgp.js | 6 ++++-- 5 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/config/config.js b/src/config/config.js index 4bdbe914..9e77710f 100644 --- a/src/config/config.js +++ b/src/config/config.js @@ -26,7 +26,7 @@ export default { * @memberof module:config * @property {Integer} preferredHashAlgorithm Default hash algorithm {@link module:enums.hash} */ - preferredHashAlgorithm: enums.hash.sha256, + preferredHashAlgorithm: enums.hash.sha512, /** * @memberof module:config * @property {Integer} preferredSymmetricAlgorithm Default encryption cipher {@link module:enums.symmetric} diff --git a/src/crypto/public_key/rsa.js b/src/crypto/public_key/rsa.js index 5c6027ca..07ac8484 100644 --- a/src/crypto/public_key/rsa.js +++ b/src/crypto/public_key/rsa.js @@ -26,6 +26,7 @@ import { uint8ArrayToB64, b64ToUint8Array } from '../../encoding/base64'; import { emsaEncode, emeEncode, emeDecode } from '../pkcs1'; import enums from '../../enums'; import { bigIntToNumber, bigIntToUint8Array, bitLength, byteLength, mod, modExp, modInv, uint8ArrayToBigInt } from '../biginteger'; +import hash from '../hash'; const webCrypto = util.getWebCrypto(); const nodeCrypto = util.getNodeCrypto(); @@ -45,6 +46,14 @@ const _1n = BigInt(1); * @async */ export async function sign(hashAlgo, data, n, e, d, p, q, u, hashed) { + if (hash.getHashByteLength(hashAlgo) >= n.length) { + // Throw here instead of `emsaEncode` below, to provide a clearer and consistent error + // e.g. if a 512-bit RSA key is used with a SHA-512 digest. + // The size limit is actually slightly different but here we only care about throwing + // on common key sizes. + throw new Error('Digest size cannot exceed key modulus size'); + } + if (data && !util.isStream(data)) { if (util.getWebCrypto()) { try { @@ -264,9 +273,6 @@ async function bnSign(hashAlgo, n, d, hashed) { n = uint8ArrayToBigInt(n); const m = uint8ArrayToBigInt(emsaEncode(hashAlgo, hashed, byteLength(n))); d = uint8ArrayToBigInt(d); - if (m >= n) { - throw new Error('Message size cannot exceed modulus size'); - } return bigIntToUint8Array(modExp(m, d, n), 'be', byteLength(n)); } diff --git a/test/crypto/rsa.js b/test/crypto/rsa.js index 21739fe5..61d00cf7 100644 --- a/test/crypto/rsa.js +++ b/test/crypto/rsa.js @@ -121,6 +121,22 @@ export default () => describe('basic RSA cryptography', function () { expect(util.uint8ArrayToHex(signatureNative)).to.be.equal(util.uint8ArrayToHex(signatureBN)); }); + it('compare native crypto and bnSign: throw on key size shorter than digest size', async function() { + if (!detectNative()) { this.skip(); } + + const bits = 512; + const hashName = 'sha512'; // digest too long for a 512-bit key + const { publicParams, privateParams } = await crypto.generateParams(openpgp.enums.publicKey.rsaSign, bits); + const { n, e, d, p, q, u } = { ...publicParams, ...privateParams }; + const message = random.getRandomBytes(64); + const hashAlgo = openpgp.enums.write(openpgp.enums.hash, hashName); + const hashed = await crypto.hash.digest(hashAlgo, message); + enableNative(); + await expect(crypto.publicKey.rsa.sign(hashAlgo, message, n, e, d, p, q, u, hashed)).to.be.rejectedWith(/Digest size cannot exceed key modulus size/); + disableNative(); + await expect(crypto.publicKey.rsa.sign(hashAlgo, message, n, e, d, p, q, u, hashed)).to.be.rejectedWith(/Digest size cannot exceed key modulus size/); + }); + it('compare native crypto and bnVerify', async function() { if (!detectNative()) { this.skip(); } diff --git a/test/general/key.js b/test/general/key.js index ab082354..ff94ecab 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -2261,7 +2261,7 @@ function versionSpecificTests() { ]); } const hash = openpgp.enums.hash; - expect(selfSignature.preferredHashAlgorithms).to.eql([hash.sha256, hash.sha512, hash.sha3_256, hash.sha3_512]); + expect(selfSignature.preferredHashAlgorithms).to.eql([hash.sha512, hash.sha256, hash.sha3_256, hash.sha3_512]); const compr = openpgp.enums.compression; expect(selfSignature.preferredCompressionAlgorithms).to.eql([compr.uncompressed, compr.zlib, compr.zip]); @@ -2495,7 +2495,7 @@ function versionSpecificTests() { }); it('Generate RSA key - two subkeys with default values', async function() { - const rsaBits = 512; + const rsaBits = 1024; const minRSABits = openpgp.config.minRSABits; openpgp.config.minRSABits = rsaBits; @@ -2601,7 +2601,7 @@ function versionSpecificTests() { }); it('Generate key - override main RSA key options for subkey', async function() { - const rsaBits = 512; + const rsaBits = 1024; const minRSABits = openpgp.config.minRSABits; openpgp.config.minRSABits = rsaBits; diff --git a/test/general/openpgp.js b/test/general/openpgp.js index 3d380d92..0a420b7b 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -1457,7 +1457,7 @@ VFBLG8uc9IiaKann/DYBAJcZNZHRSfpDoV2pUA5EAEi2MdjxkRysFQnYPRAu beforeEach(async function() { minRSABitsVal = openpgp.config.minRSABits; - openpgp.config.minRSABits = 512; + openpgp.config.minRSABits = 1024; }); afterEach(function() { @@ -3894,7 +3894,9 @@ XfA3pqV4mTzF signingKeys: privateKey_1337, detached: true, date: past, - format: 'binary' + format: 'binary', + // SHA-512 cannot be used with a 512-bit RSA key (digest too long) + config: { minRSABits: 512, preferredHashAlgorithm: openpgp.enums.hash.sha256 } }; const verifyOpt = { message,